diff --git a/README.zh-CN.md b/README.zh-CN.md index c8d2473..79f6c0f 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -61,6 +61,7 @@ The first useful target is: - 已有探针事件回归语料,LinuxCNC `G38.3` 会输出独立 `probe` 事件,不再混作普通直线进给。 - 已有主轴方向状态回归语料,`M3/M4/M5` 会通过 `set-spindle.reserved` 输出 `1=顺时针`、`2=逆时针`、`0=停止`。 - 已有注释事件行号回归语料,LinuxCNC `COMMENT` 事件会保留当前 G-code 行号。 +- 已有当前刀号事件行号回归语料,LinuxCNC `M61 Q...` 会输出带行号的 `tool-change` 事件。 - LinuxCNC Canon bridge 会把当前解释行号补到没有自带 `lineno` 的回调事件上,方便 Web 端诊断和源码高亮。 - 下一步是继续替换源码级链接中残留的 Python、INI/HAL、文件系统和动态加载依赖,并把 RTCP 内核接入 canon 事件流和机型配置。 @@ -81,6 +82,7 @@ The first useful target is: - LinuxCNC RS274 源码级链接 smoke - 五轴 RTCP 几何内核 smoke - `M3` / `M4` / `M5` 主轴方向事件回归 +- `M61 Q...` 当前刀号事件行号回归 - LinuxCNC 注释事件行号回归 - `G10 L2` / `G10 L20` / `G92.1` 坐标系事件回归 - `G38.3` 探针事件回归 diff --git a/core/src/linuxcnc_canon_bridge.cpp b/core/src/linuxcnc_canon_bridge.cpp index b9674ce..dc477d9 100644 --- a/core/src/linuxcnc_canon_bridge.cpp +++ b/core/src/linuxcnc_canon_bridge.cpp @@ -399,7 +399,7 @@ void USE_TOOL_LENGTH_OFFSET(const EmcPose &) { void CHANGE_TOOL_NUMBER(int number) { if (active_sink) { active_sink->select_tool(number); - active_sink->change_tool(0); + active_sink->change_tool(event_line()); } } diff --git a/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp b/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp index 1bd6b08..cb452b5 100644 --- a/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp +++ b/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp @@ -77,6 +77,7 @@ int main() { bool saw_spindle_ccw = false; bool saw_spindle_stop = false; bool saw_comment_line = false; + bool saw_tool_number_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; @@ -155,6 +156,21 @@ int main() { ok &= expect(saw_spindle_ccw, "expected LinuxCNC M4 counterclockwise spindle state"); ok &= expect(saw_spindle_stop, "expected LinuxCNC M5 stopped spindle state"); + const char tool_number_program[] = + "G21 G90 G17\n" + "M61 Q1\n" + "M30\n"; + events.clear(); + ok &= expect(cnc_sim_parse_program(sim, tool_number_program, sizeof(tool_number_program) - 1) == 0, + cnc_sim_last_error(sim)); + for (const auto &event : events) { + saw_tool_number_line = saw_tool_number_line || + (event.type == CNC_SIM_EVENT_TOOL_CHANGE && + event.line == 2 && + event.tool == 1); + } + ok &= expect(saw_tool_number_line, "expected LinuxCNC M61 tool-number event line"); + const char comment_program[] = "G21 G90 G17\n" "(operator note)\n" diff --git a/core/tests/linuxcnc_canon_bridge_smoke.cpp b/core/tests/linuxcnc_canon_bridge_smoke.cpp index f8e7365..1dca82a 100644 --- a/core/tests/linuxcnc_canon_bridge_smoke.cpp +++ b/core/tests/linuxcnc_canon_bridge_smoke.cpp @@ -40,6 +40,8 @@ int main() { STOP_SPINDLE_TURNING(0); SELECT_TOOL(7); CHANGE_TOOL(); + cnc_sim_linuxcnc_set_current_line(8); + CHANGE_TOOL_NUMBER(9); STRAIGHT_TRAVERSE(10, 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); STRAIGHT_FEED(11, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); ARC_FEED(12, 10.0, 10.0, 10.0, 5.0, 1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); @@ -57,6 +59,7 @@ int main() { ok &= expect(events[1].type == CNC_SIM_EVENT_SET_PLANE, "expected plane event"); bool saw_tool = false; + bool saw_tool_number = false; bool saw_rapid = false; bool saw_feed = false; bool saw_spindle_cw = false; @@ -71,6 +74,9 @@ int main() { bool saw_end = false; for (const auto &event : events) { saw_tool = saw_tool || (event.type == CNC_SIM_EVENT_TOOL_CHANGE && event.tool == 7); + saw_tool_number = saw_tool_number || (event.type == CNC_SIM_EVENT_TOOL_CHANGE && + event.line == 8 && + event.tool == 9); saw_spindle_cw = saw_spindle_cw || (event.type == CNC_SIM_EVENT_SET_SPINDLE && event.spindle == 1200.0 && event.reserved == 1); @@ -111,6 +117,7 @@ int main() { } ok &= expect(saw_tool, "expected tool change"); + ok &= expect(saw_tool_number, "expected tool number change line"); ok &= expect(saw_spindle_cw, "expected clockwise spindle state"); ok &= expect(saw_spindle_ccw, "expected counterclockwise spindle state"); ok &= expect(saw_spindle_stop, "expected stopped spindle state"); diff --git a/test-linuxcnc-rs274-native.sh b/test-linuxcnc-rs274-native.sh index 9c59d81..34ea394 100755 --- a/test-linuxcnc-rs274-native.sh +++ b/test-linuxcnc-rs274-native.sh @@ -38,6 +38,7 @@ 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_spindle_direction.ngc >/tmp/cnc_sim_linuxcnc_spindle_direction.json +CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_tool_number.ngc >/tmp/cnc_sim_linuxcnc_tool_number.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 CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_comments.ngc >/tmp/cnc_sim_linuxcnc_comments.json CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_probe_no_error.ngc >/tmp/cnc_sim_linuxcnc_probe_no_error.json @@ -85,6 +86,15 @@ if (3, 1200, 2) not in spindle_states: if (4, 0, 0) not in spindle_states: raise SystemExit("missing M5 stopped spindle state") +tool_number = json.loads(Path("/tmp/cnc_sim_linuxcnc_tool_number.json").read_text()) +if not any( + event["type"] == "tool-change" and + event["line"] == 2 and + event["tool"] == 1 + for event in tool_number +): + raise SystemExit("missing M61 Q1 tool-number event line") + cycle = json.loads(Path("/tmp/cnc_sim_linuxcnc_canned_cycle.json").read_text()) motions = [event for event in cycle if event["type"] in {"rapid", "linear-feed"}] expected_cycle = [ @@ -161,6 +171,7 @@ echo "dumped /tmp/cnc_sim_linuxcnc_basic_motion.json" echo "dumped /tmp/cnc_sim_linuxcnc_basic_mill.json" echo "dumped /tmp/cnc_sim_linuxcnc_rtcp_controls.json" echo "dumped /tmp/cnc_sim_linuxcnc_spindle_direction.json" +echo "dumped /tmp/cnc_sim_linuxcnc_tool_number.json" echo "dumped /tmp/cnc_sim_linuxcnc_canned_cycle.json" echo "dumped /tmp/cnc_sim_linuxcnc_comments.json" echo "dumped /tmp/cnc_sim_linuxcnc_probe_no_error.json" diff --git a/tests/gcode/linuxcnc_tool_number.ngc b/tests/gcode/linuxcnc_tool_number.ngc new file mode 100644 index 0000000..1d1b68f --- /dev/null +++ b/tests/gcode/linuxcnc_tool_number.ngc @@ -0,0 +1,3 @@ +G21 G90 G17 +M61 Q1 +M30