Files
cnc_wams/wasm-port/working/12-status-json-LinuxCNC对标方案.md
2026-07-08 09:20:47 -04:00

243 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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. 保留旧 SDK/UI 兼容字段,同时新增更接近 `EMC_STAT``emcStatus` 对象。
`status JSON` 不承担:
- task 状态机事实源。
- motion 状态机事实源。
- LinuxCNC planner/canon/interpreter 语义。
- queueFull、inpos、abort、estop、pause/resume/step 等语义判断。
## 推荐JSON结构
顶层保留 runtime/readiness 和兼容字段,同时以 `emcStatus` 作为 LinuxCNC 对标主对象:
```json
{
"statusSource": "StandaloneEmcStatus",
"schemaVersion": 1,
"taskTopLevelStatus": "DONE",
"rcsStatus": {
"top": "DONE",
"task": "DONE",
"motion": "DONE",
"io": "DONE"
},
"task": {},
"motionStatus": {},
"emcStatus": {
"source": "StandaloneEmcStatus",
"top": { "status": "DONE" },
"task": {},
"motion": {},
"io": {}
}
}
```
要求:
- `task``motionStatus` 是兼容视图,字段必须来自 `emcStatus` 或同一份 C/C++ status buffer。
- `emcStatus` 是后续新增 LinuxCNC 对标字段的默认入口。
- 新字段优先落在 `emcStatus.task``emcStatus.motion.traj``emcStatus.motion.joint[]``emcStatus.motion.axis[]``emcStatus.io` 中。
- 若必须保留旧字段名,应在测试中断言旧字段与 `emcStatus` 同源一致。
## 字段映射方案
| LinuxCNC字段 | WASM事实源 | JSON位置 | 状态 |
| --- | --- | --- | --- |
| `EMC_STAT.status` / top RCS status | `StandaloneEmcStatus.top_rcs_status` | `emcStatus.top.status``taskTopLevelStatus``rcsStatus.top` | 已有 |
| `EMC_STAT.task.status` | `StandaloneEmcTaskStatus.rcs_status` | `emcStatus.task.status``task.status``rcsStatus.task` | 已有 |
| `EMC_STAT.task.state` | `StandaloneEmcTaskStatus.state` | `emcStatus.task.state``task.state` | 已有 |
| `EMC_STAT.task.mode` | `StandaloneEmcTaskStatus.mode` | `emcStatus.task.mode``task.mode` | 已有 |
| `EMC_STAT.task.execState` | `StandaloneEmcTaskStatus.exec_state` | `emcStatus.task.execState``task.execState` | 已有 |
| `EMC_STAT.task.interpState` | `StandaloneEmcTaskStatus.interp_state` | `emcStatus.task.interpState``task.interpState` | 已有 |
| `EMC_STAT.task.task_paused` | `StandaloneEmcTaskStatus.task_paused` | `emcStatus.task.taskPaused``task.taskPaused` | 已有 |
| `EMC_STAT.task.file` | `StandaloneEmcTaskStatus.open_program` | `emcStatus.task.file``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``rcsStatus.motion` | 已有 |
| `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``rcsStatus.io` | 已有 |
| `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。
目标:把当前 `motionStatus.motion.*` 中已有的 queue、inpos、id、paused、stepping、currentVel 等字段,以 LinuxCNC `EMC_TRAJ_STAT` 名称归入 `emcStatus.motion.traj`
验收:
- `emcStatus.motion.traj.queue` 等于兼容字段 `motionStatus.motion.queueDepth`
- `emcStatus.motion.traj.inpos` 等于兼容字段 `motionStatus.motion.inPosition`
- `emcStatus.motion.traj.id` 等于兼容字段 `motionStatus.motion.id`
- `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 一致。
- 兼容字段若存在,必须与 `emcStatus.task.*Line` 同源。
### SJ-3规范 `motion.axis[]` 和 `motion.joint[]`
状态:已完成,对应 T-053。`emcStatus.motion.axis``emcStatus.motion.joint` 为数组;按名字访问的兼容视图保留在 `motionStatus.axis``emcStatus.motion.axisByName` 仅辅助迁移。
目标:把当前 axis x/y/z/a/b/c 和 joint0 字段扩展成数组结构,对标 `EMC_MOTION_STAT.axis[]``joint[]`
验收:
- 至少导出存在的 5/6 轴位置和 joint0 command/feedback。
-`motionStatus.axis``motionStatus.joint0` 与新数组值一致。
### 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`,并检查 `emcStatus` 与兼容字段的一致性。
验收:
- gate 检查 `statusSource=StandaloneEmcStatus`
- gate 检查 `lctask_read_status_json()` 不调用 `lcmot_read_status_json()`
- gate 检查 JS/SDK 没有实现 task/motion 语义。
- gate 纳入 `tools/verify_task_full_closure.sh`
## 兼容策略
短期保留:
- `taskTopLevelStatus`
- `rcsStatus`
- `task`
- `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
```