#pragma once #include #include #include #include #include "glm/ext/scalar_constants.hpp" namespace grbl { glm::vec<3, double> roll_components(glm::vec<3, double> v, int turns); enum class arc_plane { xy = 0, yz = 1, zx = 2 }; enum class arc_direction { cw, ccw }; struct command { virtual ~command() = default; int line_number = 1; }; struct mcode_cmd : public command { mcode_cmd(int code, int line_number); int code; }; struct spindle_cmd : public command { spindle_cmd(double speed, int line_number); double speed; }; struct dwell_cmd : public command { dwell_cmd(double seconds, int line_number); double seconds; }; struct motion_cmd : public command { glm::vec<3, double> start = glm::vec3(0); glm::vec<3, double> end = glm::vec3(0); double feed = 0; glm::vec<3, double> delta() const { return end - start; } // Total travel distance of tool virtual double length() const = 0; virtual glm::vec<3, double> interpolate(double ratio) = 0; virtual std::vector split(double length) = 0; }; struct line_motion_cmd : public motion_cmd { bool rapid = false; // PositionValid[i] is true if the corresponding coordinate of the end position was defined in the file. // eg. for a file with "G0 Z15" as the first line, X and Y would still be false bool position_valid[3] = {false, false, false}; bool start_valid = false; double length() const override; glm::vec<3, double> interpolate(double ratio) override; std::vector split(double length) override; }; struct arc_motion_cmd : public motion_cmd { arc_plane plane; arc_direction direction; double u; //absolute position of center in first axis of plane double v; //absolute position of center in second axis of plane double start_angle() const { glm::vec<3, double> start_in_plane = roll_components(start, -(int) plane); double X = start_in_plane.x - u; double Y = start_in_plane.y - v; return atan2(Y, X); } double end_angle() const { glm::vec<3, double> end_in_plane = roll_components(end, -(int) plane); double X = end_in_plane.x - u; double Y = end_in_plane.y - v; return atan2(Y, X); } double angle_span() const { double span = end_angle() - start_angle(); if (direction == arc_direction::cw) { if (span >= 0) span -= 2 * glm::pi(); } else { if (span <= 0) span += 2 * glm::pi(); } return span; } double radius() const { glm::vec<3, double> start_plane = roll_components(start, -(int) plane); glm::vec<3, double> end_plane = roll_components(end, -(int) plane); return ( sqrt(pow(start_plane.x - u, 2) + pow(start_plane.y - v, 2)) + sqrt(pow(end_plane.x - u, 2) + pow(end_plane.y - v, 2)) ) / 2; } glm::vec<3, double> interpolate(double ratio) override; std::vector split(double length) override; double length() const override; }; }