From 15b04e875839604efb9926b9a74328418e2fe20a Mon Sep 17 00:00:00 2001 From: cnc Date: Sat, 6 Jun 2026 23:03:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0G1=E9=9B=B6=E8=BF=9B=E7=BB=99?= =?UTF-8?q?=E9=94=99=E8=AF=AFfixture=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 结论:新增 g1_zero_feed 负向 fixture,固定 G1 在 feed rate 为 0 时返回 INTERP_ERROR=5、输出 LinuxCNC 对应错误文本、不产生 STRAIGHT_FEED,且失败前不更新当前位置和 #5420/#5421/#5422。检查:git diff --check 通过;wasm-port/tests/native/verify_native_probes.sh 通过。 --- wasm-port/docs/porting-steps-standalone.md | 9 ++++-- .../linuxcnc_interp_minimal_runtime.cpp | 8 +++++ .../canon_errors/g1_zero_feed.expected | 9 ++++++ .../fixtures/gcode_errors/g1_zero_feed.ngc | 1 + .../tests/native/verify_native_probes.sh | 32 +++++++++++++++++++ 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 wasm-port/tests/fixtures/canon_errors/g1_zero_feed.expected create mode 100644 wasm-port/tests/fixtures/gcode_errors/g1_zero_feed.ngc diff --git a/wasm-port/docs/porting-steps-standalone.md b/wasm-port/docs/porting-steps-standalone.md index ae2c29a..4492279 100644 --- a/wasm-port/docs/porting-steps-standalone.md +++ b/wasm-port/docs/porting-steps-standalone.md @@ -365,6 +365,11 @@ Current verified progress: current-position parameter visibility for `#5420`, `#5421`, and `#5422`. The parameter source basis is LinuxCNC `interp_parameter_def.hh` and `interp_namedparams.cc`. +- `tests/fixtures/gcode_errors/g1_zero_feed.ngc` and + `tests/fixtures/canon_errors/g1_zero_feed.expected` pin the negative + `G1` zero-feed case. The source basis is LinuxCNC + `interp_convert.cc::convert_straight()` and + `rs274ngc_return.hh::NCE_CANNOT_DO_G1_WITH_ZERO_FEED_RATE`. - This proves the current extracted interpreter slice can parse and execute a simple traverse and feed move through a standalone canonical event sink. @@ -667,7 +672,7 @@ traverse path: 1. replace the temporary minimal `convert_g()` implementation with thin wrappers around more vendored interpreter conversion code, -2. add a negative fixture for `G1` without feed rate to start pinning error - semantics, +2. add `_x`/`_y`/`_z` named parameter fixture coverage and align it with + `#5420`/`#5421`/`#5422`, 3. keep all source changes inside `wasm-port/` and leave `../linuxcnc/` read-only. diff --git a/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_minimal_runtime.cpp b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_minimal_runtime.cpp index 161673f..5f38c7a 100644 --- a/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_minimal_runtime.cpp +++ b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_minimal_runtime.cpp @@ -10,6 +10,7 @@ #include "emc/rs274ngc/rs274ngc_interp.hh" #undef private +#include "emc/rs274ngc/rs274ngc_return.hh" #include "canon_event_sink.hh" PythonPlugin *python_plugin = nullptr; @@ -381,6 +382,13 @@ int Interp::convert_g(block_pointer block, setup_pointer settings) SET_FEED_RATE(block->f_number); } + if ((block->motion_to_be == G_1) && + (settings->feed_mode == FEED_MODE::UNITS_PER_MINUTE) && + (settings->feed_rate == 0.0)) { + setError("%s", NCE_CANNOT_DO_G1_WITH_ZERO_FEED_RATE); + return INTERP_ERROR; + } + const bool incremental = settings->distance_mode == DISTANCE_MODE::INCREMENTAL; if (block->x_flag) { settings->current_x = incremental ? settings->current_x + block->x_number diff --git a/wasm-port/tests/fixtures/canon_errors/g1_zero_feed.expected b/wasm-port/tests/fixtures/canon_errors/g1_zero_feed.expected new file mode 100644 index 0000000..2efceb3 --- /dev/null +++ b/wasm-port/tests/fixtures/canon_errors/g1_zero_feed.expected @@ -0,0 +1,9 @@ +execute_line_1=5 +error_text=Cannot do g1 with zero feed rate +setup.current_x=0 +setup.current_y=0 +setup.current_z=0 +setup.parameter_5420=0 +setup.parameter_5421=0 +setup.parameter_5422=0 +absent=canon_event=STRAIGHT_FEED diff --git a/wasm-port/tests/fixtures/gcode_errors/g1_zero_feed.ngc b/wasm-port/tests/fixtures/gcode_errors/g1_zero_feed.ngc new file mode 100644 index 0000000..b3e98be --- /dev/null +++ b/wasm-port/tests/fixtures/gcode_errors/g1_zero_feed.ngc @@ -0,0 +1 @@ +G1 X1.0 diff --git a/wasm-port/tests/native/verify_native_probes.sh b/wasm-port/tests/native/verify_native_probes.sh index b7dda83..14a0e50 100755 --- a/wasm-port/tests/native/verify_native_probes.sh +++ b/wasm-port/tests/native/verify_native_probes.sh @@ -5,6 +5,8 @@ ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)" BUILD_DIR="$ROOT_DIR/build/native" GCODE_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/gcode" CANON_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/canon" +GCODE_ERROR_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/gcode_errors" +CANON_ERROR_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/canon_errors" "$ROOT_DIR/tools/build_native_probes.sh" @@ -77,4 +79,34 @@ for fixture in "$GCODE_FIXTURE_DIR"/*.ngc; do check_fixture_output "$fixture" "$expected" "$stdout_file" done +for fixture in "$GCODE_ERROR_FIXTURE_DIR"/*.ngc; do + name="$(basename "$fixture" .ngc)" + expected="$CANON_ERROR_FIXTURE_DIR/$name.expected" + if [[ ! -f "$expected" ]]; then + echo "missing expected error fixture: $expected" >&2 + exit 1 + fi + + stdout_file="$BUILD_DIR/linuxcnc_interp_minimal_harness.$name.stdout.log" + stderr_file="$BUILD_DIR/linuxcnc_interp_minimal_harness.$name.stderr.log" + "$BUILD_DIR/linuxcnc_interp_minimal_harness" "$fixture" \ + >"$stdout_file" \ + 2>"$stderr_file" + + while IFS= read -r expected_line; do + [[ -z "$expected_line" ]] && continue + if [[ "$expected_line" == absent=* ]]; then + forbidden="${expected_line#absent=}" + if grep -Fq "$forbidden" "$stdout_file"; then + echo "unexpected output in $stdout_file: $forbidden" >&2 + exit 1 + fi + elif [[ "$expected_line" == error_text=* ]]; then + grep -Fq "${expected_line#error_text=}" "$stderr_file" + else + grep -Fq "$expected_line" "$stdout_file" + fi + done < "$expected" +done + echo "native probe validation complete"