Files
cnc_wams/web-rtcp-5axis-xyzbc-trt-sim-plan/working/20-20260707-AXIS按钮LinuxCNC真实C++对标实施步骤.md
2026-07-07 18:45:26 -04:00

12 KiB
Raw Blame History

2026-07-07 AXIS 按钮 LinuxCNC 真实 C++ 对标实施步骤

1. 实施原则

本文件由 19-20260707-AXIS按钮LinuxCNC-task-motion状态机制源码分析.md 拆分而来,目标是把源码分析转成可执行的工程步骤。后续实现不能以 compare 60/60 pass 作为功能完成依据;60/60 pass 只能说明当前 compare 规则没有发现问题。真实合格标准必须是Web 项目的按钮、状态、Task/HAL/WASM、evidence 和 UI 行为逐项符合 LinuxCNC C++ task/motion/homing 的真实实现。

权威基线:

  • LinuxCNC 源码:/home/mes123456/cnc_wams/linuxcnc
  • 目标项目:/home/mes123456/cnc_wams/web-rtcp-5axis-xyzbc-trt-sim-plan
  • 核心 C++ 对标文件:
    • linuxcnc/src/emc/task/emctaskmain.cc
    • linuxcnc/src/emc/task/emctask.cc
    • linuxcnc/src/emc/task/taskintf.cc
    • linuxcnc/src/emc/motion/command.c
    • linuxcnc/src/emc/motion/control.c
    • linuxcnc/src/emc/motion/homing.c
    • linuxcnc/src/emc/nml_intf/emc.hh
    • linuxcnc/src/emc/nml_intf/emc_nml.hh

2. 实施输出物

必须形成以下输出物:

输出物 目标
C++ 行为映射表 每个按钮对应 LinuxCNC 源码入口、NML 命令、task 处理、motion 处理、状态字段
Web 状态字段表 machine.taskState/mode/interpState/... 与 LinuxCNC EMC_STAT 字段一一对应
Task/HAL/WASM 命令 ABI EMC_TASK_SET_STATEEMC_TASK_SET_MODEEMC_JOINT_HOMEEMC_TASK_PLAN_RUN/PAUSE/RESUME/STEP 的 JSON 输入输出
硬门禁测试 不允许只靠 UI disabled必须验证底层 task runtime 拒绝非法命令
真实程序执行证据 用真实 G-code、真实 line/motion id、真实状态流证明 Run/Pause/Step/Home 行为
compare 增强规则 compare 不只检查字段存在和误差,还检查 C++ 状态机不可变规则

3. 阶段 1固定 LinuxCNC C++ 源码事实

3.1 建立源码事实清单

实施步骤:

  1. 在工作文档中建立 按钮 -> AXIS Python -> emcmodule -> NML -> emctaskmain -> emctask/taskintf -> motion 的链路表。
  2. 每条链路必须标注具体源码文件和函数名。
  3. 每条链路必须标注输入命令、先决条件、状态变更、错误路径。

必须覆盖:

  • 急停:axis.py estop_clicked()EMC_TASK_SET_STATEemcTaskSetState(ESTOP/ESTOP_RESET)
  • 上电/下电:axis.py onoff_clicked()emcTaskSetState(ON/OFF)EMCMOT_ENABLE/DISABLE
  • Homehome_all_joints()home_joint()EMC_JOINT_HOMEEMCMOT_JOINT_HOMEhoming.c
  • Runtask_run()EMC_TASK_PLAN_RUNall_homed()programStartLineinterpState=READING
  • Pause/Resumetask_pause()task_pauseresume()EMC_TASK_PLAN_PAUSE/RESUMEEMCMOT_PAUSE/RESUME
  • Steptask_step()EMC_TASK_PLAN_STEPsteppingsingle_steppingEMCMOT_STEP、motion id 变化后再暂停。

完成标准:

  • 任一 Web 状态或测试断言都能追溯到 LinuxCNC C++ 源码。
  • 没有“按前端习惯推测”的状态规则。

3.2 建立状态字段对应关系

实施步骤:

  1. 对照 EMC_STAT.taskmotion.trajmotion.joint[] 建立 Web 字段映射。
  2. 区分 task 层暂停和 motion 层暂停。
  3. 区分 task state 命令请求和最终发布状态。

必须字段:

machine: {
  taskState: "estop" | "estop-reset" | "on",
  mode: "manual" | "auto" | "mdi",
  interpState: "idle" | "reading" | "paused" | "waiting",
  interpResumeState: "idle" | "reading" | "waiting",
  execState: "done" | "waiting-for-motion" | "waiting-for-io" | "waiting-for-motion-and-io" | "error",
  taskPaused: boolean,
  motionPaused: boolean,
  singleStepping: boolean,
  motionStepping: boolean,
  motionEnabled: boolean,
  homing: boolean,
  homed: boolean[],
  allHomed: boolean,
  noForceHoming: boolean,
  resumeInhibit: boolean,
  currentLine: number,
  readLine: number,
  motionLine: number
}

