diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index d3a1f91..d97671e 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -24,6 +24,7 @@ if(CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND) list(APPEND cnc_sim_core_sources src/linuxcnc_canon_bridge.cpp src/linuxcnc_rs274_backend.cpp + src/linuxcnc_tooldata_fixture.cpp ) endif() @@ -143,7 +144,15 @@ if(CNC_SIM_ENABLE_LINUXCNC_BRIDGE) ${CNC_SIM_LINUXCNC_ROOT}/src ${CNC_SIM_LINUXCNC_ROOT}/include ) - target_link_libraries(cnc_sim_linuxcnc_canon_bridge PRIVATE cnc_sim_core) + target_link_directories(cnc_sim_linuxcnc_canon_bridge + PRIVATE + ${CNC_SIM_LINUXCNC_ROOT}/lib + ) + target_link_libraries(cnc_sim_linuxcnc_canon_bridge PRIVATE cnc_sim_core tooldata) + target_link_options(cnc_sim_linuxcnc_canon_bridge + PRIVATE + "-Wl,-rpath,${CNC_SIM_LINUXCNC_ROOT}/lib" + ) endif() if(EMSCRIPTEN) diff --git a/core/src/linuxcnc_canon_bridge.cpp b/core/src/linuxcnc_canon_bridge.cpp index 1d903a1..95c13da 100644 --- a/core/src/linuxcnc_canon_bridge.cpp +++ b/core/src/linuxcnc_canon_bridge.cpp @@ -3,6 +3,7 @@ #include "canon_event_sink.h" #include "canon.hh" +#include "emc/tooldata/tooldata.hh" #include #include @@ -736,8 +737,11 @@ int GET_EXTERNAL_SELECTED_TOOL_SLOT() { return active_sink ? active_sink->selected_tool() : -1; } -CANON_TOOL_TABLE GET_EXTERNAL_TOOL_TABLE(int) { - CANON_TOOL_TABLE tool{}; +CANON_TOOL_TABLE GET_EXTERNAL_TOOL_TABLE(int pocket) { + CANON_TOOL_TABLE tool = tooldata_entry_init(); + if (tooldata_get(&tool, pocket) == IDX_OK) { + return tool; + } std::memset(&tool, 0, sizeof(tool)); return tool; } diff --git a/core/src/linuxcnc_rs274_backend.cpp b/core/src/linuxcnc_rs274_backend.cpp index e441af8..dd18497 100644 --- a/core/src/linuxcnc_rs274_backend.cpp +++ b/core/src/linuxcnc_rs274_backend.cpp @@ -3,13 +3,13 @@ #include #include "linuxcnc_canon_bridge.h" +#include "linuxcnc_tooldata_fixture.h" #include "simulator_gcode_controls.h" #include "linuxcnc.h" #include "nml_intf/canon.hh" #include "nml_intf/interp_return.hh" #include "rs274ngc/interp_base.hh" -#include "emc/tooldata/tooldata.hh" #include #include @@ -32,27 +32,6 @@ struct _inittab builtin_modules[] = { namespace { -void init_minimal_tooldata_once() { - static bool created = false; - if (!created) { - tool_mmap_creator(nullptr, 0); - created = true; - } - - tooldata_reset(); - - CANON_TOOL_TABLE spindle = tooldata_entry_init(); - spindle.toolno = 0; - spindle.pocketno = 0; - tooldata_put(spindle, 0); - - CANON_TOOL_TABLE tool = tooldata_entry_init(); - tool.toolno = 1; - tool.pocketno = 1; - tool.diameter = 6.0; - tooldata_put(tool, 1); -} - bool normal_read_status(int status) { return status == INTERP_OK || status == INTERP_EXECUTE_FINISH || @@ -192,7 +171,7 @@ int parse_linuxcnc_rs274_backend(CanonEventSink &sink, if (const char *parameter_file = std::getenv("CNC_SIM_RS274_VAR")) { SET_PARAMETER_FILE_NAME(parameter_file); } - init_minimal_tooldata_once(); + cnc_sim_init_minimal_linuxcnc_tooldata(); sink.clear_callback_status(); cnc_sim_linuxcnc_set_canon_sink(&sink); diff --git a/core/src/linuxcnc_tooldata_fixture.cpp b/core/src/linuxcnc_tooldata_fixture.cpp new file mode 100644 index 0000000..5d0a1fd --- /dev/null +++ b/core/src/linuxcnc_tooldata_fixture.cpp @@ -0,0 +1,25 @@ +#include "linuxcnc_tooldata_fixture.h" + +#include "emc/tooldata/tooldata.hh" + +void cnc_sim_init_minimal_linuxcnc_tooldata() { + static bool created = false; + if (!created) { + tool_mmap_creator(nullptr, 0); + created = true; + } + + tooldata_reset(); + + CANON_TOOL_TABLE spindle = tooldata_entry_init(); + spindle.toolno = 0; + spindle.pocketno = 0; + tooldata_put(spindle, 0); + + CANON_TOOL_TABLE tool = tooldata_entry_init(); + tool.toolno = 1; + tool.pocketno = 1; + tool.diameter = 6.0; + tooldata_put(tool, 1); + tooldata_last_index_set(1); +} diff --git a/core/src/linuxcnc_tooldata_fixture.h b/core/src/linuxcnc_tooldata_fixture.h new file mode 100644 index 0000000..0c094ef --- /dev/null +++ b/core/src/linuxcnc_tooldata_fixture.h @@ -0,0 +1,3 @@ +#pragma once + +void cnc_sim_init_minimal_linuxcnc_tooldata(); diff --git a/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp b/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp index c6dfc9b..89c9984 100644 --- a/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp +++ b/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp @@ -107,6 +107,10 @@ int main() { bool saw_cutter_right_first = false; bool saw_cutter_right_second = false; bool saw_cutter_right_off_move = false; + bool saw_explicit_cutter_left_first = false; + bool saw_explicit_cutter_left_second = false; + bool saw_explicit_cutter_right_first = false; + bool saw_explicit_cutter_right_second = 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; @@ -356,6 +360,16 @@ int main() { "G21 G90 G17\n" "G0 X0 Y0 Z0\n" "F100\n" + "G41 D1\n" + "G1 X20 Y0\n" + "G1 X20 Y20\n" + "G40\n" + "G1 X0 Y0\n" + "G42 D1\n" + "G1 X20 Y0\n" + "G1 X20 Y-20\n" + "G40\n" + "G1 X0 Y0\n" "G41.1 D6\n" "G1 X20 Y0\n" "G1 X20 Y20\n" @@ -399,13 +413,37 @@ int main() { event.line == 13 && near(event.end.x, 0.0) && near(event.end.y, 0.0)); + saw_explicit_cutter_left_first = saw_explicit_cutter_left_first || + (event.type == CNC_SIM_EVENT_LINEAR_FEED && + event.line == 16 && + near(event.end.x, 17.0) && + near(event.end.y, 3.0)); + saw_explicit_cutter_left_second = saw_explicit_cutter_left_second || + (event.type == CNC_SIM_EVENT_LINEAR_FEED && + event.line == 17 && + near(event.end.x, 17.0) && + near(event.end.y, 20.0)); + saw_explicit_cutter_right_first = saw_explicit_cutter_right_first || + (event.type == CNC_SIM_EVENT_LINEAR_FEED && + event.line == 21 && + near(event.end.x, 17.0) && + near(event.end.y, -3.0)); + saw_explicit_cutter_right_second = saw_explicit_cutter_right_second || + (event.type == CNC_SIM_EVENT_LINEAR_FEED && + event.line == 22 && + near(event.end.x, 17.0) && + near(event.end.y, -20.0)); } - ok &= expect(saw_cutter_left_first, "expected LinuxCNC G41.1 compensated lead-in motion"); - ok &= expect(saw_cutter_left_second, "expected LinuxCNC G41.1 compensated side motion"); + ok &= expect(saw_cutter_left_first, "expected LinuxCNC G41 D1 compensated lead-in motion"); + ok &= expect(saw_cutter_left_second, "expected LinuxCNC G41 D1 compensated side motion"); ok &= expect(saw_cutter_left_off_move, "expected LinuxCNC G40 move after left compensation"); - ok &= expect(saw_cutter_right_first, "expected LinuxCNC G42.1 compensated lead-in motion"); - ok &= expect(saw_cutter_right_second, "expected LinuxCNC G42.1 compensated side motion"); + ok &= expect(saw_cutter_right_first, "expected LinuxCNC G42 D1 compensated lead-in motion"); + ok &= expect(saw_cutter_right_second, "expected LinuxCNC G42 D1 compensated side motion"); ok &= expect(saw_cutter_right_off_move, "expected LinuxCNC G40 move after right compensation"); + ok &= expect(saw_explicit_cutter_left_first, "expected LinuxCNC G41.1 D6 compensated lead-in motion"); + ok &= expect(saw_explicit_cutter_left_second, "expected LinuxCNC G41.1 D6 compensated side motion"); + ok &= expect(saw_explicit_cutter_right_first, "expected LinuxCNC G42.1 D6 compensated lead-in motion"); + ok &= expect(saw_explicit_cutter_right_second, "expected LinuxCNC G42.1 D6 compensated side motion"); const char comment_program[] = "G21 G90 G17\n" diff --git a/core/tools/linuxcnc_rs274_dump.cpp b/core/tools/linuxcnc_rs274_dump.cpp index 5f8f333..30f6b5d 100644 --- a/core/tools/linuxcnc_rs274_dump.cpp +++ b/core/tools/linuxcnc_rs274_dump.cpp @@ -2,13 +2,13 @@ #include "canon_event_sink.h" #include "linuxcnc_canon_bridge.h" +#include "linuxcnc_tooldata_fixture.h" #include "simulator_gcode_controls.h" #include "linuxcnc.h" #include "nml_intf/interp_return.hh" #include "nml_intf/canon.hh" #include "rs274ngc/interp_base.hh" -#include "emc/tooldata/tooldata.hh" #include #include @@ -238,22 +238,6 @@ bool execute_open_file(InterpBase *interp, const char *path) { return ok; } -void init_minimal_tooldata() { - tool_mmap_creator(nullptr, 0); - tooldata_reset(); - - CANON_TOOL_TABLE spindle = tooldata_entry_init(); - spindle.toolno = 0; - spindle.pocketno = 0; - tooldata_put(spindle, 0); - - CANON_TOOL_TABLE tool = tooldata_entry_init(); - tool.toolno = 1; - tool.pocketno = 1; - tool.diameter = 6.0; - tooldata_put(tool, 1); -} - } // namespace int main(int argc, char **argv) { @@ -264,7 +248,7 @@ int main(int argc, char **argv) { if (const char *parameter_file = std::getenv("CNC_SIM_RS274_VAR")) { SET_PARAMETER_FILE_NAME(parameter_file); } - init_minimal_tooldata(); + cnc_sim_init_minimal_linuxcnc_tooldata(); CanonEventSink sink; bool first = true; diff --git a/docs/linuxcnc-porting.md b/docs/linuxcnc-porting.md index 7766ca5..6b70676 100644 --- a/docs/linuxcnc-porting.md +++ b/docs/linuxcnc-porting.md @@ -192,7 +192,7 @@ This matrix tracks LinuxCNC feature coverage for the web/WASM simulator. A featu | Kinematics switch `M428/M429/M430` | covered as simulator-owned control lines | `tests/gcode/linuxcnc_rtcp_controls.ngc` | | Canned cycle `G81/G80` | covered for drilling expand-to-canon path | `tests/gcode/linuxcnc_canned_cycle.ngc` | | Coordinate offset Canon events | bridge-level covered | `core/tests/linuxcnc_canon_bridge_smoke.cpp` | -| Cutter compensation | covered for explicit-radius `G41.1/G42.1/G40` through LinuxCNC native/source backends; tool-table `G41/G42 D...` remains pending | `tests/gcode/linuxcnc_cutter_comp.ngc` | +| Cutter compensation | covered for tool-table `G41/G42 D...` and explicit-radius `G41.1/G42.1/G40` through LinuxCNC native/source backends | `tests/gcode/linuxcnc_cutter_comp.ngc` | | O-word subroutines and calls | covered for numeric `O... sub/call/return/endsub` through LinuxCNC file mode; smoke parser also covers named `O` sub/call/return/endsub | `tests/gcode/smoke_oword_subprogram.ngc` | | Broader canned cycles `G73`, `G82`-`G89` | partially covered: `G73`, `G82`, `G83`, `G85`, `G86`, `G89` | `tests/gcode/linuxcnc_canned_cycles_extended.ngc`, smoke API regression | | Full source-level wasm build | pending | replace Python/HAL/INI/tooldata support dependencies | diff --git a/test-linuxcnc-api-native.sh b/test-linuxcnc-api-native.sh index 014298c..05becba 100755 --- a/test-linuxcnc-api-native.sh +++ b/test-linuxcnc-api-native.sh @@ -26,6 +26,7 @@ cp "$linuxcnc_root/tests/halui/jogging/sim.var" "$var_file" core/src/gcode_backend.cpp \ core/src/linuxcnc_canon_bridge.cpp \ core/src/linuxcnc_rs274_backend.cpp \ + core/src/linuxcnc_tooldata_fixture.cpp \ core/src/rtcp_kinematics.cpp \ core/src/simulator_gcode_controls.cpp \ core/src/smoke_gcode_parser.cpp \ diff --git a/test-linuxcnc-bridge-native.sh b/test-linuxcnc-bridge-native.sh index 878635d..8bb82b2 100755 --- a/test-linuxcnc-bridge-native.sh +++ b/test-linuxcnc-bridge-native.sh @@ -21,6 +21,9 @@ mkdir -p "$build_dir" core/src/linuxcnc_canon_bridge.cpp \ core/src/rtcp_kinematics.cpp \ core/tests/linuxcnc_canon_bridge_smoke.cpp \ + -L "$linuxcnc_root/lib" \ + -Wl,-rpath,"$linuxcnc_root/lib" \ + -ltooldata \ -o "$build_dir/linuxcnc_canon_bridge_smoke" "$build_dir/linuxcnc_canon_bridge_smoke" diff --git a/test-linuxcnc-rs274-native.sh b/test-linuxcnc-rs274-native.sh index 01bbc74..b69e695 100755 --- a/test-linuxcnc-rs274-native.sh +++ b/test-linuxcnc-rs274-native.sh @@ -24,6 +24,7 @@ cp "$base_var_file" "$var_file" -I "$linuxcnc_root/include" \ core/src/canon_event_sink.cpp \ core/src/linuxcnc_canon_bridge.cpp \ + core/src/linuxcnc_tooldata_fixture.cpp \ core/src/rtcp_kinematics.cpp \ core/src/simulator_gcode_controls.cpp \ core/tools/linuxcnc_rs274_dump.cpp \ @@ -228,6 +229,12 @@ expected_cutter_comp = [ ("linear-feed", 11, 17, -3), ("linear-feed", 12, 17, -20), ("linear-feed", 13, 0, 0), + ("linear-feed", 16, 17, 3), + ("linear-feed", 17, 17, 20), + ("linear-feed", 18, 0, 0), + ("linear-feed", 21, 17, -3), + ("linear-feed", 22, 17, -20), + ("linear-feed", 23, 0, 0), ] actual_cutter_comp = [ (event["type"], event["line"], event["end"]["x"], event["end"]["y"]) diff --git a/test-linuxcnc-source-link.sh b/test-linuxcnc-source-link.sh index c15dc69..761f178 100755 --- a/test-linuxcnc-source-link.sh +++ b/test-linuxcnc-source-link.sh @@ -46,6 +46,7 @@ done < linuxcnc-rs274-source-files.txt for source in \ core/src/canon_event_sink.cpp \ core/src/linuxcnc_canon_bridge.cpp \ + core/src/linuxcnc_tooldata_fixture.cpp \ core/src/rtcp_kinematics.cpp \ core/src/simulator_gcode_controls.cpp \ core/tools/linuxcnc_rs274_dump.cpp; do @@ -205,6 +206,12 @@ expected_cutter_comp = [ ("linear-feed", 11, 17, -3), ("linear-feed", 12, 17, -20), ("linear-feed", 13, 0, 0), + ("linear-feed", 16, 17, 3), + ("linear-feed", 17, 17, 20), + ("linear-feed", 18, 0, 0), + ("linear-feed", 21, 17, -3), + ("linear-feed", 22, 17, -20), + ("linear-feed", 23, 0, 0), ] actual_cutter_comp = [ (event["type"], event["line"], event["end"]["x"], event["end"]["y"]) diff --git a/tests/gcode/linuxcnc_cutter_comp.ngc b/tests/gcode/linuxcnc_cutter_comp.ngc index 581c46b..527ee54 100644 --- a/tests/gcode/linuxcnc_cutter_comp.ngc +++ b/tests/gcode/linuxcnc_cutter_comp.ngc @@ -1,6 +1,16 @@ G21 G90 G17 G0 X0 Y0 Z0 F100 +G41 D1 +G1 X20 Y0 +G1 X20 Y20 +G40 +G1 X0 Y0 +G42 D1 +G1 X20 Y0 +G1 X20 Y-20 +G40 +G1 X0 Y0 G41.1 D6 G1 X20 Y0 G1 X20 Y20