Skip to content

Commit 7599653

Browse files
author
Luca Toniolo
committed
fix premature FINALIZED gate on G-code mode change
G64/G61 mode changes called tpFlushCompressor_9D which sealed the queue, causing the optimizer to finalize the tail segment immediately with wrong boundary conditions (full length, vf=0) before the successor segment and its blend trimming arrived. RT would then activate the segment, accelerate to cruise speed, and when the blend later trimmed the segment to ~half its length, Ruckig had to emergency-brake in the tiny remaining distance — producing a jerk spike. Fix: add tpFlushCompressorNoSeal_9D that flushes the compressor without setting queue_sealed. Used for mode changes where new motion immediately follows. tpFlushCompressor_9D (with seal) is reserved for true sync points: dwell, M0/M1, program end.
1 parent 830f610 commit 7599653

File tree

3 files changed

+24
-6
lines changed

3 files changed

+24
-6
lines changed

src/emc/motion_planning/motion_planning_9d_userspace.cc

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,16 +241,29 @@ extern "C" int tpFlushCompressor_9D(TP_STRUCT *tp)
241241
{
242242
int result = compressorFlush(tp);
243243

244-
// Seal the queue: interpreter is at a sync point (tool change, dwell,
245-
// mode change, program end). No more motion segments are coming until
246-
// the next tpAddLine_9D/tpAddCircle_9D call clears this flag.
247-
// This lets the optimizer finalize the tail segment immediately.
244+
// Seal the queue: interpreter is at a true sync point (dwell, tool
245+
// change, M0/M1, program end). No more motion will arrive until the
246+
// next tpAddLine_9D/tpAddCircle_9D clears this flag. Lets the
247+
// optimizer finalize the tail segment immediately.
248248
tp->queue_sealed = 1;
249249
g_needs_replan = true;
250250

251251
return result;
252252
}
253253

254+
extern "C" int tpFlushCompressorNoSeal_9D(TP_STRUCT *tp)
255+
{
256+
// Flush compressor (emit any buffered segments) but do NOT seal the
257+
// queue. Used for G-code mode changes (G64, G61, tolerance updates)
258+
// where new motion segments are expected immediately after.
259+
// Sealing here would cause the optimizer to prematurely finalize the
260+
// tail segment with wrong boundary conditions before the successor
261+
// segment and its blend trimming arrive.
262+
int result = compressorFlush(tp);
263+
g_needs_replan = true;
264+
return result;
265+
}
266+
254267
/**
255268
* @brief Reset compressor state without flushing (discard any buffered segments).
256269
*

src/emc/task/taskintf.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1629,7 +1629,11 @@ int emcTrajSetTermCond(int cond, double tolerance)
16291629
if (tp) {
16301630
// Flush segment compressor before mode change — buffered segments
16311631
// were accumulated under the old mode/tolerance.
1632-
tpFlushCompressor_9D(tp);
1632+
// Use NoSeal variant: new motion segments are expected immediately
1633+
// after the mode change, so the queue is NOT at a sync boundary.
1634+
// tpFlushCompressor_9D (with seal) would prematurely finalize the
1635+
// tail segment before its blend trimming arrives, causing a spike.
1636+
tpFlushCompressorNoSeal_9D(tp);
16331637
tp->termCond = cond;
16341638
tp->tolerance = tolerance;
16351639
}

src/emc/tp/tp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ int tpAddDwell(TP_STRUCT * const tp, double seconds, struct state_tag_t tag);
102102
* Emits any buffered compressed segment. Call at program end, mode changes,
103103
* or before non-line segments (circles, dwells).
104104
*/
105-
int tpFlushCompressor_9D(TP_STRUCT *tp);
105+
int tpFlushCompressor_9D(TP_STRUCT *tp); /* flush + seal (sync points only) */
106+
int tpFlushCompressorNoSeal_9D(TP_STRUCT *tp); /* flush only, no seal (mode changes) */
106107
void tpResetCompressor_9D(void);
107108

108109
/**

0 commit comments

Comments
 (0)