- LinuxCNC
- General LinuxCNC Questions
- Is there a public NML/status signal for completion of one EMC_TASK_PLAN_STEP?
Is there a public NML/status signal for completion of one EMC_TASK_PLAN_STEP?
- rhscdn
- Offline
- Senior Member
-
Less
More
- Posts: 40
- Thank you received: 7
07 Jul 2026 20:16 #347586
by rhscdn
Is there a public NML/status signal for completion of one EMC_TASK_PLAN_STEP? was created by rhscdn
I am working on a custom LinuxCNC UI and trying to understand whether EMC_TASK_PLAN_STEP can be given reliable “step completed” answer using only public LinuxCNC command/status/error channels.
The goal is not to step exactly one authored G-code source line. I understand LinuxCNC native step mode appears to operate on internal interpreter/motion boundaries, and these may not map 1:1 to G-code lines. Multiple G-code lines may combine into one motion item, and some lines such as modal changes or dwell may not produce motion identity changes.
What I am looking for is a public NML/status signal that reliably answers:
“The requested native step has reached its terminal boundary.”
I tested the following using command/status/error NML:
EMC_TASK_PLAN_STEP
EMC_TASK_PLAN_RUN
EMC_TASK_PLAN_PAUSE
EMC_TASK_PLAN_RESUME
EMC_TASK_PLAN_RUN from a specified line
status fields including task mode/state, interpreter state, exec state, task_paused, EMC_STAT.motion.traj.single_stepping, motion_line, current_line, read_line, motion_id, in-position, active file, command echo/serial, and the error channel.
Observed behavior:
EMC_TASK_PLAN_STEP in AUTO submits and echoes reliably.
EMC_TASK_PLAN_STEP in MANUAL also writes/echoes, then reports asynchronously through the error channel: can't do that (EMC_TASK_PLAN_STEP:511) in manual mode.
From idle/AUTO, the first PLAN_STEP appears to arm/pause state but does not expose line or motion advancement.
From paused queued motion, repeated PLAN_STEP can advance motion_line / motion_id, which is useful for motion items.
For dwell/non-motion cases, I did not find a reliable public line/motion/status transition that identifies completion of one native step.
EMC_STAT.motion.traj.single_stepping is public and useful, but it seems to represent persistent stepping mode/gate state. It can remain true after observed motion or non-motion boundaries, so it does not by itself delimit one requested step.
RUN -> PAUSE and RESUME -> PAUSE expose reliable running/paused transitions, but the amount of program read/queued/executed before pause takes effect is not bounded enough to call it a STEP.
RUN(line) -> PAUSE chooses a start line but does not provide a next-boundary terminal condition.
Looking at LinuxCNC task behavior, it seems the more precise native step gate may involve internal state such as steppingWait and steppedLine, but I do not see those exposed through public status.
My questions:
Is there an existing public NML/status field, Python linuxcnc.stat() field, or other supported API that indicates completion of one native EMC_TASK_PLAN_STEP request?
Is EMC_STAT.motion.traj.single_stepping intended only as a persistent stepping-mode flag, or can it be interpreted with other public fields to detect a completed native step?
Are steppingWait, steppedLine, or equivalent native step-boundary state intentionally private, or is there another public way to observe that same information?
For UI purposes, is it correct to expose EMC_TASK_PLAN_STEP only as a raw/native LinuxCNC step command without promising source-line or completion?
Is there a recommended command/status sequence used by AXIS, QtDragon, or other UIs to decide when a single native step has completed?
At this point, my conclusion is that PLAN_STEP can be exposed as a native control, but I should not claim reliable completion unless LinuxCNC exposes a per-request step boundary or stepped identity through public status. I would appreciate confirmation or correction from anyone familiar with the task/interpreter stepping internals.
Also, I wish there were a 'developer' forum where I could ask questions like these
The goal is not to step exactly one authored G-code source line. I understand LinuxCNC native step mode appears to operate on internal interpreter/motion boundaries, and these may not map 1:1 to G-code lines. Multiple G-code lines may combine into one motion item, and some lines such as modal changes or dwell may not produce motion identity changes.
What I am looking for is a public NML/status signal that reliably answers:
“The requested native step has reached its terminal boundary.”
I tested the following using command/status/error NML:
EMC_TASK_PLAN_STEP
EMC_TASK_PLAN_RUN
EMC_TASK_PLAN_PAUSE
EMC_TASK_PLAN_RESUME
EMC_TASK_PLAN_RUN from a specified line
status fields including task mode/state, interpreter state, exec state, task_paused, EMC_STAT.motion.traj.single_stepping, motion_line, current_line, read_line, motion_id, in-position, active file, command echo/serial, and the error channel.
Observed behavior:
EMC_TASK_PLAN_STEP in AUTO submits and echoes reliably.
EMC_TASK_PLAN_STEP in MANUAL also writes/echoes, then reports asynchronously through the error channel: can't do that (EMC_TASK_PLAN_STEP:511) in manual mode.
From idle/AUTO, the first PLAN_STEP appears to arm/pause state but does not expose line or motion advancement.
From paused queued motion, repeated PLAN_STEP can advance motion_line / motion_id, which is useful for motion items.
For dwell/non-motion cases, I did not find a reliable public line/motion/status transition that identifies completion of one native step.
EMC_STAT.motion.traj.single_stepping is public and useful, but it seems to represent persistent stepping mode/gate state. It can remain true after observed motion or non-motion boundaries, so it does not by itself delimit one requested step.
RUN -> PAUSE and RESUME -> PAUSE expose reliable running/paused transitions, but the amount of program read/queued/executed before pause takes effect is not bounded enough to call it a STEP.
RUN(line) -> PAUSE chooses a start line but does not provide a next-boundary terminal condition.
Looking at LinuxCNC task behavior, it seems the more precise native step gate may involve internal state such as steppingWait and steppedLine, but I do not see those exposed through public status.
My questions:
Is there an existing public NML/status field, Python linuxcnc.stat() field, or other supported API that indicates completion of one native EMC_TASK_PLAN_STEP request?
Is EMC_STAT.motion.traj.single_stepping intended only as a persistent stepping-mode flag, or can it be interpreted with other public fields to detect a completed native step?
Are steppingWait, steppedLine, or equivalent native step-boundary state intentionally private, or is there another public way to observe that same information?
For UI purposes, is it correct to expose EMC_TASK_PLAN_STEP only as a raw/native LinuxCNC step command without promising source-line or completion?
Is there a recommended command/status sequence used by AXIS, QtDragon, or other UIs to decide when a single native step has completed?
At this point, my conclusion is that PLAN_STEP can be exposed as a native control, but I should not claim reliable completion unless LinuxCNC exposes a per-request step boundary or stepped identity through public status. I would appreciate confirmation or correction from anyone familiar with the task/interpreter stepping internals.
Also, I wish there were a 'developer' forum where I could ask questions like these
Please Log in or Create an account to join the conversation.
- rodw
-
- Offline
- Platinum Member
-
Less
More
- Posts: 11994
- Thank you received: 4084
08 Jul 2026 08:27 #347593
by rodw
Replied by rodw on topic Is there a public NML/status signal for completion of one EMC_TASK_PLAN_STEP?
In master branch 2.10, there is a pin called motion.interp.line-number which is a real time reading of the line number.
As you pointed out some commands do not move the tool. These could be deduced from motion.interp.motion-type
Ref: linuxcnc.org/docs/devel/html/en/man/man9/motion.9.html
A change of line number reliably indicates the end of the motion segment.
I coded this and I don't think that a motion segment extends over multiple lines. However, the current position will deviate from the Gcode commanded position for a number of reasons. I saw this when testing where an arc was followed by a straight line. In this case, the path is blended to transition based on look ahead planning, G64 settings etc.
Briefly, Gcode lines are read into a tokenised buffer and discarded (eg an old fashioned circular buffer). Then the trajectory planner converts the buffer one entry at a time. A single line of code might take quite some time to execute so conversion can be hundreds of lines behind. Ref github.com/LinuxCNC/linuxcnc/blob/master...gc/interp_convert.cc
Until recently there was no way for motion to read interpreter data. But now each motion segment is tagged with the interpreter state when its converted. Ref: github.com/LinuxCNC/linuxcnc/blob/master...c/motion/state_tag.h
My motion.interp pins added additional fields to the state tags which are then decoded in real time in motion so the data changes on every tick of the servo thread.
Hope that helps.
As you pointed out some commands do not move the tool. These could be deduced from motion.interp.motion-type
Ref: linuxcnc.org/docs/devel/html/en/man/man9/motion.9.html
A change of line number reliably indicates the end of the motion segment.
I coded this and I don't think that a motion segment extends over multiple lines. However, the current position will deviate from the Gcode commanded position for a number of reasons. I saw this when testing where an arc was followed by a straight line. In this case, the path is blended to transition based on look ahead planning, G64 settings etc.
Briefly, Gcode lines are read into a tokenised buffer and discarded (eg an old fashioned circular buffer). Then the trajectory planner converts the buffer one entry at a time. A single line of code might take quite some time to execute so conversion can be hundreds of lines behind. Ref github.com/LinuxCNC/linuxcnc/blob/master...gc/interp_convert.cc
Until recently there was no way for motion to read interpreter data. But now each motion segment is tagged with the interpreter state when its converted. Ref: github.com/LinuxCNC/linuxcnc/blob/master...c/motion/state_tag.h
My motion.interp pins added additional fields to the state tags which are then decoded in real time in motion so the data changes on every tick of the servo thread.
Hope that helps.
Please Log in or Create an account to join the conversation.
- rhscdn
- Offline
- Senior Member
-
Less
More
- Posts: 40
- Thank you received: 7
08 Jul 2026 13:50 - 08 Jul 2026 13:54 #347595
by rhscdn
Replied by rhscdn on topic Is there a public NML/status signal for completion of one EMC_TASK_PLAN_STEP?
Thanks Rod,
A few months ago I mentioned that I was working on an experiment to add a C++ interface layer for LinuxCNC UIs. The lower layer wraps LinuxCNC’s NML command/status channels and HAL polling, and then a higher-level controller layer sits on top of that to coordinate UI commands, wait for observable LinuxCNC state changes, and avoid treating command writes or echoes as completion. The same core can then support a local Node/N-API (or Python) UI and a WebSocket interface for remote clients, as long as those clients route machine-control actions through that higher-level command layer rather than bypassing it with raw NML calls.
As part of this, I am trying to make the higher-level UI commands report completion only when LinuxCNC has actually reached an observable machine/controller state, rather than when a command write succeeds or when command echo advances. For example, cycle start, pause, resume, stop, program load/reload, override changes, spindle state, WCS selection, and touch-off can all be treated this way because there is some later status observation that confirms the requested result.
`EMC_TASK_PLAN_STEP` is the current problem child. I do not want to say “step completed” merely because `PLAN_STEP` was accepted or echoed. I would prefer some public status/HAL indication that the requested native step has reached its end/completion.
Your suggestion about `motion.interp.line-number` and `motion.interp.motion-type` was helpful. The pins do exactly what you described for motion segments. They track the trajectory planner’s executing interpreter metadata, distinguish arc/linear motion, and in my probe they updated slightly ahead of the corresponding NML `motion_line` / `motion_id` fields. In an arc-followed-by-line test, the line/type changed at the blended segment boundary, which is very useful for execution display and diagnostics.
However, I do not think they solve the general completion problem for native STEP. In dwell or other non-motion STEP cases, `motion.interp.line-number` and `motion.interp.motion-type` did not change, so I still could not distinguish a completed non-motion native step from waiting, arming, or stale motion metadata. In an invalid MANUAL `PLAN_STEP` case, the command still wrote/echoed, the HAL interp pins stayed stale, and the asynchronous error channel was still required to detect the rejection.
So my current conclusion is:
* `motion.interp.*` is very useful for showing the currently executing motion segment.
* It is better timed than the NML motion-line fields in some cases.
* It does not appear to provide a per-request completion signal for `EMC_TASK_PLAN_STEP`.
* It does not cover dwell/non-motion interpreter items.
* It does not replace the error channel for rejected step requests.
For a UI that claims “STEP completed,” I think I would still need LinuxCNC to expose something closer to a public stepped-item sequence, stepped-line identity, or native step gate-closure signal that covers both motion and non-motion interpreter items.
Does that match your understanding of how `PLAN_STEP`, `steppingWait`, `steppedLine`, and the motion state tags fit together? Or is there another public field or HAL pin I should be watching for the non-motion STEP cases?
A few months ago I mentioned that I was working on an experiment to add a C++ interface layer for LinuxCNC UIs. The lower layer wraps LinuxCNC’s NML command/status channels and HAL polling, and then a higher-level controller layer sits on top of that to coordinate UI commands, wait for observable LinuxCNC state changes, and avoid treating command writes or echoes as completion. The same core can then support a local Node/N-API (or Python) UI and a WebSocket interface for remote clients, as long as those clients route machine-control actions through that higher-level command layer rather than bypassing it with raw NML calls.
As part of this, I am trying to make the higher-level UI commands report completion only when LinuxCNC has actually reached an observable machine/controller state, rather than when a command write succeeds or when command echo advances. For example, cycle start, pause, resume, stop, program load/reload, override changes, spindle state, WCS selection, and touch-off can all be treated this way because there is some later status observation that confirms the requested result.
`EMC_TASK_PLAN_STEP` is the current problem child. I do not want to say “step completed” merely because `PLAN_STEP` was accepted or echoed. I would prefer some public status/HAL indication that the requested native step has reached its end/completion.
Your suggestion about `motion.interp.line-number` and `motion.interp.motion-type` was helpful. The pins do exactly what you described for motion segments. They track the trajectory planner’s executing interpreter metadata, distinguish arc/linear motion, and in my probe they updated slightly ahead of the corresponding NML `motion_line` / `motion_id` fields. In an arc-followed-by-line test, the line/type changed at the blended segment boundary, which is very useful for execution display and diagnostics.
However, I do not think they solve the general completion problem for native STEP. In dwell or other non-motion STEP cases, `motion.interp.line-number` and `motion.interp.motion-type` did not change, so I still could not distinguish a completed non-motion native step from waiting, arming, or stale motion metadata. In an invalid MANUAL `PLAN_STEP` case, the command still wrote/echoed, the HAL interp pins stayed stale, and the asynchronous error channel was still required to detect the rejection.
So my current conclusion is:
* `motion.interp.*` is very useful for showing the currently executing motion segment.
* It is better timed than the NML motion-line fields in some cases.
* It does not appear to provide a per-request completion signal for `EMC_TASK_PLAN_STEP`.
* It does not cover dwell/non-motion interpreter items.
* It does not replace the error channel for rejected step requests.
For a UI that claims “STEP completed,” I think I would still need LinuxCNC to expose something closer to a public stepped-item sequence, stepped-line identity, or native step gate-closure signal that covers both motion and non-motion interpreter items.
Does that match your understanding of how `PLAN_STEP`, `steppingWait`, `steppedLine`, and the motion state tags fit together? Or is there another public field or HAL pin I should be watching for the non-motion STEP cases?
Last edit: 08 Jul 2026 13:54 by rhscdn.
Please Log in or Create an account to join the conversation.
- rodw
-
- Offline
- Platinum Member
-
Less
More
- Posts: 11994
- Thank you received: 4084
09 Jul 2026 00:37 #347615
by rodw
Replied by rodw on topic Is there a public NML/status signal for completion of one EMC_TASK_PLAN_STEP?
I think we are working at seperate parts of the code base. I suspect the info you want is probably thrown away after its buffered but I've never looked. You could look at adding your own NML as described here
linuxcnc.org/docs/stable/html/code/code-notes.html
The diagrams are also pertinent
What is visible in real time (motion) is limited to what's in state_tag.h I linked to and its populated in interp_convert.cc.
There is a high level API based on my ideas using gRPC but we've not tested anything. Its limited to what's available in the Python API
github.com/joco-nz/linuxcnc-Headless-UI
This is designed to address the authentication and security constructs the modern connected world demands.
There is also an effort to use a standards based methodology used by Haas and others but I have not been able to discuss it with the author at this stage. But we will schedule that in the short term.
linuxcnc.org/docs/stable/html/code/code-notes.html
The diagrams are also pertinent
What is visible in real time (motion) is limited to what's in state_tag.h I linked to and its populated in interp_convert.cc.
There is a high level API based on my ideas using gRPC but we've not tested anything. Its limited to what's available in the Python API
github.com/joco-nz/linuxcnc-Headless-UI
This is designed to address the authentication and security constructs the modern connected world demands.
There is also an effort to use a standards based methodology used by Haas and others but I have not been able to discuss it with the author at this stage. But we will schedule that in the short term.
Please Log in or Create an account to join the conversation.
- LinuxCNC
- General LinuxCNC Questions
- Is there a public NML/status signal for completion of one EMC_TASK_PLAN_STEP?
Time to create page: 0.085 seconds