Complete XYZAC LinuxCNC WASM parity and smooth 3D preview
This commit is contained in:
BIN
doc-rtcp/5axis-rtcp-running.png
Normal file
BIN
doc-rtcp/5axis-rtcp-running.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 186 KiB |
62
doc-rtcp/5axis-rtcp-shortcut.md
Normal file
62
doc-rtcp/5axis-rtcp-shortcut.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# 五轴 RTCP 案例快捷方式
|
||||
|
||||
快捷方式:[`../run-5axis-rtcp.sh`](../run-5axis-rtcp.sh)
|
||||
|
||||
默认执行:
|
||||
|
||||
```bash
|
||||
./run-5axis-rtcp.sh
|
||||
```
|
||||
|
||||
默认案例是:
|
||||
|
||||
```text
|
||||
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini
|
||||
```
|
||||
|
||||
它使用 `XYZAC` 五轴表旋转/倾斜(TRT)拓扑、`xyzac-trt-kins` 和 Vismach `xyzac-trt-gui`。默认演示程序是:
|
||||
|
||||
```text
|
||||
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc
|
||||
```
|
||||
|
||||
该顶层演示调用 `remap_subs/xyzac_switchkins_sub.ngc`;其螺旋插补子程序 `remap_subs/helix_ac.ngc` 使用:
|
||||
|
||||
```gcode
|
||||
M428 ;TCP:xyzac
|
||||
```
|
||||
|
||||
`M428` 通过 remap 将 `motion.switchkins-type` 切换到 XYZAC TCP/RTCP 运动学;`helix_ac.ngc` 在需要机床坐标定位时使用 `M429` 切回 identity,再用 `M428` 进入 TCP。配置的 `M430` 进入 userk。AXIS 右侧的 `TCP:XYZAC` 按钮也提供同一切换入口。
|
||||
|
||||
## XYZBC 变体
|
||||
|
||||
快捷方式接受可选配置名:
|
||||
|
||||
```bash
|
||||
./run-5axis-rtcp.sh xyzbc-trt.ini
|
||||
```
|
||||
|
||||
该变体使用 `XYZBC` 和 `xyzbc-trt-kins`,默认程序为 `demos/xyzbc_switchkins.ngc`。
|
||||
|
||||
## 启动证据
|
||||
|
||||

|
||||
|
||||
实测启动结果:
|
||||
|
||||
- AXIS 标题:`xyzac_switchkins.ngc - AXIS 2.10.0~pre1 on sim-xyzac-trt-kins (switchkins)`。
|
||||
- 右侧 `SWITCHKINS` 面板显示 `TCP:XYZAC`。
|
||||
- Vismach 预览显示五轴机床和多轴刀具轨迹。
|
||||
- LinuxCNC 状态接口返回 `file=./demos/xyzac_switchkins.ngc`,`COORDINATES=XYZAC`。
|
||||
- 当前环境使用 POSIX non-realtime 回退;这验证的是仿真配置和 RTCP 路径,不是实时硬件性能。
|
||||
|
||||
## 来源依据
|
||||
|
||||
- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini`
|
||||
- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc`
|
||||
- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzac_switchkins_sub.ngc`
|
||||
- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_ac.ngc`
|
||||
- `linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc`
|
||||
- `linuxcnc/src/emc/kinematics/xyzac-trt-kins.c`
|
||||
- `linuxcnc/src/emc/kinematics/trtfuncs.c`
|
||||
- `linuxcnc/docs/src/motion/5-axis-kinematics.adoc`
|
||||
51
doc-rtcp/README.md
Normal file
51
doc-rtcp/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# 五轴 RTCP 文档集
|
||||
|
||||
接续入口:[`../nextTask-rtcp.md`](../nextTask-rtcp.md)
|
||||
|
||||
持续执行提示词:[`xyzac-trt-autonomous-execution-prompt.md`](xyzac-trt-autonomous-execution-prompt.md)
|
||||
|
||||
本目录从 `doc-g` 集中迁移五轴机床、XYZAC/XYZBC TRT、switchkins、RTCP 和控制面板数据流资料。原 `doc-g` 文件保留不变;本目录是后续五轴案例分析的独立入口。
|
||||
|
||||
## 快速入口
|
||||
|
||||
- [五轴 RTCP 快捷方式](5axis-rtcp-shortcut.md)
|
||||
- [控制面板功能、数据流与控制流](gmoccapy-control-panel-data-control-flow.md)
|
||||
- [`xyzac-trt.ini` 控制面板与 Web/WASM 设计基础](xyzac-trt-control-panel-web-wasm-design.md)
|
||||
- [`xyzac-trt.ini` Web/WASM 实施计划与里程碑](xyzac-trt-web-wasm-implementation-plan.md)
|
||||
- [`xyzac-trt.ini` 源码对标与 WASM 唯一权威合同](xyzac-trt-web-wasm-source-parity-contract.md)
|
||||
- [GMOCCAPY 运行时和面板分析](gmoccapy-analysis.md)
|
||||
- [五轴 RTCP 运行截图](5axis-rtcp-running.png)
|
||||
|
||||
## 运行
|
||||
|
||||
```bash
|
||||
./run-5axis-rtcp.sh
|
||||
./run-5axis-rtcp.sh xyzbc-trt.ini
|
||||
```
|
||||
|
||||
快捷方式仍位于仓库根目录;文档中的 `../run-5axis-rtcp.sh` 链接指向同一入口。
|
||||
|
||||
默认案例:
|
||||
|
||||
```text
|
||||
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini
|
||||
```
|
||||
|
||||
## 文档边界
|
||||
|
||||
- `5axis-rtcp-shortcut.md`:案例入口、XYZAC/XYZBC 变体、M428/M429 和启动证据。
|
||||
- `gmoccapy-control-panel-data-control-flow.md`:从控制面板控件到 LinuxCNC TASK/motion/HAL/Vismach 的完整数据流和控制流,其中第 8 节是五轴 RTCP 专章。
|
||||
- `gmoccapy-analysis.md`:GMOCCAPY 系统运行时版本、启动提示和面板行为;作为五轴界面分析的背景材料。
|
||||
- `gmoccapy-file-inventory.*`:GMOCCAPY 相关配置、实现、资源和图标的逐文件清单。
|
||||
|
||||
## 来源
|
||||
|
||||
五轴核心来源保持在 LinuxCNC 源目录:
|
||||
|
||||
```text
|
||||
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/
|
||||
linuxcnc/src/emc/kinematics/xyzac-trt-kins.c
|
||||
linuxcnc/src/emc/kinematics/xyzbc-trt-kins.c
|
||||
linuxcnc/src/emc/kinematics/trtfuncs.c
|
||||
linuxcnc/docs/src/motion/5-axis-kinematics.adoc
|
||||
```
|
||||
170
doc-rtcp/gmoccapy-analysis.md
Normal file
170
doc-rtcp/gmoccapy-analysis.md
Normal file
@@ -0,0 +1,170 @@
|
||||
# GMOCCAPY 分析与加载测试
|
||||
|
||||
更新时间:2026-08-25
|
||||
|
||||
## 结论
|
||||
|
||||
“没有看到加载程序按钮”不是按钮缺失,而是首次启动提示和 GMOCCAPY 的模式门控共同造成的视觉结果:
|
||||
|
||||
1. 首次启动会弹出模态的 `Important change(s)` 窗口。该窗口覆盖主界面并阻止底层点击;用户截图中的右侧 `X` 是关闭按钮,底部复选框是 `Don't show this again`。
|
||||
2. 加载按钮只属于 AUTO 页面按钮组,不属于 MANUAL/JOG 页面。源码将它声明为 `btn_load`,提示为 `Load a new program`,图标为 `img_open`。
|
||||
3. AUTO 模式还受机器状态和 homing 门控。`gmoccapy.py` 在未满足状态时会禁用 `rbt_auto`,并提示 `It is not possible to change to Auto Mode at the moment`。
|
||||
4. 关闭首次提示、进入 AUTO 后,点击文件夹/打开文件图标会进入文件选择页。当前 `gmoccapy.ini` 的 `PROGRAM_PREFIX = ../../nc_files/` 解析到 `linuxcnc/nc_files`。
|
||||
|
||||
## 用户截图分析
|
||||
|
||||

|
||||
|
||||
用户提供的图片尺寸为 `697 x 837`,内容是 GMOCCAPY 3.5.x 的版本变更提示:
|
||||
|
||||
- LinuxCNC 2.10/GMOCCAPY 3.5.0 不再在换刀后自动保留 G43;需要通过 REMAP 实现自动重新激活。
|
||||
- 3.5.1 的工具表和偏置页默认使用计算器输入,可在设置或按钮中改变。
|
||||
- MDI 和 G-code 编辑模式新增调用计算器的按钮。
|
||||
- `release notes` 是橙色链接;右下方复选框用于永久隐藏该提示。
|
||||
|
||||
这张提示不是文件选择器,也不是加载失败信息。应先关闭它,再操作主界面。
|
||||
|
||||
### 新截图的源码逐项对照
|
||||
|
||||

|
||||
|
||||
这张截图与前一张内容一致,尺寸为 `697 x 837`,SHA-256 为 `df7322c30bcb6af131591a04b11cad24e7b6d186beaff83059fcfd8ffbae2d1b`。截图中的每一块文字都能在当前系统安装的 `/usr/bin/gmoccapy` 中找到:
|
||||
|
||||
| 截图区域 | 源码证据 | 含义 |
|
||||
|---|---|---|
|
||||
| `Important change(s)` 标题 | `/usr/bin/gmoccapy:557-560` | `_startup_message()` 建立启动提示标题;注释要求新增消息只能追加,不能删除旧消息,否则隐藏索引会错位。 |
|
||||
| 3.5.0 G43 提示 | `/usr/bin/gmoccapy:561-563` | GMOCCAPY 3.5.0 不再承诺换刀后自动保留 G43;想自动恢复必须使用 REMAP,示例在 GMOCCAPY 仿真配置中。 |
|
||||
| 3.5.1 计算器提示 | `/usr/bin/gmoccapy:564-565` | 工具表和偏置页默认启用计算器输入;设置或页面按钮可以关闭;MDI 和 G-code 编辑页也增加了计算器按钮。 |
|
||||
| `release notes` 链接 | `/usr/bin/gmoccapy:570-573` | 以 Pango markup 拼接 LinuxCNC 官方 release notes URL,并通过通知组件显示。点击它会打开文档,不会关闭提示。 |
|
||||
| `Don't show this again` | `notification.py:151-155` | `show_checkbox=True` 时创建 GTK `CheckButton`;它不是普通说明文字,而是真正影响后续启动行为的复选框。 |
|
||||
| 右侧 `X` | `notification.py:156-164` | 创建名为 `notification_close` 的 48x48 关闭按钮;点击后删除该消息,并把复选框状态发回 GMOCCAPY。 |
|
||||
|
||||
### 弹窗什么时候出现
|
||||
|
||||
系统运行时在 GUI 初始化和周期任务准备完成后,于 `/usr/bin/gmoccapy:519` 调用 `_startup_message()`。它读取偏好项 `hide_startup_messsage`(注意源码中确实有三个 `s` 的拼写):
|
||||
|
||||
```python
|
||||
hide_message = self.prefs.getpref("hide_startup_messsage", 0, int)
|
||||
if hide_message < len(messages):
|
||||
...
|
||||
self.notification.add_message(message, INFO_ICON, show_checkbox=True)
|
||||
```
|
||||
|
||||
当前消息数组有两项,因此默认值 `0` 会显示两项。关闭时如果复选框被勾选,`/usr/bin/gmoccapy:6241-6242` 将 `self.num`(当前为 `2`)写回 `hide_startup_messsage`。下次启动判断 `2 < 2` 为假,提示不再出现。普通点击 `X` 不勾选复选框时,只删除本次通知,下次仍会显示。
|
||||
|
||||
### 版本边界:截图运行时与仓库锁定源不同
|
||||
|
||||
这是本次分析中最重要的来源边界:
|
||||
|
||||
- 截图对应的实际运行程序是 `/usr/bin/gmoccapy`,其中 `_RELEASE = "3.5.2"`,并包含 `_startup_message()`、3.5.0/3.5.1 文本和隐藏偏好逻辑。
|
||||
- 仓库锁定源是 `linuxcnc/VERSION = 2.10.0~pre0`;`linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py:79` 的版本为 `3.4.3`,该文件没有 `_startup_message()` 实现,也没有截图中的 3.5.0/3.5.1 文本。
|
||||
- 本地启动日志曾显示 `LinuxCNC 2.10.0~pre1` 和 `gmoccapy 3.5.2`,与截图完全一致。因此这张截图是系统安装包的运行时证据,不应反向宣称锁定仓库 2.10.0~pre0/3.4.3 源码已经包含该功能。
|
||||
|
||||
已记录的运行时文件哈希:
|
||||
|
||||
```text
|
||||
/usr/bin/gmoccapy 11e7aee9216d24e4cc41018306f2541845bca9a9d6e16c38580f3ede9cca8d4d
|
||||
/usr/share/gmoccapy/gmoccapy.glade 5fdc1557b02a716d30414fe739614fcd7c1d14cbe2e0a4c202c567a60b460adb
|
||||
/usr/lib/python3/dist-packages/gmoccapy/notification.py
|
||||
e0317fea738745f480c79d1f690bc52e88cc7f81bb4d14fa09c8c7196afb4e2f
|
||||
```
|
||||
|
||||
### 用户应如何处理
|
||||
|
||||
1. 只想本次继续操作:点击右侧 `X`,不要勾选复选框。
|
||||
2. 不想以后重复看到:先勾选 `Don't show this again`,再点击 `X`。
|
||||
3. 想查看变更依据:点击 `release notes`,但这需要浏览器/网络或本地文档可用。
|
||||
4. 使用 G43 的程序:不要仅依赖界面自动行为;在 AUTO 程序中按机床配置和 REMAP 约定明确处理刀具长度补偿,并在正式加工前验证工具表和偏置。
|
||||
|
||||
## 实际界面证据
|
||||
|
||||
### 未加载状态
|
||||
|
||||

|
||||
|
||||
主界面顶部显示 `No Program loaded`。右侧竖向按钮中第三个为 AUTO 模式图标;在 MANUAL 页面时,AUTO 页面里的 `Load a new program` 不会显示在当前按钮组。
|
||||
|
||||
### 文件选择页
|
||||
|
||||

|
||||
|
||||
这张截图是实际运行 GMOCCAPY 后进入的文件选择页。页面显示 `gcmc_lib`、`macros`、`ngcgui_lib` 等目录以及 `3D_Chips.ngc`、`3dtest.ngc` 等程序。底部右侧绿色对勾是确认选择,右下黄色回退箭头是返回。
|
||||
|
||||
进入这张页面的完整点击链是:
|
||||
|
||||
1. 关闭首次 `Important change(s)` 模态提示。
|
||||
2. 在主界面右侧点击第三个模式图标,进入 AUTO;源码控件为 `rbt_auto`。
|
||||
3. 等待 AUTO 按钮组出现,在其中点击打开文件图标;源码控件为 `btn_load`,tooltip 为 `Load a new program`。
|
||||
4. `on_btn_load_clicked()` 将按钮页切换到文件选择页;此时才会看到本截图中的文件网格。
|
||||
5. 选中 `.ngc` 文件后点击底部绿色对勾,源码控件为 `btn_select`。
|
||||
|
||||
因此,文件网格不是主界面的固定按钮,也不是 MDI 入口;在 MANUAL/JOG 页面直接寻找它不会找到。
|
||||
|
||||
### 加载后的程序
|
||||
|
||||

