Document source UI gates, explicit native live-plot clearing, and remaining parity boundaries. Fix pause/resume transport continuity, repeated stepping, coordinate previews, and spindle override state. Optimize large program snapshots and rendering, and cover the control flows with native Tcl, WASM, and browser checks. Validation: 22 native tests and source/browser checks pass. Worker/App regression: 113 of 123 pass; 10 pre-existing failures remain documented with no new failures.
720 lines
46 KiB
Markdown
720 lines
46 KiB
Markdown
# XYZAC TRT 面板按钮对标测试报告
|
||
|
||
## 2026-09-08 10:33 恢复原生清图方式(北京时间,当前结论)
|
||
|
||
按最新明确要求“按原生的方法如何清除的,web 也同样方式清除”,先更新
|
||
流程文件“原生清图方式(10:14)”,再修改实现。本节取代下方历史版本中
|
||
自动换程序清图的说明,不再保留该扩展行为。
|
||
|
||
源码路径:`axis.tcl` 工具栏 Clear Live Plot / Ctrl-K →
|
||
`axis.py::clear_live_plot` → `LivePlotter.clear` → `positionlogger.clear`。
|
||
`open_file_guts`、`reload_file` 创建/替换程序预览,但不调用这一清图路径。
|
||
|
||
当前 Web 行为:
|
||
|
||
| 操作 | 加工轨迹 Live Plot | 程序预览 |
|
||
| --- | --- | --- |
|
||
| Open、同文件 Reload、编辑后 Reload、加载 Chips | 保留 | 替换 |
|
||
| Run、Pause、Resume、Stop、正常结束 | 保留 | 保留 |
|
||
| 工具栏 Clear Live Plot / Ctrl+K | 清除,运行时继续累积后续运动 | 保留 |
|
||
|
||
实现仅移除五个 Web 加载入口的自动清图标志,以及 Worker PROGRAM_LOAD
|
||
中的自动清图分支。旧调用即使附带退役的 `clear_live_plot_on_replace` 参数,
|
||
也不会额外清图。显式 VISUAL_CLEAR、暂停/恢复通信修复和 Chips 性能优化保留。
|
||
|
||
验证结果:
|
||
|
||
- Worker 验证换文件、同文件、编辑后、解析失败与 gate 拒绝均不改变
|
||
live epoch;显式 Clear 才推进 epoch,且 task/motion/program 哈希不变。
|
||
- 浏览器 Open 和 Reload 保留轨迹;工具栏 Clear 清为 0、静态预览保留。
|
||
- Ctrl+K 将 41 个实际运动轨迹点清为 0,12 段静态预览完整保留。
|
||
- 默认程序与 Chips 的重复暂停/清图/倍率/继续、暂停中 Step 后继续和
|
||
移动端清图/继续均通过;185 条桌面有序命令、4 项预期 task 拒绝,无通信错误。
|
||
- 源码契约、TypeScript/生产构建通过;桌面/移动 canvas 检查通过。
|
||
- 全量 Worker/App:123 项,113 通过、10 项原有失败;与上一轮失败集合
|
||
相同,没有新增失败。既有完整 AXIS 能力边界不因此改变。
|
||
|
||
原始记录:`/tmp/axis-native-clear-browser.json`、
|
||
`/tmp/axis-native-clear-pause.json`、`/tmp/axis-native-clear-regression.log`。
|
||
本地预览:`http://127.0.0.1:5175/`,刷新后使用新版本;未进行远程部署。
|
||
|
||
## 2026-09-08 09:57 暂停/恢复一致性修复(北京时间,当前结论)
|
||
|
||
遵循“先核对源码、更新流程文档,再修改代码”的顺序。本次修复仅涉及已连接
|
||
通信层对 PAUSED 的处理,以及 React 对 task 拒绝的采样处理;既有轨迹、
|
||
G-code、TP 步长、进给、程序切换和 UI 控件集合继续使用原实现。
|
||
|
||
### 已复现的原因
|
||
|
||
| 命令 | 发送 seq | 旧通信层 last_seq | 结果 |
|
||
| --- | --- | --- | --- |
|
||
| PROGRAM_PAUSE | 9 | 9 | 成功暂停 |
|
||
| VISUAL_CLEAR | 10 | 9 | protocol.invalid_state |
|
||
| PROGRAM_RESUME | 11 | 9 | protocol.sequence_gap |
|
||
| PROGRAM_ABORT | 12 | 9 | protocol.sequence_gap |
|
||
|
||
旧 `sim_protocol.c` 在 PAUSED 使用另一份命令白名单,拒绝了 Tcl 仍允许的
|
||
Clear、Step、主轴倍率等操作,并且不消费 seq。随后继续和停止都无法恢复
|
||
通信连续性。该问题独立于 TP 是否能恢复,也不能通过改写 task 状态解决。
|
||
|
||
源依据是 `axis.py::task_pause/task_resume/task_pauseresume` 和
|
||
`emctaskmain.cc` 的 PAUSED 命令分支、`interpResumeState` 保存/恢复:暂停
|
||
保留队列和恢复状态,NML 通道继续接受命令,再由 task 判断执行是否合法。
|
||
|
||
### 修复及保持不变的行为
|
||
|
||
- READY/PAUSED 均接收顺序正确的合法通信帧;Worker task gate 继续负责拒绝
|
||
非法机床操作,拒绝事件按该 seq 入账,后续 Resume/Stop 不再断档。
|
||
- schema、握手、operation_id、真正乱序和 tick 回退校验继续生效;不放宽
|
||
CNC gate、不丢弃错误、不自动重发副作用、不用 Reload/清 TP 实现恢复。
|
||
- React 遇到 `axis_gate` 拒绝时保留 canonical 状态。若 task 仍运行则继续
|
||
原有单请求采样;真正 FAULT/OFF/ESTOP、恢复或其他错误继续停止采样。
|
||
- 原生协议单测加入 `-UNDEBUG`,确保 Release 构建确实执行断言;补充暂停中
|
||
通信接收和真正坏帧拒绝。旧 MDI 通信拒绝断言改由真实 Worker task 拒绝
|
||
用例覆盖,未删除机床拒绝验证。
|
||
|
||
### 验证结果
|
||
|
||
| 检查 | 结果 |
|
||
| --- | --- |
|
||
| 原生构建 / CTest | 22/22 通过,协议断言已启用 |
|
||
| `test_xyzac_pause_resume_consistency.mjs` | 153 条真实 WASM 命令,通信 seq 与事件 cursor 一致;重复暂停、清图/倍率、非法命令、单步后继续、WAITING 完成、MDI 暂停/继续、最后停止均通过 |
|
||
| `test_xyzac_pause_resume_browser.mjs` | 默认程序与 Chips 各三轮暂停/清图/倍率/继续;重复命令拒绝不终止后续运动;暂停中单步后继续、移动端暂停/清图/继续/停止通过;桌面段 194 条有序命令、4 个预期 task 拒绝,无通信错误 |
|
||
| 既有按钮浏览器检查 | 20/20 组通过,浏览器错误 0 |
|
||
| 既有轨迹生命周期 | 换新文件清图、同源重复执行保留、Pause/Resume/Stop 保留、显式 Clear 通过 |
|
||
| 源码公式/清单 | Tcl 7488 条断言、源码 hash 和 82 个控件 ID 通过 |
|
||
| TypeScript / Vite | 通过;保留既有 bundle 大小提示 |
|
||
| 全量 Worker/App | **123 项,113 通过,10 项旧失败**;与上一轮失败集合相同,新增失败 0 |
|
||
|
||
剩余旧失败仍为三轴 adapter/完成状态/工具 IO 和配置数量问题,详见下方
|
||
历史记录;不能把本次专项通过写成完整 LinuxCNC 发布或全仓测试通过。
|
||
|
||
原始记录:`/tmp/axis-pause-resume-build.log`、
|
||
`/tmp/axis-pause-resume-browser.json`、`/tmp/axis-pause-resume-regression.log`、
|
||
`/tmp/axis-pause-buttons-regression.json`、`/tmp/axis-pause-plot-regression.json`。
|
||
桌面/移动截图:`/tmp/axis-pause-resume-desktop.png`、
|
||
`/tmp/axis-pause-resume-mobile.png`。
|
||
|
||
本地生产预览为 `http://127.0.0.1:5175/`。刷新页面才会启动新 WASM Worker;
|
||
本次未远程部署,也不会在旧页面已损坏的通信序号上静默重放程序。
|
||
|
||
## 2026-09-08 换程序清图与 Chips 性能(当前结论)
|
||
|
||
本次按“核对 AXIS 源码 → 先完善流程文件 → 修改实现 → 复现验收”执行。
|
||
对应流程见 `linuxcnc-axis-web-control-panel-source-logic.md` 的“换程序轨迹与
|
||
长程序性能”及更新后的“Toolpath display lifecycle”。
|
||
|
||
### 清图语义
|
||
|
||
`axis.py::open_file_guts` 替换静态 AxisCanon,不调用 LivePlotter.clear;
|
||
原生保留历史加工轨迹。因此这不是原生 Open 的缺陷。本次按用户明确要求,
|
||
Web 文件替换发送 `clear_live_plot_on_replace:true`,在新文件/新文本解析
|
||
成功后,通过与 VISUAL_CLEAR 共用的 `clearLivePlot()` 递增可视 epoch,
|
||
一次发布新预览与新 epoch。这是已记录的 `WEB_EXTENSION`,不冒充原生行为。
|
||
|
||
默认 PROGRAM_LOAD 保留轨迹;同文件同文本 Reload、Run/Pause/Resume/Stop
|
||
保留轨迹。取消、门控拒绝或解析失败不自动清图。加载期间也不再用 null
|
||
快照造成假 epoch=0;画布只按真正的 Worker epoch 清除历史和待播放样本。
|
||
|
||
### 性能原因与测量
|
||
|
||
修改前 CPU profile 中,82.9% 样本位于 JS `fnv1a64`,主要来自每次 program
|
||
snapshot 对 200509 字节源程序重复计算 hash。此外,全部 canonical 线段
|
||
都有 samples,旧绘图分支将其各建成独立 Three.js Line,导致约 4684 次
|
||
静态 draw call,而非代码注释中声称的批量绘图。
|
||
|
||
修正为源文本 hash 按不可变文本缓存,保留 WASM 动态状态的实时读取;
|
||
同一 servo 批次只读取一次不变的 program paused 状态;相邻 canonical
|
||
顶点合并成 rapid/feed 两个 LineSegments;Live Plot 使用增量更新的 GPU
|
||
缓冲,不再每几帧复制整段历史。未修改 G-code、F 值、倍率、TP 或 tick 步长。
|
||
|
||
同一主机、相同输入、两次 Chips 加载,200 task ticks(2 秒仿真)测试:
|
||
|
||
| 指标 | 修改前 | 修改后 |
|
||
| --- | --- | --- |
|
||
| 第一次 Chips 加载 | 18.904 s | 1.822 s |
|
||
| 再次 Chips 加载 | 18.394 s | 1.688 s |
|
||
| 推进 2 秒仿真(第一次) | 10.376 s CPU/墙钟 | 0.325 s CPU/墙钟 |
|
||
| 推进 2 秒仿真(再次) | 10.268 s | 0.296 s |
|
||
| 200 次长程序 snapshot | 755 ms | 40 ms |
|
||
| 5-tick 请求 p95(第一次) | 287 ms | 13.4 ms |
|
||
|
||
两个尝试的 source hash、preview hash、preview 段数、末端位置、速度、队列、
|
||
进给倍率、执行行号在修改前后逐项完全一致;清图 epoch 是唯一预期的可视
|
||
生命周期差异。以上是计算吞吐提升,不是放大机床速度。浏览器仍按 1 倍
|
||
仿真时间推进,最多一个采样请求在途。
|
||
|
||
### 完整浏览器场景
|
||
|
||
在 `http://127.0.0.1:5175/` 运行实际配置的第一份 `xyzac_switchkins.ngc`
|
||
直到完成,然后点击加载 `linuxcnc/nc_files/3D_Chips.ngc`,再运行/暂停/
|
||
恢复/停止,结果:
|
||
|
||
| 项目 | 实际结果 |
|
||
| --- | --- |
|
||
| 第一份程序完成时 Live Plot | 4349 点 |
|
||
| 第二份加载完成后旧 Live Plot | 0 点,新 epoch=2 |
|
||
| Chips 浏览器加载 | 2624 ms |
|
||
| 静态预览 | 4683 段,2 次 draw call;旧程序结束在 Z10,首个 G0 Z10 是正确消去的零位移 |
|
||
| 运行 5.020 s 墙钟 | 推进 5.050 s 仿真,比例 1.006 |
|
||
| Worker 请求 p95 | 18.2 ms |
|
||
| 暂停/停止响应 | 149 / 151 ms |
|
||
| 浏览器错误 | 0 |
|
||
|
||
另外验证同源 Reload 保留轨迹、显式 Clear 只清 Live Plot、不清静态预览;
|
||
默认 Worker PROGRAM_LOAD 的原生保留路径及成功/失败/拒绝 Web 替换均通过。
|
||
|
||
移动端长程序编辑区的自动高度曾扩展到数万像素,已改为固定 grid 高度和
|
||
内部滚动。390/768/1440 宽度下页面高度为 2520/2427/1559,编辑器可滚动
|
||
81957 像素但只渲染 30/30/37 行;移动端运行比 0.999,错误 0。桌面/移动端
|
||
canvas 非空,Chips 实体刀路正常显示,截图已检查。
|
||
|
||
### 复现与回归
|
||
|
||
- `scripts/benchmark_xyzac_program_replacement.mjs`:实际 WASM 前后基准。
|
||
- `scripts/test_xyzac_second_program_browser.mjs`:完整首程序完成后换 Chips。
|
||
- `scripts/test_xyzac_chips_layout_browser.mjs`:三种尺寸、长编辑器滚动及移动运行。
|
||
- `scripts/test_xyzac_live_path_lifecycle_browser.mjs`:暂停/恢复/停止、换文件、重复运行、显式清图。
|
||
- 源码契约、82 个控件 ID、TypeScript 和生产构建通过。
|
||
- 针对性 Worker/React 回归 9/9;全量 Worker/App **122 项,112 通过、10 项原有失败**,与上轮失败集合相同。
|
||
|
||
原始输出:`/tmp/axis-chips-before.json`、`/tmp/axis-chips-after.json`、
|
||
`/tmp/axis-chips-browser.json`、`/tmp/axis-chips-layout.json`、
|
||
`/tmp/axis-chips-lifecycle-browser.log`、`/tmp/axis-chips-full-regression.log`。
|
||
截图:`/tmp/axis-chips-replacement-1440.png`、`/tmp/axis-chips-replacement-390.png`。
|
||
|
||
本次仅修正上述换程序和性能问题,保持既有完整 AXIS/所有配置的能力边界,
|
||
未进行远程部署;线上页面不会因本地代码修改自动更新。
|
||
|
||
## 2026-09-08 第二次源码复核(当前结论)
|
||
|
||
按要求先复核并修正流程文件,再修改 Worker/WASM 和 Web。当前流程文件的
|
||
“源码复核修正”和“尚未取得完整等价证据”两节是本次审核入口;早期的
|
||
SOURCE_ADAPTER 标签不得用来掩盖其中列出的功能缺口。
|
||
|
||
### 源码证据
|
||
|
||
新增 `scripts/test_axis_source_ui_oracle.mjs`,直接执行锁定的
|
||
`axis.tcl::update_state`,对 **576 种状态组合、13 条控件公式作 7488 条断言**,
|
||
结果通过。源码 Python/Tcl hash 检查和 **82 个控件 ID** 清单检查也通过。
|
||
该测试不运行桌面 AXIS,更不替代完整 motion 数值 oracle;它验证原始 Tcl
|
||
公式与 Web 的 `ui_gates` 投影一致。
|
||
|
||
### 本次修正
|
||
|
||
| 项目 | 源码定义与实现结果 |
|
||
| --- | --- |
|
||
| UI 与命令门控 | `ui_gates` 对标 Tcl,`gates` 对标命令接收。Run/Step 不再用未回零状态改变原生 UI 公式;MDI UI 可用时,handler 仍可按 manual_ok 拒绝并保留输入 |
|
||
| OFF 状态 | `STATE_ESTOP_RESET` 在 AXIS 显示为 OFF;不再根据 last_error 猜测机器状态,也不再将 FAULT 标签直接投影成 ESTOP |
|
||
| Step | 初次从 0 行进入暂停;后续可连续解析;已有暂停运动通过 C/WASM 的 TP 执行 ID 边界单步。原生 C 测试验证两条排队运动分两次完成,不能一次排空 |
|
||
| WAITING | 程序读完但运动未结束可暂停;恢复原来的完成/等待状态,不重新开始解释;MDI 运动期间正确投影 WAITING 并保持互斥 |
|
||
| 模式恢复 | ON+IDLE 的 AUTO 边沿及文件加载后按选中标签发送 SET_MODE;在消息处理时排队,避免延迟 effect 覆盖后续 Run |
|
||
| Home Axis | switchkins 始终为 KINEMATICS_BOTH。世界轴字母回零正确拒绝;Worker 独立支持 `HOME {joint:0..4}` 的原生数字 joint 入口,未伪装为世界轴按钮 |
|
||
| 主轴覆盖率 | 独立保留 requested_rpm/direction;覆盖率 0 后恢复原转速与方向;React 不再按输出 RPM 的正负推断按钮方向 |
|
||
| 手动/MDI 控件组 | 轴单选框及 MDI 历史列表加入各自的源控件组门控;c/i/I 切换步长;Escape 可调用原生 task_stop,中止手动或 MDI 运动 |
|
||
| 预览 | Rotate 只切换鼠标 Drag/Rotate;取消自动旋转。limits 读取 C/WASM XYZ 软限位;offsets 读取 G5x;velocity/extents 现在确实改变对应显示。按 glnav.py 修正五个正交视图、Z2 的平面旋转及短程序过大的标记 |
|
||
|
||
### 验收结果
|
||
|
||
| 检查 | 结果 |
|
||
| --- | --- |
|
||
| 原始 Tcl 公式对照 | 7488/7488 通过 |
|
||
| 原生 CTest | 22/22 通过;包含双段 TP 单步和方向限位 |
|
||
| 实际 WASM 控制链 | `test_axis_source_execution.mjs` 的 UI/命令门控、Step、WAITING/MDI、回零类型、主轴零覆盖率均通过 |
|
||
| 生产构建浏览器按钮 | 20/20 组通过 |
|
||
| 生产构建事件/显示流程 | 12/12 组通过;包含重复 Step、模式恢复、旋转不自转、真实图层、1440×1000 和 390×844 画布像素检查 |
|
||
| 控件清单 | 82 个已登记 ID/家族;初始 DOM 80 个控件,About/历史为动态控件 |
|
||
| 前端投影测试 | 4/4 通过 |
|
||
| TypeScript / Vite | 通过;既有 bundle 大小提示仍存在 |
|
||
| 全部 Worker/App 测试 | **122 项,112 通过,10 失败** |
|
||
|
||
剩余 10 项均为上轮已在修改前源码复现的旧三轴/配置问题:
|
||
`test_axis3_selected_case`、`test_axis3_tutorial_motion`、`test_axis3_tutorial_program`、
|
||
`test_axis3_tutorial_sequence`、`test_axis3_tutorial_tool_io`、`test_axis3_visible_completion`、
|
||
`test_panel_gate_matrix`、`test_panel_snapshot_projection`、`test_sim_case_matrix_s8_06`、
|
||
`test_wasm_canonical_state`(均为 `web/worker/*.mjs`)。没有把这些失败计为通过。
|
||
|
||
`test_xyzac_manual_control` 已使用真实 joint 编号回零、等待 MDI 队列排空后再
|
||
加载程序;原测试的 Z180 超过选定 INI 的 Z 最大值 120,正常路径改为 Z18,
|
||
并继续保留越界拒绝和活动 MDI 拒绝断言。ESTOP_RESET 断言改为检查 source
|
||
state;界面显示 OFF。首次 Step 及暂停恢复测试已按源 task 分支更新。
|
||
|
||
日志:`/tmp/axis-source-round2-final-regression.log`、
|
||
`/tmp/axis-source-round2-camera-final.log`、`/tmp/axis-source-round2-browser-buttons2.log`。
|
||
截图:`/tmp/axis-source-flow-1440.png`、`/tmp/axis-source-flow-390.png`。
|
||
本地生产预览:`http://127.0.0.1:5175/`,未执行远程部署。
|
||
|
||
### 仍不属于完整对标
|
||
|
||
完整 joint/world 模式、Run 边界警告对话框、独立角速度和物理单位滑块、
|
||
原生 task/NML 指令级 Step 细分、全部 G92/旋转/刀具补偿图层、optional stop、
|
||
block delete、rapid override、Tool Touch Off 等仍有明确缺口。TP 执行 ID 在
|
||
伺服采样后变化,单步边界允许原生单周期内的微小推进,未伪造精确端点。
|
||
新 IO 状态布局由 `sim_io_size` 读取;旧布局 checkpoint 会明确拒绝,不能
|
||
把旧二进制状态直接套入新结构。
|
||
|
||
因此本轮结论是**指定控制路径经源码验证并修正,仍有公开的源功能缺口**;
|
||
不是“全部 LinuxCNC/AXIS 功能已经完全等价”。`release_status: STOP_RELEASE`。
|
||
|
||
## 2026-09-08 源流程文件驱动验收
|
||
|
||
本次按“核对 AXIS 源码 → 完善流程文件 → 修改 WASM/Worker → 修改 Web → 验收”执行。
|
||
当前规范为 [`linuxcnc-axis-web-control-panel-source-logic.md`](../docs/linuxcnc-axis-web-control-panel-source-logic.md),
|
||
覆盖 **82 个控件 ID/动态家族**,并同步了 DOT 与 PNG 流程图。
|
||
本节是当前结论;后面的旧版本记录仅用于历史追溯,不能替代本节或当前流程文件。
|
||
|
||
状态:`VERIFIED_WITH_SCOPE_GAPS`;发布边界继续为 `STOP_RELEASE`。
|
||
本地生产构建预览:`http://127.0.0.1:5175/`。
|
||
|
||
### 按流程修正
|
||
|
||
| 流程 | 当前行为与验证 |
|
||
| --- | --- |
|
||
| 文件打开/重载 | 统一 Worker 加载门控;运行、暂停、活动 TP 队列和读取中的互斥;异步读取后再次检查门控 |
|
||
| 按住点动 | 一次 `JOG_START`,C/WASM 选择方向限位;浏览器只发 `SIM_STEP`;释放/取消/移出/失焦/隐藏页只发送一次 `JOG_STOP` |
|
||
| 增量点动 | 松开后继续采样直到 WASM 队列排空;线性轴按显示单位转换,A/C 保持角度 |
|
||
| MDI | trim、清空输入、相邻历史去重、1000 条历史上限、单击选取、双击一次执行、Up/Down 循环选择 |
|
||
| 主轴/冷却/Stop | 区分原生命令接收条件与 Tcl 控件启用条件;主轴指令自行切 MANUAL,F9/F10 先停转分支保留;冷却复选框只在 ON+IDLE 可用,Stop 按钮只在 ON+非 IDLE 可用 |
|
||
| 覆盖率 | Feed/Jog/Max/Spindle 设置在 OFF/ESTOP 仍可提交;快照回显数值,设置本身不得使主轴启动 |
|
||
| 对刀 | G10 不改变机器位置;X/Y/Z 单位转换与 A/C 角度分开;G54..G59.3 偏置保留到 Reload,重新生成预览并更新 relative 显示 |
|
||
| 程序完成 | M2/EOF 后等待最后 TP 段排空;验收同时检查队列排空前 Run 禁用、排空后任务 STOPPED |
|
||
| 快捷键/弹窗 | F1 在文本输入中仍有效;大小写和 Ctrl/Alt/Meta 不误映射机器命令;About 焦点、Escape 和菜单关闭按流程处理 |
|
||
| 显示 | 修复菜单弹层裁切、文件栏按钮被挤压和窄屏数值裁切;减少画布调试文本遮挡 |
|
||
|
||
### 实际结果
|
||
|
||
| 检查 | 结果 |
|
||
| --- | --- |
|
||
| `scripts/build-wasm.sh` | WASM 构建及内置样例通过;native CTest **22/22** 通过 |
|
||
| 源码契约/控件清单 | Python/Tcl 源文件 SHA-256 与锁定值一致;**82** 个控件 ID 已登记 |
|
||
| `test_xyzac_panel_buttons_browser.mjs` | 最新生产构建 **20/20** 组通过,浏览器错误 0;含菜单、案例、急停和断电恢复 |
|
||
| `test_axis_panel_source_flow_browser.mjs` | **11/11** 组通过;实际统计 Worker 命令,验证五轴双向、快速释放、失焦、键盘按住、MDI 历史、对刀与相对坐标 |
|
||
| 浏览器控件清单 | 初始 80 个控件加动态 About,历史家族另在专项生成并验证;无未登记或非法重复 ID |
|
||
| 桌面/移动端 | 1440×1000、390×844;画布非空、视图改变像素、资源加载正常、无页面横向溢出 |
|
||
| `web/react/src/test_*.mjs` | **4/4** 投影测试通过 |
|
||
| TypeScript/Vite | typecheck/build 通过;保留既有大 bundle 提示 |
|
||
| 全部 `web/worker/test_*.mjs` + `web/app/test_*.mjs` | **121 项,110 通过,11 失败**;不能标记全仓通过 |
|
||
|
||
原始输出:`/tmp/axis-panel-core-build-final.log`、
|
||
`/tmp/axis-panel-browser-production.log`、`/tmp/axis-panel-source-flow-acceptance.log`、
|
||
`/tmp/axis-panel-worker-acceptance.log`。
|
||
截图:`/tmp/axis-source-flow-1440.png`、`/tmp/axis-source-flow-390.png`。
|
||
|
||
### 修改前复现与保留失败
|
||
|
||
使用主仓库提交 `845075f4a37baca145ecec572d93d8aade17ba32` 的独立源码目录
|
||
`/tmp/axis-source-baseline.mK3EZO` 重建原始 WASM,复用相同 LinuxCNC 资源,
|
||
对 13 个相关用例复测:1 通过、12 失败。
|
||
其中 `test_xyzac_hal_tool_alarm.mjs` 的 MDI 空闲态主轴拒绝已修正;
|
||
最终剩余 11 项均属于该基线失败集合,**新增失败数为 0**。
|
||
复现输出:`/tmp/axis-panel-baseline-failures.log`。
|
||
|
||
| 保留用例(均位于 `web/worker/`) | 失败原因 |
|
||
| --- | --- |
|
||
| `test_axis3_selected_case.mjs`、`test_axis3_tutorial_motion.mjs`、`test_axis3_tutorial_sequence.mjs`、`test_panel_gate_matrix.mjs`、`test_panel_snapshot_projection.mjs`、`test_wasm_canonical_state.mjs` | 旧三轴 motion adapter 缺少 `wasmMotion.jog` |
|
||
| `test_axis3_tutorial_program.mjs`、`test_axis3_visible_completion.mjs` | 旧三轴任务完成状态仍为 RUNNING |
|
||
| `test_axis3_tutorial_tool_io.mjs` | 旧三轴工具/IO 路径被门控拒绝 |
|
||
| `test_sim_case_matrix_s8_06.mjs` | 资源矩阵实际数量 236 与旧断言 235 不一致 |
|
||
| `test_xyzac_manual_control.mjs` | 旧用例要求在 MDI 运动队列未排空时接受 `PROGRAM_LOAD`,与当前文档的加载互斥相冲突;保留拒绝行为 |
|
||
|
||
`test_xyzac_machine_sequence.mjs` 已按源码补充 M2 后的有限队列排空检查,
|
||
继续断言 TP 队列非空时 Run 禁用、最终 task STOPPED、queue=0;输出记录实际
|
||
`drain_ticks`,不再把固定 8000 个采样等同于完成。
|
||
原先关于“Spindle 必须预先 MANUAL”及“OFF/ESTOP 禁止覆盖率”的断言已按
|
||
AXIS handler/Tcl 原公式修正,并增加实际 WASM 状态断言。
|
||
|
||
### 明确边界
|
||
|
||
Rapid Override、独立 Angular Jog Speed、Override Limits、Block Delete、
|
||
Optional Stop、完整 Tool Touch Off/工具偏置 ABI,以及桌面工具编辑器/Quit
|
||
仍按流程记录为 `SOURCE_BLOCKED` 或 host boundary。禁用功能不计入已实现
|
||
源码对标;当前证据也不代表完整原生 free/teleop 减速、全部坐标旋转/G92/
|
||
刀具补偿、所有 LinuxCNC 配置或完整 TP 数值 oracle 已闭合。
|
||
|
||
复现本次验收:
|
||
|
||
```bash
|
||
bash scripts/build-wasm.sh
|
||
node scripts/test_axis_control_contract.mjs
|
||
node scripts/test_axis_control_inventory.mjs
|
||
node --experimental-strip-types web/worker/test_xyzac_source_widget_gates.mjs
|
||
node --experimental-strip-types web/worker/test_xyzac_touch_off_source_flow.mjs
|
||
npm run build --prefix web/react
|
||
# 本地预览运行后,向这两个脚本传入 PLAYWRIGHT_MODULE 和 XYZAC_PANEL_URL
|
||
node scripts/test_xyzac_panel_buttons_browser.mjs
|
||
node scripts/test_axis_panel_source_flow_browser.mjs
|
||
node --experimental-strip-types --test --test-concurrency=4 web/worker/test_*.mjs web/app/test_*.mjs
|
||
```
|
||
|
||
## 历史记录(不作为当前验收结论)
|
||
|
||
## 结论
|
||
|
||
本报告针对当前选定案例
|
||
`linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini`,
|
||
按 LinuxCNC AXIS 的命令、门控、状态和错误语义执行了一轮完整面板验收。
|
||
|
||
`selected_case_status: VERIFIED_WITH_SCOPE_GAPS`
|
||
|
||
`release_status: STOP_RELEASE`
|
||
|
||
这表示已执行并通过选定 XYZAC 案例的 WASM/Worker 控制闭环,但不宣称整个 LinuxCNC 或所有 AXIS 配置已经数值完全对标。
|
||
本项目铁律:所有 G-code、运动、门控、I/O、HAL、刀具和状态业务不得由 JavaScript 模拟;React/Three 只做用户输入与显示投影。
|
||
|
||
## 对标输入
|
||
|
||
| 作用 | LinuxCNC 原始输入 | Web/WASM 输入 |
|
||
| --- | --- | --- |
|
||
| AXIS 菜单、快捷键、状态轮询 | `linuxcnc/src/emc/usr_intf/axis/scripts/axis.py`、`linuxcnc/share/axis/tcl/axis.tcl` | `web/react/src/App.tsx`、`web/app/axis-contract.mjs` |
|
||
| 程序/暂停/恢复/停止 | `axis.py:task_run/task_step/task_pause/task_resume/task_stop` | `PROGRAM_RUN/STEP/PAUSE/RESUME/ABORT` -> `SimTask` + LinuxCNC source TP |
|
||
| JOG/HOME | `axis.py:jog_on/jog_off/home_all_joints/home_joint` | `JOG_START/JOG_STOP/HOME` -> `WasmLinuxcncTp/WasmHomeLimit` |
|
||
| MDI/Touch Off | `axis.py:send_mdi_command/touch_off_system/touch_off_tool` | `MDI_EXECUTE` -> `linuxcnc-wasm-sim_program` |
|
||
| Feed/rapid/spindle override | `axis.py:set_feedrate/set_rapidrate/set_spindlerate` | `SET_OVERRIDE` -> WASM TP/IO |
|
||
| 主轴、刹车、冷却、刀具、探针 | `axis.py:spindle/brake/mist/flood/change_tool` | `SPINDLE_COMMAND/SPINDLE_BRAKE/COOLANT_COMMAND/TOOL_*/PROBE_CONFIG` -> WASM IO |
|
||
| 预览、实时轨迹、清屏 | `linuxcnc/lib/python/rs274/glcanon.py` | `XyzacToolPreview`,只投影 WASM preview/motion trace |
|
||
| XYZAC M428/M429/M430 | `switchkins_postgui.hal`、`remap_subs/428remap.ngc` 等 | `KINEMATICS_SELECT` -> WASM kinematics/switchkins |
|
||
|
||
源码输入哈希:
|
||
|
||
```text
|
||
axis.py 328c038a1e8fefd952e53c8e398e3fa98b04602351c44318edd1b044e8f63ffa
|
||
glcanon.py 0dfb20f1fdc05289894f3aa638357d98e1063fbd53329c723c777399ec7b33b7
|
||
xyzac-trt.ini f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811
|
||
source slices c9f0b4dc686717b37565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524
|
||
```
|
||
|
||
AXIS 源控件清单:菜单 80、工具栏 20、快捷键 10,共 110 条,来自 `web/workspace/xyzac-trt-source-slices.mjs`。
|
||
|
||
## 权威状态边界
|
||
|
||
选定 `xyzac-trt` 配置时,Worker 强制建立 LinuxCNC WASM TP,不接受缺省 planner 降级。前端只负责输入和显示投影,业务值、门控、运动和设备状态均来自以下 WASM 边界:
|
||
|
||
| 数据/动作 | 唯一来源 | 前端使用方式 |
|
||
| --- | --- | --- |
|
||
| G-code 解析、当前行、活动段、预览 | `WasmProgramRuntime` (`linuxcnc-wasm-sim_program`) | 显示源代码和路径,不在 React 重解析 |
|
||
| XYZAC 位姿、速度、队列、前瞻 | `WasmLinuxcncTp` (`linuxcnc-source-tp`) | DRO、实时刀具、执行状态 |
|
||
| 五关节命令值 | WASM TP 当前 pose + `sim_kinematics_switch_inverse_mode` | 关节/DRO 投影;无 JS 插值 |
|
||
| JOG 目标、速度和限位 | `sim_linuxcnc_tp_jog`、WASM TP axis limits/jog scale | Worker 只传递轴、方向、步长 |
|
||
| HOME、逐关节 homed、limit | `WasmHomeLimit` (`homed_mask`) | Home 按钮和轴状态门控 |
|
||
| ESTOP、POWER、主轴、探针、HAL | `WasmXyzacIo` / `sim_io` / `sim_hal` | 设备状态、报警和命令结果 |
|
||
| Task/程序门控 | `SimTask` `sim_task_command_gate` | 所有按钮 `disabled` 和错误原因 |
|
||
| Feed/Jog/Max/Spindle override | WASM TP/IO getter/setter | 受控 slider,值由快照回读 |
|
||
| 视图缩放、旋转、平移、tab | React/Three 本地 UI | 仅显示交互,不参与运动计算 |
|
||
|
||
实时参数区显示:主轴实际转速 `speed_rpm`、主轴指令转速 `command_rpm`、G-code `S` 值、TP 实际进给 `velocity_mm_min`、G-code `F` 值、TP 速度/上限、F/S override、队列深度、活动段和当前执行行。所有值来自 WASM program/TP/IO 快照,参数区的 `data-xyzac-parameter-source` 为 `linuxcnc-wasm`;未取得快照时显示 `-`。
|
||
|
||
程序预览替换规则:`PROGRAM_LOAD` 开始时先清空旧的 canonical preview;如果 WASM 解析或子程序加载失败,错误响应中的路径仍为空,不会把旧程序刀路重新投影出来。新的 WASM preview 成功后才替换为新程序路径。
|
||
|
||
在 WASM 快照尚未到达前,界面显示 `WASM PENDING` 并禁用运动操作;不会使用 JS 默认轴值、任务状态或 override 值。浏览器定时器只发送 `SIM_STEP` 采样请求,不执行 G-code、轨迹、运动学或设备状态计算。React/Three 中的定时器、相机、网格、刀具网格和文本格式化均为显示层,不产生或修改任何 CNC 状态。
|
||
|
||
## 按钮/控件矩阵
|
||
|
||
下表中的“通过”包含正常路径和刻意触发的 LinuxCNC 门控拒绝;拒绝不是失败,必须返回可解释的 gate/error key。
|
||
|
||
| 面板区域 | Web 控件 | LinuxCNC 命令/源函数 | WASM 权威输出 | 结果 |
|
||
| --- | --- | --- | --- | --- |
|
||
| 会话 | HELLO、SESSION_ATTACH | AXIS 启动/状态轮询 | `sim_protocol`、`SimTask` | 通过 |
|
||
| Machine | Emergency Stop、Release E-stop | `General_Halt`、`emcTaskAbort` | WASM IO + Task ESTOP/RESET | 通过 |
|
||
| Machine | Power On/Off | `commands.power`、`emcTaskSetState` | `sim_io_set_power` | 通过 |
|
||
| Machine | Reset | `commands.reset` | WASM Task/IO reset | 通过 |
|
||
| Machine | HOME ALL | `home_all_joints` | `WasmHomeLimit` 五关节回零 | 通过 |
|
||
| Machine | Home X/Y/Z/A/C | `home_joint` | `WasmHomeLimit.homed_mask` 逐关节回零 | 通过 |
|
||
| Machine | Run Startup Sequence | release -> power -> home -> run | Worker 固定顺序 | 通过 |
|
||
| Program | Load | `open_file_guts` | WASM interpreter preview | 通过 |
|
||
| Program | Run | `task_run` / `AUTO_RUN` | WASM program + source TP | 通过 |
|
||
| Program | Pause / Resume | `task_pause` / `task_resume` | WASM interpreter + TP pause/resume | 通过 |
|
||
| Program | Stop | `task_stop` / `c.abort` | WASM TP abort,队列清零 | 通过 |
|
||
| Program | Restart | `reload_file` / first line | WASM program reload | 通过 |
|
||
| Program | Step / Seek | `task_step` / `set_first_line` | WASM interpreter | 通过 |
|
||
| JOG | X、Y、Z、A、C +/-、Stop | `jog_plus/jog_minus/jog_on/jog_off` | WASM source TP jog velocity/queue | 通过 |
|
||
| JOG | 越界/非有限速度 | LinuxCNC motion limit/ferror | WASM 错误 key | 通过拒绝 |
|
||
| MDI | Go、历史命令 | `send_mdi_command` | WASM interpreter/canonical | 通过 |
|
||
| MDI | 运行中 MDI | `manual_ok` | `mdi_while_program_active` | 通过拒绝 |
|
||
| Override | Feed Override 50%/200% | `set_feedrate` | WASM TP feed override | 通过 |
|
||
| Override | Feed > 200% | `set_feedrate` range | `motion_override_range` | 通过拒绝 |
|
||
| Spindle | CW/CCW/Stop | `spindle_forward_toggle/spindle` | WASM spindle command | 通过 |
|
||
| Spindle | +/- | `SPINDLE_INCREASE/DECREASE` | WASM signed delta | 通过 |
|
||
| Spindle | Brake | `EMC_SPINDLE_BRAKE_ENGAGE/RELEASE` | WASM IO brake state | 通过 |
|
||
| Coolant | Mist/Flood | `mist_toggle/flood_toggle` | WASM device IO | 通过 |
|
||
| Tool | Prepare、Prepared、Change、Changed | iocontrol/tool handler | WASM IO tool state | 通过 |
|
||
| Probe | Arm、Disarm、Trip | probe canonical/HAL | WASM IO + HAL | 通过 |
|
||
| Switchkins | Identity/M429、TCP: XYZAC/M428、User K/M430 | `switchkins_postgui.hal` + remap files | WASM kinematics `active_type` | 通过 |
|
||
| Switchkins | IDENTITY <-> TCP: XYZAC <-> USERK 任意切换 | `KINEMATICS_SELECT` / `M429` / `M428` / `M430` | 当前 WASM TP pose + WASM inverse/forward | 通过 |
|
||
| Preview | Preview、DRO、路径/实时/限位/速度/偏置/范围 | `glcanon.py` draw layers | WASM pose/joints/toolpath | 通过投影 |
|
||
| Preview | 缩放、平移、旋转、原点坐标系 | AXIS view handlers | React/Three display-only state | 通过显示 |
|
||
| Diagnostics | 状态、门控、错误、恢复 | AXIS status/error channel | Worker snapshot/ledger | 通过 |
|
||
|
||
## 本轮自动化结果
|
||
|
||
聚合用例:`web/worker/test_xyzac_panel_buttons.mjs`
|
||
|
||
```json
|
||
{
|
||
"schema": "xyzac-panel-button-parity.v1",
|
||
"source": "linuxcnc-wasm-worker",
|
||
"verified_paths": 97,
|
||
"expected_error_paths": 8,
|
||
"blocked_by_abi_paths": 4,
|
||
"selected_case_release_status": "STOP_RELEASE"
|
||
}
|
||
```
|
||
|
||
97 条通过路径包括:
|
||
|
||
- Machine:HELLO、SESSION_ATTACH、LOAD_WORKSPACE、ESTOP、ESTOP_RESET、POWER、RESET、HOME ALL、启动序列;
|
||
- Machine:五个轴的独立 HOME、`homed_mask` 聚合和部分回零门控;
|
||
- Program:LOAD、RUN、SIM_STEP、PAUSE、SNAPSHOT、RESUME、ABORT/STOP、RESTART、STEP、SEEK、按行恢复;
|
||
- JOG:XYZAC 五轴启动、固定 tick 采样和停止;
|
||
- MDI:正常 G-code、运行中门控和非法 G-code 错误回显;
|
||
- Feed Override:50%、200% 和 201% 拒绝;
|
||
- 主轴:CW、signed increase/decrease、Stop、Brake engage/release;
|
||
- Coolant、Tool prepare/change ack、Probe arm/disarm、ESTOP recovery;
|
||
- M428/M429/M430、VISUAL_CLEAR 和诊断快照。
|
||
- Switchkins 直接按钮在非零姿态下 `0 -> 1 -> 2 -> 0 -> 1 -> 2 -> 0` 循环切换;每一步的 kinematics pose 与 TP pose 逐轴一致。
|
||
|
||
8 条错误路径是刻意验证的拒绝:OFF 状态 Run/HOME/JOG/MDI/M428、Feed 201%、非法 MDI、运行中 MDI。它们均返回 LinuxCNC/WASM 可读原因,没有把拒绝当成成功。
|
||
|
||
3D_Chips 长程序补充验证:
|
||
|
||
```text
|
||
source_length: 200509
|
||
line_count: 4711
|
||
preview_segments: 4684
|
||
fixed_tick_samples: 3000
|
||
execution_line: 337
|
||
execution_trace_entries: 335
|
||
motion_authority: wasm
|
||
motion_delta_snapshots: 0
|
||
ledger_audit_window: 32
|
||
running_queue_gaps: 0 (excluding the initial startup tick)
|
||
```
|
||
|
||
## 长距离连续性判定
|
||
|
||
`3D_Chips.ngc` 第 17 行设置 `G64 P.1`,后续是大量连续短段。对标 LinuxCNC source TP 时,正常表现是 TP 在当前段运行期间持续保留前瞻队列;G64 不应在普通同模式段之间出现人为的零速度空队列 tick。此前 Worker 在等待当前段完全结束后才入队下一段,造成截图中可见的短暂停顿,这不是源 LinuxCNC 的合理结果。
|
||
|
||
已修复为:同一运动学模式的下一段可在当前 TC 活动时进入 source TP;M428/M429/M430 模式变化仍由 WASM Task/TP 同步边界约束;队列容量由 `sim_linuxcnc_tp_queue_capacity` 读取,按真实 `TP_DEFAULT_QUEUE_SIZE` 限流。1000 tick 连续性回归中,除启动第 1 tick 外 `program_status=running && queue_depth=0` 的次数为 `0`;第 82 行附近仍保持 31 段前瞻队列。
|
||
|
||
## 当前未闭合项
|
||
|
||
以下项目仍明确记录为 `blocked_by_abi`,没有伪造通过:
|
||
|
||
1. `Override Limits`:原始 AXIS `toggle_override_limits` 有独立 motion command;选定 XYZAC WASM 配置目前把 limits 作为配置所有权,尚无等价 command ABI。
|
||
2. `Block delete` 和 `Optional pause`:当前 AXIS 图标已禁用,尚未写入 WASM interpreter modal/control state;不保留本地假状态。
|
||
3. `Tool Touch Off`:当前按钮发送固定 `G43`;原始 AXIS 先取得用户值,再发送 `G10 L10/L11` 和 `G43`,交互输入流程尚未闭合。
|
||
4. `Edit tool data`、`Quit`:依赖桌面进程/外部编辑器,属于浏览器 `HOST_BOUNDARY`,不在仿真 Web 范围内。
|
||
|
||
## 复现命令
|
||
|
||
```bash
|
||
scripts/build-wasm.sh
|
||
npm run build --prefix web/react
|
||
node --experimental-strip-types web/worker/test_xyzac_panel_buttons.mjs
|
||
node --experimental-strip-types web/worker/test_xyzac_trt_case.mjs
|
||
node --experimental-strip-types web/worker/test_xyzac_button_constraints.mjs
|
||
node --experimental-strip-types web/worker/test_xyzac_workflow.mjs
|
||
node --experimental-strip-types web/worker/test_xyzac_manual_control.mjs
|
||
node --experimental-strip-types web/worker/test_xyzac_feed_override.mjs
|
||
node --experimental-strip-types web/worker/test_xyzac_trt_io_authority.mjs
|
||
node --experimental-strip-types web/worker/test_xyzac_3d_chips.mjs
|
||
bash -n run-5axis-rtcp.sh
|
||
```
|
||
|
||
本轮结果:WASM 构建通过,原生 CTest 22/22 通过,XYZAC 聚合按钮测试通过,3D_Chips 固定 tick 长程序测试通过。Jog Speed、Max Velocity、Spindle Override 已改为 WASM TP/IO 状态和命令;前端运行态不再使用 React 默认值。发布站点 UI 运行/暂停/恢复/停止也已在 Chromium 仿真环境执行;Safari 和真实物理断电不属于本项目范围。
|
||
|
||
本轮连续性修复后,`3D_Chips.ngc` 3000 tick 执行到第 337 行,`running_queue_gaps=0`;这证明长距离运行中的中间停顿已不再由 Worker 队列饥饿制造。
|
||
|
||
暂停/恢复修复:暂停期间若有一个 `SIM_STEP` 已在浏览器与 Worker 之间传输,WASM protocol 现在接受该帧为稳定无动作轮询,不会消耗错误序号;随后 `PROGRAM_RESUME` 正常恢复 source TP。
|
||
|
||
发布站点 r11 暂停/恢复验证:
|
||
|
||
```text
|
||
url: https://49.232.250.35:58010/
|
||
release: 20260902-linuxcnc-wasm-pause-resume-r11
|
||
resource_sha256: index-EXbw4yiL.js 6759738df285bc5e2f5c3fb84043dc09fb82292bbc1c3c1011a558c8654c96ab
|
||
sim-worker-entry-DjXIMZ0D.js 190515af943d70e93037e88a5cf63b3b8e9cda675a8338cfc1fb4bb954bfd685
|
||
linuxcnc-sim-core-D3Qw0e1g.wasm f1b1961279cf8ff7ef2e3fcd0068b3ba79de57abe1e56d5c32b16d17568b9536
|
||
before_pause: line=62, tick=140, queue_depth=1, velocity=28.2842712475
|
||
paused: line=62, tick=145, queue_depth=1, velocity=28.2842712475
|
||
paused_after_1.5s: tick=145 (stable)
|
||
resumed: line=62, tick=160, queue_depth=1, velocity=4.96408252063
|
||
after_resume: line=68, tick=360, queue_depth=2, velocity=32.8295260060
|
||
PROGRAM_RESUME: acknowledged; browser_errors: 0
|
||
screenshot: /tmp/published-pause-resume-final-r11c.png
|
||
screenshot_sha256: 9d1660fd043dd0628ff2989a3e139a3239acd6386d141657a5834c9d2f1bc5a7
|
||
```
|
||
|
||
发布站点 r13 实时参数验证:
|
||
|
||
```text
|
||
url: https://49.232.250.35:58010/
|
||
release: 20260902-linuxcnc-wasm-live-parameters-r13
|
||
parameter_source: linuxcnc-wasm
|
||
idle: Spindle 0.0 rpm / Feed actual 0.0 mm/min / TP velocity 0.000 mm/s / Planner 0 queued
|
||
running: Feed actual 540.0 mm/min / TP velocity 9.000 mm/s / Planner 1 queued / Segment 13 / Line 65
|
||
fields: spindle actual+command+program S, feed actual+program F, TP velocity+limit,
|
||
F/S override, queue depth, active segment, execution line
|
||
browser_errors: 0
|
||
screenshot: /tmp/published-live-parameters-r13.png
|
||
screenshot_sha256: 4e25750136d9b5a8ed633a15091128a94fc9bbec9af857c71d9bf5dd01270fb6
|
||
```
|
||
|
||
发布站点 r14(程序主轴同步 + 实时参数)验证:
|
||
|
||
```text
|
||
url: https://49.232.250.35:58010/
|
||
release: 20260902-linuxcnc-wasm-live-parameters-r14
|
||
resource_sha256: index-CDC5yZJC.js c3a6aa009e091d5fcb2098c7254313d987229abc1e4765052edb15b465ca0fc4
|
||
sim-worker-entry-BQKHHWpv.js e72d80d9ae0fd679d92d3efbad4dba1eef55f9ce7b54bcd06e4a0d644c3cfb1a
|
||
linuxcnc-sim-core-fuIvKetC.wasm ad4e17ecbf73afbad0d9f069ab20ba3c66b6cc4d75ecdb2b3182673490ee916d
|
||
3D_Chips.ngc running: spindle_actual=210 rpm, spindle_command=1600 rpm, program_S=1600 rpm,
|
||
feed_actual=1200 mm/min, program_F=2250000 mm/min,
|
||
tp_velocity=20 mm/s, queue_depth=22, active_segment=21, line=38
|
||
browser_errors: 0
|
||
screenshot: /tmp/published-live-parameters-r14.png
|
||
screenshot_sha256: 7f5307c913d8bc4e60c2a31c29aacc9afd1b0d91fac4a4f22e8a64fc2ea37a1e
|
||
```
|
||
|
||
发布站点 r15(程序预览原子替换)验证:
|
||
|
||
```text
|
||
url: https://49.232.250.35:58010/
|
||
release: 20260902-linuxcnc-wasm-program-replace-r15
|
||
initial preview: 29 segments
|
||
invalid PROGRAM_LOAD: preview 0 segments, error shown, old path not retained
|
||
valid PROGRAM_LOAD: preview 1 new segment
|
||
browser_errors: 0
|
||
screenshot: /tmp/published-program-replace-r15.png
|
||
screenshot_sha256: c3e0a5b992381e7b6cb26f98a30338935df5239c875755727fc678911452ac24
|
||
resource_sha256: index-DUB3ldSh.js 4d71a2eb0b162608d7a47b63274cf274a57b1c2f2620b69af139b12c2ba22cce
|
||
sim-worker-entry-yfjiq6MN.js a0cf75522ddc9c6712126de86937ec89f24574bf0e0dad3dbddc6d807fb352b7
|
||
linuxcnc-sim-core-fuIvKetC.wasm ad4e17ecbf73afbad0d9f069ab20ba3c66b6cc4d75ecdb2b3182673490ee916d
|
||
```
|
||
|
||
发布站点 r10 连续性验证:
|
||
|
||
```text
|
||
url: https://49.232.250.35:58010/
|
||
release: 20260902-linuxcnc-wasm-continuous-r10
|
||
resource_sha256: index-Byst0JhC.js 26d3f21f496c8223218761ba641dab8b4f36fd18892f260c7bf5b5cfa83cafec
|
||
sim-worker-entry-BTVfbu6g.js adf2ac5621ba388408f31ceab4bbcbfa6ba2923577d8eb69aa79ea54f3be0134
|
||
linuxcnc-sim-core-B2786u4k.wasm 3163f5ff63c5f3e1d2c07d1d948fce328bf3ad919eee188e432f7ba57468fc71
|
||
3D_Chips.ngc: loaded -> POWER -> HOME ALL -> RUNNING
|
||
sampled_running_frames: 33
|
||
queue_gaps: 0
|
||
first_running: current_line=62, queue_depth=3, velocity=20, active_id=16
|
||
last_running: current_line=69, queue_depth=2, velocity=16.6666666667, active_id=17
|
||
browser_errors: 0
|
||
screenshot: /tmp/published-r10-continuous.png
|
||
screenshot_sha256: c93fd23e648e49bfa9359af245372f03f3fccee123497909f3dcc005f5a59749
|
||
```
|
||
|
||
发布站点 r5 浏览器冒烟:
|
||
|
||
```text
|
||
url: https://49.232.250.35:58010/
|
||
result: verified
|
||
startup -> pause -> resume -> stop: verified
|
||
pause_tick: 140 (position held while PAUSED)
|
||
resume_tick: 160 -> continued running
|
||
stop: IDLE / queue cleared
|
||
JOG X/Y/Z/A/C, spindle CW/CCW/+/-/brake, coolant, tool/probe,
|
||
Feed Override, M428/M429/M430, VISUAL_CLEAR, Preview/DRO/MDI/Diagnostics
|
||
and view controls: clicked with no browser errors
|
||
output_sha256: bdf705473e6cda94d721aa23329257adf4a68b705add7650da5cc47012ab70b0
|
||
```
|
||
|
||
发布站点 r6(历史 WASM authority 版本)浏览器验收:
|
||
|
||
```text
|
||
url: https://49.232.250.35:58010/
|
||
release: 20260902-linuxcnc-wasm-authority-r6
|
||
resource_sha256: index-DEinWp01.js 79f5e933909fc631186db9b5091b6239f30c1ade612bb908a4ab9fcf79965343
|
||
sim-worker-entry-7q53Ew6x.js e5c239104d6676f242ea45cb3ddaf78a379aaaecaca5ff26031dee1ba9496e7c
|
||
linuxcnc-sim-core-CJilJ2YZ.wasm 13e2746899b0cac5cf91189c00a6174160202f8e632b53c5701e9664335c97cf
|
||
initial_dom: data-axis-authority=linuxcnc-wasm-worker, data-axis-state-source=linuxcnc-wasm,
|
||
data-axis-motion-authority=wasm, data-axis-task-authority=wasm_task_canonical
|
||
3D_Chips.ngc: loaded from published workspace, preview 100%, source TP running current line 22
|
||
browser_errors: 0
|
||
screenshots: /tmp/published-r6-authority.png (e58205228a04b386c7b7514bf03c71df7b53f66f2d9ebe2292931b36ef0edb55)
|
||
/tmp/published-r6-running.png (7fc474d0cb31a0fdd4afb198061e9812c753684e3d2963cc004ec4483c5c4990)
|
||
```
|
||
|
||
当前发布资源为 r10;r6 资源 hash 仅作为历史记录保留。
|
||
|
||
发布站点 r7(IDENTITY/TCP: XYZAC/USERK 切换版本)浏览器验收:
|
||
|
||
```text
|
||
url: https://49.232.250.35:58010/
|
||
release: 20260902-linuxcnc-wasm-switchkins-r7
|
||
startup: WASM authority ready, initial machine OFF
|
||
power -> HOME ALL -> IDENTITY -> TCP: XYZAC -> USERK -> IDENTITY -> TCP: XYZAC -> USERK: verified
|
||
active modes: 0 -> 1 -> 2 -> 0 -> 1 -> 2
|
||
browser_errors: 0
|
||
screenshot: /tmp/published-switchkins-r7.png
|
||
screenshot_sha256: 920b85ad7fd6451dfb134255ffdcc4f03a7aa615ebf486c63cde8582e17af195
|
||
```
|
||
|
||
## 证据哈希
|
||
|
||
```text
|
||
panel_button_test_output 9bddcd8b0219925e00598e081dc7a4ed0f4868e8822a21f0ccd08d8e9d355d45
|
||
button_constraints_output 5b6f4ce1dec03764dcb234793ff96fc2f04d15ab954620a44dbb1210ec64a5a5
|
||
feed_authority_output deab4a51ee0e56d4f8134efba4b7a97a2b88f37d9165cf730207f71886df8526
|
||
3d_chips_test_output c97caef2ea5cf3841e1238ec443d0eebadad8cb0048af829111c06e99c9fcdd7
|
||
3d_chips_no_gap_output c97b5fbb43a6e81a8ee15272bf71aa75ec0ba79be28a34f30b4221d50251c77d
|
||
wasm_io_source 1cb066d185dd2c5bbf435e022c2518483bd44962e5a0303248757b2da51740f7
|
||
wasm_io_c_source 09bce1430d6f71702ca0b3bf29ac50db377a6f232ce0d1a9b2c1eaac7ea2162e
|
||
panel_button_test_source 80782fc1f85f88beb48ec3dfaf638a93f2edb912e694840199dbff504477fe74
|
||
switchkins_direct_test_output 24e6cb8ec1195a97f71294b49217db0cbc0d7c3ecfa4bc8aa244ba3921c816a7
|
||
panel_r10_output 9bddcd8b0219925e00598e081dc7a4ed0f4868e8822a21f0ccd08d8e9d355d45
|
||
pause_resume_browser_screenshot 9d1660fd043dd0628ff2989a3e139a3239acd6386d141657a5834c9d2f1bc5a7
|
||
live_parameters_browser_screenshot 7f5307c913d8bc4e60c2a31c29aacc9afd1b0d91fac4a4f22e8a64fc2ea37a1e
|
||
program_replace_browser_screenshot c3e0a5b992381e7b6cb26f98a30338935df5239c875755727fc678911452ac24
|
||
```
|
||
|
||
报告对应提交前工作树保留了既有 coverage 大文件和 LinuxCNC 子模块改动;本轮提交包含 WASM TP/IO/HOME authority、无 JS JOG 运动计算、前端 pending 投影、长程序快照性能修正、聚合测试和本报告。
|
||
|
||
## AXIS 源码逐项映射与发布站点审计
|
||
|
||
本轮按 `linuxcnc/src/emc/usr_intf/axis/scripts/axis.py` 对照了 `manual_ok()`、`ensure_mode()`、`open_file_guts()`、`task_run/task_pause/task_resume/task_stop/task_step`、`jog_on/jog_off_actual`、`mist_toggle/flood_toggle`、`spindle_*`、`change_tool` 和 MDI 入口。映射约束与禁止事项见 [`LinuxCNC AXIS Web 铁律`](../docs/linuxcnc-axis-web-iron-law.md)。
|
||
|
||
发现并修复的实际偏差:
|
||
|
||
- 手动/MDI 页签现在通过 WASM `SET_MODE` 同步 LinuxCNC task mode;之前仅切 React 页签会使 JOG、主轴和 MDI 被错误地显示为不可用。
|
||
- React 现在保留 `panel_snapshot.io` 的 WASM canonical envelope,正确读取 `state.ready/estop` 和设备状态。
|
||
- `JOG_STOP` 对 LinuxCNC source TP 只停止当前 jog 并保持 TP runnable;不再伪造 `AUTO_PAUSE`,避免后续 MDI/主轴操作得到 `linuxcnc_tp_paused` 调度错误。
|
||
- MDI 在前一次 JOG_STOP 后明确恢复 WASM TP runnable,再由 WASM 解释器/队列执行 MDI block。
|
||
- 工具栏 Reset 和 Reopen defaults 均走 WASM gate;Reopen 执行 `LOAD_WORKSPACE + PROGRAM_LOAD`,不再只修改本地编辑器字符串。
|
||
|
||
发布地址 `https://49.232.250.35:58010/` 的 Chromium 审计命令:
|
||
|
||
```text
|
||
PLAYWRIGHT_MODULE=... node scripts/test_xyzac_panel_buttons_browser.mjs
|
||
```
|
||
|
||
审计覆盖:WASM startup、Open G-code file、`3D_Chips.ngc`、Load case、POWER ON、HOME ALL、RESET、IDENTITY/TCP:XYZAC/USERK、视图和 Clear plot、MANUAL/MDI、XYZAC 五轴 JOG、主轴正反转/停止/刹车、Mist/Flood、Tool/Probe、Jog/Feed/Spindle/Max velocity overrides、MDI、Run/Pause/Resume/Abort/Step、Run Startup Sequence、编辑器 Load/Reopen 和 ABI-disabled 控件。发布版本 `20260902-linuxcnc-wasm-panel-audit-r27` 最终结果为 20 组 verified、83 个按钮、37 个按 LinuxCNC gate 禁用、`browser_errors=0`;WASM worker authority 标记为 `linuxcnc-wasm-worker` / `wasm_task_canonical`,截图 `/tmp/xyzac-panel-buttons-browser.png`,SHA-256 `dbf6d196cec3fe765a64d5a1d194b7ebb5681a30555f238e084c9ad6deac6032`。
|
||
|
||
源代码对标结论:AXIS 的可执行操作均通过对应 WASM command/result 和后续 snapshot;`Override Limits`、Block delete/Optional pause、完整 Tool Touch Off/G10 交互以及桌面 tool editor/Quit 仍明确记录为 `blocked_by_abi` 或浏览器宿主边界,不能用 JavaScript 模拟。整体 `release_status` 继续保持 `STOP_RELEASE`,因为本报告不替代完整 TP 数值 oracle。
|
||
|
||
## OPFS 页面临时缓存
|
||
|
||
页面上下文和断电 checkpoint 由 Dedicated Worker 的 OPFS 临时 JSON 服务保存,React 不直接访问 OPFS 或 `localStorage`。`UI_STATE_SAVE/LOAD/CLEAR` 是 Worker storage service,不进入 LinuxCNC WASM CNC protocol sequence;缓存中的程序文本恢复时必须再次经过 WASM `PROGRAM_LOAD`。
|
||
|
||
```text
|
||
node web/worker/test_opfs_ui_state.mjs
|
||
node web/worker/test_opfs_worker_bridge.mjs
|
||
status: verified
|
||
double_slot / generation / TTL / hash / corruption fallback: verified
|
||
power_off_checkpoint OPFS round-trip: verified
|
||
UI cache does not consume WASM sequence: verified
|
||
```
|
||
|
||
详细字段、文件布局、原子写入和恢复边界见 [`AXIS Web/WASM OPFS 页面临时缓存设计`](../docs/linuxcnc-axis-web-wasm-opfs-ui-cache.md)。
|
||
|
||
发布版本 `20260903-linuxcnc-wasm-opfs-r30` 的真实 Chromium OPFS 往返:改变 Preview 视角为 `z`、切换 DRO、选择 A 轴,等待 1.8 秒防抖保存后刷新页面;刷新后 `view=z`、DRO 仍激活、A 轴仍选中,OPFS 中实际存在 `state-b.json` 和 `manifest.json`,两次 `localStorage` key 数均为 `0`,`browser_errors=0`。截图 `/tmp/xyzac-opfs-browser.png`。
|
||
|
||
## 实时轨迹程序替换验证
|
||
|
||
发布版本 `20260903-linuxcnc-wasm-live-replace-r32` 执行了真实浏览器流程:第一程序运行完成并产生 5 个 live trace 点,随后加载第二个程序。第二程序加载完成后 WASM preview 为 1 段、live trace 为 0,旧程序实时轨迹不再保留,`browser_errors=0`。截图 `/tmp/xyzac-live-trace-replacement.png`,SHA-256 `4bdf642d3e51cffae8afadb881422d58408d3f095aa795566d045a35d2c05482`。
|