Solved inter-thread communication issues by feeding commands over a queue.
This commit is contained in:
+4
-1
@@ -33,8 +33,11 @@ DONE - store Z offset and place it in the heightmap
|
|||||||
- if line contains a Z coordinate, update the Z according to the X and Y
|
- if line contains a Z coordinate, update the Z according to the X and Y
|
||||||
- if line does not contain a Z coordinate, add a Z coordinate according to the X and Y
|
- if line does not contain a Z coordinate, add a Z coordinate according to the X and Y
|
||||||
|
|
||||||
Solve bug in which the probing data does not get rendered properly as it gets probed.
|
DONE -Let's get rid of the pesky inter-thread communication issue which is causing a lot of confusion.
|
||||||
|
DONE - Solve bug in which the probing data does not get rendered properly as it gets probed.
|
||||||
|
|
||||||
Bug: query coordinate systems after first z probe.
|
Bug: query coordinate systems after first z probe.
|
||||||
|
Refactor: see if we can unify machine state line handling and remove duplication
|
||||||
|
|
||||||
Edge finding
|
Edge finding
|
||||||
- prerequisites
|
- prerequisites
|
||||||
|
|||||||
+133
-31
@@ -560,10 +560,6 @@ void grbl::machine::cancel_jog() const {
|
|||||||
pipe->send_single_char_command(0x85);
|
pipe->send_single_char_command(0x85);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grbl::machine::set_listener(grbl::machine_listener *l) {
|
|
||||||
listener = l;
|
|
||||||
}
|
|
||||||
|
|
||||||
void grbl::machine::request_unlock() {
|
void grbl::machine::request_unlock() {
|
||||||
pipe->send("$X");
|
pipe->send("$X");
|
||||||
}
|
}
|
||||||
@@ -615,7 +611,8 @@ void grbl::machine::zero_offset(int which) {
|
|||||||
pipe->send("$#");
|
pipe->send("$#");
|
||||||
awaiting_responses++;
|
awaiting_responses++;
|
||||||
while (awaiting_responses > 0);
|
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) {
|
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("$#");
|
pipe->send("$#");
|
||||||
awaiting_responses++;
|
awaiting_responses++;
|
||||||
while (awaiting_responses > 0);
|
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) {
|
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);
|
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 {
|
bool grbl::jog_state::no_jogging() const {
|
||||||
return !(up_pressed || down_pressed || left_pressed || right_pressed || z_up_pressed || z_down_pressed);
|
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) {
|
void grbl::machine_state_connect::on_line_received(std::string line) {
|
||||||
// std::cerr << "Should not get content while connecting!" << std::endl;
|
// std::cerr << "Should not get content while connecting!" << std::endl;
|
||||||
if (starts_with(line, "Grbl")) {
|
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);
|
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) {
|
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) {
|
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--;
|
cnc->awaiting_responses--;
|
||||||
}
|
}
|
||||||
} else if (starts_with(line, "Grbl")) {
|
} 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();
|
cnc->reset_machine_state();
|
||||||
} else if (starts_with(line, "<")) {
|
} else if (starts_with(line, "<")) {
|
||||||
cnc->last_report = parse_status_report(line, cnc->last_report);
|
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:")) {
|
} 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:")) {
|
} 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, "$")) {
|
} else if (starts_with(line, "$")) {
|
||||||
auto pieces = split_string(line, "=");
|
auto pieces = split_string(line, "=");
|
||||||
cnc->settings[pieces[0]] = pieces[1];
|
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]);
|
probe_coords[i] = std::stof(coords_as_string[i]);
|
||||||
}
|
}
|
||||||
bool probe_touched = pieces[2] == "1";
|
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;
|
break;
|
||||||
case check_stage::disable_check_mode:
|
case check_stage::disable_check_mode:
|
||||||
if (check_failed) {
|
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 {
|
} 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);
|
cnc->switch_to_state(grbl_machine_state::idle);
|
||||||
break;
|
break;
|
||||||
@@ -908,15 +931,17 @@ void grbl::machine_state_check_program::on_line_received(std::string line) {
|
|||||||
move_to_next_check_stage();
|
move_to_next_check_stage();
|
||||||
|
|
||||||
} else if (starts_with(line, "Grbl")) {
|
} 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();
|
cnc->reset_machine_state();
|
||||||
} else if (starts_with(line, "<")) {
|
} else if (starts_with(line, "<")) {
|
||||||
cnc->last_report = parse_status_report(line, cnc->last_report);
|
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:")) {
|
} 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:")) {
|
} 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:
|
case run_stage::run_program:
|
||||||
if (run_failed || !continue_program()) {
|
if (run_failed || !continue_program()) {
|
||||||
if (run_failed) {
|
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 {
|
} 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);
|
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();
|
move_to_next_run_stage();
|
||||||
|
|
||||||
} else if (starts_with(line, "Grbl")) {
|
} 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();
|
cnc->reset_machine_state();
|
||||||
} else if (starts_with(line, "<")) {
|
} else if (starts_with(line, "<")) {
|
||||||
cnc->last_report = parse_status_report(line, cnc->last_report);
|
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:")) {
|
} 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:")) {
|
} 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
|
// heightmap probing
|
||||||
|
|
||||||
void grbl::machine_state_heightmap_probing::on_connected(grbl::machine *m) {
|
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));
|
error = std::stoi(line.substr(6));
|
||||||
move_to_next_stage();
|
move_to_next_stage();
|
||||||
} else if (starts_with(line, "Grbl")) {
|
} 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();
|
cnc->reset_machine_state();
|
||||||
} else if (starts_with(line, "<")) {
|
} else if (starts_with(line, "<")) {
|
||||||
cnc->last_report = parse_status_report(line, cnc->last_report);
|
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:")) {
|
} 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:")) {
|
} 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")) {
|
} else if (starts_with(line, "[PRB")) {
|
||||||
std::cout << "received PRB" << std::endl;
|
std::cout << "received PRB" << std::endl;
|
||||||
line = line.substr(1, line.size() - 2);
|
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;
|
auto delta_z = current_z - z_zero_in_mpos;
|
||||||
std::cout << "Z[" << probed_locations << "] = " << delta_z << std::endl;
|
std::cout << "Z[" << probed_locations << "] = " << delta_z << std::endl;
|
||||||
grid->vertices[probed_locations].z = delta_z;
|
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;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
+99
-16
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include "grbl_communication.h"
|
#include "grbl_communication.h"
|
||||||
#include "grbl.h"
|
#include "grbl.h"
|
||||||
#include "heightmap.h"
|
#include "heightmap.h"
|
||||||
@@ -116,20 +118,92 @@ static bool operator!=(const jog_state& a, const jog_state& b) {
|
|||||||
return !(a == b);
|
return !(a == b);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct machine_listener {
|
enum class machine_event_type {
|
||||||
virtual void on_connected() = 0;
|
connected,
|
||||||
virtual void on_disconnected() = 0;
|
disconnected,
|
||||||
virtual void on_realtime_status_report(realtime_status_report) = 0;
|
report_received,
|
||||||
virtual void on_banner(std::string line) = 0;
|
banner,
|
||||||
virtual void on_message(std::string message) = 0;
|
message,
|
||||||
virtual void on_alarm(int alarm) = 0;
|
alarm,
|
||||||
virtual void on_init_completed() = 0;
|
init_completed,
|
||||||
virtual void on_run_completed(bool success, size_t failed_index, size_t error) = 0;
|
run_completed,
|
||||||
virtual void on_check_completed(bool success, size_t failed_index, size_t error) = 0;
|
check_completed,
|
||||||
virtual void on_settings_reloaded() = 0;
|
settings_reloaded,
|
||||||
virtual void on_parameters_reloaded() = 0;
|
parameters_reloaded,
|
||||||
virtual void on_probe_result(bool probe_touched, float probe_coords[3]) = 0;
|
probe_result,
|
||||||
virtual void on_heightmap_probe_acquired(heightmap* grid) = 0;
|
heightmap_probe_acquired,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event {
|
||||||
|
machine_event_type type;
|
||||||
|
// TODO: ewwww
|
||||||
|
virtual void omg() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event_connect : public machine_event {
|
||||||
|
machine_event_connect();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event_disconnect : public machine_event {
|
||||||
|
machine_event_disconnect();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event_report_received : public machine_event {
|
||||||
|
explicit machine_event_report_received(const realtime_status_report& report);
|
||||||
|
realtime_status_report report;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event_banner : public machine_event {
|
||||||
|
explicit machine_event_banner(const std::string& banner);
|
||||||
|
std::string banner;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event_message : public machine_event {
|
||||||
|
explicit machine_event_message(const std::string& message);
|
||||||
|
std::string message;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event_alarm : public machine_event {
|
||||||
|
explicit machine_event_alarm(int code);
|
||||||
|
int alarm;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event_init_completed : public machine_event {
|
||||||
|
machine_event_init_completed();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event_run_completed : public machine_event {
|
||||||
|
machine_event_run_completed(bool success, size_t failed_index, size_t error);
|
||||||
|
bool success;
|
||||||
|
size_t failed_index;
|
||||||
|
size_t error;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event_check_completed : public machine_event {
|
||||||
|
machine_event_check_completed(bool success, size_t failed_idx, size_t error);
|
||||||
|
bool success;
|
||||||
|
size_t failed_index;
|
||||||
|
size_t error;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event_settings_reloaded : public machine_event {
|
||||||
|
machine_event_settings_reloaded();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event_parameters_reloaded : public machine_event {
|
||||||
|
machine_event_parameters_reloaded();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event_probe_result : public machine_event {
|
||||||
|
machine_event_probe_result(bool touched, const float *coords);
|
||||||
|
bool probe_touched;
|
||||||
|
float probe_coords[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct machine_event_heightmap_probe_acquired : public machine_event {
|
||||||
|
machine_event_heightmap_probe_acquired(heightmap *g, size_t location);
|
||||||
|
grbl::heightmap *grid;
|
||||||
|
size_t probed_location;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -278,7 +352,6 @@ struct machine : public transport_callbacks {
|
|||||||
machine();
|
machine();
|
||||||
~machine();
|
~machine();
|
||||||
|
|
||||||
void set_listener(grbl::machine_listener *listener);
|
|
||||||
void connect();
|
void connect();
|
||||||
|
|
||||||
void set_work_offset(std::string work_offset);
|
void set_work_offset(std::string work_offset);
|
||||||
@@ -311,7 +384,18 @@ struct machine : public transport_callbacks {
|
|||||||
void start_z_probe(float min_z, float feed_rate);
|
void start_z_probe(float min_z, float feed_rate);
|
||||||
|
|
||||||
void probe_heightmap(grbl::heightmap& grid);
|
void probe_heightmap(grbl::heightmap& grid);
|
||||||
|
|
||||||
|
void push_event(std::shared_ptr<machine_event> event);
|
||||||
|
|
||||||
|
// pops nullptr if queue is empty
|
||||||
|
std::shared_ptr<machine_event> pop_event();
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
std::mutex event_mutex;
|
||||||
|
std::deque<std::shared_ptr<machine_event>> events;
|
||||||
|
|
||||||
void on_connected(transport *transport) override;
|
void on_connected(transport *transport) override;
|
||||||
void on_disconnected(transport *transport) override;
|
void on_disconnected(transport *transport) override;
|
||||||
void on_line_received(std::string line, transport *transport) override;
|
void on_line_received(std::string line, transport *transport) override;
|
||||||
@@ -337,7 +421,6 @@ protected:
|
|||||||
|
|
||||||
volatile size_t awaiting_responses = 0;
|
volatile size_t awaiting_responses = 0;
|
||||||
realtime_status_report last_report{};
|
realtime_status_report last_report{};
|
||||||
machine_listener *listener = nullptr;
|
|
||||||
transport *pipe = nullptr;
|
transport *pipe = nullptr;
|
||||||
grbl_machine_state state = grbl_machine_state::disconnected;
|
grbl_machine_state state = grbl_machine_state::disconnected;
|
||||||
program running_program;
|
program running_program;
|
||||||
|
|||||||
@@ -49,15 +49,15 @@ using namespace nanogui;
|
|||||||
|
|
||||||
grbl::machine cnc{};
|
grbl::machine cnc{};
|
||||||
|
|
||||||
class SenderApp : public Screen, public grbl::machine_listener {
|
class SenderApp : public Screen {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Window *window;
|
Window *window;
|
||||||
grbl::jog_state jog;
|
grbl::jog_state jog;
|
||||||
TextBox *txt_status;
|
TextBox *txt_status;
|
||||||
TextBox *txtMessage;
|
TextBox *txt_message;
|
||||||
nanogui::Color color_red = nanogui::Color(255, 0, 0, 255);
|
nanogui::Color color_red = nanogui::Color(255, 0, 0, 255);
|
||||||
nanogui::Color colGreen = nanogui::Color(0, 255, 0, 255);
|
nanogui::Color color_green = nanogui::Color(0, 255, 0, 255);
|
||||||
int last_alarm = 0;
|
int last_alarm = 0;
|
||||||
grbl::program pgm;
|
grbl::program pgm;
|
||||||
Button *btn_load_program, *btn_check_program, *btn_run_program;
|
Button *btn_load_program, *btn_check_program, *btn_run_program;
|
||||||
@@ -242,8 +242,8 @@ public:
|
|||||||
//
|
//
|
||||||
status_text_holder->add<Label>("");
|
status_text_holder->add<Label>("");
|
||||||
|
|
||||||
txtMessage = status_text_holder->add<TextBox>("");
|
txt_message = status_text_holder->add<TextBox>("");
|
||||||
txtMessage->set_fixed_width(300);
|
txt_message->set_fixed_width(300);
|
||||||
|
|
||||||
status_text_holder->add<Label>("");
|
status_text_holder->add<Label>("");
|
||||||
|
|
||||||
@@ -806,58 +806,8 @@ public:
|
|||||||
return Screen::resize_event(size);
|
return Screen::resize_event(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_connected() override {
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_disconnected() override {
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_settings_reloaded() override {
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_parameters_reloaded() override {
|
|
||||||
refresh_offset();
|
|
||||||
update_dro();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
grbl::realtime_status_report last_report;
|
grbl::realtime_status_report last_report;
|
||||||
|
|
||||||
volatile bool machine_initialized = false;
|
|
||||||
|
|
||||||
void on_init_completed() override {
|
|
||||||
machine_initialized = true;
|
|
||||||
// need to do UI related things in UI thread
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_realtime_status_report(grbl::realtime_status_report report) override {
|
|
||||||
// if (report == last_report) return;
|
|
||||||
|
|
||||||
// if (last_report.status != report.status) {
|
|
||||||
txt_status->set_value(grbl::status_to_string(cnc.get_status().status));
|
|
||||||
|
|
||||||
if (cnc.get_status().status == grbl::machine_status::alarm) {
|
|
||||||
txt_status->set_tooltip(grbl::alarm_to_string(last_alarm));
|
|
||||||
} else {
|
|
||||||
txt_status->set_tooltip(cnc.get_status().sub_status);
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// FIXME: ugly way of retrieving the bg color
|
|
||||||
btn_pin_door->set_background_color(report.signals.bit.door ? color_red : btn_load_program->background_color());
|
|
||||||
btn_pin_hold->set_background_color(report.signals.bit.hold ? color_red : btn_load_program->background_color());
|
|
||||||
btn_pin_reset->set_background_color(report.signals.bit.soft_reset ? color_red : btn_load_program->background_color());
|
|
||||||
btn_pin_cycle_start->set_background_color(report.signals.bit.cycle_start ? color_red : btn_load_program->background_color());
|
|
||||||
btn_pin_limit_x->set_background_color(report.signals.bit.x_limit ? color_red : btn_load_program->background_color());
|
|
||||||
btn_pin_limit_y->set_background_color(report.signals.bit.y_limit ? color_red : btn_load_program->background_color());
|
|
||||||
btn_pin_limit_z->set_background_color(report.signals.bit.z_limit ? color_red : btn_load_program->background_color());
|
|
||||||
btn_pin_probe->set_background_color(report.signals.bit.probe ? color_red : btn_load_program->background_color());
|
|
||||||
|
|
||||||
update_dro();
|
|
||||||
last_report = report;
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_dro() {
|
void update_dro() {
|
||||||
auto work_pos = cnc.get_work_pos();
|
auto work_pos = cnc.get_work_pos();
|
||||||
|
|
||||||
@@ -874,63 +824,6 @@ public:
|
|||||||
mpos_z_text->set_value(dro_ss.str());
|
mpos_z_text->set_value(dro_ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_banner(std::string line) override {
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_message(std::string message) override {
|
|
||||||
txtMessage->set_value(message);
|
|
||||||
set_caption(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_alarm(int alarm) override {
|
|
||||||
last_alarm = alarm;
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_probe_result(bool probe_touched, float *probe_coords) override {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "Probing ended. Result: " << std::boolalpha << probe_touched << " at coords: ";
|
|
||||||
for (auto i = 0; i < 3; i++) {
|
|
||||||
ss << probe_coords[i] << ", ";
|
|
||||||
}
|
|
||||||
new MessageDialog(this, MessageDialog::Type::Warning, "Probe result", ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
volatile bool should_render_grid = false;
|
|
||||||
void on_heightmap_probe_acquired(grbl::heightmap *grid) override {
|
|
||||||
std::cout << "Updating grid" << std::endl;
|
|
||||||
// let's try to update this from the UI thread since the call is invoked from the
|
|
||||||
// grbl communicator thread.
|
|
||||||
should_render_grid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_check_completed(bool success, size_t failed_index, size_t error) override {
|
|
||||||
btn_check_program->set_background_color(success ? colGreen : color_red);
|
|
||||||
if (success) {
|
|
||||||
btn_run_program->set_enabled(true);
|
|
||||||
new MessageDialog(this, MessageDialog::Type::Information, "Check result", "Program checked successfully");
|
|
||||||
} else {
|
|
||||||
btn_run_program->set_enabled(false);
|
|
||||||
std::stringstream ss;
|
|
||||||
auto i = pgm.instruction_at(failed_index);
|
|
||||||
ss << "Program check failed at line " << i.line << " (" << i.command << "). Error: " << error << ", "
|
|
||||||
<< grbl::error_to_string(error);
|
|
||||||
new MessageDialog(this, MessageDialog::Type::Warning, "Check result", ss.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_run_completed(bool success, size_t failed_index, size_t error) override {
|
|
||||||
btn_run_program->set_background_color(success ? colGreen : color_red);
|
|
||||||
if (success) {
|
|
||||||
new MessageDialog(this, MessageDialog::Type::Information, "Run result", "Program executed successfully");
|
|
||||||
} else {
|
|
||||||
std::stringstream ss;
|
|
||||||
auto i = pgm.instruction_at(failed_index);
|
|
||||||
ss << "Program execution failed at line " << i.line << " (" << i.command << "). Error: " << error << ", "
|
|
||||||
<< grbl::error_to_string(error);
|
|
||||||
new MessageDialog(this, MessageDialog::Type::Warning, "Run result", ss.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool keyboard_event(int key, int scancode, int action, int modifiers) override {
|
bool keyboard_event(int key, int scancode, int action, int modifiers) override {
|
||||||
if (Screen::keyboard_event(key, scancode, action, modifiers))
|
if (Screen::keyboard_event(key, scancode, action, modifiers))
|
||||||
@@ -1056,8 +949,58 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void draw(NVGcontext *ctx) override {
|
void draw(NVGcontext *ctx) override {
|
||||||
// not pretty but need to do this in UI thread
|
std::shared_ptr<grbl::machine_event> event;
|
||||||
if (machine_initialized) {
|
while ((event = cnc.pop_event()) != nullptr) {
|
||||||
|
switch (event->type) {
|
||||||
|
case grbl::machine_event_type::connected:
|
||||||
|
break;
|
||||||
|
case grbl::machine_event_type::disconnected:
|
||||||
|
break;
|
||||||
|
case grbl::machine_event_type::report_received: {
|
||||||
|
|
||||||
|
auto ev = dynamic_cast<grbl::machine_event_report_received *>(event.get());
|
||||||
|
|
||||||
|
txt_status->set_value(grbl::status_to_string(cnc.get_status().status));
|
||||||
|
|
||||||
|
if (cnc.get_status().status == grbl::machine_status::alarm) {
|
||||||
|
txt_status->set_tooltip(grbl::alarm_to_string(last_alarm));
|
||||||
|
} else {
|
||||||
|
txt_status->set_tooltip(cnc.get_status().sub_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: ugly way of retrieving the bg color
|
||||||
|
btn_pin_door->set_background_color(ev->report.signals.bit.door ? color_red : btn_load_program->background_color());
|
||||||
|
btn_pin_hold->set_background_color(ev->report.signals.bit.hold ? color_red : btn_load_program->background_color());
|
||||||
|
btn_pin_reset->set_background_color(
|
||||||
|
ev->report.signals.bit.soft_reset ? color_red : btn_load_program->background_color());
|
||||||
|
btn_pin_cycle_start->set_background_color(
|
||||||
|
ev->report.signals.bit.cycle_start ? color_red : btn_load_program->background_color());
|
||||||
|
btn_pin_limit_x->set_background_color(
|
||||||
|
ev->report.signals.bit.x_limit ? color_red : btn_load_program->background_color());
|
||||||
|
btn_pin_limit_y->set_background_color(
|
||||||
|
ev->report.signals.bit.y_limit ? color_red : btn_load_program->background_color());
|
||||||
|
btn_pin_limit_z->set_background_color(
|
||||||
|
ev->report.signals.bit.z_limit ? color_red : btn_load_program->background_color());
|
||||||
|
btn_pin_probe->set_background_color(ev->report.signals.bit.probe ? color_red : btn_load_program->background_color());
|
||||||
|
|
||||||
|
update_dro();
|
||||||
|
last_report = ev->report;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case grbl::machine_event_type::banner:
|
||||||
|
break;
|
||||||
|
case grbl::machine_event_type::message: {
|
||||||
|
auto ev = dynamic_cast<grbl::machine_event_message *>(event.get());
|
||||||
|
txt_message->set_value(ev->message);
|
||||||
|
set_caption(ev->message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case grbl::machine_event_type::alarm: {
|
||||||
|
auto ev = dynamic_cast<grbl::machine_event_alarm *>(event.get());
|
||||||
|
last_alarm = ev->alarm;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case grbl::machine_event_type::init_completed:
|
||||||
fill_in_settings();
|
fill_in_settings();
|
||||||
fill_in_parameters();
|
fill_in_parameters();
|
||||||
|
|
||||||
@@ -1065,14 +1008,66 @@ public:
|
|||||||
|
|
||||||
refresh_offset();
|
refresh_offset();
|
||||||
update_dro();
|
update_dro();
|
||||||
machine_initialized = false;
|
break;
|
||||||
|
case grbl::machine_event_type::run_completed: {
|
||||||
|
auto ev = dynamic_cast<grbl::machine_event_run_completed *>(event.get());
|
||||||
|
btn_run_program->set_background_color(ev->success ? color_green : color_red);
|
||||||
|
if (ev->success) {
|
||||||
|
new MessageDialog(this, MessageDialog::Type::Information, "Run result", "Program executed successfully");
|
||||||
|
} else {
|
||||||
|
std::stringstream ss;
|
||||||
|
auto i = pgm.instruction_at(ev->failed_index);
|
||||||
|
ss << "Program execution failed at line " << i.line << " (" << i.command << "). Error: "
|
||||||
|
<< ev->error << ", "
|
||||||
|
<< grbl::error_to_string(ev->error);
|
||||||
|
new MessageDialog(this, MessageDialog::Type::Warning, "Run result", ss.str());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case grbl::machine_event_type::check_completed: {
|
||||||
|
auto ev = dynamic_cast<grbl::machine_event_check_completed *>(event.get());
|
||||||
|
|
||||||
|
btn_check_program->set_background_color(ev->success ? color_green : color_red);
|
||||||
|
if (ev->success) {
|
||||||
|
btn_run_program->set_enabled(true);
|
||||||
|
new MessageDialog(this, MessageDialog::Type::Information, "Check result", "Program checked successfully");
|
||||||
|
} else {
|
||||||
|
btn_run_program->set_enabled(false);
|
||||||
|
std::stringstream ss;
|
||||||
|
auto i = pgm.instruction_at(ev->failed_index);
|
||||||
|
ss << "Program check failed at line " << i.line << " (" << i.command << "). Error: "
|
||||||
|
<< ev->error << ", "
|
||||||
|
<< grbl::error_to_string(ev->error);
|
||||||
|
new MessageDialog(this, MessageDialog::Type::Warning, "Check result", ss.str());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case grbl::machine_event_type::settings_reloaded:
|
||||||
|
break;
|
||||||
|
case grbl::machine_event_type::parameters_reloaded:
|
||||||
|
refresh_offset();
|
||||||
|
update_dro();
|
||||||
|
break;
|
||||||
|
case grbl::machine_event_type::probe_result: {
|
||||||
|
auto ev = dynamic_cast<grbl::machine_event_probe_result *>(event.get());
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Probing ended. Result: " << std::boolalpha << ev->probe_touched << " at coords: ";
|
||||||
|
for (float probe_coord: ev->probe_coords) {
|
||||||
|
ss << probe_coord << ", ";
|
||||||
|
}
|
||||||
|
new MessageDialog(this, MessageDialog::Type::Warning, "Probe result", ss.str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case grbl::machine_event_type::heightmap_probe_acquired: {
|
||||||
|
std::cout << "Updating grid" << std::endl;
|
||||||
|
auto ev = dynamic_cast<grbl::machine_event_heightmap_probe_acquired *>(event.get());
|
||||||
|
renderer.update_grid(*ev->grid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: change this to something prettier. make a pipe/queue for in-between threads comm
|
|
||||||
if (should_render_grid) {
|
|
||||||
renderer.update_grid(heightmap_grid);
|
|
||||||
should_render_grid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget::draw(ctx);
|
Widget::draw(ctx);
|
||||||
}
|
}
|
||||||
@@ -1131,7 +1126,6 @@ int main(int argc, char **argv) {
|
|||||||
app->draw_all();
|
app->draw_all();
|
||||||
app->set_visible(true);
|
app->set_visible(true);
|
||||||
|
|
||||||
cnc.set_listener(app);
|
|
||||||
cnc.connect();
|
cnc.connect();
|
||||||
|
|
||||||
nanogui::mainloop(1 / 60.f * 1000);
|
nanogui::mainloop(1 / 60.f * 1000);
|
||||||
|
|||||||
Reference in New Issue
Block a user