Enabled arcs render after adapting OpenCNCPilot code.
Started porting iosender to C++
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
#include "comms.h"
|
||||
|
||||
static iosender::StreamComms *currentCommunicator = nullptr;
|
||||
|
||||
void iosender::Comms::SetCom(iosender::StreamComms *com) {
|
||||
currentCommunicator = com;
|
||||
}
|
||||
|
||||
iosender::StreamComms *iosender::Comms::GetCom() {
|
||||
return currentCommunicator;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace iosender {
|
||||
|
||||
class StreamComms;
|
||||
|
||||
class Comms {
|
||||
public:
|
||||
|
||||
enum class State {
|
||||
AwaitAck,
|
||||
DataReceived,
|
||||
ACK,
|
||||
NAK
|
||||
};
|
||||
|
||||
enum class ResetMode {
|
||||
None,
|
||||
DTR,
|
||||
RTS
|
||||
};
|
||||
|
||||
enum class StreamType {
|
||||
Serial,
|
||||
Telnet,
|
||||
Websocket
|
||||
};
|
||||
|
||||
const int TXBUFFERSIZE = 4096;
|
||||
const int RXBUFFERSIZE = 1024;
|
||||
|
||||
static void SetCom(StreamComms *com);
|
||||
static StreamComms *GetCom();
|
||||
};
|
||||
|
||||
struct DataReceivedHandler {
|
||||
virtual void DataReceived(std::string data) = 0;
|
||||
};
|
||||
|
||||
struct ByteReceivedHandler {
|
||||
virtual void ByteReceived(int b) = 0;
|
||||
};
|
||||
|
||||
class StreamComms {
|
||||
public:
|
||||
|
||||
virtual ~StreamComms() = default;
|
||||
|
||||
virtual bool IsOpen() = 0;
|
||||
virtual int OutCount() = 0;
|
||||
virtual std::string Reply() = 0;
|
||||
virtual Comms::StreamType StreamType() = 0;
|
||||
virtual bool EventMode() = 0;
|
||||
virtual void EventMode(bool mode) = 0;
|
||||
|
||||
virtual void Close() = 0;
|
||||
virtual int ReadByte() = 0;
|
||||
virtual void WriteByte(uint8_t data) = 0;
|
||||
virtual void WriteBytes(uint8_t *bytes, int len) = 0;
|
||||
virtual void WriteString(std::string data) = 0;
|
||||
virtual void WriteCommand(std::string command) = 0;
|
||||
virtual std::string GetReply(std::string command) = 0;
|
||||
virtual void AwaitAck() = 0;
|
||||
virtual void AwaitAck(std::string command) = 0;
|
||||
virtual void AwaitResponse(std::string command) = 0;
|
||||
virtual void AwaitResponse() = 0;
|
||||
virtual void PurgeQueue() = 0;
|
||||
|
||||
Comms::State CommandState = Comms::State::NAK;
|
||||
DataReceivedHandler *dataReceivedHandler = nullptr;
|
||||
ByteReceivedHandler *byteReceivedHandler = nullptr;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#include "gcode.h"
|
||||
#include "../string_utils.h"
|
||||
|
||||
std::vector<int> iosender::ToIndices(iosender::AxisFlags flags) {
|
||||
std::vector<int> result;
|
||||
|
||||
int i = 0, j = (int) flags;
|
||||
while (j != 0) {
|
||||
if ((j & 0x01) != 0)
|
||||
result.push_back(i);
|
||||
i++;
|
||||
j >>= 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<int> iosender::ToIndices(iosender::IJKFlags flags) {
|
||||
std::vector<int> result;
|
||||
|
||||
int i = 0, j = (int) flags;
|
||||
while (j != 0) {
|
||||
if ((j & 0x01) != 0)
|
||||
result.push_back(i);
|
||||
i++;
|
||||
j >>= 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<int> iosender::ToIndices(iosender::ThreadingFlags flags) {
|
||||
std::vector<int> result;
|
||||
|
||||
int i = 0, j = (int) flags;
|
||||
while (j != 0) {
|
||||
if ((j & 0x01) != 0)
|
||||
result.push_back(i);
|
||||
i++;
|
||||
j >>= 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
std::string iosender::GCodeUtils::StripSpaces(std::string line) {
|
||||
std::string s;
|
||||
bool skip = true;
|
||||
|
||||
s = to_upper(line);
|
||||
if (string_contains(s, "(MSG,")) {
|
||||
s = "";
|
||||
for (auto c: line) {
|
||||
switch (c) {
|
||||
case '(':
|
||||
s += c;
|
||||
skip = false;
|
||||
break;
|
||||
case ')':
|
||||
skip = true;
|
||||
s += c;
|
||||
break;
|
||||
case ' ':
|
||||
if (!skip)
|
||||
s += c;
|
||||
break;
|
||||
default:
|
||||
s += c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s = remove_spaces(line);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
+369
@@ -0,0 +1,369 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace iosender {
|
||||
|
||||
enum class Dialect {
|
||||
Grbl,
|
||||
GrblHAL,
|
||||
LinuxCNC
|
||||
};
|
||||
|
||||
enum class AxisFlags : int {
|
||||
None = 0,
|
||||
X = 1 << 0,
|
||||
Y = 1 << 1,
|
||||
Z = 1 << 2,
|
||||
A = 1 << 3,
|
||||
B = 1 << 4,
|
||||
C = 1 << 5,
|
||||
U = 1 << 6,
|
||||
V = 1 << 7,
|
||||
W = 1 << 8,
|
||||
XY = 0x03,
|
||||
XZ = 0x05,
|
||||
XYZ = 0x07,
|
||||
All = 0x3F
|
||||
};
|
||||
|
||||
enum class IJKFlags : int {
|
||||
None = 0,
|
||||
I = 1 << 0,
|
||||
J = 1 << 1,
|
||||
K = 1 << 2,
|
||||
All = 0x07
|
||||
};
|
||||
|
||||
enum class ThreadingFlags : int {
|
||||
None = 0,
|
||||
R = 1 << 0,
|
||||
Q = 1 << 1,
|
||||
H = 1 << 2,
|
||||
E = 1 << 3,
|
||||
L = 1 << 4,
|
||||
All = 0x1F
|
||||
};
|
||||
|
||||
enum class Plane {
|
||||
XY,
|
||||
XZ,
|
||||
YZ
|
||||
};
|
||||
|
||||
enum class DistanceMode {
|
||||
Absolute,
|
||||
Incremental
|
||||
};
|
||||
|
||||
enum class FeedRateMode {
|
||||
InverseTime, //G93
|
||||
UnitsPerMin, //G94 - default
|
||||
UnitsPerRev //G95
|
||||
};
|
||||
|
||||
enum class MotionMode {
|
||||
G0 = 0,
|
||||
G1 = 10,
|
||||
G2 = 20,
|
||||
G3 = 30,
|
||||
G5 = 50,
|
||||
G5_1 = 51,
|
||||
G5_2 = 52,
|
||||
G33 = 330,
|
||||
G38_2 = 382,
|
||||
G38_3 = 383,
|
||||
G38_4 = 384,
|
||||
G38_5 = 385,
|
||||
G73 = 730,
|
||||
G76 = 760,
|
||||
G80 = 800,
|
||||
None = G80,
|
||||
G81 = 810,
|
||||
G82 = 820,
|
||||
G83 = 830,
|
||||
G84 = 840,
|
||||
G85 = 850,
|
||||
G86 = 860,
|
||||
G87 = 870,
|
||||
G88 = 880,
|
||||
G89 = 890
|
||||
};
|
||||
|
||||
enum class IJKMode {
|
||||
Absolute,
|
||||
Incremental
|
||||
};
|
||||
|
||||
enum class Units {
|
||||
Imperial = 0,
|
||||
Metric = 1
|
||||
};
|
||||
|
||||
enum class SpindleState : int {
|
||||
Off = 1 << 0,
|
||||
CW = 1 << 1,
|
||||
CCW = 1 << 2
|
||||
};
|
||||
|
||||
enum class CoolantState : int {
|
||||
Off = 0,
|
||||
Flood = 1 << 0,
|
||||
Mist = 1 << 1,
|
||||
Shower = 1 << 2
|
||||
};
|
||||
|
||||
enum class ToolLengthOffset {
|
||||
Cancel = 0, // G49 (Default: Must be zero)
|
||||
Enable = 1, // G43
|
||||
EnableDynamic = 2, // G43.1
|
||||
ApplyAdditional = 3 // G43.2
|
||||
};
|
||||
|
||||
enum class ThreadTaper : int {
|
||||
None = 0,
|
||||
Entry = 1 << 0,
|
||||
Exit = 1 << 1,
|
||||
Both = Entry | Exit
|
||||
};
|
||||
|
||||
enum class LatheMode : int {
|
||||
Disabled = 0,
|
||||
Diameter = 1, // Do not change
|
||||
Radius = 2 // Do not change
|
||||
};
|
||||
|
||||
enum class Direction {
|
||||
Positive = 0,
|
||||
Negative
|
||||
};
|
||||
|
||||
enum class InputWaitMode {
|
||||
Immediate = 0,
|
||||
Rise,
|
||||
Fall,
|
||||
High,
|
||||
Low
|
||||
};
|
||||
|
||||
enum class Commands {
|
||||
G0,
|
||||
G1,
|
||||
G2,
|
||||
G3,
|
||||
G4,
|
||||
G5,
|
||||
G5_1,
|
||||
G7,
|
||||
G8,
|
||||
G10,
|
||||
G17,
|
||||
G18,
|
||||
G19,
|
||||
G20,
|
||||
G21,
|
||||
G28,
|
||||
G28_1,
|
||||
G30,
|
||||
G30_1,
|
||||
G33,
|
||||
G38_2,
|
||||
G38_3,
|
||||
G38_4,
|
||||
G38_5,
|
||||
G40,
|
||||
G43,
|
||||
G43_1,
|
||||
G43_2,
|
||||
G49,
|
||||
G50,
|
||||
G51,
|
||||
G53,
|
||||
G54,
|
||||
G55,
|
||||
G56,
|
||||
G57,
|
||||
G58,
|
||||
G59,
|
||||
G59_1,
|
||||
G59_2,
|
||||
G59_3,
|
||||
G61,
|
||||
G61_1,
|
||||
G64,
|
||||
G73,
|
||||
G76,
|
||||
G80,
|
||||
G81,
|
||||
G82,
|
||||
G83,
|
||||
G85,
|
||||
G86,
|
||||
G89,
|
||||
G90,
|
||||
G90_1,
|
||||
G91,
|
||||
G91_1,
|
||||
G92,
|
||||
G92_1,
|
||||
G92_2,
|
||||
G92_3,
|
||||
G93,
|
||||
G94,
|
||||
G95,
|
||||
G96,
|
||||
G97,
|
||||
G98,
|
||||
G99,
|
||||
M0,
|
||||
M1,
|
||||
M2,
|
||||
M3,
|
||||
M4,
|
||||
M5,
|
||||
M6,
|
||||
M7,
|
||||
M8,
|
||||
M9,
|
||||
M30,
|
||||
M48,
|
||||
M49,
|
||||
M50,
|
||||
M51,
|
||||
M52,
|
||||
M53,
|
||||
M56,
|
||||
M61,
|
||||
M62,
|
||||
M63,
|
||||
M64,
|
||||
M65,
|
||||
M66,
|
||||
M67,
|
||||
M68,
|
||||
Feedrate,
|
||||
SpindleRPM,
|
||||
ToolSelect,
|
||||
Comment,
|
||||
UserMCommand,
|
||||
Undefined
|
||||
};
|
||||
|
||||
std::vector<int> ToIndices(AxisFlags flags);
|
||||
std::vector<int> ToIndices(IJKFlags flags);
|
||||
std::vector<int> ToIndices(ThreadingFlags flags);
|
||||
|
||||
|
||||
class GCodeUtils {
|
||||
public:
|
||||
static std::string StripSpaces(std::string line);
|
||||
};
|
||||
|
||||
struct Point3D {
|
||||
union {
|
||||
struct {
|
||||
double X, Y, Z;
|
||||
};
|
||||
double value[3];
|
||||
};
|
||||
|
||||
double& operator[](int index) {
|
||||
return value[index];
|
||||
}
|
||||
|
||||
double *Array() { return value; }
|
||||
};
|
||||
|
||||
|
||||
struct Point6D {
|
||||
union {
|
||||
struct {
|
||||
double X, Y, Z, A, B, C, U, V, W;
|
||||
};
|
||||
double value[9];
|
||||
};
|
||||
|
||||
double& operator[](int index) {
|
||||
return value[index];
|
||||
}
|
||||
|
||||
double *Array() { return value; }
|
||||
|
||||
explicit operator Point3D() { return Point3D{X, Y, Z}; }
|
||||
|
||||
void Set(double *values, AxisFlags axisFlags, bool relative = false) {
|
||||
if (relative) {
|
||||
Add(values, axisFlags);
|
||||
} else {
|
||||
for (auto i: ToIndices(axisFlags)) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
X = values[0];
|
||||
break;
|
||||
case 1:
|
||||
Y = values[1];
|
||||
break;
|
||||
case 2:
|
||||
Z = values[2];
|
||||
break;
|
||||
case 3:
|
||||
A = values[3];
|
||||
break;
|
||||
case 4:
|
||||
B = values[4];
|
||||
break;
|
||||
case 5:
|
||||
C = values[5];
|
||||
break;
|
||||
case 6:
|
||||
U = values[6];
|
||||
break;
|
||||
case 7:
|
||||
V = values[7];
|
||||
break;
|
||||
case 8:
|
||||
W = values[8];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Add(const double values[], AxisFlags axisFlags) {
|
||||
for (auto i: ToIndices(axisFlags)) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
X += values[0];
|
||||
break;
|
||||
case 1:
|
||||
Y += values[1];
|
||||
break;
|
||||
case 2:
|
||||
Z += values[2];
|
||||
break;
|
||||
case 3:
|
||||
A += values[3];
|
||||
break;
|
||||
case 4:
|
||||
B += values[4];
|
||||
break;
|
||||
case 5:
|
||||
C += values[5];
|
||||
break;
|
||||
case 6:
|
||||
U += values[6];
|
||||
break;
|
||||
case 7:
|
||||
V += values[7];
|
||||
break;
|
||||
case 8:
|
||||
W += values[8];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#include "gcode_parser.h"
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
namespace iosender {
|
||||
|
||||
//class GCodeParser : public Machine {
|
||||
//public:
|
||||
//
|
||||
//};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "grbl.h"
|
||||
#include <thread>
|
||||
#include "comms.h"
|
||||
|
||||
void iosender::Grbl::Reset() {
|
||||
Comms::GetCom()->WriteByte(GrblConstants::CMD_RESET);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
}
|
||||
|
||||
const std::string iosender::GrblConstants::CMD_STATUS_REPORT_LEGACY = "?";
|
||||
const std::string iosender::GrblConstants::CMD_CYCLE_START_LEGACY = "~";
|
||||
const std::string iosender::GrblConstants::CMD_FEED_HOLD_LEGACY = "!";
|
||||
const std::string iosender::GrblConstants::CMD_UNLOCK = "$X";
|
||||
const std::string iosender::GrblConstants::CMD_HOMING = "$H";
|
||||
const std::string iosender::GrblConstants::CMD_CHECK = "$C";
|
||||
const std::string iosender::GrblConstants::CMD_GETSETTINGS = "$$";
|
||||
const std::string iosender::GrblConstants::CMD_GETSETTINGS_ALL = "$+";
|
||||
const std::string iosender::GrblConstants::CMD_GETPARSERSTATE = "$G";
|
||||
const std::string iosender::GrblConstants::CMD_GETINFO = "$I";
|
||||
const std::string iosender::GrblConstants::CMD_GETINFO_EXTENDED = "$I+";
|
||||
const std::string iosender::GrblConstants::CMD_GETNGCPARAMETERS = "$#";
|
||||
const std::string iosender::GrblConstants::CMD_GETSTARTUPLINES = "$N";
|
||||
const std::string iosender::GrblConstants::CMD_GETSETTINGSDETAILS = "$ES";
|
||||
const std::string iosender::GrblConstants::CMD_GETSETTINGSGROUPS = "$EG";
|
||||
const std::string iosender::GrblConstants::CMD_GETALARMCODES = "$EA";
|
||||
const std::string iosender::GrblConstants::CMD_GETERRORCODES = "$EE";
|
||||
const std::string iosender::GrblConstants::CMD_PROGRAM_DEMARCATION = "%";
|
||||
const std::string iosender::GrblConstants::CMD_SDCARD_MOUNT = "$FM";
|
||||
const std::string iosender::GrblConstants::CMD_SDCARD_DIR = "$F";
|
||||
const std::string iosender::GrblConstants::CMD_SDCARD_DIR_ALL = "$F+";
|
||||
const std::string iosender::GrblConstants::CMD_SDCARD_REWIND = "$FR";
|
||||
const std::string iosender::GrblConstants::CMD_SDCARD_RUN = "$F=";
|
||||
const std::string iosender::GrblConstants::CMD_SDCARD_UNLINK = "$FD=";
|
||||
const std::string iosender::GrblConstants::CMD_SDCARD_DUMP = "$F<=";
|
||||
const std::string iosender::GrblConstants::FORMAT_METRIC = "###0.000";
|
||||
const std::string iosender::GrblConstants::FORMAT_IMPERIAL = "##0.0000";
|
||||
const std::string iosender::GrblConstants::NO_TOOL = "None";
|
||||
const std::string iosender::GrblConstants::THCSIGNALS = "AERTOVHDU"; // Keep in sync with THCSignals enum below!!
|
||||
+304
@@ -0,0 +1,304 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include "grbl.h"
|
||||
|
||||
namespace iosender {
|
||||
|
||||
|
||||
struct Color {
|
||||
union {
|
||||
float r, g, b, a;
|
||||
};
|
||||
float values[4];
|
||||
};
|
||||
|
||||
class GrblConstants {
|
||||
public:
|
||||
|
||||
static const uint8_t CMD_EXIT = 0x03; // ctrl-C
|
||||
static const uint8_t CMD_RESET = 0x18; // ctrl-X
|
||||
static const uint8_t CMD_STOP = 0x19; // ctrl-Y
|
||||
static const uint8_t CMD_STATUS_REPORT = 0x80;
|
||||
static const uint8_t CMD_CYCLE_START = 0x81;
|
||||
static const uint8_t CMD_FEED_HOLD = 0x82;
|
||||
static const uint8_t CMD_GCODE_REPORT = 0x83;
|
||||
static const uint8_t CMD_SAFETY_DOOR = 0x84;
|
||||
static const uint8_t CMD_JOG_CANCEL = 0x85;
|
||||
static const uint8_t CMD_STATUS_REPORT_ALL = 0x87;
|
||||
static const uint8_t CMD_OPTIONAL_STOP_TOGGLE = 0x88;
|
||||
static const uint8_t CMD_SINGLE_BLOCK_TOGGLE = 0x89;
|
||||
static const uint8_t CMD_OVERRIDE_FAN0_TOGGLE = 0x8A;
|
||||
static const uint8_t CMD_FEED_OVR_RESET = 0x90;
|
||||
static const uint8_t CMD_FEED_OVR_COARSE_PLUS = 0x91;
|
||||
static const uint8_t CMD_FEED_OVR_COARSE_MINUS = 0x92;
|
||||
static const uint8_t CMD_FEED_OVR_FINE_PLUS = 0x93;
|
||||
static const uint8_t CMD_FEED_OVR_FINE_MINUS = 0x94;
|
||||
static const uint8_t CMD_RAPID_OVR_RESET = 0x95;
|
||||
static const uint8_t CMD_RAPID_OVR_MEDIUM = 0x96;
|
||||
static const uint8_t CMD_RAPID_OVR_LOW = 0x97;
|
||||
static const uint8_t CMD_SPINDLE_OVR_RESET = 0x99;
|
||||
static const uint8_t CMD_SPINDLE_OVR_COARSE_PLUS = 0x9A;
|
||||
static const uint8_t CMD_SPINDLE_OVR_COARSE_MINUS = 0x9B;
|
||||
static const uint8_t CMD_SPINDLE_OVR_FINE_PLUS = 0x9C;
|
||||
static const uint8_t CMD_SPINDLE_OVR_FINE_MINUS = 0x9D;
|
||||
static const uint8_t CMD_SPINDLE_OVR_STOP = 0x9E;
|
||||
static const uint8_t CMD_COOLANT_FLOOD_OVR_TOGGLE = 0xA0;
|
||||
static const uint8_t CMD_COOLANT_MIST_OVR_TOGGLE = 0xA1;
|
||||
static const uint8_t CMD_PID_REPORT = 0xA2;
|
||||
static const uint8_t CMD_TOOL_ACK = 0xA3;
|
||||
static const uint8_t CMD_PROBE_CONNECTED_TOGGLE = 0xA4;
|
||||
|
||||
static const std::string CMD_STATUS_REPORT_LEGACY;
|
||||
static const std::string CMD_CYCLE_START_LEGACY;
|
||||
static const std::string CMD_FEED_HOLD_LEGACY;
|
||||
static const std::string CMD_UNLOCK;
|
||||
static const std::string CMD_HOMING;
|
||||
static const std::string CMD_CHECK;
|
||||
static const std::string CMD_GETSETTINGS;
|
||||
static const std::string CMD_GETSETTINGS_ALL;
|
||||
static const std::string CMD_GETPARSERSTATE;
|
||||
static const std::string CMD_GETINFO;
|
||||
static const std::string CMD_GETINFO_EXTENDED;
|
||||
static const std::string CMD_GETNGCPARAMETERS;
|
||||
static const std::string CMD_GETSTARTUPLINES;
|
||||
static const std::string CMD_GETSETTINGSDETAILS;
|
||||
static const std::string CMD_GETSETTINGSGROUPS;
|
||||
static const std::string CMD_GETALARMCODES;
|
||||
static const std::string CMD_GETERRORCODES;
|
||||
static const std::string CMD_PROGRAM_DEMARCATION;
|
||||
static const std::string CMD_SDCARD_MOUNT;
|
||||
static const std::string CMD_SDCARD_DIR;
|
||||
static const std::string CMD_SDCARD_DIR_ALL;
|
||||
static const std::string CMD_SDCARD_REWIND;
|
||||
static const std::string CMD_SDCARD_RUN;
|
||||
static const std::string CMD_SDCARD_UNLINK;
|
||||
static const std::string CMD_SDCARD_DUMP;
|
||||
static const std::string FORMAT_METRIC;
|
||||
static const std::string FORMAT_IMPERIAL;
|
||||
static const std::string NO_TOOL;
|
||||
static const std::string THCSIGNALS; // Keep in sync with THCSignals enum below!!
|
||||
|
||||
static const int X_AXIS = 0;
|
||||
static const int Y_AXIS = 1;
|
||||
static const int Z_AXIS = 2;
|
||||
static const int A_AXIS = 3;
|
||||
static const int B_AXIS = 4;
|
||||
static const int C_AXIS = 5;
|
||||
};
|
||||
|
||||
enum class CameraMoveMode {
|
||||
XAxisFirst = 1,
|
||||
YAxisFirst = 2,
|
||||
BothAxes = 3
|
||||
};
|
||||
|
||||
|
||||
enum class GrblStates {
|
||||
Unknown = 0,
|
||||
Idle,
|
||||
Run,
|
||||
Tool,
|
||||
Hold,
|
||||
Home,
|
||||
Check,
|
||||
Jog,
|
||||
Alarm,
|
||||
Door,
|
||||
Sleep
|
||||
};
|
||||
|
||||
enum class GrblMode {
|
||||
Normal = 0,
|
||||
Laser,
|
||||
Lathe
|
||||
};
|
||||
|
||||
enum class GrblEncoderMode {
|
||||
Unknown = 0,
|
||||
FeedRate = 1,
|
||||
RapidRate = 2,
|
||||
SpindleRPM = 3
|
||||
};
|
||||
|
||||
enum class GrblSetting {
|
||||
PulseMicroseconds = 0,
|
||||
StepperIdleLockTime = 1,
|
||||
StepInvertMask = 2,
|
||||
DirInvertMask = 3,
|
||||
InvertStepperEnable = 4,
|
||||
LimitPinsInvertMask = 5,
|
||||
InvertProbePin = 6,
|
||||
StatusReportMask = 10,
|
||||
JunctionDeviation = 11,
|
||||
ArcTolerance = 12,
|
||||
ReportInches = 13,
|
||||
SoftLimitsEnable = 20,
|
||||
HardLimitsEnable = 21,
|
||||
HomingEnable = 22,
|
||||
HomingDirMask = 23,
|
||||
HomingFeedRate = 24,
|
||||
HomingSeekRate = 25,
|
||||
HomingDebounceDelay = 26,
|
||||
HomingPulloff = 27,
|
||||
G73Retract = 28,
|
||||
PulseDelayMicroseconds = 29,
|
||||
RpmMax = 30,
|
||||
RpmMin = 31,
|
||||
Mode = 32, // enum GrblMode
|
||||
PWMFreq = 33,
|
||||
PWMOffValue = 34,
|
||||
PWMMinValue = 35,
|
||||
PWMMaxValue = 36,
|
||||
TravelResolutionBase = 100,
|
||||
MaxFeedRateBase = 110,
|
||||
AccelerationBase = 120,
|
||||
MaxTravelBase = 130,
|
||||
MotorCurrentBase = 140,
|
||||
};
|
||||
|
||||
enum class grblHALSetting {
|
||||
PulseMicroseconds = 0,
|
||||
StepperIdleLockTime = 1,
|
||||
StepInvertMask = 2,
|
||||
DirInvertMask = 3,
|
||||
InvertStepperEnable = 4,
|
||||
LimitPinsInvertMask = 5,
|
||||
InvertProbePin = 6,
|
||||
StatusReportMask = 10,
|
||||
JunctionDeviation = 11,
|
||||
ArcTolerance = 12,
|
||||
ReportInches = 13,
|
||||
ControlInvertMask = 14, // Note: Used for detecting GrblHAL firmware
|
||||
CoolantInvertMask = 15,
|
||||
SpindleInvertMask = 16,
|
||||
ControlPullUpDisableMask = 17,
|
||||
LimitPullUpDisableMask = 18,
|
||||
ProbePullUpDisable = 19,
|
||||
SoftLimitsEnable = 20,
|
||||
HardLimitsEnable = 21,
|
||||
HomingEnable = 22,
|
||||
HomingDirMask = 23,
|
||||
HomingFeedRate = 24,
|
||||
HomingSeekRate = 25,
|
||||
HomingDebounceDelay = 26,
|
||||
HomingPulloff = 27,
|
||||
G73Retract = 28,
|
||||
PulseDelayMicroseconds = 29,
|
||||
RpmMax = 30,
|
||||
RpmMin = 31,
|
||||
Mode = 32, // enum GrblMode
|
||||
PWMFreq = 33,
|
||||
PWMOffValue = 34,
|
||||
PWMMinValue = 35,
|
||||
PWMMaxValue = 36,
|
||||
StepperDeenergizeMask = 37,
|
||||
SpindlePPR = 38,
|
||||
EnableLegacyRTCommands = 39,
|
||||
SoftLimitJogging = 40,
|
||||
HomingLocateCycles = 43,
|
||||
HomingCycle_1 = 44,
|
||||
HomingCycle_2 = 45,
|
||||
HomingCycle_3 = 46,
|
||||
HomingCycle_4 = 47,
|
||||
HomingCycle_5 = 48,
|
||||
HomingCycle_6 = 49,
|
||||
JogStepSpeed = 50,
|
||||
JogSlowSpeed = 51,
|
||||
JogFastSpeed = 52,
|
||||
JogStepDistance = 53,
|
||||
JogSlowDistance = 54,
|
||||
JogFastDistance = 55,
|
||||
// Per axis settings
|
||||
TravelResolutionBase = 100,
|
||||
MaxFeedRateBase = 110,
|
||||
AccelerationBase = 120,
|
||||
MaxTravelBase = 130,
|
||||
MotorCurrentBase = 140,
|
||||
MicroStepsBase = 150,
|
||||
StallGuardBase = 200,
|
||||
// End per axis settings
|
||||
ToolChangeMode = 341
|
||||
};
|
||||
|
||||
enum class StreamingState {
|
||||
NoFile = 0,
|
||||
Idle,
|
||||
Send,
|
||||
SendMDI,
|
||||
Home,
|
||||
Halted,
|
||||
FeedHold,
|
||||
ToolChange,
|
||||
Start,
|
||||
Stop,
|
||||
Paused,
|
||||
JobFinished,
|
||||
Reset,
|
||||
AwaitResetAck,
|
||||
Disabled,
|
||||
Error
|
||||
};
|
||||
|
||||
enum class HomedState {
|
||||
Unknown = 0,
|
||||
NotHomed,
|
||||
Homed
|
||||
};
|
||||
|
||||
// Keep in sync with GrblInfo.SignalLetters constant below
|
||||
enum class Signals : int {
|
||||
Off = 0,
|
||||
LimitX = 1 << 0,
|
||||
LimitY = 1 << 1,
|
||||
LimitZ = 1 << 2,
|
||||
LimitA = 1 << 3,
|
||||
LimitB = 1 << 4,
|
||||
LimitC = 1 << 5,
|
||||
LimitU = 1 << 6,
|
||||
LimitV = 1 << 7,
|
||||
LimitW = 1 << 8,
|
||||
EStop = 1 << 9,
|
||||
Probe = 1 << 10,
|
||||
Reset = 1 << 11,
|
||||
SafetyDoor = 1 << 12,
|
||||
Hold = 1 << 13,
|
||||
CycleStart = 1 << 14,
|
||||
BlockDelete = 1 << 15,
|
||||
OptionalStop = 1 << 16,
|
||||
ProbeDisconnected = 1 << 17,
|
||||
MotorWarning = 1 << 18,
|
||||
MotorFault = 1 << 19
|
||||
};
|
||||
|
||||
enum class THCSignals : int {
|
||||
Off = 0,
|
||||
ArcOk = 1 << 0,
|
||||
THCEnabled = 1 << 1,
|
||||
THCActive = 1 << 2,
|
||||
TorchOn = 1 << 3,
|
||||
OhmicProbe = 1 << 4,
|
||||
VelocityLock = 1 << 5,
|
||||
VoidLock = 1 << 6,
|
||||
Down = 1 << 7,
|
||||
Up = 1 << 8
|
||||
};
|
||||
|
||||
struct GrblState {
|
||||
GrblStates State;
|
||||
int Substate;
|
||||
int LastAlarm;
|
||||
int Error;
|
||||
Color color;
|
||||
bool MPG;
|
||||
};
|
||||
|
||||
|
||||
class Grbl {
|
||||
public:
|
||||
static void Reset();
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#include "machine.h"
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "gcode.h"
|
||||
|
||||
namespace iosender {
|
||||
|
||||
class CoordinateSystem {
|
||||
};
|
||||
|
||||
class Tool {
|
||||
};
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
|
||||
void Reset() {
|
||||
// // Sync with controller
|
||||
// if (GrblInfo.IsGrblHAL) {
|
||||
// GrblParserState.Get();
|
||||
// GrblWorkParameters.Get();
|
||||
// } else {
|
||||
// GrblParserState.Get(true);
|
||||
// }
|
||||
// coordinateSystems.Clear();
|
||||
// for (CoordinateSystem c : GrblWorkParameters.CoordinateSystems) {
|
||||
// coordinateSystems.Add(c);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
protected:
|
||||
double rpm_ = 0;
|
||||
bool isRelative = false;
|
||||
int _tool = 0;
|
||||
double offsets[9];
|
||||
double origin[9];
|
||||
double scaleFactors[9];
|
||||
double toolOffsets[9];
|
||||
std::vector<CoordinateSystem> coordinateSystems;
|
||||
std::vector<Tool> toolTable;
|
||||
Point6D machinePos;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#include "measure_view_model.h"
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "grbl.h"
|
||||
|
||||
namespace iosender {
|
||||
|
||||
class MeasureViewModel {
|
||||
public:
|
||||
|
||||
bool _isMetric = true;
|
||||
const double MM_PER_INCH = 25.4;
|
||||
|
||||
bool IsMetric() const { return _isMetric; }
|
||||
|
||||
void IsMetric(bool value) {
|
||||
if (value != _isMetric) {
|
||||
_isMetric = value;
|
||||
// trigger OnPropertyChanged()
|
||||
}
|
||||
}
|
||||
|
||||
std::string Unit() const { return _isMetric ? "mm" : "in"; }
|
||||
|
||||
std::string FeedrateUnit() const { return _isMetric ? "mm/min" : "in/min"; }
|
||||
|
||||
double UnitFactor() const { return _isMetric ? 1.0 : 25.4; }
|
||||
|
||||
std::string Format() const { return _isMetric ? GrblConstants::FORMAT_METRIC : GrblConstants::FORMAT_IMPERIAL; }
|
||||
|
||||
std::string FormatSigned() const { return "-" + Format(); }
|
||||
|
||||
int Precision() const { return _isMetric ? 3 : 4; }
|
||||
|
||||
double ConvertMM2Current(double value) const {
|
||||
if (!_isMetric)
|
||||
value /= 25.4;
|
||||
return value;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
#include "telnet.h"
|
||||
#include "../string_utils.h"
|
||||
#include "grbl.h"
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <fcntl.h>
|
||||
#include <chrono>
|
||||
|
||||
bool iosender::TelnetStream::IsOpen() {
|
||||
return fd > 0 && isConnected;
|
||||
}
|
||||
|
||||
int iosender::TelnetStream::OutCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string iosender::TelnetStream::Reply() {
|
||||
return reply;
|
||||
}
|
||||
|
||||
iosender::Comms::StreamType iosender::TelnetStream::StreamType() {
|
||||
return Comms::StreamType::Telnet;
|
||||
}
|
||||
|
||||
bool iosender::TelnetStream::EventMode() {
|
||||
return eventMode;
|
||||
}
|
||||
|
||||
void iosender::TelnetStream::EventMode(bool mode) {
|
||||
eventMode = mode;
|
||||
}
|
||||
|
||||
void iosender::TelnetStream::Close() {
|
||||
shouldQuit = true;
|
||||
workerThread.join();
|
||||
}
|
||||
|
||||
int iosender::TelnetStream::ReadByte() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iosender::TelnetStream::WriteByte(uint8_t data) {
|
||||
auto result = write(fd, &data, 1);
|
||||
if (result == -1) {
|
||||
std::cerr << "Failed while writing." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void iosender::TelnetStream::WriteBytes(uint8_t *bytes, int len) {
|
||||
ssize_t written_bytes = 0;
|
||||
for (; written_bytes < len;) {
|
||||
auto result = write(fd, &bytes, len);
|
||||
if (result == -1) {
|
||||
std::cerr << "Failed while writing." << std::endl;
|
||||
return;
|
||||
}
|
||||
written_bytes += result;
|
||||
}
|
||||
}
|
||||
|
||||
void iosender::TelnetStream::WriteString(std::string data) {
|
||||
WriteBytes(reinterpret_cast<uint8_t *>(data.data()), data.size());
|
||||
}
|
||||
|
||||
void iosender::TelnetStream::WriteCommand(std::string command) {
|
||||
CommandState = Comms::State::AwaitAck;
|
||||
|
||||
if (command.size() == 1 && command != GrblConstants::CMD_PROGRAM_DEMARCATION) {
|
||||
WriteByte(*command.data());
|
||||
} else {
|
||||
command += "\r";
|
||||
WriteString(command);
|
||||
}
|
||||
}
|
||||
|
||||
std::string iosender::TelnetStream::GetReply(std::string command) {
|
||||
reply = "";
|
||||
AwaitResponse(command);
|
||||
return reply;
|
||||
}
|
||||
|
||||
void iosender::TelnetStream::AwaitAck() {
|
||||
while (Comms::GetCom()->CommandState == Comms::State::DataReceived ||
|
||||
Comms::GetCom()->CommandState == Comms::State::AwaitAck) {
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(500));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void iosender::TelnetStream::AwaitAck(std::string command) {
|
||||
WriteCommand(command);
|
||||
AwaitAck();
|
||||
}
|
||||
|
||||
void iosender::TelnetStream::AwaitResponse() {
|
||||
while (Comms::GetCom()->CommandState == Comms::State::AwaitAck) {
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(500));
|
||||
}
|
||||
}
|
||||
|
||||
void iosender::TelnetStream::AwaitResponse(std::string command) {
|
||||
WriteCommand(command);
|
||||
AwaitResponse();
|
||||
}
|
||||
|
||||
void iosender::TelnetStream::PurgeQueue() {
|
||||
}
|
||||
|
||||
iosender::TelnetStream::TelnetStream(std::string host, iosender::DataReceivedHandler *dataHandler,
|
||||
iosender::ByteReceivedHandler *byteHandler) {
|
||||
Comms::SetCom(this);
|
||||
reply = "";
|
||||
dataReceivedHandler = dataHandler;
|
||||
byteReceivedHandler = byteHandler;
|
||||
|
||||
if (!string_contains(host, ":")) {
|
||||
host += ":23";
|
||||
}
|
||||
|
||||
auto parameter = split_string(host, ":");
|
||||
auto ip = parameter[0];
|
||||
auto port = std::stoi(parameter[1]);
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd == -1) {
|
||||
std::cerr << "Error creating socket" << std::endl;
|
||||
}
|
||||
|
||||
struct sockaddr_in serv_addr{};
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_port = htons(port);
|
||||
|
||||
if (inet_pton(AF_INET, ip.c_str(), &serv_addr.sin_addr) <= 0) {
|
||||
std::cerr << "Invalid address/ Address not supported" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
auto status = connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
|
||||
if (status < 0) {
|
||||
std::cerr << "Connection failed";
|
||||
return;
|
||||
}
|
||||
|
||||
isConnected = true;
|
||||
|
||||
// set non-blocking please, after we connected
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
workerThread = std::thread(&iosender::TelnetStream::readWorker, this);
|
||||
}
|
||||
|
||||
iosender::TelnetStream::~TelnetStream() {
|
||||
Close();
|
||||
}
|
||||
|
||||
void iosender::TelnetStream::readWorker() {
|
||||
std::string received;
|
||||
uint8_t buffer[200];
|
||||
|
||||
while (!shouldQuit) {
|
||||
if (isConnected) {
|
||||
|
||||
// anything to read?
|
||||
auto readBytes = read(fd, buffer, 200);
|
||||
if (readBytes == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
// do nothing
|
||||
} else if (readBytes == -1) {
|
||||
std::cerr << "Failed while reading." << std::endl;
|
||||
Close();
|
||||
} else {
|
||||
for (int i = 0; i < readBytes; i++) {
|
||||
auto isEol = buffer[i] == '\n';
|
||||
if (isEol) {
|
||||
reply = received;
|
||||
|
||||
CommandState = reply == "ok" ?
|
||||
Comms::State::ACK :
|
||||
(starts_with(reply, "error") ?
|
||||
Comms::State::NAK :
|
||||
Comms::State::DataReceived);
|
||||
|
||||
if (!reply.empty() && dataReceivedHandler != nullptr) {
|
||||
dataReceivedHandler->DataReceived(reply);
|
||||
}
|
||||
|
||||
received.clear();
|
||||
} else {
|
||||
received.push_back(static_cast<char>(buffer[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// give some time to others
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <thread>
|
||||
#include "comms.h"
|
||||
|
||||
namespace iosender {
|
||||
|
||||
class TelnetStream : public StreamComms {
|
||||
public:
|
||||
|
||||
TelnetStream(std::string host, DataReceivedHandler* dataHandler = nullptr, ByteReceivedHandler *byteHandler = nullptr);
|
||||
~TelnetStream() override;
|
||||
|
||||
bool IsOpen() override;
|
||||
int OutCount() override;
|
||||
std::string Reply() override;
|
||||
Comms::StreamType StreamType() override;
|
||||
bool EventMode() override;
|
||||
void EventMode(bool mode) override;
|
||||
void Close() override;
|
||||
int ReadByte() override;
|
||||
void WriteByte(uint8_t data) override;
|
||||
void WriteBytes(uint8_t *bytes, int len) override;
|
||||
void WriteString(std::string data) override;
|
||||
void WriteCommand(std::string command) override;
|
||||
std::string GetReply(std::string command) override;
|
||||
void AwaitAck() override;
|
||||
void AwaitAck(std::string command) override;
|
||||
void AwaitResponse(std::string command) override;
|
||||
void AwaitResponse() override;
|
||||
void PurgeQueue() override;
|
||||
|
||||
|
||||
private:
|
||||
volatile bool shouldQuit = false;
|
||||
void readWorker();
|
||||
|
||||
std::string reply;
|
||||
int fd;
|
||||
bool isConnected;
|
||||
bool eventMode = true;
|
||||
std::thread workerThread;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user