Files
linuxcncWebWASM/docs/linuxcnc-web-wasm-3axis-tutorial-control-panel-implementation.md

20 KiB
Raw Permalink Blame History

3axis Tutorial Web 控制面板源程序对标实施方案

目标

为固定案例 linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini 建立与 LinuxCNC AXIS 控制面板可观察行为一致的 Web 控制面板。

唯一运行时数据来源是 LinuxCNC 源码编译得到的 WASM core,以及由 Dedicated Worker 投影的 authoritative snapshot/event。React 只能发送命令、显示状态和呈现诊断;不得在浏览器端重新推导任务状态、运动轨迹、DRO、工具状态、门禁或错误结果。

本方案是固定案例的控制面板实施合同,不宣称全量 LinuxCNC、实时硬件或 release candidate。机器可读的源语义规则见 coverage/linuxcnc-source-semantics-contract.json,共享实现见 web/workspace/linuxcnc-source-semantics.mjs。

硬约束和功能矩阵

以下约束是所有 PANEL 任务的共同通过条件:

  1. 网页控制面板的唯一数据来源是 LinuxCNC WASM;React 不得生成、修正或覆盖 canonical state。
  2. 状态机严格对标 LinuxCNC 源程序;状态数值、迁移顺序、错误码和 gate reason 必须有 source line 和 WASM/Worker evidence。
  3. 所有按钮逻辑制约必须与 LinuxCNC AXIS 源程序一致;按钮 disabled/enabled、模式切换、ESTOP/limit/fault gate 不允许由 UI 自行猜测。
  4. 刀具路径预览必须来自 WASM canonical motion events,并与原生 LinuxCNC 的 segment 顺序、source line、端点、圆弧中心/法向、turn、units 和最终 hash 一致;没有 WASM event 时必须 fail-closed。
# 功能 LinuxCNC 原生 WASM 支持 Web 实现状态 优先级 主要任务
1 加载数控程序 ✅ ✅ PANEL-07 P0 PROGRAM_LOAD、exact source/hash、diagnostic
2 刀具路径预览 ✅ ✅ PANEL-11 P0 WASM motion event、segment golden、no JS preview
3 取消急停 ✅ ✅ PANEL-05 P0 ESTOP_RESET/recover source state transition
4 上电 ✅ ✅ PANEL-05 P0 STATE_OFF -> STATE_ON and gate
5 复位 ✅ ✅ PANEL-05/PANEL-12 P0 task reset、fault clear、checkpoint reconciliation
6 HOME 回零 ✅ ✅ PANEL-06 P0 individual/all home、home sequence、home-limit ABI
7 执行 G 代码 ✅ ✅ PANEL-07 P0 run/pause/resume/step/abort/restart
8 实时路径显示 ✅ ✅ PANEL-10 P0 authoritative pose/toolpath -> Three.js
9 实时坐标显示 ✅ ✅ PANEL-08 P0 commanded/actual/relative DRO、units
10 MDI 功能 ✅ ✅ PANEL-07 P1 MDI mode、queue limit、active program rejection
11 JOG 功能 ✅ ✅ PANEL-06 P1 manual mode、continuous/incremental、stop
12 按钮逻辑制约 ✅ ✅ PANEL-03 P0 complete AXIS gate matrix and error reasons

表中的“Web 实现状态”在任务完成前只能是 queued、in_progress 或 blocked;现有 selected-case smoke/Worker evidence 不得自动把矩阵项标记为 verified。

功能项统一验收证据

每个矩阵项必须同时保存:LinuxCNC source path/line/hash、WASM export/state field、Worker command/event、React control ID、normal/boundary/error/ESTOP/recovery sample、native/WASM/Worker logical tick、输入/输出/state/event hash 和 self-hashed report。P0 项缺任一项即保持 blocked;P1 项不能阻塞 P0 实施,但不能被宣称完成。

源程序映射

