530 lines
24 KiB
Markdown
530 lines
24 KiB
Markdown
# `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。
|