From f2b52d935ebc81a2eb12cfd7a1c4b924cfc5ea68 Mon Sep 17 00:00:00 2001 From: FormerLurker Date: Mon, 23 Nov 2020 08:39:15 -0600 Subject: Implement #18 and #19. Fix some compiler warnings. --- .../ArcWelderInverseProcessor.cpp | 49 +++++++++++++++++++++- ArcWelderInverseProcessor/inverse_processor.cpp | 36 +++++++--------- ArcWelderInverseProcessor/inverse_processor.h | 20 +++++---- 3 files changed, 73 insertions(+), 32 deletions(-) (limited to 'ArcWelderInverseProcessor') diff --git a/ArcWelderInverseProcessor/ArcWelderInverseProcessor.cpp b/ArcWelderInverseProcessor/ArcWelderInverseProcessor.cpp index 62a3a07..ea333b3 100644 --- a/ArcWelderInverseProcessor/ArcWelderInverseProcessor.cpp +++ b/ArcWelderInverseProcessor/ArcWelderInverseProcessor.cpp @@ -55,6 +55,12 @@ int main(int argc, char* argv[]) std::string target_file_path; bool overwrite_source_file = false; bool g90_g91_influences_extruder; + + ConfigurationStore cs; + double mm_per_arc_segment; + double min_mm_per_arc_segment; + int min_arc_segments; + double arc_segments_per_sec; std::string log_level_string; std::string log_level_string_default = "INFO"; @@ -77,7 +83,31 @@ int main(int argc, char* argv[]) arg_description_stream.str(""); arg_description_stream << "If supplied, G90/G91 influences the extruder axis. Default Value: " << DEFAULT_G90_G91_INFLUENCES_EXTRUDER; TCLAP::SwitchArg g90_arg("g", "g90-influences-extruder", arg_description_stream.str(), false); - + + // -m --mm-per-arc-segment + arg_description_stream.clear(); + arg_description_stream.str(""); + arg_description_stream << "The default segment length. Default Value: " << DEFAULT_MM_PER_ARC_SEGMENT; + TCLAP::ValueArg mm_per_arc_segment_arg("m", "mm-per-arc-segment", arg_description_stream.str(), false, DEFAULT_MM_PER_ARC_SEGMENT, "float"); + + // -n --min-mm-per-arc-segment + arg_description_stream.clear(); + arg_description_stream.str(""); + arg_description_stream << "The minimum mm per arc segment. Used to prevent unnecessarily small segments from being generated. A value less than or equal to 0 will disable this feature. Default Value: " << DEFAULT_MIN_MM_PER_ARC_SEGMENT; + TCLAP::ValueArg min_mm_per_arc_segment_arg("n", "min-mm-per-arc-segment", arg_description_stream.str(), false, DEFAULT_MIN_MM_PER_ARC_SEGMENT, "float"); + + // -s --min-arc-segments + arg_description_stream.clear(); + arg_description_stream.str(""); + arg_description_stream << "The minimum number of segments within a circle of the same radius as the arc. Can be used to increase detail on small arcs. The smallest segment generated will be no larger than min_mm_per_arc_segment. A value less than or equal to 0 will disable this feature. Default Value: " << DEFAULT_MIN_ARC_SEGMENTS; + TCLAP::ValueArg min_arc_segments_arg("r", "min-arc-segments", arg_description_stream.str(), false, DEFAULT_MIN_ARC_SEGMENTS, "int"); + + // -s --arc-segments-per-second + arg_description_stream.clear(); + arg_description_stream.str(""); + arg_description_stream << "The number of segments per second. This will produce a constant number of arcs, clamped between mm-per-arc-segment and min-mm-per-arc-segment. Can be used to prevent stuttering when printing very quickly. A value less than or equal to 0 will disable this feature. Default Value: " << DEFAULT_ARC_SEGMENTS_PER_SEC; + TCLAP::ValueArg arc_segments_per_sec_arg("s", "arc-segments-per-second", arg_description_stream.str(), false, DEFAULT_MIN_MM_PER_ARC_SEGMENT, "float"); + // -l --log-level std::vector log_levels_vector; log_levels_vector.push_back("NOSET"); @@ -98,6 +128,12 @@ int main(int argc, char* argv[]) cmd.add(source_arg); cmd.add(target_arg); cmd.add(g90_arg); + + cmd.add(mm_per_arc_segment_arg); + cmd.add(min_mm_per_arc_segment_arg); + cmd.add(min_arc_segments_arg); + cmd.add(arc_segments_per_sec_arg); + cmd.add(log_level_arg); // Parse the argv array. @@ -106,6 +142,15 @@ int main(int argc, char* argv[]) // Get the value parsed by each arg. source_file_path = source_arg.getValue(); target_file_path = target_arg.getValue(); + mm_per_arc_segment = mm_per_arc_segment_arg.getValue(); + min_mm_per_arc_segment = min_mm_per_arc_segment_arg.getValue(); + min_arc_segments = min_arc_segments_arg.getValue(); + arc_segments_per_sec = arc_segments_per_sec_arg.getValue(); + + cs.mm_per_arc_segment = (float)mm_per_arc_segment; + cs.min_mm_per_arc_segment = (float)min_mm_per_arc_segment; + cs.min_arc_segments = min_arc_segments; + cs.arc_segments_per_sec = arc_segments_per_sec; if (target_file_path.size() == 0) { @@ -188,7 +233,7 @@ int main(int argc, char* argv[]) target_file_path = temp_file_path; } - inverse_processor processor(source_file_path, target_file_path, g90_g91_influences_extruder, 50); + inverse_processor processor(source_file_path, target_file_path, g90_g91_influences_extruder, 50, cs); processor.process(); // Todo: get some results! if (true) diff --git a/ArcWelderInverseProcessor/inverse_processor.cpp b/ArcWelderInverseProcessor/inverse_processor.cpp index 6717700..d82568c 100644 --- a/ArcWelderInverseProcessor/inverse_processor.cpp +++ b/ArcWelderInverseProcessor/inverse_processor.cpp @@ -54,11 +54,12 @@ //#include "stepper.h" //#include "planner.h" -inverse_processor::inverse_processor(std::string source_path, std::string target_path, bool g90_g91_influences_extruder, int buffer_size) +inverse_processor::inverse_processor(std::string source_path, std::string target_path, bool g90_g91_influences_extruder, int buffer_size, ConfigurationStore cs) { source_path_ = source_path; target_path_ = target_path; p_source_position_ = new gcode_position(get_args_(g90_g91_influences_extruder, buffer_size)); + cs_ = cs; // ** Gloabal Variable Definition ** // 20200417 - FormerLurker - Declare two globals and pre-calculate some values that will reduce the // amount of trig funcitons we need to call while printing. For the price of having two globals we @@ -259,50 +260,50 @@ void inverse_processor::mc_arc(float* position, float* target, float* offset, fl float rt_x = t_x - center_axis_x; float rt_y = t_y - center_axis_y; // 20200419 - Add a variable that will be used to hold the arc segment length - float mm_per_arc_segment = cs.mm_per_arc_segment; + float mm_per_arc_segment = cs_.mm_per_arc_segment; // CCW angle between position and target from circle center. Only one atan2() trig computation required. float angular_travel_total = atan2(r_axis_x * rt_y - r_axis_y * rt_x, r_axis_x * rt_x + r_axis_y * rt_y); - if (angular_travel_total < 0) { angular_travel_total += 2 * M_PI; } + if (angular_travel_total < 0) { angular_travel_total += (float)(2 * M_PI); } bool check_mm_per_arc_segment_max = false; - if (cs.min_arc_segments > 0) + if (cs_.min_arc_segments > 0) { // 20200417 - FormerLurker - Implement MIN_ARC_SEGMENTS if it is defined - from Marlin 2.0 implementation // Do this before converting the angular travel for clockwise rotation - mm_per_arc_segment = radius * ((2.0f * M_PI) / cs.min_arc_segments); + mm_per_arc_segment = (float)(radius * ((2.0f * M_PI) / cs_.min_arc_segments)); check_mm_per_arc_segment_max = true; } - if (cs.arc_segments_per_sec > 0) + if (cs_.arc_segments_per_sec > 0) { // 20200417 - FormerLurker - Implement MIN_ARC_SEGMENTS if it is defined - from Marlin 2.0 implementation - float mm_per_arc_segment_sec = (feed_rate / 60.0f) * (1.0f / cs.arc_segments_per_sec); + float mm_per_arc_segment_sec = (float)((feed_rate / 60.0f) * (1.0f / cs_.arc_segments_per_sec)); if (mm_per_arc_segment_sec < mm_per_arc_segment) mm_per_arc_segment = mm_per_arc_segment_sec; check_mm_per_arc_segment_max = true; } - if (cs.min_mm_per_arc_segment > 0) + if (cs_.min_mm_per_arc_segment > 0) { check_mm_per_arc_segment_max = true; // 20200417 - FormerLurker - Implement MIN_MM_PER_ARC_SEGMENT if it is defined // This prevents a very high number of segments from being generated for curves of a short radius - if (mm_per_arc_segment < cs.min_mm_per_arc_segment) mm_per_arc_segment = cs.min_mm_per_arc_segment; + if (mm_per_arc_segment < cs_.min_mm_per_arc_segment) mm_per_arc_segment = cs_.min_mm_per_arc_segment; } - if (check_mm_per_arc_segment_max && mm_per_arc_segment > cs.mm_per_arc_segment) mm_per_arc_segment = cs.mm_per_arc_segment; + if (check_mm_per_arc_segment_max && mm_per_arc_segment > cs_.mm_per_arc_segment) mm_per_arc_segment = cs_.mm_per_arc_segment; // Adjust the angular travel if the direction is clockwise - if (isclockwise) { angular_travel_total -= 2 * M_PI; } + if (isclockwise) { angular_travel_total -= (float)(2 * M_PI); } //20141002:full circle for G03 did not work, e.g. G03 X80 Y80 I20 J0 F2000 is giving an Angle of zero so head is not moving //to compensate when start pos = target pos && angle is zero -> angle = 2Pi if (p_x == t_x && p_y == t_y && angular_travel_total == 0) { - angular_travel_total += 2 * M_PI; + angular_travel_total += (float)(2 * M_PI); } //end fix G03 @@ -388,15 +389,8 @@ void inverse_processor::plan_buffer_line(float x, float y, float z, const float& //output_file_ << stream << "G1 X" << std::setprecision(3) << x << " Y" << y; - if (output_relative_) - { - stream << std::setprecision(5) << " E" << output_relative_; - } - else - { - stream << std::setprecision(5) << " E" << e; - } - + stream << std::setprecision(5) << " E" << e; + stream << std::setprecision(0) << " F" << feed_rate << "\n"; output_file_ << stream.str(); } diff --git a/ArcWelderInverseProcessor/inverse_processor.h b/ArcWelderInverseProcessor/inverse_processor.h index ae4e19b..a5f7184 100644 --- a/ArcWelderInverseProcessor/inverse_processor.h +++ b/ArcWelderInverseProcessor/inverse_processor.h @@ -38,12 +38,12 @@ typedef signed char int8_t; #define M_PI 3.14159265358979323846 // pi enum AxisEnum { X_AXIS = 0, Y_AXIS= 1, Z_AXIS = 2, E_AXIS = 3, X_HEAD = 4, Y_HEAD = 5 }; // Arc interpretation settings: -#define DEFAULT_MM_PER_ARC_SEGMENT 100.0 // REQUIRED - The enforced maximum length of an arc segment -#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.2 /* OPTIONAL - the enforced minimum length of an interpolated segment. Must be smaller than +#define DEFAULT_MM_PER_ARC_SEGMENT 1.0 // REQUIRED - The enforced maximum length of an arc segment +#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0 /* OPTIONAL - the enforced minimum length of an interpolated segment. Must be smaller than MM_PER_ARC_SEGMENT. Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */ // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used. -#define DEFAULT_MIN_ARC_SEGMENTS 10 // OPTIONAL - The enforced minimum segments in a full circle of the same radius. -#define DEFAULT_ARC_SEGMENTS_PER_SEC 30 // OPTIONAL - Use feedrate to choose segment length. +#define DEFAULT_MIN_ARC_SEGMENTS 0 // OPTIONAL - The enforced minimum segments in a full circle of the same radius. +#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length. // approximation will not be used for the first segment. Subsequent segments will be corrected following DEFAULT_N_ARC_CORRECTION. struct ConfigurationStore { @@ -53,19 +53,21 @@ struct ConfigurationStore { min_arc_segments = DEFAULT_MIN_ARC_SEGMENTS; arc_segments_per_sec = DEFAULT_ARC_SEGMENTS_PER_SEC; } - float mm_per_arc_segment; - float min_mm_per_arc_segment; + float mm_per_arc_segment; // This value is ALWAYS used. + float min_mm_per_arc_segment; // if less than or equal to 0, this is disabled int min_arc_segments; // If less than or equal to zero, this is disabled - int arc_segments_per_sec; // If less than or equal to zero, this is disabled + double arc_segments_per_sec; // If less than or equal to zero, this is disabled + }; class inverse_processor { public: - inverse_processor(std::string source_path, std::string target_path, bool g90_g91_influences_extruder, int buffer_size); + inverse_processor(std::string source_path, std::string target_path, bool g90_g91_influences_extruder, int buffer_size, ConfigurationStore cs = ConfigurationStore()); virtual ~inverse_processor(); void process(); void mc_arc(float* position, float* target, float* offset, float feed_rate, float radius, uint8_t isclockwise, uint8_t extruder); - ConfigurationStore cs; + private: + ConfigurationStore cs_; gcode_position_args get_args_(bool g90_g91_influences_extruder, int buffer_size); std::string source_path_; std::string target_path_; -- cgit v1.2.3