Align Web execute-next-line with LinuxCNC

This commit is contained in:
2026-09-10 08:30:04 +08:00
parent 0a202e5841
commit aac1ceb250
5 changed files with 226 additions and 17 deletions

View File

@@ -219,8 +219,53 @@ command are blocked instead of being silently mapped to another operation.
Step 从第 0 行启动并暂停;PAUSED 且有运动队列时调用 `emcTrajStep`,
按执行 ID 推进并再次暂停;无排队运动时释放下一条 task 指令。
`motion/control.c:2186` 在执行 ID 改变后暂停 TP,不能“解析一行后永久
冻结”,也不能一次 Step 把全部已排队运动执行完。Web 单步的源码行解析
与原生 NML 指令细分仍是需单独验证的适配边界,不能用行数相同替代运动断言。
冻结”,也不能一次 Step 把全部已排队运动执行完。Web 已将该边界映射为
`step_phase`、`step_source_line`、`step_target_id` 和
`step_waiting_for_motion`,并用 WASM execution-id/pose 断言,不以行数相同
替代运动完成。
---
### Execute-next-line 流程(源码复核 2026-09-10)
原生入口由 `axis.py:2354-2359` 的 `task_step()` 提供,工具栏
`axis.tcl:535-541` 和快捷键 `T` 都调用同一个函数。处理顺序固定为:
```text
T / toolbar Step
-> 清除编辑器高亮;若不是 AUTO+IDLE,执行 run_warn(),用户取消则结束
-> ensure_mode(AUTO)
-> c.auto(AUTO_STEP)
-> emcmodule.cc 将 AUTO_STEP 转为 EMC_TASK_PLAN_STEP_TYPE
-> emctaskmain 根据 interpState 选择 IDLE / READING / PAUSED / WAITING 分支
-> task/TP 在后续周期执行一个源码边界或一个当前 execution-id
-> motion/control.c 在 execution-id 改变时暂停 TP
-> 发布 current_line、execution_line、pose、joints、queue、stepping
```
| 分支 | 原生动作 | Web/WASM 动作 | 响应要求 |
|---|---|---|---|
| IDLE 首次 | `AUTO_RUN(line=0)`,随即 `emcTrajPause()`,保存恢复状态 | `WasmProgramRuntime.start()` 后立即 `pause()`;任务从 READY 进入 RUNNING 再进入 PAUSED | `step_phase=start_pause`,源码行 0,不产生运动 |
| READING | `stepping=1`、`steppingWait=0`,继续 readahead | 只解析一个 WASM canonical source block;有运动时入 TP 并调用 `stepLine()` | `step_phase=source_line_motion` 或 `source_line_pause`,返回 source line 和 `program_steps` |
| READING/WAITING 或 PAUSED + queue>0 | `stepping=1`;PAUSED 时调用 `emcTrajStep()` | 运行中的 interpreter 先保存为 PAUSED,再按当前 `active_id` 调用 `sim_linuxcnc_tp_step_line()` | `step_phase=motion_step`,`step_target_id` 固定,等待后续 SIM_STEP 到 execution-id 改变 |
| PAUSED + queue=0 | 释放 `interpResumeState`,保持 task_paused | 恢复 WASM interpreter,执行一个 source block,再暂停 | 不能重读已执行行;状态仍为 PAUSED |
| WAITING | 设置 stepping,等待队列/输入完成 | 保留 WAITING 的 program status;只推进尚未完成的 TP 或返回 terminal | 不能把 WAITING 改写成 READING |
| COMPLETED/ABORTED + queue=0 | task plan 可重新从 line 0 运行 | 先重载当前 source 到 loaded、恢复 STOPPED task,再执行 IDLE 首次分支 | `reopened_taskfile=true`,不得触发 STOPPED->RUNNING 非法转换 |
| stepping 已进行 | 原生 GUI 不应叠加新的运动步 | Web 重复请求返回幂等观察结果,不重复入队 | `step_phase=motion_step_pending`,保留原 `step_target_id` |
Web 的 `ui_gates.step` 必须保持源码公式 `STATE_ON && taskfile`,不能增加
IDLE-only 条件;WASM task gate 仍负责机器状态、回零、程序存在和 AUTO 模式。
Step 命令本身不推进 logical tick,运动只由后续 `SIM_STEP`/servo 周期推进。
一个 source block 产生的 canonical motion 必须在同一 Step 事务中进入 TP 并
进入 stepping;前端收到 `step_waiting_for_motion=true` 后启动已有的采样定时器。
命令结果必须包含 `program`、`task`、`wasm_motion`、`motion`、
`step_phase`、`step_source_line` 和 `step_target_id`(无目标时为 `null`),
以便程序行、执行 ID、轨迹和机床姿态可以共同审计。错误只返回稳定的
`axis_gate`、`program_step`、`motion_queue` 或 interpreter 错误,不改变已有
程序、TP 或 live-path epoch。
---
5. **回零采用原生 homemod。** `switchkins.c::kinematicsType()` 始终返回
`KINEMATICS_BOTH`,M429 不改变这一类型。世界轴字母不能作为回零目标;
`manual-home-joint-select` 明确选择数字关节,`manual-home-axis` 保留 ID,
@@ -345,7 +390,7 @@ safety adaptation, not attributed to AXIS.
| Run | `PROGRAM_RUN` | `run_warn`, `ensure_mode(AUTO)`, `AUTO_RUN` from the selected start line, then periodic task/TP ticks. Normal AXIS Run uses line 0. In `emctaskmain.cc`, an ended or aborted task plan is closed; the next `EMC_TASK_PLAN_RUN` reopens the current taskfile and runs from line 0. Therefore Run after `completed` or `aborted` must work directly and must not require a separate Reload/Restart click. |
| Run from selected line | not exposed | AXIS `task_run_line` requires an editor highlight and source `AUTO_RUN` start line. The Web editor has no source-line selection command yet, so no partial/fake button is rendered. |
| Reverse / Forward | not exposed | AXIS `task_reverse`/`task_forward` are keyboard-only source actions; the selected WASM program ABI has no corresponding command and Web preserves the distinction from Run. |
| Step | `PROGRAM_STEP` | `SOURCE_ADAPTER`: source toolbar gate is ON plus taskfile, not interpreter IDLE. `task_step` clears highlight/runs warning unless already AUTO+IDLE, ensures AUTO and sends `AUTO_STEP`. Task-layer homing remains authoritative. |
| Step | `PROGRAM_STEP` | `SOURCE_ADAPTER`: source toolbar gate is ON plus taskfile, not interpreter IDLE. `task_step` clears highlight/runs warning unless already AUTO+IDLE, ensures AUTO and sends `AUTO_STEP`. Worker publishes `step_phase` (`start_pause`, `source_line_pause`, `source_line_motion`, `motion_step`, `terminal`) with source line, execution ID, program/task/motion state. Task-layer homing remains authoritative. |
| Pause / Resume | `PROGRAM_PAUSE` / `PROGRAM_RESUME` | `SOURCE_ADAPTER`: `task_pause` accepts AUTO plus READING/WAITING. `task_resume` requires `paused` plus mode AUTO or MDI. The combined toolbar calls `task_pauseresume`, accepts AUTO or MDI, blocks resume when `resume_inhibit`, and otherwise pauses any non-IDLE interpreter. Web scheduling must serialize the edge but cannot change these state conditions. |
| Stop | `PROGRAM_ABORT` | AXIS enables Stop only while the interpreter is non-idle; then it highlights the active line, issues `c.abort()`, waits for completion, and clears the abort edge. The Worker may accept an internal abort edge in more states, but the Web button follows the AXIS UI gate. |
| Block delete / optional pause | disabled | LinuxCNC source has these controls, but the selected WASM ABI does not expose their canonical state. They are visible as disabled, with `blocked_by_abi`, and never emulate a local toggle. |
@@ -1000,6 +1045,9 @@ predicates (7488 assertions), rather than comparing two rewritten formulas.
motion Step, WAITING/MDI Pause-Resume, source OFF state, KINEMATICS_BOTH
world-axis rejection and spindle override 0-to-100 restoration using
the actual WASM runtime.
`web/worker/test_xyzac_step_flow.mjs` verifies the source-aligned Step phases,
immediate motion stepping, execution-id boundary completion, duplicate-step
idempotence, and completed/aborted task-plan reopen from line zero.
The exhaustive control-ID audit is enforced by
`scripts/test_axis_control_inventory.mjs` and
`scripts/test_axis_control_inventory_browser.mjs`; the latter rejects any