按规划继续工作
结论:新增 rotary indexer 的 WASM 和浏览器验证,继续通过 vendored LinuxCNC 解释器路径覆盖运行边界。
This commit is contained in:
@@ -91,6 +91,9 @@ required LinuxCNC `_setup` state readback with the matching files in
|
||||
`Interp::synch()` through the WASM C ABI to validate the initialization
|
||||
canonical boundary, metric/inch machine-unit status edge, and current/selected
|
||||
tool slot status synchronization already covered by the native init harness.
|
||||
It also calls the vendored single-axis rotary indexer path through
|
||||
`Interp::execute()` to validate the `UNLOCK_ROTARY`/`LOCK_ROTARY` canonical
|
||||
runtime boundary already covered by the native indexer harness.
|
||||
It also writes selected G-code fixtures into the
|
||||
Emscripten filesystem through the SDK and runs them through LinuxCNC
|
||||
`Interp::open()`, `Interp::read()`, and `Interp::execute()` to validate the
|
||||
@@ -142,7 +145,8 @@ named-parameter file path and negative interpreter fixtures with expected
|
||||
error text plus absent canonical motion output. It also validates vendored
|
||||
`Interp::init()` and `Interp::synch()` through the same SDK/C ABI path,
|
||||
including initialization canonical events, metric/inch machine units, and tool
|
||||
slot readback. It also uses real browser OPFS
|
||||
slot readback, and checks the vendored rotary-indexer `G0 A...` execution path
|
||||
for `UNLOCK_ROTARY`/`LOCK_ROTARY` boundary events. It also uses real browser OPFS
|
||||
storage plus the interpreter SDK to restore and save a LinuxCNC parameter file
|
||||
through vendored `Interp::restore_parameters()` and `Interp::save_parameters()`,
|
||||
and directly checks missing-file success plus out-of-order parameter-file
|
||||
@@ -291,7 +295,9 @@ result before OPFS persistence writes the saved table text back. The same
|
||||
Node WASM and browser interpreter smokes now validate the exported
|
||||
`Interp::init()`/`Interp::synch()` probe for initialization canonical events,
|
||||
metric/inch `emcStatus` machine-unit conversion, and current/selected tool
|
||||
slot synchronization.
|
||||
slot synchronization. They also validate the exported rotary-indexer probe for
|
||||
vendored LinuxCNC `UNLOCK_ROTARY`/`LOCK_ROTARY` dispatch around a single-axis
|
||||
`G0 A...` move.
|
||||
OPFS validation covers the JavaScript host-boundary adapter, the INI browser
|
||||
smoke harness, the INI panel UI's machine-session load and G-code run buttons,
|
||||
the raw canonical-event display fed directly by LinuxCNC interpreter WASM
|
||||
|
||||
@@ -31,7 +31,7 @@ semantic rewrites:
|
||||
| Tool table storage | Vendored LinuxCNC `tooldata_common.cc` owns tool-table parsing and formatting; the standalone boundary only supplies the in-memory `tooldata_get()`/`tooldata_put()` callbacks, exposes load/save through the WASM C ABI, and forwards the host random-toolchanger flag to LinuxCNC `tooldata_init()`. |
|
||||
| Tool slot status | Standalone tool adapter state supplies `GET_EXTERNAL_TOOL_SLOT()` and `GET_EXTERNAL_SELECTED_TOOL_SLOT()` for vendored `Interp::synch()`; `linuxcnc_interp_init_harness` plus Node WASM and browser interpreter smokes guard current/selected slot synchronization. |
|
||||
| Interpreter state tags | LinuxCNC `UPDATE_TAG` callbacks are captured from the state tags packed by vendored interpreter code; standalone code does not derive modal state. |
|
||||
| Rotary indexer lock state | LinuxCNC `UNLOCK_ROTARY` and `LOCK_ROTARY` callbacks are captured from the vendored single-axis indexer path; standalone code does not implement rotary-indexing semantics. |
|
||||
| Rotary indexer lock state | LinuxCNC `UNLOCK_ROTARY` and `LOCK_ROTARY` callbacks are captured from the vendored single-axis indexer path; standalone code does not implement rotary-indexing semantics, and native, Node WASM, and browser interpreter smokes validate the same boundary events. |
|
||||
| File flush | LinuxCNC `FINISH` is captured as a canonical test event on the vendored `%`-delimited file-reading path. |
|
||||
| WASM parameter-file backup | LinuxCNC `save_parameters()` calls `link()` to create the `.bak` parameter-file backup; `runtime/core/linuxcnc_wrap/linuxcnc_wasm_posix_stubs.cpp` maps that WASM/MEMFS edge to a file copy so the vendored save path can run unchanged. |
|
||||
| Interpreter reset | LinuxCNC `ON_RESET` is captured as a canonical test event on the vendored interpreter reset/file-open path. |
|
||||
|
||||
@@ -45,7 +45,7 @@ Current validation is intentionally mechanical:
|
||||
| Ruckig C planner support | Selected `src/emc/tp/cruckig/*.c` and `*.h` files in the manifest | Copy unchanged | Used as LinuxCNC planner support code through vendored TP sources | Vendor byte sync, per-file source probes |
|
||||
| Posemath | `src/libnml/posemath/posemath.cc`, `_posemath.c`, `gomath.c`, `sincos.c`, and matching headers | Copy unchanged | `gomath.c` is compiled as C; `rtapi.h` shim is C/C++ compatible for this boundary | Vendor byte sync, per-file source probes, TP probe |
|
||||
| RS274 interpreter state and parser | `src/emc/rs274ngc/modal_state.*`, `interp_internal.*`, `interp_read.cc`, `interp_check.cc`, `interp_execute.cc`, `interp_find.cc`, `interp_array.cc`, `interp_queue.*`, `rs274ngc*`, `units.h` | Copy unchanged | Python/remap/runtime edges are isolated in standalone wrappers and shims; parser and execution logic remain LinuxCNC source | Vendor byte sync, per-file source probes, interpreter harness fixtures |
|
||||
| RS274 conversion semantics | `src/emc/rs274ngc/interp_convert.cc`, `interp_arc.cc`, `interp_inverse.cc`, `interp_cycles.cc`, `interp_g7x.cc`, `interp_o_word.cc`, `interp_write.cc` | Copy unchanged | Canonical calls are captured by standalone event sink functions; conversion behavior stays in vendored LinuxCNC files; feed-rate state is read back through the canonical runtime boundary during length-unit conversion | Vendor byte sync, per-file source probes, canonical fixture suite, no standalone `Interp::convert_g()` guard |
|
||||
| RS274 conversion semantics | `src/emc/rs274ngc/interp_convert.cc`, `interp_arc.cc`, `interp_inverse.cc`, `interp_cycles.cc`, `interp_g7x.cc`, `interp_o_word.cc`, `interp_write.cc` | Copy unchanged | Canonical calls are captured by standalone event sink functions; conversion behavior stays in vendored LinuxCNC files; feed-rate state is read back through the canonical runtime boundary during length-unit conversion; single-axis rotary indexer lock/unlock dispatch remains vendored LinuxCNC `issue_straight_index()` behavior | Vendor byte sync, per-file source probes, canonical fixture suite, no standalone `Interp::convert_g()` guard, `linuxcnc_indexer_harness`, `tests/wasm/node/verify_interp_wasm.sh` and `tests/browser/verify_interp_browser.sh` rotary-indexer assertions |
|
||||
| Named parameters and tool slot status | `src/emc/rs274ngc/interp_namedparams.cc`, related interpreter headers | Copy unchanged | `_ini[...]` and `_hal[...]` resolve through standalone INI/HAL adapters while lookup order stays LinuxCNC-derived; current/selected tool slot reads for vendored `Interp::synch()` come from the standalone tool adapter | Vendor byte sync, source probe, `linuxcnc_namedparam_harness`, `linuxcnc_interp_init_harness`, `tests/wasm/node/verify_interp_wasm.sh` and `tests/browser/verify_interp_browser.sh` `Interp::synch()` tool-slot assertions |
|
||||
| Tool table parsing and formatting | `src/emc/tooldata/tooldata_common.cc` | Copy unchanged plus standalone storage callbacks | Native file parsing/formatting stays in vendored LinuxCNC source; the standalone tool adapter supplies `tooldata_get()`/`tooldata_put()` storage and index lookup, the WASM boundary only selects the LinuxCNC non-random or random-toolchanger branch via `tooldata_init()`, and OPFS remains a host-side persistence boundary | Vendor byte sync, `linuxcnc_tooldata_common_source_probe`, `tests/wasm/node/verify_interp_wasm.sh` non-random/random load/save tool-table assertions |
|
||||
| Dynamic interpreter base | `src/emc/rs274ngc/interp_base.*` | Copy unchanged | `interp_base.cc` source probe uses standalone `EMC2_HOME` compile-time path boundary for LinuxCNC dynamic interpreter lookup | Vendor byte sync, `linuxcnc_interp_base_source_probe` |
|
||||
|
||||
@@ -92,6 +92,26 @@ void initialize_minimal_interp(Interp &interp)
|
||||
std::memcpy(interp._readers, Interp::default_readers, sizeof(Interp::default_readers));
|
||||
}
|
||||
|
||||
void initialize_indexer_interp(Interp &interp)
|
||||
{
|
||||
standalone::reset_hal_adapter();
|
||||
standalone::reset_tool_adapter();
|
||||
|
||||
interp._setup.length_units = CANON_UNITS_MM;
|
||||
interp._setup.distance_mode = DISTANCE_MODE::ABSOLUTE;
|
||||
interp._setup.ijk_distance_mode = DISTANCE_MODE::ABSOLUTE;
|
||||
interp._setup.feed_mode = FEED_MODE::UNITS_PER_MINUTE;
|
||||
interp._setup.plane = CANON_PLANE::XY;
|
||||
interp._setup.motion_mode = G_0;
|
||||
interp._setup.percent_flag = false;
|
||||
interp._setup.sequence_number = 1;
|
||||
interp._setup.parameter_occurrence = 0;
|
||||
interp._setup.num_spindles = 1;
|
||||
interp._setup.a_indexer_jnum = 0;
|
||||
interp._setup.parameters[5599] = 1.0;
|
||||
std::memcpy(interp._readers, Interp::default_readers, sizeof(Interp::default_readers));
|
||||
}
|
||||
|
||||
std::vector<std::string> split_program_lines(const char *program_text)
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
@@ -447,6 +467,24 @@ char *lcinterp_probe_init_and_synch()
|
||||
return copy_result(output.str());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE
|
||||
char *lcinterp_probe_indexer()
|
||||
{
|
||||
Interp interp;
|
||||
standalone::reset_canon_events();
|
||||
initialize_indexer_interp(interp);
|
||||
|
||||
std::ostringstream output;
|
||||
const int rc = interp.execute("G0 A90\n");
|
||||
output << "execute=" << rc << "\n";
|
||||
output << "post_a=" << interp._setup.AA_current << "\n";
|
||||
output << "canon_event_count=" << standalone::canon_events().size() << "\n";
|
||||
for (const auto &event : standalone::canon_events()) {
|
||||
output << "canon_event=" << event << "\n";
|
||||
}
|
||||
return copy_result(output.str());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE
|
||||
void lcinterp_free_string(char *value)
|
||||
{
|
||||
|
||||
@@ -99,5 +99,9 @@ export async function createLinuxCncInterpSdk(moduleOptions = {}) {
|
||||
probeInitAndSynch() {
|
||||
return callStringResult(mod, "lcinterp_probe_init_and_synch");
|
||||
},
|
||||
|
||||
probeIndexer() {
|
||||
return callStringResult(mod, "lcinterp_probe_indexer");
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -156,6 +156,22 @@
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
verifyExpectedOutput(
|
||||
"probe_indexer",
|
||||
interp.probeIndexer(),
|
||||
[
|
||||
"execute=0",
|
||||
"post_a=90",
|
||||
"canon_event=SET_MOTION_CONTROL_MODE mode=2 tolerance=0",
|
||||
"canon_event=UNLOCK_ROTARY line=1 joint=0",
|
||||
"canon_event=STRAIGHT_TRAVERSE line=1 x=0 y=0 z=0 a=90 b=0 c=0 u=0 v=0 w=0",
|
||||
"canon_event=LOCK_ROTARY line=1 joint=0",
|
||||
"canon_event=SET_MOTION_CONTROL_MODE mode=1 tolerance=0",
|
||||
"canon_event=SET_NAIVECAM_TOLERANCE tolerance=0",
|
||||
"canon_event=UPDATE_TAG line=1",
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
for (const fixtureName of INTERP_BROWSER_MDI_FIXTURES) {
|
||||
const programText = await fetchText(`../fixtures/gcode/${fixtureName}.ngc`);
|
||||
const expectedText = await fetchText(`../fixtures/canon/${fixtureName}.events`);
|
||||
|
||||
@@ -114,6 +114,22 @@ verifyExpectedOutput(
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
verifyExpectedOutput(
|
||||
"probe_indexer",
|
||||
interp.probeIndexer(),
|
||||
[
|
||||
"execute=0",
|
||||
"post_a=90",
|
||||
"canon_event=SET_MOTION_CONTROL_MODE mode=2 tolerance=0",
|
||||
"canon_event=UNLOCK_ROTARY line=1 joint=0",
|
||||
"canon_event=STRAIGHT_TRAVERSE line=1 x=0 y=0 z=0 a=90 b=0 c=0 u=0 v=0 w=0",
|
||||
"canon_event=LOCK_ROTARY line=1 joint=0",
|
||||
"canon_event=SET_MOTION_CONTROL_MODE mode=1 tolerance=0",
|
||||
"canon_event=SET_NAIVECAM_TOLERANCE tolerance=0",
|
||||
"canon_event=UPDATE_TAG line=1",
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
for (const fixtureName of INTERP_MDI_FIXTURES) {
|
||||
const programText = readFileSync(
|
||||
resolve(rootDir, `tests/fixtures/gcode/${fixtureName}.ngc`),
|
||||
|
||||
@@ -96,5 +96,5 @@ link_wasm_module \
|
||||
-s STACK_SIZE=2MB \
|
||||
-s NO_EXIT_RUNTIME=1 \
|
||||
-s FORCE_FILESYSTEM=1 \
|
||||
-s EXPORTED_FUNCTIONS='["_malloc","_free","_lcinterp_run_program","_lcinterp_run_program_with_ini","_lcinterp_run_file","_lcinterp_run_file_with_ini","_lcinterp_restore_parameters","_lcinterp_save_parameters","_lcinterp_load_tool_table","_lcinterp_load_tool_table_random","_lcinterp_save_tool_table","_lcinterp_probe_init_and_synch","_lcinterp_free_string"]' \
|
||||
-s EXPORTED_FUNCTIONS='["_malloc","_free","_lcinterp_run_program","_lcinterp_run_program_with_ini","_lcinterp_run_file","_lcinterp_run_file_with_ini","_lcinterp_restore_parameters","_lcinterp_save_parameters","_lcinterp_load_tool_table","_lcinterp_load_tool_table_random","_lcinterp_save_tool_table","_lcinterp_probe_init_and_synch","_lcinterp_probe_indexer","_lcinterp_free_string"]' \
|
||||
-s EXPORTED_RUNTIME_METHODS='["FS","UTF8ToString","stringToUTF8","lengthBytesUTF8"]'
|
||||
|
||||
Reference in New Issue
Block a user