Web 控制面板区域 LinuxCNC 源输入 WASM/Worker 唯一来源 React 允许行为 禁止行为
电源、急停、状态灯 axis.py 状态更新、linuxcnc STATE_*/MODE_*/INTERP_* sim_task canonical + axis_state 显示、发送命令、显示 gate reason 本地切换 ON/ESTOP
File/Program axis.py open_file_guts, reload_file, task_run WASM interpreter events + Worker program state 编辑器输入、发送 LOAD/RUN/RESTART JS 解析 G-code 或伪造当前行
MDI axis.py ensure_mode, send_mdi_command WASM interpreter/task mode/queue 提交文本、显示拒绝 本地判断 MDI 成功
Manual/Jog/Home axis.py jog_plus, jog_minus, home_all_joints, home_joint WASM motion queue + home/limit ABI 按钮、方向、速度输入 JS 插值、修改 position/home
DRO/active codes axis.py update, task_modename, motion_modename, interp_statename WASM task/interpreter/motion snapshot 格式化显示 从命令文本推导状态
Feed/spindle override axis.py set_feedrate, set_spindlerate WASM/Worker device canonical slider/number input 直接修改 React store
Spindle/coolant/tool/probe axis.py manual controls、案例 HAL、sim_io WASM IO/device canonical 显示、发送命令、fault recovery mock device response
Preview/3D axis.py preview/canon、案例 Vismach executable WASM canonical motion + Worker visual snapshot Three.js 渲染 JS G-code preview/几何 authority
配置诊断 linuxcnc-source-semantics-contract.v1 Worker startup snapshot 显示 TASK_READY/BLOCKED_*、source/line basename 替换、隐藏缺失资源

源代码锚点:

  • AXIS startup/open-file:linuxcnc/src/emc/usr_intf/axis/scripts/axis.py 约 3991-3998 行。
  • AXIS status projection:同文件 update、task_modename、motion_modename、interp_statename。
  • AXIS command gates:同文件 ensure_mode、task_run、task_pause、task_resume、task_stop、jog_*、home_*、estop_clicked。
  • 参数文件和程序前缀:linuxcnc/src/emc/rs274ngc/rs274ngc_pre.cc、linuxcnc/src/emc/task/emctask.cc。
  • 案例 UI/HAL/Vismach:linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini、.hal 和 3axis-tutorial。

控制面板数据契约

Worker 每次响应必须能追溯到同一个 context_id、session_id、logical_tick 和 state_hash。控制面板消费以下投影字段:

snapshot:
  task: wasm sim_task canonical state
  program: WASM interpreter/program state
  motion: WASM motion queue state
  home_limit: WASM kinematics home/limit state
  hal: static/virtual HAL projection with source diagnostics
  devices: WASM sim_io/tool/spindle/coolant/probe state
  configuration: startup state, exact resources, optional_missing, runtime_fixtures
  axis_state: additive AXIS state/mode/interpreter view
  visual: pose, joints, toolpath and Vismach pose projection
  state_hash: hash of the canonical projection

每个命令必须携带 operation_id,并产生 pending/result/error event。UI gate 只读取上一份 authoritative snapshot;命令被拒绝时显示 Worker 返回的 stable error code、message key、source/line 和 gate reason。错误、ESTOP、limit、following-error、资源缺失和能力边界必须可见,不能变成静默 disabled。

分层接口责任

层 必须提供 允许缓存 不得提供
LinuxCNC source/native recorder 常量、状态迁移、命令顺序、错误/拒绝语义、segment golden stdout/log/screenshot hash 浏览器状态
wasm-core canonical task/interpreter/motion/home-limit/HAL/IO state、fixed tick、canonical event raw ABI bytes、read-only sample UI 文案或按钮 gate
Dedicated Worker command ledger、session lifecycle、snapshot/event 转发、diagnostic/source line、checkpoint/trace 序列化协议和 operation trace JS authority mirror、JS G-code 解析
React/Web panel command input、snapshot projection、accessibility、visual rendering 最近一份 snapshot 用于显示 改写 state、推导成功、推导轨迹

任何层违反责任都必须在测试中以 authority_violation 失败;“结果看起来一致”不能替代唯一来源证明。

面板命令 envelope

所有 P0/P1 命令使用已有 protocol.v1 envelope,不为 UI 单独发明协议:

{
  "schema_version": 1,
  "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1",
  "session_id": "axis3-panel",
  "seq": 42,
  "operation_id": "axis-program-run-000042",
  "kind": "PROGRAM_RUN",
  "payload": {}
}

响应至少包含 kind、seq、operation_id、logical_tick、payload.task、payload.program、payload.motion、payload.axis_state、payload.state_hash。错误响应必须包含 code、message_key、source/line(若有)、gate_reason 和拒绝时的完整 snapshot。

