Initial wasm simulator checkpoint
This commit is contained in:
61
core/tests/canon_event_sink_smoke.cpp
Normal file
61
core/tests/canon_event_sink_smoke.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "canon_event_sink.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
int collect_event(const CncSimEvent *event, void *user_data) {
|
||||
auto *events = static_cast<std::vector<CncSimEvent> *>(user_data);
|
||||
events->push_back(*event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int abort_on_second_event(const CncSimEvent *, void *user_data) {
|
||||
auto *count = static_cast<int *>(user_data);
|
||||
++(*count);
|
||||
return *count >= 2 ? 1 : 0;
|
||||
}
|
||||
|
||||
bool expect(bool value, const char *message) {
|
||||
if (!value) {
|
||||
std::cerr << "FAIL: " << message << '\n';
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
bool ok = true;
|
||||
std::vector<CncSimEvent> events;
|
||||
CanonEventSink sink;
|
||||
sink.set_callback(collect_event, &events);
|
||||
|
||||
CncSimPose end{};
|
||||
end.x = 10.0;
|
||||
end.y = 5.0;
|
||||
sink.use_length_units(1.0, 1);
|
||||
sink.select_plane(17, 1);
|
||||
sink.set_feed_rate(500.0, 2);
|
||||
sink.straight_feed(3, end);
|
||||
sink.program_end(4);
|
||||
|
||||
ok &= expect(events.size() == 5, "expected five emitted events");
|
||||
ok &= expect(events[3].type == CNC_SIM_EVENT_LINEAR_FEED, "expected linear event");
|
||||
ok &= expect(events[3].end.x == 10.0 && events[3].end.y == 5.0, "expected updated end pose");
|
||||
ok &= expect(sink.position().x == 10.0 && sink.position().y == 5.0, "expected sink position update");
|
||||
|
||||
int abort_count = 0;
|
||||
sink.reset();
|
||||
sink.set_callback(abort_on_second_event, &abort_count);
|
||||
sink.select_plane(17, 1);
|
||||
sink.set_feed_rate(100.0, 2);
|
||||
sink.straight_feed(3, end);
|
||||
ok &= expect(sink.callback_aborted(), "expected callback abort state");
|
||||
ok &= expect(abort_count == 2, "expected no further callbacks after abort");
|
||||
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
162
core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp
Normal file
162
core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
#include "cnc_sim_api.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
int collect_event(const CncSimEvent *event, void *user_data) {
|
||||
auto *events = static_cast<std::vector<CncSimEvent> *>(user_data);
|
||||
events->push_back(*event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int abort_on_second_event(const CncSimEvent *, void *user_data) {
|
||||
auto *count = static_cast<int *>(user_data);
|
||||
++(*count);
|
||||
return *count >= 2 ? 1 : 0;
|
||||
}
|
||||
|
||||
bool expect(bool value, const char *message) {
|
||||
if (!value) {
|
||||
std::cerr << "FAIL: " << message << '\n';
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
const char config[] =
|
||||
"{\"backend\":\"linuxcnc-rs274\",\"rtcp\":{\"enabled\":true,\"toolLength\":100,\"toolLengths\":{\"7\":125}}}";
|
||||
const char program[] =
|
||||
"G21 G90 G17\n"
|
||||
"T1 M6\n"
|
||||
"M428 M429 M430\n"
|
||||
"G49\n"
|
||||
"G43.4 H7\n"
|
||||
"S8000 M3\n"
|
||||
"G0 X0 Y0 Z5\n"
|
||||
"F600\n"
|
||||
"G1 Z-1\n"
|
||||
"G1 X40 Y0\n"
|
||||
"G3 X40 Y40 I0 J20\n"
|
||||
"G1 X0 Y40\n"
|
||||
"G1 X0 Y0\n"
|
||||
"M30\n";
|
||||
|
||||
std::vector<CncSimEvent> events;
|
||||
CncSimHandle *sim = cnc_sim_create();
|
||||
cnc_sim_set_event_callback(sim, collect_event, &events);
|
||||
|
||||
bool ok = true;
|
||||
ok &= expect(cnc_sim_load_config_json(sim, config, sizeof(config) - 1) == 0, cnc_sim_last_error(sim));
|
||||
ok &= expect(cnc_sim_parse_program(sim, program, sizeof(program) - 1) == 0, cnc_sim_last_error(sim));
|
||||
|
||||
bool saw_tool = false;
|
||||
bool saw_rapid = false;
|
||||
bool saw_feed = false;
|
||||
bool saw_arc = false;
|
||||
bool saw_end = false;
|
||||
bool saw_rtcp = false;
|
||||
bool saw_m428 = false;
|
||||
bool saw_m429 = false;
|
||||
bool saw_m430 = false;
|
||||
bool saw_g49 = false;
|
||||
bool saw_g434 = false;
|
||||
bool saw_g5x_offset = false;
|
||||
bool saw_xy_rotation = false;
|
||||
bool saw_g92_clear = 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;
|
||||
saw_feed = saw_feed || event.type == CNC_SIM_EVENT_LINEAR_FEED;
|
||||
saw_arc = saw_arc || event.type == CNC_SIM_EVENT_ARC_FEED;
|
||||
saw_end = saw_end || event.type == CNC_SIM_EVENT_PROGRAM_END;
|
||||
saw_rtcp = saw_rtcp ||
|
||||
(event.type == CNC_SIM_EVENT_RTCP_PIVOT &&
|
||||
event.end.z == 130.0);
|
||||
saw_m428 = saw_m428 ||
|
||||
(event.type == CNC_SIM_EVENT_KINEMATICS_SWITCH &&
|
||||
event.line == 3 &&
|
||||
event.reserved == 1 &&
|
||||
event.feed == 1.0);
|
||||
saw_m429 = saw_m429 ||
|
||||
(event.type == CNC_SIM_EVENT_KINEMATICS_SWITCH &&
|
||||
event.line == 3 &&
|
||||
event.reserved == 0 &&
|
||||
event.feed == 0.0);
|
||||
saw_m430 = saw_m430 ||
|
||||
(event.type == CNC_SIM_EVENT_KINEMATICS_SWITCH &&
|
||||
event.line == 3 &&
|
||||
event.reserved == 2 &&
|
||||
event.feed == 1.0);
|
||||
saw_g49 = saw_g49 ||
|
||||
(event.type == CNC_SIM_EVENT_RTCP_STATE &&
|
||||
event.line == 4 &&
|
||||
event.feed == 0.0);
|
||||
saw_g434 = saw_g434 ||
|
||||
(event.type == CNC_SIM_EVENT_RTCP_STATE &&
|
||||
event.line == 5 &&
|
||||
event.feed == 1.0 &&
|
||||
event.tool == 7 &&
|
||||
event.dwell_seconds == 125.0);
|
||||
}
|
||||
|
||||
ok &= expect(saw_tool, "expected LinuxCNC tool-change event");
|
||||
ok &= expect(saw_rapid, "expected LinuxCNC rapid event");
|
||||
ok &= expect(saw_feed, "expected LinuxCNC linear-feed event");
|
||||
ok &= expect(saw_arc, "expected LinuxCNC arc-feed event");
|
||||
ok &= expect(saw_end, "expected LinuxCNC program-end event");
|
||||
ok &= expect(saw_rtcp, "expected LinuxCNC RTCP pivot event");
|
||||
ok &= expect(saw_m428, "expected LinuxCNC M428 kinematics switch");
|
||||
ok &= expect(saw_m429, "expected LinuxCNC M429 kinematics switch");
|
||||
ok &= expect(saw_m430, "expected LinuxCNC M430 kinematics switch");
|
||||
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 coordinate_program[] =
|
||||
"G21 G90 G17\n"
|
||||
"G10 L2 P1 X12.5 Y-3 Z4 R30\n"
|
||||
"G92 X1 Y2 Z3\n"
|
||||
"G92.1\n"
|
||||
"M30\n";
|
||||
events.clear();
|
||||
ok &= expect(cnc_sim_parse_program(sim, coordinate_program, sizeof(coordinate_program) - 1) == 0,
|
||||
cnc_sim_last_error(sim));
|
||||
for (const auto &event : events) {
|
||||
saw_g5x_offset = saw_g5x_offset ||
|
||||
(event.type == CNC_SIM_EVENT_SET_G5X_OFFSET &&
|
||||
event.tool == 1 &&
|
||||
event.start.x == 12.5 &&
|
||||
event.start.y == -3.0 &&
|
||||
event.start.z == 4.0);
|
||||
saw_xy_rotation = saw_xy_rotation ||
|
||||
(event.type == CNC_SIM_EVENT_SET_XY_ROTATION &&
|
||||
event.feed == 30.0);
|
||||
saw_g92_clear = saw_g92_clear ||
|
||||
(event.type == CNC_SIM_EVENT_SET_G92_OFFSET &&
|
||||
event.start.x == 0.0 &&
|
||||
event.start.y == 0.0 &&
|
||||
event.start.z == 0.0);
|
||||
}
|
||||
ok &= expect(saw_g5x_offset, "expected LinuxCNC G10 L2 G5X offset event");
|
||||
ok &= expect(saw_xy_rotation, "expected LinuxCNC G10 L2 XY rotation event");
|
||||
ok &= expect(saw_g92_clear, "expected LinuxCNC G92.1 clear offset event");
|
||||
|
||||
cnc_sim_destroy(sim);
|
||||
|
||||
int abort_count = 0;
|
||||
sim = cnc_sim_create();
|
||||
cnc_sim_set_event_callback(sim, abort_on_second_event, &abort_count);
|
||||
ok &= expect(cnc_sim_load_config_json(sim, config, sizeof(config) - 1) == 0, cnc_sim_last_error(sim));
|
||||
ok &= expect(cnc_sim_parse_program(sim, program, sizeof(program) - 1) != 0,
|
||||
"expected callback abort to stop LinuxCNC parsing");
|
||||
ok &= expect(abort_count == 2, "expected LinuxCNC parser to stop callbacks after abort");
|
||||
ok &= expect(std::string(cnc_sim_last_error(sim)) == "event callback aborted parsing",
|
||||
"expected callback abort error");
|
||||
cnc_sim_destroy(sim);
|
||||
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
141
core/tests/cnc_sim_api_smoke.cpp
Normal file
141
core/tests/cnc_sim_api_smoke.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
#include "cnc_sim_api.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
int collect_event(const CncSimEvent *event, void *user_data) {
|
||||
auto *events = static_cast<std::vector<CncSimEvent> *>(user_data);
|
||||
events->push_back(*event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool expect(bool value, const char *message) {
|
||||
if (!value) {
|
||||
std::cerr << "FAIL: " << message << '\n';
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
const char program[] =
|
||||
"G21 G90 G17\n"
|
||||
"T1 M6\n"
|
||||
"M428 M429 M430\n"
|
||||
"G49\n"
|
||||
"G43.4 H7\n"
|
||||
"S8000 M3\n"
|
||||
"G0 X0 Y0 Z5\n"
|
||||
"F600\n"
|
||||
"G1 Z-1\n"
|
||||
"G1 X20 Y0\n"
|
||||
"G3 X20 Y20 I0 J10\n"
|
||||
"G91 G1 X5\n"
|
||||
"G90 G4 P0.25\n"
|
||||
"G2 X25 Y25 R5\n"
|
||||
"M30\n";
|
||||
|
||||
std::vector<CncSimEvent> events;
|
||||
CncSimHandle *sim = cnc_sim_create();
|
||||
cnc_sim_set_event_callback(sim, collect_event, &events);
|
||||
const char smoke_config[] =
|
||||
"{\"backend\":\"smoke\",\"rtcp\":{\"enabled\":true,\"toolLength\":100,\"toolLengths\":{\"7\":125}}}";
|
||||
int config_rc = cnc_sim_load_config_json(sim, smoke_config, sizeof(smoke_config) - 1);
|
||||
|
||||
int rc = cnc_sim_parse_program(sim, program, sizeof(program) - 1);
|
||||
bool ok = true;
|
||||
ok &= expect(config_rc == 0, cnc_sim_last_error(sim));
|
||||
ok &= expect(rc == 0, cnc_sim_last_error(sim));
|
||||
ok &= expect(events.size() >= 8, "expected at least 8 events");
|
||||
ok &= expect(events[0].type == CNC_SIM_EVENT_SET_PLANE || events[0].type == CNC_SIM_EVENT_SET_UNITS,
|
||||
"expected modal setup event first");
|
||||
|
||||
bool saw_rapid = false;
|
||||
bool saw_feed = false;
|
||||
bool saw_arc = false;
|
||||
bool saw_dwell = false;
|
||||
bool saw_end = false;
|
||||
bool saw_units = false;
|
||||
bool saw_plane = false;
|
||||
bool saw_rtcp = false;
|
||||
bool saw_m428 = false;
|
||||
bool saw_m429 = false;
|
||||
bool saw_m430 = false;
|
||||
bool saw_g49 = false;
|
||||
bool saw_g434 = false;
|
||||
bool saw_incremental_move = false;
|
||||
bool saw_r_arc_center = false;
|
||||
for (const auto &event : events) {
|
||||
saw_rapid = saw_rapid || event.type == CNC_SIM_EVENT_RAPID;
|
||||
saw_feed = saw_feed || event.type == CNC_SIM_EVENT_LINEAR_FEED;
|
||||
saw_arc = saw_arc || event.type == CNC_SIM_EVENT_ARC_FEED;
|
||||
saw_dwell = saw_dwell || event.type == CNC_SIM_EVENT_DWELL;
|
||||
saw_end = saw_end || event.type == CNC_SIM_EVENT_PROGRAM_END;
|
||||
saw_units = saw_units || event.type == CNC_SIM_EVENT_SET_UNITS;
|
||||
saw_plane = saw_plane || event.type == CNC_SIM_EVENT_SET_PLANE;
|
||||
saw_rtcp = saw_rtcp ||
|
||||
(event.type == CNC_SIM_EVENT_RTCP_PIVOT &&
|
||||
event.line == 7 &&
|
||||
event.end.z == 130.0);
|
||||
saw_m428 = saw_m428 ||
|
||||
(event.type == CNC_SIM_EVENT_KINEMATICS_SWITCH &&
|
||||
event.line == 3 &&
|
||||
event.reserved == 1 &&
|
||||
event.feed == 1.0);
|
||||
saw_m429 = saw_m429 ||
|
||||
(event.type == CNC_SIM_EVENT_KINEMATICS_SWITCH &&
|
||||
event.line == 3 &&
|
||||
event.reserved == 0 &&
|
||||
event.feed == 0.0);
|
||||
saw_m430 = saw_m430 ||
|
||||
(event.type == CNC_SIM_EVENT_KINEMATICS_SWITCH &&
|
||||
event.line == 3 &&
|
||||
event.reserved == 2 &&
|
||||
event.feed == 1.0);
|
||||
saw_g49 = saw_g49 ||
|
||||
(event.type == CNC_SIM_EVENT_RTCP_STATE &&
|
||||
event.line == 4 &&
|
||||
event.feed == 0.0);
|
||||
saw_g434 = saw_g434 ||
|
||||
(event.type == CNC_SIM_EVENT_RTCP_STATE &&
|
||||
event.line == 5 &&
|
||||
event.feed == 1.0 &&
|
||||
event.tool == 7 &&
|
||||
event.dwell_seconds == 125.0);
|
||||
saw_incremental_move = saw_incremental_move ||
|
||||
(event.type == CNC_SIM_EVENT_LINEAR_FEED &&
|
||||
event.start.x == 20.0 && event.end.x == 25.0);
|
||||
saw_r_arc_center = saw_r_arc_center ||
|
||||
(event.type == CNC_SIM_EVENT_ARC_FEED &&
|
||||
event.line == 14 &&
|
||||
(event.center.x != event.start.x || event.center.y != event.start.y));
|
||||
}
|
||||
ok &= expect(saw_rapid, "expected rapid event");
|
||||
ok &= expect(saw_feed, "expected linear feed event");
|
||||
ok &= expect(saw_arc, "expected arc feed event");
|
||||
ok &= expect(saw_dwell, "expected dwell event");
|
||||
ok &= expect(saw_end, "expected program end event");
|
||||
ok &= expect(saw_units, "expected units event from multi-G line");
|
||||
ok &= expect(saw_plane, "expected plane event from multi-G line");
|
||||
ok &= expect(saw_rtcp, "expected RTCP pivot event from config");
|
||||
ok &= expect(saw_m428, "expected M428 original kinematics switch");
|
||||
ok &= expect(saw_m429, "expected M429 identity kinematics switch");
|
||||
ok &= expect(saw_m430, "expected M430 five-axis BC kinematics switch");
|
||||
ok &= expect(saw_g49, "expected G49 RTCP off state");
|
||||
ok &= expect(saw_g434, "expected G43.4 RTCP on state with H code");
|
||||
ok &= expect(saw_incremental_move, "expected G91 incremental move");
|
||||
ok &= expect(saw_r_arc_center, "expected R arc center calculation");
|
||||
|
||||
const char linuxcnc_config[] = "{\"backend\":\"linuxcnc-rs274\"}";
|
||||
config_rc = cnc_sim_load_config_json(sim, linuxcnc_config, sizeof(linuxcnc_config) - 1);
|
||||
rc = cnc_sim_parse_program(sim, program, sizeof(program) - 1);
|
||||
ok &= expect(config_rc == 0, cnc_sim_last_error(sim));
|
||||
ok &= expect(rc != 0, "expected uncompiled linuxcnc-rs274 backend to fail clearly");
|
||||
|
||||
cnc_sim_destroy(sim);
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
96
core/tests/linuxcnc_canon_bridge_smoke.cpp
Normal file
96
core/tests/linuxcnc_canon_bridge_smoke.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "canon_event_sink.h"
|
||||
#include "linuxcnc_canon_bridge.h"
|
||||
|
||||
#include "canon.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
int collect_event(const CncSimEvent *event, void *user_data) {
|
||||
auto *events = static_cast<std::vector<CncSimEvent> *>(user_data);
|
||||
events->push_back(*event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool expect(bool value, const char *message) {
|
||||
if (!value) {
|
||||
std::cerr << "FAIL: " << message << '\n';
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
std::vector<CncSimEvent> events;
|
||||
CanonEventSink sink;
|
||||
sink.set_callback(collect_event, &events);
|
||||
cnc_sim_linuxcnc_set_canon_sink(&sink);
|
||||
|
||||
INIT_CANON();
|
||||
USE_LENGTH_UNITS(CANON_UNITS_MM);
|
||||
SELECT_PLANE(CANON_PLANE::XY);
|
||||
SET_FEED_RATE(500.0);
|
||||
SELECT_TOOL(7);
|
||||
CHANGE_TOOL();
|
||||
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);
|
||||
SET_G5X_OFFSET(1, 10.0, 20.0, 30.0, 1.0, 2.0, 3.0, 0.0, 0.0, 0.0);
|
||||
SET_G92_OFFSET(1.0, 2.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
||||
SET_XY_ROTATION(15.0);
|
||||
PROGRAM_END();
|
||||
|
||||
bool ok = true;
|
||||
ok &= expect(events.size() >= 8, "expected bridge events");
|
||||
ok &= expect(events[0].type == CNC_SIM_EVENT_SET_UNITS, "expected units event");
|
||||
ok &= expect(events[1].type == CNC_SIM_EVENT_SET_PLANE, "expected plane event");
|
||||
|
||||
bool saw_tool = false;
|
||||
bool saw_rapid = false;
|
||||
bool saw_feed = false;
|
||||
bool saw_arc = false;
|
||||
bool saw_g5x = false;
|
||||
bool saw_g92 = false;
|
||||
bool saw_rotation = false;
|
||||
bool saw_end = false;
|
||||
for (const auto &event : events) {
|
||||
saw_tool = saw_tool || (event.type == CNC_SIM_EVENT_TOOL_CHANGE && event.tool == 7);
|
||||
saw_rapid = saw_rapid || (event.type == CNC_SIM_EVENT_RAPID && event.end.z == 5.0);
|
||||
saw_feed = saw_feed || (event.type == CNC_SIM_EVENT_LINEAR_FEED && event.end.x == 10.0);
|
||||
saw_arc = saw_arc || (event.type == CNC_SIM_EVENT_ARC_FEED &&
|
||||
event.end.y == 10.0 &&
|
||||
event.center.x == 10.0 &&
|
||||
event.center.y == 5.0);
|
||||
saw_g5x = saw_g5x || (event.type == CNC_SIM_EVENT_SET_G5X_OFFSET &&
|
||||
event.tool == 1 &&
|
||||
event.start.x == 10.0 &&
|
||||
event.start.y == 20.0 &&
|
||||
event.start.z == 30.0 &&
|
||||
event.start.a == 1.0 &&
|
||||
event.start.b == 2.0 &&
|
||||
event.start.c == 3.0);
|
||||
saw_g92 = saw_g92 || (event.type == CNC_SIM_EVENT_SET_G92_OFFSET &&
|
||||
event.start.x == 1.0 &&
|
||||
event.start.y == 2.0 &&
|
||||
event.start.z == 3.0);
|
||||
saw_rotation = saw_rotation || (event.type == CNC_SIM_EVENT_SET_XY_ROTATION &&
|
||||
event.feed == 15.0);
|
||||
saw_end = saw_end || event.type == CNC_SIM_EVENT_PROGRAM_END;
|
||||
}
|
||||
|
||||
ok &= expect(saw_tool, "expected tool change");
|
||||
ok &= expect(saw_rapid, "expected rapid move");
|
||||
ok &= expect(saw_feed, "expected linear feed");
|
||||
ok &= expect(saw_arc, "expected arc feed");
|
||||
ok &= expect(saw_g5x, "expected G5X offset event");
|
||||
ok &= expect(saw_g92, "expected G92 offset event");
|
||||
ok &= expect(saw_rotation, "expected XY rotation event");
|
||||
ok &= expect(saw_end, "expected program end");
|
||||
|
||||
cnc_sim_linuxcnc_set_canon_sink(nullptr);
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
67
core/tests/rtcp_kinematics_smoke.cpp
Normal file
67
core/tests/rtcp_kinematics_smoke.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "rtcp_kinematics.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
bool near(double actual, double expected) {
|
||||
return std::fabs(actual - expected) < 1e-9;
|
||||
}
|
||||
|
||||
bool expect_near(double actual, double expected, const char *message) {
|
||||
if (!near(actual, expected)) {
|
||||
std::cerr << "FAIL: " << message << " actual=" << actual << " expected=" << expected << '\n';
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool expect_pose_near(const CncSimPose &actual, const CncSimPose &expected, const char *message) {
|
||||
bool ok = true;
|
||||
ok &= expect_near(actual.x, expected.x, message);
|
||||
ok &= expect_near(actual.y, expected.y, message);
|
||||
ok &= expect_near(actual.z, expected.z, message);
|
||||
ok &= expect_near(actual.a, expected.a, message);
|
||||
ok &= expect_near(actual.b, expected.b, message);
|
||||
ok &= expect_near(actual.c, expected.c, message);
|
||||
return ok;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
bool ok = true;
|
||||
|
||||
CncSimPose tip{};
|
||||
tip.x = 10.0;
|
||||
tip.y = 20.0;
|
||||
tip.z = 30.0;
|
||||
|
||||
CncSimPose pivot = rtcp_pivot_from_tool_tip(tip, 100.0);
|
||||
ok &= expect_near(pivot.x, 10.0, "zero-angle pivot x");
|
||||
ok &= expect_near(pivot.y, 20.0, "zero-angle pivot y");
|
||||
ok &= expect_near(pivot.z, 130.0, "zero-angle pivot z");
|
||||
|
||||
tip.a = 90.0;
|
||||
pivot = rtcp_pivot_from_tool_tip(tip, 100.0);
|
||||
ok &= expect_near(pivot.x, 10.0, "A90 pivot x");
|
||||
ok &= expect_near(pivot.y, -80.0, "A90 pivot y");
|
||||
ok &= expect_near(pivot.z, 30.0, "A90 pivot z");
|
||||
|
||||
tip.a = 0.0;
|
||||
tip.b = 90.0;
|
||||
pivot = rtcp_pivot_from_tool_tip(tip, 100.0);
|
||||
ok &= expect_near(pivot.x, 110.0, "B90 pivot x");
|
||||
ok &= expect_near(pivot.y, 20.0, "B90 pivot y");
|
||||
ok &= expect_near(pivot.z, 30.0, "B90 pivot z");
|
||||
|
||||
tip.a = 35.0;
|
||||
tip.b = -20.0;
|
||||
tip.c = 15.0;
|
||||
pivot = rtcp_pivot_from_tool_tip(tip, 123.4);
|
||||
const CncSimPose roundtrip = rtcp_tool_tip_from_pivot(pivot, 123.4);
|
||||
ok &= expect_pose_near(roundtrip, tip, "RTCP pivot/tool-tip roundtrip");
|
||||
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
59
core/tests/simulator_gcode_controls_smoke.cpp
Normal file
59
core/tests/simulator_gcode_controls_smoke.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "simulator_gcode_controls.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
bool expect(bool value, const char *message) {
|
||||
if (!value) {
|
||||
std::cerr << "FAIL: " << message << '\n';
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
bool ok = true;
|
||||
std::vector<SimulatorGcodeControlAction> actions;
|
||||
|
||||
ok &= expect(parse_simulator_gcode_control_line("M428 M429 M430 ; switch modes", &actions),
|
||||
"expected M428/M429/M430 control line");
|
||||
ok &= expect(actions.size() == 3, "expected three kinematics actions");
|
||||
ok &= expect(actions[0].kind == SimulatorGcodeControlKind::KinematicsSwitch &&
|
||||
actions[0].value == 1 &&
|
||||
actions[0].rtcp_enabled,
|
||||
"expected M428 original kinematics action");
|
||||
ok &= expect(actions[1].kind == SimulatorGcodeControlKind::KinematicsSwitch &&
|
||||
actions[1].value == 0 &&
|
||||
!actions[1].rtcp_enabled,
|
||||
"expected M429 identity kinematics action");
|
||||
ok &= expect(actions[2].kind == SimulatorGcodeControlKind::KinematicsSwitch &&
|
||||
actions[2].value == 2 &&
|
||||
actions[2].rtcp_enabled,
|
||||
"expected M430 five-axis BC kinematics action");
|
||||
|
||||
ok &= expect(parse_simulator_gcode_control_line("G49 (cancel RTCP)", &actions),
|
||||
"expected G49 control line");
|
||||
ok &= expect(actions.size() == 1 &&
|
||||
actions[0].kind == SimulatorGcodeControlKind::RtcpState &&
|
||||
!actions[0].rtcp_enabled &&
|
||||
actions[0].h_code == 0,
|
||||
"expected G49 RTCP off action");
|
||||
|
||||
ok &= expect(parse_simulator_gcode_control_line("G43.4 H7", &actions),
|
||||
"expected G43.4 H7 control line");
|
||||
ok &= expect(actions.size() == 1 &&
|
||||
actions[0].kind == SimulatorGcodeControlKind::RtcpState &&
|
||||
actions[0].rtcp_enabled &&
|
||||
actions[0].h_code == 7,
|
||||
"expected G43.4 RTCP on action with H7");
|
||||
|
||||
ok &= expect(!parse_simulator_gcode_control_line("G43.4 H7 X10", &actions),
|
||||
"expected mixed RTCP/motion line to fall through to interpreter");
|
||||
ok &= expect(actions.empty(), "expected no actions for mixed RTCP/motion line");
|
||||
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
Reference in New Issue
Block a user