Browse Source

Merge pull request #9439 from thinkyhead/bf2_fix_G26_circle_bumps

[2.0.x] Change G26 circle angles
Scott Lahteine 7 years ago
parent
commit
03bfc0d7c8
No account linked to committer's email address
1 changed files with 46 additions and 71 deletions
  1. 46
    71
      Marlin/src/gcode/bedlevel/G26.cpp

+ 46
- 71
Marlin/src/gcode/bedlevel/G26.cpp View File

46
 #define PRIME_LENGTH 10.0
46
 #define PRIME_LENGTH 10.0
47
 #define OOZE_AMOUNT 0.3
47
 #define OOZE_AMOUNT 0.3
48
 
48
 
49
-#define SIZE_OF_INTERSECTION_CIRCLES 5
50
-#define SIZE_OF_CROSSHAIRS 3
49
+#define INTERSECTION_CIRCLE_RADIUS 5
50
+#define CROSSHAIRS_SIZE 3
51
 
51
 
52
-#if SIZE_OF_CROSSHAIRS >= SIZE_OF_INTERSECTION_CIRCLES
53
-  #error "SIZE_OF_CROSSHAIRS must be less than SIZE_OF_INTERSECTION_CIRCLES."
52
+#if CROSSHAIRS_SIZE >= INTERSECTION_CIRCLE_RADIUS
53
+  #error "CROSSHAIRS_SIZE must be less than INTERSECTION_CIRCLE_RADIUS."
54
 #endif
54
 #endif
55
 
55
 
56
 #define G26_OK false
56
 #define G26_OK false
305
 
305
 
306
   // If the end point of the line is closer to the nozzle, flip the direction,
306
   // If the end point of the line is closer to the nozzle, flip the direction,
307
   // moving from the end to the start. On very small lines the optimization isn't worth it.
307
   // moving from the end to the start. On very small lines the optimization isn't worth it.
308
-  if (dist_end < dist_start && (SIZE_OF_INTERSECTION_CIRCLES) < FABS(line_length))
308
+  if (dist_end < dist_start && (INTERSECTION_CIRCLE_RADIUS) < FABS(line_length))
309
     return print_line_from_here_to_there(ex, ey, ez, sx, sy, sz);
309
     return print_line_from_here_to_there(ex, ey, ez, sx, sy, sz);
310
 
310
 
311
   // Decide whether to retract & bump
311
   // Decide whether to retract & bump
345
             // We found two circles that need a horizontal line to connect them
345
             // We found two circles that need a horizontal line to connect them
346
             // Print it!
346
             // Print it!
347
             //
347
             //
348
-            sx = _GET_MESH_X(  i  ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // right edge
349
-            ex = _GET_MESH_X(i + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // left edge
348
+            sx = _GET_MESH_X(  i  ) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // right edge
349
+            ex = _GET_MESH_X(i + 1) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // left edge
350
 
350
 
351
             sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1);
351
             sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1);
352
             sy = ey = constrain(_GET_MESH_Y(j), Y_MIN_POS + 1, Y_MAX_POS - 1);
352
             sy = ey = constrain(_GET_MESH_Y(j), Y_MIN_POS + 1, Y_MAX_POS - 1);
378
               // We found two circles that need a vertical line to connect them
378
               // We found two circles that need a vertical line to connect them
379
               // Print it!
379
               // Print it!
380
               //
380
               //
381
-              sy = _GET_MESH_Y(  j  ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // top edge
382
-              ey = _GET_MESH_Y(j + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // bottom edge
381
+              sy = _GET_MESH_Y(  j  ) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // top edge
382
+              ey = _GET_MESH_Y(j + 1) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // bottom edge
383
 
383
 
384
               sx = ex = constrain(_GET_MESH_X(i), X_MIN_POS + 1, X_MAX_POS - 1);
384
               sx = ex = constrain(_GET_MESH_X(i), X_MIN_POS + 1, X_MAX_POS - 1);
385
               sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1);
385
               sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1);
550
  */
550
  */
551
 void GcodeSuite::G26() {
551
 void GcodeSuite::G26() {
552
   SERIAL_ECHOLNPGM("G26 command started. Waiting for heater(s).");
552
   SERIAL_ECHOLNPGM("G26 command started. Waiting for heater(s).");
553
-  float tmp, start_angle, end_angle;
554
-  int   i, xi, yi;
555
-  mesh_index_pair location;
556
 
553
 
557
   // Don't allow Mesh Validation without homing first,
554
   // Don't allow Mesh Validation without homing first,
558
   // or if the parameter parsing did not go OK, abort
555
   // or if the parameter parsing did not go OK, abort
686
   set_bed_leveling_enabled(!parser.seen('D'));
683
   set_bed_leveling_enabled(!parser.seen('D'));
687
 
684
 
688
   if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) {
685
   if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) {
689
-//  SERIAL_PROTOCOLLNPGM("! move nozzle to Z_CLEARANCE_BETWEEN_PROBES height.");
690
-//  SERIAL_ECHOLNPAIR("  Z at:", current_position[Z_AXIS]);
691
     do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
686
     do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
692
     stepper.synchronize();
687
     stepper.synchronize();
693
     set_current_from_destination();
688
     set_current_from_destination();
694
-//  SERIAL_ECHOLNPAIR("  Z now at:", current_position[Z_AXIS]);
695
   }
689
   }
