diff options
author | David Crocker <dcrocker@eschertech.com> | 2022-11-02 21:54:17 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2022-11-02 21:54:17 +0300 |
commit | fec1720d684d6fb42485b197850372fd9a412f66 (patch) | |
tree | 4727163933eae3e273ab6be93f21e4bb89d09763 | |
parent | 690c9f12b155eb0027455b1dd4735fdf4be80116 (diff) |
Refactored axis allocation and release
-rw-r--r-- | src/GCodes/GCodes.cpp | 132 | ||||
-rw-r--r-- | src/GCodes/GCodes.h | 4 | ||||
-rw-r--r-- | src/GCodes/GCodes3.cpp | 6 | ||||
-rw-r--r-- | src/Movement/RawMove.cpp | 7 | ||||
-rw-r--r-- | src/Movement/RawMove.h | 82 |
5 files changed, 140 insertions, 91 deletions
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp index acb86014..db68c372 100644 --- a/src/GCodes/GCodes.cpp +++ b/src/GCodes/GCodes.cpp @@ -1595,20 +1595,19 @@ bool GCodes::LockMovementSystemAndWaitForStandstill(GCodeBuffer& gb, unsigned in #if SUPPORT_ASYNC_MOVES // Get the position of all axes by combining positions from the queues Move& move = reprap.GetMove(); - const AxesBitmap ownedAxes = moveStates[msNumber].axesAndExtrudersOwned; + const AxesBitmap ownedAxes = ms.GetAxesAndExtrudersOwned(); // Whenever we release axes, we must update lastKnownMachinePositions for those axes first so that whoever allocated them next gets the correct positions move.GetPartialMachinePosition(lastKnownMachinePositions, ownedAxes, msNumber); - moveStates[msNumber].axesAndExtrudersOwned.Clear(); - memcpyf(moveStates[msNumber].coords, lastKnownMachinePositions, MaxAxes); - move.InverseAxisAndBedTransform(lastKnownMachinePositions, moveStates[msNumber].currentTool); - UpdateUserPositionFromMachinePosition(gb, moveStates[msNumber]); + memcpyf(ms.coords, lastKnownMachinePositions, MaxAxes); + move.InverseAxisAndBedTransform(lastKnownMachinePositions, ms.currentTool); + UpdateUserPositionFromMachinePosition(gb, ms); collisionChecker.ResetPositions(lastKnownMachinePositions, ownedAxes); // Release the axes and extruders that this movement system owns axesAndExtrudersMoved.ClearBits(ownedAxes); - ms.ownedAxisLetters.Clear(); + ms.ReleaseOwnedAxesAndExtruders(); #else UpdateCurrentUserPosition(gb); #endif @@ -1690,8 +1689,10 @@ void GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, MovementState& m } ms.hasPositiveExtrusion = false; ms.moveStartVirtualExtruderPosition = ms.latestVirtualExtruderPosition; // save this before we update it - AxesBitmap logicalDrivesMoving; ExtrudersBitmap extrudersMoving; +#if SUPPORT_ASYNC_MOVES + AxesBitmap logicalDrivesMoving; +#endif // 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 @@ -1763,7 +1764,9 @@ void GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, MovementState& m ? extrusionAmount * extrusionFactors[extruder] : extrusionAmount; extrudersMoving.SetBit(extruder); +#if SUPPORT_ASYNC_MOVES logicalDrivesMoving.SetBit(ExtruderToLogicalDrive(extruder)); +#endif } } if (!isPrintingMove && ms.usingStandardFeedrate) @@ -1803,7 +1806,9 @@ void GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, MovementState& m ? extrusionAmount * extrusionFactors[extruder] : extrusionAmount; extrudersMoving.SetBit(extruder); +#if SUPPORT_ASYNC_MOVES logicalDrivesMoving.SetBit(ExtruderToLogicalDrive(extruder)); +#endif } } } @@ -1816,7 +1821,7 @@ void GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, MovementState& m } #if SUPPORT_ASYNC_MOVES - AllocateAxes(gb, ms, logicalDrivesMoving); + AllocateAxes(gb, ms, logicalDrivesMoving, ParameterLettersBitmap()); #endif if (ms.moveType == 1 || ms.moveType == 4) @@ -1840,13 +1845,46 @@ bool GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated) THROWS(GCodeExc { MovementState& ms = GetMovementState(gb); + // Set up default move parameters + ms.movementTool = ms.currentTool; + ms.moveType = 0; + ms.isCoordinated = isCoordinated; + ms.checkEndstops = false; + ms.reduceAcceleration = false; + ms.movementTool = ms.currentTool; + ms.usePressureAdvance = false; + axesToSenseLength.Clear(); + + // Check to see if the move is a 'homing' move that endstops are checked on and for which X and Y axis mapping is not applied + { + uint32_t moveType; + bool dummy; + if (gb.TryGetLimitedUIValue('H', moveType, dummy, 5)) + { + if (!LockCurrentMovementSystemAndWaitForStandstill(gb)) + { + return false; + } + ms.moveType = moveType; + ms.movementTool = nullptr; + } + } + + #if SUPPORT_ASYNC_MOVES // We need to check for moving unowned axes right at the start in case we need to fetch axis positions before processing the command ParameterLettersBitmap axisLettersMentioned = gb.AllParameters() & allAxisLetters; - axisLettersMentioned.ClearBits(ms.ownedAxisLetters); - if (axisLettersMentioned.IsNonEmpty()) + if (ms.moveType == 0) { - AllocateAxisLetters(gb, ms, axisLettersMentioned); + axisLettersMentioned.ClearBits(ms.GetOwnedAxisLetters()); + if (axisLettersMentioned.IsNonEmpty()) + { + AllocateAxisLetters(gb, ms, axisLettersMentioned); + } + } + else + { + AllocateAxesDirectFromLetters(gb, ms, axisLettersMentioned); } #endif @@ -1862,31 +1900,6 @@ bool GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated) THROWS(GCodeExc ms.initialUserC1 = ms.currentUserPosition[(selectedPlane == 0) ? Y_AXIS : Z_AXIS]; } - // Set up default move parameters - ms.isCoordinated = isCoordinated; - ms.checkEndstops = false; - ms.reduceAcceleration = false; - ms.movementTool = ms.currentTool; - ms.moveType = 0; - ms.usePressureAdvance = false; - axesToSenseLength.Clear(); - - // Check to see if the move is a 'homing' move that endstops are checked on. - // We handle H1 parameters affecting extrusion elsewhere. - if (gb.Seen('H')) - { - const int ival = gb.GetIValue(); - if (ival >= 1 && ival <= 4) - { - if (!LockCurrentMovementSystemAndWaitForStandstill(gb)) - { - return false; - } - ms.moveType = ival; - ms.movementTool = nullptr; - } - } - // Check for 'R' parameter to move relative to a restore point const RestorePoint * rp = nullptr; if (ms.moveType == 0 && gb.Seen('R')) @@ -2044,9 +2057,6 @@ bool GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated) THROWS(GCodeExc } } -#if SUPPORT_ASYNC_MOVES - AllocateAxes(gb, ms, realAxesMoving); -#endif if (!doingManualBedProbe && CheckEnoughAxesHomed(axesMentioned)) { gb.ThrowGCodeException("G0/G1: insufficient axes homed"); @@ -2054,9 +2064,6 @@ bool GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated) THROWS(GCodeExc } else { -#if SUPPORT_ASYNC_MOVES - AllocateAxes(gb, ms, axesMentioned); -#endif switch (ms.moveType) { case 3: @@ -2267,7 +2274,7 @@ bool GCodes::DoArcMove(GCodeBuffer& gb, bool clockwise) ParameterLettersBitmap axisLettersMentioned = gb.AllParameters() & allAxisLetters; axisLettersMentioned.SetBit(ParameterLetterToBitNumber('X') + axis0); // add in the implicit axes axisLettersMentioned.SetBit(ParameterLetterToBitNumber('X') + axis1); - axisLettersMentioned.ClearBits(ms.ownedAxisLetters); + axisLettersMentioned.ClearBits(ms.GetOwnedAxisLetters()); if (axisLettersMentioned.IsNonEmpty()) { AllocateAxisLetters(gb, ms, axisLettersMentioned); @@ -2467,10 +2474,6 @@ bool GCodes::DoArcMove(GCodeBuffer& gb, bool clockwise) gb.ThrowGCodeException("G2/G3: insufficient axes homed"); } -#if SUPPORT_ASYNC_MOVES - AllocateAxes(gb, ms, realAxesMoving); -#endif - // Compute the initial and final angles. Do this before we possible rotate the coordinates of the arc centre. float finalTheta = atan2(ms.currentUserPosition[axis1] - userArcCentre[1], ms.currentUserPosition[axis0] - userArcCentre[0]); ms.arcRadius = fastSqrtf(iParam * iParam + jParam * jParam); @@ -3924,7 +3927,7 @@ GCodeResult GCodes::RetractFilament(GCodeBuffer& gb, bool retract) THROWS(GCodeE ms.feedRate = currentTool->GetRetractSpeed() * currentTool->DriveCount(); ms.canPauseAfter = false; // don't pause after a retraction because that could cause too much retraction #if SUPPORT_ASYNC_MOVES - AllocateAxes(gb, ms, drivesMoving); + AllocateAxes(gb, ms, drivesMoving, ParameterLettersBitmap()); #endif NewSingleSegmentMoveAvailable(ms); } @@ -3942,7 +3945,7 @@ GCodeResult GCodes::RetractFilament(GCodeBuffer& gb, bool retract) THROWS(GCodeE ms.canPauseAfter = false; // don't pause in the middle of a command ms.linearAxesMentioned = true; #if SUPPORT_ASYNC_MOVES - AllocateAxes(gb, ms, AxesBitmap::MakeFromBits(Z_AXIS)); + AllocateAxes(gb, ms, AxesBitmap::MakeFromBits(Z_AXIS), ParameterLettersBitmap('Z')); #endif NewSingleSegmentMoveAvailable(ms); gb.SetState(GCodeState::doingFirmwareUnRetraction); @@ -3962,7 +3965,7 @@ GCodeResult GCodes::RetractFilament(GCodeBuffer& gb, bool retract) THROWS(GCodeE ms.feedRate = currentTool->GetUnRetractSpeed() * currentTool->DriveCount(); ms.canPauseAfter = true; #if SUPPORT_ASYNC_MOVES - AllocateAxes(gb, ms, drivesMoving); + AllocateAxes(gb, ms, drivesMoving, ParameterLettersBitmap()); #endif NewSingleSegmentMoveAvailable(ms); } @@ -4936,17 +4939,17 @@ const MovementState& GCodes::GetCurrentMovementState(const ObjectExplorationCont // Allocate additional axes and/or extruders to a movement state returning true if successful, false if another movement state owns it already // This relies on cooperative scheduling between different GCodeBuffer objects -void GCodes::AllocateAxes(const GCodeBuffer& gb, MovementState& ms, AxesBitmap axes) THROWS(GCodeException) +void GCodes::AllocateAxes(const GCodeBuffer& gb, MovementState& ms, AxesBitmap axes, ParameterLettersBitmap axLetters) THROWS(GCodeException) { - if ((axes & axesAndExtrudersMoved & ~ms.axesAndExtrudersOwned).IsNonEmpty()) + if ((axes & axesAndExtrudersMoved & ~ms.GetAxesAndExtrudersOwned()).IsNonEmpty()) { gb.ThrowGCodeException("Axis is already used by a different motion system"); } axesAndExtrudersMoved |= axes; - ms.axesAndExtrudersOwned |= axes; + ms.AllocateAxes(axes, axLetters); } -// Allocate additional axes by letter. The axis letters are as in the GCode, before we account for coordinate rotation and axis mapping. +// Allocate additional axes by letter when we are doing a standard move. The axis letters are as in the GCode, before we account for coordinate rotation and axis mapping. // We must clear out owned axis letters on a tool change, or when coordinate rotation is changed from zero to nonzero void GCodes::AllocateAxisLetters(const GCodeBuffer& gb, MovementState& ms, ParameterLettersBitmap axLetters) THROWS(GCodeException) { @@ -4986,9 +4989,24 @@ void GCodes::AllocateAxisLetters(const GCodeBuffer& gb, MovementState& ms, Param } } } - newAxes &= ~ms.axesAndExtrudersOwned; - AllocateAxes(gb, ms, newAxes); - ms.ownedAxisLetters |= axLetters; + AllocateAxes(gb, ms, newAxes, axLetters); + UpdateAllCoordinates(gb); +} + +// Allocate axes by letter when we are doing a special move. Do not update the map of owned axes letters. +void GCodes::AllocateAxesDirectFromLetters(const GCodeBuffer& gb, MovementState& ms, ParameterLettersBitmap axLetters) THROWS(GCodeException) +{ + AxesBitmap newAxes; + for (size_t axis = 0; axis < numVisibleAxes; ++axis) + { + const char c = axisLetters[axis]; + const unsigned int axisLetterBitNumber = ParameterLetterToBitNumber(c); + if (axLetters.IsBitSet(axisLetterBitNumber)) + { + newAxes.SetBit(axis); + } + } + AllocateAxes(gb, ms, newAxes, ParameterLettersBitmap()); // don't own the letters! UpdateAllCoordinates(gb); } diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h index 29df59ca..084fe9e1 100644 --- a/src/GCodes/GCodes.h +++ b/src/GCodes/GCodes.h @@ -554,9 +554,11 @@ private: GCodeResult CollisionAvoidance(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); // Handle M597 GCodeResult SyncMovementSystems(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); // Handle M598 GCodeResult ExecuteM400(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); // Handle M400 - void AllocateAxes(const GCodeBuffer& gb, MovementState& ms, AxesBitmap axes) THROWS(GCodeException); // allocate axes to a movement state + void AllocateAxes(const GCodeBuffer& gb, MovementState& ms, AxesBitmap axes, ParameterLettersBitmap axLetters) THROWS(GCodeException); // allocate axes to a movement state void AllocateAxisLetters(const GCodeBuffer& gb, MovementState& ms, ParameterLettersBitmap axLetters) THROWS(GCodeException); // allocate axes by letter + void AllocateAxesDirectFromLetters(const GCodeBuffer& gb, MovementState& ms, ParameterLettersBitmap axLetters) THROWS(GCodeException); + // allocate axes by letter for a special move bool DoSync(GCodeBuffer& gb) noexcept; // sync with the other stream returning true if done, false if we need to wait for it bool SyncWith(GCodeBuffer& thisGb, const GCodeBuffer& otherGb) noexcept; // synchronise motion systems void UpdateAllCoordinates(const GCodeBuffer& gb) noexcept; diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp index f65dedb5..04aadd9f 100644 --- a/src/GCodes/GCodes3.cpp +++ b/src/GCodes/GCodes3.cpp @@ -76,7 +76,7 @@ GCodeResult GCodes::SetPositions(GCodeBuffer& gb, const StringRef& reply) THROWS #if SUPPORT_ASYNC_MOVES // Check for setting unowned axes before processing the command ParameterLettersBitmap axisLettersMentioned = gb.AllParameters() & allAxisLetters; - axisLettersMentioned.ClearBits(ms.ownedAxisLetters); + axisLettersMentioned.ClearBits(ms.GetOwnedAxisLetters()); if (axisLettersMentioned.IsNonEmpty()) { AllocateAxisLetters(gb, ms, axisLettersMentioned); @@ -1569,8 +1569,8 @@ GCodeResult GCodes::HandleG68(GCodeBuffer& gb, const StringRef& reply) THROWS(GC // We have just started doing coordinate rotation, so if we own axis letter X we need to own Y and vice versa // Simplest is just to say we don't own either in the axis letters bitmap MovementState& ms = GetMovementState(gb); - ms.ownedAxisLetters.ClearBit('X' - 'A'); - ms.ownedAxisLetters.ClearBit('Y' - 'A'); + ms.ReleaseAxisLetter('X'); + ms.ReleaseAxisLetter('Y'); } #endif UpdateCurrentUserPosition(gb); diff --git a/src/Movement/RawMove.cpp b/src/Movement/RawMove.cpp index 0df696f8..91162dd7 100644 --- a/src/Movement/RawMove.cpp +++ b/src/Movement/RawMove.cpp @@ -226,6 +226,13 @@ void MovementState::InitObjectCancellation() noexcept currentObjectCancelled = printingJustResumed = false; } +// When releasing axes we must also release the corresponding axis letters, because they serve as a cache +void MovementState::ReleaseOwnedAxesAndExtruders() noexcept +{ + axesAndExtrudersOwned.Clear(); + ownedAxisLetters.Clear(); +} + #if SUPPORT_ASYNC_MOVES void AsyncMove::SetDefaults() noexcept diff --git a/src/Movement/RawMove.h b/src/Movement/RawMove.h index 99b11d1b..e3f72656 100644 --- a/src/Movement/RawMove.h +++ b/src/Movement/RawMove.h @@ -76,11 +76,46 @@ constexpr size_t ResumeObjectRestorePointNumber = NumVisibleRestorePoints + 1; // Details of a move that are needed only by GCodes // CAUTION: segmentsLeft should ONLY be changed from 0 to not 0 by calling NewMoveAvailable()! -struct MovementState : public RawMove +class MovementState : public RawMove { +public: + AxesBitmap GetAxesAndExtrudersOwned() const noexcept { return axesAndExtrudersOwned; } // Get the axes and extruders that this movement system owns + ParameterLettersBitmap GetOwnedAxisLetters() const noexcept { return ownedAxisLetters; } // Get the letters denoting axes that this movement system owns + void AllocateAxes(AxesBitmap axes, ParameterLettersBitmap axisLetters) noexcept; + void ReleaseOwnedAxesAndExtruders() noexcept; + void ReleaseAxisLetter(char letter) noexcept; // stop claiming that we own an axis letter (if we do) but don't release the associated axis + + float GetProportionDone() const noexcept; // get the proportion of this whole move that has been completed, based on segmentsLeft and totalSegments + void Reset() noexcept; + void ChangeExtrusionFactor(unsigned int extruder, float multiplier) noexcept; // change the extrusion factor of an extruder + const RestorePoint& GetRestorePoint(size_t n) const pre(n < NumTotalRestorePoints) { return restorePoints[n]; } + void ClearMove() noexcept; + void SavePosition(unsigned int restorePointNumber, size_t numAxes, float p_feedRate, FilePosition p_filePos) noexcept + pre(restorePointNumber < NumTotalRestorePoints); + + // Tool management + void SelectTool(int toolNumber, bool simulating) noexcept; + ReadLockedPointer<Tool> GetLockedCurrentTool() const noexcept; + ReadLockedPointer<Tool> GetLockedCurrentOrDefaultTool() const noexcept; + int GetCurrentToolNumber() const noexcept; + void SetPreviousToolNumber() noexcept; + AxesBitmap GetCurrentXAxes() const noexcept; // Get the current axes used as X axes + AxesBitmap GetCurrentYAxes() const noexcept; // Get the current axes used as Y axes + AxesBitmap GetCurrentAxisMapping(unsigned int axis) const noexcept; + float GetCurrentToolOffset(size_t axis) const noexcept; // Get an axis offset of the current tool + + // Object cancellation support + void InitObjectCancellation() noexcept; + bool IsCurrentObjectCancelled() const noexcept { return currentObjectCancelled; } + bool IsFirstMoveSincePrintingResumed() const noexcept { return printingJustResumed; } + void DoneMoveSincePrintingResumed() noexcept { printingJustResumed = false; } + void StopPrinting(GCodeBuffer& gb) noexcept; + void ResumePrinting(GCodeBuffer& gb) noexcept; + + void Diagnostics(MessageType mtype, unsigned int moveSystemNumber) noexcept; + + // These variables are currently all public, but we ought to make most of them private Tool *currentTool; // the current tool of this movement system - AxesBitmap axesAndExtrudersOwned; // axes and extruders that this movement system has moved since the last sync - ParameterLettersBitmap ownedAxisLetters; // letters denoting axes that this movement system owns // The current user position now holds the requested user position after applying workplace coordinate offsets. // So we must subtract the workplace coordinate offsets when we want to display them. @@ -142,35 +177,22 @@ struct MovementState : public RawMove bool currentObjectCancelled; // true if the current object should not be printed bool printingJustResumed; // true if we have just restarted printing - float GetProportionDone() const noexcept; // get the proportion of this whole move that has been completed, based on segmentsLeft and totalSegments - void Reset() noexcept; - void ChangeExtrusionFactor(unsigned int extruder, float multiplier) noexcept; // change the extrusion factor of an extruder - const RestorePoint& GetRestorePoint(size_t n) const pre(n < NumTotalRestorePoints) { return restorePoints[n]; } - void ClearMove() noexcept; - void SavePosition(unsigned int restorePointNumber, size_t numAxes, float p_feedRate, FilePosition p_filePos) noexcept - pre(restorePointNumber < NumTotalRestorePoints); - - // Tool management - void SelectTool(int toolNumber, bool simulating) noexcept; - ReadLockedPointer<Tool> GetLockedCurrentTool() const noexcept; - ReadLockedPointer<Tool> GetLockedCurrentOrDefaultTool() const noexcept; - int GetCurrentToolNumber() const noexcept; - void SetPreviousToolNumber() noexcept; - AxesBitmap GetCurrentXAxes() const noexcept; // Get the current axes used as X axes - AxesBitmap GetCurrentYAxes() const noexcept; // Get the current axes used as Y axes - AxesBitmap GetCurrentAxisMapping(unsigned int axis) const noexcept; - float GetCurrentToolOffset(size_t axis) const noexcept; // Get an axis offset of the current tool +private: + AxesBitmap axesAndExtrudersOwned; // axes and extruders that this movement system has moved since the last sync + ParameterLettersBitmap ownedAxisLetters; // letters denoting axes that this movement system owns +}; - // Object cancellation support - void InitObjectCancellation() noexcept; - bool IsCurrentObjectCancelled() const noexcept { return currentObjectCancelled; } - bool IsFirstMoveSincePrintingResumed() const noexcept { return printingJustResumed; } - void DoneMoveSincePrintingResumed() noexcept { printingJustResumed = false; } - void StopPrinting(GCodeBuffer& gb) noexcept; - void ResumePrinting(GCodeBuffer& gb) noexcept; +inline void MovementState::AllocateAxes(AxesBitmap axes, ParameterLettersBitmap axisLetters) noexcept +{ + axesAndExtrudersOwned |= axes; + ownedAxisLetters |= axisLetters; +} - void Diagnostics(MessageType mtype, unsigned int moveSystemNumber) noexcept; -}; +// Stop claiming that we own an axis letter (if we do) but don't release the associated axis +inline void MovementState::ReleaseAxisLetter(char letter) noexcept +{ + ownedAxisLetters.ClearBit(ParameterLetterToBitNumber(letter)); +} #if SUPPORT_ASYNC_MOVES |