From 63198ff741ddb2c2c86a49284d5e653fab234dd2 Mon Sep 17 00:00:00 2001 From: David Crocker Date: Tue, 16 Aug 2022 17:36:22 +0100 Subject: Attempted fix for extruder-only moves after M400 with tapered bed comp --- src/GCodes/GCodes.cpp | 28 +++++++++++++++++----------- src/GCodes/GCodes.h | 2 +- src/GCodes/GCodes2.cpp | 38 ++++++++++++++++++++++++-------------- src/GCodes/GCodes3.cpp | 12 +++++++++--- src/GCodes/GCodes4.cpp | 34 ++++++++++++++++++++++------------ src/Movement/DDA.cpp | 12 ++++++------ src/Movement/RawMove.cpp | 2 ++ src/Movement/RawMove.h | 20 +++++++++++--------- src/Platform/Platform.h | 1 + 9 files changed, 93 insertions(+), 56 deletions(-) diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp index d0cf1c5d..12ba77aa 100644 --- a/src/GCodes/GCodes.cpp +++ b/src/GCodes/GCodes.cpp @@ -1909,13 +1909,13 @@ bool GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated, const char *& e else #endif { - ToolOffsetTransform(moveState.currentUserPosition, moveState.coords, axesMentioned); + ToolOffsetTransform(moveState.currentUserPosition, moveState.coords, axesMentioned); // apply tool offset, baby stepping, Z hop and axis scaling } - // apply tool offset, baby stepping, Z hop and axis scaling + AxesBitmap effectiveAxesHomed = axesVirtuallyHomed; if (doingManualBedProbe) { - effectiveAxesHomed.ClearBit(Z_AXIS); // if doing a manual Z probe, don't limit the Z movement + effectiveAxesHomed.ClearBit(Z_AXIS); // if doing a manual Z probe, don't limit the Z movement } const LimitPositionResult lp = reprap.GetMove().GetKinematics().LimitPosition(moveState.coords, moveState.initialCoords, numVisibleAxes, effectiveAxesHomed, moveState.isCoordinated, limitAxes); @@ -2014,6 +2014,8 @@ bool GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated, const char *& e } moveState.doingArcMove = false; + moveState.linearAxesMentioned = axesMentioned.Intersects(reprap.GetPlatform().GetLinearAxes()); + moveState.rotationalAxesMentioned = axesMentioned.Intersects(reprap.GetPlatform().GetRotationalAxes()); FinaliseMove(gb); UnlockAll(gb); // allow pause err = nullptr; @@ -2370,6 +2372,8 @@ bool GCodes::DoArcMove(GCodeBuffer& gb, bool clockwise, const char *& err) moveState.arcAxis1 = axis1; moveState.doingArcMove = true; moveState.xyPlane = (selectedPlane == 0); + moveState.linearAxesMentioned = axesMentioned.Intersects(reprap.GetPlatform().GetLinearAxes()); + moveState.rotationalAxesMentioned = axesMentioned.Intersects(reprap.GetPlatform().GetRotationalAxes()); FinaliseMove(gb); UnlockAll(gb); // allow pause // debugPrintf("Radius %.2f, initial angle %.1f, increment %.1f, segments %u\n", @@ -2441,7 +2445,8 @@ bool GCodes::TravelToStartPoint(GCodeBuffer& gb) noexcept ToolOffsetTransform(buildObjects.GetInitialPosition().moveCoords, moveState.coords); moveState.feedRate = buildObjects.GetInitialPosition().feedRate; moveState.tool = reprap.GetCurrentTool(); - NewMoveAvailable(1); + moveState.linearAxesMentioned = moveState.rotationalAxesMentioned = true; // assume that both linear and rotational axes might be moving + NewSingleSegmentMoveAvailable(); return true; } @@ -2573,14 +2578,14 @@ void GCodes::ClearMove() noexcept moveFractionToSkip = 0.0; } -// Flag that a new move is available for consumption by the Move subsystem +// Flag that a new single-segment move is available for consumption by the Move subsystem // Code that sets up a new move should ensure that segmentsLeft is zero, then set up all the move parameters, // then call this function to update SegmentsLeft safely in a multi-threaded environment -void GCodes::NewMoveAvailable(unsigned int sl) noexcept +void GCodes::NewSingleSegmentMoveAvailable() noexcept { - moveState.totalSegments = sl; + moveState.totalSegments = 1; __DMB(); // make sure that all the move details have been written first - moveState.segmentsLeft = sl; // set the number of segments to indicate that a move is available to be taken + moveState.segmentsLeft = 1; // set the number of segments to indicate that a move is available to be taken reprap.GetMove().MoveAvailable(); // notify the Move task that we have a move } @@ -3850,7 +3855,7 @@ GCodeResult GCodes::RetractFilament(GCodeBuffer& gb, bool retract) } moveState.feedRate = currentTool->GetRetractSpeed() * tool->DriveCount(); moveState.canPauseAfter = false; // don't pause after a retraction because that could cause too much retraction - NewMoveAvailable(1); + NewSingleSegmentMoveAvailable(); } if (currentTool->GetRetractHop() > 0.0) { @@ -3864,7 +3869,8 @@ GCodeResult GCodes::RetractFilament(GCodeBuffer& gb, bool retract) moveState.coords[Z_AXIS] -= moveState.currentZHop; moveState.currentZHop = 0.0; moveState.canPauseAfter = false; // don't pause in the middle of a command - NewMoveAvailable(1); + moveState.linearAxesMentioned = true; // assume that both linear and rotational axes might be moving + NewSingleSegmentMoveAvailable(); gb.SetState(GCodeState::doingFirmwareUnRetraction); } else @@ -3879,7 +3885,7 @@ GCodeResult GCodes::RetractFilament(GCodeBuffer& gb, bool retract) } moveState.feedRate = currentTool->GetUnRetractSpeed() * tool->DriveCount(); moveState.canPauseAfter = true; - NewMoveAvailable(1); + NewSingleSegmentMoveAvailable(); } } currentTool->SetRetracted(retract); diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h index 49fb067b..9e482fcf 100644 --- a/src/GCodes/GCodes.h +++ b/src/GCodes/GCodes.h @@ -504,7 +504,7 @@ private: void SaveResumeInfo(bool wasPowerFailure) noexcept; #endif - void NewMoveAvailable(unsigned int sl) noexcept; // Flag that a new move is available + void NewSingleSegmentMoveAvailable() noexcept; // Flag that a new move is available void NewMoveAvailable() noexcept; // Flag that a new move is available void SetMoveBufferDefaults() noexcept; // Set up default values in the move buffer diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index cb416160..2623cead 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -2511,7 +2511,9 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx SetMoveBufferDefaults(); moveState.feedRate = ConvertSpeedFromMmPerMin(DefaultFeedRate); moveState.tool = reprap.GetCurrentTool(); - NewMoveAvailable(1); + moveState.linearAxesMentioned = axesMentioned.Intersects(reprap.GetPlatform().GetLinearAxes()); + moveState.rotationalAxesMentioned = axesMentioned.Intersects(reprap.GetPlatform().GetRotationalAxes()); + NewSingleSegmentMoveAvailable(); } } else @@ -3935,12 +3937,21 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx break; case 673: // Align plane on rotary axis - if (numTotalAxes < U_AXIS) + if (numTotalAxes <= U_AXIS) { reply.copy("Insufficient axes configured"); result = GCodeResult::error; } - else if (LockMovementAndWaitForStandstill(gb)) + else if (!LockMovementAndWaitForStandstill(gb)) + { + result = GCodeResult::notFinished; + } + else if (!AllAxesAreHomed()) + { + reply.copy("Home the axes first"); + result = GCodeResult::error; + } + else { Move& move = reprap.GetMove(); if (move.GetNumProbedProbePoints() < 2) @@ -3948,11 +3959,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx reply.copy("Insufficient probe points"); result = GCodeResult::error; } - else if (!AllAxesAreHomed()) - { - reply.copy("Home the axes first"); - result = GCodeResult::error; - } else { // See which rotary axis needs to be compensated (if any) @@ -3977,11 +3983,18 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx SetMoveBufferDefaults(); if (axisToUse != 0) { + if (!reprap.GetPlatform().IsAxisRotational(axisToUse)) + { + reply.printf("%c axis is not rotary", axisLetters[axisToUse]); + result = GCodeResult::error; + break; + } + // An axis letter is given, so try to level the given axis const float correctionAngle = atanf((z2 - z1) / (a2 - a1)) * 180.0 / M_PI; const float correctionFactor = gb.Seen('S') ? gb.GetFValue() : 1.0; moveState.coords[axisToUse] += correctionAngle * correctionFactor; - + moveState.rotationalAxesMentioned = true; reply.printf("%c axis is off by %.2f deg", axisLetters[axisToUse], (double)correctionAngle); HandleReply(gb, GCodeResult::notFinished, reply.c_str()); } @@ -4000,6 +4013,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx ((z4 - z3) * (a2 - a1) - (z2 - z1) * (a4 - a3)); moveState.coords[(x1 == x2) ? Y_AXIS : X_AXIS] += aS; moveState.coords[Z_AXIS] += zS; + moveState.linearAxesMentioned = true; reply.printf("%c is offset by %.2fmm, Z is offset by %.2fmm", (x2 == x1) ? 'Y' : 'X', (double)aS, (double)zS); HandleReply(gb, GCodeResult::notFinished, reply.c_str()); @@ -4019,15 +4033,11 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx moveState.feedRate = gb.LatestMachineState().feedRate; moveState.usingStandardFeedrate = true; moveState.tool = reprap.GetCurrentTool(); - NewMoveAvailable(1); + NewSingleSegmentMoveAvailable(); gb.SetState(GCodeState::waitingForSpecialMoveToComplete); } } - else - { - result = GCodeResult::notFinished; - } break; #if false diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp index 9e1895bb..f5d3acdb 100644 --- a/src/GCodes/GCodes3.cpp +++ b/src/GCodes/GCodes3.cpp @@ -998,7 +998,9 @@ bool GCodes::SetupM585ProbingMove(GCodeBuffer& gb) noexcept moveState.checkEndstops = true; moveState.canPauseAfter = false; zProbeTriggered = false; - NewMoveAvailable(1); + moveState.linearAxesMentioned = reprap.GetPlatform().IsAxisLinear(m585Settings.axisNumber); + moveState.rotationalAxesMentioned = reprap.GetPlatform().IsAxisRotational(m585Settings.axisNumber); + NewSingleSegmentMoveAvailable(); return true; } @@ -1053,7 +1055,9 @@ bool GCodes::SetupM675ProbingMove(GCodeBuffer& gb, bool towardsMin) noexcept moveState.checkEndstops = true; moveState.canPauseAfter = false; zProbeTriggered = false; - NewMoveAvailable(1); // kick off the move + moveState.linearAxesMentioned = reprap.GetPlatform().IsAxisLinear(m675Settings.axisNumber); + moveState.rotationalAxesMentioned = reprap.GetPlatform().IsAxisRotational(m675Settings.axisNumber); + NewSingleSegmentMoveAvailable(); // kick off the move return true; } @@ -1064,7 +1068,9 @@ void GCodes::SetupM675BackoffMove(GCodeBuffer& gb, float position) noexcept moveState.coords[m675Settings.axisNumber] = position; moveState.feedRate = m675Settings.feedRate; moveState.canPauseAfter = false; - NewMoveAvailable(1); + moveState.linearAxesMentioned = reprap.GetPlatform().IsAxisLinear(m675Settings.axisNumber); + moveState.rotationalAxesMentioned = reprap.GetPlatform().IsAxisRotational(m675Settings.axisNumber); + NewSingleSegmentMoveAvailable(); } // Deal with a M905 diff --git a/src/GCodes/GCodes4.cpp b/src/GCodes/GCodes4.cpp index 81d5e0b8..05f3146e 100644 --- a/src/GCodes/GCodes4.cpp +++ b/src/GCodes/GCodes4.cpp @@ -487,7 +487,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept } SetMoveBufferDefaults(); ToolOffsetTransform(moveState.currentUserPosition, moveState.coords); - moveState.feedRate = ConvertSpeedFromMmPerMin(DefaultFeedRate); // ask for a good feed rate, we may have paused during a slow move + moveState.feedRate = ConvertSpeedFromMmPerMin(DefaultFeedRate); // ask for a good feed rate, we may have paused during a slow move moveState.tool = reprap.GetCurrentTool(); // needed so that bed compensation is applied correctly if (gb.GetState() == GCodeState::resuming1 && currentZ > pauseRestorePoint.moveCoords[Z_AXIS]) { @@ -500,7 +500,8 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept // Just move to the saved position in one go gb.SetState(GCodeState::resuming3); } - NewMoveAvailable(1); + moveState.linearAxesMentioned = moveState.rotationalAxesMentioned = true; // assume that both linear and rotational axes might be moving + NewSingleSegmentMoveAvailable(); } break; @@ -644,7 +645,8 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept moveState.coords[axis1Num] = axesCoords[axis1Num]; moveState.coords[Z_AXIS] = zp->GetStartingHeight(); moveState.feedRate = zp->GetTravelSpeed(); - NewMoveAvailable(1); + moveState.linearAxesMentioned = moveState.rotationalAxesMentioned = true; // assume that both linear and rotational axes might be moving + NewSingleSegmentMoveAvailable(); InitialiseTaps(false); gb.AdvanceState(); @@ -724,7 +726,8 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept moveState.reduceAcceleration = true; moveState.coords[Z_AXIS] = -zp->GetDiveHeight() + zp->GetActualTriggerHeight(); moveState.feedRate = zp->GetProbingSpeed(tapsDone); - NewMoveAvailable(1); + moveState.linearAxesMentioned = true; // assume that both linear and rotational axes might be moving + NewSingleSegmentMoveAvailable(); gb.AdvanceState(); } } @@ -775,7 +778,8 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept moveState.coords[Z_AXIS] = zp->GetStartingHeight(); moveState.feedRate = zp->GetTravelSpeed(); } - NewMoveAvailable(1); + moveState.linearAxesMentioned = true; + NewSingleSegmentMoveAvailable(); gb.AdvanceState(); break; @@ -915,7 +919,8 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept moveState.coords[Z_AXIS] = zp->GetStartingHeight(); moveState.feedRate = zp->GetTravelSpeed(); } - NewMoveAvailable(1); + moveState.linearAxesMentioned = true; + NewSingleSegmentMoveAvailable(); gb.AdvanceState(); break; @@ -929,7 +934,8 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept const auto zp = platform.GetZProbeOrDefault(currentZProbeNumber); moveState.coords[Z_AXIS] = zp->GetStartingHeight(); moveState.feedRate = zp->GetTravelSpeed(); - NewMoveAvailable(1); + moveState.linearAxesMentioned = moveState.rotationalAxesMentioned = true; // assume that both linear and rotational axes might be moving + NewSingleSegmentMoveAvailable(); InitialiseTaps(false); gb.AdvanceState(); @@ -1008,7 +1014,8 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept ? platform.AxisMinimum(Z_AXIS) - zp->GetDiveHeight() + zp->GetActualTriggerHeight() // Z axis has been homed, so no point in going very far : -1.1 * platform.AxisTotalLength(Z_AXIS); // Z axis not homed yet, so treat this as a homing move moveState.feedRate = zp->GetProbingSpeed(tapsDone); - NewMoveAvailable(1); + moveState.linearAxesMentioned = true; + NewSingleSegmentMoveAvailable(); gb.AdvanceState(); } } @@ -1102,7 +1109,8 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept moveState.coords[Z_AXIS] = zp->GetStartingHeight(); moveState.feedRate = zp->GetTravelSpeed(); } - NewMoveAvailable(1); + moveState.linearAxesMentioned = true; + NewSingleSegmentMoveAvailable(); gb.AdvanceState(); break; @@ -1297,7 +1305,8 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept moveState.reduceAcceleration = true; straightProbeSettings.SetCoordsToTarget(moveState.coords); moveState.feedRate = zp->GetProbingSpeed(0); - NewMoveAvailable(1); + moveState.linearAxesMentioned = moveState.rotationalAxesmentioned = true; + NewSingleSegmentMoveAvailable(); gb.AdvanceState(); } } @@ -1343,7 +1352,8 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept moveState.filePos = (&gb == fileGCode) ? gb.GetFilePosition() : noFilePosition; moveState.canPauseAfter = false; // don't pause after a retraction because that could cause too much retraction moveState.currentZHop = tool->GetRetractHop(); - NewMoveAvailable(1); + moveState.linearAxesMentioned = true; + NewSingleSegmentMoveAvailable(); } gb.SetState(GCodeState::normal); } @@ -1366,7 +1376,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept moveState.feedRate = tool->GetUnRetractSpeed() * tool->DriveCount(); moveState.filePos = (&gb == fileGCode) ? gb.GetFilePosition() : noFilePosition; moveState.canPauseAfter = true; - NewMoveAvailable(1); + NewSingleSegmentMoveAvailable(); } gb.SetState(GCodeState::normal); } diff --git a/src/Movement/DDA.cpp b/src/Movement/DDA.cpp index 7050a28e..5ea10f5b 100644 --- a/src/Movement/DDA.cpp +++ b/src/Movement/DDA.cpp @@ -345,17 +345,17 @@ bool DDA::InitStandardMove(DDARing& ring, const RawMove &nextMove, bool doMotorM directionVector[drive] = positionDelta; if (positionDelta != 0.0) { - if (reprap.GetPlatform().IsAxisRotational(drive)) + if (reprap.GetPlatform().IsAxisRotational(drive) && nextMove.rotationalAxesMentioned) { rotationalAxesMoving = true; } - else + else if (nextMove.linearAxesMentioned) { linearAxesMoving = true; - } - if (Tool::GetXAxes(nextMove.tool).IsBitSet(drive) || Tool::GetYAxes(nextMove.tool).IsBitSet(drive)) - { - flags.xyMoving = true; // this move has XY movement in user space, before axis were mapped + if (Tool::GetXAxes(nextMove.tool).IsBitSet(drive) || Tool::GetYAxes(nextMove.tool).IsBitSet(drive)) + { + flags.xyMoving = true; // this move has XY movement in user space, before axis were mapped + } } } } diff --git a/src/Movement/RawMove.cpp b/src/Movement/RawMove.cpp index bdcdba51..d1c1e65e 100644 --- a/src/Movement/RawMove.cpp +++ b/src/Movement/RawMove.cpp @@ -18,6 +18,8 @@ void RawMove::SetDefaults(size_t firstDriveToZero) noexcept checkEndstops = false; reduceAcceleration = false; hasPositiveExtrusion = false; + linearAxesMentioned = false; + rotationalAxesMentioned = false; filePos = noFilePosition; tool = nullptr; cosXyAngle = 1.0; diff --git a/src/Movement/RawMove.h b/src/Movement/RawMove.h index 19727e4d..7bccf816 100644 --- a/src/Movement/RawMove.h +++ b/src/Movement/RawMove.h @@ -21,21 +21,23 @@ struct RawMove float proportionDone; // what proportion of the entire move has been done when this segment is complete float cosXyAngle; // the cosine of the change in XY angle between the previous move and this move const Tool *tool; // which tool (if any) is being used -#if SUPPORT_LASER || SUPPORT_IOBITS - LaserPwmOrIoBits laserPwmOrIoBits; // the laser PWM or port bit settings required -#else - uint16_t padding; -#endif - uint8_t moveType; // the S parameter from the G0 or G1 command, 0 for a normal move - - uint8_t applyM220M221 : 1, // true if this move is affected by M220 and M221 (this could be moved to ExtendedRawMove) + uint16_t moveType : 3, // the H parameter from the G0 or G1 command, 0 for a normal move + applyM220M221 : 1, // true if this move is affected by M220 and M221 (this could be moved to ExtendedRawMove) usePressureAdvance : 1, // true if we want to us extruder pressure advance, if there is any extrusion canPauseAfter : 1, // true if we can pause just after this move and successfully restart hasPositiveExtrusion : 1, // true if the move includes extrusion; only valid if the move was set up by SetupMove isCoordinated : 1, // true if this is a coordinated move usingStandardFeedrate : 1, // true if this move uses the standard feed rate checkEndstops : 1, // true if any endstops or the Z probe can terminate the move - reduceAcceleration : 1; // true if Z probing so we should limit the Z acceleration + reduceAcceleration : 1, // true if Z probing so we should limit the Z acceleration + linearAxesMentioned : 1, // true if any linear axes were mentioned in the movement command + rotationalAxesMentioned: 1; // true if any rotational axes were mentioned in the movement command + +#if SUPPORT_LASER || SUPPORT_IOBITS + LaserPwmOrIoBits laserPwmOrIoBits; // the laser PWM or port bit settings required +#else + uint16_t padding; +#endif // If adding any more fields, keep the total size a multiple of 4 bytes so that we can use our optimised assignment operator void SetDefaults(size_t firstDriveToZero) noexcept; // set up default values diff --git a/src/Platform/Platform.h b/src/Platform/Platform.h index 9e0c9986..900b94f6 100644 --- a/src/Platform/Platform.h +++ b/src/Platform/Platform.h @@ -499,6 +499,7 @@ public: inline AxesBitmap GetLinearAxes() const noexcept { return linearAxes; } inline AxesBitmap GetRotationalAxes() const noexcept { return rotationalAxes; } + inline bool IsAxisLinear(size_t axis) const noexcept { return linearAxes.IsBitSet(axis); } inline bool IsAxisRotational(size_t axis) const noexcept { return rotationalAxes.IsBitSet(axis); } inline bool IsAxisContinuous(size_t axis) const noexcept { return continuousAxes.IsBitSet(axis); } #if 0 // shortcut axes not implemented yet -- cgit v1.2.3