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)
|
||||
|
||||
|
||||
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)
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
void grbl::tcp_transport::open(grbl::transport_callbacks &cb) {
|
||||
void grbl::tcp_transport::open(grbl::transport_callbacks& cb) {
|
||||
if (is_connected) {
|
||||
close();
|
||||
}
|
||||
@@ -83,6 +83,8 @@ void grbl::tcp_transport::worker() {
|
||||
if (result == -1) {
|
||||
std::cerr << "Failed while writing." << std::endl;
|
||||
close();
|
||||
} else {
|
||||
std::cout << "<< " << line << std::endl;
|
||||
}
|
||||
|
||||
send_queue.pop();
|
||||
@@ -127,8 +129,8 @@ grbl::tcp_transport::~tcp_transport() {
|
||||
live_check_thread.join();
|
||||
}
|
||||
|
||||
bool grbl::tcp_transport::is_empty_line(const std::string &line) {
|
||||
for (auto &c: line) {
|
||||
bool grbl::tcp_transport::is_empty_line(const std::string& line) {
|
||||
for (auto& c: line) {
|
||||
if (c != '\r' && c != '\n' && c != ' ') {
|
||||
return false;
|
||||
}
|
||||
|
||||
+7
-10
@@ -9,32 +9,31 @@ namespace grbl {
|
||||
struct transport;
|
||||
|
||||
struct transport_callbacks {
|
||||
virtual void on_connected(transport*) = 0;
|
||||
virtual void on_disconnected(transport*) = 0;
|
||||
virtual void on_line_received(std::string line, transport* ) = 0;
|
||||
virtual void on_banner(std::string version, transport* ) = 0;
|
||||
virtual void on_connected(transport *) = 0;
|
||||
virtual void on_disconnected(transport *) = 0;
|
||||
virtual void on_line_received(std::string line, transport *) = 0;
|
||||
virtual void on_banner(std::string version, transport *) = 0;
|
||||
};
|
||||
|
||||
struct transport {
|
||||
virtual void open(transport_callbacks& cb) = 0;
|
||||
virtual void close() = 0;
|
||||
virtual void send(std::string line) = 0;
|
||||
virtual void send_single_char_command(uint8_t data) const = 0;
|
||||
};
|
||||
|
||||
struct tcp_transport : public transport {
|
||||
virtual ~tcp_transport();
|
||||
tcp_transport(std::string address, uint16_t port);
|
||||
virtual ~tcp_transport();
|
||||
|
||||
void open(transport_callbacks& cb) override;
|
||||
void close() override;
|
||||
void send(std::string line) override;
|
||||
void send_single_char_command(uint8_t data) const override;
|
||||
|
||||
void request_realtime_report();
|
||||
|
||||
void request_cycle_start();
|
||||
|
||||
void request_feed_hold();
|
||||
|
||||
void parser_state_report();
|
||||
|
||||
private:
|
||||
@@ -50,8 +49,6 @@ private:
|
||||
std::queue<std::string> send_queue;
|
||||
volatile bool should_quit = false;
|
||||
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 <gtest/gtest.h>
|
||||
#include "grbl_communication.h"
|
||||
#include "machine.h"
|
||||
|
||||
using namespace nanogui;
|
||||
|
||||
grbl::machine cnc{};
|
||||
|
||||
|
||||
class SenderApp : public Screen {
|
||||
public:
|
||||
|
||||
Window *window;
|
||||
Window *left_window;
|
||||
Window *right_window;
|
||||
grbl::jog_state jog;
|
||||
|
||||
SenderApp() : Screen(Vector2i(1024, 768), "GRBL Sender") {
|
||||
inc_ref();
|
||||
@@ -82,7 +87,15 @@ public:
|
||||
new Label(left_window, "Push buttons", "sans-bold");
|
||||
|
||||
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");
|
||||
|
||||
/* Alternative construction notation using variadic template */
|
||||
@@ -553,12 +566,13 @@ public:
|
||||
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);
|
||||
Screen::resize_event(size);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
virtual bool keyboard_event(int key, int scancode, int action, int modifiers) {
|
||||
if (Screen::keyboard_event(key, scancode, action, modifiers))
|
||||
return true;
|
||||
@@ -567,13 +581,77 @@ public:
|
||||
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 (action == GLFW_PRESS) {
|
||||
set_caption("Jogging");
|
||||
new_jog.up_pressed = true;
|
||||
} 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;
|
||||
}
|
||||
|
||||
@@ -625,22 +703,22 @@ struct grbl_listener : public grbl::transport_callbacks {
|
||||
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 {
|
||||
std::cout << "Banner: " << version << std::endl;
|
||||
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) {
|
||||
|
||||
grbl_listener listener{};
|
||||
|
||||
grbl::tcp_transport transport("192.168.5.39", 23);
|
||||
transport.open(listener);
|
||||
// grbl_listener listener;
|
||||
//
|
||||
// grbl::tcp_transport transport("192.168.5.39", 23);
|
||||
// transport.open(listener);
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
auto result = RUN_ALL_TESTS();
|
||||
@@ -648,10 +726,17 @@ int main(int argc, char **argv) {
|
||||
exit(result);
|
||||
}
|
||||
|
||||
transport.request_realtime_report();
|
||||
transport.request_cycle_start();
|
||||
transport.request_feed_hold();
|
||||
transport.parser_state_report();
|
||||
cnc.connect();
|
||||
|
||||
// grbl::program pgm{"./program.nc"};
|
||||
//// 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 {
|
||||
|
||||
@@ -671,7 +756,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
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::cerr << error_msg << std::endl;
|
||||
return -1;
|
||||
|
||||
+105
-1409
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user