diff options
author | FormerLurker <hochgebe@gmail.com> | 2020-11-06 19:43:13 +0300 |
---|---|---|
committer | FormerLurker <hochgebe@gmail.com> | 2020-11-06 19:43:13 +0300 |
commit | 91633ba765214d1c6eece514e2dd2d0e898be8b4 (patch) | |
tree | 21ed3e43d72bc89efb0f363464ec26ee5e3ce536 /GcodeProcessorLib | |
parent | 395c472dfc6080b0b0b2fca9f1dba6eeb46c21cf (diff) |
Implementations for #8, #9, #10, #11.
Diffstat (limited to 'GcodeProcessorLib')
-rw-r--r-- | GcodeProcessorLib/gcode_parser.cpp | 5 | ||||
-rw-r--r-- | GcodeProcessorLib/gcode_parser.h | 2 | ||||
-rw-r--r-- | GcodeProcessorLib/parsed_command.cpp | 17 | ||||
-rw-r--r-- | GcodeProcessorLib/parsed_command_parameter.cpp | 11 | ||||
-rw-r--r-- | GcodeProcessorLib/parsed_command_parameter.h | 5 | ||||
-rw-r--r-- | GcodeProcessorLib/utilities.cpp | 88 | ||||
-rw-r--r-- | GcodeProcessorLib/utilities.h | 30 |
7 files changed, 67 insertions, 91 deletions
diff --git a/GcodeProcessorLib/gcode_parser.cpp b/GcodeProcessorLib/gcode_parser.cpp index b12b4e9..2cc49f7 100644 --- a/GcodeProcessorLib/gcode_parser.cpp +++ b/GcodeProcessorLib/gcode_parser.cpp @@ -433,7 +433,7 @@ double gcode_parser::ten_pow(unsigned short n) { return r; } -bool gcode_parser::try_extract_double(char ** p_p_gcode, double * p_double) const +bool gcode_parser::try_extract_double(char ** p_p_gcode, double * p_double, unsigned char *p_precision) const { char * p = *p_p_gcode; bool neg = false; @@ -481,6 +481,7 @@ bool gcode_parser::try_extract_double(char ** p_p_gcode, double * p_double) cons } //r += f / pow(10.0, n); r += f / ten_pow(n); + *p_precision = n; } if (neg) { r = -r; @@ -594,7 +595,7 @@ bool gcode_parser::try_extract_parameter(char ** p_p_gcode, parsed_command_param // TODO: See if unsigned long works.... // Add all values, stop at end of string or when we hit a ';' - if (try_extract_double(&p,&(parameter->double_value))) + if (try_extract_double(&p,&(parameter->double_value), &(parameter->double_precision))) { parameter->value_type = 'F'; } diff --git a/GcodeProcessorLib/gcode_parser.h b/GcodeProcessorLib/gcode_parser.h index 714dfe4..27414db 100644 --- a/GcodeProcessorLib/gcode_parser.h +++ b/GcodeProcessorLib/gcode_parser.h @@ -44,7 +44,7 @@ private: std::set<std::string> text_only_functions_; std::set<std::string> parsable_commands_; // Functions - bool try_extract_double(char ** p_p_gcode, double * p_double) const; + bool try_extract_double(char ** p_p_gcode, double * p_double, unsigned char * p_precision) const; static bool try_extract_gcode_command(char ** p_p_gcode, std::string * p_command); static bool try_extract_text_parameter(char ** p_p_gcode, std::string * p_parameter); bool try_extract_parameter(char ** p_p_gcode, parsed_command_parameter * parameter) const; diff --git a/GcodeProcessorLib/parsed_command.cpp b/GcodeProcessorLib/parsed_command.cpp index 5cd00d9..052516b 100644 --- a/GcodeProcessorLib/parsed_command.cpp +++ b/GcodeProcessorLib/parsed_command.cpp @@ -58,19 +58,6 @@ std::string parsed_command::rewrite_gcode_string() { parsed_command_parameter p = parameters[index]; - if (p.name == "E") - { - stream << std::fixed << std::setprecision(5); - } - else if (p.name == "F") - { - stream << std::fixed << std::setprecision(0); - } - else - { - stream << std::fixed << std::setprecision(3); - } - stream << " " << p.name; switch (p.value_type) { @@ -78,10 +65,10 @@ std::string parsed_command::rewrite_gcode_string() stream << p.string_value; break; case 'F': - stream << p.double_value; + stream << p.double_value << std::fixed << std::setprecision(p.double_precision); break; case 'U': - stream << p.unsigned_long_value; + stream << std::setprecision(0) << p.unsigned_long_value; break; } } diff --git a/GcodeProcessorLib/parsed_command_parameter.cpp b/GcodeProcessorLib/parsed_command_parameter.cpp index fe4ca8b..29bf599 100644 --- a/GcodeProcessorLib/parsed_command_parameter.cpp +++ b/GcodeProcessorLib/parsed_command_parameter.cpp @@ -26,19 +26,24 @@ parsed_command_parameter::parsed_command_parameter() { value_type = 'N'; name.reserve(1); + name = ""; + unsigned_long_value = 0; + double_value = 0; + double_precision = 0; + string_value = ""; } -parsed_command_parameter::parsed_command_parameter(const std::string name, double value) : name(name), double_value(value) +parsed_command_parameter::parsed_command_parameter(const std::string name, double value, unsigned char precision) : name(name), double_value(value), double_precision(precision) { value_type = 'F'; } -parsed_command_parameter::parsed_command_parameter(const std::string name, const std::string value) : name(name), string_value(value) +parsed_command_parameter::parsed_command_parameter(const std::string name, const std::string value) : name(name), string_value(value), double_precision(0) { value_type = 'S'; } -parsed_command_parameter::parsed_command_parameter(const std::string name, const unsigned long value) : name(name), unsigned_long_value(value) +parsed_command_parameter::parsed_command_parameter(const std::string name, const unsigned long value) : name(name), unsigned_long_value(value), double_precision(0) { value_type = 'U'; } diff --git a/GcodeProcessorLib/parsed_command_parameter.h b/GcodeProcessorLib/parsed_command_parameter.h index 04a7f06..69ffaa1 100644 --- a/GcodeProcessorLib/parsed_command_parameter.h +++ b/GcodeProcessorLib/parsed_command_parameter.h @@ -28,12 +28,13 @@ struct parsed_command_parameter public: parsed_command_parameter(); ~parsed_command_parameter(); - parsed_command_parameter(std::string name, double value); + parsed_command_parameter(std::string name, double value, unsigned char precision); parsed_command_parameter(std::string name, std::string value); parsed_command_parameter(std::string name, unsigned long value); std::string name; - char value_type; + unsigned char value_type; double double_value; + unsigned char double_precision; unsigned long unsigned_long_value; std::string string_value; }; diff --git a/GcodeProcessorLib/utilities.cpp b/GcodeProcessorLib/utilities.cpp index 19e47ab..d126755 100644 --- a/GcodeProcessorLib/utilities.cpp +++ b/GcodeProcessorLib/utilities.cpp @@ -25,52 +25,18 @@ #include <iostream> #include <iomanip> -// Had to increase the zero tolerance because prusa slicer doesn't always retract enough while wiping. -const double ZERO_TOLERANCE = 0.000005; const std::string utilities::WHITESPACE_ = " \n\r\t\f\v"; const char utilities::GUID_RANGE[] = "0123456789abcdef"; const bool utilities::GUID_DASHES[] = { 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0 }; -bool utilities::is_zero(double x) -{ - return std::abs(x) < ZERO_TOLERANCE; -} - -int utilities::round_up_to_int(double x) -{ - return int(x + ZERO_TOLERANCE); -} - -bool utilities::is_equal(double x, double y) -{ - double abs_difference = std::abs(x - y); - return abs_difference < ZERO_TOLERANCE; -} - -bool utilities::greater_than(double x, double y) -{ - return x > y && !is_equal(x, y); -} - -bool utilities::greater_than_or_equal(double x, double y) -{ - return x > y || is_equal(x, y); -} - -bool utilities::less_than(double x, double y) -{ - return x < y && !is_equal(x, y); -} - -bool utilities::less_than_or_equal(double x, double y) +bool utilities::is_zero(double x, double tolerance) { - return x < y || is_equal(x, y); + return std::abs(x) < tolerance; } -// custom tolerance functions -bool utilities::is_zero(double x, double tolerance) +int utilities::round_up_to_int(double x, double tolerance) { - return std::abs(x) < tolerance; + return int(x + tolerance); } bool utilities::is_equal(double x, double y, double tolerance) @@ -79,27 +45,27 @@ bool utilities::is_equal(double x, double y, double tolerance) return abs_difference < tolerance; } -int utilities::round_up_to_int(double x, double tolerance) -{ - return int(x + tolerance); -} bool utilities::greater_than(double x, double y, double tolerance) { - return x > y && !utilities::is_equal(x, y, tolerance); + return x > y && !is_equal(x, y, tolerance); } + bool utilities::greater_than_or_equal(double x, double y, double tolerance) { - return x > y || utilities::is_equal(x, y, tolerance); + return x > y || is_equal(x, y, tolerance); } + bool utilities::less_than(double x, double y, double tolerance) { - return x < y && !utilities::is_equal(x, y, tolerance); + return x < y && !is_equal(x, y, tolerance); } + bool utilities::less_than_or_equal(double x, double y, double tolerance) { - return x < y || utilities::is_equal(x, y, tolerance); + return x < y || is_equal(x, y, tolerance); } + double utilities::get_cartesian_distance(double x1, double y1, double x2, double y2) { // Compare the saved points cartesian distance from the current point @@ -133,9 +99,13 @@ std::string utilities::to_string(int value) return os.str(); } -char * utilities::to_string(double value, unsigned short precision, char * str) +char * utilities::to_string(double value, unsigned short precision, char * str, bool exact_precision) { - char reversed_int[20]; + if (utilities::is_zero(value)) + { + value = 0; + } + char reversed_int[REVERSED_INT_BUFFER]; int char_count = 0, int_count = 0; bool is_negative = false; @@ -162,20 +132,36 @@ char * utilities::to_string(double value, unsigned short precision, char * str) } int start = is_negative ? 1 : 0; int end = char_count - start; - for (int i = 0; i < int_count; i++) + for (int i = 0; i < int_count && i < REVERSED_INT_BUFFER; i++) { - str[char_count++] = reversed_int[int_count - i - 1]; + int reversed_int_index = int_count - i - 1; + if (reversed_int_index < 0 || reversed_int_index >= REVERSED_INT_BUFFER) + { + std::cerr << "Buffer overflow turning " << value << " into a string!"; + break; + } + str[char_count++] = reversed_int[reversed_int_index]; } - if (precision > 0) + if ( precision > 0) { str[char_count++] = '.'; //Decimal point + // We will look 1 past the precision to see if it is a 9. if it is, we will round up. + //if (precision > 0) precision++; while (fractional_part > 0 && precision-- > 0) //Convert fractional part, if any { fractional_part *= 10; fractional_part = std::modf(fractional_part, &integer_part); str[char_count++] = '0' + (int)integer_part; } + // remove any unnecessary zeros + if (!exact_precision) + { + while (str[char_count-1] == '0') { char_count--; } + // Remove the period + if (str[char_count-1] == '.') char_count--; + } + } str[char_count] = 0; //String terminator return str; diff --git a/GcodeProcessorLib/utilities.h b/GcodeProcessorLib/utilities.h index 8e54df0..b1fc7a3 100644 --- a/GcodeProcessorLib/utilities.h +++ b/GcodeProcessorLib/utilities.h @@ -24,30 +24,26 @@ #include <string> #include <vector> #include <set> +#define REVERSED_INT_BUFFER 20 +// Had to increase the zero tolerance because prusa slicer doesn't always +// retract enough while wiping. +#define ZERO_TOLERANCE 0.000005 + class utilities{ public: - static bool is_zero(double x); - static int round_up_to_int(double x); - static bool is_equal(double x, double y); - static bool greater_than(double x, double y); - static bool greater_than_or_equal(double x, double y); - static bool less_than(double x, double y); - static bool less_than_or_equal(double x, double y); + static bool is_zero(double x, double tolerance = ZERO_TOLERANCE); + static int round_up_to_int(double x, double tolerance = ZERO_TOLERANCE); + static bool is_equal(double x, double y, double tolerance = ZERO_TOLERANCE); + static bool greater_than(double x, double y, double tolerance = ZERO_TOLERANCE); + static bool greater_than_or_equal(double x, double y, double tolerance = ZERO_TOLERANCE); + static bool less_than(double x, double y, double tolerance = ZERO_TOLERANCE); + static bool less_than_or_equal(double x, double y, double tolerance = ZERO_TOLERANCE); - // custom tolerance functions - static bool is_zero(double x, double tolerance); - static bool is_equal(double x, double y, double tolerance); - static int round_up_to_int(double x, double tolerance); - static bool greater_than(double x, double y, double tolerance); - static bool greater_than_or_equal(double x, double y, double tolerance); - static bool less_than(double x, double y, double tolerance); - static bool less_than_or_equal(double x, double y, double tolerance); - static double get_cartesian_distance(double x1, double y1, double x2, double y2); static double get_cartesian_distance(double x1, double y1, double z1, double x2, double y2, double z2); static std::string to_string(double value); static std::string to_string(int value); - static char* to_string(double value, unsigned short precision, char* str); + static char* to_string(double value, unsigned short precision, char* str, bool exact_precision); static std::string ltrim(const std::string& s); static std::string rtrim(const std::string& s); static std::string trim(const std::string& s); |