# 12-status JSON LinuxCNC对标方案 ## 目标 本方案用于后续在 WASM 中完善 `status JSON`:对标 LinuxCNC 的 `EMC_STAT` / status buffer 模型,在 WASM/C++ 内维护结构化 status 事实源,再把最后一次 status write 序列化为 JSON 给 JS/SDK/UI 读取。 `status JSON` 不是 LinuxCNC 语义实现层。它是浏览器/Node host 无法直接读取 native NML/CMS status channel 时的外部通信格式。 ## LinuxCNC对标基线 上游 LinuxCNC 的 status 模型来自: - `/home/mes123456/cnc_wams/linuxcnc/src/emc/nml_intf/emc.hh` - 定义 `EMC_TASK_MODE`、`EMC_TASK_STATE`、`EMC_TASK_EXEC`、`EMC_TASK_INTERP`、`EMC_TRAJ_MODE` 等枚举。 - 定义 `EMC_STAT_TYPE`、`EMC_TASK_STAT_TYPE`、`EMC_MOTION_STAT_TYPE`、`EMC_IO_STAT_TYPE` 等 NML 类型编号。 - `/home/mes123456/cnc_wams/linuxcnc/src/emc/nml_intf/emc_nml.hh` - `EMC_STAT` 聚合 `EMC_TASK_STAT task`、`EMC_MOTION_STAT motion`、`EMC_IO_STAT io`。 - `EMC_TASK_STAT` 保存 task mode/state、exec/interp state、program line、file、active G/M code、offset、program units、pause 等状态。 - `EMC_MOTION_STAT` 保存 `EMC_TRAJ_STAT traj`、joint、axis、spindle、synch IO、analog IO、soft limit、heartbeat 等状态。 - `EMC_TRAJ_STAT` 保存 enabled、inpos、queue、activeQueue、queueFull、id、paused、single_stepping、position、actualPosition、current_vel、probe、kinematics 等轨迹状态。 - `EMC_IO_STAT` 保存 tool、coolant、aux、fault/reason 等 IO 状态。 上游 GUI 读取的是 status channel 中的 `EMC_STAT` 快照,不是在 GUI 层重建 task/motion 状态机。WASM 中的 JSON 应只模拟“读 status channel 后得到可展示快照”的边界。 ## WASM中的等价模型 当前 WASM 侧已建立: - `StandaloneEmcStatus` - `StandaloneEmcTaskStatus` - `StandaloneEmcMotionStatus` - `StandaloneEmcIoStatus` - `write_status_snapshot()` - `lctask_read_status_json()` 后续完善时采用以下固定链路: ```text LinuxCNC source semantics -> WASM/C++ task cycle -> LcmotStatusSnapshot -> StandaloneEmcStatus -> write_status_snapshot() -> lctask_read_status_json() -> JS/SDK/UI ``` 禁止以下链路: ```text motion JSON -> parse -> task state status JSON -> parse -> task/motion state JS/SDK -> compute LinuxCNC task/motion semantics lctask_read_status_json() -> step servo / read fresh motion / consume command ``` ## status JSON职责 `status JSON` 只承担四类职责: 1. 把最后一次 `write_status_snapshot()` 中的状态导出给 JS/SDK/UI。 2. 给浏览器 UI 提供稳定、可版本化的字段名。 3. 给 Node/WASM/browser 测试提供可断言的观察面。 4. 以更接近 `EMC_STAT` 的 `emcStatus` 对象作为唯一 task/motion/io 状态入口。 `status JSON` 不承担: - task 状态机事实源。 - motion 状态机事实源。 - LinuxCNC planner/canon/interpreter 语义。 - queueFull、inpos、abort、estop、pause/resume/step 等语义判断。 ## 推荐JSON结构 顶层只保留 runtime/readiness/source/schema 等边界字段;task/motion/io/top 状态只进入 `emcStatus`: ```json { "statusSource": "StandaloneEmcStatus", "schemaVersion": 1, "emcStatus": { "source": "StandaloneEmcStatus", "top": { "status": "DONE" }, "task": {}, "motion": {}, "io": {} } } ``` 要求: - `emcStatus` 是后续新增 LinuxCNC 对标字段的默认入口。 - 新字段优先落在 `emcStatus.task`、`emcStatus.motion.traj`、`emcStatus.motion.joint[]`、`emcStatus.motion.axis[]`、`emcStatus.io` 中。 - `taskTopLevelStatus`、`rcsStatus`、顶层 `task`、`servoCycle`、顶层 `motionStatus` 禁止再从 `lctask_read_status_json()` 输出。 ## 字段映射方案 | LinuxCNC字段 | WASM事实源 | JSON位置 | 状态 | | --- | --- | --- | --- | | `EMC_STAT.status` / top RCS status | `StandaloneEmcStatus.top_rcs_status` | `emcStatus.top.status` | 已有 | | `EMC_STAT.task.status` | `StandaloneEmcTaskStatus.rcs_status` | `emcStatus.task.status` | 已有 | | `EMC_STAT.task.state` | `StandaloneEmcTaskStatus.state` | `emcStatus.task.state` | 已有 | | `EMC_STAT.task.mode` | `StandaloneEmcTaskStatus.mode` | `emcStatus.task.mode` | 已有 | | `EMC_STAT.task.execState` | `StandaloneEmcTaskStatus.exec_state` | `emcStatus.task.execState` | 已有 | | `EMC_STAT.task.interpState` | `StandaloneEmcTaskStatus.interp_state` | `emcStatus.task.interpState` | 已有 | | `EMC_STAT.task.task_paused` | `StandaloneEmcTaskStatus.task_paused` | `emcStatus.task.taskPaused` | 已有 | | `EMC_STAT.task.file` | `StandaloneEmcTaskStatus.open_program` | `emcStatus.task.file` | 已有 | | `EMC_STAT.task.currentLine/readLine/motionLine` | staged interpreter + motion snapshot | `emcStatus.task.currentLine/readLine/motionLine` | 已有 | | `EMC_STAT.task.activeGCodes/activeMCodes/activeSettings` | vendored interpreter/canon state | `emcStatus.task.activeGCodes/activeMCodes/activeSettings` | 后续 | | `EMC_STAT.task.g5x_offset/g92_offset/toolOffset` | vendored interpreter/canon state | `emcStatus.task.offsets` | 后续 | | `EMC_STAT.motion.status` | `StandaloneEmcMotionStatus.rcs_status` | `emcStatus.motion.status` | 已有 | | `EMC_STAT.motion.traj.enabled` | `LcmotStatusSnapshot.motion_enabled` | `emcStatus.motion.traj.enabled` | 已有 | | `EMC_STAT.motion.traj.inpos` | `LcmotStatusSnapshot.in_position` | `emcStatus.motion.traj.inpos` | 已有 | | `EMC_STAT.motion.traj.queue` | `LcmotStatusSnapshot.queue_count` | `emcStatus.motion.traj.queue` | 已有 | | `EMC_STAT.motion.traj.activeQueue` | `LcmotStatusSnapshot.active_depth` | `emcStatus.motion.traj.activeQueue` | 已有 | | `EMC_STAT.motion.traj.queueFull` | `LcmotStatusSnapshot.queue_full` | `emcStatus.motion.traj.queueFull` | 已有 | | `EMC_STAT.motion.traj.id` | `LcmotStatusSnapshot.motion_id` | `emcStatus.motion.traj.id` | 已有 | | `EMC_STAT.motion.traj.paused` | `LcmotStatusSnapshot.paused` | `emcStatus.motion.traj.paused` | 已有 | | `EMC_STAT.motion.traj.single_stepping` | `LcmotStatusSnapshot.stepping` | `emcStatus.motion.traj.singleStepping` | 已有 | | `EMC_STAT.motion.traj.position/actualPosition` | `LcmotStatusSnapshot.axis_cmd/axis_fb` | `emcStatus.motion.traj.position/actualPosition` | 已有 | | `EMC_STAT.motion.traj.current_vel` | `LcmotStatusSnapshot.current_vel` | `emcStatus.motion.traj.currentVel` | 已有 | | `EMC_STAT.motion.on_soft_limit` | `LcmotStatusSnapshot.on_soft_limit` | `emcStatus.motion.onSoftLimit` | 已有 | | `EMC_STAT.motion.joint[]` | `LcmotStatusSnapshot.joint_cmd/joint_fb` | `emcStatus.motion.joint[]` | 已有 | | `EMC_STAT.motion.axis[]` | `LcmotStatusSnapshot.axis_cmd/axis_fb` | `emcStatus.motion.axis[]` | 已有 | | `EMC_STAT.io.status` | `StandaloneEmcIoStatus.rcs_status` | `emcStatus.io.status` | 已有 | | `EMC_STAT.io.aux.estop` | task/io shim | `emcStatus.io.aux.estop` | 已有 | | `EMC_STAT.io.fault/reason` | `StandaloneEmcIoStatus.error/reason` | `emcStatus.io.fault/reason` | 已有 | ## 后续实施批次 ### SJ-1:规范 `emcStatus.motion.traj` 状态:已完成,对应 T-051。 目标:把 motion snapshot 中已有的 queue、inpos、id、paused、stepping、currentVel 等字段,以 LinuxCNC `EMC_TRAJ_STAT` 名称归入 `emcStatus.motion.traj`。 验收: - `emcStatus.motion.traj.queue` 等于 `emcStatus.motion.queueDepth`。 - `emcStatus.motion.traj.inpos` 等于 `emcStatus.motion.inPosition`。 - `emcStatus.motion.traj.id` 等于 `emcStatus.motion.motionId`。 - `lctask_read_status_json()` 不新增 motion read 或 servo step。 ### SJ-2:规范 task line 和 interpreter字段 状态:已完成,对应 T-052。active G/M code、active settings 和 offsets 仍按字段映射表保留为后续 source-anchored 扩展,不计入本 SJ-2 验收。 目标:对齐 `EMC_TASK_STAT.currentLine`、`readLine`、`motionLine`、`callLevel`,让 UI 和测试能分辨 interpreter 已读行、当前执行行和 motion 正在执行行。 验收: - staged program RUN 后,`emcStatus.task.readLine/currentLine/motionLine` 与现有 plan read/execute/motion id evidence 一致。 - 顶层 `task` 兼容视图不得再存在。 ### SJ-3:规范 `motion.axis[]` 和 `motion.joint[]` 状态:已完成,对应 T-053。`emcStatus.motion.axis` 和 `emcStatus.motion.joint` 为数组;`emcStatus.motion.axisByName` 仅提供按名字读取的同对象辅助视图。 目标:把当前 axis x/y/z/a/b/c 和 joint0 字段扩展成数组结构,对标 `EMC_MOTION_STAT.axis[]` 和 `joint[]`。 验收: - 至少导出存在的 5/6 轴位置和 joint0 command/feedback。 - 顶层 `motionStatus` 兼容视图不得再存在。 ### SJ-4:规范 IO/aux/tool/coolant边界 状态:已完成,对应 T-054。tool/coolant 只暴露 shim/unsupported 边界,不提升 native IO readiness。 目标:将当前 IO shim 状态组织为 `emcStatus.io.aux`、`emcStatus.io.tool`、`emcStatus.io.coolant` 的窄对象,未实现字段显式标记为 shim/unsupported,而不是省略成语义完成。 验收: - `emcStatus.io.status`、`fault`、`reason`、`aux.estop` 可观测。 - readiness 仍保持 false,不因 JSON 字段存在而宣称 native IO ready。 ### SJ-5:引入 schema gate 状态:已完成,对应 T-055。 目标:新增专用 gate,例如 `tools/verify_task_status_json_contract.sh`,固定 status JSON 字段来自 `StandaloneEmcStatus`,并检查旧顶层状态字段不存在。 验收: - gate 检查 `statusSource=StandaloneEmcStatus`。 - gate 检查 `taskTopLevelStatus`、`rcsStatus`、顶层 `task`、`servoCycle`、顶层 `motionStatus` 不存在。 - gate 检查 `lctask_read_status_json()` 不调用 `lcmot_read_status_json()`。 - gate 检查 JS/SDK 没有实现 task/motion 语义。 - gate 纳入 `tools/verify_task_full_closure.sh`。 ## 旧字段收口策略 禁止 `lctask_read_status_json()` 输出: - `taskTopLevelStatus` - `rcsStatus` - `task` - `servoCycle` - `motionStatus` 新增字段默认进入: - `emcStatus.top` - `emcStatus.task` - `emcStatus.motion` - `emcStatus.motion.traj` - `emcStatus.motion.axis` - `emcStatus.motion.joint` - `emcStatus.io` 旧字段不再作为兼容视图保留。新增测试必须优先断言 `emcStatus`,并在契约测试中继续对旧字段做负向断言。 ## 文档和测试要求 每完成一个 SJ 批次,需要同步更新: - `04-任务矩阵.md` - `03-推进台账.md` - `05-验收证据.md` - `06-决策记录.md` - `07-emctaskmain周期对标蓝图.md` - `11-WASM核心状态机边界与后续完善路线.md` - `docs/source-reuse-map.md` - `docs/compatibility-validation.md` - 对应 `tools/verify_task_*` gate 默认最终验收命令: ```bash cd /home/mes123456/cnc_wams/wasm-port ./tools/verify_task_full_closure.sh git diff --check ```