Files
cnc_wams/web-rtcp-5axis-sim-plan/docs/program-implementation-guide.md

512 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 5 轴数控系统 Web 仿真程序具体实施文档
生成时间2026-06-20 CST
## 1. 实施目标
本文件用于指导后续正式编写 5 轴数控系统 Web 仿真程序。第一版目标是做出一个可运行、可验证、可继续扩展的浏览器前端:
- 界面风格按 `gmoccapy_5_axis.png` 实现;
- 前端使用原生 HTML/CSS + TypeScript/JavaScript ES modules
- 3D 预览使用 Three.js
- G-code 执行、五轴运动学、RTCP/TCP 相关计算必须来自 LinuxCNC/WASM 或 source-derived 边界;
- 不引入 React/Vue/Angular/Svelte
- 不把 Python GUI、GTK/Glade、Tk/OpenGLTk、native HAL process 直接作为浏览器 runtime。
## 2. 第一版完成定义
第一版完成时应具备:
- 一个可启动的 Web app
- gmoccapy 风格布局:黑底 3D 预览、大号绿色 DRO、G-code 列表、右侧模式按钮、override/spindle/coolant 区、底部运行控制;
- 至少一个 5 轴 profile优先 `xyzac-trt`
- 能加载 representative G-code
- 能显示 X/Y/Z/A/B/C、joint pose、TCP pose、RTCP state、kins type
- Three.js 视口非空,能显示机床、刀具、刀路;
- browser smoke 能截图、检查 canvas 非空、检查关键 DOM 区域存在;
- 文档明确 LinuxCNC source references 和 unsupported runtime boundary。
## 3. 推荐目录结构
后续直接在本目录中扩展:
```text
web-rtcp-5axis-sim-plan/
app/
index.html
package.json
tsconfig.json
src/
main.ts
state/
store.ts
events.ts
ui/
gmoccapy-shell.ts
gmoccapy-dro-panel.ts
gmoccapy-gcode-panel.ts
gmoccapy-status-sidebar.ts
gmoccapy-override-panel.ts
gmoccapy-spindle-coolant-panel.ts
gmoccapy-bottom-controls.ts
gmoccapy-info-tabs.ts
visualization/
five-axis-scene.ts
machine-model.ts
toolpath-layer.ts
camera-controls.ts
runtime/
simulation-runtime.ts
frame-builder.ts
playback-controller.ts
linuxcnc-adapter.ts
profiles/
index.ts
xyzac-trt.ts
xyzbc-trt.ts
panel-schema/
controls.ts
pyvcp-reference.ts
workers/
linuxcnc-worker.ts
styles/
gmoccapy.css
core/
linuxcnc_kinematics_wasm/
tests/
browser/
node/
```
## 4. 实施顺序
### Step 1Web shell
目标:
- 创建 `app/index.html`
- 创建 CSS layout
- 创建 `gmoccapy-shell.ts`
- 页面静态呈现 gmoccapy 风格区域。
必须有的 DOM 区域:
```text
data-region="titlebar"
data-region="preview"
data-region="dro"
data-region="gcode"
data-region="status-sidebar"
data-region="info-tabs"
data-region="override"
data-region="spindle-coolant"
data-region="bottom-controls"
```
验收:
- 浏览器打开页面非空;
- 页面区域与 `gmoccapy_5_axis.png` 基本一致;
- 无 React/Vue 依赖。
### Step 2状态模型
目标:
- 实现 `GmoccapySimulationState`
- 实现 `createStore()``getState()``subscribe()``dispatch()`
- UI 面板从 state 渲染,不直接互相读写 DOM。
初始 state
```text
machineProfile=xyzac-trt
runState=idle
rtcpState=off
kinsType=identity
axisPose={X,Y,Z,A,B,C}
jointPose=[]
tcpPose={x,y,z,toolAxisVector}
```
验收:
- Node smoke 验证 store 更新;
- DOM renderer 能响应 state 变化。
当前 M2 已实现:
```text
app/src/runtime/rtcp-frame.js
app/src/profiles/xyzac-trt.js
tests/node/verify_rtcp_store.mjs
```
状态模型已经输出:
```text
axisPose
jointPose
tcpPose
toolAxisVector
rtcpFrame
feed
spindle
coolant
preview
operatorMessage
```
当前 RTCP frame 已支持双来源:
```text
apiName=web-rtcp-5axis-motion-frame
fixture fallback:
sourceMode=fixture-ui-only
semanticBoundary=fixture_frame_ui_plumbing_not_linuxcnc_kinematics_proof
linuxCncKinematicsReady=false
promotionAllowed=false
LinuxCNC kinematics proof:
sourceMode=source-derived-kinematics-wasm
semanticBoundary=linuxcnc_kinematics_wasm_c_abi
linuxCncKinematicsReady=true
promotionAllowed=true for kinematics frame source only
```
这表示 Web 仿真已经具备 RTCP 状态链路、TCP pose 显示、刀轴向量显示和控制按钮切换Node 和浏览器路径均已通过 `createLinuxCncKinematicsSdk({ moduleId: "xyzac-trt" })` 加载 LinuxCNC kinematics WASM 并生成 frame浏览器默认使用 Worker 隔离 kinematics WASM 调用。fixture fallback 仍保留为 runtime load failure 的 UI 安全路径,但 smoke 不再把 fixture fallback 当作当前 proof。
当前普通 G-code 程序执行也已接入 `createLinuxCncInterpSdk()`
```text
sourceMode=linuxcnc-interpreter-wasm
semanticBoundary=linuxcnc_interpreter_wasm_canonical_events
RUN/STEP source=LinuxCNC canonical motion events
remapRuntimeReady=false
plannerRuntimeReady=false
fullLinuxCncProgramExecutionReady=false
```
这只提升普通 G-code canonical execution source不代表 Python remap、tool DB、external user-M process 或完整 planner 已 promoted。
### Step 3gmoccapy UI 组件
目标:
- DRO
- G-code panel
- right status sidebar
- override panel
- spindle/coolant panel
- bottom controls
- info tabs。
要求:
- 按 gmoccapy 风格做大按钮、大数字、黑底预览、灰色面板;
- 所有按钮先连接仿真 action不连接真实机床控制
- 文本不能溢出按钮或面板。
验收:
- browser smoke 检查关键按钮、DRO、G-code rows
- `Run/Stop/Pause/Step` 能改变仿真 state。
当前 M2 已接入的 UI action
```text
RUN
STOP
PAUSE
STEP
SET_KINS_TYPE
SET_VIEW
RESET_VIEW
CLEAR_PREVIEW
ADJUST_OVERRIDE
ADJUST_SPINDLE_OVERRIDE
TOGGLE_COOLANT
RELOAD_PROGRAM
HOME
TOGGLE_FULLSCREEN
```
这些 action 只改变 Web 仿真状态,不连接真实机床控制。
当前 M5 已补齐 operator workflow
```text
TOGGLE_POWER
ESTOP
RESET
SET_MODE(auto/manual/jog/mdi)
JOG
RUN_MDI
LOAD_PROGRAM
```
实现状态:
- 右侧按钮栏提供 POWER、E-STOP、RESET、AUTO、MANUAL、JOG、MDI
- 底部控制栏提供 Open、Run/Stop/Pause/Step/Home、JOG X/Y、MDI
- Open 使用浏览器 FileReader 读取本地 G-code 文本并进入 `LOAD_PROGRAM`
- G-code 面板显示当前程序来源、当前执行行和高亮行;
- preview 区域显示刀具预览卡;
- RUN/STEP 仍是 fixture line playback不是 LinuxCNC interpreter execution proof。
### Step 4Three.js 五轴预览
目标:
- 创建基础五轴机床模型;
- 显示坐标轴、工作空间、刀具、TCP 点、刀路;
- 支持 fit/reset/clear path。
模型优先参考:
```text
qtvismach_5axis_gantry.png
lib/python/vismach.py
src/hal/user_comps/vismach/5axisgui.py
src/hal/user_comps/vismach/xyzac-trt-gui.py
src/hal/user_comps/vismach/xyzbc-trt-gui.py
```
验收:
- canvas 非空;
- tool marker 可见;
- path points 非零;
- 视口尺寸变化不破坏布局。
当前 M3 已实现:
```text
app/src/vendor/three/three.module.js
app/src/vendor/three/three.core.js
app/src/visualization/five-axis-scene.js
```
当前 Three.js 预览会渲染基础五轴工作区、工作台、刀具/TCP marker、刀轴和刀路并消费
```text
tcpPose
toolAxisVector
rtcpState
rtcpFrame.apiName
preview.selectedView
```
browser smoke 已检查 canvas nonblank、scene objects、path points、RTCP on/off 同步和 STEP 后 TCP pose 更新。
### Step 5profile 和 panel schema
目标:
- 建立 `xyzac-trt` profile
- 后续补 `xyzbc-trt`
- 把 PyVCP XML 和 HAL 绑定整理成 Web panel schema。
`xyzac-trt` 必须记录:
```text
iniPath
coordinates=XYZAC
kinematics=xyzac-trt-kins
remap=M428/M429/M430
halPins=motion.switchkins-type, xyzac-trt-kins.tool-offset, y-offset, z-offset
samplePrograms
sourceReferences
```
验收:
- Node smoke 验证 profile 完整;
- UI 能显示 profile title、coordinates、kins type、source references。
当前 M4 已实现:
```text
app/src/profiles/xyzac-trt.js
app/src/profiles/source-reference-map.js
app/src/panel-schema/xyzac-trt-pyvcp.js
tests/node/verify_profile_boundary.mjs
```
`xyzac-trt` profile 现在记录:
```text
iniPath
pyvcpXmlPath
postguiHalPath
generatedHalPath
toolTablePath
coordinates=XYZAC
kinematics=xyzac-trt-kins
sparm=identityfirst
remaps=M428/M429/M430
switchkinsTypes=identity/TCP:XYZAC/USERK
halPins
offsets
samplePrograms
sourceReferences
```
`xyzac-trt-switchkins-pyvcp` panel schema 记录 SWITCHKINS multilabel、IDENTITY/TCP:XYZAC/USERK/vismach-clear buttons、HAL nets 和对应 MDI commands。
### Step 6LinuxCNC adapter
目标:
- 第一阶段可接现有 interpreter WASM SDK
- 若未接入完整 WASM则先用明确标记的 fixture frame 验证 UI不声称 CNC semantics pass
- 所有 runtime result 必须带 `sourceMode` 字段。
允许:
```text
sourceMode=linuxcnc-wasm
sourceMode=source-derived-kinematics-wasm
sourceMode=fixture-ui-only
```
禁止:
```text
sourceMode=js-cnc-semantics
```
验收:
- UI-only fixture 不能被标记为 LinuxCNC pass
- LinuxCNC/WASM 接入后更新 traceability。
当前 M4 已实现 adapter 接入点:
```text
app/src/runtime/linuxcnc-boundary-adapter.js
apiName=web-rtcp-5axis-linuxcnc-boundary-adapter
readinessApi=web-rtcp-5axis-linuxcnc-boundary-readiness
semanticBoundary=adapter_entrypoint_only_runtime_not_connected | linuxcnc_kinematics_wasm_runtime_connected
linuxCncKinematicsReady=false for fixture fallback, true for loaded kinematics WASM
promotionAllowed=true only for kinematics frame source proof
fullLinuxCncProgramExecutionReady=false until interpreter/remap is connected
```
store 已输出:
```text
linuxCncBoundaryAdapter
linuxCncBoundaryReadiness
```
info tabs 和 browser smoke 会检查 adapter、panel schema、source map 和 boundary readiness。Node smoke 已验证 kinematics-only runtime readyinterpreter/remap 仍显示为 missing不得声明 full LinuxCNC program execution ready。
### Step 7RTCP/kinematics frame
目标:
- 定义 `FiveAxisMotionFrame`
- 将 canonical event 和 kinematics output 转成统一 frame
- 显示 RTCP on/off、TCP pose、tool axis vector。
M2 阶段先落地 `web-rtcp-5axis-motion-frame` 的 fixture contractM6 阶段已加入 LinuxCNC kinematics WASM frame contract
```text
profileId
sourceMode
semanticBoundary
activeLine
kinsType
rtcpState
axisPose
jointPose
tcpPose
toolAxisVector
compensation
readiness
```
后续 LinuxCNC/source-derived kinematics WASM 接入时,必须替换 frame builder 的运动学来源,并把 `sourceMode``fixture-ui-only` 改为明确的 LinuxCNC/WASM 边界值。
当前 Node proof 已使用 `linuxCncKinematicsResult.forward.pose``linuxCncKinematicsResult.inverse.joints` 填充 `tcpPose` / `jointPose`,并输出 `kinematicsModuleId`、forward/inverse rc、flags 和 `linuxcnc_kinematics_wasm_c_abi`
验收:
- Node smokeframe schema
- Browser smokeDRO 和 Three.js 同步显示同一 frame
- fixture fallback 必须显示 pendingNode LinuxCNC kinematics proof 必须显示 readyinterpreter/remap 未接入时仍不得显示 full program execution ready。
### Step 8测试和验收
至少需要:
- `git diff --check`
- Node profile/store/frame smoke
- Browser shell smoke
- Browser canvas nonblank smoke
- 文档 traceability 检查。
### Step 9LinuxCNC TP queue timing runtime
目标:
- 删除真实 G-code 路径上的
`linuxcnc_canonical_motion_timing_estimate_not_planner_queue` 边界;
- 将 interpreter 生成的 LinuxCNC canonical motion events 输入从
`linuxcnc/src/emc/tp` 移植构建出的 WASM runtime
-`tpCreate()``tpSetCycleTime()``tpSetVmax()``tpSetVlimit()`
`tpSetAmax()``tpSetTermCond()``tpAddLine()``tpRunCycle()`
`tpGetPos()` 生成程序级 queue timing
- UI 的 elapsed/remaining/current velocity 来自 TP queue runtime 输出,而不是
JavaScript 按距离和进给率估算。
实现步骤:
1.`wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_tp_wasm.c` 新增
`lctp_run_canonical_motion_timing()` C ABI。
2. 输入只接受 interpreter runtime 已解析出的 canonical motion JSONC 侧只做字段读取、
TP enqueue 和 cycle loop不解释 G-code。
3.`wasm-port/runtime/sdk/src/linuxcnc-tp.js` 新增 TP SDK负责加载
`build/wasm/tp/linuxcnc_tp.{js,wasm}` 并调用 C ABI。
4. 在 Web interpreter runtime 中可选接入 `createLinuxCncTpSdk()``runProgram()`
`runMachineFileProgram()` 完成 canonical motion 后立即跑 TP queue timing。
5. `programExecution.summary.plannerRuntimeReady=true` 只在 TP runtime 调用成功且
motionCount 一致时成立;否则保留 canonical execution但不能把 planner timing 标为 ready。
6. `web-rtcp-5axis-full-linuxcnc-execution-boundary` 可把 `plannerRuntimeReady=true` 作为
已满足项,但仍必须显示 `nativeTaskReady=false``nativeHalSyncReady=false`
`fullLinuxCncProgramExecutionReady=false`,因为 native task/NML、HAL realtime thread 和
硬件驱动没有接入。
当前边界:
```text
sourceMode=linuxcnc-interpreter-wasm
timing.semanticBoundary=linuxcnc_tp_queue_runtime_timing_from_canonical_motion
plannerRuntimeReady=true
nativeTaskReady=false
nativeHalSyncReady=false
fullLinuxCncProgramExecutionReady=false
```
不允许:
- 用 JS 重写 lookahead、blend、exact stop、S-curve 或 G-code modal 语义;
- 把 TP queue timing 说成已经驱动硬件;
- 把 native LinuxCNC task/NML/realtime HAL 说成已经完成;
- 对没有通过 TP runtime 的 operator MDI lightweight path 标记 planner ready。
## 5. 禁止事项
- 不在 JavaScript 中实现 G-code 解释器。
- 不在 JavaScript 中实现 LinuxCNC 五轴运动学公式作为最终语义源。
- 不把 gmoccapy Python/GTK runtime 移植进浏览器。
- 不把 Python remap/tool DB/external user-M process 伪装成已支持。
- 不用 UI fixture 结果冒充 LinuxCNC runtime proof。
- 用于 5 轴 machine-file backed run 的 G-code 必须来自 LinuxCNC 源程序目录
`configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/*.ngc`
用户上传或手写的 G-code 只能作为 operator file/普通 interpreter 输入,不得标记为
`linuxcnc-vendored-5axis-gcode` 或用于 5 轴源程序边界证明。
## 6. 开工建议
当前已完成 Step 1 到 Step 9 的 Node/browser LinuxCNC kinematics proof、浏览器 Worker kinematics 隔离、浏览器 Worker interpreter canonical execution source、`xyzac-trt`/`xyzbc-trt` profile 切换、OPFS 五轴会话保存/恢复、OPFS machine-file staging、machine-file backed `fiveAxisRemap` C ABI run、程序级 `M428/M429` switchkins RTCP 自动切换、LinuxCNC TP queue timing runtime、full execution boundary audit以及真实 LinuxCNC TRT 5 轴 `.ngc` 源程序 staging/选择/运行路径。`M428/M429/M430` 当前既可作为 Web runtime switchkins 事件驱动 `lckins_switch()`,也可在 staged machine-file run 中交给 vendored LinuxCNC five-axis remap C ABI 验证;只有 LinuxCNC source manifest 中的 `configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/*.ngc` 可作为 `linuxcnc-vendored-5axis-gcode` 进入 UI 和 machine-file run。`web-rtcp-5axis-full-linuxcnc-execution-boundary` 可以在真实 interpreter canonical motion 已通过 TP WASM 时报告 `plannerRuntimeReady=true`,但必须继续把 `nativeTaskReady=false``nativeHalSyncReady=false``fullLinuxCncProgramExecutionReady=false``promotionAllowed=false` 显示为 blocker除非后续真正接入 native task/NML 和 realtime HAL sync。