严格状态机和按钮真值表

源常量和 AXIS 视图必须使用 docs/linuxcnc-web-wasm-3axis-tutorial-state-machine.md 中的数值,不得只使用同名字符串:

AXIS 状态 LinuxCNC source state 允许的面板操作 必须拒绝
ESTOP STATE_ESTOP cancel ESTOP、显示诊断 power/home/run/MDI/JOG
ESTOP_RESET STATE_ESTOP_RESET power on、ESTOP run/home/MDI/JOG
OFF STATE_OFF power/reset、ESTOP run/home/MDI/JOG
ON/IDLE STATE_ON + INTERP_IDLE load/run/MDI/manual/home/jog/device 与当前 mode/limit/fault 冲突的操作
HOME source home transient 等待 home result、ESTOP run/MDI/重复 home
RUNNING INTERP_READING/WAITING pause/abort/ESTOP home/jog/MDI/load
PAUSED INTERP_PAUSED resume/abort/ESTOP/step(按源 gate) home/jog/普通 MDI

按钮 gate 的可执行真值样本必须至少包含:

操作 正常条件 拒绝样本
加载程序 ON + INTERP_IDLE 或源允许的 manual load OFF、RUNNING、资源缺失
预览 WASM motion events 已存在 WASM event 缺失、解析错误
取消急停 ESTOP/ESTOP_RESET 按源状态转换 snapshot 过期、seq/tick 错误
上电 ESTOP_RESET -> ON 或源定义 reset 流程 ESTOP 未 reset、fault latch
复位 abort/clear/recover 的源顺序 active motion、坏 checkpoint
HOME ON + MANUAL + INTERP_IDLE OFF、AUTO/MDI、limit/fault、未满足 previous home
G-code run ON + AUTO + IDLE + taskfile 无程序、MDI、paused、ESTOP
实时路径/DRO snapshot tick/hash 可验证 snapshot stale、state hash mismatch
MDI ON + MDI 且 queue 未满 AUTO active、queue full、ESTOP
JOG ON + MANUAL + IDLE AUTO/MDI、未 home、limit/fault

刀具路径预览一致性算法

预览和执行都必须使用 WASM interpreter canonical motion event;Web 不得将原始 G-code 再解析一遍。每个 segment 的比较字段固定为:

segment:
  source_line: integer
  motion_type: rapid|linear|arc
  start: pose(x,y,z,a,b,c,u,v,w)
  end: pose(x,y,z,a,b,c,u,v,w)
  center: pose_or_null
  normal: vector_or_null
  turn: integer
  velocity: finite_number
  units: mm|inch
  plane: G17|G18|G19
  sequence: integer

验收顺序:

  1. native recorder 使用固定程序和固定 units/modal 初始状态生成 segment JSONL。
  2. WASM sim_interpreter_read_motion 生成同字段事件;Worker 只排序/封装,不补字段。
  3. 比较 segment count、source line、顺序、字段值和 canonical hash;浮点比较使用 source/ABI 规定的 exact或明确 tolerance,不能用截图相似度替代。
  4. Three.js 只渲染已比较的 visual projection;canvas 非空是必要条件,不是轨迹正确性的充分条件。
  5. 任意字段首差必须记录 first_divergent_segment、source_line、logical_tick、field、native、wasm,并阻止 preview/execute 继续宣称一致。

禁止条件:WASM event buffer 为空时调用 JS previewGcode;用当前 DRO 终点反推完整路径;用 native screenshot 通过 Web segment hash;用墙钟时间推进路径。

功能矩阵报告模板

每个功能项使用同一结构,便于控制面板任务和后续自动聚合:

feature_id: PANEL-07
matrix_item: execute_gcode
priority: P0
status: queued|in_progress|verified|blocked
source:
  paths: []
  lines: []
  sha256: []
authority:
  wasm_exports: []
  canonical_fields: []
worker:
  commands: []
  events: []
react:
  control_ids: []
  projection_fields: []
samples:
  normal: []
  boundary: []
  error: []
  estop_or_fault: []
  recovery: []
comparison:
  native_hash: null
  wasm_hash: null
  worker_hash: null
  first_divergent_tick: null
stop_reason: null
report_sha256: null

