Skip to content

Commit

Permalink
Revamp:
Browse files Browse the repository at this point in the history
- The averaging duration is configurable: M207 D[seconds]. default: 0.25
- Fix some potential computation errors.
  • Loading branch information
mdealer committed Mar 29, 2020
1 parent 129bfbf commit 2bbfc24
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 34 deletions.
9 changes: 7 additions & 2 deletions src/GCodes/GCodes2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2022,12 +2022,17 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
platform.SetRetractionCompensation(gb.GetFValue());
seen = true;
}
if (gb.Seen('D'))
{
platform.SetRetractionCompensationDuration(gb.GetFValue());
seen = true;
}
if (!seen)
{
reply.printf("Retraction/un-retraction settings: length %.2f/%.2fmm, speed %d/%dmm/min, Z hop %.2fmm, compensation: %.2f",
reply.printf("Retraction/un-retraction settings: length %.2f/%.2fmm, speed %d/%dmm/min, Z hop %.2fmm, compensation: %.2f / %.2fs",
(double)retractLength, (double)(retractLength + retractExtra), (int)(retractSpeed * MinutesToSeconds),
(int)(unRetractSpeed * MinutesToSeconds), (double)retractHop,
(double)platform.GetRetractionCompensation());
(double)platform.GetRetractionCompensation(), (double)platform.GetRetractionCompensationDuration());
}
}
break;
Expand Down
6 changes: 3 additions & 3 deletions src/Movement/DDA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ bool DDA::IsGoodToPrepare() const
if (!dda->IsPrintingMove())
return true;
totalTime += dda->clocksNeeded;
if (totalTime >= StepTimer::StepClockRate || ringCount >= 20)
if (totalTime >= StepTimer::StepClockRate * reprap.GetPlatform().GetRetractionCompensationDuration() || ringCount >= 20)
return true;
dda = dda->next;
}
Expand Down Expand Up @@ -1107,7 +1107,7 @@ inline void DDA::AdjustAcceleration()

// Prepare this DDA for execution.
// This must not be called with interrupts disabled, because it calls Platform::EnableDrive.
void DDA::Prepare(uint8_t simMode, float extrusionPending[])
void DDA::Prepare(uint8_t simMode, float extrusionPending[], float lastExtrusionRate[])
{
if ( flags.xyMoving
&& reprap.GetMove().IsDRCenabled()
Expand Down Expand Up @@ -1358,7 +1358,7 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[])
speedChange = 0.0;
}

