Files
cnc_wams/web-rtcp-5axis-xyzbc-trt-sim-plan/working/21-20260707-AXIS按钮LinuxCNC真实C++对标验收测试.md
2026-07-07 18:45:26 -04:00

577 lines
13 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.
# 2026-07-07 AXIS 按钮 LinuxCNC 真实 C++ 对标验收测试
## 1. 验收原则
本文件由 `19-20260707-AXIS按钮LinuxCNC-task-motion状态机制源码分析.md` 拆分而来定义“急停、上电、Home、执行、暂停、单步执行”的真实验收标准。
验收原则:
- `compare 60/60 pass` 不是最终验收结论,只是旧 compare 摘要。
- 验收必须证明 Web 行为符合 LinuxCNC C++ task/motion/homing 真实实现。
- 每个按钮必须同时验收 UI gate、runtime gate、状态记录、非法命令拒绝、真实程序执行影响。
- 如果表面 compare 通过,但 C++ 状态机硬规则失败,结论必须是失败。
最终验收结论字段建议:
```json
{
"surfaceSummary": {
"legacyComparePassCount": 60,
"legacyCompareFailCount": 0
},
"functionalSummary": {
"status": "pass",
"failCount": 0,
"requiredImprovements": []
}
}
```
只有 `functionalSummary.status == "pass"` 才允许写“真实通过”。
## 2. 验收准备
### 2.1 Native LinuxCNC 准备
命令:
```bash
/home/mes123456/cnc_wams/linuxcnc/scripts/rip-environment \
python3 /home/mes123456/cnc_wams/web-rtcp-5axis-xyzbc-trt-sim-plan/tools/collect-native-xyzbc-trt-evidence.py \
--run --timeout 90
```
必须采集:
- `task.state`
- `task.mode`
- `task.interpState`
- `task.execState`
- `task.task_paused`
- `task.currentLine`
- `task.readLine`
- `task.motionLine`
- `motion.traj.enabled`
- `motion.traj.paused`
- `motion.traj.single_stepping`
- `motion.traj.queue`
- `motion.joint[].homing`
- `motion.joint[].homed`
- active G-code line、motion id、axis pose、tcp pose、tool axis
### 2.2 Web 准备
命令:
```bash
npm --prefix /home/mes123456/cnc_wams/web-rtcp-5axis-xyzbc-trt-sim-plan/app run smoke:node
npm --prefix /home/mes123456/cnc_wams/web-rtcp-5axis-xyzbc-trt-sim-plan/app run smoke:browser
npm --prefix /home/mes123456/cnc_wams/web-rtcp-5axis-xyzbc-trt-sim-plan/app run evidence:web
```
必须采集与 native 同名字段,并额外采集:
- UI button enabled/disabled
- operator message
- runtime command accepted/rejected
- `machine.*` 状态快照
- Task/HAL status 快照
### 2.3 Compare 准备
命令:
```bash
npm --prefix /home/mes123456/cnc_wams/web-rtcp-5axis-xyzbc-trt-sim-plan/app run evidence:compare
```
compare 必须输出:
- 旧摘要 `surfaceSummary`
- 新硬规则 `functionalSummary`
- 每个 C++ 对标规则的 pass/fail 原因
## 3. 基础状态枚举验收
### T-STATE-001 task state 枚举一致
步骤:
1. 启动 Web runtime。
2. 依次发 `ESTOP``ESTOP_RESET``ON``OFF`
3. 对照 LinuxCNC `EMC_TASK_STATE`
期望:
- `ESTOP -> estop`
- `ESTOP_RESET -> estop-reset`
- `ON -> on`
- `OFF -> estop-reset/off 语义`Web 显示必须与项目约定一致,但不能伪装为 on。
失败条件:
- Web 只用 `powerOn` 推导 state。
- runtime status 与 UI 状态不一致。
### T-STATE-002 task mode 枚举一致
步骤:
1. 在 machine on 状态依次切 `manual``auto``mdi`
2.`auto + reading` 时尝试切出 auto。
期望:
- 正常 idle 下切换成功。
- `auto + reading` 切出 auto 必须被拒绝,或按 LinuxCNC abort/close/synch 语义处理并记录。
失败条件:
- 解释器运行中静默切到 manual/mdi。
### T-STATE-003 interp/exec 状态一致
步骤:
1. Run 前检查 `interpState=idle``execState=done`
2. Run 中检查 `interpState=reading/waiting``execState` 可进入 waiting 状态。
3. 完成后检查 `interpState=idle``execState=done`
失败条件:
- 只记录 `runState`,没有 `interpState/execState`
## 4. 急停验收
### T-ESTOP-001 ESTOP 可在任意状态触发
步骤:
1. machine on。
2. Home All。
3. Run 真实程序。
4. 在执行中发 ESTOP。
期望:
- runtime 接受 `EMC_TASK_SET_STATE ESTOP`
- `taskState=estop`
- `motionEnabled=false`
- `interpState=idle`
- `taskPaused=false``motionPaused=false`
- `singleStepping=false``motionStepping=false`
- feed velocity 为 0。
- spindle/coolant 关闭。
失败条件:
- ESTOP 后仍显示 running/paused/stepping。
- 位置继续推进。
- 只改 UI不改 runtime status。
### T-ESTOP-002 ESTOP_RESET 只解除急停但不上电
步骤:
1. 进入 ESTOP。
2. 发 RESET/ESTOP_RESET。
期望:
- `taskState=estop-reset`
- `powerOn=false`
- `motionEnabled=false`
- `interpState=idle`
失败条件:
- RESET 后直接上电。
## 5. 上电/下电验收
### T-POWER-001 ESTOP 下 Power 被拒绝
步骤:
1. 设置 `taskState=estop`
2. 点击/发送 Power。
期望:
- UI 禁用或 operator message 提示先解除急停。
- runtime 不接受 `ON`
- 状态保持 estop。
失败条件:
- ESTOP 下进入 on。
### T-POWER-002 ESTOP_RESET 下 Power On
步骤:
1. RESET 到 `estop-reset`
2. 点击 Power。
期望:
- 发送 `EMC_TASK_SET_STATE ON`
- `motionEnabled=true`
- 最终 `taskState=on`
失败条件:
- 只设置 `powerOn=true`runtime status 未 on。
### T-POWER-003 ON 下 Power Off
步骤:
1. machine on。
2. Home All。
3. Run 或进入 idle。
4. 点击 Power Off。
期望:
- 发送 `EMC_TASK_SET_STATE OFF`
- abort/disable。
- `motionEnabled=false`
- `interpState=idle`
- pause/step 状态清理。
失败条件:
- 下电后保留 running/paused/stepping。
## 6. Home 验收
### T-HOME-001 未上电 Home 被拒绝
步骤:
1. taskState=estop-reset。
2.`EMC_JOINT_HOME -1` 或点击 Home All。
期望:
- runtime 拒绝。
- operator message 指出 machine must be on。
- `homed[]` 不变化。
### T-HOME-002 MANUAL/ON/IDLE Home All
步骤:
1. RESET。
2. Power On。
3. 切 Manual。
4. 发 Home All。
期望:
- 出现 `homing=true` 瞬态。
- 完成后 `homing=false`
- `homed[]` 全 true。
- `allHomed=true`
- `homeState=homed` 或等价状态。
失败条件:
- 没有 homing 状态事件。
- 只设置 `allHomed=true`,没有 per-joint `homed[]`
### T-HOME-003 Homing 中禁止重复 Home/Run/Step/Jog
步骤:
1. 启动 Home All。
2. 在 homing 仍 active 时发 Home、Run、Step、Jog。
期望:
- 全部拒绝。
- 原 homing 流程不被破坏。
失败条件:
- homing 中允许 Run 或 Step。
## 7. Run 验收
### T-RUN-001 未 Home Run 被拒绝
步骤:
1. machine on。
2. mode=auto。
3. 保持 `allHomed=false`
4.`EMC_TASK_PLAN_RUN`
期望:
- runtime 拒绝。
- 错误等价于 LinuxCNC `Can't run a program when not homed`
- `interpState` 保持 idle。
失败条件:
- 只因 UI 禁用,但 runtime 可直接 Run。
### T-RUN-002 合法 Run 真实程序
步骤:
1. RESET。
2. Power On。
3. Home All。
4. 加载真实 G-code。
5. mode=auto。
6. Run。
期望:
- `interpState=reading/waiting`
- `taskPaused=false`
- `singleStepping=false`
- `currentLine/readLine/motionLine` 随执行推进。
- axis pose、tcp pose、tool axis 随真实程序变化。
- 完成后 `interpState=idle`
失败条件:
- 只播放前端路径,不产生 task/motion 状态流。
- line/motion id 不推进。
### T-RUN-003 非 idle Run 被拒绝
步骤:
1. 合法 Run。
2. 在 reading 或 paused 状态再次发 Run。
期望:
- reading 时拒绝。
- paused 时应提示 resume而不是重新 Run。
失败条件:
- 运行中重入 Run。
## 8. Pause/Resume 验收
### T-PAUSE-001 AUTO/READING Pause
步骤:
1. 合法 Run。
2. 等待进入 reading。
3. 发 Pause。
4. 连续采样至少 5 帧,每帧间隔 50ms。
期望:
- `interpState=paused`
- `interpResumeState=reading` 或 waiting。
- `taskPaused=true`
- `motionPaused=true`
- feed velocity 为 0。
- activeLine、axis pose、tcp pose、tool axis 在暂停采样中冻结。
失败条件:
- 状态 paused 但位置继续变化。
- 只冻结 UI不冻结 runtime feedback。
### T-PAUSE-002 Resume 恢复 interpResumeState
步骤:
1. 在 T-PAUSE-001 暂停状态发 Resume。
期望:
- `interpState` 恢复到 `interpResumeState`
- `taskPaused=false`
- `motionPaused=false`
- `singleStepping=false`
- 执行继续推进。
失败条件:
- Resume 固定写 reading丢失 waiting/mdi 语义。
### T-PAUSE-003 非运行 Pause 被拒绝
步骤:
1. idle 状态发菜单 Pause。
期望:
- 拒绝或忽略。
- 状态保持 idle。
失败条件:
- idle 下进入 paused。
## 9. Step 验收
### T-STEP-001 IDLE Step 等价 Run 后 Pause
步骤:
1. RESET。
2. Power On。
3. Home All。
4. 加载真实程序。
5. mode=auto。
6. 在 idle 发 Step。
期望:
- 启动 program run。
- 随后进入 paused。
- `taskPaused=true`
- `motionPaused=true`
- `singleStepping=true` 或 evidence 中记录 single stepping 事件。
- active line/motion id 到第一步后停止。
失败条件:
- Step 只是前端 sample+1没有 task/motion 状态。
### T-STEP-002 PAUSED Step 放行到下一个 motion id
步骤:
1. 执行 T-STEP-001 或 Run 后 Pause。
2. 记录当前 `motionId/currentLine`
3. 发 Step。
4. 等待下一次 paused。
期望:
- motion id 或 currentLine 前进到下一段。
- 再次 `motionPaused=true`
- `motionStepping` 事件出现后清理。
- 不是按固定采样点数量推进。
失败条件:
- Step 后没有 line/motion id 变化。
- Step 后持续 running 不再暂停。
### T-STEP-003 Resume/Abort/ESTOP/OFF 清 Step
步骤:
1. 进入 stepping/paused。
2. 分别执行 Resume、Abort、ESTOP、OFF。
期望:
- `singleStepping=false`
- `motionStepping=false`
- 不残留 step lock。
失败条件:
- 后续 Run 被旧 step 状态影响。
## 10. 非法命令矩阵验收
必须在无 UI runtime 层执行:
| 状态 | 命令 | 期望 |
|---|---|---|
| estop | ON | 拒绝,必须先 estop reset |
| estop-reset | RUN | 拒绝machine must be on |
| on/manual/idle/unhomed | RUN | 拒绝home first |
| on/auto/reading | HOME | 拒绝interpreter must be idle |
| on/auto/reading | SET_MODE manual | 拒绝或按 C++ abort/synch 明确处理 |
| on/auto/idle/no program | RUN | 拒绝,无程序 |
| on/manual/idle | PAUSE | 拒绝 |
| on/auto/idle | PAUSE | 拒绝或忽略 |
| on/auto/paused/resumeInhibit | RESUME | 拒绝 |
| homing active | RUN/STEP/JOG/HOME | 拒绝 |
失败条件:
- UI 禁用但 runtime 接受非法命令。
- runtime 拒绝但 UI 显示允许。
- 非法命令改变状态。
## 11. 真实程序功能验收
真实程序验收不能只看按钮状态,需要验证程序执行功能:
1. 使用 LinuxCNC `xyzbc-trt` 配置真实可运行 G-code。
2. Native 和 Web 使用同一 G-code、同一 INI/HAL/profile、同一采样周期。
3. 采集预览路径、执行路径、task 状态、motion 状态、joint home 状态、line/motion id。
4. 在执行中插入 Pause、Resume、Step、ESTOP。
5. 对比每个动作前后真实程序状态。
必须检查:
- G-code line 读取顺序。
- `readLine/currentLine/motionLine` 对齐。
- motion id 单步推进。
- Pause 时路径冻结。
- Resume 后继续同一程序,不重头执行。
- ESTOP 后停止且不能继续运动。
- Home 前 Run 必须失败。
## 12. Compare 硬通过标准
compare 输出必须包含以下硬检查:
| 检查名 | 必须为 pass 的依据 |
|---|---|
| `cppTaskStateMachineParity` | ESTOP/RESET/ON/OFF 与 `emcTaskSetState()` 和 task update 推导一致 |
| `cppModeGateParity` | `emcTaskSetMode()` 的 AUTO 非 idle 限制一致 |
| `cppHomingParity` | `EMCMOT_JOINT_HOME``homing.c` 状态流一致 |
| `cppRunGateParity` | `EMC_TASK_PLAN_RUN` 的 ON/AUTO/IDLE/Home/Program gate 一致 |
| `cppPauseResumeParity` | `EMC_TASK_PLAN_PAUSE/RESUME``EMCMOT_PAUSE/RESUME` 一致 |
| `cppStepParity` | `EMC_TASK_PLAN_STEP``EMCMOT_STEP` 的 motion id 单步一致 |
| `illegalCommandParity` | runtime 和 UI gate 一致拒绝非法命令 |
| `realProgramExecutionParity` | 真实程序 line/path/pose/status 一致 |
最终判定规则:
```text
如果 legacy compare 60/60 pass但任一 cpp*Parity 或 realProgramExecutionParity fail则整体验收 fail。
如果 smoke pass但非法命令矩阵 fail则整体验收 fail。
如果截图正常,但 task/motion 状态流不符合 C++,则整体验收 fail。
```
## 13. 验收记录模板
每轮验收必须记录:
```text
验收时间:
LinuxCNC 源码 commit/版本:
Web 项目 commit/工作区状态:
使用 INI
使用 G-code
Native evidence
Web evidence
Compare evidence
surfaceSummary
functionalSummary
失败项:
是否允许宣称真实通过:
结论:
```
结论只能使用:
- `真实通过`:所有 functional hard checks 通过。
- `表面通过但功能未通过`legacy 60/60 通过但硬规则失败。
- `未通过`legacy 或 functional 任一失败。
- `阻塞`:缺少 native evidence、Web evidence 或 C++ 映射。