Browse Source

Use arc moves for G26 if enabled (#10696)

Co-Authored-By: ManuelMcLure <manuelmclure@users.noreply.github.com>
Scott Lahteine 7 years ago
parent
commit
6671c064cd
No account linked to committer's email address
1 changed files with 138 additions and 56 deletions
  1. 138
    56
      Marlin/src/gcode/bedlevel/G26.cpp

+ 138
- 56
Marlin/src/gcode/bedlevel/G26.cpp View File

@@ -56,6 +56,10 @@
56 56
 #define G26_OK false
57 57
 #define G26_ERR true
58 58
 
59
+#if ENABLED(ARC_SUPPORT)
60
+  void plan_arc(const float (&cart)[XYZE], const float (&offset)[2], const uint8_t clockwise);
61
+#endif
62
+
59 63
 /**
60 64
  *   G26 Mesh Validation Tool
61 65
  *
@@ -219,9 +223,9 @@ mesh_index_pair find_closest_circle_to_print(const float &X, const float &Y) {
219 223
 
220 224
 void G26_line_to_destination(const float &feed_rate) {
221 225
   const float save_feedrate = feedrate_mm_s;
222
-  feedrate_mm_s = feed_rate;      // use specified feed rate
226
+  feedrate_mm_s = feed_rate;
223 227
   prepare_move_to_destination();  // will ultimately call ubl.line_to_destination_cartesian or ubl.prepare_linear_move_to for UBL_SEGMENTED
224
-  feedrate_mm_s = save_feedrate;  // restore global feed rate
228
+  feedrate_mm_s = save_feedrate;
225 229
 }
226 230
 
227 231
 void move_to(const float &rx, const float &ry, const float &z, const float &e_delta) {
@@ -729,21 +733,25 @@ void GcodeSuite::G26() {
729 733
 
730 734
   //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern."));
731 735
 
732
-  /**
733
-   * Pre-generate radius offset values at 30 degree intervals to reduce CPU load.
734
-   */
735
-  #define A_INT 30
736
-  #define _ANGS (360 / A_INT)
737
-  #define A_CNT (_ANGS / 2)
738
-  #define _IND(A) ((A + _ANGS * 8) % _ANGS)
739
-  #define _COS(A) (trig_table[_IND(A) % A_CNT] * (_IND(A) >= A_CNT ? -1 : 1))
740
-  #define _SIN(A) (-_COS((A + A_CNT / 2) % _ANGS))
741
-  #if A_CNT & 1
742
-    #error "A_CNT must be a positive value. Please change A_INT."
743
-  #endif
744
-  float trig_table[A_CNT];
745
-  for (uint8_t i = 0; i < A_CNT; i++)
746
-    trig_table[i] = INTERSECTION_CIRCLE_RADIUS * cos(RADIANS(i * A_INT));
736
+  #if DISABLED(ARC_SUPPORT)
737
+
738
+    /**
739
+     * Pre-generate radius offset values at 30 degree intervals to reduce CPU load.
740
+     */
741
+    #define A_INT 30
742
+    #define _ANGS (360 / A_INT)
743
+    #define A_CNT (_ANGS / 2)
744
+    #define _IND(A) ((A + _ANGS * 8) % _ANGS)
745
+    #define _COS(A) (trig_table[_IND(A) % A_CNT] * (_IND(A) >= A_CNT ? -1 : 1))
746
+    #define _SIN(A) (-_COS((A + A_CNT / 2) % _ANGS))
747
+    #if A_CNT & 1
748
+      #error "A_CNT must be a positive value. Please change A_INT."
749
+    #endif
750
+    float trig_table[A_CNT];
751
+    for (uint8_t i = 0; i < A_CNT; i++)
752
+      trig_table[i] = INTERSECTION_CIRCLE_RADIUS * cos(RADIANS(i * A_INT));
753
+
754
+  #endif // !ARC_SUPPORT
747 755
 
748 756
   mesh_index_pair location;
749 757
   do {
@@ -761,54 +769,128 @@ void GcodeSuite::G26() {
761 769
       // Determine where to start and end the circle,
762 770
       // which is always drawn counter-clockwise.
763 771
       const uint8_t xi = location.x_index, yi = location.y_index;
764
-        const bool f = yi == 0, r = xi >= GRID_MAX_POINTS_X - 1, b = yi >= GRID_MAX_POINTS_Y - 1;
765
-        int8_t start_ind = -2, end_ind = 9;  // Assume a full circle (from 5:00 to 5:00)
766
-      if (xi == 0) {                     // Left edge? Just right half.
767
-        start_ind = f ? 0 : -3;          //  03:00 to 12:00 for front-left
768
-        end_ind   = b ? 0 :  2;          //  06:00 to 03:00 for back-left
769
-      }
770
-      else if (r) {                      // Right edge? Just left half.
771
-        start_ind = b ? 6 : 3;           //  12:00 to 09:00 for front-right
772
-        end_ind   = f ? 5 : 8;           //  09:00 to 06:00 for back-right
773
-      }
774
-      else if (f) {                      // Front edge? Just back half.
775
-        start_ind = 0;                   //  03:00
776
-        end_ind   = 5;                   //  09:00
777
-      }
778
-      else if (b) {                      // Back edge? Just front half.
779
-        start_ind =  6;                  //  09:00
780
-        end_ind   = 11;                  //  03:00
781
-      }
772
+      const bool f = yi == 0, r = xi >= GRID_MAX_POINTS_X - 1, b = yi >= GRID_MAX_POINTS_Y - 1;
773
+
774
+      #if ENABLED(ARC_SUPPORT)
775
+
776
+        #define ARC_LENGTH(quarters)  (INTERSECTION_CIRCLE_RADIUS * PI * (quarters) / 2)
777
+        float sx = circle_x + INTERSECTION_CIRCLE_RADIUS,   // default to full circle
778
+              ex = circle_x + INTERSECTION_CIRCLE_RADIUS,
779
+              sy = circle_y, ey = circle_y,
780
+              arc_length = ARC_LENGTH(4);
781
+
782
+        // Figure out where to start and end the arc - we always print counterclockwise
783
+        if (xi == 0) {                             // left edge
784
+          sx = f ? circle_x + INTERSECTION_CIRCLE_RADIUS : circle_x;
785
+          ex = b ? circle_x + INTERSECTION_CIRCLE_RADIUS : circle_x;
786
+          sy = f ? circle_y : circle_y - INTERSECTION_CIRCLE_RADIUS;
787
+          ey = b ? circle_y : circle_y + INTERSECTION_CIRCLE_RADIUS;
788
+          arc_length = (f || b) ? ARC_LENGTH(1) : ARC_LENGTH(2);
789
+        }
790
+        else if (r) {                             // right edge
791
+          sx = b ? circle_x - INTERSECTION_CIRCLE_RADIUS : circle_x;
792
+          ex = f ? circle_x - INTERSECTION_CIRCLE_RADIUS : circle_x;
793
+          sy = b ? circle_y : circle_y + INTERSECTION_CIRCLE_RADIUS;
794
+          ey = f ? circle_y : circle_y - INTERSECTION_CIRCLE_RADIUS;
795
+          arc_length = (f || b) ? ARC_LENGTH(1) : ARC_LENGTH(2);
796
+        }
797
+        else if (f) {
798
+          sx = circle_x + INTERSECTION_CIRCLE_RADIUS;
799
+          ex = circle_x - INTERSECTION_CIRCLE_RADIUS;
800
+          sy = ey = circle_y;
801
+          arc_length = ARC_LENGTH(2);
802
+        }
803
+        else if (b) {
804
+          sx = circle_x - INTERSECTION_CIRCLE_RADIUS;
805
+          ex = circle_x + INTERSECTION_CIRCLE_RADIUS;
806
+          sy = ey = circle_y;
807
+          arc_length = ARC_LENGTH(2);
808
+        }
809
+        const float arc_offset[2] = {
810
+          circle_x - sx,
811
+          circle_y - sy
812
+        };
813
+
814
+        const float dx_s = current_position[X_AXIS] - sx,   // find our distance from the start of the actual circle
815
+                    dy_s = current_position[Y_AXIS] - sy,
816
+                    dist_start = HYPOT2(dx_s, dy_s);
817
+        const float endpoint[XYZE] = {
818
+          ex, ey,
819
+          g26_layer_height,
820
+          current_position[E_AXIS] + (arc_length * g26_e_axis_feedrate * g26_extrusion_multiplier)
821
+        };
822
+
823
+        if (dist_start > 2.0) {
824
+          retract_filament(destination);
825
+          //todo:  parameterize the bump height with a define
826
+          move_to(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + 0.500, 0.0);  // Z bump to minimize scraping
827
+          move_to(sx, sy, g26_layer_height + 0.500, 0.0); // Get to the starting point with no extrusion while bumped
828
+        }
782 829
 
783
-      for (int8_t ind = start_ind; ind <= end_ind; ind++) {
830
+        move_to(sx, sy, g26_layer_height, 0.0); // Get to the starting point with no extrusion / un-Z bump
784 831
 
832
+        recover_filament(destination);
833
+        const float save_feedrate = feedrate_mm_s;
834
+        feedrate_mm_s = PLANNER_XY_FEEDRATE() / 10.0;
835
+        plan_arc(endpoint, arc_offset, false);  // Draw a counter-clockwise arc
836
+        feedrate_mm_s = save_feedrate;
837
+        set_destination_from_current();
785 838
         #if ENABLED(NEWPANEL)
786
-          if (user_canceled()) goto LEAVE;          // Check if the user wants to stop the Mesh Validation
839
+          if (user_canceled()) goto LEAVE; // Check if the user wants to stop the Mesh Validation
787 840
         #endif
788 841
 
789
-        float rx = circle_x + _COS(ind),            // For speed, these are now a lookup table entry
790
-              ry = circle_y + _SIN(ind),
791
-              xe = circle_x + _COS(ind + 1),
792
-              ye = circle_y + _SIN(ind + 1);
793
-
794
-        #if IS_KINEMATIC
795
-          // Check to make sure this segment is entirely on the bed, skip if not.
796
-          if (!position_is_reachable(rx, ry) || !position_is_reachable(xe, ye)) continue;
797
-        #else                                               // not, we need to skip
798
-          rx = constrain(rx, X_MIN_POS + 1, X_MAX_POS - 1); // This keeps us from bumping the endstops
799
-          ry = constrain(ry, Y_MIN_POS + 1, Y_MAX_POS - 1);
800
-          xe = constrain(xe, X_MIN_POS + 1, X_MAX_POS - 1);
801
-          ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
802
-        #endif
842
+      #else // !ARC_SUPPORT
803 843
 
844
+        int8_t start_ind = -2, end_ind = 9; // Assume a full circle (from 5:00 to 5:00)
845
+        if (xi == 0) {                      // Left edge? Just right half.
846
+          start_ind = f ? 0 : -3;           //  03:00 to 12:00 for front-left
847
+          end_ind = b ? 0 : 2;              //  06:00 to 03:00 for back-left
848
+        }
849
+        else if (r) {                       // Right edge? Just left half.
850
+          start_ind = b ? 6 : 3;            //  12:00 to 09:00 for front-right
851
+          end_ind = f ? 5 : 8;              //  09:00 to 06:00 for back-right
852
+        }
853
+        else if (f) {                       // Front edge? Just back half.
854
+          start_ind = 0;                    //  03:00
855
+          end_ind = 5;                      //  09:00
856
+        }
857
+        else if (b) {                       // Back edge? Just front half.
858
+          start_ind = 6;                    //  09:00
859
+          end_ind = 11;                     //  03:00
860
+        }
804 861
 
805
-        print_line_from_here_to_there(rx, ry, g26_layer_height, xe, ye, g26_layer_height);
806
-        SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
807
-      }
808
-      if (look_for_lines_to_connect())
809
-        goto LEAVE;
862
+        for (int8_t ind = start_ind; ind <= end_ind; ind++) {
863
+
864
+          #if ENABLED(NEWPANEL)
865
+            if (user_canceled()) goto LEAVE;          // Check if the user wants to stop the Mesh Validation
866
+          #endif
867
+
868
+          float rx = circle_x + _COS(ind),            // For speed, these are now a lookup table entry
869
+                ry = circle_y + _SIN(ind),
870
+                xe = circle_x + _COS(ind + 1),
871
+                ye = circle_y + _SIN(ind + 1);
872
+
873
+          #if IS_KINEMATIC
874
+            // Check to make sure this segment is entirely on the bed, skip if not.
875
+            if (!position_is_reachable(rx, ry) || !position_is_reachable(xe, ye)) continue;
876
+          #else                                               // not, we need to skip
877
+            rx = constrain(rx, X_MIN_POS + 1, X_MAX_POS - 1); // This keeps us from bumping the endstops
878
+            ry = constrain(ry, Y_MIN_POS + 1, Y_MAX_POS - 1);
879
+            xe = constrain(xe, X_MIN_POS + 1, X_MAX_POS - 1);
880
+            ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
881
+          #endif
882
+
883
+          print_line_from_here_to_there(rx, ry, g26_layer_height, xe, ye, g26_layer_height);
884
+          SERIAL_FLUSH();  // Prevent host M105 buffer overrun.
885
+        }
886
+
887
+      #endif // !ARC_SUPPORT
888
+
889
+      if (look_for_lines_to_connect()) goto LEAVE;
810 890
     }
891
+
811 892
     SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
893
+
812 894
   } while (--g26_repeats && location.x_index >= 0 && location.y_index >= 0);
813 895
 
814 896
   LEAVE:

Loading…
Cancel
Save