7.6 KiB
7.6 KiB
02-项目程序开发详细步骤
开发原则
- 以 LinuxCNC 源码语义为准,不在 JavaScript 层发明新的 CNC 暂停语义。
wasm-port的 wrapper 只能作为 native/WASM 边界适配,不能扩大为独立 CNC 语义实现。- 先补 task/motion 可观测状态,再补 STEP,再推进 TP 真实接入。
- 每一步必须有 Node WASM 测试和 Web 集成测试证据。
步骤 1:补齐 task 层暂停恢复状态
目标文件:
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_task_hal_wasm.cppwasm-port/tests/wasm/node/verify_task_hal_wasm.mjswasm-port/runtime/sdk/src/linuxcnc-task-hal.jsweb-rtcp-5axis-xyzbc-trt-sim-plan/app/src/runtime/linuxcnc-task-hal-runtime.js
开发动作:
- 在
TaskRuntime增加字段:std::string interp_resume_state = "IDLE";
- 初始化、reset、abort、home、program complete 时同步维护
interp_resume_state。 - 在
EMC_TASK_PLAN_PAUSE分支中按 LinuxCNC 语义处理:
if (state.interp_state != "PAUSED") {
state.interp_resume_state = state.interp_state.empty() ? "READING" : state.interp_state;
}
state.interp_state = "PAUSED";
state.exec_state = "PAUSED";
state.task_paused = true;
forward_motion_command("{\"type\":\"EMCMOT_PAUSE\"}");
- 在
EMC_TASK_PLAN_RESUME分支中按 LinuxCNC 语义处理:
const std::string resume = state.interp_resume_state == "PAUSED" || state.interp_resume_state.empty()
? "READING"
: state.interp_resume_state;
state.interp_state = resume;
state.interp_resume_state = resume;
state.exec_state = resume == "IDLE" ? "DONE" : "WAITING_FOR_MOTION";
state.task_paused = false;
state.single_stepping = false;
forward_motion_command("{\"type\":\"EMCMOT_RESUME\"}");
status_json()输出interpResumeState。- SDK 和 Web runtime wrapper 把
interpResumeState转成小写并映射到 UI 状态。
验收:
- pause 前为
READING,pause 后interpResumeState=READING。 - resume 后恢复
READING,不是固定靠前端猜测。 - pause 前为
WAITING时 resume 能恢复WAITING。
步骤 2:补齐 motion 层 immediate pause 语义
目标文件:
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_motion_runtime.cwasm-port/tests/wasm/node/verify_task_hal_wasm.mjs
当前风险:
lcmot_write_command_json() 把 EMC_TRAJ_PAUSE 作为普通命令入队。如果队列中已有多个 move,pause 可能排在 move 后执行。AXIS 用户点击暂停属于 GUI immediate command,应尽快阻止继续消费运动队列。
开发动作:
- 对
EMCMOT_PAUSE或EMC_TRAJ_PAUSE做即时状态切换:lcmot_state.paused = 1lcmot_state.current_vel = 0lcmot_state.motion_type = 0lcmot_state.in_position = 0
- 不清空运动队列。
- 暂停期间
lcmot_step_servo()不消费普通 move,只允许:STEPRESUMEABORT
EMCMOT_RESUME即时清除 paused,后续 servo cycle 继续消费保留队列。- 状态 JSON 增加:
motion.steppingmotion.idForStep或同等 step 追踪字段。
验收:
- 先入队多个 line move,运行一部分后 pause。
- pause 后连续运行 20 个 cycle,
programLine不变、axis 不变、queueDepth 不减少。 - resume 后 queueDepth 继续减少,programLine 继续推进。
步骤 3:实现 STEP 自动回暂停
目标文件:
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_motion_runtime.cwasm-port/runtime/core/linuxcnc_wrap/linuxcnc_task_hal_wasm.cppwasm-port/tests/wasm/node/verify_task_hal_wasm.mjsweb-rtcp-5axis-xyzbc-trt-sim-plan/tests/node/verify_run_feedback_loop.mjs
LinuxCNC 对标:
EMCMOT_STEP在 paused 时记录当前 motion id,短暂恢复 TP;- motion id 改变后自动
tpPause(); - 外部仍把程序视为 paused。
开发动作:
- 在 motion runtime 增加:
int stepping;int id_for_step;int motion_id;
- 每执行一个普通 move 时递增
motion_id。 EMCMOT_STEP:- 如果当前 paused,设置
stepping=1、id_for_step=motion_id; - 允许消费一个普通 move;
- 保持对外
paused=true或在状态中明确paused=true, stepping=true。
- 如果当前 paused,设置
lcmot_step_servo()在 step 消费一个 move 后:- 自动恢复
paused=1; - 清
stepping=0。
- 自动恢复
- task 层
EMC_TASK_PLAN_STEP:- 不把解释器永久改成 running;
- step 完成后恢复
interpState=PAUSED、taskPaused=true。
验收:
- paused 状态下 STEP 后只推进一个 line 或一个 motion id。
- STEP 完成后
task.interpState=PAUSED、taskPaused=true、motion.paused=true。 - 再次 Resume 可从 step 后位置继续运行。
步骤 4:把 motion paused 字段接入 Web task policy
目标文件:
web-rtcp-5axis-xyzbc-trt-sim-plan/app/src/state/linuxcnc-task-policy.jsweb-rtcp-5axis-xyzbc-trt-sim-plan/app/src/state/store.jsweb-rtcp-5axis-xyzbc-trt-sim-plan/app/src/ui/axis-shell.jsweb-rtcp-5axis-xyzbc-trt-sim-plan/tests/node/verify_run_feedback_loop.mjs
开发动作:
- 从
taskHalStatus.ui或taskHalStatus.motionStatus.motion.paused映射machine.motionPaused。 isProgramPaused()判断改为包含:state.machine.motionPaused === truestate.programRuntimeFeedback.paused === true
canResume和RESUMEgate 改为:
taskState == on
taskMode in auto/mdi
motionPaused 或 interpState paused 或 taskPaused
未被 resumeInhibit 阻止
PAUSE_RESUMEtoggle 优先看 motion paused,贴近 AXISs.paused。- 保留菜单 Pause 的严格条件:AUTO 且
interpState为reading/waiting。
验收:
- motion paused 已 true 但 interpState 同步稍晚时,工具栏按钮显示 Resume。
- Resume 不再只依赖
interpState === paused。 - 菜单 Pause/Resume 与工具栏 toggle 逻辑仍分离。
步骤 5:补充 TP 层暂停验证
目标文件:
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_tp_wasm.cwasm-port/tests/wasm/node/verify_tp_wasm.mjs
开发动作:
- 在 TP probe 中增加 pause/resume 场景:
- 创建 TP;
- 加入至少两段 line;
- 运行若干 cycle;
- 调
tpPause(); - 继续运行若干 cycle;
- 验证位置不继续跨段推进或速度趋向 0;
- 调
tpResume(); - 验证可继续完成队列。
- 输出可测试字段:
tp_pause_rc=0tp_resume_rc=0tp_paused_velocity_zero=1tp_resume_done=1
验收:
node wasm-port/tests/wasm/node/verify_tp_wasm.mjs通过。- 证据显示 TP pause/resume 使用 vendored LinuxCNC TP API,而不是 JS 模拟。
步骤 6:构建与回归
推荐命令:
cd /home/mes123456/cnc_wams/wasm-port
./tools/build_task_hal_wasm.sh
./tools/build_tp_wasm.sh
node tests/wasm/node/verify_task_hal_wasm.mjs
node tests/wasm/node/verify_tp_wasm.mjs
Web 集成命令:
cd /home/mes123456/cnc_wams/web-rtcp-5axis-xyzbc-trt-sim-plan
npm --prefix app run build
node tests/node/verify_run_feedback_loop.mjs
APP_URL_PATH=/web-rtcp-5axis-xyzbc-trt-sim-plan/app/dist/index.html node tools/trace-pause-position-json.mjs
RUN_STABLE_BEFORE_FIRST_PAUSE_MS=3000 node tools/verify-estop-power-home-run-pause-50ms.mjs
验收输出至少包括:
linuxcnc_task_runtime_smoke=oktp_wasm_node_smoke=okrun_feedback_status_loop_smoke=okpause_position_status=passed-position-frozenverification_status=passed
步骤 7:记录证据与关闭任务
每完成一个编号任务:
- 更新
03-推进台账.md。 - 更新
04-任务矩阵.md状态。 - 把命令、输出、trace 路径、截图目录写入
05-验收证据.md。 - 如果出现新取舍,追加
06-决策记录.md。