diff options
author | David Crocker <dcrocker@eschertech.com> | 2021-07-24 13:04:13 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2021-07-24 13:04:13 +0300 |
commit | 745c9baea0c8d6b3987d0a8795c74afa5ae4da03 (patch) | |
tree | 0e1f2f27d7c5f2585e809ec5deb2eb4d5966ebc7 /src | |
parent | 107551283f1f69e607125b75bb8cfebf4cb8cd5d (diff) |
Finished converting time units to step clocks, pending testing
Diffstat (limited to 'src')
29 files changed, 252 insertions, 226 deletions
diff --git a/src/Accelerometers/LIS3DH.cpp b/src/Accelerometers/LIS3DH.cpp index 65dcc52f..c783de83 100644 --- a/src/Accelerometers/LIS3DH.cpp +++ b/src/Accelerometers/LIS3DH.cpp @@ -224,7 +224,7 @@ unsigned int LIS3DH::CollectData(const uint16_t **collectedData, uint16_t &dataR const uint32_t interval = lastInterruptTime - firstInterruptTime; dataRate = (totalNumRead == 0 || interval == 0) ? 0 - : (totalNumRead * StepTimer::StepClockRate)/interval; + : (totalNumRead * StepClockRate)/interval; totalNumRead += numToRead; } return numToRead; diff --git a/src/Configuration.h b/src/Configuration.h index e2ec0db2..72b18337 100644 --- a/src/Configuration.h +++ b/src/Configuration.h @@ -51,6 +51,7 @@ constexpr float DefaultEInstantDv = 2.0; constexpr float DefaultMinFeedrate = 0.5; // the default minimum movement speed in mm/sec (extruding moves will go slower than this if the extrusion rate demands it) constexpr float AbsoluteMinFeedrate = 0.01; // the absolute minimum movement speed in mm/sec constexpr float MinimumJerk = 0.1; // the minimum jerk in mm/sec +constexpr float MinimumAcceleration = 0.1; // he minimum acceleration in mm/sec^2 constexpr float DefaultAxisMinimum = 0.0; constexpr float DefaultAxisMaximum = 200.0; diff --git a/src/Endstops/ZProbe.cpp b/src/Endstops/ZProbe.cpp index 293bcde8..2147b664 100644 --- a/src/Endstops/ZProbe.cpp +++ b/src/Endstops/ZProbe.cpp @@ -56,7 +56,7 @@ constexpr ObjectModelArrayDescriptor ZProbe::speedsArrayDescriptor = nullptr, [] (const ObjectModel *self, const ObjectExplorationContext&) noexcept -> size_t { return ARRAY_SIZE(ZProbe::probeSpeeds); }, [] (const ObjectModel *self, ObjectExplorationContext& context) noexcept -> ExpressionValue - { return ExpressionValue(GCodeBuffer::InverseConvertSpeedToMm(((const ZProbe*)self)->probeSpeeds[context.GetLastIndex()], false), 1); } + { return ExpressionValue(InverseConvertSpeedToMmPerMin(((const ZProbe*)self)->probeSpeeds[context.GetLastIndex()]), 1); } }; constexpr ObjectModelTableEntry ZProbe::objectModelTable[] = @@ -71,13 +71,13 @@ constexpr ObjectModelTableEntry ZProbe::objectModelTable[] = { "maxProbeCount", OBJECT_MODEL_FUNC((int32_t)self->misc.parts.maxTaps), ObjectModelEntryFlags::none }, { "offsets", OBJECT_MODEL_FUNC_NOSELF(&offsetsArrayDescriptor), ObjectModelEntryFlags::none }, { "recoveryTime", OBJECT_MODEL_FUNC(self->recoveryTime, 1), ObjectModelEntryFlags::none }, - { "speed", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->probeSpeeds[1], false), 1), ObjectModelEntryFlags::obsolete }, + { "speed", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerMin(self->probeSpeeds[1]), 1), ObjectModelEntryFlags::obsolete }, { "speeds", OBJECT_MODEL_FUNC_NOSELF(&speedsArrayDescriptor), ObjectModelEntryFlags::none }, { "temperatureCoefficient", OBJECT_MODEL_FUNC(self->temperatureCoefficients[0], 5), ObjectModelEntryFlags::obsolete }, { "temperatureCoefficients", OBJECT_MODEL_FUNC_NOSELF(&temperatureCoefficientsArrayDescriptor), ObjectModelEntryFlags::none }, { "threshold", OBJECT_MODEL_FUNC((int32_t)self->adcValue), ObjectModelEntryFlags::none }, { "tolerance", OBJECT_MODEL_FUNC(self->tolerance, 3), ObjectModelEntryFlags::none }, - { "travelSpeed", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->travelSpeed, false), 1), ObjectModelEntryFlags::none }, + { "travelSpeed", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerMin(self->travelSpeed), 1), ObjectModelEntryFlags::none }, { "triggerHeight", OBJECT_MODEL_FUNC(-self->offsets[Z_AXIS], 3), ObjectModelEntryFlags::none }, { "type", OBJECT_MODEL_FUNC((int32_t)self->type), ObjectModelEntryFlags::none }, { "value", OBJECT_MODEL_FUNC_NOSELF(&valueArrayDescriptor), ObjectModelEntryFlags::live }, @@ -386,8 +386,8 @@ GCodeResult ZProbe::Configure(GCodeBuffer& gb, const StringRef &reply, bool& see float userProbeSpeeds[2]; size_t numSpeeds = 2; gb.GetFloatArray(userProbeSpeeds, numSpeeds, true); - probeSpeeds[0] = GCodeBuffer::ConvertSpeedFromMm(userProbeSpeeds[0], false); - probeSpeeds[1] = GCodeBuffer::ConvertSpeedFromMm(userProbeSpeeds[1], false); + probeSpeeds[0] = ConvertSpeedFromMmPerMin(userProbeSpeeds[0]); + probeSpeeds[1] = ConvertSpeedFromMmPerMin(userProbeSpeeds[1]); seen = true; } @@ -422,9 +422,9 @@ GCodeResult ZProbe::Configure(GCodeBuffer& gb, const StringRef &reply, bool& see const GCodeResult rslt = AppendPinNames(reply); reply.catf(", dive height %.1fmm, probe speeds %d,%dmm/min, travel speed %dmm/min, recovery time %.2f sec, heaters %s, max taps %u, max diff %.2f", (double)diveHeight, - (int)GCodeBuffer::InverseConvertSpeedToMm(probeSpeeds[0], false), - (int)GCodeBuffer::InverseConvertSpeedToMm(probeSpeeds[1], false), - (int)GCodeBuffer::InverseConvertSpeedToMm(travelSpeed, false), + (int)InverseConvertSpeedToMmPerMin(probeSpeeds[0]), + (int)InverseConvertSpeedToMmPerMin(probeSpeeds[1]), + (int)InverseConvertSpeedToMmPerMin(travelSpeed), (double)recoveryTime, (misc.parts.turnHeatersOff) ? "suspended" : "normal", misc.parts.maxTaps, (double)tolerance); diff --git a/src/Fans/LedStripDriver.cpp b/src/Fans/LedStripDriver.cpp index 1fe44f62..647302d3 100644 --- a/src/Fans/LedStripDriver.cpp +++ b/src/Fans/LedStripDriver.cpp @@ -53,7 +53,7 @@ namespace LedStripDriver { constexpr uint32_t DefaultDotStarSpiClockFrequency = 1000000; // 1MHz default constexpr uint32_t DefaultNeoPixelSpiClockFrequency = 2500000; // must be between about 2MHz and about 4MHz - constexpr uint32_t MinNeoPixelResetTicks = (250 * StepTimer::StepClockRate)/1000000; // 250us minimum Neopixel reset time on later chips + constexpr uint32_t MinNeoPixelResetTicks = (250 * StepClockRate)/1000000; // 250us minimum Neopixel reset time on later chips // Define the size of the buffer used to accumulate a sequence of colours to send to the string #if defined(DUET3_V06) diff --git a/src/Fans/LocalFan.cpp b/src/Fans/LocalFan.cpp index eb461670..bef4ccad 100644 --- a/src/Fans/LocalFan.cpp +++ b/src/Fans/LocalFan.cpp @@ -215,8 +215,8 @@ int32_t LocalFan::GetRPM() const noexcept // When the fan stops, we get no interrupts and fanInterval stops getting updated. We must recognise this and return zero. return (!tachoPort.IsValid()) ? -1 // we return -1 if there is no tacho configured - : (fanInterval != 0 && StepTimer::GetTimerTicks() - fanLastResetTime < 3 * StepTimer::StepClockRate) // if we have a reading and it is less than 3 seconds old - ? (StepTimer::StepClockRate * fanMaxInterruptCount * (60/2))/fanInterval // then calculate RPM assuming 2 interrupts per rev + : (fanInterval != 0 && StepTimer::GetTimerTicks() - fanLastResetTime < 3 * StepClockRate) // if we have a reading and it is less than 3 seconds old + ? (StepClockRate * fanMaxInterruptCount * (60/2))/fanInterval // then calculate RPM assuming 2 interrupts per rev : 0; // else assume fan is off or tacho not connected } diff --git a/src/FilamentMonitors/Duet3DFilamentMonitor.cpp b/src/FilamentMonitors/Duet3DFilamentMonitor.cpp index 41c957c9..cc91f0d9 100644 --- a/src/FilamentMonitors/Duet3DFilamentMonitor.cpp +++ b/src/FilamentMonitors/Duet3DFilamentMonitor.cpp @@ -85,7 +85,7 @@ Duet3DFilamentMonitor::PollResult Duet3DFilamentMonitor::PollReceiveBuffer(uint1 { // For the Duet3D sensors we need to decode the received data from the transition times recorded in the edgeCaptures array static constexpr uint32_t BitsPerSecond = 1000; // the nominal bit rate that the data is transmitted at - static constexpr uint32_t NominalBitLength = StepTimer::StepClockRate/BitsPerSecond; // the nominal bit length in step clocks + static constexpr uint32_t NominalBitLength = StepClockRate/BitsPerSecond; // the nominal bit length in step clocks static constexpr uint32_t MinBitLength = (NominalBitLength * 10)/13; // allow 30% clock speed tolerance static constexpr uint32_t MaxBitLength = (NominalBitLength * 13)/10; // allow 30% clock speed tolerance static constexpr uint32_t ErrorRecoveryDelayBits = 8; // before a start bit we want the line to be low for this long diff --git a/src/GCodes/GCodeBuffer/GCodeBuffer.cpp b/src/GCodes/GCodeBuffer/GCodeBuffer.cpp index a6200a76..117df375 100644 --- a/src/GCodes/GCodeBuffer/GCodeBuffer.cpp +++ b/src/GCodes/GCodeBuffer/GCodeBuffer.cpp @@ -50,17 +50,17 @@ constexpr ObjectModelTableEntry GCodeBuffer::objectModelTable[] = { // Within each group, these entries must be in alphabetical order // 0. inputs[] root - { "axesRelative", OBJECT_MODEL_FUNC((bool)self->machineState->axesRelative), ObjectModelEntryFlags::none }, - { "compatibility", OBJECT_MODEL_FUNC(self->machineState->compatibility.ToString()), ObjectModelEntryFlags::none }, - { "distanceUnit", OBJECT_MODEL_FUNC(self->GetDistanceUnits()), ObjectModelEntryFlags::none }, - { "drivesRelative", OBJECT_MODEL_FUNC((bool)self->machineState->drivesRelative), ObjectModelEntryFlags::none }, - { "feedRate", OBJECT_MODEL_FUNC(self->machineState->feedRate, 1), ObjectModelEntryFlags::live }, - { "inMacro", OBJECT_MODEL_FUNC((bool)self->machineState->doingFileMacro), ObjectModelEntryFlags::none }, - { "lineNumber", OBJECT_MODEL_FUNC((int32_t)self->GetLineNumber()), ObjectModelEntryFlags::live }, - { "name", OBJECT_MODEL_FUNC(self->codeChannel.ToString()), ObjectModelEntryFlags::none }, - { "stackDepth", OBJECT_MODEL_FUNC((int32_t)self->GetStackDepth()), ObjectModelEntryFlags::none }, - { "state", OBJECT_MODEL_FUNC(self->GetStateText()), ObjectModelEntryFlags::live }, - { "volumetric", OBJECT_MODEL_FUNC((bool)self->machineState->volumetricExtrusion), ObjectModelEntryFlags::none }, + { "axesRelative", OBJECT_MODEL_FUNC((bool)self->machineState->axesRelative), ObjectModelEntryFlags::none }, + { "compatibility", OBJECT_MODEL_FUNC(self->machineState->compatibility.ToString()), ObjectModelEntryFlags::none }, + { "distanceUnit", OBJECT_MODEL_FUNC(self->GetDistanceUnits()), ObjectModelEntryFlags::none }, + { "drivesRelative", OBJECT_MODEL_FUNC((bool)self->machineState->drivesRelative), ObjectModelEntryFlags::none }, + { "feedRate", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerSec(self->machineState->feedRate), 1), ObjectModelEntryFlags::live }, + { "inMacro", OBJECT_MODEL_FUNC((bool)self->machineState->doingFileMacro), ObjectModelEntryFlags::none }, + { "lineNumber", OBJECT_MODEL_FUNC((int32_t)self->GetLineNumber()), ObjectModelEntryFlags::live }, + { "name", OBJECT_MODEL_FUNC(self->codeChannel.ToString()), ObjectModelEntryFlags::none }, + { "stackDepth", OBJECT_MODEL_FUNC((int32_t)self->GetStackDepth()), ObjectModelEntryFlags::none }, + { "state", OBJECT_MODEL_FUNC(self->GetStateText()), ObjectModelEntryFlags::live }, + { "volumetric", OBJECT_MODEL_FUNC((bool)self->machineState->volumetricExtrusion), ObjectModelEntryFlags::none }, }; constexpr uint8_t GCodeBuffer::objectModelTableDescriptor[] = { 1, 11 }; @@ -389,19 +389,19 @@ float GCodeBuffer::GetDistance() THROWS(GCodeException) return ConvertDistance(GetFValue()); } -// Get a speed in mm/min or inches/min or optionally /sec and convert it to mm/step_clock +// Get a speed in mm/min or inches/min and convert it to mm/step_clock float GCodeBuffer::GetSpeed() THROWS(GCodeException) { return ConvertSpeed(GetFValue()); } -// Get a speed in mm/min or inches/min or optionally /sec and convert it to mm/step_clock +// Get a speed in mm/min mm/sec and convert it to mm/step_clock float GCodeBuffer::GetSpeedFromMm(bool useSeconds) THROWS(GCodeException) { return ConvertSpeedFromMm(GetFValue(), useSeconds); } -// Get an acceleration in mm/sec^2 or inches/sec^2 and convert it to mm/step_clock^2 +// Get an acceleration in mm/sec^2 and convert it to mm/step_clock^2 float GCodeBuffer::GetAcceleration() THROWS(GCodeException) { return ConvertAcceleration(GetFValue()); @@ -755,34 +755,14 @@ float GCodeBuffer::InverseConvertDistance(float distance) const noexcept return (UsingInches()) ? distance/InchToMm : distance; } -/*static*/ float GCodeBuffer::ConvertAcceleration(float accel) noexcept -{ - return accel * (1.0/StepTimer::StepClockRateSquared); -} - -/*static */float GCodeBuffer::InverseConvertAcceleration(float accel) noexcept -{ - return accel * StepTimer::StepClockRateSquared; -} - float GCodeBuffer::ConvertSpeed(float speed) const noexcept { - return speed * ((UsingInches()) ? InchToMm/StepTimer::StepClockRate : 1.0/StepTimer::StepClockRate); -} - -/*static*/ float GCodeBuffer::ConvertSpeedFromMm(float speed, bool useSeconds) noexcept -{ - return speed * ((useSeconds) ? 1.0/StepTimer::StepClockRate : MinutesToSeconds/StepTimer::StepClockRate); + return speed * ((UsingInches()) ? InchToMm/StepClockRate : 1.0/StepClockRate); } float GCodeBuffer::InverseConvertSpeed(float speed) const noexcept { - return speed * ((UsingInches()) ? StepTimer::StepClockRate/InchToMm : (float)StepTimer::StepClockRate); -} - -/*static*/ float GCodeBuffer::InverseConvertSpeedToMm(float speed, bool useSeconds) noexcept -{ - return speed * ((useSeconds) ? StepTimer::StepClockRate : StepTimer::StepClockRate * SecondsToMinutes); + return speed * ((UsingInches()) ? StepClockRate/InchToMm : (float)StepClockRate); } const char *GCodeBuffer::GetDistanceUnits() const noexcept diff --git a/src/GCodes/GCodeBuffer/GCodeBuffer.h b/src/GCodes/GCodeBuffer/GCodeBuffer.h index 946f93c4..59e86b72 100644 --- a/src/GCodes/GCodeBuffer/GCodeBuffer.h +++ b/src/GCodes/GCodeBuffer/GCodeBuffer.h @@ -134,12 +134,8 @@ public: bool UsingInches() const noexcept { return machineState->usingInches; } float ConvertDistance(float distance) const noexcept; float InverseConvertDistance(float distance) const noexcept; - static float ConvertAcceleration(float accel) noexcept; - static float InverseConvertAcceleration(float accel) noexcept; float ConvertSpeed(float speed) const noexcept; - static float ConvertSpeedFromMm(float speed, bool useSeconds) noexcept; float InverseConvertSpeed(float speed) const noexcept; - static float InverseConvertSpeedToMm(float speed, bool useSeconds) noexcept; const char *GetDistanceUnits() const noexcept; unsigned int GetStackDepth() const noexcept; bool PushState(bool withinSameFile) noexcept; // Push state returning true if successful (i.e. stack not overflowed) diff --git a/src/GCodes/GCodeMachineState.cpp b/src/GCodes/GCodeMachineState.cpp index 1af502d1..1e6e6dda 100644 --- a/src/GCodes/GCodeMachineState.cpp +++ b/src/GCodes/GCodeMachineState.cpp @@ -12,7 +12,7 @@ // Create a default initialised GCodeMachineState GCodeMachineState::GCodeMachineState() noexcept - : feedRate(DefaultFeedRate * SecondsToMinutes), + : feedRate(ConvertSpeedFromMmPerMin(DefaultFeedRate)), #if HAS_LINUX_INTERFACE fileId(NoFileId), #endif diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp index 94fb82a0..005b5018 100644 --- a/src/GCodes/GCodes.cpp +++ b/src/GCodes/GCodes.cpp @@ -1492,7 +1492,7 @@ void GCodes::SaveResumeInfo(bool wasPowerFailure) noexcept buf.catf("\nG0 F6000 Z%.3f\n", (double)pauseRestorePoint.moveCoords[Z_AXIS]); // Set the feed rate - buf.catf("G1 F%.1f", (double)(pauseRestorePoint.feedRate * MinutesToSeconds)); + buf.catf("G1 F%.1f", (double)InverseConvertSpeedToMmPerMin(pauseRestorePoint.feedRate)); #if SUPPORT_LASER if (machineType == MachineType::laser) { @@ -1630,7 +1630,7 @@ const char * GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, bool isP moveBuffer.applyM220M221 = (moveBuffer.moveType == 0 && isPrintingMove && !gb.IsDoingFileMacro()); if (gb.Seen(feedrateLetter)) { - gb.LatestMachineState().feedRate = gb.GetDistance() * SecondsToMinutes; // update requested speed, not allowing for speed factor + gb.LatestMachineState().feedRate = gb.GetSpeed(); // update requested speed, not allowing for speed factor } moveBuffer.feedRate = (moveBuffer.applyM220M221) ? speedFactor * gb.LatestMachineState().feedRate @@ -1640,7 +1640,7 @@ const char * GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, bool isP else { moveBuffer.applyM220M221 = false; - moveBuffer.feedRate = DefaultG0FeedRate; // use maximum feed rate, the M203 parameters will limit it + moveBuffer.feedRate = ConvertSpeedFromMmPerMin(DefaultG0FeedRate); // use maximum feed rate, the M203 parameters will limit it moveBuffer.usingStandardFeedrate = false; } @@ -1650,11 +1650,11 @@ const char * GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, bool isP moveBuffer.coords[drive] = 0.0; } moveBuffer.hasPositiveExtrusion = false; - moveBuffer.virtualExtruderPosition = virtualExtruderPosition; // save this before we update it + moveBuffer.virtualExtruderPosition = virtualExtruderPosition; // save this before we update it ExtrudersBitmap extrudersMoving; // Check if we are extruding - if (gb.Seen(extrudeLetter)) // DC 2018-08-07: at E3D's request, extrusion is now recognised even on uncoordinated moves + if (gb.Seen(extrudeLetter)) // DC 2018-08-07: at E3D's request, extrusion is now recognised even on uncoordinated moves { // Check that we have a tool to extrude with Tool* const tool = reprap.GetCurrentTool(); diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 34a8dd1e..22510e8a 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -2083,7 +2083,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx gb.GetFloatArray(eVals, eCount, true); for (size_t e = 0; e < eCount; e++) { - platform.SetAcceleration(ExtruderToLogicalDrive(e), GCodeBuffer::ConvertAcceleration(eVals[e])); + platform.SetAcceleration(ExtruderToLogicalDrive(e), ConvertAcceleration(eVals[e])); } } @@ -2096,13 +2096,13 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx reply.copy("Accelerations (mm/sec^2): "); for (size_t axis = 0; axis < numTotalAxes; ++axis) { - reply.catf("%c: %.1f, ", axisLetters[axis], (double)GCodeBuffer::InverseConvertAcceleration(platform.Acceleration(axis))); + reply.catf("%c: %.1f, ", axisLetters[axis], (double)InverseConvertAcceleration(platform.Acceleration(axis))); } reply.cat("E:"); char sep = ' '; for (size_t extruder = 0; extruder < numExtruders; extruder++) { - reply.catf("%c%.1f", sep, (double)GCodeBuffer::InverseConvertAcceleration(platform.Acceleration(ExtruderToLogicalDrive(extruder)))); + reply.catf("%c%.1f", sep, (double)InverseConvertAcceleration(platform.Acceleration(ExtruderToLogicalDrive(extruder)))); sep = ':'; } } @@ -2139,7 +2139,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx gb.GetFloatArray(eVals, eCount, true); for (size_t e = 0; e < eCount; e++) { - platform.SetMaxFeedrate(ExtruderToLogicalDrive(e), gb.ConvertSpeedFromMm(eVals[e], usingMmPerSec)); + platform.SetMaxFeedrate(ExtruderToLogicalDrive(e), ConvertSpeedFromMm(eVals[e], usingMmPerSec)); } } @@ -2152,16 +2152,16 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx reply.printf("Max speeds (%s)): ", (usingMmPerSec) ? "mm/sec" : "mm/min"); for (size_t axis = 0; axis < numTotalAxes; ++axis) { - reply.catf("%c: %.1f, ", axisLetters[axis], (double)gb.InverseConvertSpeedToMm(platform.MaxFeedrate(axis), usingMmPerSec)); + reply.catf("%c: %.1f, ", axisLetters[axis], (double)InverseConvertSpeedToMm(platform.MaxFeedrate(axis), usingMmPerSec)); } reply.cat("E:"); char sep = ' '; for (size_t extruder = 0; extruder < numExtruders; extruder++) { - reply.catf("%c%.1f", sep, (double)gb.InverseConvertSpeedToMm(platform.MaxFeedrate(ExtruderToLogicalDrive(extruder)), usingMmPerSec)); + reply.catf("%c%.1f", sep, (double)InverseConvertSpeedToMm(platform.MaxFeedrate(ExtruderToLogicalDrive(extruder)), usingMmPerSec)); sep = ':'; } - reply.catf(", min. speed %.2f", (double)gb.InverseConvertSpeedToMm(platform.MinMovementSpeed(), usingMmPerSec)); + reply.catf(", min. speed %.2f", (double)InverseConvertSpeedToMm(platform.MinMovementSpeed(), usingMmPerSec)); } } break; @@ -3298,7 +3298,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx gb.GetFloatArray(eVals, eCount, true); for (size_t e = 0; e < eCount; e++) { - platform.SetInstantDv(ExtruderToLogicalDrive(e), gb.ConvertSpeedFromMm(eVals[e], useMmPerSec)); + platform.SetInstantDv(ExtruderToLogicalDrive(e), ConvertSpeedFromMm(eVals[e], useMmPerSec)); } } @@ -3317,13 +3317,13 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx reply.printf("Maximum jerk rates (%s): ", (useMmPerSec) ? "mm/sec" : "mm/min"); for (size_t axis = 0; axis < numTotalAxes; ++axis) { - reply.catf("%c: %.1f, ", axisLetters[axis], (double)gb.InverseConvertSpeedToMm(platform.GetInstantDv(axis), useMmPerSec)); + reply.catf("%c: %.1f, ", axisLetters[axis], (double)InverseConvertSpeedToMm(platform.GetInstantDv(axis), useMmPerSec)); } reply.cat("E:"); char sep = ' '; for (size_t extruder = 0; extruder < numExtruders; extruder++) { - reply.catf("%c%.1f", sep, (double)gb.InverseConvertSpeedToMm(platform.GetInstantDv(ExtruderToLogicalDrive(extruder)), useMmPerSec)); + reply.catf("%c%.1f", sep, (double)InverseConvertSpeedToMm(platform.GetInstantDv(ExtruderToLogicalDrive(extruder)), useMmPerSec)); sep = ':'; } if (code == 566) @@ -3962,8 +3962,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx // Get the feedrate (if any) and kick off a new move if (gb.Seen(feedrateLetter)) { - const float rate = gb.ConvertDistance(gb.GetFValue()); - gb.LatestMachineState().feedRate = rate * SecondsToMinutes; // don't apply the speed factor + gb.LatestMachineState().feedRate = gb.GetSpeed(); // don't apply the speed factor } moveBuffer.feedRate = gb.LatestMachineState().feedRate; moveBuffer.usingStandardFeedrate = true; diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp index b48ae06b..7fc6069c 100644 --- a/src/GCodes/GCodes3.cpp +++ b/src/GCodes/GCodes3.cpp @@ -915,7 +915,7 @@ GCodeResult GCodes::ProbeTool(GCodeBuffer& gb, const StringRef& reply) THROWS(GC // Get the feed rate and axis gb.MustSee(feedrateLetter); - m585Settings.feedRate = gb.LatestMachineState().feedRate = gb.GetDistance() * SecondsToMinutes; // don't apply the speed factor to homing and other special moves + m585Settings.feedRate = gb.LatestMachineState().feedRate = gb.GetSpeed(); // don't apply the speed factor to homing and other special moves m585Settings.axisNumber = FindAxisLetter(gb); m585Settings.offset = gb.GetDistance(); @@ -1006,7 +1006,7 @@ GCodeResult GCodes::FindCenterOfCavity(GCodeBuffer& gb, const StringRef& reply) // Get the feed rate, backoff distance, and axis gb.MustSee(feedrateLetter); - m675Settings.feedRate = gb.LatestMachineState().feedRate = gb.GetDistance() * SecondsToMinutes; // don't apply the speed factor to homing and other special moves + m675Settings.feedRate = gb.LatestMachineState().feedRate = gb.GetSpeed(); // don't apply the speed factor to homing and other special moves m675Settings.backoffDistance = gb.Seen('R') ? gb.GetDistance() : 5.0; m675Settings.axisNumber = FindAxisLetter(gb); diff --git a/src/GCodes/RestorePoint.cpp b/src/GCodes/RestorePoint.cpp index edbfbf71..f197b25d 100644 --- a/src/GCodes/RestorePoint.cpp +++ b/src/GCodes/RestorePoint.cpp @@ -34,7 +34,7 @@ constexpr ObjectModelTableEntry RestorePoint::objectModelTable[] = { "coords", OBJECT_MODEL_FUNC_NOSELF(&coordinatesArrayDescriptor), ObjectModelEntryFlags::none }, { "extruderPos", OBJECT_MODEL_FUNC(self->virtualExtruderPosition, 1), ObjectModelEntryFlags::none }, { "fanPwm", OBJECT_MODEL_FUNC(self->fanSpeed, 2), ObjectModelEntryFlags::none }, - { "feedRate", OBJECT_MODEL_FUNC(self->feedRate, 1), ObjectModelEntryFlags::none }, + { "feedRate", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerSec(self->feedRate), 1), ObjectModelEntryFlags::none }, #if SUPPORT_IOBITS { "ioBits", OBJECT_MODEL_FUNC_IF(reprap.GetGCodes().GetMachineType() != MachineType::laser, (int32_t)self->laserPwmOrIoBits.ioBits), ObjectModelEntryFlags::none }, @@ -64,7 +64,7 @@ void RestorePoint::Init() noexcept moveCoords[i] = 0.0; } - feedRate = DefaultFeedRate * SecondsToMinutes; + feedRate = ConvertSpeedFromMmPerMin(DefaultFeedRate); virtualExtruderPosition = 0.0; filePos = noFilePosition; proportionDone = 0.0; diff --git a/src/Heating/Sensors/DhtSensor.cpp b/src/Heating/Sensors/DhtSensor.cpp index 82ddae7c..521e25bb 100644 --- a/src/Heating/Sensors/DhtSensor.cpp +++ b/src/Heating/Sensors/DhtSensor.cpp @@ -17,7 +17,7 @@ constexpr uint16_t MinimumReadInterval = 2000; // ms constexpr uint8_t MaximumReadTime = 20; // ms constexpr uint8_t MinimumOneBitLength = 50; // microseconds -constexpr uint32_t MinimumOneBitStepClocks = (StepTimer::StepClockRate * MinimumOneBitLength)/1000000; +constexpr uint32_t MinimumOneBitStepClocks = (StepClockRate * MinimumOneBitLength)/1000000; // Pulse ISR void DhtDataTransition(CallbackParameter cp) noexcept diff --git a/src/Libraries/Fatfs/diskio.cpp b/src/Libraries/Fatfs/diskio.cpp index 41b8e7fb..22687235 100644 --- a/src/Libraries/Fatfs/diskio.cpp +++ b/src/Libraries/Fatfs/diskio.cpp @@ -67,14 +67,14 @@ unsigned int DiskioGetAndClearMaxRetryCount() noexcept float DiskioGetAndClearLongestReadTime() noexcept { - const float ret = (float)longestReadTime * StepTimer::StepClocksToMillis; + const float ret = (float)longestReadTime * StepClocksToMillis; longestReadTime = 0; return ret; } float DiskioGetAndClearLongestWriteTime() noexcept { - const float ret = (float)longestWriteTime * StepTimer::StepClocksToMillis; + const float ret = (float)longestWriteTime * StepClocksToMillis; longestWriteTime = 0; return ret; } diff --git a/src/Movement/AxisShaper.cpp b/src/Movement/AxisShaper.cpp index d6eb636b..0b7d5d4f 100644 --- a/src/Movement/AxisShaper.cpp +++ b/src/Movement/AxisShaper.cpp @@ -39,7 +39,7 @@ AxisShaper::AxisShaper() noexcept : numExtraImpulses(0), frequency(DefaultFrequency), zeta(DefaultDamping), - minimumAcceleration(DefaultMinimumAcceleration/StepTimer::StepClockRateSquared), + minimumAcceleration(ConvertAcceleration(DefaultMinimumAcceleration)), type(InputShaperType::none) { } @@ -47,7 +47,7 @@ AxisShaper::AxisShaper() noexcept // Process M593 GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException) { - constexpr float MinimumInputShapingFrequency = (float)StepTimer::StepClockRate/(2 * 65535); // we use a 16-bit number of step clocks to represent half the input shaping period + constexpr float MinimumInputShapingFrequency = (float)StepClockRate/(2 * 65535); // we use a 16-bit number of step clocks to represent half the input shaping period constexpr float MaximumInputShapingFrequency = 1000.0; bool seen = false; if (gb.Seen('F')) @@ -58,7 +58,7 @@ GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROW if (gb.Seen('L')) { seen = true; - minimumAcceleration = max<float>(gb.GetFValue(), 1.0)/StepTimer::StepClockRateSquared; // very low accelerations cause problems with the maths + minimumAcceleration = ConvertAcceleration(max<float>(gb.GetFValue(), 1.0)); // very low accelerations cause problems with the maths } if (gb.Seen('S')) { @@ -93,7 +93,7 @@ GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROW { const float sqrtOneMinusZetaSquared = fastSqrtf(1.0 - fsquare(zeta)); const float dampedFrequency = frequency * sqrtOneMinusZetaSquared; - const float dampedPeriod = StepTimer::StepClockRate/dampedFrequency; + const float dampedPeriod = StepClockRate/dampedFrequency; const float k = expf(-zeta * Pi/sqrtOneMinusZetaSquared); switch (type.RawValue()) { @@ -123,7 +123,7 @@ GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROW } for (unsigned int i = 0; i < numAmplitudes; ++i) { - durations[i] *= StepTimer::StepClockRate; // convert from seconds to step clocks + durations[i] *= StepClockRate; // convert from seconds to step clocks } } else @@ -219,9 +219,9 @@ GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROW } } - minimumShapingStartOriginalClocks = totalShapingClocks - extraClocksAtStart + (MinimumMiddleSegmentTime * StepTimer::StepClockRate); - minimumShapingEndOriginalClocks = totalShapingClocks - extraClocksAtEnd + (MinimumMiddleSegmentTime * StepTimer::StepClockRate); - minimumNonOverlappedOriginalClocks = (totalShapingClocks * 2) - extraClocksAtStart - extraClocksAtEnd + (MinimumMiddleSegmentTime * StepTimer::StepClockRate); + minimumShapingStartOriginalClocks = totalShapingClocks - extraClocksAtStart + (MinimumMiddleSegmentTime * StepClockRate); + minimumShapingEndOriginalClocks = totalShapingClocks - extraClocksAtEnd + (MinimumMiddleSegmentTime * StepClockRate); + minimumNonOverlappedOriginalClocks = (totalShapingClocks * 2) - extraClocksAtStart - extraClocksAtEnd + (MinimumMiddleSegmentTime * StepClockRate); { float v = 0.0; @@ -278,7 +278,7 @@ GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROW else { reply.printf("Input shaping '%s' at %.1fHz damping factor %.2f, min. acceleration %.1f", - type.ToString(), (double)frequency, (double)zeta, (double)(minimumAcceleration * StepTimer::StepClockRateSquared)); + type.ToString(), (double)frequency, (double)zeta, (double)InverseConvertAcceleration(minimumAcceleration)); if (numExtraImpulses != 0) { reply.cat(", impulses"); @@ -289,7 +289,7 @@ GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROW reply.cat(" with durations (ms)"); for (unsigned int i = 0; i < numExtraImpulses; ++i) { - reply.catf(" %.2f", (double)(durations[i] * (1000.0/StepTimer::StepClockRate))); + reply.catf(" %.2f", (double)(durations[i] * StepClocksToMillis)); } } } @@ -485,17 +485,17 @@ void AxisShaper::PlanShaping(DDA& dda, PrepParams& params, bool shapingEnabled) if (params.shapingPlan.shapeAccelStart || params.shapingPlan.shapeAccelEnd || params.shapingPlan.shapeAccelOverlapped) { const float speedIncrease = dda.topSpeed - dda.startSpeed; - params.accelClocks = 2 * (dda.topSpeed * params.accelClocks - params.accelDistance * StepTimer::StepClockRate)/speedIncrease; - params.accelDistance = (dda.startSpeed + dda.topSpeed) * params.accelClocks/(2 * StepTimer::StepClockRate); - dda.acceleration = (speedIncrease * StepTimer::StepClockRate)/params.accelClocks; + params.accelClocks = 2 * (dda.topSpeed * params.accelClocks - params.accelDistance)/speedIncrease; + params.accelDistance = (dda.startSpeed + dda.topSpeed) * params.accelClocks * 0.5; + dda.acceleration = speedIncrease/params.accelClocks; } if (params.shapingPlan.shapeDecelStart || params.shapingPlan.shapeDecelEnd || params.shapingPlan.shapeDecelOverlapped) { const float speedDecrease = dda.endSpeed - dda.startSpeed; - params.decelClocks = 2 * (params.decelDistance * StepTimer::StepClockRate - dda.topSpeed * params.decelClocks)/speedDecrease; - params.decelDistance = (dda.topSpeed + dda.endSpeed) * params.decelClocks/(2 * StepTimer::StepClockRate); + params.decelClocks = 2 * (params.decelDistance - dda.topSpeed * params.decelClocks)/speedDecrease; + params.decelDistance = (dda.topSpeed + dda.endSpeed) * params.decelClocks * 0.5; params.decelStartDistance = dda.totalDistance - params.decelDistance; - dda.deceleration = (speedDecrease * StepTimer::StepClockRate)/params.decelClocks; + dda.deceleration = speedDecrease/params.decelClocks; } } else @@ -548,20 +548,20 @@ void AxisShaper::TryShapeAccelEnd(const DDA& dda, PrepParams& params) const noex void AxisShaper::TryShapeAccelBoth(DDA& dda, PrepParams& params) const noexcept { - if ((dda.topSpeed - dda.startSpeed)/StepTimer::StepClockRate <= overlappedDeltaVPerA * (dda.acceleration/StepTimer::StepClockRateSquared)) + if (dda.topSpeed - dda.startSpeed <= overlappedDeltaVPerA * dda.acceleration) { // We can use overlapped shaping - const float newAcceleration = ((dda.topSpeed - dda.startSpeed)/StepTimer::StepClockRate)/overlappedDeltaVPerA; + const float newAcceleration = (dda.topSpeed - dda.startSpeed)/overlappedDeltaVPerA; if (newAcceleration < minimumAcceleration) { return; } - const float newAccelDistance = ((dda.startSpeed/StepTimer::StepClockRate) * overlappedShapingClocks) + (newAcceleration * overlappedDistancePerA); + const float newAccelDistance = (dda.startSpeed * overlappedShapingClocks) + (newAcceleration * overlappedDistancePerA); if (newAccelDistance >= params.decelStartDistance) { return; } - dda.acceleration = newAcceleration * StepTimer::StepClockRateSquared; + dda.acceleration = newAcceleration; params.accelDistance = newAccelDistance; params.accelClocks = overlappedShapingClocks; params.shapingPlan.shapeAccelOverlapped = true; @@ -572,13 +572,13 @@ void AxisShaper::TryShapeAccelBoth(DDA& dda, PrepParams& params) const noexcept { // The speed change is too high to allow overlapping, but non-overlapped shaping will give a very short steady acceleration segment. // If we have enough spare distance, reduce the acceleration slightly to lengthen that segment. - const float newAcceleration = (dda.acceleration/StepTimer::StepClockRateSquared) * params.accelClocks/minimumNonOverlappedOriginalClocks; - const float newAccelDistance = ((dda.startSpeed/StepTimer::StepClockRate) + (0.5 * newAcceleration * minimumNonOverlappedOriginalClocks)) * minimumNonOverlappedOriginalClocks; + const float newAcceleration = (dda.acceleration * params.accelClocks)/minimumNonOverlappedOriginalClocks; + const float newAccelDistance = (dda.startSpeed + (0.5 * newAcceleration * minimumNonOverlappedOriginalClocks)) * minimumNonOverlappedOriginalClocks; if (newAccelDistance >= params.decelStartDistance) { return; } - dda.acceleration = newAcceleration * StepTimer::StepClockRateSquared; + dda.acceleration = newAcceleration; params.accelDistance = newAccelDistance; params.accelClocks = minimumNonOverlappedOriginalClocks; } @@ -631,21 +631,21 @@ void AxisShaper::TryShapeDecelEnd(const DDA& dda, PrepParams& params) const noex void AxisShaper::TryShapeDecelBoth(DDA& dda, PrepParams& params) const noexcept { - if ((dda.topSpeed - dda.endSpeed)/StepTimer::StepClockRate <= overlappedDeltaVPerA * (dda.deceleration/StepTimer::StepClockRateSquared)) + if (dda.topSpeed - dda.endSpeed <= overlappedDeltaVPerA * dda.deceleration) { // We can use overlapped shaping - const float newDeceleration = ((dda.topSpeed - dda.endSpeed)/StepTimer::StepClockRate)/overlappedDeltaVPerA; + const float newDeceleration = (dda.topSpeed - dda.endSpeed)/overlappedDeltaVPerA; if (newDeceleration < minimumAcceleration) { return; } - const float newDecelDistance = ((dda.topSpeed/StepTimer::StepClockRate) * overlappedShapingClocks) - (newDeceleration * overlappedDistancePerA); + const float newDecelDistance = (dda.topSpeed * overlappedShapingClocks) - (newDeceleration * overlappedDistancePerA); const float newDecelStartDistance = dda.totalDistance - newDecelDistance; if (newDecelStartDistance < params.accelDistance) { return; } - dda.deceleration = newDeceleration * StepTimer::StepClockRateSquared; + dda.deceleration = newDeceleration; params.decelDistance = newDecelDistance; params.decelStartDistance = newDecelStartDistance; params.decelClocks = overlappedShapingClocks; @@ -657,14 +657,14 @@ void AxisShaper::TryShapeDecelBoth(DDA& dda, PrepParams& params) const noexcept { // The speed change is too high to allow overlapping, but non-overlapped shaping will give a very short steady acceleration segment. // If we have enough spare distance, reduce the acceleration slightly to lengthen that segment. - const float newDeceleration = (dda.deceleration/StepTimer::StepClockRateSquared) * params.decelClocks/minimumNonOverlappedOriginalClocks; - const float newDecelDistance = ((dda.endSpeed/StepTimer::StepClockRate) + (0.5 * newDeceleration * minimumNonOverlappedOriginalClocks)) * minimumNonOverlappedOriginalClocks; + const float newDeceleration = (dda.deceleration * params.decelClocks)/minimumNonOverlappedOriginalClocks; + const float newDecelDistance = (dda.endSpeed + (0.5 * newDeceleration * minimumNonOverlappedOriginalClocks)) * minimumNonOverlappedOriginalClocks; const float newDecelStartDistance = dda.totalDistance - newDecelDistance; if (newDecelStartDistance <= params.accelDistance) { return; } - dda.deceleration = newDeceleration * StepTimer::StepClockRateSquared; + dda.deceleration = newDeceleration; params.decelStartDistance = newDecelStartDistance; params.decelClocks = overlappedShapingClocks; } @@ -678,15 +678,14 @@ MoveSegment *AxisShaper::GetAccelerationSegments(const DDA& dda, const PrepParam { if (dda.beforePrepare.accelDistance > 0.0) { - const float peakAcceleration = dda.acceleration/StepTimer::StepClockRateSquared; if (params.shapingPlan.shapeAccelOverlapped) { MoveSegment *accelSegs = nullptr; - float segStartSpeed = dda.topSpeed/StepTimer::StepClockRate; + float segStartSpeed = dda.topSpeed; for (int i = (2 * numExtraImpulses) - 1; i >= 0; --i) { accelSegs = MoveSegment::Allocate(accelSegs); - const float acceleration = peakAcceleration * overlappedCoefficients[i]; + const float acceleration = dda.acceleration * overlappedCoefficients[i]; const float segTime = overlappedDurations[i]; segStartSpeed -= acceleration * segTime; const float b = segStartSpeed/(-acceleration); @@ -703,11 +702,11 @@ MoveSegment *AxisShaper::GetAccelerationSegments(const DDA& dda, const PrepParam if (params.shapingPlan.shapeAccelEnd) { // Shape the end of the acceleration - float segStartSpeed = dda.topSpeed/StepTimer::StepClockRate; + float segStartSpeed = dda.topSpeed; for (int i = numExtraImpulses - 1; i >= 0; --i) { endAccelSegs = MoveSegment::Allocate(endAccelSegs); - const float acceleration = peakAcceleration * (1.0 - coefficients[i]); + const float acceleration = dda.acceleration * (1.0 - coefficients[i]); const float segTime = durations[i]; segStartSpeed -= acceleration * segTime; const float b = segStartSpeed/(-acceleration); @@ -720,7 +719,7 @@ MoveSegment *AxisShaper::GetAccelerationSegments(const DDA& dda, const PrepParam } float startDistance = 0.0; - float startSpeed = dda.startSpeed/StepTimer::StepClockRate; + float startSpeed = dda.startSpeed; MoveSegment *startAccelSegs = nullptr; if (params.shapingPlan.shapeAccelStart) { @@ -728,7 +727,7 @@ MoveSegment *AxisShaper::GetAccelerationSegments(const DDA& dda, const PrepParam for (unsigned int i = 0; i < numExtraImpulses; ++i) { MoveSegment *seg = MoveSegment::Allocate(nullptr); - const float acceleration = peakAcceleration * coefficients[i]; + const float acceleration = dda.acceleration * coefficients[i]; const float segTime = durations[i]; const float b = startSpeed/(-acceleration); const float c = 2.0/acceleration; @@ -752,8 +751,8 @@ MoveSegment *AxisShaper::GetAccelerationSegments(const DDA& dda, const PrepParam if (endDistance > startDistance) { endAccelSegs = MoveSegment::Allocate(endAccelSegs); - const float b = startSpeed/(-peakAcceleration); - const float c = 2.0/peakAcceleration; + const float b = startSpeed/(-dda.acceleration); + const float c = 2.0/dda.acceleration; endAccelSegs->SetNonLinear(endDistance - startDistance, params.accelClocks - accumulatedSegTime, b, c); } @@ -777,15 +776,14 @@ MoveSegment *AxisShaper::GetDecelerationSegments(const DDA& dda, const PrepParam { if (dda.beforePrepare.decelDistance > 0.0) { - const float peakDeceleration = dda.deceleration/StepTimer::StepClockRateSquared; if (params.shapingPlan.shapeDecelOverlapped) { MoveSegment *decelSegs = nullptr; - float segStartSpeed = dda.endSpeed/StepTimer::StepClockRate; + float segStartSpeed = dda.endSpeed; for (int i = (2 * numExtraImpulses) - 1; i >= 0; --i) { decelSegs = MoveSegment::Allocate(decelSegs); - const float deceleration = peakDeceleration * overlappedCoefficients[i]; + const float deceleration = dda.deceleration * overlappedCoefficients[i]; const float segTime = overlappedDurations[i]; segStartSpeed += deceleration * segTime; const float b = segStartSpeed/deceleration; @@ -802,11 +800,11 @@ MoveSegment *AxisShaper::GetDecelerationSegments(const DDA& dda, const PrepParam if (params.shapingPlan.shapeDecelEnd) { // Shape the end of the deceleration - float segStartSpeed = dda.endSpeed/StepTimer::StepClockRate; + float segStartSpeed = dda.endSpeed; for (int i = numExtraImpulses - 1; i >= 0; --i) { endDecelSegs = MoveSegment::Allocate(endDecelSegs); - const float deceleration = peakDeceleration * (1.0 - coefficients[i]); + const float deceleration = dda.deceleration * (1.0 - coefficients[i]); const float segTime = durations[i]; segStartSpeed += deceleration * segTime; const float b = segStartSpeed/deceleration; @@ -819,7 +817,7 @@ MoveSegment *AxisShaper::GetDecelerationSegments(const DDA& dda, const PrepParam } float startDistance = params.decelStartDistance; - float startSpeed = dda.topSpeed/StepTimer::StepClockRate; + float startSpeed = dda.topSpeed; MoveSegment *startDecelSegs = nullptr; if (params.shapingPlan.shapeDecelStart) { @@ -827,7 +825,7 @@ MoveSegment *AxisShaper::GetDecelerationSegments(const DDA& dda, const PrepParam for (unsigned int i = 0; i < numExtraImpulses; ++i) { MoveSegment *seg = MoveSegment::Allocate(nullptr); - const float deceleration = peakDeceleration * coefficients[i]; + const float deceleration = dda.deceleration * coefficients[i]; const float segTime = durations[i]; const float b = startSpeed/deceleration; const float c = -2.0/deceleration; @@ -851,8 +849,8 @@ MoveSegment *AxisShaper::GetDecelerationSegments(const DDA& dda, const PrepParam if (endDistance > startDistance) { endDecelSegs = MoveSegment::Allocate(endDecelSegs); - const float b = startSpeed/peakDeceleration; - const float c = -2.0/peakDeceleration; + const float b = startSpeed/dda.deceleration; + const float c = -2.0/dda.deceleration; endDecelSegs->SetNonLinear(endDistance - startDistance, params.decelClocks - accumulatedSegTime, b, c); } @@ -879,7 +877,7 @@ MoveSegment *AxisShaper::FinishSegments(const DDA& dda, const PrepParams& params { // Insert a steady speed segment before the deceleration segments decelSegs = MoveSegment::Allocate(decelSegs); - const float c = StepTimer::StepClockRate/dda.topSpeed; + const float c = 1.0/dda.topSpeed; decelSegs->SetLinear(params.decelStartDistance - params.accelDistance, params.steadyClocks, c); } @@ -898,24 +896,24 @@ MoveSegment *AxisShaper::FinishSegments(const DDA& dda, const PrepParams& params // Calculate the additional acceleration distance needed if we shape the start of acceleration inline float AxisShaper::GetExtraAccelStartDistance(const DDA& dda) const noexcept { - return ((extraClocksAtStart * dda.startSpeed)/StepTimer::StepClockRate) + ((extraDistanceAtStart * dda.acceleration)/StepTimer::StepClockRateSquared); + return (extraClocksAtStart * dda.startSpeed) + (extraDistanceAtStart * dda.acceleration); } // Calculate the additional acceleration distance needed if we shape the end of acceleration inline float AxisShaper::GetExtraAccelEndDistance(const DDA& dda) const noexcept { - return ((extraClocksAtEnd * dda.topSpeed)/StepTimer::StepClockRate) + ((extraDistanceAtEnd * dda.acceleration)/StepTimer::StepClockRateSquared); + return (extraClocksAtEnd * dda.topSpeed) + (extraDistanceAtEnd * dda.acceleration); } inline float AxisShaper::GetExtraDecelStartDistance(const DDA& dda) const noexcept { - return ((extraClocksAtStart * dda.topSpeed)/StepTimer::StepClockRate) - ((extraDistanceAtStart * dda.deceleration)/StepTimer::StepClockRateSquared); + return (extraClocksAtStart * dda.topSpeed) - (extraDistanceAtStart * dda.deceleration); } // Calculate the additional deceleration distance needed if we shape the end of deceleration inline float AxisShaper::GetExtraDecelEndDistance(const DDA& dda) const noexcept { - return ((extraClocksAtEnd * dda.endSpeed)/StepTimer::StepClockRate) - ((extraDistanceAtEnd * dda.deceleration)/StepTimer::StepClockRateSquared); + return (extraClocksAtEnd * dda.endSpeed) - (extraDistanceAtEnd * dda.deceleration); } /*static*/ MoveSegment *AxisShaper::GetUnshapedSegments(DDA& dda, const PrepParams& params) noexcept @@ -925,8 +923,8 @@ inline float AxisShaper::GetExtraDecelEndDistance(const DDA& dda) const noexcept if (params.decelClocks > 0.0) { tempSegments = MoveSegment::Allocate(nullptr); - const float b = (dda.topSpeed * StepTimer::StepClockRate)/dda.deceleration; - const float c = (2 * StepTimer::StepClockRateSquared)/(-dda.deceleration); + const float b = dda.topSpeed/dda.deceleration; + const float c = -2.0/dda.deceleration; tempSegments->SetNonLinear(params.decelDistance, params.decelClocks, b, c); } else @@ -938,7 +936,7 @@ inline float AxisShaper::GetExtraDecelEndDistance(const DDA& dda) const noexcept if (params.steadyClocks > 0.0) { tempSegments = MoveSegment::Allocate(tempSegments); - const float c = StepTimer::StepClockRate/dda.topSpeed; + const float c = 1.0/dda.topSpeed; tempSegments->SetLinear(params.decelStartDistance - params.accelDistance, params.steadyClocks, c); } @@ -946,8 +944,8 @@ inline float AxisShaper::GetExtraDecelEndDistance(const DDA& dda) const noexcept if (params.accelClocks > 0.0) { tempSegments = MoveSegment::Allocate(tempSegments); - const float b = (dda.startSpeed * StepTimer::StepClockRate)/(-dda.acceleration); - const float c = (2 * StepTimer::StepClockRateSquared)/dda.acceleration; + const float b = dda.startSpeed/(-dda.acceleration); + const float c = 2.0/dda.acceleration; tempSegments->SetNonLinear(params.accelDistance, params.accelClocks, b, c); } diff --git a/src/Movement/DDA.cpp b/src/Movement/DDA.cpp index c084b6b1..f3596640 100644 --- a/src/Movement/DDA.cpp +++ b/src/Movement/DDA.cpp @@ -123,8 +123,8 @@ void PrepParams::SetFromDDA(const DDA& dda) noexcept // Due to rounding error, for an accelerate-decelerate move we may have accelDistance+decelDistance slightly greater than totalDistance. // We need to make sure that accelDistance <= decelStartDistance for subsequent calculations to work. accelDistance = min<float>(dda.beforePrepare.accelDistance, decelStartDistance); - accelClocks = ((dda.topSpeed - dda.startSpeed) * StepTimer::StepClockRate)/dda.acceleration; - decelClocks = ((dda.topSpeed - dda.endSpeed) * StepTimer::StepClockRate)/dda.deceleration; + accelClocks = (dda.topSpeed - dda.startSpeed)/dda.acceleration; + decelClocks = (dda.topSpeed - dda.endSpeed)/dda.deceleration; #if SUPPORT_CAN_EXPANSION initialSpeedFraction = dda.startSpeed/dda.topSpeed; @@ -136,7 +136,7 @@ void PrepParams::SetFromDDA(const DDA& dda) noexcept void PrepParams::Finalise(DDA& dda) noexcept { const float steadyDistance = decelStartDistance - accelDistance; - steadyClocks = (steadyDistance <= 0.0) ? 0.0 : (steadyDistance * StepTimer::StepClockRate)/dda.topSpeed; + steadyClocks = (steadyDistance <= 0.0) ? 0.0 : steadyDistance/dda.topSpeed; dda.clocksNeeded = (uint32_t)(accelClocks + decelClocks + steadyClocks); } @@ -700,16 +700,16 @@ bool DDA::InitFromRemote(const CanMessageMovementLinear& msg) noexcept // Normalise the move to unit distance and convert time units from step clocks to seconds totalDistance = 1.0; - topSpeed = (2.0 * StepTimer::StepClockRate)/(2 * msg.steadyClocks + (msg.initialSpeedFraction + 1.0) * msg.accelerationClocks + (msg.finalSpeedFraction + 1.0) * msg.decelClocks); + topSpeed = 2.0/(2 * msg.steadyClocks + (msg.initialSpeedFraction + 1.0) * msg.accelerationClocks + (msg.finalSpeedFraction + 1.0) * msg.decelClocks); startSpeed = topSpeed * msg.initialSpeedFraction; endSpeed = topSpeed * msg.finalSpeedFraction; - acceleration = (msg.accelerationClocks == 0) ? 0.0 : (topSpeed * (1.0 - msg.initialSpeedFraction) * StepTimer::StepClockRate)/msg.accelerationClocks; - deceleration = (msg.decelClocks == 0) ? 0.0 : (topSpeed * (1.0 - msg.finalSpeedFraction) * StepTimer::StepClockRate)/msg.decelClocks; + acceleration = (msg.accelerationClocks == 0) ? 0.0 : (topSpeed * (1.0 - msg.initialSpeedFraction))/msg.accelerationClocks; + deceleration = (msg.decelClocks == 0) ? 0.0 : (topSpeed * (1.0 - msg.finalSpeedFraction))/msg.decelClocks; PrepParams params; - params.accelDistance = topSpeed * (1.0 + msg.initialSpeedFraction) * msg.accelerationClocks/(2 * StepTimer::StepClockRate); - params.decelDistance = topSpeed * (1.0 + msg.finalSpeedFraction) * msg.decelClocks/(2 * StepTimer::StepClockRate); + params.accelDistance = topSpeed * (1.0 + msg.initialSpeedFraction) * msg.accelerationClocks * 0.5; + params.decelDistance = topSpeed * (1.0 + msg.finalSpeedFraction) * msg.decelClocks * 0.5; params.decelStartDistance = 1.0 - params.decelDistance; params.accelClocks = msg.accelerationClocks; params.steadyClocks = msg.steadyClocks; @@ -1187,7 +1187,7 @@ void DDA::RecalculateMove(DDARing& ring) noexcept const float totalTime = (topSpeed - startSpeed)/acceleration + (topSpeed - endSpeed)/deceleration + (totalDistance - beforePrepare.accelDistance - beforePrepare.decelDistance)/topSpeed; - clocksNeeded = (uint32_t)(totalTime * StepTimer::StepClockRate); + clocksNeeded = (uint32_t)totalTime; } // Decide what speed we would really like this move to end at. @@ -1523,7 +1523,7 @@ void DDA::Prepare(uint8_t simMode) noexcept if (platform.GetExtrusionCoefficients(extruder, a, b, limit)) { float& dv = directionVector[drive]; - const float averageExtrusionSpeed = (totalDistance * dv * StepTimer::StepClockRate)/clocksNeeded; + const float averageExtrusionSpeed = (totalDistance * dv)/clocksNeeded; const float factor = 1.0 + min<float>((averageExtrusionSpeed * a) + (averageExtrusionSpeed * averageExtrusionSpeed * b), limit); dv *= factor; } @@ -2249,8 +2249,7 @@ uint32_t DDA::ManageLaserPower() const noexcept return LaserPwmIntervalMillis; } - const float timeMoving = (float)clocksMoving * (1.0/(float)StepTimer::StepClockRate); - const float accelSpeed = startSpeed + acceleration * timeMoving; + const float accelSpeed = startSpeed + acceleration * clocksMoving; if (accelSpeed < topSpeed) { // Acceleration phase @@ -2260,7 +2259,7 @@ uint32_t DDA::ManageLaserPower() const noexcept } const uint32_t clocksLeft = clocksNeeded - clocksMoving; - const float decelSpeed = endSpeed + deceleration * (float)clocksLeft * (1.0/(float)StepTimer::StepClockRate); + const float decelSpeed = endSpeed + deceleration * clocksLeft; if (decelSpeed < topSpeed) { // Deceleration phase @@ -2271,13 +2270,13 @@ uint32_t DDA::ManageLaserPower() const noexcept // We must be in the constant speed phase platform.SetLaserPwm(laserPwmOrIoBits.laserPwm); - const uint32_t decelClocks = ((topSpeed - endSpeed)/deceleration) * StepTimer::StepClockRate; + const uint32_t decelClocks = (topSpeed - endSpeed)/deceleration; if (clocksLeft <= decelClocks) { return LaserPwmIntervalMillis; } const uint32_t clocksToDecel = clocksLeft - decelClocks; - return lrintf((float)clocksToDecel * StepTimer::StepClocksToMillis) + LaserPwmIntervalMillis; + return lrintf((float)clocksToDecel * StepClocksToMillis) + LaserPwmIntervalMillis; } #endif diff --git a/src/Movement/DDA.h b/src/Movement/DDA.h index ae11df2e..d9c06a45 100644 --- a/src/Movement/DDA.h +++ b/src/Movement/DDA.h @@ -187,25 +187,25 @@ public: // Note: the above measurements were taken some time ago, before some firmware optimisations. #if SAME70 // Use the same defaults as for the SAM4E for now. - static constexpr uint32_t MinCalcInterval = (40 * StepTimer::StepClockRate)/1000000; // same as delta for now, but could be lower - static constexpr uint32_t HiccupTime = (30 * StepTimer::StepClockRate)/1000000; // how long we hiccup for in step timer clocks + static constexpr uint32_t MinCalcInterval = (40 * StepClockRate)/1000000; // same as delta for now, but could be lower + static constexpr uint32_t HiccupTime = (30 * StepClockRate)/1000000; // how long we hiccup for in step timer clocks #elif SAM4E || SAM4S || SAME5x - static constexpr uint32_t MinCalcIntervalDelta = (40 * StepTimer::StepClockRate)/1000000; // the smallest sensible interval between calculations (40us) in step timer clocks - static constexpr uint32_t MinCalcInterval = (40 * StepTimer::StepClockRate)/1000000; // same as delta for now, but could be lower - static constexpr uint32_t HiccupTime = (30 * StepTimer::StepClockRate)/1000000; // how long we hiccup for in step timer clocks + static constexpr uint32_t MinCalcIntervalDelta = (40 * StepClockRate)/1000000; // the smallest sensible interval between calculations (40us) in step timer clocks + static constexpr uint32_t MinCalcInterval = (40 * StepClockRate)/1000000; // same as delta for now, but could be lower + static constexpr uint32_t HiccupTime = (30 * StepClockRate)/1000000; // how long we hiccup for in step timer clocks #elif defined(__LPC17xx__) - static constexpr uint32_t MinCalcInterval = (40 * StepTimer::StepClockRate)/1000000; // same as delta for now, but could be lower - static constexpr uint32_t HiccupTime = (30 * StepTimer::StepClockRate)/1000000; // how long we hiccup for in step timer clocks + static constexpr uint32_t MinCalcInterval = (40 * StepClockRate)/1000000; // same as delta for now, but could be lower + static constexpr uint32_t HiccupTime = (30 * StepClockRate)/1000000; // how long we hiccup for in step timer clocks #else // SAM3X - static constexpr uint32_t MinCalcInterval = (60 * StepTimer::StepClockRate)/1000000; // same as delta for now, but could be lower - static constexpr uint32_t HiccupTime = (40 * StepTimer::StepClockRate)/1000000; // how long we hiccup for in step timer clocks + static constexpr uint32_t MinCalcInterval = (60 * StepClockRate)/1000000; // same as delta for now, but could be lower + static constexpr uint32_t HiccupTime = (40 * StepClockRate)/1000000; // how long we hiccup for in step timer clocks #endif - static constexpr uint32_t MaxStepInterruptTime = 10 * StepTimer::MinInterruptInterval; // the maximum time we spend looping in the ISR , in step clocks - static constexpr uint32_t WakeupTime = (100 * StepTimer::StepClockRate)/1000000; // stop resting 100us before the move is due to end - static constexpr uint32_t HiccupIncrement = HiccupTime/2; // how much we increase the hiccup time by on each attempt + static constexpr uint32_t MaxStepInterruptTime = 10 * StepTimer::MinInterruptInterval; // the maximum time we spend looping in the ISR , in step clocks + static constexpr uint32_t WakeupTime = (100 * StepClockRate)/1000000; // stop resting 100us before the move is due to end + static constexpr uint32_t HiccupIncrement = HiccupTime/2; // how much we increase the hiccup time by on each attempt - static constexpr uint32_t UsualMinimumPreparedTime = StepTimer::StepClockRate/10; // 100ms - static constexpr uint32_t AbsoluteMinimumPreparedTime = StepTimer::StepClockRate/20; // 50ms + static constexpr uint32_t UsualMinimumPreparedTime = StepClockRate/10; // 100ms + static constexpr uint32_t AbsoluteMinimumPreparedTime = StepClockRate/20; // 50ms #if DDA_LOG_PROBE_CHANGES static const size_t MaxLoggedProbePositions = 40; diff --git a/src/Movement/DDARing.cpp b/src/Movement/DDARing.cpp index ea4341fa..03789657 100644 --- a/src/Movement/DDARing.cpp +++ b/src/Movement/DDARing.cpp @@ -212,7 +212,7 @@ bool DDARing::CanAddMove() const noexcept prevMoveTime = dda->GetClocksNeeded(); } - return (unPreparedTime < StepTimer::StepClockRate/2 || unPreparedTime + prevMoveTime < 2 * StepTimer::StepClockRate); + return (unPreparedTime < StepClockRate/2 || unPreparedTime + prevMoveTime < 2 * StepClockRate); } return false; } @@ -266,7 +266,7 @@ void DDARing::Spin(uint8_t simulationMode, bool shouldStartMove) noexcept // Do this here rather than at the end, so that when simulating, currentDda is non-null for most of the time and IsExtruding() returns the correct value if (simulationMode != 0 && cdda != nullptr) { - simulationTime += (float)cdda->GetClocksNeeded()/StepTimer::StepClockRate; + simulationTime += (float)cdda->GetClocksNeeded() * (1.0/StepClockRate); cdda->Complete(); CurrentMoveCompleted(); cdda = currentDda; diff --git a/src/Movement/DriveMovement.cpp b/src/Movement/DriveMovement.cpp index d071595a..73f5327a 100644 --- a/src/Movement/DriveMovement.cpp +++ b/src/Movement/DriveMovement.cpp @@ -382,10 +382,8 @@ bool DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params) no if (dda.flags.usePressureAdvance && shaper.GetK() > 0.0) { // We are using nonzero pressure advance. Movement must be forwards. - const float acceleration = dda.acceleration * (1.0/StepTimer::StepClockRateSquared); - const float deceleration = dda.deceleration * (1.0/StepTimer::StepClockRateSquared); - mp.cart.pressureAdvanceK = shaper.GetK() * StepTimer::StepClockRate; - mp.cart.extraExtrusionDistance = mp.cart.pressureAdvanceK * acceleration * params.accelClocks; + mp.cart.pressureAdvanceK = shaper.GetK() * StepClockRate; + mp.cart.extraExtrusionDistance = mp.cart.pressureAdvanceK * dda.acceleration * params.accelClocks; forwardDistance += mp.cart.extraExtrusionDistance; // Check if there is a reversal in the deceleration segment @@ -403,12 +401,12 @@ bool DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params) no } else { - const float initialDecelSpeed = (dda.topSpeed * (1.0/StepTimer::StepClockRate)) - mp.cart.pressureAdvanceK * deceleration; + const float initialDecelSpeed = dda.topSpeed - mp.cart.pressureAdvanceK * dda.deceleration; if (initialDecelSpeed <= 0.0) { // The entire deceleration segment is in reverse forwardDistance += params.decelStartDistance; - reverseDistance = ((0.5 * deceleration * params.decelClocks) - initialDecelSpeed) * params.decelClocks; + reverseDistance = ((0.5 * dda.deceleration * params.decelClocks) - initialDecelSpeed) * params.decelClocks; } else { @@ -416,14 +414,14 @@ bool DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params) no if (timeToReverse < params.decelClocks) { // There is a reversal - const float distanceToReverse = 0.5 * deceleration * fsquare(timeToReverse); + const float distanceToReverse = 0.5 * dda.deceleration * fsquare(timeToReverse); forwardDistance += params.decelStartDistance + distanceToReverse; - reverseDistance = 0.5 * deceleration * fsquare(params.decelClocks - timeToReverse); + reverseDistance = 0.5 * dda.deceleration * fsquare(params.decelClocks - timeToReverse); } else { // No reversal - forwardDistance += dda.totalDistance - (mp.cart.pressureAdvanceK * deceleration * params.decelClocks); + forwardDistance += dda.totalDistance - (mp.cart.pressureAdvanceK * dda.deceleration * params.decelClocks); reverseDistance = 0.0; } } diff --git a/src/Movement/Move.cpp b/src/Movement/Move.cpp index c01098f8..94707367 100644 --- a/src/Movement/Move.cpp +++ b/src/Movement/Move.cpp @@ -94,11 +94,11 @@ constexpr ObjectModelTableEntry Move::objectModelTable[] = { "extruders", OBJECT_MODEL_FUNC_NOSELF(&extrudersArrayDescriptor), ObjectModelEntryFlags::live }, { "idle", OBJECT_MODEL_FUNC(self, 1), ObjectModelEntryFlags::none }, { "kinematics", OBJECT_MODEL_FUNC(self->kinematics), ObjectModelEntryFlags::none }, - { "printingAcceleration", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertAcceleration(self->maxPrintingAcceleration), 1), ObjectModelEntryFlags::none }, + { "printingAcceleration", OBJECT_MODEL_FUNC(InverseConvertAcceleration(self->maxPrintingAcceleration), 1), ObjectModelEntryFlags::none }, { "queue", OBJECT_MODEL_FUNC_NOSELF(&queueArrayDescriptor), ObjectModelEntryFlags::none }, { "shaping", OBJECT_MODEL_FUNC(&self->axisShaper, 0), ObjectModelEntryFlags::none }, { "speedFactor", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetSpeedFactor(), 2), ObjectModelEntryFlags::none }, - { "travelAcceleration", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertAcceleration(self->maxTravelAcceleration), 1), ObjectModelEntryFlags::none }, + { "travelAcceleration", OBJECT_MODEL_FUNC(InverseConvertAcceleration(self->maxTravelAcceleration), 1), ObjectModelEntryFlags::none }, { "virtualEPos", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetVirtualExtruderPosition(), 5), ObjectModelEntryFlags::live }, { "workplaceNumber", OBJECT_MODEL_FUNC_NOSELF((int32_t)reprap.GetGCodes().GetWorkplaceCoordinateSystemNumber() - 1), ObjectModelEntryFlags::none }, { "workspaceNumber", OBJECT_MODEL_FUNC_NOSELF((int32_t)reprap.GetGCodes().GetWorkplaceCoordinateSystemNumber()), ObjectModelEntryFlags::obsolete }, @@ -108,14 +108,14 @@ constexpr ObjectModelTableEntry Move::objectModelTable[] = { "timeout", OBJECT_MODEL_FUNC(0.001f * (float)self->idleTimeout, 1), ObjectModelEntryFlags::none }, // 2. move.currentMove members - { "acceleration", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertAcceleration(self->GetAcceleration()), 1), ObjectModelEntryFlags::live }, - { "deceleration", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertAcceleration(self->GetDeceleration()), 1), ObjectModelEntryFlags::live }, + { "acceleration", OBJECT_MODEL_FUNC(InverseConvertAcceleration(self->GetAcceleration()), 1), ObjectModelEntryFlags::live }, + { "deceleration", OBJECT_MODEL_FUNC(InverseConvertAcceleration(self->GetDeceleration()), 1), ObjectModelEntryFlags::live }, # if SUPPORT_LASER { "laserPwm", OBJECT_MODEL_FUNC_IF_NOSELF(reprap.GetGCodes().GetMachineType() == MachineType::laser, reprap.GetPlatform().GetLaserPwm(), 2), ObjectModelEntryFlags::live }, # endif - { "requestedSpeed", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->GetRequestedSpeed(), true), 1), ObjectModelEntryFlags::live }, - { "topSpeed", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->GetTopSpeed(), true), 1), ObjectModelEntryFlags::live }, + { "requestedSpeed", OBJECT_MODEL_FUNC(InverseConvertSpeedToMm(self->GetRequestedSpeed(), true), 1), ObjectModelEntryFlags::live }, + { "topSpeed", OBJECT_MODEL_FUNC(InverseConvertSpeedToMm(self->GetTopSpeed(), true), 1), ObjectModelEntryFlags::live }, // 3. move.calibration members { "final", OBJECT_MODEL_FUNC(self, 5), ObjectModelEntryFlags::none }, @@ -993,7 +993,7 @@ GCodeResult Move::ConfigureAccelerations(GCodeBuffer&gb, const StringRef& reply) else { reply.printf("Maximum printing acceleration %.1f, maximum travel acceleration %.1f mm/sec^2", - (double)gb.InverseConvertAcceleration(maxPrintingAcceleration), (double)gb.InverseConvertAcceleration(maxTravelAcceleration)); + (double)InverseConvertAcceleration(maxPrintingAcceleration), (double)InverseConvertAcceleration(maxTravelAcceleration)); } return GCodeResult::ok; } diff --git a/src/Movement/StepTimer.h b/src/Movement/StepTimer.h index 8a2fcda6..f0080cd7 100644 --- a/src/Movement/StepTimer.h +++ b/src/Movement/StepTimer.h @@ -63,18 +63,7 @@ public: // ISR called from StepTimer static void Interrupt() noexcept; -#if SAME70 || SAME5x - // All Duet 3 boards use a common step clock rate of 750kHz so that we can sync the clocks over CAN - static constexpr uint32_t StepClockRate = 48000000/64; // 750kHz -#elif defined(__LPC17xx__) - static constexpr uint32_t StepClockRate = 1000000; // 1MHz -#else - static constexpr uint32_t StepClockRate = SystemCoreClockFreq/128; // Duet 2 and Maestro: use just under 1MHz -#endif - - static constexpr uint64_t StepClockRateSquared = (uint64_t)StepClockRate * StepClockRate; - static constexpr float StepClocksToMillis = 1000.0/(float)StepClockRate; - static constexpr uint32_t MinInterruptInterval = 6; // about 6us + static constexpr uint32_t MinInterruptInterval = 6; // Minimum interval between step timer interrupts, in step clocks; about 6us #if SUPPORT_REMOTE_COMMANDS static uint32_t GetLocalTimeOffset() noexcept { return localTimeOffset; } diff --git a/src/Movement/StepperDrivers/TMC51xx.cpp b/src/Movement/StepperDrivers/TMC51xx.cpp index 5f1c72ed..e796a0f4 100644 --- a/src/Movement/StepperDrivers/TMC51xx.cpp +++ b/src/Movement/StepperDrivers/TMC51xx.cpp @@ -829,7 +829,7 @@ void TmcDriverState::SetStallDetectFilter(bool sgFilter) noexcept void TmcDriverState::SetStallMinimumStepsPerSecond(unsigned int stepsPerSecond) noexcept { //TODO use hardware facility instead - maxStallStepInterval = StepTimer::StepClockRate/max<unsigned int>(stepsPerSecond, 1); + maxStallStepInterval = StepClockRate/max<unsigned int>(stepsPerSecond, 1); } void TmcDriverState::AppendStallConfig(const StringRef& reply) const noexcept @@ -840,7 +840,7 @@ void TmcDriverState::AppendStallConfig(const StringRef& reply) const noexcept { threshold -= 128; } - const uint32_t fullstepsPerSecond = StepTimer::StepClockRate/maxStallStepInterval; + const uint32_t fullstepsPerSecond = StepClockRate/maxStallStepInterval; const float speed1 = ((fullstepsPerSecond << microstepShiftFactor)/reprap.GetPlatform().DriveStepsPerUnit(axisNumber)); const uint32_t tcoolthrs = writeRegisters[WriteTcoolthrs] & ((1ul << 20) - 1u); bool bdummy; @@ -929,7 +929,7 @@ void TmcDriverState::TransferSucceeded(const uint8_t *rcvDataBlock) noexcept { if ( (regVal & TMC_RR_STST) != 0 || interval == 0 - || interval > StepTimer::StepClockRate/MinimumOpenLoadFullStepsPerSec + || interval > StepClockRate/MinimumOpenLoadFullStepsPerSec || motorCurrent < MinimumOpenLoadMotorCurrent ) { diff --git a/src/Networking/Network.cpp b/src/Networking/Network.cpp index 3da1528c..887b3f78 100644 --- a/src/Networking/Network.cpp +++ b/src/Networking/Network.cpp @@ -551,7 +551,7 @@ void Network::Diagnostics(MessageType mtype) noexcept #if HAS_NETWORKING platform.Message(mtype, "=== Network ===\n"); - platform.MessageF(mtype, "Slowest loop: %.2fms; fastest: %.2fms\n", (double)(slowLoop * StepTimer::StepClocksToMillis), (double)(fastLoop * StepTimer::StepClocksToMillis)); + platform.MessageF(mtype, "Slowest loop: %.2fms; fastest: %.2fms\n", (double)(slowLoop * StepClocksToMillis), (double)(fastLoop * StepClocksToMillis)); fastLoop = UINT32_MAX; slowLoop = 0; diff --git a/src/Platform/Platform.cpp b/src/Platform/Platform.cpp index f532f322..e2c4091a 100644 --- a/src/Platform/Platform.cpp +++ b/src/Platform/Platform.cpp @@ -265,12 +265,12 @@ constexpr ObjectModelTableEntry Platform::objectModelTable[] = #endif // 3. move.axes[] members - { "acceleration", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertAcceleration(self->Acceleration(context.GetLastIndex())), 1), ObjectModelEntryFlags::none }, + { "acceleration", OBJECT_MODEL_FUNC(InverseConvertAcceleration(self->Acceleration(context.GetLastIndex())), 1), ObjectModelEntryFlags::none }, { "babystep", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetTotalBabyStepOffset(context.GetLastIndex()), 3), ObjectModelEntryFlags::none }, { "current", OBJECT_MODEL_FUNC((int32_t)lrintf(self->GetMotorCurrent(context.GetLastIndex(), 906))), ObjectModelEntryFlags::none }, { "drivers", OBJECT_MODEL_FUNC_NOSELF(&axisDriversArrayDescriptor), ObjectModelEntryFlags::none }, { "homed", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().IsAxisHomed(context.GetLastIndex())), ObjectModelEntryFlags::none }, - { "jerk", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->GetInstantDv(context.GetLastIndex()), false), 1), ObjectModelEntryFlags::none }, + { "jerk", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerMin(self->GetInstantDv(context.GetLastIndex())), 1), ObjectModelEntryFlags::none }, { "letter", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetAxisLetters()[context.GetLastIndex()]), ObjectModelEntryFlags::none }, { "machinePosition", OBJECT_MODEL_FUNC_NOSELF(reprap.GetMove().LiveCoordinate(context.GetLastIndex(), reprap.GetCurrentTool()), 3), ObjectModelEntryFlags::live }, { "max", OBJECT_MODEL_FUNC(self->AxisMaximum(context.GetLastIndex()), 2), ObjectModelEntryFlags::none }, @@ -278,7 +278,7 @@ constexpr ObjectModelTableEntry Platform::objectModelTable[] = { "microstepping", OBJECT_MODEL_FUNC(self, 7), ObjectModelEntryFlags::none }, { "min", OBJECT_MODEL_FUNC(self->AxisMinimum(context.GetLastIndex()), 2), ObjectModelEntryFlags::none }, { "minProbed", OBJECT_MODEL_FUNC(self->axisMinimaProbed.IsBitSet(context.GetLastIndex())), ObjectModelEntryFlags::none }, - { "speed", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->MaxFeedrate(context.GetLastIndex()), false), 1), ObjectModelEntryFlags::none }, + { "speed", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerMin(self->MaxFeedrate(context.GetLastIndex())), 1), ObjectModelEntryFlags::none }, { "stepsPerMm", OBJECT_MODEL_FUNC(self->driveStepsPerUnit[context.GetLastIndex()], 2), ObjectModelEntryFlags::none }, { "userPosition", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetUserCoordinate(context.GetLastIndex()), 3), ObjectModelEntryFlags::live }, { "visible", OBJECT_MODEL_FUNC_NOSELF(context.GetLastIndex() < (int32_t)reprap.GetGCodes().GetVisibleAxes()), ObjectModelEntryFlags::none }, @@ -290,13 +290,13 @@ constexpr ObjectModelTableEntry Platform::objectModelTable[] = { "driver", OBJECT_MODEL_FUNC(self->extruderDrivers[context.GetLastIndex()]), ObjectModelEntryFlags::none }, { "factor", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetExtrusionFactor(context.GetLastIndex()), 2), ObjectModelEntryFlags::none }, { "filament", OBJECT_MODEL_FUNC_NOSELF(GetFilamentName(context.GetLastIndex())), ObjectModelEntryFlags::none }, - { "jerk", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->GetInstantDv(ExtruderToLogicalDrive(context.GetLastIndex())), false), 1), ObjectModelEntryFlags::none }, + { "jerk", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerMin(self->GetInstantDv(ExtruderToLogicalDrive(context.GetLastIndex()))), 1), ObjectModelEntryFlags::none }, { "microstepping", OBJECT_MODEL_FUNC(self, 8), ObjectModelEntryFlags::none }, { "nonlinear", OBJECT_MODEL_FUNC(self, 5), ObjectModelEntryFlags::none }, { "position", OBJECT_MODEL_FUNC_NOSELF(ExpressionValue(reprap.GetMove().LiveCoordinate(ExtruderToLogicalDrive(context.GetLastIndex()), reprap.GetCurrentTool()), 1)), ObjectModelEntryFlags::live }, { "pressureAdvance", OBJECT_MODEL_FUNC_NOSELF(reprap.GetMove().GetPressureAdvance(context.GetLastIndex()), 2), ObjectModelEntryFlags::none }, { "rawPosition", OBJECT_MODEL_FUNC_NOSELF(ExpressionValue(reprap.GetGCodes().GetRawExtruderTotalByDrive(context.GetLastIndex()), 1)), ObjectModelEntryFlags::live }, - { "speed", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->MaxFeedrate(ExtruderToLogicalDrive(context.GetLastIndex())), false), 1), ObjectModelEntryFlags::none }, + { "speed", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerMin(self->MaxFeedrate(ExtruderToLogicalDrive(context.GetLastIndex()))), 1), ObjectModelEntryFlags::none }, { "stepsPerMm", OBJECT_MODEL_FUNC(self->driveStepsPerUnit[ExtruderToLogicalDrive(context.GetLastIndex())], 2), ObjectModelEntryFlags::none }, // 5. move.extruders[].nonlinear members @@ -590,7 +590,7 @@ void Platform::Init() noexcept instantDvs[drive] = DefaultEInstantDv; } - minimumMovementSpeed = DefaultMinFeedrate/StepTimer::StepClockRate; + minimumMovementSpeed = ConvertSpeedFromMmPerSec(DefaultMinFeedrate); axisMaximaProbed.Clear(); axisMinimaProbed.Clear(); idleCurrentFactor = DefaultIdleCurrentFactor; @@ -3185,7 +3185,7 @@ void Platform::SetDriverStepTiming(size_t driver, const float microseconds[4]) n if (microseconds[i] > MinStepPulseTiming) { slowDriversBitmap |= StepPins::CalcDriverBitmap(driver); // this drive does need extended timing - const uint32_t clocks = (uint32_t)(((float)StepTimer::StepClockRate * microseconds[i] * 0.000001) + 0.99); // convert microseconds to step clocks, rounding up + const uint32_t clocks = (uint32_t)(((float)StepClockRate * microseconds[i] * 0.000001) + 0.99); // convert microseconds to step clocks, rounding up if (clocks > slowDriverStepTimingClocks[i]) { slowDriverStepTimingClocks[i] = clocks; @@ -3201,7 +3201,7 @@ bool Platform::GetDriverStepTiming(size_t driver, float microseconds[4]) const n for (size_t i = 0; i < 4; ++i) { microseconds[i] = (isSlowDriver) - ? (float)slowDriverStepTimingClocks[i] * 1000000.0/(float)StepTimer::StepClockRate + ? (float)slowDriverStepTimingClocks[i] * 1000000.0/(float)StepClockRate : 0.0; } return isSlowDriver; @@ -4173,16 +4173,6 @@ void Platform::SetAxisMinimum(size_t axis, float value, bool byProbing) noexcept reprap.MoveUpdated(); } -void Platform::SetInstantDv(size_t drive, float value) noexcept -{ - instantDvs[drive] = max<float>(value, MinimumJerk/StepTimer::StepClockRate); // don't allow zero or negative values, they causes Move to loop indefinitely -} - -void Platform::SetMinMovementSpeed(float value) noexcept -{ - minimumMovementSpeed = max<float>(value, AbsoluteMinFeedrate/StepTimer::StepClockRate); -} - void Platform::InitZProbeFilters() noexcept { zProbeOnFilter.Init(0); diff --git a/src/Platform/Platform.h b/src/Platform/Platform.h index 4a025cd1..02200faf 100644 --- a/src/Platform/Platform.h +++ b/src/Platform/Platform.h @@ -917,7 +917,7 @@ inline const float* Platform::Accelerations() const noexcept inline void Platform::SetAcceleration(size_t drive, float value) noexcept { - accelerations[drive] = max<float>(value, 1.0); // don't allow zero or negative + accelerations[drive] = max<float>(value, ConvertAcceleration(MinimumAcceleration)); // don't allow zero or negative } inline float Platform::MaxFeedrate(size_t drive) const noexcept @@ -927,7 +927,17 @@ inline float Platform::MaxFeedrate(size_t drive) const noexcept inline void Platform::SetMaxFeedrate(size_t drive, float value) noexcept { - maxFeedrates[drive] = max<float>(value, minimumMovementSpeed); // don't allow zero or negative, but do allow small values + maxFeedrates[drive] = max<float>(value, minimumMovementSpeed); // don't allow zero or negative, but do allow small values +} + +inline void Platform::SetInstantDv(size_t drive, float value) noexcept +{ + instantDvs[drive] = max<float>(value, ConvertSpeedFromMmPerSec(MinimumJerk)); // don't allow zero or negative values, they causes Move to loop indefinitely +} + +inline void Platform::SetMinMovementSpeed(float value) noexcept +{ + minimumMovementSpeed = max<float>(value, ConvertSpeedFromMmPerSec(AbsoluteMinFeedrate)); } inline float Platform::GetInstantDv(size_t drive) const noexcept diff --git a/src/Platform/PortControl.cpp b/src/Platform/PortControl.cpp index 0632f0a5..26256efe 100644 --- a/src/Platform/PortControl.cpp +++ b/src/Platform/PortControl.cpp @@ -60,7 +60,7 @@ uint32_t PortControl::UpdatePorts() noexcept { SetBasePriority(0); UpdatePorts(cdda->GetIoBits()); - return (moveEndTime - now + StepTimer::StepClockRate/1000 - 1)/(StepTimer::StepClockRate/1000); + return (moveEndTime - now + StepClockRate/1000 - 1)/(StepClockRate/1000); } cdda = cdda->GetNext(); st = cdda->GetState(); @@ -96,7 +96,18 @@ bool PortControl::Configure(GCodeBuffer& gb, const StringRef& reply) { seen = true; advanceMillis = (unsigned int)constrain<int>(gb.GetIValue(), 0, 1000); - advanceClocks = (advanceMillis * (uint64_t)StepTimer::StepClockRate)/1000; + if constexpr (StepClockRate % 1000 == 0) + { + advanceClocks = advanceMillis * (StepClockRate/1000); + } + else if constexpr (StepClockRate % 500 == 0) + { + advanceClocks = (advanceMillis * (StepClockRate/500))/2; + } + else + { + advanceClocks = (advanceMillis * (uint64_t)StepClockRate)/1000; + } } if (!seen) { diff --git a/src/Platform/RepRap.cpp b/src/Platform/RepRap.cpp index 8854614b..aad77b7a 100644 --- a/src/Platform/RepRap.cpp +++ b/src/Platform/RepRap.cpp @@ -839,7 +839,7 @@ void RepRap::Spin() noexcept void RepRap::Timing(MessageType mtype) noexcept { - platform->MessageF(mtype, "Slowest loop: %.2fms; fastest: %.2fms\n", (double)(slowLoop * StepTimer::StepClocksToMillis), (double)(fastLoop * StepTimer::StepClocksToMillis)); + platform->MessageF(mtype, "Slowest loop: %.2fms; fastest: %.2fms\n", (double)(slowLoop * StepClocksToMillis), (double)(fastLoop * StepClocksToMillis)); fastLoop = UINT32_MAX; slowLoop = 0; } @@ -1356,7 +1356,7 @@ OutputBuffer *RepRap::GetStatusResponse(uint8_t type, ResponseSource source) con AppendFloatArray(response, "extr", GetExtrudersInUse(), [this](size_t extruder) noexcept { return move->LiveCoordinate(ExtruderToLogicalDrive(extruder), currentTool); }, 1); // Current speeds - response->catf("},\"speeds\":{\"requested\":%.1f,\"top\":%.1f}", (double)GCodeBuffer::InverseConvertSpeedToMm(move->GetRequestedSpeed(), true), (double)GCodeBuffer::InverseConvertSpeedToMm(move->GetTopSpeed(), true)); + response->catf("},\"speeds\":{\"requested\":%.1f,\"top\":%.1f}", (double)InverseConvertSpeedToMmPerSec(move->GetRequestedSpeed()), (double)InverseConvertSpeedToMmPerSec(move->GetTopSpeed())); // Current tool number response->catf(",\"currentTool\":%d", GetCurrentToolNumber()); @@ -1839,7 +1839,7 @@ OutputBuffer *RepRap::GetConfigResponse() noexcept // Accelerations response->cat(','); - AppendFloatArray(response, "accelerations", MaxAxesPlusExtruders, [this](size_t drive) noexcept { return GCodeBuffer::InverseConvertAcceleration(platform->Acceleration(drive)); }, 2); + AppendFloatArray(response, "accelerations", MaxAxesPlusExtruders, [this](size_t drive) noexcept { return InverseConvertAcceleration(platform->Acceleration(drive)); }, 2); // Motor currents response->cat(','); @@ -1886,11 +1886,11 @@ OutputBuffer *RepRap::GetConfigResponse() noexcept response->catf(",\"idleTimeout\":%.1f,", (double)(move->IdleTimeout())); // Minimum feedrates - AppendFloatArray(response, "minFeedrates", MaxAxesPlusExtruders, [this](size_t drive) noexcept { return GCodeBuffer::InverseConvertSpeedToMm(platform->GetInstantDv(drive), true); }, 2); + AppendFloatArray(response, "minFeedrates", MaxAxesPlusExtruders, [this](size_t drive) noexcept { return InverseConvertSpeedToMmPerSec(platform->GetInstantDv(drive)); }, 2); // Maximum feedrates response->cat(','); - AppendFloatArray(response, "maxFeedrates", MaxAxesPlusExtruders, [this](size_t drive) noexcept { return GCodeBuffer::InverseConvertSpeedToMm(platform->MaxFeedrate(drive), true); }, 2); + AppendFloatArray(response, "maxFeedrates", MaxAxesPlusExtruders, [this](size_t drive) noexcept { return InverseConvertSpeedToMmPerSec(platform->MaxFeedrate(drive)); }, 2); // Config file is no longer included, because we can use rr_configfile or M503 instead response->cat('}'); diff --git a/src/RepRapFirmware.h b/src/RepRapFirmware.h index edc921e0..53019c85 100644 --- a/src/RepRapFirmware.h +++ b/src/RepRapFirmware.h @@ -503,6 +503,61 @@ constexpr float TwoPi = 3.141592653589793 * 2; constexpr float DegreesToRadians = 3.141592653589793/180.0; constexpr float RadiansToDegrees = 180.0/3.141592653589793; +// The step clock is used for timing step pulses and oyther fine-resolution timer purposes + +#if SAME70 || SAME5x +// All Duet 3 boards use a common step clock rate of 750kHz so that we can sync the clocks over CAN +constexpr uint32_t StepClockRate = 48000000/64; // 750kHz +#elif defined(__LPC17xx__) +constexpr uint32_t StepClockRate = 1000000; // 1MHz +#else +constexpr uint32_t StepClockRate = SystemCoreClockFreq/128; // Duet 2 and Maestro: use just under 1MHz +#endif + +constexpr uint64_t StepClockRateSquared = (uint64_t)StepClockRate * StepClockRate; +constexpr float StepClocksToMillis = 1000.0/(float)StepClockRate; + +// Functions to convert speeds and accelerations between seconds and step clocks +static inline constexpr float ConvertSpeedFromMmPerSec(float speed) noexcept +{ + return speed * 1.0/StepClockRate; +} + +static inline constexpr float ConvertSpeedFromMmPerMin(float speed) noexcept +{ + return speed * (MinutesToSeconds/StepClockRate); +} + +static inline constexpr float ConvertSpeedFromMm(float speed, bool useSeconds) noexcept +{ + return speed * ((useSeconds) ? 1.0/StepClockRate : MinutesToSeconds/StepClockRate); +} + +static inline constexpr float InverseConvertSpeedToMmPerSec(float speed) noexcept +{ + return speed * StepClockRate; +} + +static inline constexpr float InverseConvertSpeedToMmPerMin(float speed) noexcept +{ + return speed * (StepClockRate * SecondsToMinutes); +} + +static inline constexpr float InverseConvertSpeedToMm(float speed, bool useSeconds) noexcept +{ + return speed * ((useSeconds) ? StepClockRate : StepClockRate * SecondsToMinutes); +} + +static inline constexpr float ConvertAcceleration(float accel) noexcept +{ + return accel * (1.0/StepClockRateSquared); +} + +static inline constexpr float InverseConvertAcceleration(float accel) noexcept +{ + return accel * StepClockRateSquared; +} + constexpr unsigned int MaxFloatDigitsDisplayedAfterPoint = 7; const char *GetFloatFormatString(unsigned int numDigitsAfterPoint) noexcept; |