696
 
690
 
697
   if (turn_on_heaters() != G26_OK) goto LEAVE;
691
   if (turn_on_heaters() != G26_OK) goto LEAVE;
699
   current_position[E_AXIS] = 0.0;
693
   current_position[E_AXIS] = 0.0;
700
   sync_plan_position_e();
694
   sync_plan_position_e();
701
 
695
 
702
-  if (g26_prime_flag && prime_nozzle()) goto LEAVE;
696
+  if (g26_prime_flag && prime_nozzle() != G26_OK) goto LEAVE;
703
 
697
 
704
   /**
698
   /**
705
    *  Bed is preheated
699
    *  Bed is preheated
717
 
711
 
718
   // Move nozzle to the specified height for the first layer
712
   // Move nozzle to the specified height for the first layer
719
   set_destination_from_current();
713
   set_destination_from_current();
720
-//SERIAL_PROTOCOLLNPGM("! moving nozzle to 1st layer height.");
721
-//SERIAL_ECHOLNPAIR("  Z1 at:", current_position[Z_AXIS]);
722
-
723
   destination[Z_AXIS] = g26_layer_height;
714
   destination[Z_AXIS] = g26_layer_height;
724
   move_to(destination, 0.0);
715
   move_to(destination, 0.0);
725
-//stepper.synchronize();
726
-//set_destination_from_current();
727
-//SERIAL_ECHOLNPAIR("  Z2 at:", current_position[Z_AXIS]);
728
   move_to(destination, g26_ooze_amount);
716
   move_to(destination, g26_ooze_amount);
729
 
717
 
730
   #if ENABLED(ULTRA_LCD)
718
   #if ENABLED(ULTRA_LCD)
734
   //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern."));
722
   //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern."));
735
 
723
 
736
   /**
724
   /**
737
-   * Declare and generate a sin() & cos() table to be used during the circle drawing. This will lighten
738
-   * the CPU load and make the arc drawing faster and more smooth
725
+   * Pre-generate radius offset values at 30 degree intervals to reduce CPU load.
726
+   * All angles are offset by 15 degrees to allow for a smaller table.
739
    */
727
    */
740
-  float sin_table[360 / 30 + 1], cos_table[360 / 30 + 1];
741
-  for (i = 0; i <= 360 / 30; i++) {
742
-    cos_table[i] = SIZE_OF_INTERSECTION_CIRCLES * cos(RADIANS(valid_trig_angle(i * 30.0)));
743
-    sin_table[i] = SIZE_OF_INTERSECTION_CIRCLES * sin(RADIANS(valid_trig_angle(i * 30.0)));
744
-  }
728
+  #define A_CNT ((360 / 30) / 2)
729
+  #define _COS(A) (trig_table[((N + A_CNT * 8) % A_CNT)] * (A >= A_CNT ? -1 : 1))
730
+  #define _SIN(A) (-_COS((A + A_CNT / 2) % (A_CNT * 2)))
731
+  float trig_table[A_CNT];
732
+  for (uint8_t i = 0; i < A_CNT; i++)
733
+    trig_table[i] = INTERSECTION_CIRCLE_RADIUS * cos(RADIANS(i * 30 + 15));
745
 
734
 
