1436 lines
45 KiB
Plaintext
1436 lines
45 KiB
Plaintext
# text16.txt - LinuxCNC WASM/browser port continuation
|
||
|
||
Created: 2026-06-16 CST
|
||
|
||
This file continues from `text15.txt`. Use it for the next execution batches.
|
||
|
||
## Current Repository State
|
||
|
||
- Branch: `master`
|
||
- Remote sync state at creation: `master...origin/master`
|
||
- Latest commit at creation:
|
||
|
||
```text
|
||
69ccf93 支持真实G代码程序执行
|
||
```
|
||
|
||
- Working tree at creation: clean
|
||
- Active project tracker still exists at `PROJECT_COMPLETION_TRACKER.md`
|
||
- Previous continuation file: `text15.txt`
|
||
|
||
## Current Priority
|
||
|
||
The first priority remains the real browser CNC simulation page:
|
||
|
||
```text
|
||
wasm-port/runtime/ui/simulation/index.html
|
||
```
|
||
|
||
Primary supporting docs:
|
||
|
||
```text
|
||
wasm-port/docs/real-browser-simulation-priority.md
|
||
wasm-port/docs/axis-style-simulation-implementation.md
|
||
PROJECT_COMPLETION_TRACKER.md
|
||
```
|
||
|
||
Do not switch back to dashboard-only metadata work unless it directly creates a
|
||
gate or unblocks the browser simulation page.
|
||
|
||
## Completed Since text15 Start
|
||
|
||
The browser simulation page now has:
|
||
|
||
- AXIS-style browser shell:
|
||
- titlebar;
|
||
- File / Machine / View / Help menubar;
|
||
- toolbar;
|
||
- Manual Control / MDI tabs;
|
||
- Preview / DRO tabs;
|
||
- G-code pane;
|
||
- machine-state pane;
|
||
- bottom status bar.
|
||
- LinuxCNC-backed WASM execution through `createLinuxCncInterpSdk()`.
|
||
- Built-in test program selector.
|
||
- Built-in program directory:
|
||
|
||
```text
|
||
wasm-port/runtime/ui/simulation/programs/
|
||
```
|
||
|
||
- Current built-in program modules:
|
||
- `square-linear.js`;
|
||
- `pocket-z.js`;
|
||
- `incremental-loop.js`;
|
||
- `arc-g2-g3.js`;
|
||
- `drill-g81.js`.
|
||
- Program inventory export:
|
||
|
||
```text
|
||
wasm-port/runtime/ui/simulation/programs/index.js
|
||
```
|
||
|
||
- Reset / Step Back / Play / Step Forward / Finish playback over LinuxCNC
|
||
canonical motion events.
|
||
- Active G-code line highlighting.
|
||
- Active and executed motion row highlighting.
|
||
- Live XYZ/ABC readout.
|
||
- Full toolpath and executed-path SVG rendering.
|
||
- Moving toolhead marker.
|
||
- Real operator-provided G-code execution:
|
||
- `linuxCncRealSimulationApi.runProgramText(programText, metadata)`;
|
||
- `linuxCncRealSimulationApi.loadProgramFile(file)`;
|
||
- toolbar `Open` file input for `.ngc/.nc/.tap/.gcode/.txt`.
|
||
- Editable AXIS-style G-code pane:
|
||
- loaded file/custom/built-in program text is visible in a textarea;
|
||
- editor text can be changed before execution;
|
||
- toolbar `Run Editor Text` executes the current editor contents;
|
||
- `getProgramText()`, `setProgramText()`, and `runEditorProgramText()` are
|
||
exposed on the browser API.
|
||
- Program source metadata:
|
||
- `program.source`;
|
||
- `program.sourceLabel`;
|
||
- `program.filename`;
|
||
- `document.body.dataset.simulationProgramSource`.
|
||
|
||
## Current Browser API
|
||
|
||
Available on the simulation page:
|
||
|
||
```js
|
||
window.linuxCncRealSimulationApi
|
||
```
|
||
|
||
Current methods:
|
||
|
||
- `getState()`
|
||
- `getPrograms()`
|
||
- `runProgramById(programId)`
|
||
- `runProgramText(programText, metadata)`
|
||
- `loadProgramFile(file)`
|
||
- `getProgramText()`
|
||
- `setProgramText(text, metadata)`
|
||
- `runEditorProgramText()`
|
||
- `getPlaybackFrame()`
|
||
- `resetPlayback()`
|
||
- `stepPlayback(delta)`
|
||
- `play()`
|
||
- `pause()`
|
||
- `finishPlayback()`
|
||
|
||
All G-code execution must continue to go through LinuxCNC-backed WASM. Browser
|
||
JS must not interpret G-code or implement planner/machine semantics.
|
||
|
||
## Validation Baseline
|
||
|
||
The latest full validation completed successfully:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
ui_node_smokes=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
axis_style_simulation_docs_node_smoke=ok
|
||
real_browser_simulation_priority_docs_node_smoke=ok
|
||
project_release_gate=ok
|
||
```
|
||
|
||
Useful focused commands:
|
||
|
||
```bash
|
||
wasm-port/tests/ui/node/verify_real_simulation_programs.sh
|
||
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
|
||
SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_real_simulation_browser.sh
|
||
wasm-port/tests/docs/node/verify_axis_style_simulation_docs.sh
|
||
wasm-port/tests/docs/node/verify_real_browser_simulation_priority_docs.sh
|
||
```
|
||
|
||
Full gate:
|
||
|
||
```bash
|
||
wasm-port/tests/host/verify_project_release_gate.sh
|
||
```
|
||
|
||
## Semantic Boundary
|
||
|
||
LinuxCNC remains the only CNC semantic source.
|
||
|
||
Browser code may:
|
||
|
||
- render UI layout and interaction state;
|
||
- read user-selected G-code files/text;
|
||
- call the SDK/WASM boundary;
|
||
- render LinuxCNC-produced canonical output;
|
||
- animate playback over LinuxCNC-produced canonical motion events;
|
||
- stage future OPFS/session files when that integration is added.
|
||
|
||
Browser code must not implement:
|
||
|
||
- G-code interpretation;
|
||
- modal semantics;
|
||
- tool/cutter compensation semantics;
|
||
- parameter semantics;
|
||
- kinematics;
|
||
- remap behavior;
|
||
- planner behavior;
|
||
- machine-control behavior not backed by LinuxCNC/WASM or validated session APIs.
|
||
|
||
## Next Recommended Batches
|
||
|
||
### 1. Real G-code Editor Pane
|
||
|
||
Status: complete.
|
||
|
||
Implemented:
|
||
|
||
- show loaded file/custom text in an editor area;
|
||
- allow editing before run;
|
||
- add `Run Editor Text`;
|
||
- preserve line numbers and active-line highlighting;
|
||
- expose `linuxCncRealSimulationApi.getProgramText()`;
|
||
- expose `linuxCncRealSimulationApi.setProgramText(text, metadata)`.
|
||
- expose `linuxCncRealSimulationApi.runEditorProgramText()`.
|
||
|
||
Validation:
|
||
|
||
- browser smoke sets editor text, runs it, and verifies changed LinuxCNC
|
||
canonical output.
|
||
|
||
### 2. OPFS Program Persistence
|
||
|
||
Connect real G-code programs to OPFS:
|
||
|
||
- save current program text to OPFS;
|
||
- load program text from OPFS;
|
||
- show OPFS path in status/readiness;
|
||
- keep browser file loading as an import path, not the only path.
|
||
|
||
Validation:
|
||
|
||
- browser smoke load file -> save OPFS -> reload OPFS -> run -> playback.
|
||
|
||
### 3. AXIS DRO/Modal State Expansion
|
||
|
||
Improve the DRO panel without inventing unsupported data:
|
||
|
||
- derive any available fields from LinuxCNC output or validated summaries;
|
||
- show unavailable fields as `n/a`;
|
||
- add tests that prevent silently fabricated G54/G92/TLO/DTG values.
|
||
|
||
Validation:
|
||
|
||
- browser smoke verifies no `undefined` and no fabricated unavailable values.
|
||
|
||
### 4. Preview Controls
|
||
|
||
Add AXIS-like preview controls:
|
||
|
||
- zoom fit;
|
||
- reset view;
|
||
- optional pan/viewport scale state;
|
||
- keep SVG nonblank and stable.
|
||
|
||
Validation:
|
||
|
||
- browser smoke verifies viewBox changes/reset and toolhead/path remain visible.
|
||
|
||
### 5. Machine/Session Integration
|
||
|
||
Use the existing OPFS/session workflow:
|
||
|
||
- load machine session;
|
||
- show machine file readiness;
|
||
- stage INI/parameter/tool-table/program into WASM;
|
||
- block run with explicit reasons when readiness is missing.
|
||
|
||
Validation:
|
||
|
||
- OPFS/session browser smoke covers load -> run -> playback.
|
||
|
||
## Adding More Built-In Test Programs
|
||
|
||
To add a built-in test:
|
||
|
||
1. Add a module under:
|
||
|
||
```text
|
||
wasm-port/runtime/ui/simulation/programs/
|
||
```
|
||
|
||
2. Export an object with:
|
||
|
||
```js
|
||
{
|
||
id,
|
||
label,
|
||
category,
|
||
text,
|
||
expectedMotionTypes,
|
||
}
|
||
```
|
||
|
||
3. Import it in:
|
||
|
||
```text
|
||
wasm-port/runtime/ui/simulation/programs/index.js
|
||
```
|
||
|
||
4. Add it to `SIMULATION_TEST_PROGRAMS`.
|
||
|
||
5. Run:
|
||
|
||
```bash
|
||
wasm-port/tests/ui/node/verify_real_simulation_programs.sh
|
||
SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_real_simulation_browser.sh
|
||
```
|
||
|
||
## Commit / Upload Rule
|
||
|
||
After each completed implementation batch:
|
||
|
||
1. Run focused smoke(s).
|
||
2. Run `wasm-port/tests/host/verify_project_release_gate.sh` when feasible.
|
||
3. Commit with a Chinese title and conclusion body.
|
||
4. Push to:
|
||
|
||
```text
|
||
http://154.8.160.151:3000/wangdequan/cnc_wams.git
|
||
```
|
||
|
||
## Immediate Suggested Start
|
||
|
||
Start with "OPFS Program Persistence" because the page can now load, edit, and
|
||
run real G-code text/files, but programs are not yet saved to or restored from
|
||
OPFS from within the AXIS shell.
|
||
|
||
Updated after batch 9: compact run summary is implemented. The next recommended
|
||
batch is adding machine/session run summaries to saved OPFS/session artifacts or
|
||
making the preview controls more AXIS-like with fit-state persistence.
|
||
|
||
## Execution Record
|
||
|
||
### 一、2026-06-16 Real G-code Editor Pane
|
||
|
||
按 `text16.txt` 的 Immediate Suggested Start 推进,完成 AXIS shell 内真实 G-code 编辑区。
|
||
|
||
本批新增实质能力:
|
||
|
||
- `runtime/ui/simulation/index.html` 新增 editable G-code pane:
|
||
- `data-axis-shell="program-editor"`;
|
||
- `textarea[data-program-editor]`;
|
||
- `data-program-editor-status`;
|
||
- 工具栏新增:
|
||
- `Run Editor Text`;
|
||
- 页面状态新增 `programEditorState`;
|
||
- 内置程序加载、真实文本执行、真实文件加载都会同步到 editor textarea;
|
||
- editor textarea 修改后可直接运行;
|
||
- `window.linuxCncRealSimulationApi` 新增:
|
||
- `getProgramText()`;
|
||
- `setProgramText(text, metadata)`;
|
||
- `runEditorProgramText()`;
|
||
- browser smoke 新增验证:
|
||
- 初始内置程序会同步到 editor;
|
||
- `runProgramText()` 后 editor 同步自定义文本;
|
||
- `loadProgramFile()` 后 editor 同步文件文本和 filename metadata;
|
||
- `setProgramText()` 修改 editor 内容;
|
||
- `runEditorProgramText()` 通过 LinuxCNC WASM 执行修改后的 G-code,并验证 canonical output
|
||
出现修改后的坐标。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
browser_real_simulation_page_smoke=ok
|
||
real_simulation_programs_node_smoke=ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- editor 只保存和显示 G-code 文本;
|
||
- G-code 执行仍通过 LinuxCNC-backed WASM;
|
||
- JS 不解释 G-code、不规划刀路、不推导 modal/machine semantics。
|
||
|
||
### 二、2026-06-16 AXIS DRO/Modal State and Preview Controls
|
||
|
||
继续按 AXIS 实现文档推进,完成 Phase 3/4 的可落地部分。
|
||
|
||
本批新增实质能力:
|
||
|
||
- `runtime/ui/simulation/simulation-app.js` 新增:
|
||
- `createModalState(resultText)`;
|
||
- `createDroState(frame)`;
|
||
- `zoomToolpathViewBox(viewBox, zoom)`;
|
||
- modal display 不再使用硬编码 active G-code 文本,改为显示 LinuxCNC
|
||
`canon_event=UPDATE_TAG` 字段;
|
||
- DRO 显示:
|
||
- actual X/Y/Z/A/B/C 来自 LinuxCNC canonical motion playback frame;
|
||
- DTG/G54/G92/TLO/velocity 在当前 canonical 输出不可用时明确显示 `n/a`;
|
||
- `window.linuxCncRealSimulationApi` 新增:
|
||
- `getDroState()`;
|
||
- `getModalState()`;
|
||
- `fitPreview()`;
|
||
- `zoomPreview(factor)`;
|
||
- `resetPreview()`;
|
||
- preview toolbar 新增 Fit / Zoom In / Zoom Out / Reset;
|
||
- SVG preview 保留 full path、executed path、toolhead,并支持 viewBox 缩放/恢复。
|
||
|
||
测试覆盖:
|
||
|
||
- Node smoke 验证:
|
||
- modal state 来自 `UPDATE_TAG`;
|
||
- unavailable DRO 字段保持显式 `n/a`;
|
||
- viewBox zoom 会收窄;
|
||
- browser smoke 验证:
|
||
- API 暴露;
|
||
- modal DOM 显示 LinuxCNC 字段;
|
||
- DRO 不伪造 DTG/G54/G92/TLO/velocity;
|
||
- preview zoom 改变 viewBox,reset 恢复 fit viewBox;
|
||
- 现有 built-in/custom/file/editor G-code 执行继续走 LinuxCNC WASM。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
axis_style_simulation_docs_node_smoke=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- JS 只解析 LinuxCNC canonical text 中已经输出的 `UPDATE_TAG` 字段用于显示;
|
||
- JS 不解释 G-code,不推导 modal 语义,不计算 DTG/G54/G92/TLO/velocity;
|
||
- preview zoom/reset 只改变 SVG viewBox,不改变 LinuxCNC 生成的 motion events。
|
||
|
||
### 三、2026-06-16 AXIS OPFS Program Persistence
|
||
|
||
继续按 AXIS 实现文档推进,完成 Phase 2 的 OPFS program persistence 闭环。
|
||
|
||
本批新增实质能力:
|
||
|
||
- AXIS editable G-code pane 新增:
|
||
- OPFS G-code filename 输入;
|
||
- `Save OPFS`;
|
||
- `Load OPFS`;
|
||
- 页面复用既有 OPFS helpers:
|
||
- `saveGcodeProgram()`;
|
||
- `loadGcodeProgram()`;
|
||
- `gcodeProgramPath()`;
|
||
- `window.linuxCncRealSimulationApi` 新增:
|
||
- `getOpfsProgramState()`;
|
||
- `saveProgramToOpfs(filename)`;
|
||
- `loadProgramFromOpfs(filename)`;
|
||
- OPFS load 会调用现有 `runProgramText()`,因此 reloaded program 仍通过
|
||
LinuxCNC-backed WASM 执行;
|
||
- OPFS metadata 写入 program state:
|
||
- `program.source = "opfs"`;
|
||
- `program.opfsPath = "linuxcnc/gcode/<filename>"`;
|
||
- statusbar 显示 `Loaded OPFS: ...`。
|
||
|
||
browser smoke 新增验证:
|
||
|
||
- 设置 editor G-code;
|
||
- 保存到 `linuxcnc/gcode/axis-opfs-roundtrip.ngc`;
|
||
- 修改 editor 为不同内容;
|
||
- 从 OPFS 重新加载保存的程序;
|
||
- 验证 reloaded canonical output 出现保存内容的坐标;
|
||
- 验证 editor、body dataset、statusbar 和 OPFS state metadata 同步。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
browser_real_simulation_page_smoke=ok
|
||
real_simulation_programs_node_smoke=ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- OPFS 只持久化 G-code 文本;
|
||
- OPFS load 后仍走 LinuxCNC-backed WASM interpreter;
|
||
- JS 不解释 G-code,不推导机床状态,不绕过 canonical output。
|
||
|
||
### 四、2026-06-16 AXIS Machine/Session Readiness
|
||
|
||
继续按 AXIS 实现文档推进,完成 Phase 5 的 readiness 前半段。
|
||
|
||
本批新增实质能力:
|
||
|
||
- Manual Control panel 新增 `data-axis-shell="machine-session"` 区域:
|
||
- machine id;
|
||
- session id;
|
||
- G-code filename;
|
||
- `Check Session`;
|
||
- readiness phase/missing/path readout;
|
||
- 页面复用既有 OPFS/session helper:
|
||
- `readMachineSessionReadiness()`;
|
||
- `window.linuxCncRealSimulationApi` 新增:
|
||
- `getMachineReadiness()`;
|
||
- `checkMachineSessionReadiness(options)`;
|
||
- readiness DOM 同步:
|
||
- `document.body.dataset.machineSessionReady`;
|
||
- `data-machine-readiness-phase`;
|
||
- `data-machine-readiness-missing`;
|
||
- `data-machine-readiness-path="ini"`;
|
||
- `data-machine-readiness-path="gcode"`。
|
||
|
||
browser smoke 新增验证:
|
||
|
||
- 检查不存在的 machine/session,确认 readiness 为 blocked,并报告 missing
|
||
`ini` 和 `gcode`;
|
||
- 通过既有 OPFS helpers 写入:
|
||
- machine INI;
|
||
- parameter file;
|
||
- tool table;
|
||
- G-code;
|
||
- machine session snapshot;
|
||
- 再次调用 AXIS API 检查 readiness,确认 phase 为 `ready`,missing 为空;
|
||
- 验证 readiness paths 与 OPFS path model 一致,并同步到 API/body/DOM。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
browser_real_simulation_page_smoke=ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- readiness 只检查 OPFS 文件存在和 snapshot envelope;
|
||
- JS 不合成 INI/tool/parameter/G-code 语义;
|
||
- 本批不加载或执行完整 machine session,只把可运行前置条件暴露给 AXIS shell。
|
||
|
||
### 五、2026-06-16 AXIS Machine/Session WASM Staging
|
||
|
||
继续按 AXIS 实现文档推进,完成 Phase 5 的 ready session load/stage 能力。
|
||
|
||
本批新增实质能力:
|
||
|
||
- Manual Control panel 的 machine-session 区域新增:
|
||
- `Load Session`;
|
||
- loaded INI WASM path;
|
||
- loaded parameter WASM path;
|
||
- loaded tool-table WASM path;
|
||
- 页面复用既有 LinuxCNC-backed helpers:
|
||
- `createLinuxCncInterpSdk()`;
|
||
- `createLinuxCncIniSdk()`;
|
||
- `loadMachineSessionFromOpfs()`;
|
||
- `window.linuxCncRealSimulationApi` 新增:
|
||
- `getMachineSessionLoadState()`;
|
||
- `loadReadyMachineSession(options)`;
|
||
- `loadReadyMachineSession()` 先调用 readiness check;blocked 时返回 blocked
|
||
load state,不 stage;
|
||
- ready 时创建 LinuxCNC interp/INI SDK,调用 `loadMachineSessionFromOpfs()`,
|
||
把 OPFS INI/parameter/tool-table staged 到 WASM filesystem;
|
||
- DOM 同步:
|
||
- `document.body.dataset.machineSessionLoaded`;
|
||
- `data-machine-session-loaded-path="ini"`;
|
||
- `data-machine-session-loaded-path="parameters"`;
|
||
- `data-machine-session-loaded-path="toolTable"`。
|
||
|
||
browser smoke 新增验证:
|
||
|
||
- 在 ready machine/session 基础上调用 `loadReadyMachineSession()`;
|
||
- 使用显式 WASM paths:
|
||
- `/work/axis-smoke/machine.ini`;
|
||
- `/work/axis-smoke/linuxcnc.var`;
|
||
- `/work/axis-smoke/tool.tbl`;
|
||
- 验证 API 返回 loaded state;
|
||
- 验证 API/body/DOM 中 loaded paths 同步。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
browser_real_simulation_page_smoke=ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- session load/stage 完全通过既有 LinuxCNC-backed SDK 和 OPFS bridge;
|
||
- JS 不解释 INI/tool-table/parameter/G-code;
|
||
- 本批只 stage machine session,不改变 program execution semantics。
|
||
|
||
### 六、2026-06-16 AXIS Loaded-Session Program Execution
|
||
|
||
继续按 AXIS 实现文档推进,让 loaded machine session 真正参与程序执行。
|
||
|
||
本批新增实质能力:
|
||
|
||
- `simulation-app.js` 新增:
|
||
- `runLinuxCncProgram(interp, programText, options)`;
|
||
- `runRealBrowserSimulation({ interp, iniPath })`;
|
||
- state.execution:
|
||
- `mode: "linuxcnc-wasm"`;
|
||
- `mode: "linuxcnc-wasm-with-ini"`;
|
||
- `iniPath`;
|
||
- AXIS page 在 `loadReadyMachineSession()` 成功后保留 staged interpreter;
|
||
- 后续 built-in/custom/editor/OPFS text execution 自动使用:
|
||
- staged interpreter;
|
||
- loaded session INI WASM path;
|
||
- LinuxCNC-backed `runProgramWithIni()`;
|
||
- program source label 会显示 `Session INI: <wasm path>`。
|
||
|
||
browser smoke 新增验证:
|
||
|
||
- 在 ready session staged 后设置 editor G-code;
|
||
- 调用 `runEditorProgramText()`;
|
||
- 验证 returned state:
|
||
- `execution.mode === "linuxcnc-wasm-with-ini"`;
|
||
- `execution.iniPath === "/work/axis-smoke/machine.ini"`;
|
||
- canonical output 包含修改后的 G-code 坐标;
|
||
- source label 包含 loaded session INI path。
|
||
|
||
Node smoke 新增验证:
|
||
|
||
- `runLinuxCncProgram()` 无 INI 时调用 `runProgram()`;
|
||
- 有 INI 时调用 `runProgramWithIni()`;
|
||
- `runRealBrowserSimulation({ interp, iniPath })` 返回
|
||
`linuxcnc-wasm-with-ini` execution metadata。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- JS 只选择 LinuxCNC-backed interpreter SDK 方法;
|
||
- G-code 解释仍由 LinuxCNC WASM 执行;
|
||
- INI/tool/parameter state 仍由 existing OPFS bridge 和 LinuxCNC SDK staged/loaded。
|
||
|
||
### 七、2026-06-16 AXIS Run Mode Status and OPFS Session-Backed Execution
|
||
|
||
继续按 AXIS 实现文档推进,补齐 visible run-mode 状态,并扩展 OPFS program
|
||
在 loaded session 下的执行覆盖。
|
||
|
||
本批新增实质能力:
|
||
|
||
- toolbar status strip 新增:
|
||
- `Run mode Standalone`;
|
||
- loaded session 执行后显示 `Session-backed: <iniPath>`;
|
||
- statusbar 同步显示 run mode;
|
||
- body dataset 新增:
|
||
- `data-run-mode="standalone"`;
|
||
- `data-run-mode="session-backed"`;
|
||
- `window.linuxCncRealSimulationApi` 新增:
|
||
- `getRunMode()`;
|
||
- 每次 program render 后同步 run-mode UI/API 状态。
|
||
|
||
browser smoke 新增验证:
|
||
|
||
- 初始页面 run mode 为 standalone;
|
||
- loaded session editor run 后 run mode 切换为 session-backed;
|
||
- OPFS-loaded G-code 在 session-backed 模式下执行:
|
||
- 保存 `axis-session-opfs.ngc` 到 OPFS;
|
||
- 修改 editor 为不同内容;
|
||
- 从 OPFS load/run;
|
||
- 验证 `execution.mode === "linuxcnc-wasm-with-ini"`;
|
||
- 验证 canonical output 来自 OPFS 保存内容;
|
||
- 验证 source label 同时包含 OPFS path 和 Session INI path。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- run mode 只反映当前 LinuxCNC-backed execution path;
|
||
- OPFS program load/run 仍通过 LinuxCNC-backed `runProgramWithIni()`;
|
||
- JS 不解释 G-code,也不实现 session semantics。
|
||
|
||
### 八、2026-06-16 AXIS Run Mode Session Toggle
|
||
|
||
继续按 AXIS 实现文档推进,补齐 standalone/session-backed 显式切换。
|
||
|
||
本批新增实质能力:
|
||
|
||
- Manual Control machine-session actions 新增:
|
||
- `Use Session` checkbox;
|
||
- run mode 逻辑新增:
|
||
- loaded session 存在且 Use Session 开启时,程序执行走 loaded session INI;
|
||
- Use Session 关闭时,即使 session staged,也回到 standalone execution;
|
||
- `window.linuxCncRealSimulationApi` 新增:
|
||
- `setUseLoadedSession(value)`;
|
||
- `getRunMode()` 返回:
|
||
- `mode`;
|
||
- `label`;
|
||
- `iniPath`;
|
||
- `useLoadedSession`;
|
||
- `sessionLoaded`。
|
||
|
||
browser smoke 新增验证:
|
||
|
||
- loaded session editor run 后为 session-backed;
|
||
- 调用 `setUseLoadedSession(false)` 后 checkbox 同步关闭;
|
||
- 再次运行 editor G-code,确认:
|
||
- `execution.mode === "linuxcnc-wasm"`;
|
||
- `execution.iniPath === null`;
|
||
- body run mode 维持 standalone;
|
||
- 调用 `setUseLoadedSession(true)` 后 checkbox 同步开启;
|
||
- 后续 OPFS program load/run 再次使用 loaded session INI。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- Use Session 只选择 LinuxCNC-backed execution method;
|
||
- 不修改 staged machine session 内容;
|
||
- JS 不解释 G-code/INI/tool/parameter semantics。
|
||
|
||
### 九、2026-06-16 AXIS Run Summary
|
||
|
||
继续按 AXIS 实现文档推进,增加 compact run summary,方便操作时判断当前运行上下文。
|
||
|
||
本批新增实质能力:
|
||
|
||
- Machine State readout 新增:
|
||
- Execution Mode;
|
||
- Session INI;
|
||
- OPFS Program;
|
||
- Session State;
|
||
- `window.linuxCncRealSimulationApi` 新增:
|
||
- `getRunSummary()`;
|
||
- run summary 字段:
|
||
- `apiName: "real-browser-simulation-run-summary"`;
|
||
- `executionMode`;
|
||
- `runMode`;
|
||
- `sessionIniPath`;
|
||
- `opfsProgramPath`;
|
||
- `readinessPhase`;
|
||
- `sessionLoadPhase`;
|
||
- `programSource`;
|
||
- readiness/load/run/toggle 后都会同步 run summary DOM。
|
||
|
||
browser smoke 新增验证:
|
||
|
||
- 初始 summary 为 standalone `linuxcnc-wasm`;
|
||
- session ready/load 后 summary 显示 `ready / loaded`;
|
||
- session-backed editor run 后 summary 显示:
|
||
- `linuxcnc-wasm-with-ini`;
|
||
- `/work/axis-smoke/machine.ini`;
|
||
- Use Session 关闭后 standalone run summary 回到:
|
||
- `linuxcnc-wasm`;
|
||
- Session INI `n/a`;
|
||
- session-backed OPFS run 后 summary 显示:
|
||
- OPFS program path `linuxcnc/gcode/axis-session-opfs.ngc`。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- run summary 只汇总已有 LinuxCNC-backed execution/session/readiness state;
|
||
- 不推导 CNC semantics;
|
||
- 不改变 execution path。
|
||
|
||
### 十、2026-06-17 AXIS MDI Text and Preview Pan
|
||
|
||
继续按 AXIS 实现文档推进,补齐 MDI scratch 文本路径和 preview pan 控制。
|
||
|
||
本批新增实质能力:
|
||
|
||
- AXIS MDI panel 新增:
|
||
- `data-mdi-program-text` scratch G-code textarea;
|
||
- `Load MDI Text`;
|
||
- `Run MDI Text`;
|
||
- `data-mdi-status`;
|
||
- `window.linuxCncRealSimulationApi` 新增:
|
||
- `loadProgramText(text, metadata)`;
|
||
- `runMdiProgramText(text)`;
|
||
- `loadProgramText()` 只把 operator text staging 到 AXIS G-code pane,
|
||
不执行、不解释 G-code;
|
||
- `runMdiProgramText()` 复用既有 `runProgramText()`,继续走 LinuxCNC-backed
|
||
WASM execution;
|
||
- preview controls 新增 pan left/right/up/down;
|
||
- `simulation-app.js` 新增纯显示 helper:
|
||
- `panToolpathViewBox(viewBox, offset)`;
|
||
- browser API 新增:
|
||
- `panPreview(dx, dy)`;
|
||
- `fitPreview()` / `resetPreview()` 清除 pan offset,zoom/pan 不改变 canonical
|
||
motion state。
|
||
|
||
browser smoke 新增验证:
|
||
|
||
- MDI 控件存在;
|
||
- `loadProgramText()` 可以 staging 文本到 editor/statusbar;
|
||
- MDI scratch 文本执行后 canonical output 包含 LinuxCNC-produced
|
||
`STRAIGHT_FEED`;
|
||
- `panPreview()` 会移动已填充 toolpath viewBox;
|
||
- `fitPreview()` 会清除 pan offset 并恢复 fit viewBox。
|
||
|
||
Node smoke 新增验证:
|
||
|
||
- `panToolpathViewBox()` 只平移 viewBox,不改变 width/height;
|
||
- existing zoom helper 仍围绕 fit viewBox 缩放。
|
||
|
||
文档同步:
|
||
|
||
- `wasm-port/docs/axis-style-simulation-implementation.md` 将
|
||
`loadProgramText()` 从 future API 移入 required API;
|
||
- Phase 2 增补 MDI text execution;
|
||
- Phase 4 增补 preview pan;
|
||
- Immediate Next Batch 更新为当前后续方向:run-control blocked/ready
|
||
messaging 和 preview state readback。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
axis_style_simulation_docs_node_smoke=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
git diff --check ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- MDI text 只是 operator-provided program text,仍由 LinuxCNC WASM 解释;
|
||
- preview pan/zoom 只改变 SVG viewBox;
|
||
- JS 不实现 G-code、modal、planner、kinematics 或 machine runtime semantics。
|
||
|
||
### 十一、2026-06-17 AXIS Run-Control State and Preview State Readback
|
||
|
||
继续按“页面样式和功能对标 LinuxCNC AXIS”的方向推进,补齐 operator-facing
|
||
状态反馈,避免 session-backed/standalone 执行路径不透明。
|
||
|
||
本批新增实质能力:
|
||
|
||
- toolbar status strip 新增 run-control 状态行:
|
||
- `data-run-control-state`;
|
||
- `document.body.dataset.runControlPhase`;
|
||
- 初始显示 `fallback`,说明 Use Session 开启但尚无 loaded machine session;
|
||
- Machine State readout 新增:
|
||
- Run Control;
|
||
- Preview;
|
||
- browser API 新增:
|
||
- `getRunControlState()`;
|
||
- `getPreviewState()`;
|
||
- run-control state 字段:
|
||
- `apiName: "real-browser-simulation-run-control-state"`;
|
||
- `phase`;
|
||
- `requestedMode`;
|
||
- `executionMode`;
|
||
- `reason`;
|
||
- `canUseSession`;
|
||
- `loadedIniPath`;
|
||
- preview state 字段:
|
||
- `apiName: "real-browser-simulation-preview-state"`;
|
||
- `zoom`;
|
||
- `pan`;
|
||
- `fitViewBox`;
|
||
- `viewBox`;
|
||
- preview controls 的 pan/zoom 状态同步到:
|
||
- `data-preview-zoom`;
|
||
- `data-preview-pan`;
|
||
- Machine State Preview;
|
||
- Manual Control 新增 explicit blocked LED:
|
||
- `data-axis-machine-control-state`;
|
||
- 明确 jog/spindle/coolant 未绑定真实 machine runtime。
|
||
|
||
AXIS visual polish:
|
||
|
||
- preview pan controls 从长文字改为更接近工具按钮的 `< > ^ v`;
|
||
- 保留 `aria-label` 和原有 `data-preview-pan-*` selectors;
|
||
- 控件仍保持密集、灰色、边框式 AXIS 风格。
|
||
|
||
browser smoke 新增验证:
|
||
|
||
- 初始 run-control 为 fallback;
|
||
- run-control DOM 解释 standalone fallback 原因;
|
||
- preview pan 后 API/DOM 同步;
|
||
- fit 后 pan offset 清零;
|
||
- session load 后 run-control 显示 loaded INI 可用;
|
||
- session-backed run 后 run-control 为 ready;
|
||
- Use Session 关闭后 run-control 说明 loaded session 被 bypass;
|
||
- real-machine controls 必须显示 `not bound` blocked 状态。
|
||
|
||
文档同步:
|
||
|
||
- `wasm-port/docs/axis-style-simulation-implementation.md` 增补:
|
||
- `getRunControlState()`;
|
||
- `getPreviewState()`;
|
||
- real jog/spindle/coolant unbound blocked state;
|
||
- run-control ready/fallback 状态。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
axis_style_simulation_docs_node_smoke=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
git diff --check ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- run-control 只反映当前 LinuxCNC-backed execution path;
|
||
- preview state 只反映 SVG viewBox;
|
||
- unbound machine-control 状态不伪造真实 jog/spindle/coolant 行为。
|
||
|
||
### 十二、2026-06-17 AXIS Canonical Machine Status Panel
|
||
|
||
继续推进 AXIS 对标,把左侧和 Machine State 中的 spindle/coolant/tool/override
|
||
状态从静态 UI 升级为 LinuxCNC canonical output 派生状态。
|
||
|
||
本批新增实质能力:
|
||
|
||
- `simulation-app.js` 新增:
|
||
- `createMachineStatusState(resultText)`;
|
||
- simulation state 新增:
|
||
- `machineStatus`;
|
||
- browser API 新增:
|
||
- `getMachineStatusState()`;
|
||
- machine status 字段:
|
||
- `apiName: "real-browser-simulation-machine-status-state"`;
|
||
- `source: "linuxcnc-canonical-events"`;
|
||
- `spindle.state` / `spindle.direction` / `spindle.speed`;
|
||
- `coolant.mist` / `coolant.flood`;
|
||
- `tool.selected` / `tool.current` / `tool.pocket` / `tool.lengthOffset`;
|
||
- `overrides.feed` / `overrides.speed` / `overrides.adaptiveFeed` /
|
||
`overrides.feedHold`;
|
||
- AXIS UI 新增/同步:
|
||
- Manual Control Spindle status LED;
|
||
- Manual Control Coolant status LED;
|
||
- Machine State Spindle row;
|
||
- Machine State Coolant row;
|
||
- Machine State Tool row;
|
||
- Machine State Overrides row;
|
||
- 没有 LinuxCNC canonical event 的字段保持 `n/a`。
|
||
|
||
canonical event mapping:
|
||
|
||
- `SET_SPINDLE_SPEED` -> spindle speed;
|
||
- `START_SPINDLE_CLOCKWISE` / `START_SPINDLE_COUNTERCLOCKWISE` -> spindle
|
||
direction/state;
|
||
- `STOP_SPINDLE_TURNING` -> spindle off;
|
||
- `MIST_ON/OFF`、`FLOOD_ON/OFF` -> coolant state;
|
||
- `SELECT_TOOL`、`CHANGE_TOOL_NUMBER`、`USE_TOOL_LENGTH_OFFSET` -> tool/TLO;
|
||
- `ENABLE/DISABLE_*_OVERRIDE`、`ENABLE/DISABLE_FEED_HOLD` -> override rows。
|
||
|
||
browser smoke 新增验证:
|
||
|
||
- 初始 built-in program 未产生 machine-status events 时,spindle/coolant
|
||
明确显示 `n/a`;
|
||
- 执行包含 `S1200 M3/M5/M7/M8/M9/M48/M50/T2/M6/G43/G49/M61` 的 program;
|
||
- 验证 API 和 DOM 中 spindle/coolant/tool/override 状态均来自 LinuxCNC
|
||
canonical output。
|
||
|
||
Node smoke 新增验证:
|
||
|
||
- `createMachineStatusState()` 对 unavailable canonical output 返回 `n/a`;
|
||
- spindle/coolant/override canonical events 可正确折叠为最终状态;
|
||
- tool/TLO canonical events 可正确折叠为当前 tool/pocket/TLO。
|
||
|
||
文档同步:
|
||
|
||
- `wasm-port/docs/axis-style-simulation-implementation.md` 增补:
|
||
- machine status canonical event display;
|
||
- `getMachineStatusState()` required API。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
git diff --check ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- machine status 只显示 LinuxCNC canonical output 已产生的事件;
|
||
- 前端不推断真实 spindle/coolant/tool runtime;
|
||
- 缺失字段继续显示 `n/a`。
|
||
|
||
### 十三、2026-06-17 AXIS Preview Extents, Origin, and Legend
|
||
|
||
继续推进 AXIS preview 对标,补齐更接近 LinuxCNC AXIS 的预览覆盖层。
|
||
|
||
本批新增实质能力:
|
||
|
||
- SVG preview 新增:
|
||
- `data-preview-extents` extents rectangle;
|
||
- `data-preview-origin-x` / `data-preview-origin-y` origin axes;
|
||
- `data-preview-origin` origin marker;
|
||
- `data-axis-shell="preview-legend"` legend;
|
||
- `data-preview-extents-label` extents text;
|
||
- `renderToolpath()` 现在基于 LinuxCNC canonical motion 生成的
|
||
`createToolpathViewBox(motion)` 同步:
|
||
- extents rectangle;
|
||
- origin axes;
|
||
- origin marker size;
|
||
- extents label;
|
||
- preview legend 显示:
|
||
- Extents;
|
||
- Full path;
|
||
- Executed path;
|
||
- Origin。
|
||
|
||
browser smoke 新增验证:
|
||
|
||
- AXIS shell 必须存在 preview legend;
|
||
- SVG extents rectangle width/height > 0;
|
||
- origin marker 位于 `0,0`;
|
||
- extents label 同时包含 X/Y 范围;
|
||
- zoom/pan/fit 仍保持原有行为。
|
||
|
||
文档同步:
|
||
|
||
- `wasm-port/docs/axis-style-simulation-implementation.md` Phase 4 记录:
|
||
- motion-derived extents rectangle;
|
||
- origin axes/marker;
|
||
- preview legend。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
axis_style_simulation_docs_node_smoke=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
git diff --check ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- extents 只来自 LinuxCNC canonical motion path;
|
||
- origin marker/axes 只是 preview display overlay;
|
||
- 不新增浏览器端 CNC 几何、planner 或 kinematics 语义。
|
||
|
||
### 十四、2026-06-17 AXIS Three.js Toolpath Preview
|
||
|
||
按用户要求,刀具轨迹预览区改用 Three.js,版本要求为:
|
||
|
||
```json
|
||
"three": "^0.183.2"
|
||
```
|
||
|
||
本批新增实质能力:
|
||
|
||
- 新增 `wasm-port/runtime/ui/simulation/package.json`:
|
||
- `dependencies.three = "^0.183.2"`;
|
||
- 新增 `package-lock.json` 记录 resolved dependency;
|
||
- 新增 vendored runtime build:
|
||
- `runtime/ui/simulation/vendor/three/three.module.js`;
|
||
- `runtime/ui/simulation/vendor/three/three.core.js`;
|
||
- `runtime/ui/simulation/vendor/three/LICENSE`;
|
||
- `simulation-app.js` 直接 import:
|
||
- `./vendor/three/three.module.js`;
|
||
- preview 主视图新增:
|
||
- `<canvas data-toolpath-three>`;
|
||
- 原 SVG preview 改为 hidden fallback/state surface:
|
||
- 保留 `data-toolpath-svg`;
|
||
- 保留 polyline/head/extents selectors,兼容既有 tests/API。
|
||
|
||
Three.js 渲染内容:
|
||
|
||
- orthographic camera;
|
||
- dark AXIS-like background;
|
||
- motion-derived extents outline;
|
||
- origin X/Y axes;
|
||
- full canonical path;
|
||
- executed canonical path;
|
||
- origin marker;
|
||
- active tool marker;
|
||
- camera fit/zoom/pan 与现有 `fitPreview()` / `zoomPreview()` /
|
||
`panPreview()` 同步。
|
||
|
||
browser smoke 新增验证:
|
||
|
||
- `data-toolpath-three.dataset.threeReady === "true"`;
|
||
- Three.js revision 为 `183`;
|
||
- Three path point count 等于 LinuxCNC canonical motion count;
|
||
- playback step 后 Three executed point count 前进;
|
||
- SVG fallback viewBox/polyline 继续保持兼容。
|
||
|
||
docs smoke 新增验证:
|
||
|
||
- AXIS implementation docs 记录 Three.js `^0.183.2`;
|
||
- simulation package 声明 `three: ^0.183.2`;
|
||
- vendored `three.core.js` revision 为 `183`;
|
||
- real-browser priority docs smoke 确认页面包含 `data-toolpath-three`。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
axis_style_simulation_docs_node_smoke=ok
|
||
real_browser_simulation_priority_docs_node_smoke=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
git diff --check ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- Three.js 只负责显示 LinuxCNC canonical motion;
|
||
- 不在 Three.js/浏览器端实现 G-code、planner、kinematics 或 compensation;
|
||
- SVG fallback 仅作为 state/compatibility surface 保留。
|
||
|
||
### 十五、2026-06-17 AXIS Three.js Preview View Modes
|
||
|
||
继续按用户“预览区使用 threejs、对标 LinuxCNC AXIS”的要求推进,补齐 AXIS
|
||
常见预览视图模式。
|
||
|
||
本批新增实质能力:
|
||
|
||
- Preview toolbar 新增:
|
||
- `Top`;
|
||
- `Front`;
|
||
- `Side`;
|
||
- `Iso`;
|
||
- `window.linuxCncRealSimulationApi` 新增:
|
||
- `setPreviewViewMode(mode)`;
|
||
- `getPreviewState()` 新增:
|
||
- `viewMode`;
|
||
- Three.js preview canvas 新增/同步:
|
||
- `data-three-view-mode`;
|
||
- UI 新增:
|
||
- `data-preview-view-label`;
|
||
- active view-mode button state。
|
||
|
||
Three.js camera behavior:
|
||
|
||
- `top`:正交 top view;
|
||
- `front`:正交 front-style view;
|
||
- `side`:正交 side-style view;
|
||
- `iso`:isometric-like angled view;
|
||
- zoom/pan/fit 继续复用现有 viewBox 状态;
|
||
- Three.js 仅显示 LinuxCNC canonical motion,不改变 motion semantics。
|
||
|
||
browser smoke 新增验证:
|
||
|
||
- API 必须存在 `setPreviewViewMode()`;
|
||
- 切换 `iso` 后:
|
||
- `getPreviewState().viewMode === "iso"`;
|
||
- Three canvas `data-three-view-mode === "iso"`;
|
||
- UI label 显示 `Iso`;
|
||
- 切换 `side` 后:
|
||
- active button state 为 true;
|
||
- 切回 `top` 后继续执行 fit/zoom/pan smoke。
|
||
|
||
文档同步:
|
||
|
||
- `wasm-port/docs/axis-style-simulation-implementation.md` Phase 4 增补
|
||
Top/Front/Side/Iso view modes;
|
||
- Required APIs 增补 `setPreviewViewMode(mode)`。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
axis_style_simulation_docs_node_smoke=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
git diff --check ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- view modes 只改变 Three.js camera;
|
||
- 不改变 LinuxCNC canonical motion path;
|
||
- 不实现浏览器端 kinematics 或 G-code 几何语义。
|
||
|
||
### 十六、2026-06-17 AXIS Three.js Grid, Axis Labels, and Pixel Smoke
|
||
|
||
继续按“预览区使用 threejs、对标 LinuxCNC AXIS”推进,补齐 Three.js 预览的
|
||
网格、轴标签和 canvas 非空验证。
|
||
|
||
本批新增实质能力:
|
||
|
||
- Three.js preview 新增动态 grid:
|
||
- `chooseGridStep(span)` 按 viewBox 尺寸选择 1/2/5/10 系列步距;
|
||
- `addThreeGrid(scene, viewBox)` 生成 viewBox 覆盖范围内的 grid lines;
|
||
- canvas dataset:
|
||
- `data-three-grid-step`;
|
||
- `data-three-grid-lines`;
|
||
- Three.js preview 新增 X/Y/Z axis labels:
|
||
- `createTextSprite(text, color)`;
|
||
- `addThreeAxisLabels(scene, viewBox)`;
|
||
- canvas dataset:
|
||
- `data-three-axis-labels="3"`;
|
||
- Three.js preview smoke 新增 WebGL pixel readback:
|
||
- 获取 `webgl2` / `webgl` context;
|
||
- `readPixels()` 检查 canvas 中心像素非透明空白;
|
||
- 继续验证 Three.js revision/path points/executed points。
|
||
|
||
文档同步:
|
||
|
||
- `wasm-port/docs/axis-style-simulation-implementation.md` Phase 4 增补:
|
||
- dynamic grid lines;
|
||
- X/Y/Z axis labels;
|
||
- browser smoke canvas pixel check。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
axis_style_simulation_docs_node_smoke=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
git diff --check ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- grid 和 labels 只使用当前 preview viewBox;
|
||
- Three.js 仍只显示 LinuxCNC canonical motion;
|
||
- pixel smoke 只验证渲染非空,不推导 CNC 语义。
|
||
|
||
### 十七、2026-06-17 Browser Virtual HAL for AXIS Manual Controls
|
||
|
||
接续“虚拟 HAL 业务”,本批把 AXIS 手动控制从静态未绑定状态推进为浏览器
|
||
虚拟 HAL 状态模型,并接入 UI、SDK 和 WASM bridge。
|
||
|
||
本批新增实质能力:
|
||
|
||
- 新增 `wasm-port/runtime/sdk/src/linuxcnc-hal.js`:
|
||
- `VIRTUAL_HAL_AXISUI_PINS` 对齐 `linuxcnc/bin/axis` 中的 axisui pins:
|
||
`jog.x/y/z/a/b/c/u/v/w`、`jog.increment`、notification pins、
|
||
`error`、`abort`;
|
||
- `createVirtualHalState()` / `applyVirtualHalAction()` 管理 ESTOP、Power、
|
||
Home、Jog、Touch Off、Spindle、Coolant、Limit Override、Brake 等状态;
|
||
- `createVirtualHalDroState()` 输出 AXIS DRO 默认/实际位置;
|
||
- `createVirtualHalLimitsHomeState()` 输出 home/limit/fault rows;
|
||
- `createVirtualHalMachineStatusState()` 输出 spindle/coolant/tool/override state;
|
||
- `createVirtualHalWasmBridgeSnapshot()` 生成可写入 standalone HAL adapter 的
|
||
pin/value snapshot。
|
||
|
||
- SDK 入口新增 re-export:
|
||
- virtual HAL 状态、action、DRO、limits/home、machine status、runtime、
|
||
bridge snapshot、jog increment parser。
|
||
|
||
- Interpreter SDK 新增 HAL bridge API:
|
||
- `hasWasmFunction(name)`;
|
||
- `resetHal()`;
|
||
- `setHalValue({ kind, name, type, value, connected })`;
|
||
- `applyVirtualHalSnapshot(snapshot, options)`;
|
||
- `applyVirtualHalState(halState, options)`;
|
||
- `probeHalNamed(name)`。
|
||
|
||
- WASM wrapper 新增导出:
|
||
- `lcinterp_hal_reset()`;
|
||
- `lcinterp_hal_set_value()`;
|
||
- `lcinterp_probe_hal_named()`;
|
||
- `build_wasm_core.sh` 已把这些函数加入 `EXPORTED_FUNCTIONS`。
|
||
|
||
- Browser simulation UI 接入:
|
||
- F1/F2 快捷键驱动 ESTOP/Power;
|
||
- Ctrl-Home 驱动 Home All;
|
||
- Manual jog 更新 `jog.*` pins 和 DRO;
|
||
- spindle/coolant/brake/limit override 写入 virtual HAL state;
|
||
- diagnostics artifact 新增 `virtualHal`;
|
||
- machine control state 从“not bound”变为
|
||
`browser virtual HAL active for jog/spindle/coolant/home simulation`。
|
||
|
||
- Bridge snapshot 同时输出:
|
||
- AXIS Python component 内部 pin 名,例如 `jog.x`;
|
||
- HAL 全名,例如 `axisui.jog.x`;
|
||
- machine/task pins,例如 `halui.machine.is-on`;
|
||
- spindle/coolant pins,例如 `spindle.0.speed-out`、
|
||
`iocontrol.0.coolant-flood`。
|
||
|
||
新增/扩展验证:
|
||
|
||
- `verify_real_simulation_programs.mjs` 覆盖 virtual HAL SDK、runtime snapshot、
|
||
`axisui.*` HAL 全名、DRO、home、spindle、coolant;
|
||
- `real_simulation_page_smoke.html` 覆盖 F1/F2/Ctrl-Home/jog/spindle/coolant 的
|
||
浏览器交互;
|
||
- `verify_interp_wasm.mjs` 在新 WASM 导出存在时验证:
|
||
`applyVirtualHalState()` 写入 HAL adapter 后,`probeHalNamed()` 能读到
|
||
`_hal[jog.x]`、`_hal[axisui.jog.x]`、`_hal[halui.machine.is-on]`、
|
||
`_hal[spindle.0.speed-out]`、`_hal[iocontrol.0.coolant-flood]`。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
real_simulation_programs_node_smoke=ok
|
||
interp_wasm_node_smoke=ok (SKIP_INTERP_BUILD=1)
|
||
browser_real_simulation_page_smoke=ok (SKIP_INTERP_BUILD=1)
|
||
sdk_surface_node_smoke=ok
|
||
ui_node_smokes=ok
|
||
git diff --check ok
|
||
```
|
||
|
||
当前构建备注:
|
||
|
||
- 当前 Codex shell 的 `PATH` 未解析到 `emcc`,完整 `build_wasm_core.sh` 会停在
|
||
`emcc: command not found`;
|
||
- 这不是代码侧缺少 Emscripten 的结论,只是本 shell 未加载用户已有的
|
||
Emscripten 环境;
|
||
- 快速 smoke 已用现有 WASM 产物验证旧路径不回归,新导出的 HAL bridge smoke 会在
|
||
重建后的 WASM 存在对应函数时自动执行。
|
||
|
||
语义边界:
|
||
|
||
- virtual HAL 只模拟 AXIS/manual UI 与 standalone HAL adapter 的状态桥;
|
||
- 不在浏览器端实现 LinuxCNC realtime HAL、motion controller、planner、
|
||
kinematics 或 G-code 语义;
|
||
- G-code execution 和 canonical motion 仍来自 LinuxCNC interpreter WASM。
|
||
|
||
### 十八、2026-06-17 Project-level Virtual HAL SDK Boundary
|
||
|
||
按用户要求“虚拟 HAL 适合整个项目”,本批把上一节的 simulation/UI 虚拟 HAL
|
||
提升为项目级 SDK host-boundary 能力,供 simulation、INI panel、Node/browser
|
||
smoke、外部 dashboard 和 interpreter bridge 共用。
|
||
|
||
新增项目级 API:
|
||
|
||
- `VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS`:
|
||
- `lcinterp_hal_reset`;
|
||
- `lcinterp_hal_set_value`;
|
||
- `lcinterp_probe_hal_named`;
|
||
- `VIRTUAL_HAL_PROJECT_PIN_GROUPS`:
|
||
- `axisui`;
|
||
- `axis`;
|
||
- `task`;
|
||
- `spindle-coolant`;
|
||
- `createVirtualHalPinInventory(halState)`:
|
||
- 输出全部 bridge pin rows;
|
||
- 按项目级 pin group 归类;
|
||
- `createVirtualHalBridgeReadiness(options)`:
|
||
- 检查 snapshot 是否包含 required pins;
|
||
- 检查 caller-provided WASM function evidence 是否覆盖
|
||
`VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS`;
|
||
- 无 evidence 时显式 blocked:`wasm-function-evidence`;
|
||
- `createVirtualHalBridgeActionPlan(readiness)`:
|
||
- blocked 时给出下一步:
|
||
`wasm-port/tools/build_wasm_core.sh`;
|
||
`SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_interp_wasm.sh`;
|
||
- ready 时返回空 command;
|
||
- `createVirtualHalProjectReport(options)`:
|
||
- 汇总 state、DRO、limits/home、machine status、pin inventory、
|
||
WASM bridge snapshot、bridge readiness、bridge action plan;
|
||
- `applyVirtualHalToInterpSdk(interpSdk, halState, options)`:
|
||
- 对有 `applyVirtualHalState()` 或 `applyVirtualHalSnapshot()` 的 interpreter
|
||
SDK 做统一适配;
|
||
- `createLinuxCncVirtualHalRuntime()` 新增:
|
||
- `getPinInventory()`;
|
||
- `getProjectReport(options)`;
|
||
- `applyToInterpSdk(interpSdk, options)`。
|
||
|
||
文档同步:
|
||
|
||
- `runtime/sdk/README.md` 新增 `Project-level virtual HAL boundary` 小节;
|
||
- `docs/project-release-handoff.md` 把 project-level virtual HAL 纳入当前支持
|
||
workflow;
|
||
- `PROJECT_COMPLETION_TRACKER.md` 的 SDK/API surface 行记录 pin inventory、
|
||
bridge readiness/action-plan、project report、interpreter apply adapter;
|
||
- `verify_project_release_handoff_docs.mjs` 增加文档 gate,防止后续退回页面私有
|
||
virtual HAL。
|
||
|
||
新增/扩展验证:
|
||
|
||
- `verify_sdk_surface.mjs` 覆盖:
|
||
- SDK re-export;
|
||
- constants discovery;
|
||
- virtual HAL snapshot;
|
||
- pin inventory;
|
||
- blocked/ready bridge readiness;
|
||
- bridge action plan;
|
||
- project report;
|
||
- runtime project report;
|
||
- fake interpreter SDK apply wrapper;
|
||
- `verify_project_release_handoff_docs.mjs` 覆盖 handoff/README 中的项目级
|
||
virtual HAL API 和 realtime HAL runtime 边界声明。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
sdk_surface_node_smoke=ok
|
||
project_release_handoff_docs_node_smoke=ok
|
||
real_simulation_programs_node_smoke=ok
|
||
git diff --check ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- project-level virtual HAL 仍是 host-boundary adapter;
|
||
- 它可服务 UI/session/diagnostics/dashboard 和 `_hal[...]` interpreter probe;
|
||
- 它不是 LinuxCNC realtime HAL runtime;
|
||
- 不提升 task、motion、HAL module loading、HALUI process、Tcl/Python process、
|
||
external device semantics。
|
||
|
||
### 十九、2026-06-17 Simulation-grade LinuxCNC Realtime HAL / halcmd / Motion Replacement
|
||
|
||
按用户要求“在满足仿真方面,实现 LinuxCNC realtime HAL / halcmd / motion controller
|
||
的完整替代,以虚拟 HAL 方式实现”,本批把上一节项目级 virtual HAL 从 bridge/readiness
|
||
推进为仿真级 runtime replacement。
|
||
|
||
新增实质能力:
|
||
|
||
- `VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS`:
|
||
- `linuxcnc-realtime-hal`;
|
||
- `halcmd`;
|
||
- `motion-controller`;
|
||
- `VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES` 新增:
|
||
- `realtime-hal-simulation-replacement`;
|
||
- `halcmd-simulation-replacement`;
|
||
- `motion-controller-simulation-replacement`;
|
||
- 新增 `executeVirtualHalcmd()`:
|
||
- 作为 `executeVirtualHalCommand()` 的 halcmd 语义别名;
|
||
- 支持当前仿真所需 `setp`、`sets`、`newsig`、`net`、`show`、`getp`、`gets`、
|
||
`loadrt`、`loadusr`、`addf`、`start`、`stop`、`unlinkp`、`motion-step`;
|
||
- 新增 `stepVirtualHalMotionController()`:
|
||
- 多周期 servo step;
|
||
- 输出每周期 position/motion frame;
|
||
- 更新 target、velocity、distance-to-go、in-position;
|
||
- 新增 `createVirtualHalSimulationReplacementReport()`:
|
||
- 明确报告 realtime HAL、halcmd、motion controller 三类仿真替代 ready 状态;
|
||
- 保留 `hardRealtime: false`、`realtimeKernelAbi: false`,避免伪装为 Linux kernel
|
||
realtime ABI;
|
||
- `createLinuxCncVirtualHalRuntime()` 新增:
|
||
- `executeHalcmd()`;
|
||
- `stepMotionController()`;
|
||
- `getSimulationReplacementReport()`。
|
||
|
||
Browser simulation API 新增:
|
||
|
||
- `executeVirtualHalcmd()`;
|
||
- `executeVirtualHalCommand()`;
|
||
- `stepVirtualHalMotionController()`;
|
||
- `getVirtualHalSimulationRuntimeReport()`;
|
||
- `getVirtualHalSimulationReplacementReport()`;
|
||
- `getVirtualRealtimeHalRuntimeReport()`;
|
||
- diagnostics artifact 新增 `virtualHalSimulationReplacement`。
|
||
|
||
新增/扩展验证:
|
||
|
||
- `verify_sdk_surface.mjs` 覆盖:
|
||
- replacement target constants;
|
||
- runtime capability constants;
|
||
- `executeVirtualHalcmd()`;
|
||
- `stepVirtualHalMotionController()`;
|
||
- `createVirtualHalSimulationReplacementReport()`;
|
||
- runtime wrapper 的 `executeHalcmd()` / `stepMotionController()` /
|
||
`getSimulationReplacementReport()`;
|
||
- `real_simulation_page_smoke.html` 覆盖:
|
||
- 页面 API 暴露 halcmd/motion/replacement report;
|
||
- browser 中执行 `loadrt`、`addf`、`setp`、`show pin`;
|
||
- browser 中执行 motion controller 多周期 step;
|
||
- diagnostics artifact 携带 replacement report。
|
||
|
||
关键验证:
|
||
|
||
```text
|
||
sdk_surface_node_smoke=ok
|
||
project_release_gate_manifest_node_smoke=ok
|
||
project_release_artifact_url_workflow_node_smoke=ok
|
||
project_batch_acceptance_workflow_node_smoke=ok
|
||
project_batch_acceptance_artifact_node_smoke=ok
|
||
real_simulation_programs_node_smoke=ok
|
||
browser_real_simulation_page_smoke=ok
|
||
git diff --check ok
|
||
```
|
||
|
||
语义边界:
|
||
|
||
- 本批实现的是 simulation-grade replacement;
|
||
- Browser/SDK 仿真不再依赖 host `halcmd`、host realtime HAL process 或 host motion
|
||
process 来完成页面/Node 仿真闭环;
|
||
- 仍不声称提供 Linux kernel hard-realtime ABI、外部硬件驱动 ABI、native HAL module ABI;
|
||
- G-code 执行、canonical event、planner/interpreter 语义仍来自 LinuxCNC-backed WASM。
|