Add LinuxCNC G10 L20 coordinate regression

This commit is contained in:
CNC Local
2026-05-22 04:53:48 +08:00
parent bf7192cc07
commit 8afbadc6d0
4 changed files with 55 additions and 4 deletions

View File

@@ -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 后端

View File

@@ -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"

View File

@@ -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"

View File

@@ -0,0 +1,5 @@
G21 G90 G17
G0 X5 Y6 Z7
G10 L20 P2 X1 Y2 Z3
G55
M30