Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarkmaker <mark@makr.zone>2021-02-05 16:40:34 +0300
committerGitHub <noreply@github.com>2021-02-05 16:40:34 +0300
commit4ddc6328895b0bcd727bec09793fcb3110046e59 (patch)
tree61b4bd44c88913043edf6dc94bfbd03afdb808d8 /src/Movement
parent21085888ef5917fa424bdabfe86c37392464c14e (diff)
Feature / Configurable Grace Period for Starting into Moves (#471)
* Added M595 Rnn word to set the grace period, that is waited out before starting moves. The R word is given in milliseconds and it controls the idle time after receiving the last move command to process. This will make sure fine-grained move sequences will be received in full and can be look-ahead-planned properly, right to the end. This option has been introduced after it was demonstrated that Duet would rush into premature deceleration on fine-grained interpolation move sequences send from OpenPnP. De to their nature, these motion sequences typically need to be look-ahead-planned in full, otherwise they will be degraded. Note that M400 (and others) will release the motion sequence immediately. A motion sequence closed with M400 will therefore incur no additional wait time (once the commands have been received). * Changes, as indicated by dc42
Diffstat (limited to 'src/Movement')
-rw-r--r--src/Movement/DDARing.cpp10
-rw-r--r--src/Movement/DDARing.h2
-rw-r--r--src/Movement/Move.cpp7
-rw-r--r--src/Movement/Move.h1
4 files changed, 16 insertions, 4 deletions
diff --git a/src/Movement/DDARing.cpp b/src/Movement/DDARing.cpp
index dad6f4e8..100445d4 100644
--- a/src/Movement/DDARing.cpp
+++ b/src/Movement/DDARing.cpp
@@ -18,7 +18,7 @@
constexpr uint32_t UsualMinimumPreparedTime = StepTimer::StepClockRate/10; // 100ms
constexpr uint32_t AbsoluteMinimumPreparedTime = StepTimer::StepClockRate/20; // 50ms
-DDARing::DDARing() noexcept : scheduledMoves(0), completedMoves(0), numHiccups(0)
+DDARing::DDARing() noexcept : gracePeriod(0), scheduledMoves(0), completedMoves(0), numHiccups(0)
{
}
@@ -99,6 +99,7 @@ GCodeResult DDARing::ConfigureMovementQueue(GCodeBuffer& gb, const StringRef& re
uint32_t numDdasWanted = 0, numDMsWanted = 0;
gb.TryGetUIValue('P', numDdasWanted, seen);
gb.TryGetUIValue('S', numDMsWanted, seen);
+ gb.TryGetUIValue('R', gracePeriod, seen);
if (seen)
{
if (!reprap.GetGCodes().LockMovementAndWaitForStandstill(gb))
@@ -143,7 +144,7 @@ GCodeResult DDARing::ConfigureMovementQueue(GCodeBuffer& gb, const StringRef& re
}
else
{
- reply.printf("DDAs %u, DMs %u", numDdasInRing, DriveMovement::NumCreated());
+ reply.printf("DDAs %u, DMs %u, GracePeriod %" PRIu32, numDdasInRing, DriveMovement::NumCreated(), gracePeriod);
}
return GCodeResult::ok;
}
@@ -357,6 +358,11 @@ bool DDARing::IsIdle() const noexcept
return currentDda == nullptr && getPointer->GetState() == DDA::empty;
}
+uint32_t DDARing::GetGracePeriod() const noexcept
+{
+ return gracePeriod;
+}
+
// Try to push some babystepping through the lookahead queue, returning the amount pushed
float DDARing::PushBabyStepping(size_t axis, float amount) noexcept
{
diff --git a/src/Movement/DDARing.h b/src/Movement/DDARing.h
index d386a176..f0725c27 100644
--- a/src/Movement/DDARing.h
+++ b/src/Movement/DDARing.h
@@ -31,6 +31,7 @@ public:
void Spin(uint8_t simulationMode, bool shouldStartMove) noexcept SPEED_CRITICAL; // Try to process moves in the ring
bool IsIdle() const noexcept; // Return true if this DDA ring is idle
+ uint32_t GetGracePeriod() const noexcept; // Return the minimum idle time, before we should start a move. Better to have a few moves in the queue so that we can do lookahead
float PushBabyStepping(size_t axis, float amount) noexcept; // Try to push some babystepping through the lookahead queue, returning the amount pushed
@@ -106,6 +107,7 @@ private:
volatile int32_t liveEndPoints[MaxAxesPlusExtruders]; // The XYZ endpoints of the last completed move in motor coordinates
unsigned int numDdasInRing;
+ uint32_t gracePeriod; // The minimum idle time, before we should start a move. Better to have a few moves in the queue so that we can do lookahead
uint32_t scheduledMoves; // Move counters for the code queue
volatile uint32_t completedMoves; // This one is modified by an ISR, hence volatile
diff --git a/src/Movement/Move.cpp b/src/Movement/Move.cpp
index e5504fbb..4b1f5d63 100644
--- a/src/Movement/Move.cpp
+++ b/src/Movement/Move.cpp
@@ -195,6 +195,7 @@ void Move::Init() noexcept
moveState = MoveState::idle;
lastStateChangeTime = millis();
idleCount = 0;
+ idleStartTime = lastStateChangeTime;
simulationMode = 0;
longestGcodeWaitInterval = 0;
@@ -284,11 +285,12 @@ void Move::Spin() noexcept
if (mainDDARing.AddStandardMove(nextMove, !IsRawMotorMove(nextMove.moveType)))
{
+ const uint32_t now = millis();
idleCount = 0;
+ idleStartTime = now;
if (moveState == MoveState::idle || moveState == MoveState::timing)
{
moveState = MoveState::collecting;
- const uint32_t now = millis();
const uint32_t timeWaiting = now - lastStateChangeTime;
if (timeWaiting > longestGcodeWaitInterval)
{
@@ -302,7 +304,8 @@ void Move::Spin() noexcept
}
}
- mainDDARing.Spin(simulationMode, idleCount > 10); // let the DDA ring process moves. Better to have a few moves in the queue so that we can do lookahead, hence the test on idleCount.
+ // let the DDA ring process moves. Better to have a few moves in the queue so that we can do lookahead, hence the test on idleCount and idleTime.
+ mainDDARing.Spin(simulationMode, idleCount > 10 && millis() - idleStartTime >= mainDDARing.GetGracePeriod());
#if SUPPORT_ASYNC_MOVES
if (auxMoveAvailable && auxDDARing.CanAddMove())
diff --git a/src/Movement/Move.h b/src/Movement/Move.h
index 60a49235..5f01e390 100644
--- a/src/Movement/Move.h
+++ b/src/Movement/Move.h
@@ -250,6 +250,7 @@ private:
unsigned int jerkPolicy; // When we allow jerk
unsigned int idleCount; // The number of times Spin was called and had no new moves to process
+ uint32_t idleStartTime; // the time when we started to idle
uint32_t longestGcodeWaitInterval; // the longest we had to wait for a new GCode
float tangents[3]; // Axis compensation - 90 degrees + angle gives angle between axes