Repository navigation
Conversation
…ue (LinuxCNC#246) A wait (M66, G38, M6 epilog, M61, user M-codes) inside a subroutine or remap on a skipped line sent the queued commands to motion before the skip discarded them, so skipped code half-executed. While skipping, discard at every call level and let a wait neither send nor wait. The skip ends before the first main-program line at or after the start line (this also fixes run from line 1). #<_task_skipping> lets remaps skip their own work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aee4dec to
36de389
Compare
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dew does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for digging into this one. The core change looks right to me: discarding after every interpreter call at any depth, and not letting a wait flush the queue while skipping, is exactly the gap zultron described in #246. Nothing from skipped code should reach motion, and with this PR it doesn't. A few points. Please don't close #246 with this PR. I would change "Fixes #246" to "Part of #246". This PR stops skipped code from leaking out, which is necessary, but the issue discussion (andypugh's comments in particular) is about the larger question of what state the start line needs and who sets it up. Your three reviewer questions are that same question, and it stays open after this merges. Skipped probes now return stale results instead of re-probing. Inside a sub or remap, a skipped On On your three questions, I would not decide them in core. At |
Fixes #246.
When you run from a line, you expect every line before it to be skipped: nothing moves. Instead, if a skipped line calls a subroutine or remap that contains a wait (
M66,G38,M61, anM6remap, ...), movement can occur. Specifically, everything queued before the wait runs on the machine and everything after it is thrown away. In other words, the machine actually runs some of the "skipped" code buried in subroutines.Run this example from line 7, you expect X and Y to stay where they are. Instead X moves to 10, and Y stays at 0.
This happens because the skip and the queue disagree in
emctaskmain.cc. The skip throws the queue away only after a main-program line has finished (lines 624-641). A wait first sends the queue to the machine (lines 601-609). Lines 2-4 belong to line 6, so theM66on line 3 sends X before line 6 finishes.The fix: while skipping, throw the queue away after every interpreter call at any depth, and let a wait neither send nor wait. The fix is not perfect: the correct tool must still be in the spindle before you run from a line, as before. Would love to dig more, but for now, this improves the line resume functionality while still requiring the correct tool in spindle before resuming, consistent with the documentation ("it does not start the spindle or confirm the proper tool"). It does prevent disasters like portions of a tool change sequence executing. Other things that leak today: a skipped
G38probe moves,M61changes the tool number, and anM64output turns on and stays on.More details below.
Details
More examples: the same 7-line program with other contents inside
o100, run from its last line (M2). All results were predicted before the runs and measured in simulation.o100G0 X10,G0 Y10(no wait: the control)G0 X10,M66 P0 L0,G0 Y10,M66 P0 L0G0 X10,G38.3 Z-5,G0 Y10G0 X10,M61 Q14,G0 Y10M64 P0,M66 P1 L0,M65 P0The change (
emctaskmain.cc,interp_namedparams.cc):_task_skipping, is set by run from line. It ends just before the first main-program line at or after the start line, and is cleared at program end and on abort.#<_task_skipping>(read-only) lets a remap skip its own work.Behavior changes:
Questions for reviewers:
G38refuse the run or warn, since its result will be stale? (Refusing breaks configs whose M6 remap probes tool length.)Tests:
tests/motion-logger/run-from-line-wait(the example above: no skipped move may reach motion) andrun-from-line-first(from line 1 everything runs).mountaindewandbasicstill pass.