Solved inter-thread communication issues by feeding commands over a queue.

This commit is contained in:
2023-05-10 16:14:57 +03:00
parent 5748e3d5af
commit 91d438353d
4 changed files with 356 additions and 174 deletions
+133 -31
View File
@@ -560,10 +560,6 @@ void grbl::machine::cancel_jog() const {
pipe->send_single_char_command(0x85);
}
void grbl::machine::set_listener(grbl::machine_listener *l) {
listener = l;
}
void grbl::machine::request_unlock() {
pipe->send("$X");
}
@@ -615,7 +611,8 @@ void grbl::machine::zero_offset(int which) {
pipe->send("$#");
awaiting_responses++;
while (awaiting_responses > 0);
listener->on_parameters_reloaded();
push_event(std::make_shared<machine_event_parameters_reloaded>());
}
void grbl::machine::zero_offset_axis(int offset_index, int axis) {
@@ -627,7 +624,8 @@ void grbl::machine::zero_offset_axis(int offset_index, int axis) {
pipe->send("$#");
awaiting_responses++;
while (awaiting_responses > 0);
listener->on_parameters_reloaded();
push_event(std::make_shared<machine_event_parameters_reloaded>());
}
void grbl::machine::go_to_zero(bool x, bool y, bool z) {
@@ -695,6 +693,23 @@ void grbl::machine::probe_heightmap(grbl::heightmap& grid) {
switch_to_state(grbl_machine_state::heightmap_probing);
}
void grbl::machine::push_event(std::shared_ptr<machine_event> event) {
std::scoped_lock<std::mutex> lock(event_mutex);
events.push_back(event);
}
std::shared_ptr<grbl::machine_event> grbl::machine::pop_event() {
// TODO: make this more efficient
std::scoped_lock<std::mutex> lock(event_mutex);
if (events.empty())
return nullptr;
else {
auto result = events.front();
events.pop_front();
return result;
}
}
bool grbl::jog_state::no_jogging() const {
return !(up_pressed || down_pressed || left_pressed || right_pressed || z_up_pressed || z_down_pressed);
}
@@ -719,7 +734,7 @@ void grbl::machine_state_connect::on_exit(grbl::machine *m) {
void grbl::machine_state_connect::on_line_received(std::string line) {
// std::cerr << "Should not get content while connecting!" << std::endl;
if (starts_with(line, "Grbl")) {
cnc->listener->on_banner(line);
cnc->push_event(std::make_shared<machine_event_banner>(line));
cnc->switch_to_state(grbl_machine_state::init);
}
}
@@ -732,7 +747,7 @@ void grbl::machine_state_init::on_enter(grbl::machine *m) {
}
void grbl::machine_state_init::on_exit(grbl::machine *m) {
cnc->listener->on_init_completed();
cnc->push_event(std::make_shared<machine_event_init_completed>());
}
void grbl::machine_state_init::on_line_received(std::string line) {
@@ -808,15 +823,17 @@ void grbl::machine_state_idle::on_line_received(std::string line) {
cnc->awaiting_responses--;
}
} else if (starts_with(line, "Grbl")) {
cnc->listener->on_banner(line);
cnc->push_event(std::make_shared<machine_event_banner>(line));
cnc->reset_machine_state();
} else if (starts_with(line, "<")) {
cnc->last_report = parse_status_report(line, cnc->last_report);
cnc->listener->on_realtime_status_report(cnc->last_report);
cnc->push_event(std::make_shared<machine_event_report_received>(cnc->last_report));
} else if (starts_with(line, "[MSG:")) {
cnc->listener->on_message(line.substr(5, line.size() - 6));
auto message = line.substr(5, line.size() - 6);
cnc->push_event(std::make_shared<machine_event_message>(message));
} else if (starts_with(line, "ALARM:")) {
cnc->listener->on_alarm(std::stoi(line.substr(6)));
auto alarm = std::stoi(line.substr(6));
cnc->push_event(std::make_shared<machine_event_alarm>(alarm));
} else if (starts_with(line, "$")) {
auto pieces = split_string(line, "=");
cnc->settings[pieces[0]] = pieces[1];
@@ -835,7 +852,7 @@ void grbl::machine_state_idle::on_line_received(std::string line) {
probe_coords[i] = std::stof(coords_as_string[i]);
}
bool probe_touched = pieces[2] == "1";
cnc->listener->on_probe_result(probe_touched, probe_coords);
cnc->push_event(std::make_shared<machine_event_probe_result>(probe_touched, probe_coords));
}
}
}
@@ -884,9 +901,15 @@ void grbl::machine_state_check_program::move_to_next_check_stage() {
break;
case check_stage::disable_check_mode:
if (check_failed) {
cnc->listener->on_check_completed(false, cnc->executed_instructions - 1, check_error);
bool success = false;
size_t failed_idx = cnc->executed_instructions - 1;
size_t error = check_error;
cnc->push_event(std::make_shared<machine_event_check_completed>(success, failed_idx, error));
} else {
cnc->listener->on_check_completed(true, 0, 0);
bool success = true;
size_t failed_idx = 0;
size_t error = 0;
cnc->push_event(std::make_shared<machine_event_check_completed>(success, failed_idx, error));
}
cnc->switch_to_state(grbl_machine_state::idle);
break;
@@ -908,15 +931,17 @@ void grbl::machine_state_check_program::on_line_received(std::string line) {
move_to_next_check_stage();
} else if (starts_with(line, "Grbl")) {
cnc->listener->on_banner(line);
cnc->push_event(std::make_shared<machine_event_banner>(line));
cnc->reset_machine_state();
} else if (starts_with(line, "<")) {
cnc->last_report = parse_status_report(line, cnc->last_report);
cnc->listener->on_realtime_status_report(cnc->last_report);
cnc->push_event(std::make_shared<machine_event_report_received>(cnc->last_report));
} else if (starts_with(line, "[MSG:")) {
cnc->listener->on_message(line.substr(5, line.size() - 6));
auto message = line.substr(5, line.size() - 6);
cnc->push_event(std::make_shared<machine_event_message>(message));
} else if (starts_with(line, "ALARM:")) {
cnc->listener->on_alarm(std::stoi(line.substr(6)));
auto alarm = std::stoi(line.substr(6));
cnc->push_event(std::make_shared<machine_event_alarm>(alarm));
}
}
@@ -970,9 +995,15 @@ void grbl::machine_state_run_program::move_to_next_run_stage() {
case run_stage::run_program:
if (run_failed || !continue_program()) {
if (run_failed) {
cnc->listener->on_run_completed(false, cnc->executed_instructions - 1, run_error);
bool success = false;
size_t failed_index = cnc->executed_instructions - 1;
size_t error = run_error;
cnc->push_event(std::make_shared<machine_event_run_completed>(success, failed_index, error));
} else {
cnc->listener->on_run_completed(true, 0, 0);
bool success = true;
size_t failed_index = 0;
size_t error = 0;
cnc->push_event(std::make_shared<machine_event_run_completed>(success, failed_index, error));
}
cnc->switch_to_state(grbl_machine_state::idle);
}
@@ -1013,20 +1044,21 @@ void grbl::machine_state_run_program::on_line_received(std::string line) {
move_to_next_run_stage();
} else if (starts_with(line, "Grbl")) {
cnc->listener->on_banner(line);
cnc->push_event(std::make_shared<machine_event_banner>(line));
cnc->reset_machine_state();
} else if (starts_with(line, "<")) {
cnc->last_report = parse_status_report(line, cnc->last_report);
cnc->listener->on_realtime_status_report(cnc->last_report);
cnc->push_event(std::make_shared<machine_event_report_received>(cnc->last_report));
} else if (starts_with(line, "[MSG:")) {
cnc->listener->on_message(line.substr(5, line.size() - 6));
auto message = line.substr(5, line.size() - 6);
cnc->push_event(std::make_shared<machine_event_message>(message));
} else if (starts_with(line, "ALARM:")) {
cnc->listener->on_alarm(std::stoi(line.substr(6)));
auto alarm = std::stoi(line.substr(6));
cnc->push_event(std::make_shared<machine_event_alarm>(alarm));
}
}
// heightmap probing
void grbl::machine_state_heightmap_probing::on_connected(grbl::machine *m) {
}
@@ -1062,15 +1094,17 @@ void grbl::machine_state_heightmap_probing::on_line_received(std::string line) {
error = std::stoi(line.substr(6));
move_to_next_stage();
} else if (starts_with(line, "Grbl")) {
cnc->listener->on_banner(line);
cnc->push_event(std::make_shared<machine_event_banner>(line));
cnc->reset_machine_state();
} else if (starts_with(line, "<")) {
cnc->last_report = parse_status_report(line, cnc->last_report);
cnc->listener->on_realtime_status_report(cnc->last_report);
cnc->push_event(std::make_shared<machine_event_report_received>(cnc->last_report));
} else if (starts_with(line, "[MSG:")) {
cnc->listener->on_message(line.substr(5, line.size() - 6));
auto message = line.substr(5, line.size() - 6);
cnc->push_event(std::make_shared<machine_event_message>(message));
} else if (starts_with(line, "ALARM:")) {
cnc->listener->on_alarm(std::stoi(line.substr(6)));
auto alarm = std::stoi(line.substr(6));
cnc->push_event(std::make_shared<machine_event_alarm>(alarm));
} else if (starts_with(line, "[PRB")) {
std::cout << "received PRB" << std::endl;
line = line.substr(1, line.size() - 2);
@@ -1132,7 +1166,8 @@ void grbl::machine_state_heightmap_probing::move_to_next_stage() {
auto delta_z = current_z - z_zero_in_mpos;
std::cout << "Z[" << probed_locations << "] = " << delta_z << std::endl;
grid->vertices[probed_locations].z = delta_z;
cnc->listener->on_heightmap_probe_acquired(grid);
cnc->push_event(std::make_shared<machine_event_heightmap_probe_acquired>(grid, probed_locations));
}
}
@@ -1167,3 +1202,70 @@ void grbl::machine_state_heightmap_probing::move_to_next_stage() {
break;
}
}
grbl::machine_event_connect::machine_event_connect() {
machine_event::type = machine_event_type::connected;
}
grbl::machine_event_disconnect::machine_event_disconnect() {
machine_event::type = machine_event_type::disconnected;
}
grbl::machine_event_report_received::machine_event_report_received(const grbl::realtime_status_report& r)
: report(r) {
machine_event::type = machine_event_type::report_received;
}
grbl::machine_event_banner::machine_event_banner(const std::string& b)
: banner{b} {
machine_event::type = machine_event_type::banner;
}
grbl::machine_event_message::machine_event_message(const std::string& m)
: message{m} {
machine_event::type = machine_event_type::message;
}
grbl::machine_event_alarm::machine_event_alarm(int code)
: alarm(code) {
machine_event::type = machine_event_type::alarm;
}
grbl::machine_event_init_completed::machine_event_init_completed() {
machine_event::type = machine_event_type::init_completed;
}
grbl::machine_event_run_completed::machine_event_run_completed(bool success, size_t failed_index, size_t error)
: success(success),
failed_index(failed_index),
error(error) {
machine_event::type = machine_event_type::run_completed;
}
grbl::machine_event_check_completed::machine_event_check_completed(bool success, size_t failed_idx, size_t error)
: success(success),
failed_index(failed_idx),
error(error) {
machine_event::type = machine_event_type::check_completed;
}
grbl::machine_event_settings_reloaded::machine_event_settings_reloaded() {
machine_event::type = machine_event_type::settings_reloaded;
}
grbl::machine_event_parameters_reloaded::machine_event_parameters_reloaded() {
machine_event::type = machine_event_type::parameters_reloaded;
}
grbl::machine_event_probe_result::machine_event_probe_result(bool touched, const float *coords)
: probe_touched(touched),
probe_coords{coords[0], coords[1], coords[2]} {
machine_event::type = machine_event_type::probe_result;
}
grbl::machine_event_heightmap_probe_acquired::machine_event_heightmap_probe_acquired(grbl::heightmap *g, size_t location)
: grid(g),
probed_location(location) {
machine_event::type = machine_event_type::heightmap_probe_acquired;
}