text39.txt

一、接续说明

执行时间：2026-06-21 CST

本文件接续 `wasm-port/docs/porting-steps-standalone.md` 中 Phase 9 / Phase 10
关于 kinematics 的要求，关闭下面这个状态问题：

```text
是否已经导出独立 kinematics ABI？
LinuxCNC 的所有逆解相关算法是否已经完整移植到 WASM？
```

二、准确结论

当前结论必须分两层写：

```text
1. 独立 LinuxCNC TRT kinematics WASM ABI 已完成第一批接入。
2. LinuxCNC 所有 kinematics / 逆解模块尚未全部移植为 WASM ABI。
```

因此，之前的准确状态从：

```text
LinuxCNC kinematics WASM ABI 未完成
```

更新为：

```text
LinuxCNC TRT kinematics WASM ABI 已完成第一批；
全量 LinuxCNC kinematics WASM ABI 仍未完成。
```

三、本批完成内容

新增独立 kinematics WASM C ABI：

```text
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_kinematics_wasm.c
```

导出 ABI：

```text
lckins_init
lckins_exit
lckins_type
lckins_switchable
lckins_switch
lckins_forward
lckins_inverse
lckins_run_probe
lckins_free_string
```

新增独立构建脚本：

```text
wasm-port/tools/build_kinematics_wasm.sh
```

当前生成的 WASM 产物：

```text
wasm-port/build/wasm/kinematics/linuxcnc_xyzac_trt_kinematics.js
wasm-port/build/wasm/kinematics/linuxcnc_xyzac_trt_kinematics.wasm
wasm-port/build/wasm/kinematics/linuxcnc_xyzbc_trt_kinematics.js
wasm-port/build/wasm/kinematics/linuxcnc_xyzbc_trt_kinematics.wasm
```

当前每个模块使用的 vendored LinuxCNC source：

```text
src/emc/kinematics/kins_util.c
src/emc/kinematics/switchkins.c
src/emc/kinematics/userkfuncs.c
src/emc/kinematics/trtfuncs.c
src/emc/kinematics/xyzac-trt-kins.c
src/emc/kinematics/xyzbc-trt-kins.c
```

说明：

```text
每个 kinematics WASM module 都是独立模块。
没有把多个 LinuxCNC kinematics 模块强行塞进同一个同名符号空间。
没有在 JavaScript 中实现 forward/inverse 算法。
```

四、SDK 接入

新增 SDK wrapper：

```text
wasm-port/runtime/sdk/src/linuxcnc-kinematics.js
```

新增统一导出：

```text
createLinuxCncKinematicsSdk
supportedLinuxCncKinematicsModules
linuxCncKinematicsWasmFile
```

相关文件：

```text
wasm-port/runtime/sdk/src/index.js
wasm-port/runtime/sdk/README.md
```

当前 SDK 支持 moduleId：

```text
xyzac-trt
xyzbc-trt
```

五、验证

新增 Node/WASM smoke：

```text
wasm-port/tests/wasm/node/verify_kinematics_wasm.sh
wasm-port/tests/wasm/node/verify_kinematics_wasm.mjs
```

通过命令：

```bash
EMSDK_QUIET=1 source /home/cnc/emsdk/emsdk_env.sh >/dev/null && wasm-port/tests/wasm/node/verify_kinematics_wasm.sh
```

通过输出：

```text
kinematics_wasm_node_smoke=ok
```

验证覆盖：

```text
1. xyzac-trt 独立 WASM module 可加载；
2. xyzbc-trt 独立 WASM module 可加载；
3. lckins_inverse 导出存在；
4. kinematicsType() == KINEMATICS_BOTH；
5. kinematicsSwitchable() == 1；
6. forward -> inverse roundtrip joints 成立；
7. switchkins identity path 可切换并 forward 成立；
8. SDK 只做 ABI/memory wrapper，不做 kinematics 数学。
```

六、关键实现注意事项

1. `hal.h` 已补 C ABI 边界：

```text
RTAPI_BEGIN_DECLS / RTAPI_END_DECLS
```

原因：

```text
LinuxCNC kinematics C 源以 C 符号调用 hal_*；
HAL shim 实现位于 C++ 文件 linuxcnc_hal_adapter.cpp；
必须让 HAL shim 对 C/C++ 调用者都呈现一致 C ABI。
```

2. kinematics wrapper 使用 C 文件而不是 C++ 文件：

```text
linuxcnc_kinematics_wasm.c
```

原因：

```text
LinuxCNC kinematics.h 间接包含 posemath C++ overload 声明；
强制 extern "C" 包裹整个头会破坏 C++ overload；
而把 kinematics C 源全部按 C++ 编译又会遇到 C 源中的 void* 隐式转换问题。
当前 C wrapper + C 编译 LinuxCNC kinematics 源是最小稳定边界。
```

七、仍未完成的部分

不能把本批写成“所有逆解完整移植到 WASM”。

尚未导出独立 WASM ABI 的 native-probe kinematics family 至少包括：

```text
trivkins
5axiskins
corexykins
rotatekins
rosekins
maxkins
lineardeltakins
rotarydeltakins
scorbot-kins
tripodkins
scarakins
pumakins
genserkins
genhexkins
pentakins
```

这些 native probes 证明原生 extracted-core 覆盖存在，但不等于 WASM ABI 完成。

八、后续建议

下一批如继续 kinematics，应按同一模式推进：

```text
1. 选一个 native probe 已通过的 kinematics family；
2. 建独立 WASM module，避免同名 kinematicsForward/Inverse 符号冲突；
3. 复用 vendored LinuxCNC source + linuxcnc_kinematics_wasm.c wrapper；
4. 必要时补 posemath/source 依赖；
5. 增加 Node WASM smoke；
6. 通过 SDK moduleId 暴露；
7. 文档只声明该 family 完成，不声明全量完成。
```

推荐下一批优先级：

```text
1. 5axiskins
2. trivkins
3. corexy / rotate / lineardelta / rotarydelta
4. posemath-heavy: puma / genser / genhex / pentakins
```

九、当前状态一句话

```text
LinuxCNC interpreter WASM ABI 已完成；
LinuxCNC TRT kinematics WASM ABI 已完成第一批；
LinuxCNC 全量 kinematics WASM ABI 未完成；
M4/M5 web app 仍需显式接入新的 kinematics SDK 后才能从 fixture/frame 逻辑升级为 LinuxCNC kinematics WASM 输出。
```