746
   do {
735
   do {
747
-    location = g26_continue_with_closest
736
+    const mesh_index_pair location = g26_continue_with_closest
748
       ? find_closest_circle_to_print(current_position[X_AXIS], current_position[Y_AXIS])
737
       ? find_closest_circle_to_print(current_position[X_AXIS], current_position[Y_AXIS])
749
       : find_closest_circle_to_print(g26_x_pos, g26_y_pos); // Find the closest Mesh Intersection to where we are now.
738
       : find_closest_circle_to_print(g26_x_pos, g26_y_pos); // Find the closest Mesh Intersection to where we are now.
750
 
739
 
753
                   circle_y = _GET_MESH_Y(location.y_index);
742
                   circle_y = _GET_MESH_Y(location.y_index);
754
 
743
 
755
       // If this mesh location is outside the printable_radius, skip it.
744
       // If this mesh location is outside the printable_radius, skip it.
756
-
757
       if (!position_is_reachable(circle_x, circle_y)) continue;
745
       if (!position_is_reachable(circle_x, circle_y)) continue;
758
 
746
 
759
-      xi = location.x_index;  // Just to shrink the next few lines and make them easier to understand
760
-      yi = location.y_index;
761
-
747
+      // Determine where to start and end the circle,
748
+      // which is always drawn counter-clockwise.
749
+      const uint8_t xi = location.x_index, yi = location.y_index;
750
+      const bool f = yi == 0, r = xi == GRID_MAX_POINTS_X - 1, b = yi == GRID_MAX_POINTS_Y - 1;
751
+      int8_t start_ind = -2, end_ind = 10;  // Assume a full circle (from 4:30 to 4:30)
752
+      if (xi == 0) {                        // Left edge? Just right half.
753
+        start_ind = f ?  0 : -3;            // 05:30 (02:30 for front-left)
754
+        end_ind   = b ? -1 :  2;            // 12:30 (03:30 for back-left)
755
+      }
756
+      else if (r) {                         // Right edge? Just left half.
757
+        start_ind = f ? 5 : 3;              // 11:30 (09:30 for front-right)
758
+        end_ind   = b ? 6 : 8;              // 06:30 (08:30 for back-right)
759
+      }
760
+      else if (f) {                         // Front edge? Just back half.
761
+        start_ind = 0;                      // 02:30
762
+        end_ind   = 5;                      // 09:30
763
+      }
764
+      else if (b) {                         // Back edge? Just front half.
765
+        start_ind =  6;                     // 08:30
766
+        end_ind   = 11;                     // 03:30
767
+      }
762
       if (g26_debug_flag) {
768
       if (g26_debug_flag) {
763
         SERIAL_ECHOPAIR("   Doing circle at: (xi=", xi);
769
         SERIAL_ECHOPAIR("   Doing circle at: (xi=", xi);
764
         SERIAL_ECHOPAIR(", yi=", yi);
770
         SERIAL_ECHOPAIR(", yi=", yi);
766
         SERIAL_EOL();
772
         SERIAL_EOL();
767
       }
773
       }
768
 
774
 
769
-      start_angle = 0.0;    // assume it is going to be a full circle
770
-      end_angle   = 360.0;
771
-      if (xi == 0) {       // Check for bottom edge
772
-        start_angle = -90.0;
773
-        end_angle   =  90.0;
774
-        if (yi == 0)        // it is an edge, check for the two left corners
775
-          start_angle = 0.0;
776
-        else if (yi == GRID_MAX_POINTS_Y - 1)
777
-          end_angle = 0.0;
778
-      }
779
-      else if (xi == GRID_MAX_POINTS_X - 1) { // Check for top edge
780
-        start_angle =  90.0;
781
-        end_angle   = 270.0;
782
-        if (yi == 0)                  // it is an edge, check for the two right corners
783
-          end_angle = 180.0;
784
-        else if (yi == GRID_MAX_POINTS_Y - 1)
785
-          start_angle = 180.0;
786
-      }
787
-      else if (yi == 0) {
788
-        start_angle =   0.0;         // only do the top   side of the cirlce
789
-        end_angle   = 180.0;
790
-      }
791
-      else if (yi == GRID_MAX_POINTS_Y - 1) {
792
-        start_angle = 180.0;         // only do the bottom side of the cirlce
793
-        end_angle   = 360.0;
794
-      }
795
-
796
-      for (tmp = start_angle; tmp < end_angle - 0.1; tmp += 30.0) {
775
+      for (int8_t ind = start_ind; ind < end_ind; ind++) {
797
 
776
 
798
         #if ENABLED(NEWPANEL)
777
         #if ENABLED(NEWPANEL)
799
-          if (user_canceled()) goto LEAVE;              // Check if the user wants to stop the Mesh Validation
778
+          if (user_canceled()) goto LEAVE;          // Check if the user wants to stop the Mesh Validation
800
         #endif
779
         #endif
801
 
780
 
802
-        int tmp_div_30 = tmp / 30.0;
803
-        if (tmp_div_30 < 0) tmp_div_30 += 360 / 30;
804
-        if (tmp_div_30 > 11) tmp_div_30 -= 360 / 30;
781
+        float rx = circle_x + _COS(ind),            // For speed, these are now a lookup table entry
782
+              ry = circle_y + _SIN(ind),
783
+              xe = circle_x + _COS(ind + 1),
784
+              ye = circle_y + _SIN(ind + 1);
805
 
785
 
806
-        float rx = circle_x + cos_table[tmp_div_30],    // for speed, these are now a lookup table entry
807
-              ry = circle_y + sin_table[tmp_div_30],
808
-              xe = circle_x + cos_table[tmp_div_30 + 1],
809
-              ye = circle_y + sin_table[tmp_div_30 + 1];
810
         #if IS_KINEMATIC
786
         #if IS_KINEMATIC
811
           // Check to make sure this segment is entirely on the bed, skip if not.
787
           // Check to make sure this segment is entirely on the bed, skip if not.
812
           if (!position_is_reachable(rx, ry) || !position_is_reachable(xe, ye)) continue;
788
           if (!position_is_reachable(rx, ry) || !position_is_reachable(xe, ye)) continue;
832
         MYSERIAL0.flush(); // G26 takes a long time to complete.   PronterFace can
808
         MYSERIAL0.flush(); // G26 takes a long time to complete.   PronterFace can
833
                            // over run the serial character buffer with M105's without
809
                            // over run the serial character buffer with M105's without
834
                            // this fix
810
                            // this fix
835
-
836
       }
811
       }
837
       if (look_for_lines_to_connect())
812
       if (look_for_lines_to_connect())
838
         goto LEAVE;
813
         goto LEAVE;

Loading…
Cancel
Save