Problem
The trajectory planner (src/emc/tp/, both TP 0 and TP 1) halves acceleration on segments that never actually blend:
- single MDI move / one-line program: half accel the whole move
- first segment: half accel from rest
- last segment before M2 / M0 / G4: half accel decelerating to a stop
Corner blending is correct and must keep the half. Only the non-overlapping parts are wasted.
Cause
tcGetOverallMaxAccel() in src/emc/tp/tc.c halves on a flag, not an active overlap:
if (tc->blend_prev || TC_TERM_COND_PARABOLIC == tc->term_cond) {
a_scale *= 0.5;
}
Under G64, term_cond defaults to PARABOLIC on every new segment (optimistic "might blend next"), so a lone move is halved. blend_prev halves the last segment across its whole length, including the final stop.
The per-segment maxaccel from canon (getStraightAcceleration, acc = dtot / tmax) already respects every joint limit for that direction, so a single moving segment at full accel violates nothing. The half is only needed during a real parabolic overlap, where two segments accelerate at once and per-axis contributions add.
Intentional but never revisited
tests/motion/g0/checkresult asserts a lone G0 reaches exactly half accel, with the comment "emc2 reserves half the acceleration for blending". Added 2011 (c649836). So it is long standing and deliberate, but a conservative simplification.
Fix (prototyped)
Gate the half on an actual overlap instead of the flag. Keep tcGetOverallMaxAccel reduced for corner-speed sizing; add tcGetCycleMaxAccel(tc, in_overlap) for the per-cycle motion cap, applying half only while the segment overlaps a neighbor in an active blend.
runtests tests/abort tests/motion tests/lathe: 9/10 pass. Only tests/motion/g0 fails, because the lone rapid now uses full accel; that test needs updating to the new behavior.
Questions
- Fix this, or is the half relied on somewhere?
- OK to update
tests/motion/g0 to expect full accel on a lone move?
- Follow-up: replace the worst-case 0.5 with a geometry-aware per-axis scale during real overlaps?
Problem
The trajectory planner (
src/emc/tp/, both TP 0 and TP 1) halves acceleration on segments that never actually blend:Corner blending is correct and must keep the half. Only the non-overlapping parts are wasted.
Cause
tcGetOverallMaxAccel()insrc/emc/tp/tc.chalves on a flag, not an active overlap:Under G64,
term_conddefaults to PARABOLIC on every new segment (optimistic "might blend next"), so a lone move is halved.blend_prevhalves the last segment across its whole length, including the final stop.The per-segment
maxaccelfrom canon (getStraightAcceleration,acc = dtot / tmax) already respects every joint limit for that direction, so a single moving segment at full accel violates nothing. The half is only needed during a real parabolic overlap, where two segments accelerate at once and per-axis contributions add.Intentional but never revisited
tests/motion/g0/checkresultasserts a loneG0reaches exactly half accel, with the comment "emc2 reserves half the acceleration for blending". Added 2011 (c649836). So it is long standing and deliberate, but a conservative simplification.Fix (prototyped)
Gate the half on an actual overlap instead of the flag. Keep
tcGetOverallMaxAccelreduced for corner-speed sizing; addtcGetCycleMaxAccel(tc, in_overlap)for the per-cycle motion cap, applying half only while the segment overlaps a neighbor in an active blend.runtests tests/abort tests/motion tests/lathe: 9/10 pass. Onlytests/motion/g0fails, because the lone rapid now uses full accel; that test needs updating to the new behavior.Questions
tests/motion/g0to expect full accel on a lone move?