|
||||
|
||||
通过 LinuxCNC 的 `command.program_open()` 加载:
|
||||
|
||||
```text
|
||||
/home/mes006/linuxcncWebWASM/linuxcnc/nc_files/3dtest.ngc
|
||||
```
|
||||
|
||||
加载成功的证据是:
|
||||
|
||||
- 顶部由 `No Program loaded` 变成完整程序路径;
|
||||
- 预览区出现 G-code 刀具轨迹;
|
||||
- `linuxcnc.stat().file` 返回上述路径;
|
||||
- `interp_state` 保持空闲,加载本身不会自动运行程序。
|
||||
|
||||
## 源码与界面映射
|
||||
|
||||
| 层 | 文件/符号 | 结论 |
|
||||
|---|---|---|
|
||||
| 主逻辑 | `linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py` | `on_btn_load_clicked()` 切到文件选择页;`on_IconFileSelection1_selected()` 调用 `hal_action_open.load_file(path)`。 |
|
||||
| 加载按钮 | `btn_load` / `img_open` | tooltip 是 `Load a new program`,只在 AUTO 按钮页 `hbtb_auto`。 |
|
||||
| 运行按钮 | `btn_run` / `img_run` | tooltip 是 `Run the loaded program`;加载后仍需手动运行。 |
|
||||
| 文件确认 | `btn_select` / `img_select` | tooltip 是 `select the highlighted file and return the path`。 |
|
||||
| 返回 | `btn_back_file_load` / `img_back_file_load` | 关闭文件选择页但不返回路径。 |
|
||||
| 文件资源 | `linuxcnc/lib/python/gladevcp/iconview.py` 及 GMOCCAPY 初始化 | 读取 `PROGRAM_PREFIX`,按配置扩展名展示文件和目录。 |
|
||||
| 首次提示 | GMOCCAPY preferences/release-notes 逻辑 | 模态提示优先于主界面,必须先关闭。 |
|
||||
|
||||
## 配置与资源分析
|
||||
|
||||
默认配置为 `linuxcnc/configs/sim/gmoccapy/gmoccapy.ini`:
|
||||
|
||||
- `[DISPLAY] DISPLAY = gmoccapy`:选择 GMOCCAPY GUI。
|
||||
- `[DISPLAY] PROGRAM_PREFIX = ../../nc_files/`:从配置目录解析到 `linuxcnc/nc_files`。
|
||||
- `[RS274NGC] PARAMETER_FILE = sim.var`:仿真参数文件。
|
||||
- `[RS274NGC] SUBROUTINE_PATH = macros`:宏和子程序搜索路径。
|
||||
- `[EMCIO] TOOL_TABLE = tool.tbl`:工具表。
|
||||
- `[HAL]` 加载 `core_sim.hal`、`spindle_sim.hal`、`simulated_home.hal`,并在 GUI 启动后加载 `gmoccapy_postgui.hal`。
|
||||
|
||||
`configs/sim/gmoccapy` 不是单一案例,而是一组配置族,包含标准三轴、四轴、XYZAB/XYZAC/XYZCW、多轴、侧面板、消息、工具传感器、用户页、等离子和车床配置。完整逐文件路径与哈希见 [文件清单](gmoccapy-file-inventory.md)。
|
||||
|
||||
## 运行环境与限制
|
||||
|
||||
- 启动入口:[`../run-gmoccapy.sh`](../run-gmoccapy.sh),默认执行 `gmoccapy.ini`。
|
||||
- 实际 GUI 进程:`/usr/bin/python3 /usr/bin/gmoccapy -ini .../gmoccapy.ini`。
|
||||
- 当前环境没有实时内核,LinuxCNC 日志明确回退到 POSIX non-realtime;这不影响本次“加载和预览”验证,但不等同于实时硬件运行验证。
|
||||
- `simulated_home.hal` 的共享 home switch 在本次手动尝试中报告 `Cannot home while shared home switch is closed j=2`,因此 AUTO 模式按钮可能保持禁用。加载程序本身仍可通过 GUI 文件页/API 验证。
|
||||
- 加载和运行是两个动作:`program_open` 只读入程序并生成预览;需要 `AUTO` 页面中的 Run 按钮或 `R` 快捷键才会执行。
|
||||
|
||||
## 推荐操作顺序
|
||||
|
||||
1. 启动 `./run-gmoccapy.sh`。
|
||||
2. 关闭首次 `Important change(s)` 提示;可勾选 `Don't show this again`。
|
||||
3. 确认急停复位、机器上电,并按配置完成 homing;否则 AUTO 可能被门控。
|
||||
4. 点击右侧 AUTO 图标,进入 AUTO 按钮页。
|
||||
5. 点击带打开文件/文件夹图标的 `Load a new program`。
|
||||
6. 选择 `linuxcnc/nc_files` 下的 `.ngc` 文件,点击底部绿色对勾。
|
||||
7. 检查顶部路径和预览轨迹,再使用 Run;不要把加载误认为已经执行。
|
||||
|
||||
## 证据文件
|
||||
|
||||
- `gmoccapy-important-changes.png`:用户原始提示截图。
|
||||
- `gmoccapy-before-load.png`:未加载程序。
|
||||
- `gmoccapy-after-popup-close.png`:关闭提示后的主界面。
|
||||
- `gmoccapy-load-file-page.png`:实际文件选择页。
|
||||
- `gmoccapy-program-loaded.png`:加载后的程序和轨迹。
|
||||
- `gmoccapy-file-inventory.json`:逐文件 SHA-256 清单。
|
||||
BIN
doc-rtcp/gmoccapy-before-load.png
Normal file
BIN
doc-rtcp/gmoccapy-before-load.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 282 KiB |
323
doc-rtcp/gmoccapy-control-panel-data-control-flow.md
Normal file
323
doc-rtcp/gmoccapy-control-panel-data-control-flow.md
Normal file
@@ -0,0 +1,323 @@
|
||||
# GMOCCAPY 控制面板功能、数据流与控制流
|
||||
|
||||
更新时间:2026-08-25
|
||||
|
||||
本文是后续分析 GMOCCAPY 控制面板的总入口。它把普通三轴 `gmoccapy.ini` 和五轴 XYZAC RTCP 案例放在同一套模型中,区分 UI 控件、GMOCCAPY Python handler、LinuxCNC command/status、TASK/motion、HAL 和 Vismach 的责任边界。
|
||||
|
||||
## 1. 范围与版本边界
|
||||
|
||||
| 项目 | 当前工作区/运行时 |
|
||||
|---|---|
|
||||
| 仓库源码 | `linuxcnc/VERSION = 2.10.0~pre0` |
|
||||
| 仓库 GMOCCAPY 源码 | `linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py`,`_RELEASE = 3.4.3` |
|
||||
| 实际系统 GUI | `/usr/bin/gmoccapy`,运行时版本 `3.5.2`,系统 LinuxCNC `2.10.0~pre1` |
|
||||
| 普通面板入口 | [`run-gmoccapy.sh`](../run-gmoccapy.sh),默认 `configs/sim/gmoccapy/gmoccapy.ini` |
|
||||
| 五轴 RTCP 入口 | [`run-5axis-rtcp.sh`](../run-5axis-rtcp.sh),默认 XYZAC TRT switchkins |
|
||||
| 发布/仿真边界 | POSIX non-realtime 仿真;不等同于实时硬件验证 |
|
||||
|
||||
截图中的 `Important change(s)` 弹窗来自系统 GMOCCAPY 3.5.2,不存在于仓库 3.4.3 源文件中;两套来源不能混为一个源码版本。详细证据见 [GMOCCAPY 分析报告](gmoccapy-analysis.md)。
|
||||
|
||||
## 2. 总体架构
|
||||
|
||||
```text
|
||||
快捷方式 / linuxcnc -r CASE.ini
|
||||
│
|
||||
▼
|
||||
LinuxCNC 启动器与 INI 解析
|
||||
│
|
||||
├── linuxcncsvr / NML 状态与命令通道
|
||||
├── milltask / RS274NGC interpreter / task mode
|
||||
├── motmod + kinematics / fixed servo cycle
|
||||
├── HAL files / HALUI / simulated devices
|
||||
└── DISPLAY=gmoccapy 或 DISPLAY=axis
|
||||
│
|
||||
▼
|
||||
GMOCCAPY Gtk/Glade 控制面板
|
||||
│
|
||||
┌─────────┴─────────┐
|
||||
│ │
|
||||
用户点击/键盘/HAL linuxcnc.stat/HAL status
|
||||
│ ▲
|
||||
▼ │
|
||||
Python handler ── command ─┴── TASK/motion/HAL feedback
|
||||
│
|
||||
├── 模式/按钮页切换
|
||||
├── 程序加载/预览
|
||||
├── AUTO 运行/暂停/停止/单步
|
||||
├── MDI 命令
|
||||
└── homing、tool、offset、spindle、coolant
|
||||
```
|
||||
|
||||
GMOCCAPY 不是运动学计算器。它负责把操作员动作转换为 LinuxCNC command,并把 LinuxCNC status/HAL status 投影回界面;真正的解释器、轨迹规划、逆解/正解和关节命令由 LinuxCNC runtime 完成。
|
||||
|
||||
## 3. 启动控制流
|
||||
|
||||
### 3.1 快捷方式层
|
||||
|
||||
`run-gmoccapy.sh` 和 `run-5axis-rtcp.sh` 都遵循相同模式:
|
||||
|
||||
1. 计算仓库绝对路径,避免从任意工作目录启动时相对路径漂移。
|
||||
2. 校验 INI、演示程序、LinuxCNC launcher 是否存在。
|
||||
3. 进入 LinuxCNC 根目录。
|
||||
4. 执行 `/usr/bin/linuxcnc -r CASE.ini`,保留终端诊断。
|
||||
|
||||
五轴快捷方式额外检查 RTCP 子程序中确实存在 `M428`,并支持 `xyzac-trt.ini` 与 `xyzbc-trt.ini` 两个变体。
|
||||
|
||||
### 3.2 INI 到进程
|
||||
|
||||
以普通 GMOCCAPY 为例:
|
||||
|
||||
```text
|
||||
[DISPLAY] DISPLAY=gmoccapy
|
||||
[TASK] TASK=milltask
|
||||
[HAL] core_sim.hal + spindle_sim.hal + simulated_home.hal
|
||||
[EMCIO] TOOL_TABLE=tool.tbl
|
||||
[RS274NGC] PARAMETER_FILE=sim.var, SUBROUTINE_PATH=macros
|
||||
[KINS] trivkins coordinates=xyz
|
||||
```
|
||||
|
||||
启动器随后创建 `linuxcncsvr`、`milltask`、`halui` 和 GMOCCAPY。GMOCCAPY 进程通过 `-ini` 得到同一个 INI 路径,不能自行替代 TASK/motion/HAL。
|
||||
|
||||
### 3.3 GMOCCAPY 初始化顺序
|
||||
|
||||
仓库源码 `gmoccapy.py` 的主初始化顺序为:
|
||||
|
||||
1. 解析 `-user_mode`、`-logo` 参数(约 `243-270` 行)。
|
||||
2. 读取 INI(`_get_ini_data()`,约 `272-275` 行)。
|
||||
3. 读取偏好文件(`_get_pref_data()`)。
|
||||
4. 动态创建 DRO、home、touch-off、jog、macro 等控件(约 `280-305` 行)。
|
||||
5. 建立 GMOCCAPY HAL pins(约 `307` 行)。
|
||||
6. 连接 Glade signals(约 `315-320` 行)。
|
||||
7. 显示主窗口(约 `324-325` 行)。
|
||||
8. 初始化主题、G-code preview、kinematics view、offset/tool editor、keyboard 和文件选择器(约 `327-342` 行)。
|
||||
|
||||
系统 3.5.2 运行时在 GUI 初始化后额外调用 `_startup_message()`,生成版本提示弹窗;它属于安装包新增功能,不属于仓库 3.4.3 初始化链。
|
||||
|
||||
## 4. 控制面板模式和按钮门控
|
||||
|
||||
### 4.1 模式按钮
|
||||
|
||||
Glade 中的主要模式控件:
|
||||
|
||||
| 控件 | 作用 | handler/状态 |
|
||||
|---|---|---|
|
||||
| `rbt_manual` | MANUAL/JOG | `on_rbt_manual_pressed()` 发出 `MODE_MANUAL` |
|
||||
| `rbt_mdi` | MDI | `on_rbt_mdi_pressed()` 发出 `MODE_MDI` |
|
||||
| `rbt_auto` | AUTO | `on_rbt_auto_pressed()` 发出 `MODE_AUTO` |
|
||||
| `tbtn_setup` | 设置页 | 进入设置前强制 MANUAL,并禁用模式按钮 |
|
||||
| `tbtn_user_tabs` | 用户页 | 切换主 notebook 页面 |
|
||||
|
||||
`on_hal_status_mode_auto()` 在收到 HAL status 后将主页面切回 page 0,把按钮 notebook 切到 `_BB_AUTO`,并将 jog notebook 切到 AUTO 页面(约 `2804-2824` 行)。因此“点击 AUTO 图标”与“看到 AUTO 按钮组”是同一个状态转换的两个可观察结果。
|
||||
|
||||
### 4.2 急停、上电、homing 门控
|
||||
|
||||
`on_tbtn_setup_toggled()` 和 HAL status handler 根据以下条件设置按钮敏感度:
|
||||
|
||||
```text
|
||||
ESTOP → manual/mdi/auto 均禁用
|
||||
ON + 未 homed → 只允许 manual
|
||||
ON + all_homed 或 NO_FORCE_HOMING → manual/mdi/auto 全部可用
|
||||
```
|
||||
|
||||
对应仓库源码约为 `3793-3808` 行。未满足条件时,点击 AUTO 会被 `on_hal_status_mode_auto()` 拒绝,显示 `It is not possible to change to Auto Mode at the moment`,并回到 MANUAL。
|
||||
|
||||
这解释了为什么控制面板可能“没有加载按钮”:加载按钮不在 MANUAL 页面,而且 AUTO 页面本身可能因状态门控没有激活。
|
||||
|
||||
## 5. G-code 加载数据流
|
||||
|
||||
### 5.1 控件链
|
||||
|
||||
```text
|
||||
rbt_auto
|
||||
│ on_hal_status_mode_auto()
|
||||
▼
|
||||
hbtb_auto / _BB_AUTO
|
||||
│
|
||||
│ btn_load(图标 img_open,tooltip=Load a new program)
|
||||
│ on_btn_load_clicked()
|
||||
▼
|
||||
_BB_LOAD_FILE + IconFileSelection1
|
||||
│
|
||||
│ 用户选中路径
|
||||
│ btn_select / IconFileSelection1_selected
|
||||
▼
|
||||
hal_action_open.load_file(path)
|
||||
▼
|
||||
LinuxCNC task/interpreter + preview/status
|
||||
▼
|
||||
ntb_preview page 0 + ntb_button _BB_AUTO + stat.file
|
||||
```
|
||||
|
||||
### 5.2 打开文件界面
|
||||
|
||||
`on_btn_load_clicked()`(`gmoccapy.py:5046-5078`)执行:
|
||||
|
||||
1. `ntb_button.set_current_page(_BB_LOAD_FILE)`。
|
||||
2. `ntb_preview.set_current_page(3)`。
|
||||
3. 打开 full-size preview。
|
||||
4. `_show_iconview_tab(True)`。
|
||||
5. 刷新 `IconFileSelection1` 文件列表。
|
||||
6. 暂时禁用 MANUAL、MDI 和设置按钮,避免文件选择过程中切换模式。
|
||||
|
||||
文件选择器在 `_init_IconFileSelection()` 和 `_init_file_to_load()` 中读取 `PROGRAM_PREFIX` 与 `[FILTER] PROGRAM_EXTENSION`。普通案例 `PROGRAM_PREFIX = ../../nc_files/` 最终指向仓库的 `linuxcnc/nc_files`。
|
||||
|
||||
### 5.3 确认文件
|
||||
|
||||
`on_IconFileSelection1_selected()`(`gmoccapy.py:5114-5125`)执行:
|
||||
|
||||
1. 将选中的 `path` 交给 `hal_action_open.load_file(path)`。
|
||||
2. 恢复 preview page 0。
|
||||
3. 关闭 full-size preview 和 icon view。
|
||||
4. 把按钮 notebook 切回 `_BB_AUTO`。
|
||||
5. 重新启用 MANUAL、MDI 和设置按钮。
|
||||
|
||||
这一步是“加载程序”,不是“运行程序”。运行还需要 `btn_run`/`AUTO_RUN`;源码键盘 handler 将 `R` 映射为运行、`P` 映射为暂停、`S` 映射为恢复。
|
||||
|
||||
### 5.4 启动时自动加载
|
||||
|
||||
`on_window1_show()` 会读取偏好项 `open_file`(约 `2920-2924` 行)。如果用户在设置页指定“启动时加载文件”,GMOCCAPY 会在窗口显示后直接调用 `hal_action_open.load_file(file)`。这条路径绕过手动点击文件选择器,但仍通过同一个 LinuxCNC load action。
|
||||
|
||||
## 6. AUTO 运行控制流
|
||||
|
||||
```text
|
||||
btn_run / R
|
||||
▼
|
||||
linuxcnc.command().auto(AUTO_RUN, line)
|
||||
▼
|
||||
milltask / RS274NGC interpreter
|
||||
▼
|
||||
TP queue → motion controller → kinematics → joint commands
|
||||
▼
|
||||
HAL simulated device / spindle / coolant / tool change
|
||||
▼
|
||||
linuxcnc.stat + hal_status
|
||||
▼
|
||||
GMOCCAPY DRO、progress、preview、button sensitivity
|
||||
```
|
||||
|
||||
相关按钮属于 `hbtb_auto`:`btn_load`、`btn_reload`、`btn_run`、`btn_stop`、`tbtn_pause`、`btn_step`、`btn_from_line`、`tbtn_optional_blocks`、`btn_edit`。Glade 负责控件和 signal 绑定,Python handler 负责调用 LinuxCNC command;运动本身不在 GTK handler 中实现。
|
||||
|
||||
## 7. MDI、Jog、Home、Tool 和 Offset 数据流
|
||||
|
||||
### MDI
|
||||
|
||||
`rbt_mdi` 将 task mode 设为 `MODE_MDI`。MDI 输入提交后进入 LinuxCNC interpreter;G-code 解析错误通过 LinuxCNC error channel 返回,再由 GMOCCAPY notification/error handler 显示。
|
||||
|
||||
### Jog
|
||||
|
||||
JOG 按钮由 `_make_jog_button()` 动态生成;轴/关节列表来自 INI 的 `COORDINATES`、kinematics 类型和 joint-axis mapping。Jog 命令仍经 LinuxCNC command 通道,不直接改变 DRO;DRO 的真值来自 status feedback。
|
||||
|
||||
### Home
|
||||
|
||||
Home 按钮最终调用 `command.home(joint_or_axis)`。仿真 HAL 的 `sim_home_switch` 或自定义 home HAL 决定 home switch 状态;`all_homed` HAL status 决定 MDI/AUTO 是否重新开放。
|
||||
|
||||
### Tool/Offset
|
||||
|
||||
工具表来自 `[EMCIO] TOOL_TABLE`,offset page 和 tool editor 通过 LinuxCNC tool data/action 更新。G43/G49/G43.1 的解释器语义由 RS274NGC 负责;GMOCCAPY 只显示和提交工具/offset 操作。系统 3.5.2 的启动提示明确提醒:AUTO 中换刀后的 G43 不能假定由界面自动恢复,应由程序/REMAP 明确处理。
|
||||
|
||||
## 8. 五轴 XYZAC RTCP 控制流
|
||||
|
||||
### 8.1 配置层
|
||||
|
||||
五轴案例 `xyzac-trt.ini` 的关键字段:
|
||||
|
||||
```text
|
||||
[DISPLAY] OPEN_FILE = ./demos/xyzac_switchkins.ngc
|
||||
[RS274NGC] SUBROUTINE_PATH = ./remap_subs
|
||||
[RS274NGC] REMAP = M428 ... ngc=428remap
|
||||
[RS274NGC] REMAP = M429 ... ngc=429remap
|
||||
[RS274NGC] REMAP = M430 ... ngc=430remap
|
||||
[KINS] KINEMATICS = xyzac-trt-kins sparm=identityfirst
|
||||
[TRAJ] COORDINATES = XYZAC
|
||||
[HAL] HALCMD = net ... motion.switchkins-type
|
||||
[HAL] HALCMD = loadusr -W xyzac-trt-gui
|
||||
```
|
||||
|
||||
### 8.2 switchkins 状态
|
||||
|
||||
`xyzac-trt-kins.c` 将 `sparm=identityfirst` 定义为:
|
||||
|
||||
```text
|
||||
switchkins-type 0 → identity kinematics
|
||||
switchkins-type 1 → xyzac TRT kinematics
|
||||
switchkins-type 2 → userk kinematics
|
||||
```
|
||||
|
||||
`trtfuncs.c` 为 XYZAC/XYZBC 实现 forward/inverse mapping,并声明 `tool-offset`、旋转中心和轴 offset HAL pins。XYZAC 的五个关节是 `X Y Z A C`;A 是倾斜台,C 是水平旋转台。
|
||||
|
||||
### 8.3 M428/M429 控制链
|
||||
|
||||
```text
|
||||
G-code M428
|
||||
▼
|
||||
428remap.ngc
|
||||
├── M68 E3 Q1 写 motion.analog-out-03 = 1
|
||||
├── M66 E0 L0 等待同步
|
||||
└── 检查 motion.switchkins-type == 1
|
||||
▼
|
||||
xyzac-trt-kins inverse/forward
|
||||
▼
|
||||
XYZAC joint commands with TCP/RTCP compensation
|
||||
```
|
||||
|
||||
`M429` 对称地写入 `Q0`,切回 identity;`M430` 写入 `Q2`,进入 userk。`helix_ac.ngc` 演示了典型顺序:先用 M429 在 machine coordinates 安全定位,再用 M428 执行带 A/C 姿态变化的螺旋插补,结束后再切回 M429 做返回定位。
|
||||
|
||||
### 8.4 Vismach feedback
|
||||
|
||||
INI 中的 HAL nets 将以下反馈送到 `xyzac-trt-gui`:
|
||||
|
||||
```text
|
||||
joint.0.pos-fb → table-x
|
||||
joint.1.pos-fb → saddle-y
|
||||
joint.2.pos-fb → spindle-z
|
||||
joint.3.pos-fb → tilt-a
|
||||
joint.4.pos-fb → rotate-c
|
||||
motion.tooloffset.z → tool-offset
|
||||
xyzac-trt-kins.y-offset/z-offset → Vismach geometry
|
||||
```
|
||||
|
||||
因此 Vismach 不是运动 authority;它是 joint feedback、tool offset 和 geometry offset 的可视化消费者。
|
||||
|
||||
## 9. 状态真值与可观察结果
|
||||
|
||||
| 状态 | authority | 面板表现 |
|
||||
|---|---|---|
|
||||
| 急停 | TASK/motion state | E-stop active,模式按钮禁用 |
|
||||
| 上电 | TASK state + HAL | Power icon active,允许进一步操作 |
|
||||
| all homed | HAL status / joint state | MDI/AUTO 解除门控 |
|
||||
| 当前模式 | `stat.task_mode` | MANUAL/MDI/AUTO 页面切换 |
|
||||
| 当前文件 | `stat.file` / file-loaded status | 顶部文件名、G-code view、Run gate |
|
||||
| 解释器状态 | `stat.interp_state` | Run/Pause/Step/Stop 敏感度 |
|
||||
| 当前 G/M codes | `stat.gcodes` / `stat.mcodes` | G-Code 信息区域 |
|
||||
| 机床位置 | `stat.position` / joint feedback | DRO 和 Vismach |
|
||||
| kinematics mode | `motion.switchkins-type` | AXIS switchkins 面板/RTCP 模式 |
|
||||
|
||||
任何未来 Web/WASM 控制面板都应消费这些 authority 的 snapshot/event,而不是在 JS/GUI 层镜像一套可写的机床状态。
|
||||
|
||||
## 10. 现有证据与复现
|
||||
|
||||
```bash
|
||||
./run-gmoccapy.sh
|
||||
./run-5axis-rtcp.sh
|
||||
./run-5axis-rtcp.sh xyzbc-trt.ini
|
||||
```
|
||||
|
||||
已验证的五轴运行证据:
|
||||
|
||||
- [5axis-rtcp-running.png](5axis-rtcp-running.png)
|
||||
- [5axis-rtcp-shortcut.md](5axis-rtcp-shortcut.md)
|
||||
- `linuxcnc` 状态返回 `file=./demos/xyzac_switchkins.ngc`
|
||||
- AXIS 标题包含 `sim-xyzac-trt-kins (switchkins)`
|
||||
- `xyzac-trt-gui` 进程和五轴 Vismach 预览存在
|
||||
|
||||
## 11. 后续分析顺序
|
||||
|
||||
分析任何新的 GMOCCAPY/五轴控制问题时,按以下顺序取证:
|
||||
|
||||
1. 先记录实际运行时路径、LinuxCNC 版本、GMOCCAPY 版本;不要把系统安装脚本和仓库源码混为一份。
|
||||
2. 读取 INI 的 DISPLAY/TASK/HAL/RS274NGC/KINS/TRAJ/EMCIO 段,建立配置闭包。
|
||||
3. 在 Glade 中找到 widget ID,再在 `gmoccapy.py` 找 signal handler;不要只根据截图猜按钮语义。
|
||||
4. 追踪 handler 发出的 `linuxcnc.command()`,确认 command 进入 TASK/motion/HAL 的路径。
|
||||
5. 用 `linuxcnc.stat()`、HAL pins、日志和 Vismach feedback 交叉验证,不把 DRO 或 preview 当作 authority。
|
||||
6. 五轴问题先确认 kinematics type、M428/M429 状态、tool offset、rotation center/axis offset,再分析轨迹差异。
|
||||
7. 任何缺失的官方 oracle、实时硬件、浏览器或资源输入都保留为明确 blocker,不以 GUI 截图替代完整等价证明。
|
||||
7427
doc-rtcp/gmoccapy-file-inventory.json
Normal file
7427
doc-rtcp/gmoccapy-file-inventory.json
Normal file
File diff suppressed because it is too large
Load Diff
18
doc-rtcp/gmoccapy-file-inventory.md
Normal file
18
doc-rtcp/gmoccapy-file-inventory.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# GMOCCAPY 文件清单
|
||||
|
||||
清单范围内共 `1233` 个文件;每项包含相对路径、角色、字节数和 SHA-256。
|
||||
|
||||
| 角色 | 数量 |
|
||||
|---|---:|
|
||||
| `documentation` | 2 |
|
||||
| `documentation_asset` | 27 |
|
||||
| `icon_asset` | 973 |
|
||||
| `implementation` | 28 |
|
||||
| `installed_ui_asset` | 1 |
|
||||
| `simulation_asset` | 16 |
|
||||
| `simulation_ini` | 29 |
|
||||
| `simulation_resource` | 69 |
|
||||
| `simulation_runtime_data` | 64 |
|
||||
| `translation` | 24 |
|
||||
|
||||
完整逐文件数据见 [`gmoccapy-file-inventory.json`](gmoccapy-file-inventory.json)。
|
||||
BIN
doc-rtcp/gmoccapy-important-changes-v2.png
Normal file
BIN
doc-rtcp/gmoccapy-important-changes-v2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 201 KiB |
BIN
doc-rtcp/gmoccapy-important-changes.png
Normal file
BIN
doc-rtcp/gmoccapy-important-changes.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 197 KiB |
BIN
doc-rtcp/gmoccapy-load-file-page.png
Normal file
BIN
doc-rtcp/gmoccapy-load-file-page.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 239 KiB |
BIN
doc-rtcp/gmoccapy-program-loaded.png
Normal file
BIN
doc-rtcp/gmoccapy-program-loaded.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 295 KiB |
60
doc-rtcp/xyzac-trt-autonomous-execution-prompt.md
Normal file
60
doc-rtcp/xyzac-trt-autonomous-execution-prompt.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# `nextTask-rtcp.md` 持续执行提示词
|
||||
|
||||
复制下面的提示词即可从五轴 XYZAC TRT Web/WASM 轨道持续执行:
|
||||
|
||||
```text
|
||||
你是本仓库的 XYZAC TRT Web/WASM 源码对标工程代理。请持续推进任务,不要只给计划;每轮都从 nextTask-rtcp.md 当前指针认领并执行,直到任务 verified、明确 blocked 或遇到 Stop 条件。
|
||||
|
||||
1. 先读取 nextTask-rtcp.md 的 Current、Read、Task、Next、Verify、Stop;不要用 nextTask.md 或 nextTask1.md 替代它们。
|
||||
2. 按 Task.direct_inputs 读取当前任务的直接源码、配置和报告;不要批量加载聊天记录、完整日志或无关 coverage 文件。
|
||||
3. 开始前运行:
|
||||
python3 scripts/validate_baseline.py
|
||||
python3 scripts/validate_download_index.py
|
||||
python3 scripts/validate_task_pointer.py nextTask-rtcp.md --lock context-lock.json
|
||||
4. 确认 task_id、context_id、active_case、直接输入、required_outputs 和完成报告;当前案例固定为:
|
||||
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini
|
||||
5. 将当前 Task.status 从 queued 改为 in_progress 前,先读取:
|
||||
doc-rtcp/xyzac-trt-control-panel-web-wasm-design.md
|
||||
doc-rtcp/xyzac-trt-web-wasm-implementation-plan.md
|
||||
doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md
|
||||
6. 严格遵守源码唯一权威:所有 task、interpreter、TP、motion、XYZAC forward/inverse、RTCP、HAL、IO、tool、preview、recovery 和 state hash 必须来自 LinuxCNC WASM/Worker;React、JS、Three.js 只能输入、投影和显示。
|
||||
7. 对每个功能建立 source behavior slice,必须保留 source path、symbol、source hash、输入、native command、WASM command、gate、authoritative output、错误、恢复和 Web control id。
|
||||
8. 不得使用 JS G-code preview、JS 姿态/RTCP 补偿、浏览器墙钟 tick、主线程 OPFS 写入、直接 WASM 指针、mock runtime 或宿主 LinuxCNC fallback 冒充 WASM 通过。
|
||||
9. 每项实现先写失败边界和专项测试,再做最小垂直切片;优先复用现有 protocol.v1、WorkerClient、AxisOperationController、PanelSnapshotV1、WASM ABI 和固定 tick runtime。
|
||||
10. 五轴必须特别验证:
|
||||
- XYZAC 坐标、五 joints、A/C 角度单位和 limits;
|
||||
- xyzac-trt-kins forward/inverse、tool offset、y/z offset、rotation point;
|
||||
- M428/M429/M430 remap、HAL_PIN_VARS、motion.switchkins-type 和状态确认;
|
||||
- helix/arc/姿态变化、singularity、non-finite、limit、following error;
|
||||
- Vismach pose/joints/toolpath 只消费 authoritative snapshot;
|
||||
- pause/resume/abort/restart/checkpoint/recovery 不重复 segment、M-code 或 IO/tool side effect。
|
||||
11. 所有有副作用命令必须有 operation_id、seq、ledger prepare/ack/result/commit/reconcile;超时不能盲目重发,必须查询 Worker ledger 或 authoritative snapshot。
|
||||
12. 运行任务专属测试、真实 WASM Worker/session、native 对照、React typecheck/build、Three.js canvas 检查和报告 self-hash。命令不存在时先创建任务产物或明确记录 blocked,不能写成已通过。
|
||||
13. 报告必须包含 context_id、case_path、输入/输出 hash、测试命令、normal/boundary/error/recovery、state hash、command trace、tick trace、first divergent tick、failure samples、known blockers 和 report_sha256。
|
||||
14. 失败样本必须保留并分类为 SOURCE_BLOCKED、HOST_EXCLUDED、REAL-EXCLUDED、BLOCKED_RESOURCE、BLOCKED_HAL、BLOCKED_INI、BLOCKED_STARTUP 或具体 Worker/Task/motion/kinematics pending;不得删失败、降级检查或把 blocker 改名为通过。
|
||||
15. 只有当前任务的专项测试、native/WASM/Worker 证据、完整回归和报告 self-hash 全部通过,才能把 Task.status 改为 verified;否则改为 blocked 并保留证据。
|
||||
16. 当前任务 verified 后,更新 nextTask-rtcp.md 的 Current、Next、Verify、Stop 和 completion evidence;只有依赖满足的下一个任务才可写为 queued。不要修改 nextTask.md、nextTask1.md、context-lock、ABI、protocol、schema、许可证决定或 release gate。
|
||||
17. 不要在 verified + queued 状态停下;若 Next 依赖满足,立即认领下一个任务并继续执行。若外部源码、oracle、浏览器、OPFS、实时硬件、owner 输入或批准变更缺失,则保持 blocked,不自动重试同一阻塞。
|
||||
18. 每隔约 30 秒发送简短进度更新,说明当前 task_id、已完成检查、正在执行的测试和 blocker;不要输出无关长日志。
|
||||
19. 只有 nextTask-rtcp.md 明确 next_task: none 且 local continuation verified,或当前任务满足 Stop/外部阻塞条件时才暂停。selected-case verified 不得写成全 LinuxCNC parity,release_status 继续保持 STOP_RELEASE,直到源码、WASM authority、canonical parity、recovery、browser、oracle 和其它正式门禁全部有证据。
|
||||
|
||||
现在立即读取 nextTask-rtcp.md,并从当前 Task 开始执行。
|
||||
```
|
||||
|
||||
## 推荐调用语句
|
||||
|
||||
最短调用:
|
||||
|
||||
```text
|
||||
按 nextTask-rtcp.md 接续执行,严格使用 doc-rtcp/xyzac-trt-autonomous-execution-prompt.md 的规则。
|
||||
```
|
||||
|
||||
更强约束调用:
|
||||
|
||||
```text
|
||||
持续执行 nextTask-rtcp.md:先验证基线和指针,认领当前任务,按源码 slice 实现 LinuxCNC WASM 唯一权威闭环,运行 native/WASM/Worker/React/Three.js 证据,更新报告和指针;不要修改 nextTask.md、nextTask1.md、context lock、ABI、protocol、schema 或 release gate,也不要在 verified+queued 状态停下。
|
||||
```
|
||||
|
||||
## 当前起点
|
||||
|
||||
当前指针的任务是 `SRC-00`,目标是建立 AXIS/XYZAC source slice inventory 和 WASM authority contract;下一任务是 `WASM-00`。读取和执行状态以根目录的 [`nextTask-rtcp.md`](../nextTask-rtcp.md) 为准。
|
||||
529
doc-rtcp/xyzac-trt-control-panel-web-wasm-design.md
Normal file
529
doc-rtcp/xyzac-trt-control-panel-web-wasm-design.md
Normal file
@@ -0,0 +1,529 @@
|
||||
# `xyzac-trt.ini` 控制面板、数据流、控制约束与 Web/WASM 设计基础
|
||||
|
||||
更新时间:2026-08-25
|
||||
|
||||
本文专门分析:
|
||||
|
||||
```text
|
||||
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini
|
||||
```
|
||||
|
||||
目标不是复刻一个静态 AXIS 外观,而是为 Web/WASM 控制台建立可验证的功能、数据、控制和权限模型。所有“按钮是否可点”的结论都必须来自 LinuxCNC authoritative task/motion/HAL 状态;React/浏览器只能投影状态并发出带 gate 的命令。
|
||||
|
||||
相关运行入口和基础说明:
|
||||
|
||||
- [`run-5axis-rtcp.sh`](../run-5axis-rtcp.sh)
|
||||
- [`5axis-rtcp-shortcut.md`](5axis-rtcp-shortcut.md)
|
||||
- [`gmoccapy-control-panel-data-control-flow.md`](gmoccapy-control-panel-data-control-flow.md)
|
||||
- [`5axis-rtcp-running.png`](5axis-rtcp-running.png)
|
||||
|
||||
## 1. 案例边界
|
||||
|
||||
### 1.1 入口配置
|
||||
|
||||
`xyzac-trt.ini` 的关键配置如下:
|
||||
|
||||
| INI 段 | 字段 | 功能 |
|
||||
|---|---|---|
|
||||
| `[EMC]` | `MACHINE = sim-xyzac-trt-kins (switchkins)` | 案例名称和 switchkins 语义 |
|
||||
| `[DISPLAY]` | `DISPLAY = axis` | 主控制面板是 AXIS/Tk,不是 GMOCCAPY |
|
||||
| `[DISPLAY]` | `OPEN_FILE = ./demos/xyzac_switchkins.ngc` | 启动后预置的 G-code 文件 |
|
||||
| `[DISPLAY]` | `PYVCP = ./xyzac-trt.xml` | 右侧 SWITCHKINS/vismach-clear 面板 |
|
||||
| `[DISPLAY]` | `JOG_AXES = XYZC` | 手动点动显示 X/Y/Z/C;A 仍属于五轴运动学 |
|
||||
| `[DISPLAY]` | `PROGRAM_PREFIX = ../../nc_files` | 默认程序搜索目录 |
|
||||
| `[DISPLAY]` | `POSITION_OFFSET = RELATIVE` | DRO 默认显示相对坐标 |
|
||||
| `[DISPLAY]` | `POSITION_FEEDBACK = ACTUAL` | DRO 使用 actual position |
|
||||
| `[RS274NGC]` | `SUBROUTINE_PATH = ./remap_subs` | M428/M429/M430 和 helix 子程序路径 |
|
||||
| `[RS274NGC]` | `HAL_PIN_VARS = 1` | 允许 remap 访问 HAL pin |
|
||||
| `[RS274NGC]` | `REMAP = M428/M429/M430` | kinematics 状态切换入口 |
|
||||
| `[RS274NGC]` | `PARAMETER_FILE = xyzac.var` | RS274 参数持久化 |
|
||||
| `[KINS]` | `KINEMATICS = xyzac-trt-kins sparm=identityfirst` | 5 关节 XYZAC,0=identity,1=TRT,2=userk |
|
||||
| `[KINS]` | `JOINTS = 5` | X/Y/Z/A/C 五个 joint |
|
||||
| `[HAL]` | `HALFILE = LIB:basic_sim.tcl` | 生成仿真 motion/HAL/模拟设备 |
|
||||
| `[HAL]` | `POSTGUI_HALFILE = switchkins_postgui.hal` | GUI 创建后连接 PyVCP 控件 |
|
||||
| `[HAL]` | `motion.analog-out-03 => motion.switchkins-type` | remap 写入 switchkins 的控制通道 |
|
||||
| `[HAL]` | `loadusr -W xyzac-trt-gui` | 独立 Vismach 五轴模型进程 |
|
||||
| `[TRAJ]` | `COORDINATES = XYZAC` | 解释器和轨迹规划的笛卡尔坐标集合 |
|
||||
| `[EMCIO]` | `TOOL_TABLE = xyzac-trt.tbl` | 工具长度/直径等数据 |
|
||||
|
||||
### 1.2 三个界面实体
|
||||
|
||||
```text
|
||||
AXIS 主窗口
|
||||
├── Tk 菜单、工具栏、Manual Control、MDI、Preview、DRO、G-code view
|
||||
├── PyVCP xyzac-trt.xml(右侧 SWITCHKINS 面板)
|
||||
└── AXIS 内部 Python/Tk command + linuxcnc.stat 状态轮询
|
||||
|
||||
xyzac-trt-gui 进程
|
||||
└── Python vismach 模型,仅消费 HAL joint feedback/tool-offset/offset
|
||||
|
||||
LinuxCNC runtime
|
||||
├── linuxcncsvr / NML
|
||||
├── milltask / RS274NGC interpreter
|
||||
├── motmod / TP / switchkins / xyzac-trt-kins
|
||||
└── HAL / simulated home / spindle / tool-change / PyVCP pins
|
||||
```
|
||||
|
||||
AXIS 是控制和状态投影者,PyVCP 是 HAL 控件,Vismach 是可视化消费者;三者都不是独立的运动 authority。
|
||||
|
||||
## 2. 启动与初始化数据流
|
||||
|
||||
```text
|
||||
run-5axis-rtcp.sh
|
||||
│
|
||||
▼
|
||||
/usr/bin/linuxcnc -r xyzac-trt.ini
|
||||
│
|
||||
├── 读取 [DISPLAY]/[TASK]/[HAL]/[KINS]/[TRAJ]
|
||||
├── 启动 linuxcncsvr
|
||||
├── 启动 milltask
|
||||
├── 运行 basic_sim.tcl 生成 HAL
|
||||
├── loadusr xyzac-trt-gui
|
||||
├── 执行 switchkins_postgui.hal
|
||||
└── 启动 /usr/bin/axis -ini xyzac-trt.ini
|
||||
│
|
||||
├── open_file_guts(OPEN_FILE)
|
||||
├── 创建 Tk/AXIS widgets
|
||||
├── 读取 linuxcnc.stat
|
||||
└── 周期刷新 DRO/preview/gates
|
||||
```
|
||||
|
||||
### 2.1 AXIS 初始化的责任
|
||||
|
||||
主要来源:
|
||||
|
||||
```text
|
||||
linuxcnc/src/emc/usr_intf/axis/scripts/axis.py
|
||||
```
|
||||
|
||||
核心职责:
|
||||
|
||||
1. 解析 INI 和显示选项。
|
||||
2. 初始化 `linuxcnc.command()`、`linuxcnc.stat()` 和 HAL component。
|
||||
3. 根据 `COORDINATES=XYZAC` 建立 axis/joint 映射。
|
||||
4. 读取 `OPEN_FILE`,通过 `open_file_guts()` 和 `c.program_open()` 载入程序。
|
||||
5. 读取 G-code,运行 canon/preview 生成程序轨迹。
|
||||
6. 周期 `s.poll()`,将 position、joint position、homed、limit、tool、G/M code、task/interpreter state 投影到 Tk 变量。
|
||||
7. 根据 `running()`、`manual_ok()`、`all_homed()` 和 task/motion 状态决定按钮是否响应。
|
||||
|
||||
### 2.2 Vismach 初始化的责任
|
||||
|
||||
`linuxcnc/src/hal/user_comps/vismach/xyzac-trt-gui.py` 创建 HAL component:
|
||||
|
||||
```text
|
||||
xyzac-trt-gui.table-x HAL_FLOAT IN
|
||||
xyzac-trt-gui.saddle-y HAL_FLOAT IN
|
||||
xyzac-trt-gui.spindle-z HAL_FLOAT IN
|
||||
xyzac-trt-gui.tilt-a HAL_FLOAT IN
|
||||
xyzac-trt-gui.rotate-c HAL_FLOAT IN
|
||||
xyzac-trt-gui.y-offset HAL_FLOAT IN
|
||||
xyzac-trt-gui.z-offset HAL_FLOAT IN
|
||||
xyzac-trt-gui.tool-offset HAL_FLOAT IN
|
||||
```
|
||||
|
||||
模型通过 `HalTranslate`/`HalRotate` 将这些输入转换为 OpenGL 模型姿态。它不发 `program_run`、`jog`、`home` 或 kinematics 命令。
|
||||
|
||||
## 3. AXIS 主控制面板功能
|
||||
|
||||
### 3.1 顶部菜单和工具栏
|
||||
|
||||
AXIS/Tk 主面板通常提供:
|
||||
|
||||
| 类别 | 典型动作 | LinuxCNC command/效果 |
|
||||
|---|---|---|
|
||||
| 文件 | Open | `program_open(path)`,更新 loaded file 和 preview |
|
||||
| AUTO 按钮组 | `hbtb_auto` / `btn_load` | AXIS 的 Open/Load 文件入口;只在程序未运行时打开文件选择器 |
|
||||
| 文件 | Reload | 重新读取当前文件;运行中拒绝 |
|
||||
| 文件 | Recent files | 偏好文件保存最近路径,最多 10 项 |
|
||||
| 文件 | Edit | 调用 `EDITOR`/外部编辑器;不改变 runtime authority |
|
||||
| 程序 | Run | `c.mode(MODE_AUTO)` + `c.auto(AUTO_RUN, start_line)` |
|
||||
| 程序 | Step | `c.auto(AUTO_STEP)` |
|
||||
| 程序 | Pause | `c.auto(AUTO_PAUSE)` |
|
||||
| 程序 | Resume | `c.auto(AUTO_RESUME)` |
|
||||
| 程序 | Stop | `c.abort()`,同时设置 GUI abort 状态 |
|
||||
| 程序 | Run from line | 设置 first line 后再 AUTO_RUN,风险高于普通 Run |
|
||||
| 机床 | Power | `c.state(STATE_ON/OFF)` |
|
||||
| 机床 | E-stop | `c.state(STATE_ESTOP/STATE_ESTOP_RESET)` 或硬件链路 |
|
||||
| 机床 | Home/Unhome | `c.home(joint)` / `c.unhome(joint)` |
|
||||
| 机床 | Spindle | `c.spindle(...)` 或 MDI/halui |
|
||||
| 机床 | Feed/rapid/spindle override | `c.feedrate()`/`c.maxvel()` 或相应 HAL/command |
|
||||
| 辅助 | HAL show/tooleditor | 外部工具或 tool data action |
|
||||
| 视图 | Perspective/X/Y/Z/clear plot | 只改变 view/preview,不改变运动状态 |
|
||||
|
||||
菜单图标不是 authority。每个动作必须以 command result 和下一次 status snapshot 确认。
|
||||
|
||||
### 3.2 Manual Control
|
||||
|
||||
Manual 页包含:
|
||||
|
||||
- X/Y/Z/A/C 轴选择;`JOG_AXES=XYZC` 会影响默认可点动轴列表。
|
||||
- Continuous/incremental jog 选择。
|
||||
- jog speed、angular jog speed。
|
||||
- Home All、单轴 Home、Unhome。
|
||||
- Touch Off、Tool Touch Off。
|
||||
- feed/rapid/spindle override。
|
||||
- spindle start/stop/reverse。
|
||||
|
||||
AXIS 的 `manual_ok()` 条件:
|
||||
|
||||
```text
|
||||
task_state == STATE_ON
|
||||
并且当前没有 AUTO/MDI 正在运行
|
||||
并且 interp_state == INTERP_IDLE
|
||||
或当前为 MDI 且 queued_mdi_commands < max_queued_mdi_commands
|
||||
```
|
||||
|
||||
`jog_on()` 还要满足当前 tab 是 manual、轴/joint 映射有效、没有 active limit 阻止动作。Web/WASM 应把这些结果作为 gate reason 返回,不仅仅把 HTML button 设为 disabled。
|
||||
|
||||
### 3.3 MDI
|
||||
|
||||
MDI 入口通过 `ensure_mdi()`:
|
||||
|
||||
1. 检查 `manual_ok()`。
|
||||
2. 关闭 teleop 或切换到合适 motion mode。
|
||||
3. `c.mode(MODE_MDI)`。
|
||||
4. 用户输入字符串后调用 `c.mdi(command)`。
|
||||
5. interpreter 执行后由 `stat.interp_state`、`queued_mdi_commands`、位置和错误通道反馈。
|
||||
|
||||
MDI 不是任意字符串的本地脚本执行器。Web/WASM 必须保留 G-code parser、能力边界、长度限制、错误码和 operation id。
|
||||
|
||||
### 3.4 Preview/DRO/G-code view
|
||||
|
||||
AXIS 周期更新同时刷新:
|
||||
|
||||
- `stat.actual_position` / `joint_actual_position` → DRO。
|
||||
- `stat.g5x_offset` / `g92_offset` / `rotation_xy` / `tool_offset` → 坐标投影。
|
||||
- `stat.gcodes` / `stat.mcodes` / `settings` → G-code 信息。
|
||||
- canon/preview → 静态程序路径。
|
||||
- `motion_line` / `running_line` → 当前行高亮。
|
||||
- `joint.pos-fb` → Vismach 模型。
|
||||
|
||||
静态 preview 和 realtime/live plot 必须分开建模;Web 端不能用 JS 重新解析一份程序来代替 WASM canonical motion。
|
||||
|
||||
## 4. `xyzac-trt.xml` SWITCHKINS 面板
|
||||
|
||||
### 4.1 控件定义
|
||||
|
||||
PyVCP XML 定义:
|
||||
|
||||
| 控件文本 | HAL pin | 目标 |
|
||||
|---|---|---|
|
||||
| `IDENTITY` | `pyvcp.type0-button` | 触发 `halui.mdi-command-00` → M429 |
|
||||
| `TCP:XYZAC` | `pyvcp.type1-button` | 触发 `halui.mdi-command-01` → M428 |
|
||||
| `userk` | `pyvcp.type2-button` | 触发 `halui.mdi-command-02` → M430 |
|
||||
| 多标签 | `kinstype.is-0/1/2` | 显示当前 switchkins type |
|
||||
| `vismach-clear` | `pyvcp.vismach-clear` | 连接 `vismach.plotclear` |
|
||||
|
||||
`switchkins_postgui.hal` 将按钮连接到 HALUI MDI command:
|
||||
|
||||
```text
|
||||
pyvcp.type0-button → halui.mdi-command-00
|
||||
pyvcp.type1-button → halui.mdi-command-01
|
||||
pyvcp.type2-button → halui.mdi-command-02
|
||||
```
|
||||
|
||||
这意味着浏览器端的“TCP:XYZAC”按钮不能直接写 `motion.switchkins-type`,应走同等的受控 command/remap 路径,并等待确认状态。
|
||||
|
||||
### 4.2 switchkins 状态模型
|
||||
|
||||
```text
|
||||
type 0 / M429 → identity
|
||||
type 1 / M428 → xyzac TRT TCP/RTCP
|
||||
type 2 / M430 → userk
|
||||
```
|
||||
|
||||
`xyzac-trt-kins.c` 在 `sparm=identityfirst` 下将 type 0 绑定 identity,type 1 绑定 `trtKinematicsSetup + xyzacKinematicsForward/Inverse`,type 2 绑定 userk。配置注释和实现必须同时读取,不能只依据面板标签。
|
||||
|
||||
## 5. 五轴 RTCP 控制流
|
||||
|
||||
### 5.1 M428/M429 remap
|
||||
|
||||
`428remap.ngc` 的关键操作:
|
||||
|
||||
```text
|
||||
验证 motion.switchkins-type HAL pin 存在
|
||||
M68 E3 Q1 写 motion.analog-out-03 = 1
|
||||
M66 E0 L0 同步等待
|
||||
读取 motion.switchkins-type,必须等于 1
|
||||
```
|
||||
|
||||
`429remap.ngc` 相同,但写入 `Q0`。失败时输出 debug STOP 并结束子程序;Web/WASM 需要把这些失败变成稳定的错误码,而不是只显示“按钮没有反应”。
|
||||
|
||||
### 5.2 典型 helix 数据流
|
||||
|
||||
`helix_ac.ngc` 的典型顺序:
|
||||
|
||||
```text
|
||||
M429 identity
|
||||
G0 / G10 L20 机床坐标定位和设置工作偏置
|
||||
M428 XYZAC TRT / TCP
|
||||
G0 A... C... 改变刀轴姿态
|
||||
G2 ... 在 RTCP 运动学下插补
|
||||
M429 切回 identity
|
||||
G0 ... 安全返回
|
||||
M428 如后续仍需 TCP
|
||||
```
|
||||
|
||||
这里的关键不是“同时有 A/C 数字”,而是同一轨迹块由 XYZAC inverse kinematics 将 TCP pose 转换为五个 joint 命令。姿态变化可能导致 X/Y/Z 补偿变化;因此前端必须同时展示笛卡尔 pose、joint positions、active kinematics mode 和 tool offset。
|
||||
|
||||
### 5.3 Vismach 数据流
|
||||
|
||||
```text
|
||||
joint.0.pos-fb → table-x → HalTranslate
|
||||
joint.1.pos-fb → saddle-y → HalTranslate
|
||||
joint.2.pos-fb → spindle-z → HalTranslate
|
||||
joint.3.pos-fb → tilt-a → HalRotate(A)
|
||||
joint.4.pos-fb → rotate-c → HalRotate(C)
|
||||
motion.tooloffset.z → tool-offset → HalTranslate(tool)
|
||||
y/z-offset → rotary geometry placement
|
||||
```
|
||||
|
||||
Vismach 只读 HAL input。Web/WASM 的 Three.js adapter 应消费 authoritative `visual.pose`/`joints`/`toolpath`,而不是在 React 中根据 A/C 自行推算补偿。
|
||||
|
||||
## 6. 按钮互相制约条件
|
||||
|
||||
下表是 AXIS/LinuxCNC 语义的最小可执行门控。`running` 表示 AUTO 或 MDI 且 `interp_state != INTERP_IDLE`。
|
||||
|
||||
| 按钮/动作 | 必须满足 | 典型阻塞原因 |
|
||||
|---|---|---|
|
||||
| E-stop | 始终可用 | transport/session 不可用 |
|
||||
| Power ON/OFF | 非 ESTOP;不在禁止转换状态 | `ESTOP_ACTIVE` |
|
||||
| Reset | machine ON、非 running、无 active limit | `LIMIT_ACTIVE` / `INTERP_RUNNING` |
|
||||
| Manual jog | `STATE_ON`、MANUAL、非 running、未 fault | `MACHINE_OFF` / `MODE_REQUIRED` |
|
||||
| Home all | `manual_ok()`;必要时确认重复 homing | `NOT_ON` / `RUNNING` |
|
||||
| 单轴 Home | `manual_ok()`;非 identity 时通常必须 joint mode;重复坐标字母禁用单轴 home | `JOINT_MODE_REQUIRED` |
|
||||
| MDI | machine ON;队列未满;idle 或当前 MDI | `MDI_QUEUE_FULL` / `INTERP_RUNNING` |
|
||||
| Open file | 解释器 idle;AXIS `open_file_guts` 临时切 MANUAL 后恢复原 mode | `INTERP_RUNNING` |
|
||||
| Load program | machine ON、idle | `MACHINE_OFF` |
|
||||
| Reload | idle 且已有 loaded file | `TASKFILE_MISSING` |
|
||||
| Run | machine ON、idle、已有程序 | `TASKFILE_MISSING` / `INTERP_RUNNING` |
|
||||
| Run from line | Run 条件 + 有明确 highlight line | `HIGHLIGHT_MISSING` |
|
||||
| Step | machine ON 且有程序;进入 AUTO | `TASKFILE_MISSING` |
|
||||
| Pause | machine ON 且 interpreter READING/WAITING | `PAUSE_STATE_GATE` |
|
||||
| Resume | machine ON 且 interpreter PAUSED | `RESUME_STATE_GATE` |
|
||||
| Stop/Abort | machine ON 且 running;abort 可以强制恢复状态 | `STOP_STATE_GATE` |
|
||||
| Touch Off | manual_ok、MANUAL、允许的 motion mode | `JOINT_MODE_REQUIRED` |
|
||||
| Tool Touch Off | Touch Off 条件 + 有当前工具 | `TOOL_MISSING` |
|
||||
| TCP:XYZAC/M428 | remap HAL pin 存在、HAL net 正确、当前程序允许切换 | `MISSING_HAL_PIN` / `WRONG_SWITCHKINS_TYPE` |
|
||||
| Identity/M429 | 同上,切换后必须确认 type=0 | `WRONG_SWITCHKINS_TYPE` |
|
||||
| Vismach clear | 只清显示 plot,不改变 task/motion | 不应改变机床状态 |
|
||||
|
||||
### 6.1 重要状态互斥
|
||||
|
||||
```text
|
||||
ESTOP → 禁止所有运动、模式、MDI、RTCP 切换
|
||||
OFF → 可以复位/上电,禁止 Run/Jog/Home/MDI
|
||||
ON + 未 homed → 允许 Manual/Home,禁止 AUTO/MDI(除非配置 NO_FORCE_HOMING)
|
||||
RUNNING → 禁止 Open/Reload/Edit/MDI/Jog/Home;允许 Pause/Stop/状态观察
|
||||
PAUSED → 允许 Resume/Stop;禁止 MDI/Jog/重新加载
|
||||
RTCP type switch → 应在 interpreter idle、安全位置、无活动轨迹时执行
|
||||
```
|
||||
|
||||
## 7. 当前 Web/WASM 的对应实现
|
||||
|
||||
### 7.1 已存在的通用契约
|
||||
|
||||
当前 Web 代码已经提供可复用基础:
|
||||
|
||||
| 文件 | 作用 |
|
||||
|---|---|
|
||||
| `web/app/axis-contract.mjs` | `AXIS_COMMANDS`、状态归一化、纯 gate 函数 |
|
||||
| `web/app/axis-operation-controller.mjs` | operation id、gate 检查、command trace、错误保留 |
|
||||
| `web/react/src/protocol.ts` | `MessageEnvelope`、`SimSnapshotV1`、`PanelSnapshotV1`、`AxisStateView` |
|
||||
| `web/react/src/store.ts` | Worker message → authoritative snapshot/projected UI state |
|
||||
| `web/react/src/worker-client.ts` | Dedicated Worker transport、seq、session/context、错误处理 |
|
||||
| `web/react/src/visual-workflow.ts` | AXIS/GMOCCAPY/Vismach 的 visual source 分类 |
|
||||
|
||||
现有 `AXIS_COMMANDS` 已覆盖 `PROGRAM_LOAD/RUN/STEP/PAUSE/RESUME/ABORT/RESTART`、`MDI_EXECUTE`、`JOG_START/STOP`、`HOME`、`ESTOP`、`RESET`、override、spindle、coolant、tool 和 probe。
|
||||
|
||||
### 7.2 `xyzac-trt` 需要的新增协议字段
|
||||
|
||||
建议在现有 `PanelSnapshotV1` 上 additive 扩展,不破坏 `sim_task.v1`:
|
||||
|
||||
```json
|
||||
{
|
||||
"configuration": {
|
||||
"case_path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
|
||||
"coordinates": ["X", "Y", "Z", "A", "C"],
|
||||
"kinematics": "xyzac-trt-kins",
|
||||
"topology": "table-tilting-A/table-rotary-C",
|
||||
"joint_count": 5,
|
||||
"program_prefix": "../../nc_files"
|
||||
},
|
||||
"kinematics": {
|
||||
"family": "switchkins",
|
||||
"active_type": 1,
|
||||
"active_name": "xyzac-trt",
|
||||
"available": [
|
||||
{"type": 0, "name": "identity", "command": "M429"},
|
||||
{"type": 1, "name": "xyzac-trt", "command": "M428"},
|
||||
{"type": 2, "name": "userk", "command": "M430"}
|
||||
],
|
||||
"transition": "idle_only"
|
||||
},
|
||||
"motion": {
|
||||
"axes": {"x": 0, "y": 0, "z": 10, "a": 0, "c": 0},
|
||||
"joints": [0, 0, 10, 0, 0],
|
||||
"tool_offset": {"z": 0},
|
||||
"rotation_center": {"x": 0, "y": 0, "z": 0},
|
||||
"axis_offsets": {"y": 20, "z": 10}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
字段的 authoritative 来源必须来自 WASM kinematics/motion snapshot 或受控 native oracle;不能由 A/C slider 在浏览器中自行补偿。
|
||||
|
||||
### 7.3 命令映射建议
|
||||
|
||||
| Web action | protocol command | xyzac 行为 |
|
||||
|---|---|---|
|
||||
| `PROGRAM_LOAD` | `PROGRAM_LOAD` | 载入程序、canonical preview、重置 active segment |
|
||||
| `PROGRAM_RUN` | `PROGRAM_RUN` | 进入 AUTO,固定 tick 推进 interpreter/TP |
|
||||
| `PROGRAM_PAUSE` | `PROGRAM_PAUSE` | 保留当前 segment/kinematics type |
|
||||
| `PROGRAM_RESUME` | `PROGRAM_RESUME` | 继续同一 program state |
|
||||
| `PROGRAM_ABORT` | `PROGRAM_ABORT` | 停止并返回稳定 STOPPED/IDLE |
|
||||
| `MDI_EXECUTE` | `MDI_EXECUTE` | 用于 `M428`/`M429`/`M430`,必须有 idle gate |
|
||||
| `KINEMATICS_SELECT` | 建议新增 | payload `{type:0\|1\|2}`,内部走 remap/受控 HAL,不直接写 pin |
|
||||
| `JOG_START` | `JOG_START` | 仅允许合法 axis/joint;XYZAC 的 A/C 速度单位独立校验 |
|
||||
| `HOME` | `HOME` | 返回每个 joint homed 状态和错误 |
|
||||
| `VISMACH_CLEAR` | `VISUAL_CLEAR` | 只清可视化轨迹,不清 task/motion/program |
|
||||
|
||||
### 7.3.1 当前 Web 实现的五轴缺口
|
||||
|
||||
现有通用 AXIS contract 已有大量三轴/通用动作,但对本案例仍有明确缺口,不能把“按钮存在”当成已实现:
|
||||
|
||||
| 缺口 | 当前状态 | 五轴实现要求 |
|
||||
|---|---|---|
|
||||
| `KINEMATICS_SELECT` | `AXIS_COMMANDS` 尚未定义 | 新增受 gate 的 type 0/1/2 命令,禁止前端直接写 HAL |
|
||||
| `POWER` | `axisGate()` 有 `power` 分支,但 `AXIS_COMMANDS` 没有对应 action | 补齐 command map 和 Worker handler,保持 OFF/ESTOP 语义 |
|
||||
| `VISUAL_CLEAR` | 原生 PyVCP 有 `vismach-clear`,通用 Web command 尚未固定 | 作为 visual-only command,不能改 program/motion hash |
|
||||
| A/C jog | 当前 React 示例轴选择主要是 X/Y/Z | 增加 A/C angular units、limits、jog speed 和 joint/teleop gate |
|
||||
| XYZAC pose | `PanelSnapshotV1.visual.pose` 目前是通用 Record | 增加明确 `a/c`、joint vector、kinematics type 和 tool-offset 字段 |
|
||||
| rotation centers | 当前通用 snapshot 没有 TRT rotation-point 完整字段 | 将 x/y/z rotation point、y/z offset 纳入 configuration/authoritative |
|
||||
| switchkins recovery | 通用 recovery 有 task/program,但没有 active kinematics mode | checkpoint 必须保存 type、remap transition、source line、joint/pose hash |
|
||||
|
||||
### 7.4 Worker snapshot 到 React
|
||||
|
||||
```text
|
||||
WASM/native runtime
|
||||
└── task + interpreter + motion + joints + kinematics + HAL + devices
|
||||
│
|
||||
▼
|
||||
protocol.v1 STATE_SNAPSHOT / COMMAND_RESULT
|
||||
│
|
||||
▼
|
||||
store.ts projection()
|
||||
├── axis_state
|
||||
├── gates
|
||||
├── task/program
|
||||
├── motion.axes / motion.joints
|
||||
├── authoritative.planner / authoritative.kinematics
|
||||
└── visual.pose / visual.toolpath
|
||||
│
|
||||
▼
|
||||
React DRO / controls / Three.js Vismach
|
||||
```
|
||||
|
||||
React 控件的 `disabled` 只是 projection;真正 gate 必须在 Worker/runtime 再检查一次。`AxisOperationController` 已提供 operation id、拒绝原因和 trace 结构,五轴切换应复用此机制。
|
||||
|
||||
## 8. Web/WASM 不应直接照搬的部分
|
||||
|
||||
| 原生机制 | Web/WASM 处理 |
|
||||
|---|---|
|
||||
| Tk widget/菜单 | React button/menu/keyboard command,但保留 source control id 和 tooltip 语义 |
|
||||
| LinuxCNC NML | Dedicated Worker protocol envelope + session/seq/operation_id |
|
||||
| HAL pin `motion.switchkins-type` | Worker-owned runtime capability;浏览器不能任意写 HAL pin |
|
||||
| `loadusr -W xyzac-trt-gui` | Worker/Three.js Vismach adapter;visual-only,不是 authority |
|
||||
| `OPEN_FILE` | Worker workspace resolver + exact path/resource closure |
|
||||
| `G-code preview` | WASM canonical interpreter/TP segments;不能用 JS preview 冒充 |
|
||||
| `linuxcnc.stat()` polling | fixed-tick STATE_SNAPSHOT/EVENT,带 state_hash |
|
||||
| M428/M429 remap | WASM remap/interpreter capability,记录切换、错误和首个 divergent tick |
|
||||
| POSIX realtime/HAL hardware | SIM-DEVICE 或 REAL-EXCLUDED,不能静默当成 Web 等价 |
|
||||
|
||||
## 9. 推荐的 Web 端组件拆分
|
||||
|
||||
```text
|
||||
XyzacTrtCaseResolver
|
||||
├── exact ini/hal/remap/resource resolver
|
||||
└── startup diagnostics
|
||||
|
||||
XyzacTrtControlStore
|
||||
├── axis_state / task / interp / homed / limits
|
||||
├── kinematics.active_type
|
||||
├── gates and gate reasons
|
||||
└── command trace
|
||||
|
||||
XyzacTrtOperationController
|
||||
├── PROGRAM_LOAD/RUN/PAUSE/RESUME/ABORT
|
||||
├── MDI M428/M429/M430
|
||||
├── JOG/HOME/override
|
||||
└── transition checks: idle, no fault, valid capability
|
||||
|
||||
XyzacTrtPanel
|
||||
├── mode/task controls
|
||||
├── XYZAC DRO and joint view
|
||||
├── TCP/identity/userk segmented control
|
||||
├── gate-aware MDI/run/jog/home buttons
|
||||
└── alarms and diagnostics
|
||||
|
||||
XyzacTrtVismach
|
||||
├── pose/joints/toolpath from authoritative snapshot
|
||||
├── A/C table rotation
|
||||
├── tool-offset rendering
|
||||
└── canvas/WebGL pixel/interaction checks
|
||||
```
|
||||
|
||||
## 10. 验收和测试矩阵
|
||||
|
||||
### 正常流程
|
||||
|
||||
1. 加载 `xyzac_switchkins.ngc`。
|
||||
2. 验证 `XYZAC` 五个轴和五个 joints 出现在 snapshot。
|
||||
3. 验证 preview segment/source line/hash。
|
||||
4. `M429` → active type 0。
|
||||
5. `M428` → active type 1,等待确认后再允许 TCP 轨迹。
|
||||
6. 运行包含 A/C 变化的 helix;比较 Cartesian pose、joint positions、tool offset。
|
||||
7. `M429` 安全返回;验证 no duplicate segment/no stale active segment。
|
||||
|
||||
### 边界和拒绝
|
||||
|
||||
| 测试 | 期望 |
|
||||
|---|---|
|
||||
| ESTOP 时 M428 | blocked,不改变 kinematics type |
|
||||
| interpreter running 时 M428 | blocked 或排队策略明确,不能隐式切换 |
|
||||
| 缺 `HAL_PIN_VARS=1` | remap 错误码 `M428:Missing...`,保留证据 |
|
||||
| 缺 `motion.switchkins-type` net | `WRONG_SWITCHKINS_TYPE`/source diagnostic |
|
||||
| A/C 超限 | limit/fault snapshot,禁止继续运动 |
|
||||
| tool offset 非有限值 | fail closed,不能送入 kinematics |
|
||||
| pause 后 resume | segment、kinematics type、state hash 连续 |
|
||||
| abort 后 reload | program/task/preview 清理顺序确定 |
|
||||
| Worker restart | checkpoint 恢复 kinematics type、program line、joint/pose hash |
|
||||
| Vismach clear | 只清 visual layer,task/program/state_hash 不变 |
|
||||
|
||||
### 必须保存的证据
|
||||
|
||||
- context id、case path、INI/HAL/remap source hash。
|
||||
- command envelope、operation id、gate result、command result。
|
||||
- 每个固定 tick 的 task/interp/motion/kinematics state hash。
|
||||
- Cartesian pose、XYZAC joint vector、tool offset、active segment/source line。
|
||||
- 首个 divergent tick、错误码、资源缺失分类。
|
||||
- native/WASM/Worker 对照结果;不以单一截图替代。
|
||||
|
||||
## 11. 已知限制
|
||||
|
||||
- 当前 `xyzac-trt.ini` 是 AXIS + PyVCP + 独立 Vismach 的 LinuxCNC 原生案例;Web/WASM 尚未声明其完整五轴 RTCP parity 已完成。
|
||||
- 当前环境使用 POSIX non-realtime;不提供实时硬件周期、延迟和驱动证明。
|
||||
- `xyzac-trt-gui` 只可视化 joint feedback/tool offset;它不是 canonical motion authority。
|
||||
- 官方 kinematics oracle 缺失时,native/WASM 结果只能作为实现证据,不能伪称官方 golden。
|
||||
- `xyzac-trt` 配置中的 `x-rot-point/y-rot-point/z-rot-point` 在示例中固定为 0,且注释说明当前 Vismach GUI 不支持通过 GUI 调整;Web 端必须把它作为配置/能力字段,而不是随意暴露可写 slider。
|
||||
|
||||
## 12. 后续实现顺序
|
||||
|
||||
1. 建立 exact-path `xyzac-trt.ini` resolver 和 resource graph。
|
||||
2. 在 Worker/WASM 建立 additive `kinematics` snapshot 与 `KINEMATICS_SELECT` command。
|
||||
3. 将 M428/M429/M430 的 remap 行为接入固定 tick interpreter,先做拒绝和错误边界。
|
||||
4. 将 XYZAC Cartesian/joint/tool-offset canonical snapshot 接到 Three.js Vismach adapter。
|
||||
5. 实现 gate matrix:ESTOP/OFF/ON/HOME/IDLE/RUNNING/PAUSED/limit/fault。
|
||||
6. 完成 program load/run/pause/resume/abort/restart + RTCP switch recovery 测试。
|
||||
7. 运行 native/Worker/browser 三方对照,并记录首个差异 tick。
|
||||
8. 只有 source/resource/oracle/recovery/浏览器边界均有证据后,才可提升为 selected-case verified;不能从一个 AXIS 截图直接宣称全 LinuxCNC 五轴 parity。
|
||||
572
doc-rtcp/xyzac-trt-web-wasm-implementation-plan.md
Normal file
572
doc-rtcp/xyzac-trt-web-wasm-implementation-plan.md
Normal file
@@ -0,0 +1,572 @@
|
||||
# `xyzac-trt.ini` Web/WASM 控制面板实施计划
|
||||
|
||||
文档状态:实施基线 v1.0
|
||||
|
||||
本计划完全以 [`xyzac-trt-control-panel-web-wasm-design.md`](xyzac-trt-control-panel-web-wasm-design.md) 为设计契约,目标是把以下 LinuxCNC 原生案例的控制面板、数据流和控制流迁移为 Worker/WASM/React/Three.js Web 控制台:
|
||||
|
||||
```text
|
||||
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini
|
||||
```
|
||||
|
||||
它不是 AXIS 的截图复刻计划,而是面向行为、状态、错误、资源、轨迹、RTCP 和恢复结果的 Web-equivalent 实施计划。任何视觉实现都必须服从 Worker/WASM authoritative state。
|
||||
|
||||
“完全对标 LinuxCNC 源码”和“全部功能唯一来自 LinuxCNC WASM”定义为唯一权威合同,强制定义见 [`xyzac-trt-web-wasm-source-parity-contract.md`](xyzac-trt-web-wasm-source-parity-contract.md)。若本计划与该合同冲突,以源码对标合同的禁止项、source slice、WASM authority、first divergent tick 和 parity gate 为准。
|
||||
|
||||
## 1. 目标与不可变约束
|
||||
|
||||
### 1.1 交付目标
|
||||
|
||||
完成一个可在浏览器中运行的 XYZAC 五轴 TRT 控制台,覆盖:
|
||||
|
||||
1. exact-path 案例解析、资源闭包和启动诊断。
|
||||
2. Dedicated Worker 中的 WASM 任务、解释器、TP、motion、XYZAC kinematics、HAL/IO 虚拟设备和固定 tick。
|
||||
3. AXIS 等价的程序、MDI、Manual/Jog、Home、limit、override、spindle、coolant、tool 和 alarm 工作流。
|
||||
4. `M428/M429/M430` switchkins/RTCP 切换、拒绝边界、状态确认和恢复。
|
||||
5. XYZAC Cartesian pose、A/C 姿态、五个 joints、tool offset、rotation/axis offsets 和 canonical toolpath 的 Three.js 可视化。
|
||||
6. protocol.v1 command/result/snapshot/event/stream、operation ledger、checkpoint、Worker 重启和 offline recovery。
|
||||
7. native/Worker/WASM/React/Three.js 之间的确定性 parity 报告、错误样本和首个 divergent tick。
|
||||
|
||||
### 1.2 不可变约束
|
||||
|
||||
| 约束 | 实施要求 |
|
||||
|---|---|
|
||||
| WASM/Worker 权威 | React 不创建第二份 task、motion、kinematics 或 program authority;本地状态只能是 draft/pending |
|
||||
| 固定 tick | 解释器、TP、motion、HAL、IO、kinematics、event、journal 以 logical tick 串行执行,不使用墙钟决定结果 |
|
||||
| exact path | `xyzac-trt.ini` 中的 `HALFILE`、`POSTGUI_HALFILE`、`OPEN_FILE`、`SUBROUTINE_PATH`、`TOOL_TABLE` 和 `PYVCP` 按 exact path 解析,不按 basename 猜文件 |
|
||||
| RTCP 原语 | `M428/M429/M430` 必须保留 remap 语义和 `motion.switchkins-type` 的确认,禁止前端直接写一个近似值 |
|
||||
| 一致 gate | UI gate 只是 projection;Worker/runtime 必须再次检查 ESTOP/OFF/ON/HOME/IDLE/RUNNING/PAUSED/limit/fault/kinematics 条件 |
|
||||
| 轨迹权威 | 预览和 Three.js 使用 canonical WASM trajectory/pose/joints;JS 不能重算 RTCP 结果冒充通过 |
|
||||
| 单写者 | 一个 session 只有一个 Worker 写入 task/WASM/OPFS journal;多标签页只能观察或持有租约 |
|
||||
| 幂等恢复 | 每个副作用命令有 operation id、ledger prepare/commit 和结果重查;超时不能盲目重发 |
|
||||
| 能力拒绝 | 宿主路径、shell、真实硬件、socket、动态库和未授权 Python/HAL 能力稳定返回拒绝码 |
|
||||
| 发布边界 | 没有官方 oracle、真实硬件、Safari/Firefox、OPFS crash 或许可证输入时保持 blocked,不升级为全 LinuxCNC parity |
|
||||
|
||||
## 2. 设计契约追溯
|
||||
|
||||
| 设计文档章节 | 本计划对应实施面 |
|
||||
|---|---|
|
||||
| §1 范围与版本边界 | `RTCP-00` source/runtime/version lock |
|
||||
| §2 总体架构 | `RTCP-01` Worker topology、authority boundary |
|
||||
| §3 启动与初始化 | `RTCP-02` exact case resolver/startup state machine |
|
||||
| §4 AXIS 主控制面板 | `RTCP-05` UI domain、controls、status projection |
|
||||
| §5 G-code 加载流 | `RTCP-04` PROGRAM_LOAD/preview/program ledger |
|
||||
| §6 AUTO 运行流 | `RTCP-06` run/pause/resume/step/abort/restart |
|
||||
| §7 MDI/Jog/Home/Tool/Offset | `RTCP-07` manual and device workflows |
|
||||
| §8 SWITCHKINS/RTCP | `RTCP-08` M428/M429/M430/XYZAC kinematics |
|
||||
| §9 状态真值 | `RTCP-03` snapshot/axis_state/gates |
|
||||
| §10 Web/WASM mapping | `RTCP-09` protocol and frontend integration |
|
||||
| §11 测试与限制 | `RTCP-10` parity/recovery/browser gates |
|
||||
|
||||
## 3. 功能范围矩阵
|
||||
|
||||
### 3.1 P0:必须先闭合的主链
|
||||
|
||||
| ID | 功能 | 原生来源/对照 | Web 结果 |
|
||||
|---|---|---|---|
|
||||
| P0-01 | 案例选择与启动 | `xyzac-trt.ini`、`run-5axis-rtcp.sh` | `TASK_READY` 或可定位 `BLOCKED_*` |
|
||||
| P0-02 | 配置/资源图 | INI/HAL/XML/TBL/VAR/NGC/remap | exact path、source hash、missing edge |
|
||||
| P0-03 | Task/ESTOP/OFF/ON | AXIS `stat.task_state` | axis_state + gate matrix |
|
||||
| P0-04 | Mode MANUAL/MDI/AUTO | AXIS `ensure_mode`、`on_hal_status_mode_auto` | state transition + command result |
|
||||
| P0-05 | Program load/open | AXIS `open_file_guts`、`c.program_open` | program hash、line count、preview |
|
||||
| P0-06 | Canonical preview | AXIS canon/preview | stable segments/source lines |
|
||||
| P0-07 | Program run | AXIS `task_run` | RUNNING、tick、active line |
|
||||
| P0-08 | Pause/resume/step | AXIS `task_pause/resume/step` | PAUSED/RESUMED/step endpoint |
|
||||
| P0-09 | Abort/restart | AXIS `task_stop/reload` | STOPPED/loaded、no duplicate side effect |
|
||||
| P0-10 | MDI | AXIS `send_mdi_command` | parser result、queue gate、error |
|
||||
| P0-11 | XYZAC kinematics | `xyzac-trt-kins.c`、`trtfuncs.c` | forward/inverse pose/joints |
|
||||
| P0-12 | M428/M429/M430 | `428remap.ngc`、`429remap.ngc`、HAL net | active type + verified transition |
|
||||
| P0-13 | Vismach pose/joints | `xyzac-trt-gui.py` | Three.js pose/joints/toolpath |
|
||||
|
||||
### 3.2 P1:操作完整性
|
||||
|
||||
| ID | 功能 | 关键边界 |
|
||||
|---|---|---|
|
||||
| P1-01 | XYZAC jog | X/Y/Z linear units,A/C angular units,按下/释放 stop |
|
||||
| P1-02 | Home/unhome | 五 joint homing、共享开关、home sequence、重复 homing |
|
||||
| P1-03 | Soft/hard limits | limit active、override limit、following error |
|
||||
| P1-04 | Feed/rapid/spindle override | 范围、非有限值、暂停/ESTOP |
|
||||
| P1-05 | Spindle/coolant | command/actual/at-speed、冷却状态、fault |
|
||||
| P1-06 | Tool table/offset | `xyzac-trt.tbl`、tool offset、G43/G49/G43.1 |
|
||||
| P1-07 | HAL/PyVCP | `type0/1/2-button`、legend、vismach-clear、HAL read |
|
||||
| P1-08 | Alarm/event timeline | source、severity、operation id、acknowledge |
|
||||
| P1-09 | Configuration diagnostics | startup/resource/HAL/remap errors |
|
||||
|
||||
### 3.3 P2:交付和恢复完整性
|
||||
|
||||
| ID | 功能 | 退出要求 |
|
||||
|---|---|---|
|
||||
| P2-01 | Checkpoint/journal | tick、program line、kinematics type、pose/joints、hash 可恢复 |
|
||||
| P2-02 | Worker restart | 无重复 M428/M429、无重复 segment/IO/tool side effect |
|
||||
| P2-03 | Offline project | 缓存资源、OPFS journal、配额和冲突可诊断 |
|
||||
| P2-04 | Stream/backpressure | trajectory/HAL/log drop 有 cursor/gap/最终快照 |
|
||||
| P2-05 | Browser matrix | Chromium/Firefox/Safari 逐项证据;缺环境保持 blocked |
|
||||
| P2-06 | Native/WASM parity | normal/boundary/error/recovery + deterministic self-hash |
|
||||
|
||||
## 4. 目标架构
|
||||
|
||||
```text
|
||||
React/Web UI
|
||||
├── XyzacCaseView / ProgramView / ManualView / RtccpView / DiagnosticsView
|
||||
├── Domain store: task/program/motion/kinematics/hal/devices/recovery
|
||||
├── Pure gate selectors and source control IDs
|
||||
└── WorkerClient only
|
||||
│ protocol.v1 MessageEnvelope
|
||||
▼
|
||||
Dedicated sim.worker
|
||||
├── ProtocolGateway + runtime schema validator
|
||||
├── Session/Liveness/Lease manager
|
||||
├── CommandLedger (prepare/ack/result/commit/reconcile)
|
||||
├── XyzacCaseResolver + resource graph
|
||||
├── SimScheduler (fixed logical tick)
|
||||
├── WASM LinuxCncCompat
|
||||
│ ├── Task/RS274/TP/Motion
|
||||
│ ├── xyzac-trt forward/inverse
|
||||
│ ├── remap M428/M429/M430
|
||||
│ └── HAL/IO/tool/probe virtual devices
|
||||
├── SnapshotPublisher + StateHash
|
||||
├── OPFS journal/checkpoint/recovery
|
||||
└── trajectory/HAL/log stream backpressure
|
||||
│ authoritative snapshots/events
|
||||
▼
|
||||
React projection + Three.js XYZAC Vismach adapter
|
||||
```
|
||||
|
||||
### 4.1 Authority ownership
|
||||
|
||||
| 数据 | 唯一 authority | React 是否可写 |
|
||||
|---|---|---:|
|
||||
| task state/mode/interp | WASM Task/Interpreter | 否 |
|
||||
| program parsed state/line | WASM Interpreter/Task | 否 |
|
||||
| TP queue/active segment | WASM TP | 否 |
|
||||
| Cartesian pose/XYZAC joints | WASM Kinematics/Motion | 否 |
|
||||
| switchkins type | WASM/HAL compatibility layer | 只能发请求 |
|
||||
| homed/limit/following error | WASM Motion/Home/HAL | 否 |
|
||||
| tool/offset/spindle/coolant | virtual IO/tool runtime | 只能发命令 |
|
||||
| UI draft/selection | React local store | 是,但不等于运行态 |
|
||||
| Three.js camera/layer toggle | React/renderer | 是,不影响 motion |
|
||||
|
||||
## 5. 实施任务队列
|
||||
|
||||
任务状态使用:`queued → in_progress → verified` 或 `in_progress → blocked`。每个任务完成时必须生成报告、自哈希、输入哈希、命令记录、错误边界和下一任务依赖。
|
||||
|
||||
### RTCP-00:源码、版本和案例锁定
|
||||
|
||||
**目标**:冻结 `xyzac-trt.ini`、所有引用资源、系统运行时和 source symbol 映射。
|
||||
|
||||
**直接输入**:
|
||||
|
||||
- `xyzac-trt.ini`
|
||||
- `xyzac-trt.xml`
|
||||
- `switchkins_postgui.hal`
|
||||
- `demos/*.ngc`
|
||||
- `remap_subs/*.ngc`
|
||||
- `xyzac-trt-kins.c`、`trtfuncs.c`
|
||||
- `xyzac-trt-gui.py`
|
||||
- `context-lock.json`
|
||||
|
||||
**产物**:
|
||||
|
||||
- `coverage/xyzac-trt-web-source-lock.report.json`
|
||||
- `web/workspace/xyzac-trt-source-contract.mjs`
|
||||
- exact resource graph、source hash、runtime version record
|
||||
|
||||
**验收**:每个 INI path、HAL edge、PyVCP pin、remap、G-code 入口可追溯;缺失资源为明确 blocker。
|
||||
|
||||
### RTCP-01:Worker 拓扑和 LinuxCncCompat 外壳
|
||||
|
||||
**目标**:建立单 Worker/session/ledger/scheduler 边界,不实现五轴细节。
|
||||
|
||||
**产物**:
|
||||
|
||||
- `web/worker/xyzac-session.mjs`
|
||||
- `web/worker/xyzac-scheduler.mjs`
|
||||
- `web/worker/xyzac-command-ledger.mjs`
|
||||
- `web/worker/test_xyzac_session.mjs`
|
||||
|
||||
**验收**:HELLO/CAPABILITIES/SESSION_ATTACH/SESSION_READY、seq、operation_id、取消、超时重查和重复命令测试通过;Worker 之外不能写 runtime。
|
||||
|
||||
### RTCP-02:Exact case resolver 和启动状态机
|
||||
|
||||
**目标**:把 `xyzac-trt.ini` 解析到 `TASK_NEW → CONFIG_RESOLVED → HAL_READY → RUNTIME_READY → TASK_READY`。
|
||||
|
||||
**要求**:
|
||||
|
||||
- 解析 `DISPLAY/TASK/HAL/RS274NGC/KINS/TRAJ/EMCIO`。
|
||||
- 解析 `LIB:basic_sim.tcl` 的虚拟 HAL 边界。
|
||||
- exact resolve `OPEN_FILE`、`SUBROUTINE_PATH`、`xyzac-trt.tbl`、`xyzac.var`、`xyzac-trt.xml` 和 `xyzac-trt-gui.py`。
|
||||
- 识别 `BLOCKED_RESOURCE`、`BLOCKED_HAL`、`BLOCKED_INI`、`BLOCKED_STARTUP`。
|
||||
|
||||
**产物**:`web/workspace/xyzac-trt-case-loader.mjs`、startup snapshot、diagnostic report。
|
||||
|
||||
### RTCP-03:Authoritative snapshot、axis_state 和 gate matrix
|
||||
|
||||
**目标**:将 native task/motion/interp/home/limit/kinematics 状态统一为 Worker snapshot。
|
||||
|
||||
**产物**:
|
||||
|
||||
- additive `axis_state`
|
||||
- `kinematics.active_type`
|
||||
- `configuration.coordinates/joints/topology`
|
||||
- `gates`(action/enabled/reason)
|
||||
- `web/worker/test_xyzac_gate_matrix.mjs`
|
||||
|
||||
**验收**:ESTOP/OFF/ON/HOME/IDLE/RUNNING/PAUSED、limit/fault/tool/no-file/no-highlight 每项都有 gate reason 和状态哈希。
|
||||
|
||||
### RTCP-04:程序加载、canonical preview 和 program ledger
|
||||
|
||||
**目标**:实现 AXIS `open_file_guts → program_open → canon/preview → stat.file` 的 Worker/WASM 等价流程。
|
||||
|
||||
**要求**:
|
||||
|
||||
- source/path/hash/line count 固化。
|
||||
- preview segment 带 id/source_line/start/end/motion_type/center/normal/turn。
|
||||
- 解析错误、超限、非有限值、空文件和缺资源 fail closed。
|
||||
- load/reload/restart 与 ledger/recovery 可重放。
|
||||
|
||||
**验收**:native 与 Worker 首个 segment、line count、preview hash、loaded file、invalid G-code 错误码一致。
|
||||
|
||||
### RTCP-05:程序运行控制和 AXIS workflow
|
||||
|
||||
**目标**:覆盖 Run/Pause/Resume/Step/Abort/Restart/Run-from-line。
|
||||
|
||||
**按钮约束**:
|
||||
|
||||
```text
|
||||
RUN = machine_on && interp_idle && task_file
|
||||
PAUSE = machine_on && interp_reading_or_waiting
|
||||
RESUME = machine_on && interp_paused
|
||||
STEP = machine_on && task_file
|
||||
ABORT = machine_on && interp_running
|
||||
RESTART = machine_on && interp_idle && task_file
|
||||
RUN_LINE = RUN && highlight_line != null
|
||||
```
|
||||
|
||||
**验收**:固定 tick 下 pause/resume 不重复 segment,abort 无重复副作用,restart 重置 program state 但保留正确 source hash。
|
||||
|
||||
### RTCP-06:MDI、Jog、Home 和 limit
|
||||
|
||||
**目标**:实现 XYZAC 手动控制。
|
||||
|
||||
**要求**:
|
||||
|
||||
- X/Y/Z 线性单位和 A/C 角度单位分离。
|
||||
- pointerdown/keydown 只发一个 JOG_START;pointerup/keyup/blur/visibilitychange 必须发 JOG_STOP。
|
||||
- MDI queue limit、running/paused/ESTOP gate 与 native 一致。
|
||||
- home all、单 joint home、unhome、共享 home switch 和 limit override。
|
||||
- following error、非有限速度、超范围轴拒绝。
|
||||
|
||||
**验收**:每个 X/Y/Z/A/C 轴有 normal/boundary/stop/fault/recovery 样本;A/C 不得被当作 linear mm。
|
||||
|
||||
### RTCP-07:HAL、PyVCP、tool、spindle、coolant 和 alarm
|
||||
|
||||
**目标**:把 `xyzac-trt.xml` 和 `switchkins_postgui.hal` 中的控件接入 Worker capability。
|
||||
|
||||
**功能**:
|
||||
|
||||
- type0/type1/type2 button 状态和 `kinstype.is-*` legend。
|
||||
- `vismach-clear` 只清 visual plot。
|
||||
- tool table、tool offset、G43/G49/G43.1、tool prepare/change。
|
||||
- spindle command/actual/at-speed/direction、coolant、manual tool change。
|
||||
- HAL pin read/write 白名单、类型和权限。
|
||||
- alarm/event timeline、acknowledge、source file/line。
|
||||
|
||||
**验收**:HAL command 不能越权写任意 pin;tool/IO ack、timeout、abort、recovery 和 `REAL-EXCLUDED` 分类都有报告。
|
||||
|
||||
### RTCP-08:XYZAC kinematics 和 RTCP
|
||||
|
||||
**目标**:实现 `xyzac-trt-kins` 的 forward/inverse、tool offset、rotation/axis offset 和 switchkins。
|
||||
|
||||
**阶段拆分**:
|
||||
|
||||
1. K0:XYZAC 坐标/joint mapping、单位、limits、finite-value 校验。
|
||||
2. K1:identity type 0,forward/inverse identity golden。
|
||||
3. K2:TRT type 1,`trtKinematicsSetup`、XYZAC forward/inverse、`y-offset/z-offset`、tool-offset。
|
||||
4. K3:userk type 2 capability boundary;无 userk 时稳定拒绝。
|
||||
5. K4:M428/M429/M430 remap 与 `motion.switchkins-type` handshake。
|
||||
6. K5:helix_ac/helix_bc、姿态变化、G93/arc、奇异/限位/非有限值。
|
||||
7. K6:pause/resume/abort/restart/recovery 时 active kinematics type 和 pose/joints 保持一致。
|
||||
|
||||
**必须保存**:Cartesian pose、XYZAC joints、A/C angle、tool offset、rotation point、axis offsets、kinematics type、首个 divergent tick、state hash。
|
||||
|
||||
### RTCP-09:Protocol v1 和 React 控制台
|
||||
|
||||
**目标**:把现有 `axis-contract.mjs`、`AxisOperationController`、`PanelSnapshotV1` 扩展到 XYZAC。
|
||||
|
||||
**产物**:
|
||||
|
||||
- `KINEMATICS_SELECT`、`VISUAL_CLEAR`、`POWER` 等 additive commands。
|
||||
- `xyzac-panel-snapshot.v1` additive view 或兼容扩展。
|
||||
- React `XyzacTrtPanel`、`XyzacProgramPane`、`XyzacKinematicsControl`、`XyzacManualPanel`、`XyzacDiagnostics`。
|
||||
- gate-aware controls、operation trace、alarm/recovery view。
|
||||
|
||||
**验收**:React 不直接调用 WASM/OPFS;所有 controls 只通过 WorkerClient;gate reason、pending、ack、result、error 状态可见。
|
||||
|
||||
### RTCP-10:Three.js XYZAC Vismach adapter
|
||||
|
||||
**目标**:使用 authoritative `visual.pose/joints/toolpath` 实现五轴模型。
|
||||
|
||||
**要求**:
|
||||
|
||||
- 机床结构对应 `xyzac-trt-gui.py`:table-x、saddle-y、spindle-z、tilt-a、rotate-c、tool-offset。
|
||||
- pose/joints 与 toolpath 来自同一 `state_hash`/tick。
|
||||
- camera/layer/clear 不改变 task/motion/program。
|
||||
- canvas nonblank、A/C 旋转方向、tool offset、轨迹 active segment 和 resize/mobile 通过。
|
||||
|
||||
### RTCP-11:Journal、checkpoint、Worker restart 和 offline recovery
|
||||
|
||||
**目标**:恢复完整 XYZAC 运行态。
|
||||
|
||||
**checkpoint 最小字段**:
|
||||
|
||||
```text
|
||||
context_id, case_id, source_hashes
|
||||
simulation_tick, seq, state_hash
|
||||
task_state, task_mode, interp_state, program_hash, current_line
|
||||
kinematics_type, kinematics_transition, pose, joints
|
||||
tool_offset, y_offset, z_offset, rotation_points
|
||||
TP queue/active segment, HAL/IO/tool pending commands
|
||||
```
|
||||
|
||||
**验收**:
|
||||
|
||||
- M428 在 checkpoint 前后不重复执行。
|
||||
- 暂停程序恢复不重复 segment。
|
||||
- tool/spindle/coolant/IO side effect 不重复。
|
||||
- 损坏 checkpoint、缺资源、schema mismatch fail closed。
|
||||
- Worker 重启后 endpoint pose/joints/program/kinematics/state hash 一致。
|
||||
|
||||
### RTCP-12:Native/Worker/Browser parity 和验收闭环
|
||||
|
||||
**目标**:形成 selected-case parity report,不冒充全 LinuxCNC release。
|
||||
|
||||
**矩阵**:
|
||||
|
||||
- Chromium desktop/mobile。
|
||||
- Firefox/Safari 可用时运行;不可用保留 `HOST_EXCLUDED`/`blocked`。
|
||||
- native AXIS + xyzac-trt-gui。
|
||||
- Worker/WASM + React + Three.js。
|
||||
- normal/boundary/error/limit/pause/abort/restart/recovery。
|
||||
|
||||
**产物**:
|
||||
|
||||
- `coverage/xyzac-trt-web-wasm-parity.report.json`
|
||||
- native/worker command golden
|
||||
- snapshot/trajectory/kinematics self-hash
|
||||
- failure samples and first divergence report
|
||||
|
||||
## 6. 里程碑设计
|
||||
|
||||
### M0:Source and Case Contract
|
||||
|
||||
**包含**:RTCP-00。
|
||||
|
||||
**退出条件**:
|
||||
|
||||
- 所有直接引用资源均 exact-path indexed(不以抽样替代)。
|
||||
- `xyzac-trt.ini` 的 INI/HAL/NGC/XML/Python/C source graph 自哈希稳定。
|
||||
- 版本、context、运行时和能力边界记录完成。
|
||||
- 缺失/未索引/宿主资源明确 blocked。
|
||||
|
||||
### M1:Worker Startup and State Authority
|
||||
|
||||
**包含**:RTCP-01、RTCP-02、RTCP-03。
|
||||
|
||||
**退出条件**:
|
||||
|
||||
- Worker session handshake、TASK_READY、CAPABILITIES 通过。
|
||||
- snapshot 包含 task/motion/home/limit/program/kinematics/gates/configuration。
|
||||
- ESTOP/OFF/ON/HOME/IDLE gate matrix 和 deterministic state hash 通过。
|
||||
- React 尚未接入前,Worker 测试可独立验证 authority。
|
||||
|
||||
### M2:Program and AXIS Operation Workflow
|
||||
|
||||
**包含**:RTCP-04、RTCP-05、RTCP-06。
|
||||
|
||||
**退出条件**:
|
||||
|
||||
- load/preview/run/pause/resume/step/abort/restart/MDI/jog/home 全部有 native/Worker 对照。
|
||||
- 每个操作的 gate reason、operation id、command result 和 state hash 可追溯。
|
||||
- running/paused/ESTOP/limit/tool missing 的拒绝不被 UI 绕过。
|
||||
|
||||
### M3:HAL/IO/PyVCP and Device Closure
|
||||
|
||||
**包含**:RTCP-07。
|
||||
|
||||
**退出条件**:
|
||||
|
||||
- SWITCHKINS PyVCP 三个按钮和 vismach-clear 的 HAL 图可解析。
|
||||
- spindle/coolant/tool/probe/hal read/write/ack/error 边界通过。
|
||||
- 未授权 pin、外部进程、真实硬件被稳定拒绝。
|
||||
|
||||
### M4:XYZAC Kinematics and RTCP
|
||||
|
||||
**包含**:RTCP-08。
|
||||
|
||||
**退出条件**:
|
||||
|
||||
- type 0/1/2 切换和 M428/M429/M430 handshake 与 native 一致。
|
||||
- XYZAC pose/joints/tool offset/axis offset/rotation point 的 forward/inverse golden 通过。
|
||||
- helix/姿态变化、奇异、limits、non-finite、pause/abort/recovery 样本齐全。
|
||||
- 首个 divergent tick 可定位;没有 JS kinematics fallback。
|
||||
|
||||
### M5:React/Protocol/Three.js Console
|
||||
|
||||
**包含**:RTCP-09、RTCP-10。
|
||||
|
||||
**退出条件**:
|
||||
|
||||
- React 所有按钮只通过 WorkerClient/OperationController。
|
||||
- Three.js 使用 authoritative snapshot,A/C 方向、tool offset 和 active segment 正确。
|
||||
- desktop/mobile DOM、canvas nonblank、keyboard/touch、错误/pending/gate UI 通过。
|
||||
|
||||
### M6:Recovery and Offline Runtime
|
||||
|
||||
**包含**:RTCP-11。
|
||||
|
||||
**退出条件**:
|
||||
|
||||
- checkpoint/restart/reconcile/replay 无重复副作用。
|
||||
- OPFS journal、配额、schema mismatch、坏数据和离线重新打开可诊断。
|
||||
- recovery endpoint state hash 与连续运行一致。
|
||||
|
||||
### M7:Selected-Case Parity Acceptance
|
||||
|
||||
**包含**:RTCP-12。
|
||||
|
||||
**退出条件**:
|
||||
|
||||
- native/Worker/WASM/React/Three.js 的选定案例完整矩阵通过。
|
||||
- 结果报告有 source/input/output hash、命令、状态、首个差异 tick 和失败样本。
|
||||
- Chromium/Firefox/Safari、官方 oracle、实时硬件、OPFS crash 和许可证边界按真实环境记录。
|
||||
- 只能声明 `selected_case_verified`;任何外部 blocker 存在时保持 `STOP_RELEASE`。
|
||||
|
||||
## 7. 任务依赖图
|
||||
|
||||
```text
|
||||
RTCP-00 source lock
|
||||
│
|
||||
▼
|
||||
RTCP-01 session/ledger ── RTCP-02 case startup ── RTCP-03 snapshot/gates
|
||||
│ │ │
|
||||
└─────────────────────────┴──────────────────────┘
|
||||
▼
|
||||
RTCP-04 program/preview
|
||||
│
|
||||
┌──────────────┴──────────────┐
|
||||
▼ ▼
|
||||
RTCP-05 run/control RTCP-06 manual
|
||||
│ │
|
||||
└──────────────┬──────────────┘
|
||||
▼
|
||||
RTCP-07 HAL/IO/PyVCP
|
||||
│
|
||||
▼
|
||||
RTCP-08 XYZAC/RTCP
|
||||
│
|
||||
┌───────────┴───────────┐
|
||||
▼ ▼
|
||||
RTCP-09 React/protocol RTCP-10 Three.js
|
||||
│ │
|
||||
└───────────┬───────────┘
|
||||
▼
|
||||
RTCP-11 recovery
|
||||
│
|
||||
▼
|
||||
RTCP-12 parity gate
|
||||
```
|
||||
|
||||
不得跳过 RTCP-03 的 authority/gate、RTCP-04 的 canonical program 或 RTCP-08 的 kinematics 就先做“漂亮界面”。
|
||||
|
||||
## 8. 统一任务报告格式
|
||||
|
||||
每个 `RTCP-*` 任务必须生成 JSON 报告,至少包含:
|
||||
|
||||
```json
|
||||
{
|
||||
"schema": "xyzac-trt-web-wasm-task-report.v1",
|
||||
"task_id": "RTCP-08",
|
||||
"milestone": "M4",
|
||||
"status": "verified",
|
||||
"context_id": "...",
|
||||
"case_path": ".../xyzac-trt.ini",
|
||||
"inputs": [{"path": "...", "sha256": "..."}],
|
||||
"outputs": [{"path": "...", "sha256": "..."}],
|
||||
"commands": [{"name": "...", "status": "passed", "stdout_sha256": "..."}],
|
||||
"normal": {},
|
||||
"boundaries": [],
|
||||
"errors": [],
|
||||
"first_divergent_tick": null,
|
||||
"known_blockers": [],
|
||||
"report_sha256": "..."
|
||||
}
|
||||
```
|
||||
|
||||
失败样本必须保留,不得删除失败、降低 gate、把资源缺失改成通过或用 JS preview/姿态镜像冒充 native/WASM parity。
|
||||
|
||||
## 9. 最低测试命令集合
|
||||
|
||||
任务开发期间按范围运行:
|
||||
|
||||
```bash
|
||||
python3 scripts/validate_baseline.py
|
||||
python3 scripts/validate_download_index.py
|
||||
python3 scripts/validate_task_pointer.py nextTask1.md --lock context-lock.json
|
||||
scripts/build-wasm.sh
|
||||
ctest --test-dir build-native --output-on-failure
|
||||
```
|
||||
|
||||
五轴专属命令:
|
||||
|
||||
```bash
|
||||
./run-5axis-rtcp.sh
|
||||
./run-5axis-rtcp.sh xyzbc-trt.ini
|
||||
node web/worker/test_xyzac_trt_case.mjs
|
||||
node web/worker/test_xyzac_program.mjs
|
||||
node web/worker/test_xyzac_switchkins.mjs
|
||||
node web/worker/test_xyzac_rtcp.mjs
|
||||
node web/worker/test_xyzac_recovery.mjs
|
||||
npm --prefix web/react run typecheck
|
||||
npm --prefix web/react run build
|
||||
```
|
||||
|
||||
命令名称在对应任务开始前必须实际创建并纳入报告;不存在的测试命令不能写成已通过。
|
||||
|
||||
## 10. 停止条件和阻塞处理
|
||||
|
||||
以下任一情况必须将当前任务标记为 blocked,并保留证据:
|
||||
|
||||
- `xyzac-trt.ini` 的 source/resource/hal/remap graph 不完整。
|
||||
- native 运行时版本、锁定 source 或 ABI/protocol/schema 不一致。
|
||||
- M428/M429 状态切换没有确认、重复执行或首个差异 tick 未定位。
|
||||
- A/C 角度、tool offset、rotation point、joint pose 由 JS/React 生成。
|
||||
- ESTOP、limit、following error、pause、abort、recovery 语义不可解释。
|
||||
- 真实 HAL、动态 loader、宿主 Python、外部进程或真实硬件被错误标记为 Web-equivalent。
|
||||
- Worker 重启造成重复 G-code、重复 tool/IO side effect 或 checkpoint hash 不一致。
|
||||
- 只有 Chromium 截图而缺 Firefox/Safari/OPFS/oracle 证据,却要求全量 release。
|
||||
- 缺少 owner/source/oracle/resource/browser/license 外部输入。
|
||||
|
||||
阻塞转移规则:
|
||||
|
||||
```text
|
||||
技术缺陷 → 保留最小复现/错误码/首个 divergent tick → 修复同一任务
|
||||
源码/ABI/protocol/schema 输入缺失 → SOURCE_BLOCKED → 等待审查输入
|
||||
宿主/浏览器/硬件缺失 → HOST_EXCLUDED 或 REAL-EXCLUDED → 不伪造通过
|
||||
发布/owner 决策缺失 → STOP_RELEASE → 不自动刷新 gate
|
||||
```
|
||||
|
||||
## 11. 里程碑交付顺序
|
||||
|
||||
后续实施按以下顺序推进,不能在任务依赖未 verified 时跳级:
|
||||
|
||||
```text
|
||||
M0 Source/Case Contract
|
||||
→ M1 Worker Startup/Authority
|
||||
→ M2 Program/AXIS Workflow
|
||||
→ M3 HAL/IO/PyVCP
|
||||
→ M4 XYZAC/RTCP Kinematics
|
||||
→ M5 React/Protocol/Three.js
|
||||
→ M6 Recovery/Offline
|
||||
→ M7 Selected-Case Parity
|
||||
```
|
||||
|
||||
每个里程碑完成后生成独立报告和自哈希,并将下一里程碑的直接输入、完成门禁、外部 blocker 和停止边界写入任务记录。完成单元测试或界面截图不等于该里程碑完成;必须同时满足 authority、数据流、控制流、错误、恢复和确定性要求。
|
||||
440
doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md
Normal file
440
doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md
Normal file
@@ -0,0 +1,440 @@
|
||||
# XYZAC TRT Web/WASM 源码对标与唯一权威合同
|
||||
|
||||
文档状态:强制实施合同 v1.0
|
||||
|
||||
本合同是 [`xyzac-trt-web-wasm-implementation-plan.md`](xyzac-trt-web-wasm-implementation-plan.md) 的约束性补充。它回答一个更严格的问题:Web 控制面板如何证明自己是 LinuxCNC 源码行为的 Web/WASM 等价实现,并且所有控制功能唯一来自 LinuxCNC WASM,而不是来自 React、浏览器状态或第二套 JavaScript 运动模型。
|
||||
|
||||
适用案例:
|
||||
|
||||
```text
|
||||
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini
|
||||
```
|
||||
|
||||
## 1. 强制结论
|
||||
|
||||
### 1.1 唯一权威
|
||||
|
||||
以下数据只能由 LinuxCNC WASM runtime 产生;React、TypeScript、Three.js、Worker UI adapter 和浏览器不能自行生成“看起来合理”的替代值:
|
||||
|
||||
- task state、task mode、interpreter state、current line、queued MDI。
|
||||
- program parse state、canonical events、trajectory queue、active segment。
|
||||
- Cartesian pose、X/Y/Z/A/C 轴位置、五个 joint 位置、速度、加速度和 limits。
|
||||
- XYZAC forward/inverse kinematics、switchkins type、TCP/RTCP tool compensation。
|
||||
- tool table、tool offset、G43/G49/G43.1、spindle、coolant、probe、home、limit、following error。
|
||||
- HAL pin/signal/parameter 读值、PyVCP state、IO ack、报警、错误和恢复结果。
|
||||
- checkpoint、journal、replay、recovery endpoint 和 state hash。
|
||||
|
||||
前端可以拥有以下本地状态,但必须明确标记为非权威:
|
||||
|
||||
- 编辑器 draft、搜索词、文件选择、当前 tab、camera、图层显示、窗口尺寸、pending operation。
|
||||
- 尚未提交的配置表单、UI 偏好和输入法状态。
|
||||
|
||||
### 1.2 严禁的替代 authority
|
||||
|
||||
下列行为一律视为实现失败:
|
||||
|
||||
1. React 根据按钮点击直接把 task/mode/position/kinematics 写成目标状态。
|
||||
2. JS 根据 A/C 角度和 tool length 自行计算 X/Y/Z 补偿并展示为实际 pose。
|
||||
3. JS G-code preview、Three.js preview 或 canvas 轨迹被当作 canonical motion。
|
||||
4. UI 通过 `setTimeout`、墙钟、`requestAnimationFrame` 或点击次数推进仿真 tick。
|
||||
5. 浏览器直接访问 WASM 指针、导出内部内存、写 OPFS journal 或调用宿主 LinuxCNC。
|
||||
6. 前端绕过 Worker gateway 直接发送 HAL pin 写入、M428/M429 或模拟 IO 副作用。
|
||||
7. 收不到 `COMMAND_RESULT` 时把 pending 命令当作成功,或超时后无 ledger reconcile 直接重发。
|
||||
8. 把 native/AXIS 行为复制成新的 JS 状态机,再用 WASM 只做最终演示。
|
||||
9. 以截图、按钮存在、模块测试或“曲线看起来一样”宣称完整五轴 parity。
|
||||
10. 把 HOST_BOUNDARY、REAL-EXCLUDED、SOURCE_BLOCKED 或缺少官方 oracle 的结果改写为 verified。
|
||||
|
||||
## 2. 对标单位:source behavior slice
|
||||
|
||||
对标的最小单位不是“页面”或“组件”,而是 source behavior slice:
|
||||
|
||||
```text
|
||||
source symbol/control
|
||||
→ input/event/command
|
||||
→ native state gate
|
||||
→ LinuxCNC canonical result
|
||||
→ status/event/visual output
|
||||
→ error/abort/recovery behavior
|
||||
```
|
||||
|
||||
每个 slice 必须有唯一 `slice_id`。示例:
|
||||
|
||||
```text
|
||||
AXIS-XYZAC-AUTO-RUN
|
||||
AXIS-XYZAC-M428-TCP
|
||||
AXIS-XYZAC-JOG-C
|
||||
AXIS-XYZAC-HOME-JOINT-3
|
||||
AXIS-XYZAC-LOAD-PROGRAM
|
||||
AXIS-XYZAC-VISMACH-POSE
|
||||
```
|
||||
|
||||
### 2.1 Slice manifest 必填字段
|
||||
|
||||
```json
|
||||
{
|
||||
"slice_id": "AXIS-XYZAC-M428-TCP",
|
||||
"source": {
|
||||
"path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
|
||||
"symbols": ["428remap"],
|
||||
"lines": "1-24",
|
||||
"sha256": "..."
|
||||
},
|
||||
"inputs": ["MDI_EXECUTE:M428", "task_state", "motion.switchkins-type"],
|
||||
"native_commands": ["M68 E3 Q1", "M66 E0 L0"],
|
||||
"wasm_commands": ["MDI_EXECUTE", "KINEMATICS_SELECT"],
|
||||
"authoritative_outputs": ["kinematics.active_type", "state_hash"],
|
||||
"ui_controls": ["AXIS-RTCP-TCP-XYZAC"],
|
||||
"gates": ["interp_idle", "hal_pin_present", "switchkins_net_present"],
|
||||
"normal_cases": [],
|
||||
"boundary_cases": [],
|
||||
"error_cases": [],
|
||||
"recovery_cases": [],
|
||||
"status": "queued"
|
||||
}
|
||||
```
|
||||
|
||||
没有 source path、symbol、输入、native command、WASM command、输出、gate 和测试的功能,不得进入“实现完成”统计。
|
||||
|
||||
## 3. 源码到 WASM 的闭合分层
|
||||
|
||||
### 3.1 Source inventory 层
|
||||
|
||||
必须锁定并哈希以下来源:
|
||||
|
||||
| 层 | 来源 |
|
||||
|---|---|
|
||||
| AXIS controls | `linuxcnc/share/axis/tcl/axis.tcl`、`support.tcl`、`accel.tcl`、`dialog.tcl`、`combobox.tcl`、`sb.tcl` |
|
||||
| AXIS Python | `linuxcnc/src/emc/usr_intf/axis/scripts/axis.py` |
|
||||
| Preview/canon | `linuxcnc/lib/python/rs274/glcanon.py`、`gremlin.py`、`vismach.py` |
|
||||
| Case config | `xyzac-trt.ini`、`xyzac-trt.xml`、`switchkins_postgui.hal`、`xyzac-trt.tbl`、`xyzac.var` |
|
||||
| Program/remap | `demos/*.ngc`、`remap_subs/*.ngc` |
|
||||
| Kinematics | `xyzac-trt-kins.c`、`xyzbc-trt-kins.c`、`trtfuncs.c`、`switchkins.c/h`、`kins_util.c` |
|
||||
| Motion/TP | `motion/command.c`、`motion/control.c`、`motion/homing.c`、`motion/motion.c`、`tp/tp.c`、`tp/tcq.c`、`tp/blendmath.c` |
|
||||
| Interpreter | `rs274ngc/interp_read.cc`、`interp_execute.cc`、`interp_queue.cc`、`interp_convert.cc`、`modal_state.cc` |
|
||||
| HAL/IO | `task/emctaskmain.cc`、`iotask/ioControl.cc`、HAL component source and `basic_sim.tcl` |
|
||||
|
||||
Inventory 不能只记录目录;必须展开到具体文件、source hash、引用关系和运行时 fixture。生成的 `sim.var`、`position`、journal 和临时 tool table 必须单独标为 `runtime-generated-fixture`。
|
||||
|
||||
### 3.2 Compat API 层
|
||||
|
||||
WASM 不直接向 React 暴露 C 内部函数。应建立有限、版本化的 `LinuxCncCompat`:
|
||||
|
||||
```text
|
||||
LinuxCncCompat
|
||||
├── task: state/mode/interpreter/queue
|
||||
├── program: load/parse/run/pause/resume/step/abort/seek
|
||||
├── mdi: execute/cancel/result
|
||||
├── motion: jog/home/limit/override/spindle
|
||||
├── kinematics: forward/inverse/select/diagnostics
|
||||
├── hal: read/write/subscribe/type-check
|
||||
├── io: tool/coolant/probe/spindle ack
|
||||
├── snapshot: full/delta/hash
|
||||
└── recovery: checkpoint/replay/reconcile
|
||||
```
|
||||
|
||||
每个方法必须映射到 source symbol 和固定 tick 位置;不允许添加“为了 UI 方便”的隐式状态改变。
|
||||
|
||||
### 3.3 Worker protocol 层
|
||||
|
||||
Worker gateway 负责 schema、capability、gate、ledger、seq、operation id 和错误包装;不负责猜测 motion 结果。协议命令必须能够回到 compat API,并最终回到 WASM canonical state。
|
||||
|
||||
```text
|
||||
UI event
|
||||
→ WorkerClient
|
||||
→ protocol validator
|
||||
→ capability/gate validator
|
||||
→ CommandLedger.prepare
|
||||
→ LinuxCncCompat
|
||||
→ fixed-tick WASM runtime
|
||||
→ snapshot/event/hash
|
||||
→ CommandLedger.commit
|
||||
→ UI projection
|
||||
```
|
||||
|
||||
### 3.4 Projection 层
|
||||
|
||||
React reducer 只做:
|
||||
|
||||
- 校验消息。
|
||||
- 保存 authoritative snapshot/event/result。
|
||||
- 派生按钮 gate、标签、错误和可视化 props。
|
||||
- 保留 pending/draft/ack/reconcile 状态。
|
||||
|
||||
Reducer 不得:
|
||||
|
||||
- 生成新的 motion/joint/pose。
|
||||
- 依据 UI 点击顺序补齐缺少的状态。
|
||||
- 在没有 Worker 快照时把按钮变为成功。
|
||||
- 把 preview segment 当成 active motion segment。
|
||||
|
||||
## 4. 完整功能对标登记
|
||||
|
||||
### 4.1 控制面板域
|
||||
|
||||
以下域必须全部有 source slice;每项还要登记 menu/toolbar/button/keyboard/HAL 入口:
|
||||
|
||||
| 域 | 最低条目 |
|
||||
|---|---|
|
||||
| Shell | title、machine name、version、about、quick reference、window/min-size、focus、tooltip |
|
||||
| File | open、recent、reload、save-as、properties、tool data、quit、exact path |
|
||||
| Machine | ESTOP、power、reset、home all、home joint、unhome、override limits、touch-off |
|
||||
| Mode | manual、mdi、auto、joint/world/teleop、mode denial |
|
||||
| Program | run、pause、resume、step、abort、restart、run-from-line、optional stop、block delete |
|
||||
| MDI | input、history、queue、clear、calculator、error/ack |
|
||||
| Jog | axis/joint selection、continuous/incremental、linear/angular speed、press/release/stop |
|
||||
| DRO | actual/commanded/relative/machine、G5x/G92/tool offsets、DTG、rotation |
|
||||
| Preview | perspective/X/Y/Z、zoom、pan/rotate、grid、rapids、tool、limits、extents、live plot、clear |
|
||||
| Tool | tool table、reload、tool change、tool offset、G43/G49/G43.1、manual toolchange |
|
||||
| Spindle/IO | direction、speed、override、brake、coolant、lube、probe、digital/analog |
|
||||
| HAL/PLC | HAL graph/scope/command、PyVCP、ClassicLadder/PLC state、capability denial |
|
||||
| Diagnostics | alarm、error、event log、command trace、snapshot diff、runtime overrun、recovery |
|
||||
| Case-specific | XYZAC/XYZBC type buttons、M428/M429/M430、A/C limits、RTCP offsets、Vismach clear |
|
||||
|
||||
### 4.2 对标登记状态
|
||||
|
||||
每项只能处于:
|
||||
|
||||
```text
|
||||
UNREGISTERED → SOURCE_MAPPED → WASM_IMPLEMENTED → WORKER_VERIFIED → UI_VERIFIED → PARITY_VERIFIED
|
||||
```
|
||||
|
||||
任意阶段失败都必须停留在对应状态并保存原因。`UI_VERIFIED` 不能越过 `WASM_IMPLEMENTED`;`PARITY_VERIFIED` 不能只用浏览器截图证明。
|
||||
|
||||
## 5. 状态和 gate 的唯一实现
|
||||
|
||||
### 5.1 Native gate 取证
|
||||
|
||||
对于每个按钮,必须从原始 AXIS/LinuxCNC 源码提取:
|
||||
|
||||
- handler 名和绑定位置。
|
||||
- 读取的 `stat`、HAL pin、INI 值和局部变量。
|
||||
- 允许状态/拒绝状态。
|
||||
- 发送的 command 和参数。
|
||||
- command 后检查的 state。
|
||||
- 错误对话框/状态栏/恢复行为。
|
||||
|
||||
### 5.2 WASM gate 复现
|
||||
|
||||
WASM gate 只允许读取 WASM snapshot:
|
||||
|
||||
```text
|
||||
gate(action, authoritative_snapshot, capability, configuration)
|
||||
→ { enabled, reason, required_state, source_slice_id }
|
||||
```
|
||||
|
||||
React 可以显示 gate,但不能覆盖 gate。若 native 与 WASM gate 不同,先生成差异报告;不能在 React 中添加特殊分支“修正”显示。
|
||||
|
||||
### 5.3 XYZAC 特殊 gate
|
||||
|
||||
```text
|
||||
M428/TCP = interpreter_idle && HAL_PIN_VARS && switchkins_net && finite_offsets
|
||||
M429/identity = interpreter_idle && HAL_PIN_VARS && switchkins_net
|
||||
M430/userk = interpreter_idle && userk_capability
|
||||
A/C jog = manual_ok && axis_enabled && angular_limits && no_fault
|
||||
RTCP motion = active_type == 1 && pose/joint transform verified
|
||||
Vismach clear = visual-only,不改变 task/motion/program/hash
|
||||
```
|
||||
|
||||
## 6. Native/WASM 等价证明
|
||||
|
||||
### 6.1 输入冻结
|
||||
|
||||
每次 parity run 固定:
|
||||
|
||||
- context id、case source hashes、browser/runtime build hash。
|
||||
- INI/HAL/NGC/TBL/VAR/Python/XML exact resources。
|
||||
- 程序文本、MDI 文本、按钮动作序列、固定 logical tick 数量。
|
||||
- 初始 task/mode/home/tool/offset/kinematics state。
|
||||
|
||||
### 6.2 Trace 规范
|
||||
|
||||
```json
|
||||
{
|
||||
"slice_id": "AXIS-XYZAC-M428-TCP",
|
||||
"step": 7,
|
||||
"input": {"kind": "MDI_EXECUTE", "line": "M428"},
|
||||
"native": {
|
||||
"task_mode": "MDI",
|
||||
"motion_switchkins_type": 1,
|
||||
"state_hash": "..."
|
||||
},
|
||||
"wasm": {
|
||||
"task_mode": "MDI",
|
||||
"motion_switchkins_type": 1,
|
||||
"state_hash": "..."
|
||||
},
|
||||
"equal": true,
|
||||
"first_divergent_tick": null
|
||||
}
|
||||
```
|
||||
|
||||
### 6.3 等价层级
|
||||
|
||||
1. **Protocol**:信封、seq、operation id、command/result/error schema。
|
||||
2. **Control**:按钮 gate、模式转换、队列、取消、abort/reconcile。
|
||||
3. **State**:task/interp/motion/home/limit/tool/IO/kinematics snapshot。
|
||||
4. **Canonical**:canonical events、TP queue、pose/joints/toolpath。
|
||||
5. **Recovery**:checkpoint、replay、endpoint hash、无重复副作用。
|
||||
6. **Visual**:DRO、当前行、轨迹、A/C pose、Vismach 非空和布局。
|
||||
|
||||
低层级通过不能替代高层级缺口;visual 通过尤其不能替代 canonical/control 失败。
|
||||
|
||||
## 7. WASM-only 前端实施拆分
|
||||
|
||||
### 7.1 Runtime 完整性
|
||||
|
||||
WASM bundle 必须包含或明确拒绝:
|
||||
|
||||
- RS274NGC parser/interpreter、modal state、canonical events。
|
||||
- TP queue/blend/arc/helix、fixed tick。
|
||||
- XYZAC/XYZBC TRT forward/inverse、tool offset、rotation points、limits。
|
||||
- task/motion/home/limit/IO/tool/probe/spindle/coolant。
|
||||
- remap/Python capability model(无能力时稳定拒绝)。
|
||||
- snapshot/event/hash/checkpoint/recovery。
|
||||
|
||||
`REAL-EXCLUDED` 能力不能通过宿主 LinuxCNC fallback 伪装成 WASM 支持。
|
||||
|
||||
### 7.2 Worker 完整性
|
||||
|
||||
Worker 必须是:
|
||||
|
||||
- WASM runtime 的唯一调度者。
|
||||
- protocol schema 和 capability 的唯一入口。
|
||||
- OPFS journal/checkpoint 的唯一写者。
|
||||
- command ledger 和 reconcile 的唯一实现者。
|
||||
- snapshot/event/trajectory 的发布者。
|
||||
|
||||
Worker 不得把某些命令转给主线程 JS authority;若能力未实现,返回 `capability_unavailable`/`source_blocked`。
|
||||
|
||||
### 7.3 Web 控制台完整性
|
||||
|
||||
React 页面必须从 `PanelSnapshotV1`/扩展快照显示:
|
||||
|
||||
- case/configuration/source hash。
|
||||
- task/mode/interpreter/kinematics state。
|
||||
- gates 和 reason。
|
||||
- program/line/preview/active segment。
|
||||
- Cartesian pose、XYZAC joints、tool offset、A/C limits。
|
||||
- HAL/IO/tool/spindle/coolant/probe/alarms。
|
||||
- pending/ack/result/reconcile/recovery。
|
||||
|
||||
所有 button handler 只能调用 `WorkerClient`/`AxisOperationController`;禁止 `setState` 直接表示 command 已完成。
|
||||
|
||||
## 8. 里程碑增强版
|
||||
|
||||
在原 `M0-M7` 上增加“源码唯一权威”退出条件:
|
||||
|
||||
### M0-SOURCE:完整 source manifest
|
||||
|
||||
- AXIS、G-code、motion、TP、kinematics、HAL、IO、Vismach 所有功能已登记 slice。
|
||||
- source hash、symbol、resource graph 和 version lock 可复现。
|
||||
- unregistered count = 0;blocked count 单独报告。
|
||||
|
||||
### M1-WASM-AUTHORITY:无 JS authority
|
||||
|
||||
- 所有 task/motion/kinematics/program state 均由 WASM snapshot 产生。
|
||||
- JS authority call count = 0;可以使用的 JS 只剩 projection/ledger/UI。
|
||||
- 损坏/篡改 snapshot fail closed。
|
||||
|
||||
### M2-CONTROL-PARITY:按钮和命令对标
|
||||
|
||||
- 每个 source slice 有 native/WASM button gate trace。
|
||||
- 正常、拒绝、ESTOP、limit、pause、abort、reconcile 全部通过。
|
||||
- gate mismatch count = 0。
|
||||
|
||||
### M3-CANONICAL-PARITY:解释器、TP、运动学
|
||||
|
||||
- program/canonical/TP/XYZAC pose/joint/toolpath trace 一致。
|
||||
- M428/M429/M430、helix、A/C 姿态和 tool offset 一致。
|
||||
- first divergent tick 可定位且 verified 样本无差异。
|
||||
|
||||
### M4-FRONTEND-PARITY:React/Three.js
|
||||
|
||||
- 所有 UI controls 只消费 WASM state。
|
||||
- Three.js 不重算姿态;canvas 与 snapshot hash 对账。
|
||||
- DOM、keyboard/touch、错误、pending、recovery UI 通过。
|
||||
|
||||
### M5-RECOVERY-PARITY:恢复和离线
|
||||
|
||||
- command ledger、checkpoint、journal、Worker restart endpoint 一致。
|
||||
- 无重复 M-code、tool/IO side effect、trajectory segment。
|
||||
- offline/OPFS quota/schema mismatch 证据完整。
|
||||
|
||||
### M6-RELEASE-PARITY:严格发布门
|
||||
|
||||
- source slice coverage = 100%(verified + explicit blocked 分开统计)。
|
||||
- native/WASM/Worker trace、hash、错误、恢复和 browser matrix 报告齐全。
|
||||
- 任何外部 oracle/browser/hardware/license/owner blocker 都保持 `STOP_RELEASE`。
|
||||
|
||||
## 9. 任务新增与调整
|
||||
|
||||
在 `xyzac-trt-web-wasm-implementation-plan.md` 的 `RTCP-00..12` 之前增加以下治理任务:
|
||||
|
||||
### SRC-00:AXIS/XYZAC Source Slice Inventory
|
||||
|
||||
**输出**:`coverage/xyzac-trt-source-slice-inventory.report.json`、`web/workspace/xyzac-trt-source-slices.mjs`。
|
||||
|
||||
**门禁**:所有 source controls、handlers、commands、state fields、visual outputs 和 errors 有唯一 slice id;unregistered=0。
|
||||
|
||||
### WASM-00:唯一权威审计
|
||||
|
||||
**输出**:`coverage/xyzac-trt-wasm-authority-audit.report.json`。
|
||||
|
||||
**门禁**:扫描 JS/TS/React/WASM bridge,证明没有 JS task/motion/kinematics authority、JS G-code execution 或 OPFS direct writer。
|
||||
|
||||
### PARITY-00:Native/WASM Trace Comparator
|
||||
|
||||
**输出**:`scripts/compare_xyzac_native_wasm_trace.py`、`web/worker/test_xyzac_trace_parity.mjs`、parity report。
|
||||
|
||||
**门禁**:协议、control、state、canonical、recovery 五级比较器能报告 first divergent tick,而不是只比较最终位置。
|
||||
|
||||
### UI-00:Source Control Binding Audit
|
||||
|
||||
**输出**:React control manifest、每个 control 的 source slice/gate/command/result 映射。
|
||||
|
||||
**门禁**:每个 button/menu/keyboard/gesture 都能追溯到 source id;每个 UI action 都通过 WorkerClient。
|
||||
|
||||
### RELEASE-00:WASM-only Release Gate
|
||||
|
||||
**输出**:`coverage/xyzac-trt-wasm-only-release-gate.report.json`。
|
||||
|
||||
**门禁**:WASM-only capability、source coverage、trace parity、browser matrix、recovery、错误和 blocker identity 全部审计;任何缺口都输出 `STOP_RELEASE`。
|
||||
|
||||
## 10. 测试和证据规则
|
||||
|
||||
每个 source slice 最少包含:
|
||||
|
||||
```text
|
||||
native normal
|
||||
native boundary
|
||||
native error
|
||||
WASM normal
|
||||
WASM boundary
|
||||
WASM error
|
||||
Worker command/result
|
||||
UI gate projection
|
||||
pause/resume/abort
|
||||
checkpoint/recovery(适用时)
|
||||
deterministic state hash
|
||||
```
|
||||
|
||||
测试不能只调用纯 JS helper;必须运行真实 WASM module、Dedicated Worker/session、固定 logical tick 和实际 snapshot publisher。`mock` 只能用于协议单元测试,不能用于功能通过。
|
||||
|
||||
报告必须记录:source hash、input hash、output hash、command sequence、tick sequence、state hash、first divergent tick、error code、failure sample、environment and exclusion reason。
|
||||
|
||||
## 11. 停止条件
|
||||
|
||||
下列任一条件出现,停止当前“完全对标”声明:
|
||||
|
||||
- 任意功能没有 source slice 或 source hash。
|
||||
- 任意程序/运动/RTCP 结果来自 JS/React/Three.js 推算。
|
||||
- 任意 button gate 与 native 不一致且没有明确 source/version 差异。
|
||||
- `M428/M429/M430` 没有通过 WASM remap/kinematics 状态确认。
|
||||
- canonical trace 只比较最终坐标,未比较首个 divergent tick。
|
||||
- recovery 可能重复 segment、M-code、tool/IO side effect。
|
||||
- browser 截图通过但 Worker/WASM authority 或 state hash 未验证。
|
||||
- 缺少官方 oracle、浏览器、实时硬件、OPFS crash 或 owner 输入时试图 promote release。
|
||||
|
||||
## 12. 对当前项目状态的诚实结论
|
||||
|
||||
当前仓库已有通用 AXIS gate、Worker protocol、React reducer、Three.js workflow 和选定案例证据,但这些不能直接等同于 `xyzac-trt.ini` 的完整 WASM-only parity。按照本合同,下一步应先执行 `SRC-00` 和 `WASM-00`,再实现 `RTCP-01..12` 中的缺口;在 source slice coverage、WASM authority audit、RTCP trace parity 和 recovery 完成前,状态必须保持 `in_progress` 或 `blocked`,不能写成 `verified` 或全功能完成。
|
||||
Reference in New Issue
Block a user