From c5a1d655b0320c08e58e6435c403cb7b066ea10e Mon Sep 17 00:00:00 2001 From: cnc Date: Wed, 3 Jun 2026 10:04:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=82=E8=80=83=E6=89=80=E6=9C=89=E5=88=86?= =?UTF-8?q?=E7=BB=84=EF=BC=9A=E8=A1=A5=20program=20end=20source=20?= =?UTF-8?q?=E8=A6=86=E7=9B=96=EF=BC=8C=E6=B5=8B=E8=AF=95=E9=80=9A=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test-linuxcnc-rs274-native.sh | 30 +++++++++++++++++++++ test-linuxcnc-source-link.sh | 34 ++++++++++++++++++++++++ tests/gcode/linuxcnc_program_end_m2.ngc | 5 ++++ tests/gcode/linuxcnc_program_end_m99.ngc | 5 ++++ 4 files changed, 74 insertions(+) create mode 100644 tests/gcode/linuxcnc_program_end_m2.ngc create mode 100644 tests/gcode/linuxcnc_program_end_m99.ngc diff --git a/test-linuxcnc-rs274-native.sh b/test-linuxcnc-rs274-native.sh index a83a890..47054e6 100755 --- a/test-linuxcnc-rs274-native.sh +++ b/test-linuxcnc-rs274-native.sh @@ -545,6 +545,14 @@ for case in "${tool_number_error_cases[@]}"; do grep -Fq "$expected" "$output_dir/cnc_sim_linuxcnc_$fixture.err" done CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_program_stops.ngc >"$output_dir/cnc_sim_linuxcnc_program_stops.json" +# Source basis: LinuxCNC src/emc/rs274ngc/interp_convert.cc convert_stop() +# sends M2 through the reset plus PROGRAM_END branch without the M30-only +# PALLET_SHUTTLE call. +CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_program_end_m2.ngc >"$output_dir/cnc_sim_linuxcnc_program_end_m2.json" +# Source basis: LinuxCNC src/emc/rs274ngc/interp_internal.hh defaults +# loop_on_main_m99 false; interp_convert.cc convert_stop() then treats +# main-program M99 as the same reset plus PROGRAM_END branch. +CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_program_end_m99.ngc >"$output_dir/cnc_sim_linuxcnc_program_end_m99.json" # Source basis: LinuxCNC src/emc/rs274ngc/interp_check.cc treats exactly # P-1.0 as a missing G4 dwell P word, while interp_convert.cc convert_dwell() # and interp_queue.cc enqueue_DWELL() pass neighboring values through. @@ -1370,6 +1378,26 @@ for expected in [(2, 1), (3, 2), (4, 3), (4, 1), (5, 0)]: if expected not in stop_states: raise SystemExit(f"missing program stop state {expected!r}") +for output_name, label in [ + ("cnc_sim_linuxcnc_program_end_m2.json", "M2"), + ("cnc_sim_linuxcnc_program_end_m99.json", "M99"), +]: + events = load(output_name) + line4 = [event for event in events if event["line"] == 4] + line4_types = {event["type"] for event in line4} + for expected_type in {"set-g5x-offset", "set-xy-rotation", "set-feed", "set-spindle", "program-end"}: + if expected_type not in line4_types: + raise SystemExit(f"missing native {label} reset event {expected_type}") + program_end_states = [ + event["reserved"] + for event in line4 + if event["type"] == "program-end" + ] + if program_end_states != [0]: + raise SystemExit(f"unexpected native {label} program-end states: {program_end_states!r}") + if any(event["type"] == "program-end" and event["reserved"] == 3 for event in line4): + raise SystemExit(f"unexpected native {label} pallet shuttle event") + g4_boundaries = load("cnc_sim_linuxcnc_g4_dwell_boundaries.json") g4_dwell_states = [ (event["line"], event["dwellSeconds"]) @@ -2791,6 +2819,8 @@ echo "dumped $output_dir/cnc_sim_linuxcnc_lathe_diameter_g76.json" echo "dumped $output_dir/cnc_sim_linuxcnc_g76only.json" echo "dumped $output_dir/cnc_sim_linuxcnc_tool_number.json" echo "dumped $output_dir/cnc_sim_linuxcnc_program_stops.json" +echo "dumped $output_dir/cnc_sim_linuxcnc_program_end_m2.json" +echo "dumped $output_dir/cnc_sim_linuxcnc_program_end_m99.json" echo "dumped $output_dir/cnc_sim_linuxcnc_coolant.json" echo "dumped $output_dir/cnc_sim_linuxcnc_feed_modes.json" echo "dumped $output_dir/cnc_sim_linuxcnc_motion_modes.json" diff --git a/test-linuxcnc-source-link.sh b/test-linuxcnc-source-link.sh index 0066b4e..7cf55a0 100755 --- a/test-linuxcnc-source-link.sh +++ b/test-linuxcnc-source-link.sh @@ -298,6 +298,18 @@ done CNC_SIM_RS274_VAR="$var_file" \ "$build_dir/linuxcnc_rs274_source_dump" tests/gcode/linuxcnc_program_stops.ngc \ >"$output_dir/cnc_sim_linuxcnc_source_program_stops.json" +# Source basis: LinuxCNC src/emc/rs274ngc/interp_convert.cc convert_stop() +# sends M2 through the reset plus PROGRAM_END branch without the M30-only +# PALLET_SHUTTLE call. +CNC_SIM_RS274_VAR="$var_file" \ + "$build_dir/linuxcnc_rs274_source_dump" tests/gcode/linuxcnc_program_end_m2.ngc \ + >"$output_dir/cnc_sim_linuxcnc_source_program_end_m2.json" +# Source basis: LinuxCNC src/emc/rs274ngc/interp_internal.hh defaults +# loop_on_main_m99 false; interp_convert.cc convert_stop() then treats +# main-program M99 as the same reset plus PROGRAM_END branch. +CNC_SIM_RS274_VAR="$var_file" \ + "$build_dir/linuxcnc_rs274_source_dump" tests/gcode/linuxcnc_program_end_m99.ngc \ + >"$output_dir/cnc_sim_linuxcnc_source_program_end_m99.json" # Source basis: LinuxCNC src/emc/rs274ngc/interp_check.cc treats exactly # P-1.0 as a missing G4 dwell P word, while interp_convert.cc convert_dwell() # and interp_queue.cc enqueue_DWELL() pass neighboring values through. @@ -1922,6 +1934,26 @@ for expected in [(2, 1), (3, 2), (4, 3), (4, 1), (5, 0)]: if expected not in stop_states: raise SystemExit(f"missing source-linked program stop state {expected!r}") +for output_name, label in [ + ("cnc_sim_linuxcnc_source_program_end_m2.json", "M2"), + ("cnc_sim_linuxcnc_source_program_end_m99.json", "M99"), +]: + events = load(output_name) + line4 = [event for event in events if event["line"] == 4] + line4_types = {event["type"] for event in line4} + for expected_type in {"set-g5x-offset", "set-xy-rotation", "set-feed", "set-spindle", "program-end"}: + if expected_type not in line4_types: + raise SystemExit(f"missing source-linked {label} reset event {expected_type}") + program_end_states = [ + event["reserved"] + for event in line4 + if event["type"] == "program-end" + ] + if program_end_states != [0]: + raise SystemExit(f"unexpected source-linked {label} program-end states: {program_end_states!r}") + if any(event["type"] == "program-end" and event["reserved"] == 3 for event in line4): + raise SystemExit(f"unexpected source-linked {label} pallet shuttle event") + g4_boundaries = load("cnc_sim_linuxcnc_source_g4_dwell_boundaries.json") g4_dwell_states = [ (event["line"], event["dwellSeconds"]) @@ -3497,6 +3529,8 @@ echo "dumped $output_dir/cnc_sim_linuxcnc_source_lathe_diameter_mode.json" echo "dumped $output_dir/cnc_sim_linuxcnc_source_lathe_diameter_g76.json" echo "dumped $output_dir/cnc_sim_linuxcnc_source_tool_number.json" echo "dumped $output_dir/cnc_sim_linuxcnc_source_program_stops.json" +echo "dumped $output_dir/cnc_sim_linuxcnc_source_program_end_m2.json" +echo "dumped $output_dir/cnc_sim_linuxcnc_source_program_end_m99.json" echo "dumped $output_dir/cnc_sim_linuxcnc_source_coolant.json" echo "dumped $output_dir/cnc_sim_linuxcnc_source_feed_modes.json" echo "dumped $output_dir/cnc_sim_linuxcnc_source_motion_modes.json" diff --git a/tests/gcode/linuxcnc_program_end_m2.ngc b/tests/gcode/linuxcnc_program_end_m2.ngc new file mode 100644 index 0000000..24463be --- /dev/null +++ b/tests/gcode/linuxcnc_program_end_m2.ngc @@ -0,0 +1,5 @@ +G21 G90 G17 +(Source basis: LinuxCNC src/emc/rs274ngc/interp_convert.cc convert_stop handles M2 in the reset plus PROGRAM_END branch.) +(Unlike M30 in the same branch, M2 does not call PALLET_SHUTTLE before PROGRAM_END.) +M2 +M30 diff --git a/tests/gcode/linuxcnc_program_end_m99.ngc b/tests/gcode/linuxcnc_program_end_m99.ngc new file mode 100644 index 0000000..44fb2cb --- /dev/null +++ b/tests/gcode/linuxcnc_program_end_m99.ngc @@ -0,0 +1,5 @@ +G21 G90 G17 +(Source basis: LinuxCNC src/emc/rs274ngc/interp_internal.hh defaults loop_on_main_m99 false.) +(Source basis: src/emc/rs274ngc/interp_convert.cc convert_stop treats main-program M99 like M2/M30 when looping is disabled.) +M99 +M30