verified 只允许在 source、authority、worker、react、5 类 samples、comparison 和 self-hash 全部存在时使用。任何 REAL-EXCLUDED、SOURCE_BLOCKED、WASM_CAPABILITY_BLOCKED 都必须保持 blocked,并带 failure sample。

面板布局和交互范围

桌面和移动布局都必须保持以下固定区域,不因动态文字改变尺寸:

  1. 顶栏:案例名、WASM capability、连接/session、TASK_READY/BLOCKED、ESTOP 和 recover。
  2. 左侧状态:machine power、task mode、interp state、program status、current line、logical tick、state hash。
  3. 中央机床视图:Three.js Vismach 3-axis model、tool pose、joints、limits、toolpath、axis labels。
  4. 右侧 DRO:commanded/actual/relative 的 X/Y/Z、unit、feed/spindle override、active G/M codes。
  5. 下方 tabs:Manual、MDI、Program、Diagnostics;每个 tab 的控件 gate 来自 Worker snapshot。
  6. 操作条:Home all/individual、jog +/-/stop、Run/Pause/Resume/Step/Abort/Restart、spindle/coolant/tool/probe/ESTOP。
  7. 诊断面板:按事件顺序显示 source path、line、code、reason、first divergent tick、recovery status。

熟悉符号使用 AXIS 源图标或 lucide icon;按钮必须有 accessible name、disabled reason 和 keyboard path。控件不能仅通过颜色表示 fault/ESTOP。

功能缺口移植流程

当 WASM/Worker 当前能力不满足 AXIS 行为时,严格按以下顺序处理:

  1. 从 LinuxCNC 源文件定位函数、状态常量、命令顺序和错误语义,记录 source path、line、source hash。
  2. 判断是否属于纯仿真可移植行为。实时内核、真实硬件、宿主动态 loader、宿主 GUI/Python 进程只能登记 REAL-EXCLUDED/HOST_EXCLUDED,不能伪造 WASM parity。
  3. 先增加 native source sample 和失败测试,再在 wasm-core 增加 C ABI/状态实现;ABI 变更必须建立新 context,不能就地改锁定 ABI。
  4. 增加真实 WASM module 测试,再接 web/worker adapter;Worker 只投影 WASM canonical,不保留 JS authority 镜像。
  5. 最后接 React 命令/渲染,补 normal、boundary、error、non-finite、capacity、pause/resume、ESTOP、recovery 样本。
  6. 记录首个 divergent phase/tick、native/WASM/Worker hash、checkpoint/trace/recovery hash,更新 self-hashed report。

详细实施任务

P0/P1 执行顺序

先完成 P0 的 authority、状态机、按钮 gate、程序加载/执行、preview、实时路径和实时坐标,再实现 P1 的 MDI/JOG 扩展。P0 任务之间按 PANEL-01 -> PANEL-02 -> PANEL-03 -> PANEL-05 -> PANEL-06/PANEL-07 -> PANEL-08/PANEL-10/PANEL-11 -> PANEL-14 -> PANEL-15 执行;P1 的 MDI/JOG 只能复用同一 WASM/Worker authority,不能另建一套 UI state。

P0 完成的硬条件:12 项矩阵中的 1-9、12 有 native source reference、真实 WASM module、Worker sequence 和 React evidence;刀具路径 preview 与 native canonical segments 的 hash/端点一致;所有按钮 gate 在正常、运行、暂停、MDI、ESTOP、limit、fault、未 home 和 queue-full 样本中一致。P1 完成的硬条件:10-11 的 MDI/JOG 与 P0 状态机、queue、home/limit、ESTOP gate 共用同一 snapshot,不能产生 divergent tick。

