From 5e7920dea901011a9144d0cd3fbd7b78624b7d81 Mon Sep 17 00:00:00 2001 From: FormerLurker Date: Thu, 4 Feb 2021 13:39:36 -0600 Subject: Fix for issue #34. --- ArcWelder/arc_welder.cpp | 31 ++++++++++++++++++------------- ArcWelder/arc_welder.h | 1 - ArcWelder/segmented_arc.h | 1 + ArcWelder/segmented_shape.cpp | 32 ++++++++++++++------------------ ArcWelder/segmented_shape.h | 2 +- ArcWelder/unwritten_command.h | 7 ++++++- ArcWelderTest/ArcWelderTest.h | 3 +++ CMakeLists.txt | 2 +- GcodeProcessorLib/array_list.h | 4 ++-- GcodeProcessorLib/version.h | 22 +++++++++++----------- 10 files changed, 57 insertions(+), 48 deletions(-) diff --git a/ArcWelder/arc_welder.cpp b/ArcWelder/arc_welder.cpp index c06ce77..5d53a90 100644 --- a/ArcWelder/arc_welder.cpp +++ b/ArcWelder/arc_welder.cpp @@ -92,7 +92,6 @@ arc_welder::arc_welder( arcs_created_ = 0; waiting_for_arc_ = false; previous_feedrate_ = -1; - previous_is_extruder_relative_ = false; gcode_position_args_.set_num_extruders(8); for (int index = 0; index < 8; index++) { @@ -386,6 +385,7 @@ int arc_welder::process_gcode(parsed_command cmd, bool is_end, bool is_reprocess p_source_position_->update(cmd, lines_processed_, gcodes_processed_, -1); position* p_cur_pos = p_source_position_->get_current_position_ptr(); position* p_pre_pos = p_source_position_->get_previous_position_ptr(); + bool is_previous_extruder_relative = p_pre_pos->is_extruder_relative; extruder extruder_current = p_cur_pos->get_current_extruder(); extruder previous_extruder = p_pre_pos->get_current_extruder(); //std::cout << lines_processed_ << " - " << cmd.gcode << ", CurrentEAbsolute: " << cur_extruder.e <<", ExtrusionLength: " << cur_extruder.extrusion_length << ", Retraction Length: " << cur_extruder.retraction_length << ", IsExtruding: " << cur_extruder.is_extruding << ", IsRetracting: " << cur_extruder.is_retracting << ".\n"; @@ -455,7 +455,7 @@ int arc_welder::process_gcode(parsed_command cmd, bool is_end, bool is_reprocess // we can get more arcs. (previous_extruder.is_retracting && extruder_current.is_retracting) ) && - p_cur_pos->is_extruder_relative == p_pre_pos->is_extruder_relative && + p_cur_pos->is_extruder_relative == is_previous_extruder_relative && (!waiting_for_arc_ || p_pre_pos->f == p_cur_pos->f) && // might need to skip the waiting for arc check... (!waiting_for_arc_ || p_pre_pos->feature_type_tag == p_cur_pos->feature_type_tag) ) @@ -464,7 +464,6 @@ int arc_welder::process_gcode(parsed_command cmd, bool is_end, bool is_reprocess printer_point p(p_cur_pos->get_gcode_x(), p_cur_pos->get_gcode_y(), p_cur_pos->get_gcode_z(), extruder_current.e_relative, movement_length_mm); if (!waiting_for_arc_) { - previous_is_extruder_relative_ = p_pre_pos->is_extruder_relative; if (debug_logging_enabled_) { p_logger_->log(logger_type_, DEBUG, "Starting new arc from Gcode:" + cmd.gcode); @@ -581,6 +580,7 @@ int arc_welder::process_gcode(parsed_command cmd, bool is_end, bool is_reprocess } } + bool arc_generated = false; if (!arc_added && !(cmd.is_empty && cmd.comment.length() == 0)) { if (current_arc_.get_num_segments() < current_arc_.get_min_segments()) { @@ -604,10 +604,13 @@ int arc_welder::process_gcode(parsed_command cmd, bool is_end, bool is_reprocess points_compressed_ += current_arc_.get_num_segments()-1; arcs_created_++; // increment the number of generated arcs write_arc_gcodes(p_pre_pos->is_extruder_relative, p_pre_pos->f); + // Now clear the arc and flag the processor as not waiting for an arc + waiting_for_arc_ = false; + arc_generated = true; + current_arc_.clear(); p_cur_pos = NULL; p_pre_pos = NULL; - // Reprocess this line if (!is_end) { @@ -642,13 +645,16 @@ int arc_welder::process_gcode(parsed_command cmd, bool is_end, bool is_reprocess if (waiting_for_arc_ || !arc_added) { - position* cur_pos = p_source_position_->get_current_position_ptr(); - unwritten_commands_.push_back(unwritten_command(cur_pos, movement_length_mm)); + // This might not work.... + //position* cur_pos = p_source_position_->get_current_position_ptr(); + + unwritten_commands_.push_back(unwritten_command(cmd, is_previous_extruder_relative, movement_length_mm)); } - if (!waiting_for_arc_) + else if (!waiting_for_arc_) { write_unwritten_gcodes_to_file(); + current_arc_.clear(); } return lines_written; } @@ -660,9 +666,10 @@ void arc_welder::write_arc_gcodes(bool is_extruder_relative, double current_feed // remove the same number of unwritten gcodes as there are arc segments, minus 1 for the start point // Which isn't a movement // note, skip the first point, it is the starting point - for (int index = 0; index < current_arc_.get_num_segments() - 1; index++) + int num_segments = current_arc_.get_num_segments() - 1; + for (int index = 0; index < num_segments; index++) { - unwritten_commands_.pop_back(); + while (!unwritten_commands_.pop_back().is_g1_g2); } // Undo the current command, since it isn't included in the arc @@ -675,7 +682,7 @@ void arc_welder::write_arc_gcodes(bool is_extruder_relative, double current_feed // Craete the arc gcode std::string gcode; - if (previous_is_extruder_relative_) { + if (is_extruder_relative) { gcode = get_arc_gcode_relative(current_feedrate, comment); } @@ -703,9 +710,7 @@ void arc_welder::write_arc_gcodes(bool is_extruder_relative, double current_feed // now write the current arc to the file write_gcode_to_file(gcode); - // Now clear the arc and flag the processor as not waiting for an arc - waiting_for_arc_ = false; - current_arc_.clear(); + } std::string arc_welder::get_comment_for_arc() diff --git a/ArcWelder/arc_welder.h b/ArcWelder/arc_welder.h index 66b6428..6d00ec4 100644 --- a/ArcWelder/arc_welder.h +++ b/ArcWelder/arc_welder.h @@ -478,7 +478,6 @@ private: // We don't care about the printer settings, except for g91 influences extruder. gcode_position* p_source_position_; double previous_feedrate_; - bool previous_is_extruder_relative_; gcode_parser parser_; bool verbose_output_; int logger_type_; diff --git a/ArcWelder/segmented_arc.h b/ArcWelder/segmented_arc.h index c67c071..3515143 100644 --- a/ArcWelder/segmented_arc.h +++ b/ArcWelder/segmented_arc.h @@ -62,6 +62,7 @@ private: bool try_add_point_internal_(printer_point p); std::string get_shape_gcode_(bool has_e, double e, double f) const; arc current_arc_; + int num_gcode; double max_radius_mm_; int min_arc_segments_; double mm_per_arc_segment_; diff --git a/ArcWelder/segmented_shape.cpp b/ArcWelder/segmented_shape.cpp index 2a7d9b7..42aadcb 100644 --- a/ArcWelder/segmented_shape.cpp +++ b/ArcWelder/segmented_shape.cpp @@ -80,6 +80,12 @@ point point::get_midpoint(point p1, point p2) return point(x, y, z); } + +bool point::is_near_collinear(const point& p1, const point& p2, const point& p3, double tolerance) +{ + return fabs((p1.y - p2.y) * (p1.x - p3.x) - (p1.y - p3.y) * (p1.x - p2.x)) <= 1e-9; +} + #pragma endregion Point Functions #pragma region Segment Functions @@ -133,34 +139,24 @@ double vector::cross_product_magnitude(vector v1, vector v2) // Users of this code must verify correctness for their application. // dot product (3D) which allows vector operations in arguments #define dot(u,v) ((u).x * (v).x + (u).y * (v).y + (u).z * (v).z) +#define dotxy(u,v) ((u).x * (v).x + (u).y * (v).y) #define norm(v) sqrt(dot(v,v)) // norm = length of vector #define d(u,v) norm(u-v) // distance = norm of difference -double distance_from_segment(segment s, point p) -{ - vector v = s.p2 - s.p1; - vector w = p - s.p1; - - double c1 = dot(w, v); - if (c1 <= 0) - return d(p, s.p1); - - double c2 = dot(v, v); - if (c2 <= c1) - return d(p, s.p2); - - double b = c1 / c2; - point pb = s.p1 + (v * b); - return d(p, pb); -} - #pragma endregion Distance Calculation Source #pragma region Circle Functions + bool circle::try_create_circle(const point& p1, const point& p2, const point& p3, const double max_radius, circle& new_circle) { + if (point::is_near_collinear(p1,p2,p3, 0.001)) + { + return false; + } + + double x1 = p1.x; double y1 = p1.y; double x2 = p2.x; diff --git a/ArcWelder/segmented_shape.h b/ArcWelder/segmented_shape.h index 0b617ea..8b014bc 100644 --- a/ArcWelder/segmented_shape.h +++ b/ArcWelder/segmented_shape.h @@ -46,6 +46,7 @@ public: double y; double z; static point get_midpoint(point p1, point p2); + static bool is_near_collinear(const point& p1, const point& p2, const point& p3, double percent_tolerance); }; struct printer_point : point @@ -192,7 +193,6 @@ struct arc : circle double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT, bool allow_3d_arcs = DEFAULT_ALLOW_3D_ARCS); }; -double distance_from_segment(segment s, point p); #define DEFAULT_MIN_SEGMENTS 3 #define DEFAULT_MAX_SEGMENTS 50 diff --git a/ArcWelder/unwritten_command.h b/ArcWelder/unwritten_command.h index 0bfea2d..8f85a50 100644 --- a/ArcWelder/unwritten_command.h +++ b/ArcWelder/unwritten_command.h @@ -32,22 +32,27 @@ struct unwritten_command e_relative = 0; offset_e = 0; extrusion_length = 0; + is_g1_g2 = false; } unwritten_command(parsed_command &cmd, bool is_relative, double command_length) { is_extruder_relative = is_relative; + is_g1_g2 = cmd.command == "G0" || cmd.command == "G1"; gcode = cmd.gcode; comment = cmd.comment; extrusion_length = command_length; } + /* unwritten_command(position* p, double command_length) { e_relative = p->get_current_extruder().e_relative; offset_e = p->get_current_extruder().get_offset_e(); is_extruder_relative = p->is_extruder_relative; + is_g1_g2 = p->command.command == "G0" || p->command.command == "G1"; gcode = p->command.gcode; comment = p->command.comment; extrusion_length = command_length; - } + } */ + bool is_g1_g2; bool is_extruder_relative; double e_relative; double offset_e; diff --git a/ArcWelderTest/ArcWelderTest.h b/ArcWelderTest/ArcWelderTest.h index b29b2a0..db5c995 100644 --- a/ArcWelderTest/ArcWelderTest.h +++ b/ArcWelderTest/ArcWelderTest.h @@ -93,6 +93,7 @@ static std::string FIRMWARE_COMPENSATION_TEST_1 = "C:\\Users\\Brad\\Documents\\3 static std::string BENCHY_MIN_RADIUS_TEST = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\BenchyMinRadiusTest.gcode"; static std::string ISSUE_93 = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\Issues\\93\\FailingGCode.gcode"; static std::string ISSUE_99 = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\Issues\\99\\FailingGCode.gcode"; +static std::string ISSUE_134 = "C:\\Users\\Brad\\Documents\\AntiStutter\\Issues\\134\\BirdHouse [PETG] [brim]+Infill [20%,cubic]+Noz [0.6]+LH [0.2]+LW-[0.6]+Temps [240+70]+50.0mms+Support [normal (56)]+Coast-[False].gcode" ; static std::string CONE_TEST = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\ConeTest.gcode"; static std::string CONE_TEST_VASE = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\ConeTestVase.gcode"; @@ -102,6 +103,8 @@ static std::string BAD_ARC_DIRECTIONS = "C:\\Users\\Brad\\Documents\\3DPrinter\\ static std::string BAD_ARC_DIRECTIONS_2 = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\BadArcDirections2.gcode"; static std::string WIPER_TEST = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\wiper_test.gcode"; static std::string SLOW_COUPLER = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\Rob_Coupler.gcode"; +static std::string ISSUE_34 = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\spacer.gcode"; +static std::string DIFFICULT_ARCS_ISSUE_34 = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\DifficultArcs\\issue_34.gcode"; diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d4303c..60af044 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION "3.15") +cmake_minimum_required (VERSION "3.13") set(CMAKE_VERBOSE_MAKEFILE ON) if(NOT CMAKE_BUILD_TYPE) diff --git a/GcodeProcessorLib/array_list.h b/GcodeProcessorLib/array_list.h index e5aec2e..90e0cb5 100644 --- a/GcodeProcessorLib/array_list.h +++ b/GcodeProcessorLib/array_list.h @@ -64,7 +64,7 @@ public: inline int get_index_position(int index) const { - int index_position = index + front_index_ + max_size_; + int index_position = index + front_index_;// + max_size_; while (index_position >= max_size_) { index_position = index_position - max_size_; @@ -135,7 +135,7 @@ public: { throw std::exception(); } - int pos = get_index_position(count_); + int pos = get_index_position(count_-1); count_--; return items_[pos]; } diff --git a/GcodeProcessorLib/version.h b/GcodeProcessorLib/version.h index 5653329..d12d4ab 100644 --- a/GcodeProcessorLib/version.h +++ b/GcodeProcessorLib/version.h @@ -1,15 +1,15 @@ #ifndef VERSION_H -#define VERSION_H - #ifndef HAS_GENERATED_VERSION - #define GIT_BRANCH "Unknown" - #define GIT_COMMIT_HASH "Unknown" - #define GIT_TAGGED_VERSION "Unknown" - #define GIT_TAG "Unknown" - #define BUILD_DATE "Unknown" - #define COPYRIGHT_DATE "2020" - #define AUTHOR "Brad Hochgesang" + #define VERSION_H + #ifndef HAS_GENERATED_VERSION + #define VERSION_GENERATED_H + #define GIT_BRANCH "master" + #define GIT_COMMIT_HASH "11d11e4" + #define GIT_TAGGED_VERSION "1.1.0" + #define GIT_TAG "1.1.0" + #define BUILD_DATE "2021-01-24T20:44:10Z" + #define COPYRIGHT_DATE "2021" + #define AUTHOR "Brad Hochgesang" #else - #include "version.generated.h" - + #include "version.generated.h" #endif #endif \ No newline at end of file -- cgit v1.2.3