Initial wasm simulator checkpoint

This commit is contained in:
CNC Local
2026-05-22 04:43:21 +08:00
commit 55d9fff9f0
54 changed files with 5523 additions and 0 deletions

163
README.zh-CN.md Normal file
View File

@@ -0,0 +1,163 @@
# LinuxCNC Web/WASM CNC Simulator
本目录是把 LinuxCNC 面向浏览器仿真的改写入口。目标不是把完整 LinuxCNC 直接搬进浏览器,而是复用可移植的解释器、运动学和刀路算法,替换实时 HAL/NML/GUI 层,输出适合 Web Worker、Three.js/WebGPU 和后续碰撞/去料仿真的事件流。
## 关键判断
- 不能按“整套 LinuxCNC 编译为 wasm”做。LinuxCNC 包含实时线程、HAL、NML、动态模块、Python/Boost.Python remap、桌面 GUI 和 POSIX 依赖,这些都不是浏览器仿真核心。
- 可以先复用 `src/emc/rs274ngc` 解释器,接管 `canon.hh` 中的 Canonical Machining Functions`STRAIGHT_FEED``ARC_FEED``DWELL``CHANGE_TOOL` 等调用记录为仿真事件。
- Fanuc、Siemens 等主流系统应作为“方言层”实现先把宏变量、固定循环、坐标旋转、RTCP/TRAORI/CYCLE800 等控制器特性归一化为内部 IR再交给同一个仿真内核。
- 浏览器端不做实时控制,只做可重复、可暂停、可回放的离线仿真,所以速度规划、前瞻、碰撞和去料可以使用非实时算法。
## 分层
1. `dialect`
- LinuxCNC RS274/NGC
- Fanuc Macro B / common milling and turning extensions
- Siemens 840D-style cycles and transforms
2. `interp`
- LinuxCNC interpreter compiled to wasm where possible
- Canon callback adapter records normalized motion/tool/state events
3. `sim-core`
- Units, modal state, work offsets, tool table
- Arc/NURBS segmentation
- 3/4/5-axis kinematics and RTCP
- Feed/time estimation and non-realtime lookahead
4. `verification`
- Golden G-code corpus
- Controller dialect compatibility matrix
- Numeric tolerance checks against LinuxCNC native output
5. `web`
- Web Worker wrapper around wasm
- Toolpath display
- Machine model, fixtures, stock, collision and material removal
## First milestone
The first useful target is:
- compile a small wasm module exposing `cnc_sim_*` C ABI;
- connect LinuxCNC RS274 interpreter to a Canon event sink;
- return a JSON event stream to TypeScript;
- render rapid/feed/arc events in the browser;
- compare the event stream against native LinuxCNC for a small test corpus.
## 当前进度
- 已有稳定 C ABI 和 Web 调用封装。
- 已有数控系统风格网页面板。
- 已有临时 smoke parser用于在 LinuxCNC 后端接入前测试 UI 和 wasm 回调链路。
- 已有 native smoke test 和 JSON dump 工具。
- 已有 LinuxCNC `canon.hh` bridge并已通过独立 smoke test。
- 已有 native `librs274` runner可以让 LinuxCNC 解释器输出 `CncSimEvent`
- 已有最小 LinuxCNC tooldata 初始化native runner 和 API 后端都能覆盖 `T... M6` 换刀路径。
- 已有 LinuxCNC RS274 源码级链接 smoke本项目直接编译 23 个解释器 core 源文件,不再通过 `librs274` 取得解释器主体。
- 已有五轴 RTCP 第一版几何内核可根据编程刀尖点、A/B/C 姿态和刀长计算枢轴/主轴点补偿位置。
- 已有坐标系事件回归语料,覆盖 `G10 L2` 的 G5X/XY 旋转事件和 `G92.1` 清零事件。
- 下一步是继续替换源码级链接中残留的 Python、INI/HAL、文件系统和动态加载依赖并把 RTCP 内核接入 canon 事件流和机型配置。
## 本地测试
```bash
./test-all-native.sh
```
当前 native 测试覆盖:
- smoke parser
- Canon event sink
- LinuxCNC Canon bridge
- 直接链接 LinuxCNC `librs274` 的 runner
- 通过 `cnc_sim_api` 选择 `linuxcnc-rs274` 后端
- LinuxCNC RS274 源文件语法探针和对象编译探针
- LinuxCNC RS274 源码级链接 smoke
- 五轴 RTCP 几何内核 smoke
- `G10 L2` / `G92.1` 坐标系事件回归
## 后端选择
公共 API 使用同一个入口解析程序,后端通过 JSON 配置选择:
```json
{"backend":"smoke"}
```
`smoke` 是默认后端,用于 wasm 和 UI 联调。
native 构建启用 LinuxCNC 后端后,可以使用:
```json
{"backend":"linuxcnc-rs274"}
```
网页面板右上角的 `BACKEND` 下拉框会把该配置传给 wasm/core。当前默认 wasm 构建不包含 LinuxCNC 后端,选择 `LINUXCNC` 会返回明确错误native API 测试已验证该后端可用。
## RTCP 配置
RTCP 默认关闭。开启后,原有 `rapid``linear-feed``arc-feed` 事件仍表示编程刀尖轨迹core 会额外发出 `rtcp-pivot` 事件,`start`/`end` 是按刀长和 A/B/C 姿态补偿后的枢轴/主轴点轨迹,`center``x/y/z` 暂存当前刀具向量。
```json
{
"backend": "linuxcnc-rs274",
"rtcp": {
"enabled": true,
"toolLength": 100,
"toolLengths": {
"7": 125
}
}
}
```
当前 RTCP 内核是第一版头头/摆头类几何模型:编程 XYZ 视为刀尖点,刀长沿本地 `-Z`A/B/C 按 `Rz(C) * Ry(B) * Rx(A)` 旋转。后续会继续加入机型拓扑、旋转中心偏置、刀表刀长和不同五轴构型。
RTCP G 码控制已开始标准化:
- `G43.4 H...`:开启 RTCP`H` 号进入事件,实际刀长优先从 JSON 配置中的 `toolLengths` 按 H 号读取,未配置时回退到 `toolLength`
- `G43.5 H...`:同样作为 RTCP 开启处理。
- `G49`:关闭 RTCP。
解析后会发出 `rtcp-state` 事件。事件中的 `feed` 表示 RTCP 状态:`0=关闭``1=开启``tool` 表示 H 号;`dwell_seconds` 暂存当前配置刀长。
## 运动学切换 M 码
core 已对原型中的运动学切换 M 码做标准化解析:
- `M429`:切换到三轴恒等运动学 `IDENTITY`,关闭 RTCP。
- `M428`:恢复到原始五轴运动学,开启 RTCP。
- `M430`:切换到 `FIVEAXIS_BC`,开启 RTCP。
解析后会发出 `kinematics-switch` 事件。事件中的 `reserved` 字段表示运动学类型:`0=IDENTITY``1=ORIGINAL``2=FIVEAXIS_BC``feed` 字段临时表示 RTCP 状态:`0=关闭``1=开启`。同一行中的 `M428 M429 M430` 会按出现顺序产生三个切换事件。
`linuxcnc-rs274` native API backend 会在送入 LinuxCNC 解释器前拦截只包含这些切换 M 码的行,避免 LinuxCNC 去查找外部用户 M-code 文件。
## 坐标系事件
Canon bridge 已不再丢弃坐标系相关回调,会输出:
- `set-g5x-offset`:来自 `SET_G5X_OFFSET``tool` 字段存 G5X index`start` 存 XYZABCUVW offset。
- `set-g92-offset`:来自 `SET_G92_OFFSET``start` 存 XYZABCUVW offset。
- `set-xy-rotation`:来自 `SET_XY_ROTATION``feed` 暂存旋转角度。
这些事件先保证 LinuxCNC Canon 层信息完整进入 Web/core。具体 G-code`G10``G92`、坐标旋转)是否触发这些回调,还要继续按 LinuxCNC 解释器参数路径逐项补回归语料。
目前已有第一组回归语料 `tests/gcode/linuxcnc_coordinate_offsets.ngc`,覆盖 `G10 L2 P1 X... Y... Z... R...` 触发 `set-g5x-offset` / `set-xy-rotation`,以及 `G92.1` 触发 `set-g92-offset` 清零。后续继续扩展到 `G10 L20`、多坐标系 P 号、持久参数文件和旋转叠加运动路径。
## CMake native LinuxCNC 后端
手写测试脚本仍是当前主验证路径。如果使用 CMake启用 native LinuxCNC 后端的配置为:
```bash
cmake -S core -B build/native-linuxcnc \
-DCNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND=ON \
-DCNC_SIM_LINUXCNC_ROOT=/home/cnc/桌面/cnc/linuxcnc
```
该选项是 native-only会链接 LinuxCNC 已构建的 `librs274``libtooldata`
## Legal note
LinuxCNC is GPL licensed. If this wasm module links LinuxCNC code, the combined simulator core must be distributed under GPL-compatible terms unless you replace that part with an independently written interpreter.