ID 任务 主要实现 直接源输入 验收输出 依赖
PANEL-01 源控件 inventory 把 AXIS 菜单、toolbar、快捷键、Manual/MDI/Auto、DRO、诊断控件登记为稳定 IDs axis.py、AXIS Tcl UI、案例 INI source inventory + control ID contract 无
PANEL-02 snapshot projection contract 固定 task/program/motion/home/hal/devices/configuration/axis_state/visual 字段、tick/hash 和 event envelope sim-session.mjs、T4/T3 reports schema-compatible projection test 01
PANEL-03 source gate matrix 逐命令复刻 AXIS ensure_mode、状态和 gate;禁止 React 自判定 axis.py command functions、axis-contract.mjs gate matrix normal/error/ESTOP test 01/02
PANEL-04 startup/config panel 显示 exact resources、optional OPEN_FILE/graphic、HAL/resource/INI diagnostics 和 runtime fixtures source semantics contract、案例 INI/HAL TASK_READY/BLOCKED_* UI test 02
PANEL-05 power/ESTOP/recover 对齐 STATE_OFF/ON/ESTOP/ESTOP_RESET 和 recover transition axis.py、sim_task、sim_io transition/event/hash report 02/03
PANEL-06 Manual/Home/Jog 对齐 individual/all home、continuous/incremental jog、stop、joint/teleop gate axis.py jog_*/home_*、T4 home-limit native/WASM/Worker sequence report 03/05
PANEL-07 Program/MDI 对齐 open/load/reload/run/pause/resume/step/abort/restart/MDI queue and active-program rejection axis.py、WASM interpreter/task program control and current-line report 03/05
PANEL-08 DRO/active codes 对齐 actual/commanded/relative、units、feed/spindle、active G/M/modal display AXIS update/stat mixins、WASM snapshot DRO golden and unit switch test 02/06/07
PANEL-09 device panels 对齐 spindle ramp/at-speed, coolant, tool prepare/change, probe, limit/FERROR faults 案例 HAL、sim_io、tool-IO report device fault/recovery report 05/06/07
PANEL-10 Vismach/3D 按 3axis-tutorial Python model 和 HAL pins 实现 geometry/pose/tool continuity 案例 executable、Vismach source、Three.js view canvas pixel/nonblank/pose report 02/06/08/09
PANEL-11 editor/preview Worker WASM preview、source line highlighting、active G-code 和 diagnostics sim_interpreter、AXIS editor/preview no-JS-preview test + source-line parity 07/08
PANEL-12 persistence/recovery UI checkpoint, journal, trace import, .var/.bak/position/tool.tbl restart and fail-closed recovery T4/T6 reports、workspace recovery recovered endpoint and no duplicate side effects 05/07/09
PANEL-13 keyboard/accessibility/layout AXIS shortcut mapping、focus order、ARIA、desktop/mobile no-overlap AXIS shortcut table、React source DOM/accessibility/visual report 01/03/08/10/11
PANEL-14 native/Worker/UI recorder 同一 operation sequence、same logical ticks、first divergence and hash comparison native runner、Dedicated Worker、React sequence ledger and diff report 05..13
PANEL-15 selected-case acceptance 汇总所有面板区域、normal/boundary/error/recovery 和 release boundaries all PANEL evidence self-hashed closure report 14

验收和停止条件

通过条件:每个 PANEL row 有 source reference、WASM authority、Worker test、UI evidence、state/event hash 和 recovery sample;同一操作序列 native/WASM/Worker/UI 的首个差异可定位;控制面板无 JS authority、无 JS G-code preview、无 basename 替换。

保持 blocked:缺 source/oracle/resource、WASM ABI 不足、首个 divergent tick 未定位、Worker snapshot/hash 不稳定、恢复重复副作用、只在 Chromium 可见但 browser minimum 未锁定,或只能靠 mock/墙钟/宿主能力通过。

停止发布:不把固定案例 verified 写成全量 LinuxCNC parity;Firefox/Safari、OPFS 物理崩溃、实时硬件、官方 oracle、许可证和 owner release gate 继续保持 STOP_RELEASE。

证据命令

python3 scripts/validate_baseline.py
python3 scripts/validate_task_pointer.py nextTask1.md --lock context-lock.json
python3 scripts/test_source_semantics_contract.py
node web/workspace/test_source_semantics.mjs
node web/workspace/test_sim_case_loader.mjs
node web/worker/test_sim_case_matrix_s8_06.mjs
node web/worker/test_wasm_canonical_state.mjs
node web/worker/test_wasm_canonical_state_checkpoint.mjs
node web/worker/test_axis3_selected_case.mjs
node web/worker/test_axis3_visible_completion.mjs
npm --prefix web/react run typecheck
npm --prefix web/react run build

每个 PANEL 任务必须增加专属测试和 self-hashed report;未完成的任务保留 queued/blocked,不能从 UI smoke 直接升级为 parity。