if (pdm->PrepareExtruder(*this, params, extrusionPending[drive - numTotalAxes], speedChange, flags.usePressureAdvance))
if (pdm->PrepareExtruder(*this, params, extrusionPending[drive - numTotalAxes], lastExtrusionRate[drive - numTotalAxes], speedChange, flags.usePressureAdvance))
{
// Check for sensible values, print them if they look dubious
if ( reprap.Debug(moduleDda)
Expand Down
2 changes: 1 addition & 1 deletion src/Movement/DDA.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class DDA
void SetPrevious(DDA *p) { prev = p; }
void Complete() { state = completed; }
bool Free();
void Prepare(uint8_t simMode, float extrusionPending[]) __attribute__ ((hot)); // Calculate all the values and freeze this DDA
void Prepare(uint8_t simMode, float extrusionPending[], float lastExtrusionRate[]) __attribute__ ((hot)); // Calculate all the values and freeze this DDA
bool HasStepError() const;
bool CanPauseAfter() const { return flags.canPauseAfter; }
bool IsPrintingMove() const { return flags.isPrintingMove; } // Return true if this involves both XY movement and extrusion
Expand Down
13 changes: 2 additions & 11 deletions src/Movement/DDARing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void DDARing::Init2()
{
extrusionAccumulators[i] = 0;
extrusionPending[i] = 0.0;
lastExtrusionRate[i] = 0.0;
}
extrudersPrinting = false;
simulationTime = 0.0;
Expand Down Expand Up @@ -246,7 +247,7 @@ void DDARing::PrepareMoves(DDA *firstUnpreparedMove, int32_t moveTimeLeft, unsig
#endif
)
{
firstUnpreparedMove->Prepare(simulationMode, extrusionPending);
firstUnpreparedMove->Prepare(simulationMode, extrusionPending, lastExtrusionRate);
moveTimeLeft += firstUnpreparedMove->GetTimeLeft();
++alreadyPrepared;
firstUnpreparedMove = firstUnpreparedMove->GetNext();
Expand Down Expand Up @@ -329,16 +330,6 @@ void DDARing::CurrentMoveCompleted()
for (size_t drive = numAxes; drive < MaxTotalDrivers; ++drive)
{
extrusionAccumulators[drive - numAxes] += currentDda->GetStepsTaken(drive);
if (currentDda->IsPrintingMove())
{
auto cn = currentDda->GetClocksNeeded();
auto accumulatorDuration = StepTimer::StepClockRate / 100;
auto extrusionRate = (currentDda->totalDistance * currentDda->directionVector[drive]) / (cn / (double)StepTimer::StepClockRate);
if (accumulatorDuration > cn)
lastPrintingMoveExtrusionRequired[drive - numAxes] = lastPrintingMoveExtrusionRequired[drive - numAxes] * (1.0 - cn / (double)accumulatorDuration) + cn / (double)accumulatorDuration * extrusionRate;
else
lastPrintingMoveExtrusionRequired[drive - numAxes] = extrusionRate;
}
}
currentDda = nullptr;

Expand Down
4 changes: 1 addition & 3 deletions src/Movement/DDARing.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ class DDARing
uint32_t GetScheduledMoves() const { return scheduledMoves; } // How many moves have been scheduled?
uint32_t GetCompletedMoves() const { return completedMoves; } // How many moves have been completed?
void ResetMoveCounters() { scheduledMoves = completedMoves = 0; }
float GetLastPrintingMoveExtrusionRequired(size_t extruder) const { return extruder < MaxExtruders ? lastPrintingMoveExtrusionRequired[extruder] : 0.0; };
void SetLastPrintingMoveExtrusionRequired(size_t extruder, float v) { if (extruder < MaxExtruders) lastPrintingMoveExtrusionRequired[extruder] = v; };

float GetSimulationTime() const { return simulationTime; }
void ResetSimulationTime() { simulationTime = 0.0; }
Expand Down Expand Up @@ -99,10 +97,10 @@ class DDARing

float simulationTime; // Print time since we started simulating
float extrusionPending[MaxExtruders]; // Extrusion not done due to rounding to nearest step
float lastExtrusionRate[MaxExtruders];
volatile int32_t extrusionAccumulators[MaxExtruders]; // Accumulated extruder motor steps
volatile uint32_t extrudersPrintingSince; // The milliseconds clock time when extrudersPrinting was set to true
volatile bool extrudersPrinting; // Set whenever an extruder starts a printing move, cleared by a non-printing extruder move
volatile float lastPrintingMoveExtrusionRequired[MaxExtruders];
};

// Start the next move. Return true if the
Expand Down
63 changes: 52 additions & 11 deletions src/Movement/DriveMovement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ bool DriveMovement::PrepareDeltaAxis(const DDA& dda, const PrepParams& params)
}
#define DEBUG_RETRACTION_COMPENSATION 1
// Prepare this DM for an extruder move, returning true if there are steps to do
bool DriveMovement::PrepareExtruder(DDA& dda, const PrepParams& params, float& extrusionPending, float speedChange, bool doCompensation)
bool DriveMovement::PrepareExtruder(DDA& dda, const PrepParams& params, float& extrusionPending, float& lastExtrusionRate, float speedChange, bool doCompensation)
{
// Calculate the requested extrusion amount and a few other things
float &dv = dda.directionVector[drive];
Expand All @@ -207,7 +207,7 @@ bool DriveMovement::PrepareExtruder(DDA& dda, const PrepParams& params, float& e
}
}
#endif
const float moveTime = dda.clocksNeeded / (float)StepTimer::StepClockRate;
const float moveTime = dda.clocksNeeded * StepTimer::StepClocksToMillis;
float retractionComp = reprap.GetPlatform().GetRetractionCompensation();
// Add on any fractional extrusion pending from the previous move
extrusionRequired += extrusionPending;
Expand All @@ -217,27 +217,52 @@ bool DriveMovement::PrepareExtruder(DDA& dda, const PrepParams& params, float& e
float nextExtrusionRate = 0.0;
size_t n = 0;
uint32_t totalTime = 0;
while (nextDda->IsPrintingMove() && nextDda->state == DDA::provisional && totalTime < StepTimer::StepClockRate / 100)
float maxDuration = StepTimer::StepClockRate * reprap.GetPlatform().GetRetractionCompensationDuration();
while (nextDda->IsPrintingMove() && nextDda->state == DDA::provisional)
{
++n;
nextDda = nextDda->next;
}
size_t maxMoves = n / 2;
n = 0;
nextDda = dda.GetNext();
while (nextDda->IsPrintingMove() && nextDda->state == DDA::provisional && n <= maxMoves && totalTime < maxDuration)
{
++n;
totalTime += nextDda->clocksNeeded;
nextExtrusionRate = nextExtrusionRate + nextDda->totalDistance * nextDda->directionVector[drive] / (nextDda->clocksNeeded / (double)StepTimer::StepClockRate);
float nextMoveTime = nextDda->clocksNeeded * StepTimer::StepClocksToMillis;
float ddv = nextDda->totalDistance * nextDda->directionVector[drive] * 1000.0;
float rate = ddv / nextMoveTime;
if (nextExtrusionRate == 0.0)
nextExtrusionRate = rate;
else
{
float r = min<float>(1.0, nextDda->clocksNeeded / maxDuration * 4);
nextExtrusionRate = nextExtrusionRate * (max<float>(0.0, 1.0 - r)) + rate * min<float>(1.0, r);
}
nextDda = nextDda->next;
#if DEBUG_RETRACTION_COMPENSATION > 0
if (extruder == 0)
{
debugPrintf("prepared [%03f %03f %03f] mt=%03f, rate=%03f, ner=%03f, ddv=%03f\n", (double)nextDda->endCoordinates[0], (double)nextDda->endCoordinates[1], (double)nextDda->endCoordinates[2], (double)nextMoveTime, (double)rate, (double)nextExtrusionRate, (double)ddv);
}
#endif
}
if (n)
nextExtrusionRate /= n;
float lastExtrusionRate = reprap.GetMove().GetLastPrintingMoveExtrusionRequired(extruder);
if (abs(nextExtrusionRate) > 0.00001 && abs(lastExtrusionRate) > 0.00001)
{
constexpr float maxRatio = 2.0;
float unretractPending = lastExtrusionRate > 0.01 ? (nextExtrusionRate - lastExtrusionRate) * retractionComp : 0.0;
unretractPending = min<float>(abs(extrusionRequired) * maxRatio, max<float>(-abs(extrusionRequired) * maxRatio, unretractPending));
#if DEBUG_RETRACTION_COMPENSATION > 0
#if DEBUG_RETRACTION_COMPENSATION > 0
if (extruder == 0)
debugPrintf("[%03f %03f %03f] mt=%03f, er=%03f, up=%03f, ler=%03f, ner=%03f, ep=%03f\n", (double)dda.endCoordinates[0], (double)dda.endCoordinates[1], (double)dda.endCoordinates[2], (double)moveTime, (double)extrusionRequired, (double)unretractPending, (double)lastExtrusionRate, (double)nextExtrusionRate, (double)extrusionPending);
#endif
{
debugPrintf("unretract [%03f %03f %03f] mt=%03f, er=%03f, up=%03f, ler=%03f, ner=%03f, ep=%03f", (double)dda.endCoordinates[0], (double)dda.endCoordinates[1], (double)dda.endCoordinates[2], (double)moveTime, (double)extrusionRequired, (double)unretractPending, (double)lastExtrusionRate, (double)nextExtrusionRate, (double)extrusionPending);
debugPrintf(", nc=%" PRIu32 "\n", n);
}
#endif
extrusionRequired += unretractPending;
}
lastExtrusionRate = 0.0;
}
else
{
Expand All @@ -255,6 +280,23 @@ bool DriveMovement::PrepareExtruder(DDA& dda, const PrepParams& params, float& e
float compensationTime;
float accelCompensationDistance;

if (dda.IsPrintingMove())
{
float maxDuration = StepTimer::StepClockRate * reprap.GetPlatform().GetRetractionCompensationDuration();
float ddv = dda.totalDistance * dda.directionVector[drive] * 1000.0;
float extrusionRate = ddv / moveTime;
if (lastExtrusionRate != 0.0)
{
float r = min<float>(1.0, dda.clocksNeeded / maxDuration * 4);
lastExtrusionRate = lastExtrusionRate * (1.0 - r) + (r) * extrusionRate;
}
else
lastExtrusionRate = extrusionRate;
#if DEBUG_RETRACTION_COMPENSATION > 0
if (extruder == 0)
debugPrintf("print [%03f %03f %03f] mt=%03f, er=%03f, ler=%03f, ep=%03f, ddv=%03f\n", (double)dda.endCoordinates[0], (double)dda.endCoordinates[1], (double)dda.endCoordinates[2], (double)moveTime, (double)extrusionRequired, (double)lastExtrusionRate, (double)extrusionPending, (double)ddv);
#endif
}
if (doCompensation && direction)
{
// Calculate the pressure advance parameters
Expand Down Expand Up @@ -284,7 +326,6 @@ bool DriveMovement::PrepareExtruder(DDA& dda, const PrepParams& params, float& e
// Calculate the acceleration phase parameters
mp.cart.accelStopStep = (uint32_t)(params.accelDistance * effectiveStepsPerMm) + 1;
}

int32_t netSteps = (int32_t)(extrusionRequired * rawStepsPerMm);
extrusionPending = extrusionRequired - (float)netSteps/rawStepsPerMm;

Expand Down
2 changes: 1 addition & 1 deletion src/Movement/DriveMovement.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class DriveMovement
bool CalcNextStepTimeDelta(const DDA &dda, bool live) __attribute__ ((hot));
bool PrepareCartesianAxis(const DDA& dda, const PrepParams& params) __attribute__ ((hot));
bool PrepareDeltaAxis(const DDA& dda, const PrepParams& params) __attribute__ ((hot));
bool PrepareExtruder(DDA& dda, const PrepParams& params, float& extrusionPending, float speedChange, bool doCompensation) __attribute__ ((hot));
bool PrepareExtruder(DDA& dda, const PrepParams& params, float& extrusionPending, float& lastExtrusionRate, float speedChange, bool doCompensation) __attribute__ ((hot));
void ReduceSpeed(uint32_t inverseSpeedFactor);
void DebugPrint() const;
int32_t GetNetStepsLeft() const;
Expand Down
1 change: 0 additions & 1 deletion src/Movement/Move.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ class Move INHERIT_OBJECT_MODEL

float GetTopSpeed() const { return mainDDARing.GetTopSpeed(); }
float GetRequestedSpeed() const { return mainDDARing.GetRequestedSpeed(); }
float GetLastPrintingMoveExtrusionRequired(size_t extruder) const { return mainDDARing.GetLastPrintingMoveExtrusionRequired(extruder); }

void AdjustLeadscrews(const floatc_t corrections[]); // Called by some Kinematics classes to adjust the leadscrews

Expand Down
7 changes: 7 additions & 0 deletions src/Platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ void Platform::Init()
}
slowDriversBitmap = 0; // assume no drivers need extended step pulse timing
SetRetractionCompensation(0.0);
SetRetractionCompensationDuration(0.25);
for (size_t extr = 0; extr < MaxExtruders; ++extr)
{
extruderDrivers[extr] = (uint8_t)(extr + MinAxes); // set up default extruder drive mapping
Expand Down Expand Up @@ -3976,6 +3977,12 @@ void Platform::SetRetractionCompensation(float factor)
retractionCompensation = factor;
}

void Platform::SetRetractionCompensationDuration(float factor)
{
retractionCompDuration = factor;
}


#if SUPPORT_NONLINEAR_EXTRUSION

bool Platform::GetExtrusionCoefficients(size_t extruder, float& a, float& b, float& limit) const
Expand Down
8 changes: 8 additions & 0 deletions src/Platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,8 @@ class Platform
void SetPressureAdvance(size_t extruder, float factor);
float GetRetractionCompensation() const;
void SetRetractionCompensation(float factor);
float GetRetractionCompensationDuration() const;
void SetRetractionCompensationDuration(float factor);

void SetEndStopConfiguration(size_t axis, EndStopPosition endstopPos, EndStopInputType inputType)
pre(axis < MaxAxes);
Expand Down Expand Up @@ -746,6 +748,7 @@ class Platform
float instantDvs[MaxTotalDrivers];
float pressureAdvance[MaxExtruders];
float retractionCompensation;
float retractionCompDuration;
#if SUPPORT_NONLINEAR_EXTRUSION
float nonlinearExtrusionA[MaxExtruders], nonlinearExtrusionB[MaxExtruders], nonlinearExtrusionLimit[MaxExtruders];
#endif
Expand Down Expand Up @@ -1122,6 +1125,11 @@ inline float Platform::GetRetractionCompensation() const
return retractionCompensation;
}

inline float Platform::GetRetractionCompensationDuration() const
{
return retractionCompDuration;
}

// This is called by the tick ISR to get the raw Z probe reading to feed to the filter
inline uint16_t Platform::GetRawZProbeReading() const
{
Expand Down
2 changes: 1 addition & 1 deletion src/Version.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#endif

#ifndef DATE
# define DATE "2020-03-28b1"
# define DATE "2020-03-29b1"
#endif

#define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman, printm3d, mdealer"
Expand Down

0 comments on commit 2bbfc24

Please sign in to comment.