结论:real simulation page 已将保存的 virtual HAL session snapshot 联动到 release diagnostics artifact,保存或恢复后的 Web CNC 仿真会话可直接输出 release-ready virtual HAL source、sim-config、halcmd fixture 与 motion matrix evidence;该能力仍限于 Web 仿真替代层,不声明 Linux kernel hard-realtime ABI、外部硬件驱动 ABI 或 native HAL module ABI。
22 KiB
AXIS-Style Browser Simulation Implementation Plan
This document defines the implementation plan for evolving
runtime/ui/simulation/index.html toward a browser simulation surface inspired
by LinuxCNC AXIS. It is a product/UI implementation guide, not permission to
reimplement LinuxCNC CNC semantics in JavaScript.
Reference Target
The reference UI is LinuxCNC AXIS with:
- a top menu and compact icon toolbar;
- Manual Control and MDI tabs;
- machine controls for axis selection, jog mode, homing, spindle, coolant, feed/rapid/spindle overrides, jog speed, and max velocity;
- active G-code modal display;
- a combined preview/DRO area;
- a 3D toolpath preview with machine extents and tool marker;
- DRO rows for relative/absolute position, distance-to-go, work offsets, G92 offsets, tool length offsets, and velocity;
- a scrollable G-code source pane with active line;
- a bottom status bar for E-stop, tool, and coordinate mode.
The browser implementation should match the operational shape of AXIS while staying suitable for a web runtime and the current WASM/OPFS architecture.
Non-Negotiable Boundary
LinuxCNC remains the only CNC semantic source.
Browser JavaScript may:
- render UI layout and interaction state;
- call the existing LinuxCNC-backed WASM SDK;
- stage G-code, INI, parameter, and tool-table text into OPFS or the Emscripten filesystem;
- display LinuxCNC-produced canonical output, motion events, modal state, run status, and validated runtime summaries;
- animate playback over LinuxCNC-produced motion events.
Browser JavaScript must not implement:
- G-code interpretation;
- modal semantics;
- cutter/tool compensation semantics;
- parameter semantics;
- kinematics;
- remap behavior;
- planner behavior;
- canonical motion semantics beyond display mapping of LinuxCNC-produced canonical fields.
Current Baseline
The current simulation page already has:
- LinuxCNC interpreter WASM execution through
createLinuxCncInterpSdk(); - selectable test programs under
runtime/ui/simulation/programs/; - custom G-code text and browser File execution through LinuxCNC WASM;
- editable G-code pane plus run-editor-text workflow;
- canonical output rendering;
- program-line rendering;
- motion table;
- final and playback axis readout;
- SVG toolpath preview;
- reset/step/play/finish playback over LinuxCNC canonical motion events;
- browser smoke coverage in
tests/browser/verify_real_simulation_browser.sh; - Node contract coverage in
tests/ui/node/verify_real_simulation_programs.sh.
Target Layout
The first AXIS-style browser layout should be a single operator workspace:
menu/toolbar/status badges
┌───────────────────────┬─────────────────────────────────────┐
│ Manual / MDI tabs │ Preview / DRO tabs │
│ Jog controls │ 3D or 2.5D toolpath viewport │
│ spindle/coolant │ DRO overlay / panel │
│ overrides/speeds │ active tool marker │
│ active modal codes │ machine/work extents │
├───────────────────────┴─────────────────────────────────────┤
│ G-code source with active execution line │
├───────────────────────────────────────────────────────────────┤
│ E-stop | tool | position mode | run state | program state │
└───────────────────────────────────────────────────────────────┘
The Phase 1 implementation has replaced the former three-column MVP with this AXIS-style shell while preserving the existing LinuxCNC-backed execution and playback APIs.
Implementation Phases
Phase 1: AXIS-Style Shell
Status: implemented.
Build the visual shell around the existing simulation state:
- menu bar: File, Machine, View, Help;
- toolbar: open, reload, run, pause, step, stop, reset, zoom controls;
- left panel tabs: Manual Control and MDI;
- right panel tabs: Preview and DRO;
- lower G-code pane;
- bottom status bar.
Controls may initially be display-only or disabled when no real runtime action exists, but they must show explicit readiness/blocked state.
Validation:
- browser smoke proves all AXIS-style regions render;
- current program selection and playback still work;
- no existing simulation API is removed.
Current implemented regions:
data-axis-shell="titlebar";data-axis-shell="menubar";data-axis-shell="toolbar";data-axis-shell="manual-mdi";data-axis-shell="preview-dro";data-axis-shell="gcode-pane";data-axis-shell="machine-state";data-axis-shell="statusbar".
Phase 2: Program Execution Workflow
Status: active; custom text/file/editor execution and OPFS program persistence are implemented. MDI scratch text can now be loaded into the AXIS G-code pane or executed through the same LinuxCNC-backed WASM path.
Upgrade the G-code pane and execution controls:
- load a selected built-in test program;
- run through LinuxCNC WASM;
- reset/step/play/pause/finish playback from toolbar and keyboard-accessible buttons;
- reload the current built-in, editor, MDI, file, or OPFS-backed program through the same LinuxCNC-backed execution path;
- highlight active G-code line and current motion row;
- show run status, source program, motion count, and current frame.
- load operator-provided G-code text through
runProgramText(); - stage operator-provided G-code text without executing through
loadProgramText(); - load browser
Fileobjects throughloadProgramFile(); - edit visible G-code in the AXIS shell and run it through
runEditorProgramText(); - load or run the MDI panel scratch program through LinuxCNC-backed text execution;
- record successful LinuxCNC-backed MDI executions in an AXIS-style MDI history list, with click-to-restore and clear controls;
- record successful LinuxCNC-backed built-in, text, editor, file, OPFS, MDI, and session-backed executions in an AXIS-style recent program list, with click-to-stage and clear controls;
- save the current editor G-code through OPFS with
saveProgramToOpfs(); - load an OPFS G-code program through
loadProgramFromOpfs()and execute it through LinuxCNC WASM;
Built-in test programs must live in:
runtime/ui/simulation/programs/
Each program should have its own module and be exported through
runtime/ui/simulation/programs/index.js. The simulation renderer should keep
importing the inventory through the program index rather than embedding G-code
fixtures in simulation-app.js.
Validation:
- browser smoke runs at least one linear program, one arc program, and one canned-cycle program through toolbar actions;
- active-line, toolhead, executed path, and status bar update together.
- browser smoke saves an edited G-code program to OPFS, changes the editor text, reloads the OPFS program, and verifies the reloaded text executes through LinuxCNC WASM.
- browser smoke verifies
loadProgramText()stages text without executing and that MDI text execution produces LinuxCNC canonical output. - browser smoke verifies successful MDI execution records history, restores history text into the MDI pane, and clears history without changing LinuxCNC-produced motion state.
- browser smoke verifies successful LinuxCNC-backed executions populate recent programs, recent entries stage text back into the editor without implicit execution, and the recent list can be cleared.
Phase 3: DRO and Modal Display
Status: partially implemented; actual axis readout and LinuxCNC UPDATE_TAG
modal display are implemented.
Add a DRO panel modeled after AXIS:
- relative actual X/Y/Z/A/B/C;
- distance-to-go when available from LinuxCNC-produced or validated runtime events;
- G54 and G92 rows when available from canonical output or runtime summaries;
- tool length offset rows when available;
- velocity from playback delta or LinuxCNC-produced runtime field when available;
- active G-code modal display from LinuxCNC output only.
Fallback values must be marked as unavailable rather than invented.
Current implemented behavior:
- relative actual X/Y/Z/A/B/C values are rendered from LinuxCNC canonical motion frames;
- distance-to-go, G54, G92, tool-length offset, and velocity fields render as
explicit
n/auntil LinuxCNC-produced or validated runtime fields are available; - modal rows are derived from LinuxCNC
canon_event=UPDATE_TAGoutput; - spindle, coolant, tool, and override rows are derived from LinuxCNC canonical
events when present and otherwise remain explicit
n/a; - browser API exposes
getDroState(),getModalState(), andgetMachineStatusState().
Validation:
- Node and browser tests verify no unavailable field is silently fabricated;
- modal/DRO display is derived from LinuxCNC output or explicit unavailable state.
Phase 4: Preview Upgrade
Status: implemented for the current browser simulation scope; AXIS-like Three.js viewport controls are available with SVG fallback state for compatibility tests.
Improve the preview from a simple SVG polyline into an AXIS-like viewport:
- dark viewport theme;
- work envelope and extents grid;
- full path versus executed path;
- active tool marker;
- zoom fit / pan / reset view;
- orthographic 3D using Three.js
^0.183.2, kept stable in browser smoke.
Current implemented behavior:
- dark viewport theme;
- full path versus executed path;
- active tool marker;
- motion-derived extents rectangle, origin axes/marker, and preview legend;
- Three.js canvas renders the primary toolpath preview from LinuxCNC canonical motion, while SVG remains a hidden fallback/state surface for compatibility;
- runtime imports the local
runtime/ui/simulation/vendor/three/three.module.jsbuild, withruntime/ui/simulation/package.jsondocumenting the requestedthreedependency range; - Three.js preview includes dynamic grid lines and X/Y/Z axis labels;
- Three.js preview renders coordinate axes, motion-type segment metadata, active toolhead coordinates, renderer revision, and canvas size into the preview state API for smoke validation;
- Three.js preview samples
ARC_FEEDdisplay curves from LinuxCNC-produced canonical center, rotation, active-plane, and endpoint fields, while keeping SVG fallback state endpoint-compatible for existing browser tests; - Three.js preview now renders AXIS-style tool geometry with a visible tool
body, optional LinuxCNC-produced tool-length-offset indicator, current tool
label when available, and a viewport scale bar surfaced through
getPreviewState(); - Three.js preview renders a compact X/Y/Z orientation triad in the viewport
and surfaces its structured display state through
getPreviewState(); - AXIS-style preview HUD overlays the Three.js stage with view/zoom/pan, toolhead XYZ, machine envelope, grid step, and renderer/path counts derived from LinuxCNC canonical motion and Three.js render state;
- AXIS-style bottom status bar is structured into E-stop, tool, program
source, active line, position/run mode, and preview state fields, with
getAxisStatusbarState()exposing the same browser state for smoke tests; - fit, zoom in, zoom out, pan, Top/Front/Side/Iso view modes, and reset view controls;
- AXIS-style preview layer toggles can show/hide rapid traverse, feed, arc, tool, envelope, and scale-bar display layers without changing the LinuxCNC-produced motion state;
- Three.js canvas exposes an AXIS-style cursor crosshair and live X/Y preview coordinate readout derived from the current rendered viewBox; this is display state only and does not change machine or G-code state;
- Three.js canvas supports wheel zoom, pointer-drag pan, and double-click fit;
- browser resize refreshes the Three.js viewport while preserving playback, zoom, pan, and view-mode state;
- dedicated desktop/mobile screenshot smoke validates the Three.js viewport, preview legend, diagnostics, compact tool table, status history, and G-code/Machine State layout in real browser viewports;
- screenshot smoke captures Preview, DRO, and MDI entry states through stable URL view parameters;
- screenshot smoke can persist desktop/mobile PNGs and screenshot metadata JSON
when
AXIS_SCREENSHOT_ARTIFACT_DIRis provided; fullexportDiagnosticsArtifact()JSON is available behindAXIS_SCREENSHOT_FULL_DIAGNOSTICS=1for CI jobs that opt into CDP capture; - release-readiness artifact generation summarizes persisted AXIS screenshot
diagnostics when
AXIS_SCREENSHOT_ARTIFACT_DIRpoints at the screenshot artifact directory, without changing the fixed release gate count; - browser API exposes
fitPreview(),zoomPreview(factor),panPreview(dx, dy),setPreviewViewMode(mode),getPreviewState(), andresetPreview(); - browser API exposes
getPreviewLayerState()andsetPreviewLayer(name, enabled)for AXIS-style display layer controls. - browser API exposes
getPreviewCursorState()for the current preview cursor/crosshair readout.
Validation:
- browser smoke verifies nonblank preview, executed path growth, toolhead movement, Three.js canvas pixels, sampled canonical arc rendering, structured tool geometry, scale bar state, AXIS preview layer toggles, and stable viewport controls;
- browser smoke verifies pointer-driven preview cursor/crosshair coordinate readout and pointer-leave clearing;
- mobile and desktop screenshot smoke verifies nonblank Three.js rendering, visible compact panels, and non-overlapping AXIS shell sections.
Phase 5: Machine/Session Integration
Status: partially implemented; OPFS machine/session readiness, session staging, and loaded-session program execution are visible in the AXIS shell.
Connect the AXIS-style shell to the existing OPFS/session workflow:
- load machine session from OPFS;
- show machine file readiness;
- show loaded INI/parameter/tool-table/program paths;
- stage files into WASM before execution;
- block run controls with explicit reasons when session readiness is missing.
Current implemented behavior:
- Manual Control panel includes machine id, session id, and G-code filename inputs;
- Manual Control also renders explicit blocked state for real jog/spindle and coolant controls that are not backed by the browser runtime;
Check Sessioncalls existingreadMachineSessionReadiness();- readiness phase, missing checks, INI path, and G-code path render in the AXIS shell;
- browser API exposes
getMachineReadiness()andcheckMachineSessionReadiness(options); - AXIS panels show LinuxCNC canonical machine status for spindle, coolant, tool, and override fields when available;
Load Sessioncalls existing LinuxCNC-backedloadMachineSessionFromOpfs()after readiness passes;- staged INI, parameter, and tool-table WASM paths render in the AXIS shell;
- browser API exposes
getMachineSessionLoadState()andloadReadyMachineSession(options); - staged LinuxCNC tool-table load results are summarized in Machine State with OPFS/WASM paths, tool count, and the first loaded tool row;
- staged LinuxCNC tool-table rows also render in a compact AXIS-style table with T/P/Z/D/comment columns;
- editor/custom/built-in program execution uses
runProgramWithIni()with the loaded session INI path when a session has been staged; - toolbar and status bar expose the current run mode as standalone or session-backed with the active INI path;
- Manual Control exposes a
Use Sessiontoggle so a staged machine session can be enabled or bypassed for subsequent runs; - Machine State includes a compact run summary for execution mode, session INI, OPFS program path, readiness phase, and session load phase;
- browser API exposes
getRunMode(),setUseLoadedSession(value), andgetRunSummary(); - toolbar and Machine State expose run-control ready/fallback state so operators can see whether a requested session-backed run will actually use a loaded INI or fall back to standalone LinuxCNC WASM;
- AXIS-style keyboard bindings route F3/F5/F6/F7, run, playback stepping, finish/reset, and preview fit through the same browser API as toolbar controls;
- Machine State includes a compact diagnostics panel for the last LinuxCNC canonical event, last surfaced error, readiness/load phase, and most recent shortcut action;
- Machine State includes a compact status-history ring for recent run, readiness, session, OPFS, shortcut, and error events;
- Machine State includes a compact limits/home panel that explicitly reports
n/auntil LinuxCNC-produced runtime fields are available; - diagnostics can be exported as a structured browser artifact containing run summary, preview state, status history, tool-table summary, and limits/home state;
- browser API exposes
getDiagnosticsState(),getStatusHistory(),getToolTableSummary(),getLimitsHomeState(),exportDiagnosticsArtifact(),exportVirtualHalSessionDiagnosticsArtifact(), andhandleAxisShortcut(event); - saved virtual HAL session snapshots are linked back into the browser diagnostics artifact as release-ready virtual HAL source, sim-config, halcmd-fixture, and motion-matrix evidence;
- browser smoke covers run and play/pause keyboard shortcuts after waiting for their async UI/API side effects;
- browser smoke verifies blocked readiness before OPFS files exist, then writes
machine files, G-code, and a session snapshot through existing OPFS helpers
and verifies readiness becomes
ready; - browser smoke verifies a ready machine session stages INI, parameter, and tool-table files into the WASM filesystem through LinuxCNC-backed SDKs.
- browser smoke verifies editor G-code execution uses the loaded session INI path and still renders LinuxCNC canonical output/playback state.
- browser smoke verifies OPFS-loaded G-code also uses the loaded session INI path and that run-mode UI/API state switches to session-backed.
- browser smoke verifies disabling
Use Sessionreturns editor execution to standalone mode while leaving the staged session available. - browser smoke verifies run summary API/DOM values for standalone, session-backed, and OPFS program execution.
- browser smoke verifies AXIS URL view parameters can open Manual/MDI and Preview/DRO panels without bypassing the normal tab controls.
Validation:
- OPFS/session browser smoke covers load -> run -> playback;
- release gate includes the AXIS-style simulation workflow.
Required APIs
The page should expose a stable browser API under:
window.linuxCncRealSimulationApi
Required methods:
getState();getPrograms();runProgramById(programId);reloadCurrentProgram();getPlaybackFrame();isPlaybackRunning();resetPlayback();stepPlayback(delta);play();pause();finishPlayback();runProgramText(programText, metadata);loadProgramText(text, metadata);loadProgramFile(file);getProgramText();setProgramText(text, metadata);runEditorProgramText();runMdiProgramText(text);getMdiHistory();clearMdiHistory();getRecentPrograms();clearRecentPrograms();getOpfsProgramState();saveProgramToOpfs(filename);loadProgramFromOpfs(filename);getDroState();getModalState();getMachineStatusState();fitPreview();zoomPreview(factor);panPreview(dx, dy);setPreviewViewMode(mode);getPreviewState();getPreviewLayerState();setPreviewLayer(name, enabled);getPreviewCursorState();resetPreview();getMachineReadiness();checkMachineSessionReadiness(options);getMachineSessionLoadState();loadReadyMachineSession(options);getRunMode();getRunControlState();getAxisStatusbarState();setUseLoadedSession(value);getRunSummary();getDiagnosticsState();getStatusHistory();getToolTableSummary();getLimitsHomeState();exportDiagnosticsArtifact();exportVirtualHalSessionDiagnosticsArtifact();handleAxisShortcut(event);applyAxisViewFromUrl(search);
API additions must be covered by Node or browser smoke before being relied on by UI controls.
Visual Design Rules
Use the reference as an operational model, not a pixel-perfect clone.
- Keep controls dense and tool-like.
- Prefer plain borders, compact buttons, tabs, and status strips.
- Avoid landing-page composition, marketing cards, oversized hero text, and decorative backgrounds.
- Keep preview large and central.
- Keep G-code visible during playback.
- Keep status and blocked reasons visible without modal interruptions.
- Use icons where available, but text labels are acceptable until a stable icon dependency exists.
Acceptance Gates
Every implementation batch must keep these passing:
wasm-port/tests/ui/node/verify_real_simulation_programs.sh
SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_real_simulation_browser.sh
SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_real_simulation_axis_screenshot_browser.sh
wasm-port/tests/docs/node/verify_real_browser_simulation_priority_docs.sh
wasm-port/tests/host/verify_project_release_gate.sh
When AXIS-style shell work starts, add or extend browser assertions for:
- menu bar;
- toolbar;
- Manual Control tab;
- MDI tab;
- Preview tab;
- DRO tab;
- active G-code pane;
- status bar;
- playback controls driving the same LinuxCNC-backed state as the API.
Immediate Next Batch
Continue AXIS by deepening operator workflow coverage without adding browser-side CNC semantics:
- Add limits/home real data mapping only when LinuxCNC-produced runtime fields are available.
- Keep unavailable DRO and machine fields explicit
n/auntil LinuxCNC-produced runtime data exists. - Promote AXIS screenshot artifact summaries into CI retention once the release job has a stable artifact directory.
- Harden the optional CDP diagnostics capture path before making full
exportDiagnosticsArtifact()retention mandatory in CI.