From 25cb6885bf8dc1de8c22c864a197fda5d07481b8 Mon Sep 17 00:00:00 2001 From: cnc Date: Sat, 6 Jun 2026 08:26:21 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8C=89=E6=BA=90=E4=BF=AE=E6=AD=A3=E5=A4=96?= =?UTF-8?q?=E9=83=A8=E5=8D=95=E4=BD=8D=E6=8D=A2=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 结论:依据 LinuxCNC emccanon.cc 与 units.h,GET_EXTERNAL_LENGTH_UNITS 返回 user-units-per-mm 而非当前程序单位;新增 G20/G21 后 G92.3 恢复覆盖,native/source-link/test-native 均通过。 --- core/src/linuxcnc_canon_bridge.cpp | 9 +++++-- test-linuxcnc-rs274-native.sh | 27 ++++++++++++++++++++ test-linuxcnc-source-link.sh | 29 ++++++++++++++++++++++ tests/gcode/linuxcnc_units_g92_restore.ngc | 7 ++++++ 4 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 tests/gcode/linuxcnc_units_g92_restore.ngc diff --git a/core/src/linuxcnc_canon_bridge.cpp b/core/src/linuxcnc_canon_bridge.cpp index f4e2dea..b034505 100644 --- a/core/src/linuxcnc_canon_bridge.cpp +++ b/core/src/linuxcnc_canon_bridge.cpp @@ -782,11 +782,16 @@ int GET_EXTERNAL_FLOOD() { } CANON_UNITS GET_EXTERNAL_LENGTH_UNIT_TYPE() { - return active_sink && active_sink->unit_scale() == 25.4 ? CANON_UNITS_INCHES : CANON_UNITS_MM; + // LinuxCNC src/emc/task/emccanon.cc derives this from INI machine/user + // units, not from the active G20/G21 program units. + return CANON_UNITS_MM; } double GET_EXTERNAL_LENGTH_UNITS() { - return active_sink ? active_sink->unit_scale() : 1.0; + // LinuxCNC src/emc/task/emccanon.cc returns traj.linearUnits here: + // external/user units per internal millimeter. The simulator has no INI + // machine-units bridge yet, so the source-linked default is metric. + return 1.0; } double GET_EXTERNAL_ANGLE_UNITS() { diff --git a/test-linuxcnc-rs274-native.sh b/test-linuxcnc-rs274-native.sh index 9487e0a..bd7deef 100755 --- a/test-linuxcnc-rs274-native.sh +++ b/test-linuxcnc-rs274-native.sh @@ -1178,6 +1178,10 @@ CNC_SIM_RS274_FILE_MODE=1 CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs2 # asserts that unit changes rescale current linear axes and work/G92 linear # offsets while rotary axes remain angular values. CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_units_current_position.ngc >"$output_dir/cnc_sim_linuxcnc_units_current_position.json" +# Source basis: LinuxCNC src/emc/rs274ngc/interp_convert.cc convert_axis_offsets() +# stores G92 offsets through PROGRAM_TO_USER_LEN and restores them through +# USER_TO_PROGRAM_LEN after convert_length_units() changes active program units. +CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_units_g92_restore.ngc >"$output_dir/cnc_sim_linuxcnc_units_g92_restore.json" CNC_SIM_RS274_NATIVE_OUTPUT_DIR="$output_dir" python3 - <<'PY' import json import os @@ -1224,6 +1228,28 @@ if units_rapid[2]["start"] != units_rapid[2]["end"]: if (units_rapid[1]["end"]["a"], units_rapid[1]["end"]["b"], units_rapid[1]["end"]["c"]) != (4, 5, 6): raise SystemExit("LinuxCNC G21 unit change unexpectedly scaled rotary axes") +units_g92_restore = load("cnc_sim_linuxcnc_units_g92_restore.json") +units_g92_states = [ + ( + event["line"], + event["start"]["x"], + event["start"]["y"], + event["start"]["z"], + event["start"]["a"], + event["start"]["b"], + event["start"]["c"], + ) + for event in units_g92_restore + if event["type"] == "set-g92-offset" and event["line"] > 0 +] +expected_units_g92_states = [ + (3, -1, -2, -3, -4, -5, -6), + (5, 0, 0, 0, 0, 0, 0), + (6, -25.4, -50.8, -76.2, -4, -5, -6), +] +if units_g92_states != expected_units_g92_states: + raise SystemExit(f"unexpected LinuxCNC G20/G21 G92 restore states: {units_g92_states!r}") + fractional_linenumbers = load("cnc_sim_linuxcnc_fractional_linenumbers.json") fractional_spindle_states = [ (event["line"], event["spindle"]) @@ -3076,6 +3102,7 @@ echo "dumped $output_dir/cnc_sim_linuxcnc_arc_center_tolerance_good_imperial.jso echo "dumped $output_dir/cnc_sim_linuxcnc_arc_center_tolerance_tight_metric_default.json" echo "dumped $output_dir/cnc_sim_linuxcnc_arc_center_tolerance_tight_metric_ini.err" echo "dumped $output_dir/cnc_sim_linuxcnc_units_current_position.json" +echo "dumped $output_dir/cnc_sim_linuxcnc_units_g92_restore.json" echo "dumped $output_dir/cnc_sim_linuxcnc_predefined_positions.json" echo "dumped $output_dir/cnc_sim_linuxcnc_machine_coordinates.json" echo "dumped $output_dir/cnc_sim_linuxcnc_cutter_comp.json" diff --git a/test-linuxcnc-source-link.sh b/test-linuxcnc-source-link.sh index acaba9a..ecfc442 100755 --- a/test-linuxcnc-source-link.sh +++ b/test-linuxcnc-source-link.sh @@ -1864,6 +1864,12 @@ CNC_SIM_RS274_FILE_MODE=1 CNC_SIM_RS274_VAR="$var_file" \ CNC_SIM_RS274_VAR="$var_file" \ "$build_dir/linuxcnc_rs274_source_dump" tests/gcode/linuxcnc_units_current_position.ngc \ >"$output_dir/cnc_sim_linuxcnc_source_units_current_position.json" +# Source basis: LinuxCNC src/emc/rs274ngc/interp_convert.cc convert_axis_offsets() +# stores G92 offsets through PROGRAM_TO_USER_LEN and restores them through +# USER_TO_PROGRAM_LEN after convert_length_units() changes active program units. +CNC_SIM_RS274_VAR="$var_file" \ + "$build_dir/linuxcnc_rs274_source_dump" tests/gcode/linuxcnc_units_g92_restore.ngc \ + >"$output_dir/cnc_sim_linuxcnc_source_units_g92_restore.json" CNC_SIM_RS274_SOURCE_OUTPUT_DIR="$output_dir" python3 - <<'PY' import json @@ -1922,6 +1928,28 @@ if units_rapid[2]["start"] != units_rapid[2]["end"]: if (units_rapid[1]["end"]["a"], units_rapid[1]["end"]["b"], units_rapid[1]["end"]["c"]) != (4, 5, 6): raise SystemExit("source-linked LinuxCNC G21 unit change unexpectedly scaled rotary axes") +units_g92_restore = load("cnc_sim_linuxcnc_source_units_g92_restore.json") +units_g92_states = [ + ( + event["line"], + event["start"]["x"], + event["start"]["y"], + event["start"]["z"], + event["start"]["a"], + event["start"]["b"], + event["start"]["c"], + ) + for event in units_g92_restore + if event["type"] == "set-g92-offset" and event["line"] > 0 +] +expected_units_g92_states = [ + (3, -1, -2, -3, -4, -5, -6), + (5, 0, 0, 0, 0, 0, 0), + (6, -25.4, -50.8, -76.2, -4, -5, -6), +] +if units_g92_states != expected_units_g92_states: + raise SystemExit(f"unexpected source-linked LinuxCNC G20/G21 G92 restore states: {units_g92_states!r}") + fractional_linenumbers = load("cnc_sim_linuxcnc_source_fractional_linenumbers.json") fractional_spindle_states = [ (event["line"], event["spindle"]) @@ -4176,3 +4204,4 @@ echo "dumped $output_dir/cnc_sim_linuxcnc_source_extended_linenumbers.json" echo "dumped $output_dir/cnc_sim_linuxcnc_source_close_and_downcase_words.json" echo "dumped $output_dir/cnc_sim_linuxcnc_source_percent_file_ignores_trailing.json" echo "dumped $output_dir/cnc_sim_linuxcnc_source_units_current_position.json" +echo "dumped $output_dir/cnc_sim_linuxcnc_source_units_g92_restore.json" diff --git a/tests/gcode/linuxcnc_units_g92_restore.ngc b/tests/gcode/linuxcnc_units_g92_restore.ngc new file mode 100644 index 0000000..66100ba --- /dev/null +++ b/tests/gcode/linuxcnc_units_g92_restore.ngc @@ -0,0 +1,7 @@ +G20 G90 G17 +(Source basis: LinuxCNC src/emc/rs274ngc/interp_convert.cc convert_length_units rescales G92 axis offsets, and convert_axis_offsets restores #5211-#5219 through USER_TO_PROGRAM_LEN and USER_TO_PROGRAM_ANG on G92.3.) +G92 X1 Y2 Z3 A4 B5 C6 +G21 +G92.2 +G92.3 +M30