Validate AXIS task state flow

This commit is contained in:
wangdequan
2026-07-09 18:12:01 -04:00
parent f99ba2bbe8
commit f4b9911d45
57 changed files with 195248 additions and 647 deletions

View File

@@ -59,9 +59,9 @@ lctask_read_status_json() -> step servo / read fresh motion / consume command
`status JSON` 只承担四类职责:
1. 把最后一次 `write_status_snapshot()` 中的状态导出给 JS/SDK/UI。
2. 给浏览器 UI 提供稳定、可版本化、可兼容的字段名。
2. 给浏览器 UI 提供稳定、可版本化的字段名。
3. 给 Node/WASM/browser 测试提供可断言的观察面。
4. 保留旧 SDK/UI 兼容字段,同时新增更接近 `EMC_STAT``emcStatus` 对象。
4. 更接近 `EMC_STAT``emcStatus` 对象作为唯一 task/motion/io 状态入口
`status JSON` 不承担:
@@ -72,21 +72,12 @@ lctask_read_status_json() -> step servo / read fresh motion / consume command
## 推荐JSON结构
顶层保留 runtime/readiness 和兼容字段,同时以 `emcStatus` 作为 LinuxCNC 对标主对象
顶层保留 runtime/readiness/source/schema 等边界字段task/motion/io/top 状态只进入 `emcStatus`
```json
{
"statusSource": "StandaloneEmcStatus",
"schemaVersion": 1,
"taskTopLevelStatus": "DONE",
"rcsStatus": {
"top": "DONE",
"task": "DONE",
"motion": "DONE",
"io": "DONE"
},
"task": {},
"motionStatus": {},
"emcStatus": {
"source": "StandaloneEmcStatus",
"top": { "status": "DONE" },
@@ -99,27 +90,26 @@ lctask_read_status_json() -> step servo / read fresh motion / consume command
要求:
- `task``motionStatus` 是兼容视图,字段必须来自 `emcStatus` 或同一份 C/C++ status buffer。
- `emcStatus` 是后续新增 LinuxCNC 对标字段的默认入口。
- 新字段优先落在 `emcStatus.task``emcStatus.motion.traj``emcStatus.motion.joint[]``emcStatus.motion.axis[]``emcStatus.io` 中。
- 若必须保留旧字段名,应在测试中断言旧字段与 `emcStatus` 同源一致
- `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``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.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``rcsStatus.motion` | 已有 |
| `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` | 已有 |
@@ -133,7 +123,7 @@ lctask_read_status_json() -> step servo / read fresh motion / consume command
| `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.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` | 已有 |
@@ -143,13 +133,13 @@ lctask_read_status_json() -> step servo / read fresh motion / consume command
状态:已完成,对应 T-051。
目标:把当前 `motionStatus.motion.*` 中已有的 queue、inpos、id、paused、stepping、currentVel 等字段,以 LinuxCNC `EMC_TRAJ_STAT` 名称归入 `emcStatus.motion.traj`
目标:把 motion snapshot 中已有的 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`
- `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字段
@@ -161,18 +151,18 @@ lctask_read_status_json() -> step servo / read fresh motion / consume command
验收:
- staged program RUN 后,`emcStatus.task.readLine/currentLine/motionLine` 与现有 plan read/execute/motion id evidence 一致。
- 兼容字段若存在,必须与 `emcStatus.task.*Line` 同源
- 顶层 `task` 兼容视图不得再存在
### SJ-3规范 `motion.axis[]` 和 `motion.joint[]`
状态:已完成,对应 T-053。`emcStatus.motion.axis``emcStatus.motion.joint` 为数组;按名字访问的兼容视图保留在 `motionStatus.axis``emcStatus.motion.axisByName`辅助迁移
状态:已完成,对应 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.axis``motionStatus.joint0` 与新数组值一致
- 顶层 `motionStatus` 兼容视图不得再存在
### SJ-4规范 IO/aux/tool/coolant边界
@@ -189,22 +179,24 @@ lctask_read_status_json() -> step servo / read fresh motion / consume command
状态:已完成,对应 T-055。
目标:新增专用 gate例如 `tools/verify_task_status_json_contract.sh`,固定 status JSON 字段来自 `StandaloneEmcStatus`,并检查 `emcStatus` 与兼容字段的一致性
目标:新增专用 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`
新增字段默认进入:
@@ -217,7 +209,7 @@ lctask_read_status_json() -> step servo / read fresh motion / consume command
- `emcStatus.motion.joint`
- `emcStatus.io`
旧字段只能作为兼容视图,不能作为后续实现的主字段。新增测试优先断言 `emcStatus`再断言兼容字段与其一致
旧字段不再作为兼容视图保留。新增测试必须优先断言 `emcStatus`并在契约测试中继续对旧字段做负向断言
## 文档和测试要求