Initial wasm simulator checkpoint
This commit is contained in:
194
docs/linuxcnc-porting.md
Normal file
194
docs/linuxcnc-porting.md
Normal file
@@ -0,0 +1,194 @@
|
||||
# LinuxCNC to WASM porting steps
|
||||
|
||||
This file defines the incremental path for replacing the temporary smoke parser with the LinuxCNC interpreter.
|
||||
|
||||
## Step 0: Stable simulator ABI
|
||||
|
||||
Status: done.
|
||||
|
||||
The browser calls only `cnc_sim_*` functions from `core/include/cnc_sim_api.h`. This ABI remains stable while the backend changes.
|
||||
|
||||
Test:
|
||||
|
||||
```bash
|
||||
g++ -std=c++17 -I core/include core/src/cnc_sim_api.cpp core/tests/cnc_sim_api_smoke.cpp -o /tmp/cnc_sim_api_smoke
|
||||
/tmp/cnc_sim_api_smoke
|
||||
```
|
||||
|
||||
## Step 1: Temporary event parser
|
||||
|
||||
Status: in progress.
|
||||
|
||||
This parser only exists to test the ABI and UI before Emscripten and LinuxCNC are wired in. It currently handles:
|
||||
|
||||
- multiple G/M words on one line
|
||||
- `G0`, `G1`, `G2`, `G3`
|
||||
- `G17`, `G18`, `G19`
|
||||
- `G20`, `G21`, `G70`, `G71`
|
||||
- `G90`, `G91`
|
||||
- `G4 P...`
|
||||
- `F`, `S`, `T`, `M3`, `M4`, `M5`, `M6`, `M2`, `M30`
|
||||
- IJK and R arcs
|
||||
|
||||
It is not the production interpreter.
|
||||
|
||||
## Step 2: Canon event sink
|
||||
|
||||
Status: started.
|
||||
|
||||
Create a C++ file that implements the Canon functions declared by LinuxCNC `src/emc/nml_intf/canon.hh`.
|
||||
|
||||
High-priority callbacks:
|
||||
|
||||
- `INIT_CANON`
|
||||
- `USE_LENGTH_UNITS`
|
||||
- `SELECT_PLANE`
|
||||
- `SET_FEED_RATE`
|
||||
- `SET_SPINDLE_SPEED`
|
||||
- `SELECT_TOOL`
|
||||
- `CHANGE_TOOL`
|
||||
- `STRAIGHT_TRAVERSE`
|
||||
- `STRAIGHT_FEED`
|
||||
- `ARC_FEED`
|
||||
- `DWELL`
|
||||
- `PROGRAM_END`
|
||||
- `FINISH`
|
||||
|
||||
The sink will translate these callbacks to `CncSimEvent`.
|
||||
|
||||
Current bridge files:
|
||||
|
||||
- `core/src/canon_event_sink.h`
|
||||
- `core/src/canon_event_sink.cpp`
|
||||
- `core/src/linuxcnc_canon_bridge.h`
|
||||
- `core/src/linuxcnc_canon_bridge.cpp`
|
||||
|
||||
The LinuxCNC bridge is optional and not built by default:
|
||||
|
||||
```bash
|
||||
cmake -S core -B build/native-linuxcnc \
|
||||
-DCNC_SIM_ENABLE_LINUXCNC_BRIDGE=ON \
|
||||
-DCNC_SIM_LINUXCNC_ROOT=/path/to/linuxcnc
|
||||
```
|
||||
|
||||
This bridge is intentionally thin. The production parser still needs the `rs274ngc` interpreter linked on top of it.
|
||||
|
||||
Bridge smoke test:
|
||||
|
||||
```bash
|
||||
./test-linuxcnc-bridge-native.sh
|
||||
```
|
||||
|
||||
Set `LINUXCNC_ROOT=/path/to/linuxcnc` if the LinuxCNC source tree is not next to `wasm-simulator`.
|
||||
|
||||
## Step 3a: Native `librs274` runner
|
||||
|
||||
Status: started.
|
||||
|
||||
Before porting `rs274ngc` sources to wasm, use the already-built native LinuxCNC `librs274` to validate the bridge and event schema:
|
||||
|
||||
```bash
|
||||
./test-linuxcnc-rs274-native.sh
|
||||
```
|
||||
|
||||
This builds `core/tools/linuxcnc_rs274_dump.cpp`, links LinuxCNC `librs274`, and writes:
|
||||
|
||||
- `/tmp/cnc_sim_linuxcnc_basic_motion.json`
|
||||
- `/tmp/cnc_sim_linuxcnc_basic_mill.json`
|
||||
|
||||
This is a native-only stepping stone. Once stable, the same event sink is used by the wasm build.
|
||||
|
||||
`T... M6` now works in the native runner after initializing LinuxCNC mmap tooldata with a minimal tool table.
|
||||
|
||||
## Step 3b: API-level native `librs274` backend
|
||||
|
||||
Status: started.
|
||||
|
||||
The public `cnc_sim_api` can now select backends through config JSON:
|
||||
|
||||
```json
|
||||
{"backend":"smoke"}
|
||||
```
|
||||
|
||||
or, in a native build compiled with `CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND`:
|
||||
|
||||
```json
|
||||
{"backend":"linuxcnc-rs274"}
|
||||
```
|
||||
|
||||
API-level native smoke:
|
||||
|
||||
```bash
|
||||
./test-linuxcnc-api-native.sh
|
||||
```
|
||||
|
||||
## Step 4a: Source compilation map
|
||||
|
||||
Status: started.
|
||||
|
||||
Before replacing `librs274` with source-level compilation, keep the source manifest and syntax probe green:
|
||||
|
||||
```bash
|
||||
./test-linuxcnc-source-syntax.sh
|
||||
./test-linuxcnc-source-objects.sh
|
||||
```
|
||||
|
||||
The manifest is:
|
||||
|
||||
- `linuxcnc-rs274-source-files.txt`
|
||||
- `docs/linuxcnc-rs274-source-map.md`
|
||||
|
||||
The first compile condition discovered is that LinuxCNC user-space source probes need `-DULAPI`.
|
||||
|
||||
## Step 3: Native LinuxCNC interpreter comparison
|
||||
|
||||
Build a native adapter that links:
|
||||
|
||||
- `src/emc/rs274ngc`
|
||||
- `src/emc/nml_intf`
|
||||
- the Canon event sink
|
||||
|
||||
Then run the same G-code corpus through both the temporary parser and LinuxCNC-backed parser. Numeric differences are expected around arc canonicalization; they must be recorded and bounded.
|
||||
|
||||
## Step 4: Remove browser-hostile dependencies
|
||||
|
||||
LinuxCNC interpreter sources currently involve Python/Boost.Python remap paths. For the first WASM target:
|
||||
|
||||
- disable Python remap
|
||||
- disable dynamic module loading
|
||||
- replace file-backed parameter persistence with in-memory buffers
|
||||
- provide browser-safe tool table and INI/config loading through JSON
|
||||
|
||||
## Step 5: Emscripten build
|
||||
|
||||
Generate:
|
||||
|
||||
- `web/public/cnc_sim.js`
|
||||
- `web/public/cnc_sim.wasm`
|
||||
|
||||
Command:
|
||||
|
||||
```bash
|
||||
./build-wasm.sh
|
||||
```
|
||||
|
||||
## Step 6: Controller dialects
|
||||
|
||||
Fanuc and Siemens support should remain outside the LinuxCNC core as preprocessors/adapters. They normalize controller-specific constructs into the internal event/interpreter input layer.
|
||||
|
||||
## Functional parity matrix
|
||||
|
||||
This matrix tracks LinuxCNC feature coverage for the web/WASM simulator. A feature is not considered covered until it has a native regression in at least the `librs274` runner and the source-link runner.
|
||||
|
||||
| Area | Status | Regression |
|
||||
| --- | --- | --- |
|
||||
| Basic modal motion `G0/G1/G2/G3` | covered | `tests/gcode/linuxcnc_basic_motion.ngc`, `tests/gcode/basic_mill.ngc` |
|
||||
| Tool select/change `T... M6` | covered with minimal native tooldata | `tests/gcode/basic_mill.ngc` |
|
||||
| RTCP controls `G43.4/G43.5/G49` | covered as simulator-owned control lines | `tests/gcode/linuxcnc_rtcp_controls.ngc` |
|
||||
| Kinematics switch `M428/M429/M430` | covered as simulator-owned control lines | `tests/gcode/linuxcnc_rtcp_controls.ngc` |
|
||||
| Canned cycle `G81/G80` | covered for drilling expand-to-canon path | `tests/gcode/linuxcnc_canned_cycle.ngc` |
|
||||
| Coordinate offset Canon events | bridge-level covered | `core/tests/linuxcnc_canon_bridge_smoke.cpp` |
|
||||
| Cutter compensation | pending | add LinuxCNC corpus and tolerance checks |
|
||||
| O-word subroutines and calls | pending | current line-by-line runner does not execute sub bodies like LinuxCNC task planner |
|
||||
| Broader canned cycles `G82`-`G89` | pending | add corpus after `G81` baseline |
|
||||
| Full source-level wasm build | pending | replace Python/HAL/INI/tooldata support dependencies |
|
||||
Reference in New Issue
Block a user