Enabling opening and running of programs. Added jogging.
This commit is contained in:
+1
-1
@@ -23,5 +23,5 @@ set(CMAKE_CXX_STANDARD 17)
|
|||||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||||
|
|
||||||
|
|
||||||
add_executable(sender main.cpp grbl.h grbl.cpp grbl_test.cpp grbl_communication.h grbl_communication.cpp)
|
add_executable(sender main.cpp grbl.h grbl.cpp grbl_test.cpp grbl_communication.h grbl_communication.cpp machine.h grbl_machine.cpp)
|
||||||
target_link_libraries(sender nanogui gtest gtest_main)
|
target_link_libraries(sender nanogui gtest gtest_main)
|
||||||
@@ -12,7 +12,7 @@ grbl::tcp_transport::tcp_transport(std::string address, uint16_t p)
|
|||||||
live_check_thread = std::thread(&grbl::tcp_transport::worker, this);
|
live_check_thread = std::thread(&grbl::tcp_transport::worker, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grbl::tcp_transport::open(grbl::transport_callbacks &cb) {
|
void grbl::tcp_transport::open(grbl::transport_callbacks& cb) {
|
||||||
if (is_connected) {
|
if (is_connected) {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
@@ -83,6 +83,8 @@ void grbl::tcp_transport::worker() {
|
|||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
std::cerr << "Failed while writing." << std::endl;
|
std::cerr << "Failed while writing." << std::endl;
|
||||||
close();
|
close();
|
||||||
|
} else {
|
||||||
|
std::cout << "<< " << line << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
send_queue.pop();
|
send_queue.pop();
|
||||||
@@ -127,8 +129,8 @@ grbl::tcp_transport::~tcp_transport() {
|
|||||||
live_check_thread.join();
|
live_check_thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool grbl::tcp_transport::is_empty_line(const std::string &line) {
|
bool grbl::tcp_transport::is_empty_line(const std::string& line) {
|
||||||
for (auto &c: line) {
|
for (auto& c: line) {
|
||||||
if (c != '\r' && c != '\n' && c != ' ') {
|
if (c != '\r' && c != '\n' && c != ' ') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-10
@@ -9,32 +9,31 @@ namespace grbl {
|
|||||||
struct transport;
|
struct transport;
|
||||||
|
|
||||||
struct transport_callbacks {
|
struct transport_callbacks {
|
||||||
virtual void on_connected(transport*) = 0;
|
virtual void on_connected(transport *) = 0;
|
||||||
virtual void on_disconnected(transport*) = 0;
|
virtual void on_disconnected(transport *) = 0;
|
||||||
virtual void on_line_received(std::string line, transport* ) = 0;
|
virtual void on_line_received(std::string line, transport *) = 0;
|
||||||
virtual void on_banner(std::string version, transport* ) = 0;
|
virtual void on_banner(std::string version, transport *) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct transport {
|
struct transport {
|
||||||
virtual void open(transport_callbacks& cb) = 0;
|
virtual void open(transport_callbacks& cb) = 0;
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
virtual void send(std::string line) = 0;
|
virtual void send(std::string line) = 0;
|
||||||
|
virtual void send_single_char_command(uint8_t data) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tcp_transport : public transport {
|
struct tcp_transport : public transport {
|
||||||
virtual ~tcp_transport();
|
|
||||||
tcp_transport(std::string address, uint16_t port);
|
tcp_transport(std::string address, uint16_t port);
|
||||||
|
virtual ~tcp_transport();
|
||||||
|
|
||||||
void open(transport_callbacks& cb) override;
|
void open(transport_callbacks& cb) override;
|
||||||
void close() override;
|
void close() override;
|
||||||
void send(std::string line) override;
|
void send(std::string line) override;
|
||||||
|
void send_single_char_command(uint8_t data) const override;
|
||||||
|
|
||||||
void request_realtime_report();
|
void request_realtime_report();
|
||||||
|
|
||||||
void request_cycle_start();
|
void request_cycle_start();
|
||||||
|
|
||||||
void request_feed_hold();
|
void request_feed_hold();
|
||||||
|
|
||||||
void parser_state_report();
|
void parser_state_report();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -50,8 +49,6 @@ private:
|
|||||||
std::queue<std::string> send_queue;
|
std::queue<std::string> send_queue;
|
||||||
volatile bool should_quit = false;
|
volatile bool should_quit = false;
|
||||||
static bool is_empty_line(const std::string& line);
|
static bool is_empty_line(const std::string& line);
|
||||||
|
|
||||||
void send_single_char_command(uint8_t data) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
|
grbl::machine::machine() {
|
||||||
|
pipe = new tcp_transport("192.168.5.39", 23);
|
||||||
|
}
|
||||||
|
|
||||||
|
grbl::machine::~machine() {
|
||||||
|
delete pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
void grbl::machine::connect() {
|
||||||
|
pipe->open(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void grbl::machine::run_program(grbl::program pgm) {
|
||||||
|
std::cout << "running program with " << pgm.number_of_instructions() << " instructions" << std::endl;
|
||||||
|
running_program = pgm;
|
||||||
|
state = grbl_machine_state::run_program;
|
||||||
|
|
||||||
|
executed_instructions = 0;
|
||||||
|
continue_program();
|
||||||
|
}
|
||||||
|
|
||||||
|
void grbl::machine::on_connected(grbl::transport *transport) {
|
||||||
|
std::cout << "grbl machine connected" << std::endl;
|
||||||
|
// telnet handshake so that we get the banner. banner won't be coming otherwise
|
||||||
|
// t->send("\xff\xfd\x18\xff\xfd\x20\xff\xfd\x23\xff\xfd\x27");
|
||||||
|
pipe->send("\xff\xfd\x18");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void grbl::machine::on_disconnected(grbl::transport *transport) {
|
||||||
|
std::cout << "grbl machine disconnected" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void grbl::machine::on_line_received(std::string line, grbl::transport *transport) {
|
||||||
|
std::cout << ">> " << line << std::endl;
|
||||||
|
|
||||||
|
if (state == grbl_machine_state::run_program) {
|
||||||
|
if (line.rfind("ok", 0) == 0) {
|
||||||
|
continue_program();
|
||||||
|
} else if (line.rfind("error", 0) == 0) {
|
||||||
|
std::cerr << "Received error" << std::endl;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// evaluate responses when not running a program
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void grbl::machine::on_banner(std::string version, grbl::transport *transport) {
|
||||||
|
std::cout << "grbl machine received banner" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void grbl::machine::continue_program() {
|
||||||
|
if (executed_instructions < running_program.number_of_instructions()) {
|
||||||
|
instruction to_send;
|
||||||
|
do {
|
||||||
|
to_send = running_program.instruction_at(executed_instructions++);
|
||||||
|
} while (to_send.type != instruction_type::gcode && executed_instructions < running_program.number_of_instructions());
|
||||||
|
|
||||||
|
if (to_send.type == instruction_type::gcode) {
|
||||||
|
pipe->send(to_send.command);
|
||||||
|
} else {
|
||||||
|
state = grbl_machine_state::idle;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state = grbl_machine_state::idle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void grbl::machine::request_jog(jog_state jog) const {
|
||||||
|
cancel_jog();
|
||||||
|
if (jog.no_jogging()) {
|
||||||
|
// cancel_jog();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "$J=G91 G21 ";
|
||||||
|
|
||||||
|
if (jog.left_pressed)
|
||||||
|
ss << " X-1000";
|
||||||
|
else if (jog.right_pressed)
|
||||||
|
ss << " X1000";
|
||||||
|
|
||||||
|
if (jog.up_pressed)
|
||||||
|
ss << " Y1000";
|
||||||
|
else if (jog.down_pressed)
|
||||||
|
ss << " Y-1000";
|
||||||
|
|
||||||
|
if (jog.z_up_pressed)
|
||||||
|
ss << " Z1000";
|
||||||
|
else if (jog.z_down_pressed)
|
||||||
|
ss << " Z-1000";
|
||||||
|
|
||||||
|
if (jog.speed_fast_pressed) {
|
||||||
|
ss << " F10000";
|
||||||
|
} else if (jog.speed_slow_pressed) {
|
||||||
|
ss << " F100";
|
||||||
|
} else {
|
||||||
|
ss << " F1000";
|
||||||
|
}
|
||||||
|
|
||||||
|
pipe->send(ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void grbl::machine::cancel_jog() const {
|
||||||
|
pipe->send_single_char_command(0x85);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool grbl::jog_state::no_jogging() const {
|
||||||
|
return !(up_pressed || down_pressed || left_pressed || right_pressed || z_up_pressed || z_down_pressed);
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "grbl_communication.h"
|
||||||
|
#include "grbl.h"
|
||||||
|
|
||||||
|
namespace grbl {
|
||||||
|
|
||||||
|
|
||||||
|
enum class grbl_machine_state {
|
||||||
|
init,
|
||||||
|
run_program,
|
||||||
|
idle,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class jog_direction {
|
||||||
|
up,
|
||||||
|
down,
|
||||||
|
left,
|
||||||
|
right,
|
||||||
|
up_left,
|
||||||
|
up_right,
|
||||||
|
down_left,
|
||||||
|
down_right
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jog_state {
|
||||||
|
bool left_pressed = false;
|
||||||
|
bool right_pressed = false;
|
||||||
|
bool up_pressed = false;
|
||||||
|
bool down_pressed = false;
|
||||||
|
bool z_up_pressed = false;
|
||||||
|
bool z_down_pressed = false;
|
||||||
|
bool speed_fast_pressed = false;
|
||||||
|
bool speed_slow_pressed = false;
|
||||||
|
|
||||||
|
bool no_jogging() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool operator==(const jog_state& a, const jog_state& b) {
|
||||||
|
if (a.left_pressed != b.left_pressed ||
|
||||||
|
a.right_pressed != b.right_pressed ||
|
||||||
|
a.up_pressed != b.up_pressed ||
|
||||||
|
a.down_pressed != b.down_pressed ||
|
||||||
|
a.z_up_pressed != b.z_up_pressed ||
|
||||||
|
a.z_down_pressed != b.z_down_pressed ||
|
||||||
|
a.speed_fast_pressed != b.speed_fast_pressed ||
|
||||||
|
a.speed_slow_pressed != b.speed_slow_pressed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool operator!=(const jog_state& a, const jog_state& b) {
|
||||||
|
return !(a == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct machine : public transport_callbacks {
|
||||||
|
machine();
|
||||||
|
~machine();
|
||||||
|
|
||||||
|
void connect();
|
||||||
|
void run_program(grbl::program pgm);
|
||||||
|
void request_jog(jog_state jog) const;
|
||||||
|
void cancel_jog() const;
|
||||||
|
|
||||||
|
void on_connected(transport *transport) override;
|
||||||
|
void on_disconnected(transport *transport) override;
|
||||||
|
void on_line_received(std::string line, transport *transport) override;
|
||||||
|
|
||||||
|
|
||||||
|
void on_banner(std::string version, transport *transport) override;
|
||||||
|
transport *pipe = nullptr;
|
||||||
|
grbl_machine_state state = grbl_machine_state::init;
|
||||||
|
program running_program;
|
||||||
|
size_t executed_instructions = 0;
|
||||||
|
void continue_program();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -51,15 +51,20 @@
|
|||||||
#include "grbl.h"
|
#include "grbl.h"
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include "grbl_communication.h"
|
#include "grbl_communication.h"
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
using namespace nanogui;
|
using namespace nanogui;
|
||||||
|
|
||||||
|
grbl::machine cnc{};
|
||||||
|
|
||||||
|
|
||||||
class SenderApp : public Screen {
|
class SenderApp : public Screen {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Window *window;
|
Window *window;
|
||||||
Window *left_window;
|
Window *left_window;
|
||||||
Window *right_window;
|
Window *right_window;
|
||||||
|
grbl::jog_state jog;
|
||||||
|
|
||||||
SenderApp() : Screen(Vector2i(1024, 768), "GRBL Sender") {
|
SenderApp() : Screen(Vector2i(1024, 768), "GRBL Sender") {
|
||||||
inc_ref();
|
inc_ref();
|
||||||
@@ -82,7 +87,15 @@ public:
|
|||||||
new Label(left_window, "Push buttons", "sans-bold");
|
new Label(left_window, "Push buttons", "sans-bold");
|
||||||
|
|
||||||
Button *b = new Button(left_window, "Plain button");
|
Button *b = new Button(left_window, "Plain button");
|
||||||
b->set_callback([] { std::cout << "pushed!" << std::endl; });
|
b->set_callback([&] {
|
||||||
|
auto path = file_dialog(
|
||||||
|
{{"nc", "G-Code files"},
|
||||||
|
{"ngc", "G-Code files"}}, false);
|
||||||
|
grbl::program pgm{path};
|
||||||
|
if (pgm.is_loaded) {
|
||||||
|
cnc.run_program(pgm);
|
||||||
|
}
|
||||||
|
});
|
||||||
b->set_tooltip("short tooltip");
|
b->set_tooltip("short tooltip");
|
||||||
|
|
||||||
/* Alternative construction notation using variadic template */
|
/* Alternative construction notation using variadic template */
|
||||||
@@ -553,12 +566,13 @@ public:
|
|||||||
m_shader->set_uniform("intensity", 0.5f);
|
m_shader->set_uniform("intensity", 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool resize_event(const Vector2i &size) override {
|
bool resize_event(const Vector2i& size) override {
|
||||||
window->set_size(size);
|
window->set_size(size);
|
||||||
Screen::resize_event(size);
|
Screen::resize_event(size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual bool keyboard_event(int key, int scancode, int action, int modifiers) {
|
virtual bool keyboard_event(int key, int scancode, int action, int modifiers) {
|
||||||
if (Screen::keyboard_event(key, scancode, action, modifiers))
|
if (Screen::keyboard_event(key, scancode, action, modifiers))
|
||||||
return true;
|
return true;
|
||||||
@@ -567,13 +581,77 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto new_jog = jog;
|
||||||
|
|
||||||
|
if (key == GLFW_KEY_LEFT_SHIFT) {
|
||||||
|
if (action == GLFW_PRESS) {
|
||||||
|
new_jog.speed_fast_pressed = true;
|
||||||
|
} else if (action == GLFW_RELEASE) {
|
||||||
|
new_jog.speed_fast_pressed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == GLFW_KEY_LEFT_CONTROL) {
|
||||||
|
if (action == GLFW_PRESS) {
|
||||||
|
new_jog.speed_slow_pressed = true;
|
||||||
|
} else if (action == GLFW_RELEASE) {
|
||||||
|
new_jog.speed_slow_pressed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (key == GLFW_KEY_UP) {
|
if (key == GLFW_KEY_UP) {
|
||||||
if (action == GLFW_PRESS) {
|
if (action == GLFW_PRESS) {
|
||||||
set_caption("Jogging");
|
new_jog.up_pressed = true;
|
||||||
} else if (action == GLFW_RELEASE) {
|
} else if (action == GLFW_RELEASE) {
|
||||||
set_caption("Idle");
|
new_jog.up_pressed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key == GLFW_KEY_DOWN) {
|
||||||
|
if (action == GLFW_PRESS) {
|
||||||
|
new_jog.down_pressed = true;
|
||||||
|
} else if (action == GLFW_RELEASE) {
|
||||||
|
new_jog.down_pressed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == GLFW_KEY_LEFT) {
|
||||||
|
if (action == GLFW_PRESS) {
|
||||||
|
new_jog.left_pressed = true;
|
||||||
|
} else if (action == GLFW_RELEASE) {
|
||||||
|
new_jog.left_pressed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == GLFW_KEY_RIGHT) {
|
||||||
|
if (action == GLFW_PRESS) {
|
||||||
|
new_jog.right_pressed = true;
|
||||||
|
} else if (action == GLFW_RELEASE) {
|
||||||
|
new_jog.right_pressed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == GLFW_KEY_PAGE_UP) {
|
||||||
|
if (action == GLFW_PRESS) {
|
||||||
|
new_jog.z_up_pressed = true;
|
||||||
|
} else if (action == GLFW_RELEASE) {
|
||||||
|
new_jog.z_up_pressed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == GLFW_KEY_PAGE_DOWN) {
|
||||||
|
if (action == GLFW_PRESS) {
|
||||||
|
new_jog.z_down_pressed = true;
|
||||||
|
} else if (action == GLFW_RELEASE) {
|
||||||
|
new_jog.z_down_pressed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jog != new_jog) {
|
||||||
|
cnc.request_jog(new_jog);
|
||||||
|
jog = new_jog;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,22 +703,22 @@ struct grbl_listener : public grbl::transport_callbacks {
|
|||||||
std::cout << "Listener: disconnected!" << std::endl;
|
std::cout << "Listener: disconnected!" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_line_received(std::string line, grbl::transport *t) override {
|
|
||||||
std::cout << "Listener: -> " << line << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_banner(std::string version, grbl::transport *t) override {
|
void on_banner(std::string version, grbl::transport *t) override {
|
||||||
std::cout << "Banner: " << version << std::endl;
|
std::cout << "Banner: " << version << std::endl;
|
||||||
t->send("$$");
|
t->send("$$");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void on_line_received(std::string line, grbl::transport *t) override {
|
||||||
|
std::cout << "Listener: -> " << line << std::endl;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
grbl_listener listener{};
|
// grbl_listener listener;
|
||||||
|
//
|
||||||
grbl::tcp_transport transport("192.168.5.39", 23);
|
// grbl::tcp_transport transport("192.168.5.39", 23);
|
||||||
transport.open(listener);
|
// transport.open(listener);
|
||||||
|
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
auto result = RUN_ALL_TESTS();
|
auto result = RUN_ALL_TESTS();
|
||||||
@@ -648,10 +726,17 @@ int main(int argc, char **argv) {
|
|||||||
exit(result);
|
exit(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
transport.request_realtime_report();
|
cnc.connect();
|
||||||
transport.request_cycle_start();
|
|
||||||
transport.request_feed_hold();
|
// grbl::program pgm{"./program.nc"};
|
||||||
transport.parser_state_report();
|
//// pgm.dump(std::cout);
|
||||||
|
//
|
||||||
|
// cnc.run_program(pgm);
|
||||||
|
|
||||||
|
// transport.request_realtime_report();
|
||||||
|
// transport.request_cycle_start();
|
||||||
|
// transport.request_feed_hold();
|
||||||
|
// transport.parser_state_report();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
@@ -671,7 +756,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nanogui::shutdown();
|
nanogui::shutdown();
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception& e) {
|
||||||
std::string error_msg = std::string("Caught a fatal error: ") + std::string(e.what());
|
std::string error_msg = std::string("Caught a fatal error: ") + std::string(e.what());
|
||||||
std::cerr << error_msg << std::endl;
|
std::cerr << error_msg << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
+105
-1409
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user