36 KiB
LinuxCNC Web/WASM 运动学完整移植计划
文档状态:重梳理版 v1.0
适用基线:LinuxCNC 2.10.0~pre0,以 context-lock.json 为准
目标:完成所有纳入 configs/sim/** 的运动学类型、配置变体、正解/逆解、回零、模式切换和浏览器可视化闭环
上位实施:完整仿真机床实施蓝图
源程序关联:功能与源程序关联目录
覆盖验收:仿真全功能覆盖矩阵
本文件将运动学从“CORE-04 的一个任务”提升为贯穿核心、运动、HAL、数字孪生、可视化和回归的主线。它不把算法按文件名简单罗列,而是要求每个类型都闭合:配置选择、参数解析、坐标/关节映射、正解、逆解、分支标志、回零、限制/奇异性、固定 tick、故障注入、native/WASM oracle、UI 姿态和恢复。
1. 为什么运动学必须单独成线
LinuxCNC 的 KINEMATICS 不只是一个 forward()/inverse() 函数:
KINEMATICS_IDENTITY、FORWARD_ONLY、INVERSE_ONLY、BOTH会改变 Task、motion、jog、home 和世界/关节模式转换。coordinates=可以重复轴字母(如XYYZ),额外关节不进入 kinematics;映射错误会让解释器正确的轨迹驱动错误的关节。- 正解和逆解可能有多分支,需要
KINEMATICS_FORWARD_FLAGS、KINEMATICS_INVERSE_FLAGS保持姿态连续;并行机构和机器人还需要上一次 pose 作为迭代初值。 - 许多配置使用
switchkins、HAL 实现的 CoreXY 或 GUI 专用 kinematics,不能只按[KINS]KINEMATICS的模块名判断。 - 5 轴刀尖跟随、转台/摆头、Delta/Hexapod、SCARA/PUMA 等算法的单位、角度、奇异点和收敛策略不同;“能编译”不代表“可运行”。
因此运动学主线是 M2 核心行为进入 M3 HAL/数字孪生和 M4 UI 的硬门。运动学主线未达到 verified,不得把任意非 trivkins 配置标为可运行。
2. 锁定来源和类型清单
2.1 公共接口和适配基础
必须逐文件登记并保留 source_sha:
| 来源组 | 文件 | 作用 |
|---|---|---|
| ABI/类型 | src/emc/kinematics/kinematics.h |
EmcPose、四种 kinematics 类型、正逆解 flags、home 和 switch API |
| 映射/通用 | kins_util.c、userkfuncs.c、ugenserkins.c |
coordinates 到 joint 映射、identity 实现、用户模板 |
| 切换 | switchkins.c、switchkins.h |
0/1/2 类型选择、last pose、迭代正解和 GUI pins |
| 几何 | src/libnml/posemath/**、src/libnml/gomath/** |
变换、矩阵、向量、数值容差和姿态表示 |
| 运动耦合 | src/emc/motion/control.c、command.c、motion.c、homing.c |
kinematics 类型如何影响 mode、home、限位、following error 和实际位置 |
2.2 LinuxCNC 实际运动学实现族
下表是代码级实现族,不等同于配置数量。每个文件都要进入 manifest;同一算法的 .c/.cc 变体不能只保留一个目录状态。
| 族 | 实现文件 | 几何类别 | 典型配置入口 |
|---|---|---|---|
| 笛卡尔/映射 | trivkins.c、maxkins.c、rotatekins.c |
轴与关节同构、最大轴/旋转映射、identity/both 变体 | axis/*.ini、qtaxis/xyz、gmoccapy/*axis* |
| 耦合线性 | corexykins.c、rosekins.c |
线性关节耦合、双电机/特殊并联映射 | axis/corexy/*、axis/rose_engine/* |
| 泡沫/扩展轴 | 5axiskins.c、trivkins 重复轴/extra joints |
XYZ 与 UVW、旋转轴、非 kins extra joints | axis/foam/*、9 轴/extra-joints 配置 |
| 转台/摆头 | trtfuncs.c、xyzac-trt-kins.c、xyzbc-trt-kins.c |
table-rotary-tilting、刀尖/偏置变换 | axis/vismach/5axis/*、gmoccapy/non_trivial_kinematics/* |
| Delta | lineardeltakins.c/.cc、lineardeltakins-common.h |
线性 Delta 正逆解、工作空间限制 | axis/ldelta*、tklinuxcnc/ldelta.ini |
| Rotary Delta | rotarydeltakins.c/.cc、rotarydeltakins-common.h |
旋转 Delta 几何 | axis/rdelta.ini |
| Tripod/并联 | tripodkins.c |
三腿并联、姿态分支 | tklinuxcnc/tripod.ini |
| Hexapod | genhexkins.c、genhexkins.h |
六杆并联、迭代正解、平台上下分支 | axis/vismach/hexapod-sim/* |
| Pentapod | pentakins.c/.h |
五杆并联、平台姿态和分支 | axis/pentapod/* |
| 通用串联机器人 | genserkins.c、genserfuncs.c、genserkins.h |
DH 链、Jacobian、迭代逆/正解 | qtaxis/non-trivial/scara 及机器人样例 |
| SCARA | scarakins.c |
平面串联、腕部旋转、分支选择 | axis/vismach/scara/*、qtvcp_screens/non-trivial/scara/* |
| PUMA | pumakins.c |
6 轴串联、腕部奇异性和分支 | axis/vismach/puma/* |
| Scorbot | scorbot-kins.c |
机器人专用几何和姿态分支 | configs/sim 中 Scorbot/robot 资源 |
| 用户/示例 | cubic.c/.h、userkfuncs.c、ugenserkins.c |
用户参数和模板;不允许动态宿主插件 | 只在 manifest 明确登记后启用 |
| 切换容器 | switchkins.c |
多算法运行时切换 | SCARA、Hexapod 和含 switchkins 的配置 |
除了 KINEMATICS 值,还要扫描 HALFILE 中的 corexy_by_hal、xyzab_tdr_kins、loadrt 和 GUI pin;这些可能在 HAL 或用户组件层实现变换。
2.4 K0-INV-01 闭合审计(2026-08-20)
coverage/kinematics-source-closure.report.json(schema v2)是本节点的机器可读证据,并以当前 context_id 绑定到锁定来源。报告不只按文件名计数,而是把 source index、source-symbols、配置行和 HAL 行转成稳定 ID:
| 审计面 | 结果 | 证据字段 |
|---|---|---|
src/emc/kinematics 全目录文件 |
38 个,其中 35 个 .c/.cc/.h 实现/头文件 |
source.files[*].source_id、extension、sha256 |
KINEMATICS=(.ini 和 .inc) |
268 条 | configuration.entries[*].config_id |
loadrt、HAL 变换、switchkins 控制 |
111 条;模板 [KINS]KINEMATICS、corexy_by_hal、motion.switchkins-type 分别保留 |
hal.entries[*].config_id、kind、family |
| 实现族 | 11 族均有源码 ID 和配置候选映射 | families[*].source_ids、configuration_ids |
| 测试输入 | tests/matrixkins 6 个文件;linuxcnc/unit_tests/kinematics 缺失 |
tests.*、missing_required_test_roots |
| FK/IK oracle | 11 族全部 blocked |
families[*].oracle.reason、closure.oracle_blocked_families |
缺失的官方测试根目录来自锁定提交本身;报告不会把 tests/matrixkins/** 改名或升级为 unit_tests/kinematics/**。matrixkins 仍作为 HAL 组件/配置入口候选登记,待契约变更或补充官方输入后才能产生 native FK/IK golden。2 个 TRT .c 文件在现有 source-symbols 报告中是 indexed_empty,不是静默丢失;其 source ID、哈希和待补符号状态均保留。
2.5 K0-INV-02 配置图与样本集(2026-08-20)
coverage/kinematics-config-graph.report.json 将审计报告中的 262 个 KINEMATICS 条目和 111 个 HAL/切换条目展开为 373 个入口节点、1,491 个文件/族/资源节点和 2,774 条有向边。模板化 loadrt [KINS]KINEMATICS 的解析状态分为 explicit_reference、directory_owner 和 inactive_reference;后两类保留来源事实,但不能当作已启动配置。图的 orphan_entry_ids 和 unowned_template_ids 必须为空。
coverage/kinematics-oracle-samples.jsonl 为 11 个实现族各登记一个固定 fk_ik_fk_roundtrip 样本、候选配置、输入姿态/关节、容差和精确字段。样本当前全部 blocked,原因仍是锁定提交没有 linuxcnc/unit_tests/kinematics/**;tests/matrixkins/test.ini 只作为 user_static 的配置候选,未被提升为官方 oracle。只有补充/批准输入契约后,才允许把 execution.status 改为可运行并生成 native golden。
2.6 K0-ORACLE-01 runner/schema(2026-08-20)
scripts/generate_kinematics_oracle_report.py 在固定 PATH/HOME/LANG/LC_ALL/TZ/PYTHONHASHSEED 环境中运行 build-native/sim_kinematics_test 作为 native smoke,并为 11 个样本输出 coverage/kinematics-oracle.report.json。coverage/kinematics-golden-schema.json(linuxcnc-web-wasm/kinematics-golden.v1)要求 status/error_code/kinematics_type/branch_id/flags/current_tick/config_hash/axis_joint_mapping 等字段;缺字段不会通过比较。当前 native smoke 为 passed,但 11 个样本均为 blocked,错误码为 MISSING_OFFICIAL_ORACLE,没有伪造数值 golden。
2.7 K1-CONTRACT-01 ABI contract(2026-08-20)
coverage/kinematics-abi-contract.json 从 sim_kinematics.h、wasm-core/CMakeLists.txt 和固定数值策略生成。它锁定 ABI version 1、8 个公开函数、结果/类型/mode 枚举、3 个结构体字段列表、SIM_KIN_ERR_* 错误码、-ffp-contract=off/-fno-fast-math、非有限值拒绝、100000 最大迭代和 FNV-1a-64 state hash;缺失 Emscripten export 会使 contract blocked。当前 contract verified,native/WASM 构建及 8 个 CTest 均通过。
coverage/kinematics-mapping-contract.json 进一步锁定 ASCII case-fold、重复轴 first-wins、extra-joint 数量、home 零位、inclusive limits、forward/inverse 映射和 state hash 输入字段;sim_kinematics_test 已覆盖 XYYZ、越界和 home 样本。
coverage/kinematics-numeric-policy.json 固定 -ffp-contract=off、禁用 fast-math、角度单位、100000 迭代上限、1e-12 奇异阈值、1e-9 golden 容差和 exact 字段;NaN/Inf、负容差、超迭代、奇异和越界都列入边界矩阵。
2.3 当前 WASM 雏形的真实边界
当前 wasm-core/include/sim_kinematics.h/sim_kinematics.c 只能作为 K1 之前的实验切片,不能作为完整实现证据:
| 已存在 | 尚未闭合 |
|---|---|
trivkins、XYZAC-TRT、XYZBC-TRT、XYZBCW 的有限正逆解和基础 joint limit 检查 |
LinuxCNC 全部实现族:CoreXY、Rose、5axiskins 完整模式、Delta/RotaryDelta、Tripod、Hexapod、Pentapod、GenSer、SCARA、PUMA、Scorbot、switchkins 和用户静态扩展 |
基础 coordinates 字符串和重复关节填充 |
KINEMATICS_TYPE 四种语义、extra joints、完整轴 bitmap、world/joint mode 约束和 home 语义 |
| 有限性检查、少量奇异性检查和 FNV 状态 hash | fflags/iflags 分支状态、last-pose/seed、residual、iterations、branch_id、确定性迭代策略和恢复字段 |
| C API 单元样例 | LinuxCNC native FK/IK oracle、每个配置入口的 golden、HAL 实现等价性和 UI/Vismach 姿态证据 |
另外,现有 sim_kinematics.c 尚未加入 wasm-core/CMakeLists.txt 的 sim_core/Emscripten module,sim_kinematics_test.c 也未进入 CTest;因此当前 ctest 的 7/7 通过不包含运动学验证。K1 的第一项集成工作必须先修复构建和测试注册,再谈算法族扩展。
因此 K0/K1 不能只围绕现有 sim_kinematics_* 函数补测试;必须先完成统一契约,再按 K2-K5 族逐步替换或扩展实现。现有切片的错误码和字段若与统一 ABI 冲突,应通过版本化契约迁移,不得在旧 ABI 上堆叠不可兼容的类型。
3. 统一运动学契约
3.1 输入、输出和状态
WASM 内部使用固定宽度、明确大小的结构,TypeScript 不接触 C 结构体布局。逻辑契约如下:
KinematicsRequest {
kind: FORWARD | INVERSE | HOME | CHECK
joints[N] / pose{ x,y,z,a,b,c,u,v,w }
fflags: uint64
iflags: uint64
seed_pose: optional pose # 迭代正解初值
config_hash: bytes32
simulation_tick: uint64
}
KinematicsResult {
status: OK | INVALID_INPUT | OUT_OF_RANGE | SINGULAR | NO_SOLUTION |
NOT_CONVERGED | UNSUPPORTED | NUMERIC_ERROR
joints[N] / pose
fflags: uint64
iflags: uint64
residual: float64
iterations: uint32
branch_id: uint32
state_hash: bytes32
}
必须固定以下语义:
forward(joints)返回世界 pose,并更新适用的iflags;inverse(pose)返回关节,并更新适用的fflags。- flags 是会话状态的一部分,必须进入快照、golden 和恢复账本;不能每次调用清零来掩盖分支变化。
home()产生已知的世界 pose、joint 和 flags;不能只把所有关节设为零。KINEMATICS_FORWARD_ONLY、INVERSE_ONLY的 mode 转换限制要与 LinuxCNC 一致;不支持的调用返回UNSUPPORTED,不能返回伪造 pose。- 所有输入输出先检查有限性、维数、单位和配置 hash;NaN/Inf、数组越界、未知轴字母和未知类型在进入算法前拒绝。
3.2 坐标、关节和 extra joints
coordinates 解析为轴索引到 joint 编号的稳定映射,并记录重复轴 bitmap。运动学 joint 数量与 EMCMOT_MAX_JOINTS、NO_OF_KINS_JOINTS、extra joints 的边界必须分开表示:
- kinematics 只接收前
NO_OF_KINS_JOINTS个关节;extra joints 由 motion/Task 管理,不得误传给算法。 XYYZ、XYZY等重复坐标必须在配置加载时生成映射 golden,并在 joint/world 模式切换时复用。- 旋转轴的角度单位、绕轴方向、回绕策略和连续性要逐类型登记;不能用统一的线性限位代码代替。
- UI 显示的 axis pose、joint pose、commanded/actual pose 必须注明坐标系和来源 tick。
3.3 正逆解数值策略
解析解与迭代解使用同一个数值政策:
- Emscripten/native 固定编译选项、舍入模式和
sin/cos/sqrt/atan2包装;算法不得调用墙钟或未锁定随机数。 - 解析算法返回工作空间、关节限位、姿态范围和分支错误,而不是将超界结果钳位后返回
OK。 - 迭代算法固定初值来源、最大迭代次数、收敛残差、步长/阻尼、奇异阈值和失败码;每次结果记录
iterations/residual/branch_id。 - 对正逆解只使用定义好的几何容差;状态、分支、错误码和事件顺序必须精确一致。
- 迭代正解(Hexapod、通用串联等)在相邻 tick 使用上一次有效 pose,但恢复后必须从 checkpoint 中恢复该 seed。
4. 按算法族的实施要求
4.1 笛卡尔和耦合线性族
先完成 trivkins 的 identity/both/inverse-only/forward-only、坐标重复映射和 max/rotate 变体,再完成 corexykins、rosekins 的矩阵映射。每一类需要:
- 正逆解矩阵和符号方向的单元向量测试;
- 重复轴、extra joints、关节限位、回零和 joint/world 模式测试;
- HAL 实现的
corexy_by_hal与 kinematics 模块实现的对照,证明同一轨迹在两条链上等价; - 快速/1x/暂停恢复后的关节和世界 pose hash 一致。
当前 K2 耦合切片已完成 CoreXY、Rose、MaxKins 和 RotateKins 的统一实现。CoreXY 复现 LinuxCNC 的半和/半差公式,并分别登记 corexy_by_kins.ini 与 corexy_by_hal.ini,HAL 组件路径保持为独立入口;Rose inverse 保存上一象限和累计圈数,跨 2→3 象限得到连续角度和稳定 branch;MaxKins 保留 pivot/B/C/U/V/W 修正公式并覆盖真实 max5kins.ini 的 pivot-length=0;RotateKins 覆盖负 C 旋转方向和 90°边界。锁定 LinuxCNC 没有 shipped 的 rotatekins .ini,因此新增的 linuxcnc/configs/sim/axis/rotate/rotatekins.ini 明确标为 workspace-derived fixture,不冒充官方配置或 oracle。coverage/coupled-kinematics.report.json 使用相同样本运行 native 与 WASM,并比较规范化 JSON 和 state hash;由于 linuxcnc/unit_tests/kinematics 不在锁定源中,报告状态仍为 partial/blocked,不生成伪造官方 golden。
K2-HAL-01 已在同一契约上接入静态 corexy_by_hal。SimHAL 注册组件的 8 个 float pin 和 servo-thread function,周期内执行 .comp 的 alpha/beta 命令矩阵与 j0/j1 反馈矩阵;HAL 配置中的 j0home/j1home 路由在变换前保留 Cartesian home 语义,并与 corexykins 的 motor-joint home 明确区分。coverage/corexy-hal.report.json 对配置连接、公式、native/WASM 输出和 oracle 阻塞状态做确定性检查;完整 HAL 命令解析、其它组件和真实 unit-test oracle 仍属于后续节点。
K3-5AXIS-01 已接入 5axiskins 的 XYZBCW spherical pivot 链。真实 bridgemill/5axis.ini 使用 coordinates=xyzbcwy 和七个 joints,重复 Y 由 first-wins 映射并在 inverse 后同步 suffix;pivot length 250、B/C 角度和 W 工具运动均进入 FK/IK 与 state hash。缺少 XYZBCW 任一必需字母返回 configuration error;coverage/fiveaxis-kinematics.report.json 对配置、源公式、重复轴、边界和 native/WASM 样本做确定性记录,官方 unit-test oracle 仍 blocked。
K3-TRT-01 已接入 xyzac-trt-kins 与 xyzbc-trt-kins 共用的 trtfuncs.c 姿态链。table-rotary-tilting/xyzac-trt.ini 与 xyzbc-trt.ini 的 sparm=identityfirst、五关节、tool/offset HAL pins 均登记;XYZAC 保持 C→A 顺序,XYZBC 保持 C→B 顺序,offset 与 tool length 进入固定解析式。B=90 的配置边界显式返回 singular,native/WASM 样本和 hash 见 coverage/trt-kinematics.report.json;switchkins 运行时切换容器留到 K5,不在本节点伪装完成。
K3-ROBOT-01 已接入 SCARA、PUMA 和 Scorbot 专用解析式。SCARA 使用 D1-D6、C 总姿态和 elbow 分支;PUMA 使用 A2/A3/D3/D4/D6、完整旋转矩阵/RPY 转换以及 shoulder/elbow/wrist 分支和 wrist singular 检查;Scorbot 使用固定 L0/L1/L2 链和受控点 RZ 逆解。SCARA 与 PUMA 取自 shipped Vismach 配置,Scorbot 因锁定源没有 shipped INI 使用明确标注的 workspace-derived fixture。PUMA 等复杂三角函数的 native/WASM state hash 在 1e-9 golden 容差上规范化,避免后端 libm 末位差异成为伪状态分叉;所有不可达/奇异边界和官方 oracle 状态见 coverage/robot-kinematics.report.json。
K3-GENSER-01 已接入六关节 Craig DH 链和固定零初值的阻尼数值 Jacobian inverse。DH A/ALPHA/D 数组、alpha 弧度与 joint 度数转换、有限差分步长、阻尼、最大迭代次数、residual 和不收敛错误均进入配置/报告;melfa 与 puma560 的真实 genserkins 配置作为候选,样本在 native/WASM 逐字一致。此节点不把动态 switchkins 或用户库放行到浏览器,官方 unit-test oracle 仍 blocked,详见 coverage/genser-kinematics.report.json。
K4-DELTA-01 已接入 linear/rotary Delta 的统一 forward/inverse/mapping 路径。线性 Delta 使用锁定 lineardeltakins-common.h 的 120 度塔架与杆长解析二次式;旋转 Delta 使用锁定 rotarydeltakins-common.h 的平台/大腿/小腿/足端几何。两者均固定 XYZ 到前三个 kinematics joints 的映射,A/B/C/U/V/W 透传,额外 joints 不进入算法;默认根保持 LinuxCNC 的平台根,SIM_KIN_DELTA_ALTERNATE_ROOT bit 0 使 alternate root、branch_id 和 state hash 可观察。真实 ldelta.ini、ldelta_demo.ini、tklinuxcnc/ldelta.ini、rdelta.ini 均登记;nominal/alternate root、工作空间无解、关节限位和 rotary z=0 奇异边界在 native/WASM 逐字对照。配置引用的 HAL 文件在锁定工作区缺失,作为 resource gap 保留,不能升级为配置 smoke 或数值 golden;官方 linuxcnc/unit_tests/kinematics/** 同样缺失,全部 Delta oracle 明确 blocked,详见 coverage/delta-kinematics.report.json。
4.2 5 轴转台/摆头族
5axiskins、xyzac-trt-kins、xyzbc-trt-kins 必须共享但不能混用各自的旋转顺序、刀尖点和 offset 语义。验收至少包括:
- A/B/C 旋转顺序、正负方向、角度单位和回绕;
- table-rotary 与 tool-rotary 的姿态链;
identityfirst参数、刀长/刀尖偏置、G43/G43.1/G49 与逆解;- 旋转轴接近 0/180/360 度、万向节/姿态奇异和无解报警;
- impeller、table-rotary-tilting、dual-rotary 的真实
configs/sim入口和 Vismach 姿态。
4.3 Delta、Tripod、Hexapod、Pentapod
并联机构不能只测“一个可达姿态”。每种机构需要工作空间边界、腿长/关节范围、平台上下分支、奇异面和迭代初值测试:
- Delta:塔架几何、臂长、平台平移边界、负根/无根和线性/旋转变体;
- Tripod:三腿约束、姿态分支、回零和连续轨迹;
- Hexapod:六杆长度、平台上下姿态、迭代正解、last-pose 和 GUI pins;
- Pentapod:五杆约束、平台姿态、不可达/奇异区域和
pentapod.var参数。
每次迭代必须输出 residual 和迭代次数。相同 seed、输入和 tick 必须得到相同分支;越过分支边界时要产生可解释的 SINGULAR 或 NO_SOLUTION 事件,不能突然跳姿态。
4.4 通用串联机器人族
genserkins 以 DH 链、Jacobian 和迭代求解为核心;scarakins、pumakins、scorbot-kins 是专用参数化实现。实施顺序:
- 统一 link 参数、角度单位、joint offset、正方向和关节范围。
- 先用 FK 生成 pose oracle,再用 FK→IK→FK round-trip 验证每一个分支。
- 对 Jacobian 条件数、阻尼、步长、初值和最大迭代建立配置字段,全部进入快照。
- 覆盖 elbow-up/down、腕部翻转、SCARA 平面无解、PUMA wrist singularity 和 Scorbot 专用姿态。
- UI 轨迹显示必须消费 kinematics 输出的姿态,不能用线性 axis 拼接替代机器人 FK。
4.5 Switchkins 和用户扩展
switchkins 不是动态加载的放行口,而是静态注册的最多三种实现容器。每个 switchkins_type 必须有:
- 类型、坐标要求、最大 joint 数、是否允许重复轴、是否迭代正解的 manifest;
- 切换前后同步点、flags/lastpose 初始化和 GUI pin;
- 非法类型、缺失实现、切换中运动、恢复后重建和回滚测试。
userkfuncs、ugenserkins 和 .so/.so 类宿主动态模块不能直接加载。可移植用户运动学必须在构建期编译为静态 WASM 模块,提供相同 ABI、版本和 capability;不满足时返回 UNSUPPORTED_USER_KINS 并阻断配置启动。
5. 运动学主线任务和里程碑
M0/M1 的基线和会话骨架保持不变;从原 M2-CORE-04 起,采用以下 K 系列主线。K 系列任务完成后才能解锁对应的 M3/M4 工作流。
| 里程碑 | 任务 | 结果 | 依赖 | 退出门槛 |
|---|---|---|---|---|
| K0 清单与 oracle | K0-INV-01 源文件/符号索引;K0-INV-02 配置入口图;K0-ORACLE-01 native FK/IK/golden schema |
完整类型、参数和配置清单 | M0 | 所有 kinematics 文件和入口有 source/feature/test/oracle;缺失输入显式 blocked |
| K1 ABI 与数值 | K1-CONTRACT-01 C ABI;K1-CONTRACT-02 flags/pose/映射;K1-NUM-01 浮点/迭代政策 |
sim_kinematics.h、错误码、状态 hash |
K0、M1 | 同输入三次字节和 hash 一致;非法/NaN/Inf/越界全有测试 |
| K2 笛卡尔/耦合 | K2-TRIV-01 trivkins 全类型;K2-TRIV-02 重复轴/extra joints;K2-COUPLED-01 corexy/rose/max/rotate;K2-HAL-01 HAL 等价链 |
identity、both、耦合线性运动学 | K1 | 轴/关节模式、home、限位、HAL 和恢复 golden 全绿 |
| K3 5 轴串联 | K3-5AXIS-01 5axiskins;K3-TRT-01 xyzac/xyzbc/trt;K3-ROBOT-01 SCARA/PUMA/Scorbot;K3-GENSER-01 DH/Jacobian |
5 轴、转台/摆头和串联机器人 | K2、posemath | FK/IK round-trip、分支、奇异、刀尖/刀长和真实配置入口通过 |
| K4 并联机构 | K4-DELTA-01 linear/rotary Delta;K4-TRIPOD-01 tripod;K4-HEX-01 genhex;K4-PENTA-01 pentapod |
全部并联正逆解和迭代恢复 | K1、K2 | 工作空间边界、无解、奇异、分支、lastpose、GUI pins 和故障注入通过 |
| K5 切换/扩展 | K5-SWITCH-01 switchkins;K5-USER-01 静态 userk/ugenser;K5-CFG-01 参数和能力注册 |
可切换和构建期扩展模型 | K3、K4 | 非法切换、缺模块、恢复、版本和权限错误明确;无动态宿主加载 |
| K6 运动集成 | K6-MOTION-01 TP→IK→motion;K6-MOTION-02 FK feedback;K6-HOME-01 home/limit;K6-IO-01 spindle/tool/probe |
运动学与 Task/HAL/IO/数字孪生闭环 | K2-K5 | configs/sim 运动学入口可启动、运行、暂停、急停、恢复 |
| K7 UI/回归 | K7-VIS-01 姿态/关节/刀尖渲染;K7-RECOVERY-01 固定 tick checkpoint/replay 与 workspace 恢复;K7-REG-01 全配置;K7-REG-02 浏览器故障矩阵 |
可视化、恢复和全量回归 | K6、M3/M4 | 轨迹、姿态、joint/world、报警、恢复终点与连续运行一致、回放和多浏览器证据齐全 |
| K8 发布闭合 | K8-REL-01 兼容报告;K8-REL-02 迁移/回滚;K8-REL-03 许可证/来源闭包 |
运动学纳入完整仿真机床发布 | K0-K7 | 受影响条目全部 accepted,无孤儿、无未解释差异、无静默降级 |
K4-TRIPOD-01 已完成:tripodkins.c 的点顶点三杆并联机构已接入统一 forward/inverse/mapping,使用真实 linuxcnc/configs/sim/tklinuxcnc/tripod.ini 和 linuxcnc/lib/hallib/tripodsim.hal 验证 XYZ/AD-BD-CD 映射、above/below 根分支、三角不等式无解、基面奇异、关节限位、退化基座和固定零迭代;native/WASM JSON 与 state hash 一致,官方 oracle 因锁定来源缺少 linuxcnc/unit_tests/kinematics/** 继续显式 blocked。证据见 coverage/tripod-kinematics.report.json。
K4-PENTA-01 已完成:pentakins.c/.h 的五杆并联机构已接入统一 forward/inverse/mapping,使用真实 linuxcnc/configs/sim/axis/pentapod/pentapod.ini/kinematics.hal 和派生非零姿态 seed,固定 XYZAB 映射、roll/pitch 姿态约束、tool-offset 双端几何、Newton 5x5 收敛/迭代上限/最大误差/奇异/非正杆长/关节限位边界;native/WASM JSON 与 state hash 一致。官方 oracle 因锁定来源缺少 linuxcnc/unit_tests/kinematics/** 继续显式 blocked。证据见 coverage/pentapod-kinematics.report.json。
K5-SWITCH-01 已完成:基于真实 xyzac-trt.ini 的 sparm=identityfirst 约定接入三槽位 switchkins 容器,固定 type 0 identity、type 1 xyzac-trt、type 2 userk 注册表;切换通过旧模式 FK、目标模式 IK 的 prepare/commit,保证 pose 连续,失败和 abort 保持旧模式,非法模式、缺模块和切换中断分别返回稳定错误码;native/WASM runner、模式状态 hash 和恢复计数一致。官方 oracle 因锁定来源缺少 linuxcnc/unit_tests/kinematics/** 继续显式 blocked。证据见 coverage/switchkins-kinematics.report.json。
K5-USER-01 已完成:userkfuncs.c 的 identity 模板和 ugenserkins.c 的 genser 使用面已收敛为构建期静态描述符,固定 ABI v1 与 forward/inverse/static capability mask;userk 可注册到 switchkins type 2,ugenser 复用已验证的静态 genser FK/IK,调用计数与 state hash 进入确定性状态。带路径名称、宿主 .so、ABI/能力不匹配、未知和未初始化模块均 fail-closed;旧 ugenser userspace CLI 按其源码警告明确排除,不作为 oracle。native/WASM runner 一致,官方 oracle 继续显式 blocked。证据见 coverage/userkins-kinematics.report.json。
K5-CFG-01 已完成:18 个内建运动学类型进入 ABI v1 构建期只读注册表,稳定登记 LinuxCNC 模块名、type、必需坐标、关节范围、forward/inverse/identity/iterative/switchable/extra-joint/duplicate-coordinate 能力位,以及 mapping/limits/offsets/tool/pivot/geometry/DH/solver 参数族。18 个最小配置全部经实际 sim_kinematics_init 验证;能力/参数不满足、type/坐标/关节错配、未知和路径名称均返回稳定错误。native/WASM 注册表 JSON 与 hash 一致,官方 oracle 继续显式 blocked。证据见 coverage/kinematics-registry.report.json。
K6-MOTION-01 已完成:新增固定 tick 的 TP→IK→关节样本队列适配器,复用现有 sim_tp 和 sim_kinematics_inverse_ex,每帧先推进 planner 再事务式生成关节样本;队列容量 64、暂停/恢复、非有限输入、planner 错误、IK 奇异和容量满边界均有固定错误码。IK 或容量失败会回滚 planner/kinematics 状态,nominal/capacity/inverse rollback 的 native/WASM JSON 与 state hash 一致;官方 oracle 继续显式 blocked。证据见 coverage/kinematics-motion.report.json。
K6-MOTION-02 已完成:新增固定 tick 的 actual-joint→FK feedback 适配器,保存世界 pose、joint snapshot、forward/inverse flags、tick、valid 和双层错误码;首次读取前返回 stale,非有限和 joint-count 错误不推进有效状态,forward 不支持/失败时保留无效状态且不发布 pose。native/WASM feedback JSON 与 state hash 一致,官方 oracle 继续显式 blocked。证据见 coverage/kinematics-feedback.report.json。
K6-HOME-01 已完成:新增固定 home sequence、sim_kinematics_home 初始化和 joint limit/FK 检查适配器;未 home、非法 sequence、越界、非有限和 joint-count 错误均 fail-closed,越界时保留上一帧有效 pose/joints,home/limit state hash 稳定,native/WASM JSON 一致。官方 oracle 继续显式 blocked。证据见 coverage/kinematics-home-limit.report.json。
K6-IO-01 已完成:新增固定 tick 的 sim_io spindle/tool/probe 适配器,注册 LinuxCNC motion/iocontrol pins 和 sim-io-servo 调度函数;主轴覆盖限速、加减速、inhibit、到速、制动、revs/index、orient 和故障,换刀覆盖 prepare/prepared/change/changed、停主轴互锁、abort/fault/恢复,探针覆盖 arm、输入边沿和 forward pose 锁存。非法 pin 类型、超限、未 ready、急停、故障清除和恢复均有稳定错误码;native/WASM JSON 与 state hash 一致。官方 IO/kinematics oracle 继续显式 blocked。证据见 coverage/io-runtime.report.json。
K7-RECOVERY-01 已完成当前恢复适配子集:固定 tick checkpoint 携带 context、event cursor、snapshot/state hash 和 operation ledger;Worker replay 严格拒绝损坏 checkpoint、未知 schema、缺号/重复事件和未确认副作用,abort 进入显式 aborted,恢复终点与连续运行状态 hash 对齐;native sim_event_import 与 Worker replay/recovery 测试均通过。官方 recovery oracle、完整 native/WASM 全状态对照和浏览器 OPFS 崩溃场景因锁定来源缺失继续显式 blocked。证据见 coverage/workspace-recovery.report.json、web/worker/replay.mjs、web/workspace/recovery.mjs。
K8-REG-01 已完成全配置回归适配:从统一配置图确定性枚举 264 个运动学入口(覆盖 233 个 configs/sim 主入口及 include/测试入口),逐入口保留 INI 形状、资源行、缺失/未解析资源、注册表归属和静态启动预检结果;资源图没有新增孤儿入口或未拥有模板。native/WASM 的 kinematics、motion、feedback、home/limit、IO 固定样本和重复运行 hash 均稳定,Worker replay、workspace recovery、sim session 摘要重复一致;恢复终点与连续状态 hash 对齐。当前资源缺失、未索引 include、未注册模块和官方 kinematics/recovery oracle 均显式 blocked,派生配置摘要不作为官方 golden。证据见 coverage/configuration-regression.report.json、scripts/generate_configuration_regression.py、scripts/test_configuration_regression.py。
K4-HEX-01 已完成:genhexkins.c 的六腿 Stewart 平台已接入统一 forward/inverse/mapping,使用真实 linuxcnc/configs/sim/axis/vismach/hexapod-sim/hexapod.ini 与 kinematics.hal 验证六腿闭式逆解、Newton 6x6 正解、确定性初始种子、alternate seed、非正 strut、迭代上限、最大误差、奇异 Jacobian、限位、HAL GUI/迭代 pin 和 native/WASM state hash;官方 oracle 继续显式 blocked。证据见 coverage/genhex-kinematics.report.json。
每个 K 里程碑都必须同时更新 coverage/manifest.jsonl、source map、golden 索引、任务指针和证据摘要。算法代码通过单测但没有配置入口或 UI 姿态证据时,不能推进到下一个里程碑。
6. 运动学测试矩阵
每个实现族至少有以下测试层;参数和样本由 K0 清单生成,不允许只挑“容易收敛”的点:
| 层 | 样本 | 必测内容 |
|---|---|---|
| 纯函数 | 合法 pose/joint、边界、随机种子固定的网格 | FK、IK、FK→IK→FK、IK→FK→IK、flags 和 residual |
| 几何边界 | 轴/关节最小最大、工作空间边缘、旋转回绕 | limit、无解、奇异、分支连续性 |
| 配置 | 每个非 trivkins configs/sim 入口及所有 trivkins 变体 |
参数、坐标、HALFILE、tool/var、资源图和启动错误 |
| 运动 | G0/G1/G2/G3、5 轴刀尖、jog、home、暂停、abort | TP→IK→motion、反馈、following error、最终姿态 |
| 故障 | 探针、限位、主轴/换刀、迭代不收敛、Python 异常 | 报警、停止、恢复、状态 hash 和事件顺序 |
| 持久化 | checkpoint、journal、刷新、Worker 重启、离线 | flags、lastpose、seed、工具和姿态恢复一致 |
| 浏览器 | Chromium/Firefox/Safari 计划矩阵、窄屏/触摸 | 3D 非空、姿态无跳变、背压、错误可见 |
6.1 Golden 和容差
native runner 为每个样本保存输入 hash、配置 hash、算法版本、pose/joint、flags、residual、iterations、branch、错误和最终 state hash。WASM 只允许在已登记的浮点字段使用容差;以下字段必须精确:
status / error_code / kinematics_type / branch_id
flags / current_tick / event_order / config_hash
axis-to-joint mapping / home result presence / state transition
差异报告必须包含首个 divergent tick、字段路径、原生值、WASM 值、容差、source_id 和可重放命令。迭代不收敛不得被提高最大迭代次数或放宽容差“修绿”;应记录算法参数和失败原因。
7. 与整体仿真机床的接合顺序
运动学主线不是独立库,接合顺序固定如下:
- K1 ABI 完成后,
sim_motion只通过KinematicsRegistry调用,不再硬编码 trivkins。 - K2 完成后,解释器/TP 的 canonical 轨迹接入 axis/joint 变换,HAL 反馈接入 FK。
- K3/K4 完成后,数字孪生为每种机床提供真实 joint/pose 反馈、限位、回零和故障;Vismach/Three.js 使用同一 FK 结果。
- K5 完成后,Python/remap/VCP 获得只读 kinematics 状态和受控切换命令;切换必须经过 Task 同步点。
- K6 完成后,OPFS checkpoint 保存 kinematics type、参数、flags、lastpose、seed 和 joint/pose 状态。
- K7 完成后,UI 同时显示世界坐标、关节坐标、机床姿态、刀尖和限制原因;不能把 axis 数值当成所有机床的刀具姿态。
8. 当前执行和停止线
当前 M2-CORE-04 的 unit_tests/kinematics/** 缺失仍然是 K0 的输入审计事项,不自动改成实现任务。立即顺序为:
K0-INV-01确认锁定提交的 kinematics 文件、符号和测试路径,生成缺失输入报告。K0-INV-02从configs/sim、tests/matrixkins和实际 kinematics 配置生成入口图;这些可以作为配置 oracle,但不能冒充缺失的官方 unit test。K0-ORACLE-01在原生 runner 中建立 FK/IK JSONL schema 和最小 trivkins/corexy/非平凡样本。- 经审查决定是否创建新的输入契约/context lock;未决定前保持 blocked,不跳到 HAL 节点。
- K1 ABI 和数值政策完成后,再按 K2→K5 算法族推进;K6 以前不开放全量 UI 运动学声明。
以下条件必须停止并回到对应里程碑:输入源或配置入口遗漏;正逆解首次差异未定位;分支/flags/lastpose 未进入快照;算法依赖墙钟或随机数;用伪造 pose、钳位越界值、放宽容差或刷新重建掩盖失败;用户运动学需要未登记的动态宿主库。
完成 K8 后,运动学才能从“核心切片”升级为“仿真机床完整能力”,并作为整个 LinuxCNC Web/WASM 发布的必要条件。