Files
linuxcncWebWASM/docs/linuxcnc-web-wasm-complete-simulation-plan.md

272 lines
20 KiB
Markdown
Raw Permalink 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.
# LinuxCNC Web/WASM 完整仿真移植实施计划
**版本**:1.0
**状态**:implementation baseline
**目标基线**:仓库 `context-lock.json` 锁定的 LinuxCNC 版本
**接续入口**:[`nextTask1.md`](../nextTask1.md)
**已有专项资料**:
- [`linuxcnc-web-wasm-full-port-implementation.md`](linuxcnc-web-wasm-full-port-implementation.md)
- [`linuxcnc-web-wasm-simulation-coverage.md`](linuxcnc-web-wasm-simulation-coverage.md)
- [`linuxcnc-web-wasm-source-map.md`](linuxcnc-web-wasm-source-map.md)
- [`linuxcnc-web-wasm-frontend-communication-design.md`](linuxcnc-web-wasm-frontend-communication-design.md)
- [`linuxcnc-web-wasm-kinematics-migration-plan.md`](linuxcnc-web-wasm-kinematics-migration-plan.md)
本文件是“完整仿真移植”实施轨道的唯一执行目录。仿真实现不依赖 release、owner、许可证审批或发布候选流程;这些内容不参与仿真任务的排队、执行和验收。
## 1. 目标和边界
### 1.1 目标
在浏览器 Dedicated Worker 中运行 LinuxCNC 的可观察仿真行为,使用 WASM 承载数值密集型核心,使用 Web API 承载工程、恢复、界面和可视化。用户应能:
1. 导入或创建一个 LinuxCNC 仿真工程。
2. 解析 INI/HAL/工具表/参数/程序/Python/VCP/ClassicLadder 等资源。
3. 启动仿真并看到确定性的 `READY`、`RUNNING`、`PAUSED`、`ESTOP`、`FAULT`、`STOPPED` 状态。
4. 执行 G-code、MDI、jog、home、pause、resume、single-step、abort、override 和模式切换。
5. 观察轴/关节/姿态/轨迹、HAL pin/signal、主轴、工具、探针、限位、冷却、报警和 Python/VCP 状态。
6. 注入故障、暂停、导出 checkpoint、刷新 Worker、从 OPFS 恢复并得到相同的确定性终点。
7. 对纳入范围的 `configs/sim` 入口给出 `READY` 或可定位的 `BLOCKED/ERROR`,不静默跳过资源。
### 1.2 仿真范围
以下行为必须实现或有原生/WASM 对照证据:
| 功能域 | 必须覆盖的行为 | 浏览器实现边界 |
|---|---|---|
| 工程与配置 | workspace、INI/include/变量、HAL、工具表、参数、程序、Python、VCP、ClassicLadder、资源错误 | `/workspace` 虚拟文件系统;禁止宿主绝对路径、`..`、符号链接逃逸 |
| Task/命令 | mode、MDI、program load/run/pause/resume/step/abort、错误、状态、operation ledger | Worker 单写者;主线程只能发送版本化命令 |
| 解释器 | G/M/O words、模态、单位、坐标、参数、子程序、循环、宏、过滤器和错误行号 | 运行在 WASM/Python Worker;能力拒绝必须稳定 |
| TP/motion | canonical queue、直线/圆弧/同步运动、速度/加速度/jerk、blend、exact stop、暂停和恢复 | 逻辑 tick 取代硬实时墙钟,保持顺序和结果确定 |
| 运动学 | trivkins、gantry/CoreXY、5/6 轴、TRT、机器人、Delta/Tripod/Hexapod/Pentapod、switchkins/userk | 静态链接、注册表选择;动态模块加载不进入浏览器 |
| 轴/关节 | joint/axis 映射、home、软限位、following error、外部偏置、jog、override、estop | 由数字孪生提供输入和故障状态 |
| HAL/组件 | pin、signal、parameter、thread、function、addf、setp、net、twopass、`.comp` 静态组件 | 组件不得访问宿主设备、进程、网络或动态库 |
| PLC/IO | ClassicLadder scan、寄存器、定时器、计数器、数字/模拟 IO、采样、触发、背压 | 虚拟寄存器和逻辑设备;真实 transport 为 `REAL-EXCLUDED` |
| 设备数字孪生 | 主轴、编码器、探针、限位、home、换刀、冷却/润滑、故障/延迟/抖动 | 故障注入必须可记录、回放、恢复,不使用未固定的随机数 |
| Python/remap/VCP | 白名单模块、参数/工具/INI API、remap/filter 生命周期、VCP pin/回调/异常 | Pyodide Worker;`subprocess/socket/device files` 明确拒绝 |
| 持久化/恢复 | journal、checkpoint、snapshot、event replay、Worker restart、OPFS quota、migration、rollback、offline | OPFS 只保存已提交数据,不参与运动计算 |
| Web 工作流 | 编辑器、MDI、控制台、HAL/PLC 面板、报警、恢复向导、轨迹和机床可视化 | UI 只消费 authoritative snapshot/event,不反写核心状态 |
### 1.3 明确排除
以下是宿主能力排除,不是仿真行为排除:
- 真实 PCI/USB/串口/GPIO/并口、真实伺服和真实安全回路。
- Linux PREEMPT_RT、内核线程、共享内存 NML/CMS 进程边界、`fork/exec` 和动态 `.so` 加载。
- 浏览器无法提供的设备文件、任意宿主路径、任意网络 socket 和真实硬件时钟。
被排除的宿主层必须返回稳定的 `REAL-EXCLUDED` 错误;对应的轴、主轴、编码器、探针、限位、换刀和 IO 仍必须由数字孪生覆盖。
## 2. 架构和不变量
```text
Web UI / Editor / Three.js
│ protocol.v1
Dedicated Worker
CommandRouter → TaskLedger → SimScheduler
├─ SimTask / rs274 / canonical
├─ TP / posemath / kinematics
├─ SimMotion / home / limits
├─ SimHAL / components / ClassicLadder
├─ SimIO / digital twins
└─ PythonRuntime / remap / VCP
├─ SnapshotPublisher / EventBus / TraceRecorder
└─ WorkspaceRuntime → WasmFS/POSIX → OPFS journal/checkpoint
│
└─ native oracle 使用同一输入和命令序列
```
必须保持以下不变量:
1. Worker 是唯一 authoritative state 写者;UI 不读取 WASM 指针,不直接写 HAL/OPFS。
2. `sim_step(cycles)` 是唯一改变仿真结果的入口;墙钟只负责调度和让出事件循环。
3. 命令按 `seq` 顺序提交,`operation_id` 幂等;确认丢失先对账,不重复执行副作用。
4. 固定宽度 ABI、明确的 protocol/snapshot/event/workspace schema 和稳定错误码优先于 UI 便利。
5. 状态、事件、轨迹、HAL、IO、Python 和恢复结果都能产生确定性 hash。
6. 缺少输入、未支持能力、配额不足、非法路径、非有限数和 schema mismatch 必须 fail closed。
7. 任何 native/WASM 差异都保留首个 divergent tick、字段路径、单位、容差和来源证据。
### 2.1 固定 tick 顺序
每一个逻辑 tick 依次执行:
1. 对账并去重已确认命令。
2. 执行 Task/解释器预算,更新模态、参数、当前行和 canonical。
3. 执行 TP 前瞻、速度/加速度/jerk、blend/exact-stop。
4. 调用 kinematics inverse,检查奇异性、joint 数量、limits 和 NaN/Inf。
5. 更新 motion、home、jog、following error、外部偏置、estop/limit。
6. 按静态线程/function 顺序运行 HAL、组件、编码器、主轴、探针、换刀和 PLC scan。
7. 运行 IO 完成、超时、报警、Python/remap/VCP 回调;回调不能越过当前 tick。
8. 生成 snapshot/event/trace/state hash,再执行已提交 checkpoint/journal。
快速运行、1x、单步、暂停恢复、导出导入和 replay 在相同逻辑终点必须得到相同 hash。
## 3. 功能实施顺序
### F0:输入、来源和契约
- 以 `context-lock.json`、source index、manifest、config resource graph 和 protocol schema 为输入。
- 为每个 source/file/symbol/config/test 建立 `source_id → feature_id → task_id → test_id → oracle_id` 关系。
- 固定 `sim_task.v1`、`command-envelope.v1`、`snapshot.v1`、`event-log.v1`、`workspace-package.v1` 的字段、版本和错误策略。
- 缺少官方测试输入时保留 `blocked`,不得用近似目录伪装官方 oracle。
### F1:运行时骨架
- 建立 `SimTask`、`SimScheduler`、`TaskLedger`、`SnapshotPublisher` 和 `EventBus`。
- 把现有 WASM lifecycle、fixed tick、event、snapshot、G-code runner 接入 authoritative task state。
- 增加容量、非有限值、取消、abort、pause/resume、operation replay 和 checkpoint 边界。
### F2:工作区和配置启动
- 实现虚拟 POSIX 文件 API、规范化路径、大小/配额和事务写入。
- 解析 INI/include/变量,解析 HAL/工具表/参数/程序/Python/VCP/ClassicLadder 资源图。
- 统一 `NEW → MOUNTED → PARSED → RESOLVED → CORE_CREATED → HAL_READY → TASK_READY` 状态机。
- 每个 `configs/sim` 入口输出 `READY` 或带文件/行/字段/source_id 的诊断。
### F3:解释器、Task、TP、motion、kinematics
- 先让 native oracle 输出每个 block 的 modal/canonical/参数和错误,再接入 WASM。
- 接入 O-word/子程序/循环/参数/宏/remap/filter、MDI、program state machine。
- 将 canonical queue 连接 TP、motion 和 kinematics;实现暂停、单步、abort、jog、home、override、limits、following error。
- 按 kinematics registry 逐族接入并保留每个族的 forward/inverse、branch、singularity 和 limit 证据。
### F4:HAL、PLC、IO 和数字孪生
- 解析并执行 pin/signal/parameter/thread/function、`loadrt/addf/setp/net/sets/link*` 和静态 `.comp`。
- 实现 ClassicLadder 工程、scan、寄存器、计数器、定时器、HAL 绑定和诊断。
- 接入 spindle/encoder/probe/limit/home/tool/coolant/IO,支持故障注入、延迟、抖动、恢复和回放。
### F5:Python、remap、VCP
- 固定 Pyodide 版本、manifest、模块白名单、内存/时间/源码限制。
- 实现 `linuxcnc/hal/gstat/INI/tool/parameter/workspace/virtual-clock` 兼容 API。
- 接入 remap/filter 生命周期、VCP descriptor、pin callback、异常隔离和权限拒绝。
### F6:恢复、离线和迁移
- 将 Task、解释器、TP、motion、kinematics、HAL、IO、Python、workspace 和 ledger 纳入 checkpoint。
- 实现 journal prepare/commit、确认丢失对账、崩溃恢复、OPFS quota、离线包、版本迁移和 rollback。
- 恢复必须从最近有效 checkpoint 重放已提交 event,不得只重新加载配置。
### F7:Web 工作流和可视化
- 完善工程导入、编辑器诊断、MDI、run/pause/step/abort、jog/home/override、HAL/PLC/IO/报警面板。
- 以 authoritative snapshot/event 驱动姿态、joint、toolpath、stock、坐标系、工具、主轴和故障渲染。
- 用 Worker 重启、离线、配额和错误场景覆盖 UI 恢复向导;不使用 mock 替代真实 Worker。
### F8:全量兼容、性能和交付
- 对所有纳入范围的 `configs/sim`、相关 tests/unit_tests 和资源入口执行 native/WASM 差异矩阵。
- 固定至少三次重复、快速/1x/单步/恢复、浏览器矩阵、性能、内存和离线报告。
- 许可证、来源、下载、迁移、回滚和 REAL-EXCLUDED 边界全部有证据;只有所有 gate 满足时才讨论 release candidate。
## 4. 任务分解
任务状态只能按 `queued → in_progress → verified` 或 `in_progress → blocked` 转移。每个任务只有一个主要结果,并必须提供输入 context、直接证据、专属测试、完整回归和回滚点。
| ID | 任务 | 依赖 | 主要产物 | 验收重点 |
|---|---|---|---|---|
| P0-01 | 冻结来源、工具链、schema 和 source hash | 无 | context/source baseline | baseline 可重建,缺输入 fail closed |
| P0-02 | 建立 source→feature→task→test 图 | P0-01 | coverage graph/manifest | 无孤儿、重复、未知 ID |
| P0-03 | 固定 ABI/protocol/snapshot/event/workspace 契约 | P0-01 | schema + compatibility tests | 版本 mismatch 和字段缺失拒绝 |
| P1-01 | 建立 `sim_task.v1` authoritative 状态对象 | P0-03 | Task state/native/WASM tests | state hash、状态机、错误码一致 |
| P1-02 | 固定 `sim_step` 调度顺序和 tick budget | P1-01 | scheduler + tick golden | 快速/1x/单步终点一致 |
| P1-03 | 接入 command ledger、幂等和 abort | P1-01 | ledger/replay tests | operation replay 不重复副作用 |
| P1-04 | 将现有 G-code/MDI runner 接入 Task snapshot | P1-01 | Worker/native/WASM report | 当前行、模态、程序状态可观察 |
| P2-01 | 虚拟 POSIX/Workspace API | P1-01 | workspace runtime | 路径、编码、配额、事务错误稳定 |
| P2-02 | INI/include/变量解析器 | P2-01 | parser/resource graph | 行号、循环、缺失资源可诊断 |
| P2-03 | HAL/工具表/参数/程序/Python/VCP/CLP resolver | P2-01 | config resource graph | 所有依赖可定位、不静默替换 |
| P2-04 | 统一配置启动状态机 | P2-02/P2-03/P1-02 | startup resolver/233-entry report | 入口只进入 READY 或 BLOCKED |
| P3-01 | rs274 grammar/modal/parameter 完整闭环 | P1-04 | native/WASM interpreter oracle | block、错误列和 modal hash 一致 |
| P3-02 | O-word、子程序、循环、宏和过滤器 | P3-01/P5-02 | interpreter golden | 深度、预算、异常边界完整 |
| P3-03 | canonical queue、TP 前瞻、blend/exact-stop | P1-02/P3-01 | TP golden/diff report | segment 顺序、速度和首差 tick |
| P3-04 | Task mode、MDI、program state machine | P1-03/P3-01 | command golden | run/pause/resume/step/abort 可恢复 |
| P3-05 | motion、jog、override、home、limits、following error | P3-03 | motion state/故障矩阵 | 轴/关节、estop、limit、home 一致 |
| P3-06 | kinematics registry 和 trivkins/gantry/CoreXY | P3-05 | registry + native/WASM tests | forward/inverse/branch/limits |
| P3-07 | 5/6-axis、TRT、机器人、并联和 switch/user kins | P3-06 | 每族 report/golden | singularity、非有限、缺 oracle 明确 |
| P4-01 | HAL graph/twopass/pin/signal/thread/function | P2-03/P1-02 | HAL graph/runtime | 顺序、类型、重复、未知组件 fail closed |
| P4-02 | 静态 `.comp` 组件和能力 manifest | P4-01 | component manifest/tests | 不动态加载、不访问宿主 |
| P4-03 | ClassicLadder/采样/触发/背压 | P4-01 | PLC runtime/report | scan 顺序、寄存器、故障可回放 |
| P4-04 | spindle/encoder/probe/limit/home/tool/coolant twin | P4-01/P3-05 | device model/fault matrix | 延迟、故障、恢复、hash 一致 |
| P4-05 | IO command/ack/timeout/estop/recover | P4-04/P1-03 | IO Worker/native tests | ack 丢失和恢复不重复副作用 |
| P5-01 | Pyodide runtime、模块白名单和虚拟时钟 | P2-01 | runtime manifest/report | 资源和能力限制稳定 |
| P5-02 | Python linuxcnc/hal/INI/tool/parameter API | P5-01/P3-04 | API compatibility tests | 正常、异常、禁止能力 |
| P5-03 | remap/filter/VCP callback 和隔离 | P5-02/P4-01 | remap/VCP report | 异常不破坏 Worker 核心 |
| P6-01 | snapshot/event/trace 全状态导出 | P1-02/P3-05/P4-05/P5-03 | schema/hash tests | 导入导出 round-trip |
| P6-02 | journal/checkpoint/operation reconciliation | P6-01/P1-03 | recovery matrix | crash、半提交、确认丢失 |
| P6-03 | OPFS/offline/migration/rollback | P6-02/P2-01 | browser recovery report | 离线、配额、版本迁移 |
| P7-01 | Worker protocol/client、backpressure、cancel | P1-03/P6-01 | protocol E2E | seq、schema、timeout、cancel |
| P7-02 | editor/diagnostic/MDI/run workflow | P3-04/P7-01 | browser E2E | 真实 Worker,不用 mock |
| P7-03 | state/HAL/IO/Python/PLC/alarm panels | P4/P5/P7-01 | UI tests | snapshot/event 单向消费 |
| P7-04 | Three.js pose/joint/toolpath/stock view | P3-05/P7-03 | WebGL/canvas tests | 非空、姿态和轨迹跟随 authoritative state |
| P7-05 | recovery/offline/error/permission UX | P6-03/P7-02 | browser fault E2E | 恢复状态可操作、错误可定位 |
| P8-01 | native oracle runner 和 golden schema | P0-03/P3/P4 | JSONL oracle | 同输入、同命令、首差 tick |
| P8-02 | 全量 sim entrypoint matrix | P2-04/P8-01 | startup/diff matrix | 每入口 READY 或诊断 BLOCKED |
| P8-03 | 三次重复和执行模式 determinism | P8-02/P6 | determinism report | 1x/fast/step/recover hash 一致 |
| P8-04 | browser/performance/memory/offline matrix | P7/P8-03 | perf/compat report | P95/P99、配额、WebGL、离线 |
| P8-05 | 来源/许可证/下载/迁移/回滚交付闭合 | P8-02/P8-04 | release evidence | 所有排除项和剩余 blocker 显式保留 |
## 5. 里程碑
| 里程碑 | 名称 | 包含任务 | 退出条件 |
|---|---|---|---|
| M0 | 输入和契约闭合 | P0-01..03 | context/source/schema hash 可重建;输入缺失不会被接受 |
| M1 | Task/WASM/Worker 会话闭合 | P1-01..04 | create/load/MDI/program/tick/pause/abort/snapshot/replay 通过 native/WASM/Worker |
| M2 | 解释器和运动主链 | P3-01..07 | G-code→canonical→TP→motion→kinematics→snapshot 闭合,首差可定位 |
| M3 | 配置启动闭合 | P2-01..04 | 纳入范围的每个入口进入 READY 或带来源诊断的 BLOCKED |
| M4 | HAL/IO/数字孪生闭合 | P4-01..05 | HAL/PLC/主轴/编码器/探针/限位/工具/冷却/estop 故障可执行、可回放 |
| M5 | Python/remap/VCP 闭合 | P5-01..03 | 白名单 API、remap、VCP、异常、能力拒绝和资源限制通过 |
| M6 | 恢复和离线闭合 | P6-01..03 | Worker 重启、OPFS checkpoint、journal、迁移、回滚、离线路径通过 |
| M7 | Web 工作流和可视化闭合 | P7-01..05 | UI 真实消费 Worker authoritative state,Three.js/Canvas 非空并可恢复 |
| M8 | 全量兼容和交付闭合 | P8-01..05 | 全量矩阵、三次 determinism、浏览器/性能和来源证据齐全;仿真结果独立可运行 |
每个里程碑完成时必须生成一份确定性 report,包含 `context_id`、任务 ID、输入/输出 hash、native/WASM/Worker 测试、已知 blocked 项和下一个依赖任务。里程碑不能从 `blocked` 自动跳回 `in_progress`。
## 6. 验收证据和回归门禁
每个任务至少保留:
- native test;适用时必须有 WASM/Worker 对照 test。
- 正常、边界、非有限值、容量、错误、abort、pause/resume、恢复和离线样本。
- 输入 context、source hash、ABI/protocol/schema 影响和直接 evidence 路径。
- 状态 hash、event hash、首个 divergent tick 或明确的 `REAL-EXCLUDED/BLOCKED` 原因。
- 可重跑命令和报告 self-hash。
技术任务的最小回归:
```bash
python3 scripts/validate_baseline.py
python3 scripts/validate_download_index.py
python3 scripts/validate_task_pointer.py
scripts/build-wasm.sh
ctest --test-dir build-native --output-on-failure
for f in web/worker/test_*.mjs; do node "$f" || exit 1; done
for f in web/app/test_*.mjs; do node "$f" || exit 1; done
```
修改配置、协议、恢复或发布证据时,再运行对应的生成器专项测试和完整 Python unittest;生成器产生的报告不能被手工改 hash 伪装为通过。
## 7. 停止线
立即将当前任务标记为 `blocked` 并保留证据的情况:
1. LinuxCNC 来源、官方测试输入、配置资源或协议契约缺失。
2. 需要改变 ABI/protocol/schema/manifest 时,必须同步更新兼容性测试和迁移证据。
3. native/WASM 差异的首个 divergent tick 未定位。
4. 只能删除失败样本、降低检查、静默替换资源或把缺失能力改成 `REAL-EXCLUDED` 才能通过。
5. Python/组件/VCP 需要未经允许的宿主路径、设备、进程或网络能力。
6. checkpoint/journal 无法验证 hash、确认丢失无法对账或恢复会重复副作用。
7. 运行结果依赖未固定的墙钟、随机数、线程竞争或浏览器环境。
blocked 不是失败样本删除理由,也不是自动跳过前置任务的理由。修复后必须重新运行原任务的专属测试和完整回归,再认领下一个依赖满足的任务。
## 8. 当前实现基线
截至本计划建立时,仓库已有:
- WASM/native 核心构建、posemath、解释器、多个 kinematics、HAL、IO 和固定 tick 切片。
- Worker protocol/session、虚拟设备、Python bridge、workspace recovery 和前端基础面板。
- G-code `PROGRAM_LOAD/RUN/PAUSE/RESUME/ABORT/STEP/SEEK`、`MDI_EXECUTE` 的 Worker/WASM 垂直切片。
这些能力仍不能替代 M1-M8 的完整验收。下一项直接实现任务由 [`nextTask1.md`](../nextTask1.md) 指向 `P1-01`:把已有 runner、解释器、motion/kinematics、HAL、IO 和 snapshot 统一纳入 `sim_task.v1` authoritative state,并固定首个可对照的 tick 边界。