From 82d14c198d7b61005093b2b06457d83435a76564 Mon Sep 17 00:00:00 2001 From: David Crocker Date: Thu, 11 Nov 2021 18:57:55 +0000 Subject: Fixed issue with extruder stopping after a tiny move Also refactored nonlinear extrusion coce to make it more efficient --- src/GCodes/GCodes2.cpp | 4 ++-- src/Movement/DDA.cpp | 18 ++++++++---------- src/Platform/Platform.cpp | 30 +++++++++--------------------- src/Platform/Platform.h | 15 +++++++++++++-- 4 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 4755bc61..a04a106b 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -3729,8 +3729,8 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx } else { - platform.GetExtrusionCoefficients(extruder, a, b, limit); - reply.printf("Drive %u nonlinear extrusion coefficients: A=%.3f, B=%.4f, limit=%.2f", extruder, (double)a, (double)b, (double)limit); + const NonlinearExtrusion& nl = platform.GetExtrusionCoefficients(extruder); + reply.printf("Drive %u nonlinear extrusion coefficients: A=%.3f, B=%.4f, limit=%.2f", extruder, (double)nl.A, (double)nl.B, (double)nl.limit); } } break; diff --git a/src/Movement/DDA.cpp b/src/Movement/DDA.cpp index 7958a71b..26358f6d 100644 --- a/src/Movement/DDA.cpp +++ b/src/Movement/DDA.cpp @@ -1527,17 +1527,15 @@ void DDA::Prepare(SimulationMode simMode) noexcept platform.EnableDrivers(drive, false); const size_t extruder = LogicalDriveToExtruder(drive); #if SUPPORT_NONLINEAR_EXTRUSION - // Add the nonlinear extrusion correction to totalExtrusion - if (flags.isPrintingMove) + // Add the nonlinear extrusion correction to totalExtrusion. + // If we are given a stupidly short move to execute then clocksNeeded can be zero, which leads to NaNs in this code; so we need to guard against that. + if (flags.isPrintingMove && clocksNeeded != 0) { - float a, b, limit; - if (platform.GetExtrusionCoefficients(extruder, a, b, limit)) - { - float& dv = directionVector[drive]; - const float averageExtrusionSpeed = (totalDistance * dv)/clocksNeeded; - const float factor = 1.0 + min((averageExtrusionSpeed * a) + (averageExtrusionSpeed * averageExtrusionSpeed * b), limit); - dv *= factor; - } + const NonlinearExtrusion& nl = platform.GetExtrusionCoefficients(extruder); + float& dv = directionVector[drive]; + const float averageExtrusionSpeed = (totalDistance * dv)/clocksNeeded; + const float factor = 1.0 + min((averageExtrusionSpeed * nl.A) + (averageExtrusionSpeed * averageExtrusionSpeed * nl.B), nl.limit); + dv *= factor; } #endif diff --git a/src/Platform/Platform.cpp b/src/Platform/Platform.cpp index 259eae32..8aafab9a 100644 --- a/src/Platform/Platform.cpp +++ b/src/Platform/Platform.cpp @@ -313,9 +313,9 @@ constexpr ObjectModelTableEntry Platform::objectModelTable[] = { "stepsPerMm", OBJECT_MODEL_FUNC(self->driveStepsPerUnit[ExtruderToLogicalDrive(context.GetLastIndex())], 2), ObjectModelEntryFlags::none }, // 5. move.extruders[].nonlinear members - { "a", OBJECT_MODEL_FUNC(self->nonlinearExtrusionA[context.GetLastIndex()], 3), ObjectModelEntryFlags::none }, - { "b", OBJECT_MODEL_FUNC(self->nonlinearExtrusionB[context.GetLastIndex()], 3), ObjectModelEntryFlags::none }, - { "upperLimit", OBJECT_MODEL_FUNC(self->nonlinearExtrusionLimit[context.GetLastIndex()], 2), ObjectModelEntryFlags::none }, + { "a", OBJECT_MODEL_FUNC(self->nonlinearExtrusion[context.GetLastIndex()].A, 3), ObjectModelEntryFlags::none }, + { "b", OBJECT_MODEL_FUNC(self->nonlinearExtrusion[context.GetLastIndex()].B, 3), ObjectModelEntryFlags::none }, + { "upperLimit", OBJECT_MODEL_FUNC(self->nonlinearExtrusion[context.GetLastIndex()].limit, 2), ObjectModelEntryFlags::none }, #if HAS_12V_MONITOR // 6. v12 members @@ -694,8 +694,8 @@ void Platform::Init() noexcept extruderDrivers[extr].SetLocal(extr + MinAxes); // set up default extruder drive mapping driveDriverBits[ExtruderToLogicalDrive(extr)] = StepPins::CalcDriverBitmap(extr + MinAxes); #if SUPPORT_NONLINEAR_EXTRUSION - nonlinearExtrusionA[extr] = nonlinearExtrusionB[extr] = 0.0; - nonlinearExtrusionLimit[extr] = DefaultNonlinearExtrusionLimit; + nonlinearExtrusion[extr].A = nonlinearExtrusion[extr].B = 0.0; + nonlinearExtrusion[extr].limit = DefaultNonlinearExtrusionLimit; #endif } @@ -3709,25 +3709,13 @@ void Platform::AtxPowerOff() noexcept #if SUPPORT_NONLINEAR_EXTRUSION -bool Platform::GetExtrusionCoefficients(size_t extruder, float& a, float& b, float& limit) const noexcept -{ - if (extruder < MaxExtruders) - { - a = nonlinearExtrusionA[extruder]; - b = nonlinearExtrusionB[extruder]; - limit = nonlinearExtrusionLimit[extruder]; - return true; - } - return false; -} - void Platform::SetNonlinearExtrusion(size_t extruder, float a, float b, float limit) noexcept { - if (extruder < MaxExtruders && nonlinearExtrusionLimit[extruder] > 0.0) + if (extruder < MaxExtruders && limit > 0.0) { - nonlinearExtrusionLimit[extruder] = limit; - nonlinearExtrusionA[extruder] = a; - nonlinearExtrusionB[extruder] = b; + nonlinearExtrusion[extruder].limit = limit; + nonlinearExtrusion[extruder].A = a; + nonlinearExtrusion[extruder].B = b; } } diff --git a/src/Platform/Platform.h b/src/Platform/Platform.h index a1f816da..201e10f2 100644 --- a/src/Platform/Platform.h +++ b/src/Platform/Platform.h @@ -303,6 +303,17 @@ struct AxisDriversConfig DriverId driverNumbers[MaxDriversPerAxis]; // The driver numbers assigned - only the first numDrivers are meaningful }; +#if SUPPORT_NONLINEAR_EXTRUSION + +struct NonlinearExtrusion +{ + float A; + float B; + float limit; +}; + +#endif + // The main class that defines the RepRap machine for the benefit of the other classes class Platform INHERIT_OBJECT_MODEL { @@ -511,7 +522,7 @@ public: void EnableAllSteppingDrivers() noexcept { steppingEnabledDriversBitmap = 0xFFFFFFFFu; } #if SUPPORT_NONLINEAR_EXTRUSION - bool GetExtrusionCoefficients(size_t extruder, float& a, float& b, float& limit) const noexcept; + const NonlinearExtrusion& GetExtrusionCoefficients(size_t extruder) const noexcept pre(extruder < MaxExtruders) { return nonlinearExtrusion[extruder]; } void SetNonlinearExtrusion(size_t extruder, float a, float b, float limit) noexcept; #endif @@ -737,7 +748,7 @@ private: #endif #if SUPPORT_NONLINEAR_EXTRUSION - float nonlinearExtrusionA[MaxExtruders], nonlinearExtrusionB[MaxExtruders], nonlinearExtrusionLimit[MaxExtruders]; + NonlinearExtrusion nonlinearExtrusion[MaxExtruders]; // nonlinear extrusion coefficients #endif DriverId extruderDrivers[MaxExtruders]; // the driver number assigned to each extruder -- cgit v1.2.3