完成标准:

  • taskState 不再只从 powerOn 派生,而是符合 LinuxCNC “IO estop + motion enabled” 语义。
  • paused 不再是单字段,必须拆成 interpState/taskPaused/motionPaused
  • Step 不再只用 sampleIndex + 1 表示,必须能表达 singleStepping/motionStepping/motion id

4. 阶段 2实现 Task/HAL/WASM 真实状态机

4.1 实现 NML 命令 ABI

实施文件:

  • wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_task_hal_wasm.cpp
  • wasm-port/runtime/sdk/src/linuxcnc-task-hal.js
  • web-rtcp-5axis-xyzbc-trt-sim-plan/app/src/runtime/linuxcnc-task-hal-runtime.js

实施步骤:

  1. 统一 JSON 命令名称为 LinuxCNC NML 名称。
  2. 每条命令返回 command accepted/rejected、operator error、状态快照。
  3. 非法命令必须在 runtime 层拒绝,不能只靠 UI gate。

命令要求:

命令 必须实现的 C++ 语义
EMC_TASK_SET_STATE ESTOP abort motion/task/io/spindledisable motion清 pause/stepvolatile home 处理
EMC_TASK_SET_STATE ESTOP_RESET IO estop offmachine offabort/synch
EMC_TASK_SET_STATE ON motion enable只有 enable 成功后最终 state 才是 on
EMC_TASK_SET_STATE OFF abort、disable、清运行、清 pause/step、volatile unhome
EMC_TASK_SET_MODE MANUAL AUTO 非 idle 时拒绝或必须按 LinuxCNC abort/close/synch 语义处理
EMC_TASK_SET_MODE AUTO/MDI motion coord mode、abort、plan synch
EMC_JOINT_HOME 只在 on/manual/free/idle/非 homing/homing-inhibit=false 时启动
EMC_TASK_PLAN_RUN on/auto/idle/homed/program open/motion plan loaded
EMC_TASK_PLAN_PAUSE 保存 interpResumeStatetask paused + motion paused
EMC_TASK_PLAN_RESUME 恢复 interpResumeState,清 single stepping
EMC_TASK_PLAN_STEP idle step 等价 run 后 pausepaused step 放行到下一个 motion id

完成标准:

  • Runtime 层能在无 UI 的 Node 测试中复现所有先决条件和状态变化。
  • 任一非法命令都有明确错误消息,且状态保持不被破坏。

4.2 实现 Home 状态机

实施步骤:

  1. 增加 per-joint homed[]homing[]homeState[]
  2. Home All 使用 joint=-1
  3. Home 过程至少记录 HOME_START -> HOME_FINISHED/HOME_IDLE 的可观测状态。
  4. 正在 homing 时再次 Home 必须拒绝。
  5. 下电/急停只清 LinuxCNC 语义中应清的 home 状态;若当前 Web 无 volatile home 配置,必须显式记录简化边界。

完成标准:

  • Home All 后所有 active joints homed[] = true
  • Home 期间 Run、Step、Jog、再次 Home 都被拒绝。
  • Evidence 能看到 homing 瞬态,不允许直接静默从 unhomed 跳到 homed 而无事件记录。

4.3 实现 Pause/Resume/Step 真实 motion 语义

实施步骤:

  1. Pause 时冻结执行位置、active line、tcp pose、tool axis、feed velocity。
  2. Resume 恢复 interpResumeState,不是固定写 reading
  3. Step 从 idle 开始时:先进入 run再立即 pause。
  4. Step 从 paused 开始时:只放行到下一个 motionId/currentLine 后再次 pause。
  5. Abort、ESTOP、OFF、Resume 都必须清理 singleStepping/motionStepping

完成标准:

  • 暂停期间 50ms 多帧采样位置完全冻结。
  • Step 后 active line 或 motion id 按 LinuxCNC 语义变化,不能只看 sample index。
  • Resume 后速度和执行状态恢复,且暂停锁消失。

5. 阶段 3收敛 Web 状态与 UI 门禁

实施文件:

  • app/src/state/linuxcnc-task-policy.js
  • app/src/state/store.js
  • app/src/ui/axis-shell.js
  • app/src/ui/gmoccapy-shell.js

实施步骤:

  1. linuxcnc-task-policy.js 作为唯一按钮门禁入口。
  2. UI 组件只读取 policy不再各自写 LinuxCNC 状态判断。
  3. store.js 的每个 action 都映射到 LinuxCNC NML 命令或明确的 UI 辅助流程。
  4. Task/HAL runtime 存在时,前端可先进入预期状态,但最终必须以 status 回写覆盖。

按钮 gate 要求:

按钮 Web gate 必须等价的 LinuxCNC 条件
ESTOP 始终可触发
RESET ESTOP 当前 taskState=estop
POWER ON taskState=estop-reset
POWER OFF taskState=on
HOME taskState=on、mode=manual、interpState=idle、非 homing
RUN taskState=on、mode=auto、interpState=idle、allHomed 或 noForceHoming、programOpen
PAUSE taskState=on、mode=auto、interpState=reading/waiting
PAUSE_RESUME taskState=on、mode=auto/mdipaused 走 resume非 idle 走 pause
STEP taskState=on、mode=auto、programOpen、已 homed 或 noForceHoming、resumeInhibit=false

完成标准:

  • UI 按钮禁用状态、operator message、runtime 拒绝状态三者一致。
  • UI 显示状态必须能追溯到 task/HAL status而不是只看本地 runState

6. 阶段 4重构 evidence 与 compare

6.1 evidence 必须采真实功能

实施步骤:

  1. Native evidence 采集 LinuxCNC 真实 task.state/mode/interpState/execState/currentLine/readLine/motionLine
  2. Native evidence 采集 motion enabled/paused/stepping/queue/motion id/homing/homed[]
  3. Web evidence 输出同名字段。
  4. 每个按钮输出 action 前、命令接受/拒绝、action 后、下一周期状态。

必须新增 evidence 段:

{
  "taskMotionStateTrace": [],
  "buttonCommandTrace": [],
  "homingTrace": [],
  "pauseFreezeTrace": [],
  "stepMotionIdTrace": [],
  "illegalCommandTrace": [],
  "cppParityAssertions": []
}

完成标准:

  • 证据能说明“为什么允许/拒绝”,而不是只说明最终 pass。
  • 每个 pass 都有对应 LinuxCNC C++ 规则名称。

6.2 compare 必须从表面 pass 升级为硬规则

现有 60/60 pass 只能保留为兼容摘要。必须增加真实功能硬检查:

新检查 失败条件
cppTaskStateMachineParity Web 状态转移不符合 emcTaskSetState() 或 task update 推导
cppModeGateParity AUTO 非 idle 可切出或 MDI/AUTO gate 不符合 C++
cppHomingParity Home 无 homing 瞬态、非法 Home 未拒绝、homed[] 错误
cppRunGateParity 未 home 可 Run、非 idle 可 Run、无 program 可 Run
cppPauseResumeParity pause 未冻结、resume 未恢复 interpResumeState
cppStepParity Step 不是 motion id/line 语义,只推进 sample
illegalCommandParity UI 禁用但 runtime 接受非法命令,或 runtime 拒绝但 UI 显示允许
realProgramExecutionParity 真实 G-code 执行 line/motion/path/status 与 native 不一致

完成标准:

  • compare 输出 surfaceSummaryfunctionalSummary 两部分。
  • 只有 functionalSummary.failCount=0 才能称为真实通过。
  • surfaceSummary 60/60 passfunctionalSummary 失败时,结论必须是失败。

7. 阶段 5测试实现顺序

建议顺序:

  1. 先补 Task/HAL runtime 的无 UI 状态矩阵测试。
  2. 再补 store/action 状态测试。
  3. 再补 UI gate 测试。
  4. 再补 native/Web evidence 字段。
  5. 最后补 compare functional checks。

对应测试文件建议:

测试文件 目标
wasm-port/tests/wasm/node/verify_task_state_matrix.mjs C++ task state/mode/run/pause/step/home gate
wasm-port/tests/wasm/node/verify_task_hal_wasm.mjs WASM command ABI 和 status 字段
app/tests/node/verify_linuxcnc_task_policy.mjs 或现有同类测试 Web policy gate
tests/node/verify_rtcp_store.mjs store action 状态写入
tests/node/verify_run_preconditions.mjs Run/Home/Power/ESTOP 前置
tests/browser/xyzbc_trt_browser_smoke.html UI 按钮状态与实际流程
tools/collect-native-xyzbc-trt-evidence.py native C++ 行为证据
tools/collect-web-xyzbc-trt-evidence.mjs Web 同名证据
tools/compare-xyzbc-trt-evidence.mjs functionalSummary 硬检查

8. 完成判定

实施完成必须同时满足:

  1. C++ 源码规则已映射到文档和测试断言。
  2. Task/HAL runtime 无 UI 情况下能拒绝非法命令。
  3. Web UI gate、store 状态、runtime status 三者一致。
  4. Native/Web evidence 包含真实状态流、非法命令、Home、Run、Pause、Step。
  5. compare 输出功能级硬检查,且功能级检查通过。
  6. 真实 G-code 程序执行过程中active line、motion id、path、pose、task/motion 状态与 LinuxCNC 对齐。

明确禁止把以下结果单独作为完成依据:

  • compare 60/60 pass
  • 页面截图看起来正常
  • UI 按钮样式 active/disabled 正常
  • 单个 smoke 测试通过
  • Web 本地 runState 看起来合理