# 03 RUN 第一步完成记录与下一步建议 生成时间:2026-06-22 ## 1. 本轮完成范围 本轮只完成 `02-run-preconditions-test-and-implementation-steps.md` 中的第一步和第二步: ```text Step 1: 增加 validateRunPreconditions(state) Step 2: RUN action 先调用前置检查 ``` 本轮没有实现连续 feedback pump。也没有把 `RUN` 宣称为完整实时运行模型。 ## 2. 已完成改动 ### 2.1 RUN 前置条件 gate 新增源码: ```text app/src/state/store.js export function validateRunPreconditions(...) ``` 校验内容: ```text 1. profile 必须是 xyzac-trt 或 xyzbc-trt。 2. LinuxCNC INI 必须已加载并 validation.ready=true。 3. profile.iniPath 必须与已加载 INI path 一致。 4. profile TRAJ coordinates 必须与 INI coordinates 一致。 5. profile.kinematicsModuleId 必须与 INI [KINS] 推导结果一致。 6. LinuxCNC kinematics runtime 必须 loaded。 7. kinematics runtime moduleId 必须匹配当前 profile。 8. RTCP frame 必须来自 source-derived-kinematics-wasm。 9. machine files 必须 staged。 10. 必须已选择 LinuxCNC source-directory G-code。 11. task/HAL runtime 必须 ready。 12. requireTaskHalSession=true 时,taskHalSession.programPath 必须匹配当前 selected G-code。 ``` 关键结果: ```text 当 taskHalRuntime 已加载时,RUN 不再直接发送 EMC_TASK_PLAN_RUN。 RUN 会先校验 INI/profile/kinematics/machine-file/task-HAL 上下文。 前置条件不满足时,只给 operatorMessage,不进入 fixture playback。 ``` ### 2.2 RUN 使用真实 machine-file session 新增内部流程: ```text runValidatedTaskHalProgramRun() ``` 执行顺序: ```text 1. validateRunPreconditions(..., requireTaskHalSession=false) 2. 如 taskHalSession 缺失或 programPath 不匹配,initializeTaskHalSession({ openProgram: true }) 3. validateRunPreconditions(..., requireTaskHalSession=true) 4. 发送: EMC_TASK_SET_STATE ON EMC_TASK_SET_MODE AUTO EMC_TASK_PLAN_RUN line = activeLine - programStartLine 5. runTaskHalCommandSequence(..., allowFixtureSession=false) ``` 这一步解决的是“RUN 之前先确定明确 INI、机床类型和五轴运动学算法”,不是连续执行问题。 ### 2.3 新增测试 新增: ```text tests/node/verify_run_preconditions.mjs ``` 覆盖: ```text 1. xyzac-trt.ini 解析: MACHINE=sim-xyzac-trt-kins (switchkins) COORDINATES=XYZAC KINEMATICS=xyzac-trt-kins kinematicsModuleId=xyzac-trt 2. xyzbc-trt.ini 解析: MACHINE=sim-xyzbc-trt-kins (switchkins) COORDINATES=XYZBC KINEMATICS=xyzbc-trt-kins kinematicsModuleId=xyzbc-trt 3. applyIniConfigToProfile() 后 profile 与 INI 保持一致。 4. createLinuxCncKinematicsRuntime() 可按 moduleId 加载对应 WASM。 5. stageProfileMachineFiles() 和 buildTaskHalSessionFromMachineFiles() 能形成同一 machine-file 上下文。 6. validateRunPreconditions() 能阻断未加载 INI 的初始状态。 7. validateRunPreconditions() 能在 INI/kinematics/staged G-code ready 时通过非 task-HAL session 预检。 8. task/HAL runtime 缺失时返回明确阻断消息。 ``` `app/package.json` 的 `smoke:node` 已加入: ```text node ../tests/node/verify_run_preconditions.mjs ``` ### 2.4 调整 task/HAL smoke 更新: ```text tests/node/verify_linuxcnc_task_hal_runtime.mjs ``` 调整点: ```text 1. 不再用内联 fixture G-code 直接测试真实 RUN。 2. 加载 xyzac-trt INI。 3. 加载 xyzac-trt kinematics runtime。 4. stage machine files。 5. LOAD_LINUXCNC_GCODE_SOURCE 选择: configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc 6. 等待 taskHalSession.programPath 指向该 G-code。 7. 再执行 POWER/HOME/AUTO/RUN。 ``` 这样 task/HAL RUN smoke 与新的 RUN 前置条件一致。 ## 3. 已运行验证 通过: ```bash node web-rtcp-5axis-sim-plan/tests/node/verify_run_preconditions.mjs node web-rtcp-5axis-sim-plan/tests/node/verify_linuxcnc_task_hal_runtime.mjs npm --prefix web-rtcp-5axis-sim-plan/app run build ``` 输出: ```text run_preconditions_ini_profile_smoke=ok run_preconditions_kinematics_smoke=ok run_preconditions_machine_file_smoke=ok linuxcnc_task_hal_runtime_smoke=ok task_hal_machine_file_smoke=ok switchkins_remap_hal_sync_smoke=ok browser_task_hal_worker_smoke=ok gmoccapy_static_build=ok ``` 部分通过后失败: ```bash npm --prefix web-rtcp-5axis-sim-plan/app run smoke:node ``` 该命令已通过本轮新增和相关测试: ```text linuxcnc_kinematics_runtime_smoke=ok linuxcnc_interpreter_runtime_smoke=ok linuxcnc_ini_runtime_smoke=ok run_preconditions_ini_profile_smoke=ok run_preconditions_kinematics_smoke=ok run_preconditions_machine_file_smoke=ok linuxcnc_task_hal_runtime_smoke=ok task_hal_machine_file_smoke=ok switchkins_remap_hal_sync_smoke=ok browser_task_hal_worker_smoke=ok ``` 随后在既有 native audit 停止: ```text wasm-port/tests/native/verify_task_hal_phase0.sh failed with status 1 ``` 直接运行该脚本确认失败点是: ```text wasm-port/tools/verify_task_hal_source_manifest.sh ``` 日志: ```text task_hal_source_manifest_ready=0 task_hal_reference_source_ready=0 task_hal_missing_reference_source_count=20 ``` 说明:该失败来自外部 reference source `../linuxcnc` 缺失 task/HAL manifest 需要的 20 个文件,不是本轮 RUN 前置条件改动造成。 ## 4. 当前 RUN 状态 现在 `RUN` 的第一道边界已经收紧: ```text 没有明确 INI -> 不 RUN profile/INI 坐标不一致 -> 不 RUN kinematics module 不一致 -> 不 RUN kinematics frame 未 ready -> 不 RUN machine files 未 staged -> 不 RUN 没有 LinuxCNC source G-code -> 不 RUN task/HAL runtime 未 ready -> 不 RUN taskHalSession.programPath 不匹配当前 G-code -> 不 RUN ``` 但当前 `RUN` 仍然是: ```text 发送 task command -> runCycles({ taskCycles: 5 }) -> readStatus() 一次 -> TASK_HAL_STATUS_APPLIED 一次 ``` 所以 `01-run-gcode-execution-principle-and-test.md` 中指出的连续 feedback 问题仍未解决。 ## 5. 下一步工作建议 下一步应实现 `02` 文件中的 Step 3 和 Step 4: ```text Step 3: 拆分 task command 与执行 pump Step 4: 增加 RUN pump 状态 ``` 建议最小实现范围: ```text 1. 在 store state 增加 taskHalRunPump: active sequence profileId iniPath kinematicsModuleId tickCount lastStatusAt lastError 2. 增加 programRuntimeFeedbackHistory,最多保留 100 条。 3. RUN 发送 EMC_TASK_PLAN_RUN 后,不只 runCycles 5 次。 改为启动 pump: runCycles({ taskCycles: batchSize }) readStatus() dispatch TASK_HAL_STATUS_APPLIED append feedback history 根据 interpState / task.nextProgramLine / openedLineCount / paused / aborted 停止。 4. STOP/ABORT 必须停止 pump。 5. PAUSE 停止或降频 pump,并保留 paused status。 6. RESUME 重新启动 pump。 7. STEP 在 task/HAL runtime loaded 时不走 fixture sample playback, 而是推进一个明确 task cycle batch 并 readStatus 一次。 ``` 下一步测试建议: ```text 1. 新增 tests/node/verify_run_feedback_pump.mjs。 2. 使用 xyzac_switchkins_test_1.ngc。 3. RUN 后采集至少 8 个 feedback tick。 4. 断言 taskCycle 或 servoCycle 单调递增。 5. 断言 activeLine 不停留在 RUN 后第一帧。 6. 断言每个 tick 的 sourceMode 都是 linuxcnc-task-motion-hal-wasm。 7. 断言 programRuntimeFeedbackHistory 至少包含 3 条。 8. 断言 STOP 后 pump.active=false。 ``` 浏览器测试建议: ```text 扩展 qa/web-rtcp-5axis-site-test/capture-toolpath-preview-cases.mjs 新增 07-run-preconditions-and-feedback case。 采集 RUN 后 0.2s / 0.5s / 1.0s / 2.0s 的 state。 断言 activeLine、DRO、runtime feedback、canvas RTCP 状态来自同一 feedback snapshot。 ``` ## 6. 重要边界 下一步实现 pump 时仍需保持: ```text 不引入 JS G-code parser。 不在 UI 里自增 activeLine。 不在 UI 里自造 axisPose。 不把 canonical timing estimate 当作真实 task/HAL runtime。 不把 fixture playback 标记为 fullLinuxCncProgramExecutionReady。 ``` RUN 的真实推进必须来自: ```text taskHalRuntime.runCycles() taskHalRuntime.readStatus() TASK_HAL_STATUS_APPLIED ```