From 8afbadc6d09e0faef6af39bdfb3a6b1663674014 Mon Sep 17 00:00:00 2001 From: CNC Local Date: Fri, 22 May 2026 04:53:48 +0800 Subject: [PATCH] Add LinuxCNC G10 L20 coordinate regression --- README.zh-CN.md | 6 ++--- .../cnc_sim_api_linuxcnc_rs274_smoke.cpp | 26 +++++++++++++++++++ test-linuxcnc-rs274-native.sh | 22 +++++++++++++++- tests/gcode/linuxcnc_coordinate_l20.ngc | 5 ++++ 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 tests/gcode/linuxcnc_coordinate_l20.ngc diff --git a/README.zh-CN.md b/README.zh-CN.md index a94da87..d510bdf 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -57,7 +57,7 @@ The first useful target is: - 已有最小 LinuxCNC tooldata 初始化,native runner 和 API 后端都能覆盖 `T... M6` 换刀路径。 - 已有 LinuxCNC RS274 源码级链接 smoke:本项目直接编译 23 个解释器 core 源文件,不再通过 `librs274` 取得解释器主体。 - 已有五轴 RTCP 第一版几何内核,可根据编程刀尖点、A/B/C 姿态和刀长计算枢轴/主轴点补偿位置。 -- 已有坐标系事件回归语料,覆盖 `G10 L2` 的 G5X/XY 旋转事件和 `G92.1` 清零事件。 +- 已有坐标系事件回归语料,覆盖 `G10 L2`、`G10 L20` 的 G5X/XY 旋转事件和 `G92.1` 清零事件。 - LinuxCNC Canon bridge 会把当前解释行号补到没有自带 `lineno` 的回调事件上,方便 Web 端诊断和源码高亮。 - 下一步是继续替换源码级链接中残留的 Python、INI/HAL、文件系统和动态加载依赖,并把 RTCP 内核接入 canon 事件流和机型配置。 @@ -77,7 +77,7 @@ The first useful target is: - LinuxCNC RS274 源文件语法探针和对象编译探针 - LinuxCNC RS274 源码级链接 smoke - 五轴 RTCP 几何内核 smoke -- `G10 L2` / `G92.1` 坐标系事件回归 +- `G10 L2` / `G10 L20` / `G92.1` 坐标系事件回归 ## 后端选择 @@ -145,7 +145,7 @@ Canon bridge 已不再丢弃坐标系相关回调,会输出: - `set-xy-rotation`:来自 `SET_XY_ROTATION`,`feed` 暂存旋转角度。 这些事件先保证 LinuxCNC Canon 层信息完整进入 Web/core。具体 G-code(如 `G10`、`G92`、坐标旋转)是否触发这些回调,还要继续按 LinuxCNC 解释器参数路径逐项补回归语料。 -目前已有第一组回归语料 `tests/gcode/linuxcnc_coordinate_offsets.ngc`,覆盖 `G10 L2 P1 X... Y... Z... R...` 触发 `set-g5x-offset` / `set-xy-rotation`,以及 `G92.1` 触发 `set-g92-offset` 清零。后续继续扩展到 `G10 L20`、多坐标系 P 号、持久参数文件和旋转叠加运动路径。 +目前已有两组回归语料:`tests/gcode/linuxcnc_coordinate_offsets.ngc` 覆盖 `G10 L2 P1 X... Y... Z... R...` 触发 `set-g5x-offset` / `set-xy-rotation`,以及 `G92.1` 触发 `set-g92-offset` 清零;`tests/gcode/linuxcnc_coordinate_l20.ngc` 覆盖 `G10 L20 P2` 按当前位置和目标工件坐标计算 G55 偏置。测试脚本会在坐标系语料之间重置参数文件,避免 LinuxCNC 持久参数互相污染。后续继续扩展到更多坐标系 P 号、持久参数文件读写策略和旋转叠加运动路径。 LinuxCNC 中部分 Canon 函数不携带行号参数,bridge 会在调用解释器 `read/execute` 前记录当前输入行,并用它填充这类事件的 `line` 字段。 ## CMake native LinuxCNC 后端 diff --git a/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp b/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp index 56f5ce8..31bb717 100644 --- a/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp +++ b/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp @@ -69,6 +69,8 @@ int main() { bool saw_xy_rotation = false; bool saw_g92_clear = false; bool saw_coordinate_end_line = false; + bool saw_l20_g55_offset = false; + bool saw_l20_end_line = false; for (const auto &event : events) { saw_tool = saw_tool || event.type == CNC_SIM_EVENT_TOOL_CHANGE; saw_rapid = saw_rapid || event.type == CNC_SIM_EVENT_RAPID; @@ -117,6 +119,30 @@ int main() { ok &= expect(saw_g49, "expected LinuxCNC G49 RTCP off state"); ok &= expect(saw_g434, "expected LinuxCNC G43.4 RTCP on state with H code"); + const char l20_program[] = + "G21 G90 G17\n" + "G0 X5 Y6 Z7\n" + "G10 L20 P2 X1 Y2 Z3\n" + "G55\n" + "M30\n"; + events.clear(); + ok &= expect(cnc_sim_parse_program(sim, l20_program, sizeof(l20_program) - 1) == 0, + cnc_sim_last_error(sim)); + for (const auto &event : events) { + saw_l20_g55_offset = saw_l20_g55_offset || + (event.type == CNC_SIM_EVENT_SET_G5X_OFFSET && + event.line == 4 && + event.tool == 2 && + event.start.x == 4.0 && + event.start.y == 4.0 && + event.start.z == 4.0); + saw_l20_end_line = saw_l20_end_line || + (event.type == CNC_SIM_EVENT_PROGRAM_END && + event.line == 5); + } + ok &= expect(saw_l20_g55_offset, "expected LinuxCNC G10 L20 P2 offset after G55 selection"); + ok &= expect(saw_l20_end_line, "expected LinuxCNC G10 L20 program end line number"); + const char coordinate_program[] = "G21 G90 G17\n" "G10 L2 P1 X12.5 Y-3 Z4 R30\n" diff --git a/test-linuxcnc-rs274-native.sh b/test-linuxcnc-rs274-native.sh index f1eb8ff..ce2df3c 100755 --- a/test-linuxcnc-rs274-native.sh +++ b/test-linuxcnc-rs274-native.sh @@ -8,7 +8,9 @@ cxx=${CXX:-g++} build_dir=${TMPDIR:-/tmp}/cnc_sim_native mkdir -p "$build_dir" var_file="$build_dir/rs274ngc.var" -cp "$linuxcnc_root/tests/halui/jogging/sim.var" "$var_file" +base_var_file="$build_dir/rs274ngc-base.var" +cp "$linuxcnc_root/tests/halui/jogging/sim.var" "$base_var_file" +cp "$base_var_file" "$var_file" "$cxx" -std=c++17 \ $(python3.13-config --includes 2>/dev/null || python3-config --includes) \ @@ -36,7 +38,10 @@ CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linux CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/basic_mill.ngc >/tmp/cnc_sim_linuxcnc_basic_mill.json CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_rtcp_controls.ngc >/tmp/cnc_sim_linuxcnc_rtcp_controls.json CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_canned_cycle.ngc >/tmp/cnc_sim_linuxcnc_canned_cycle.json +cp "$base_var_file" "$var_file" CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_coordinate_offsets.ngc >/tmp/cnc_sim_linuxcnc_coordinate_offsets.json +cp "$base_var_file" "$var_file" +CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_coordinate_l20.ngc >/tmp/cnc_sim_linuxcnc_coordinate_l20.json python3 - <<'PY' import json from pathlib import Path @@ -102,6 +107,20 @@ if not any( raise SystemExit("missing G92.1 clear offset event") if not any(event["type"] == "program-end" and event["line"] == 5 for event in coords): raise SystemExit("missing coordinate program end line number") + +l20 = json.loads(Path("/tmp/cnc_sim_linuxcnc_coordinate_l20.json").read_text()) +if not any( + event["type"] == "set-g5x-offset" and + event["line"] == 4 and + event["tool"] == 2 and + event["start"]["x"] == 4 and + event["start"]["y"] == 4 and + event["start"]["z"] == 4 + for event in l20 +): + raise SystemExit("missing G10 L20 P2 offset event after G55 selection") +if not any(event["type"] == "program-end" and event["line"] == 5 for event in l20): + raise SystemExit("missing G10 L20 program end line number") PY echo "linuxcnc rs274 native smoke passed" @@ -110,3 +129,4 @@ echo "dumped /tmp/cnc_sim_linuxcnc_basic_mill.json" echo "dumped /tmp/cnc_sim_linuxcnc_rtcp_controls.json" echo "dumped /tmp/cnc_sim_linuxcnc_canned_cycle.json" echo "dumped /tmp/cnc_sim_linuxcnc_coordinate_offsets.json" +echo "dumped /tmp/cnc_sim_linuxcnc_coordinate_l20.json" diff --git a/tests/gcode/linuxcnc_coordinate_l20.ngc b/tests/gcode/linuxcnc_coordinate_l20.ngc new file mode 100644 index 0000000..a78f6c7 --- /dev/null +++ b/tests/gcode/linuxcnc_coordinate_l20.ngc @@ -0,0 +1,5 @@ +G21 G90 G17 +G0 X5 Y6 Z7 +G10 L20 P2 X1 Y2 Z3 +G55 +M30