Преглед изворни кода

Merge pull request #3069 from thinkyhead/rc_delta_compat_m48

Delta-compatible extensions to M48
Scott Lahteine пре 8 година
родитељ
комит
7bf5d117e7
2 измењених фајлова са 138 додато и 118 уклоњено
  1. 138
    114
      Marlin/Marlin_main.cpp
  2. 0
    4
      Marlin/SanityCheck.h

+ 138
- 114
Marlin/Marlin_main.cpp Прегледај датотеку

@@ -1805,6 +1805,11 @@ static void setup_for_endstop_move() {
1805 1805
 
1806 1806
 #endif // AUTO_BED_LEVELING_FEATURE
1807 1807
 
1808
+static void unknown_position_error() {
1809
+  LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
1810
+  SERIAL_ECHO_START;
1811
+  SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN);
1812
+}
1808 1813
 
1809 1814
 #if ENABLED(Z_PROBE_SLED)
1810 1815
 
@@ -1826,9 +1831,7 @@ static void setup_for_endstop_move() {
1826 1831
       }
1827 1832
     #endif
1828 1833
     if (!axis_known_position[X_AXIS] || !axis_known_position[Y_AXIS]) {
1829
-      LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
1830
-      SERIAL_ECHO_START;
1831
-      SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN);
1834
+      unknown_position_error();
1832 1835
       return;
1833 1836
     }
1834 1837
 
@@ -2578,9 +2581,7 @@ inline void gcode_G28() {
2578 2581
               }
2579 2582
             }
2580 2583
             else {
2581
-              LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
2582
-              SERIAL_ECHO_START;
2583
-              SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN);
2584
+              unknown_position_error();
2584 2585
             }
2585 2586
 
2586 2587
           } // !home_all_axes && homeZ
@@ -2851,9 +2852,7 @@ inline void gcode_G28() {
2851 2852
 
2852 2853
     // Don't allow auto-leveling without homing first
2853 2854
     if (!axis_known_position[X_AXIS] || !axis_known_position[Y_AXIS]) {
2854
-      LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
2855
-      SERIAL_ECHO_START;
2856
-      SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN);
2855
+      unknown_position_error();
2857 2856
       return;
2858 2857
     }
2859 2858
 
@@ -3639,6 +3638,7 @@ inline void gcode_M42() {
3639 3638
    *     V = Verbose level (0-4, default=1)
3640 3639
    *     E = Engage Z probe for each reading
3641 3640
    *     L = Number of legs of movement before probe
3641
+   *     S = Schizoid (Or Star if you prefer)
3642 3642
    *
3643 3643
    * This function assumes the bed has been homed.  Specifically, that a G28 command
3644 3644
    * as been issued prior to invoking the M48 Z probe repeatability measurement function.
@@ -3647,8 +3647,13 @@ inline void gcode_M42() {
3647 3647
    */
3648 3648
   inline void gcode_M48() {
3649 3649
 
3650
+    if (!axis_known_position[X_AXIS] || !axis_known_position[Y_AXIS] || !axis_known_position[Z_AXIS]) {
3651
+      unknown_position_error();
3652
+      return;
3653
+    }
3654
+
3650 3655
     double sum = 0.0, mean = 0.0, sigma = 0.0, sample_set[50];
3651
-    uint8_t verbose_level = 1, n_samples = 10, n_legs = 0;
3656
+    uint8_t verbose_level = 1, n_samples = 10, n_legs = 0, schizoid_flag = 0;
3652 3657
 
3653 3658
     if (code_seen('V')) {
3654 3659
       verbose_level = code_value_short();
@@ -3669,50 +3674,57 @@ inline void gcode_M42() {
3669 3674
       }
3670 3675
     }
3671 3676
 
3672
-    double X_current = st_get_axis_position_mm(X_AXIS),
3673
-           Y_current = st_get_axis_position_mm(Y_AXIS),
3674
-           Z_current = st_get_axis_position_mm(Z_AXIS),
3675
-           E_current = st_get_axis_position_mm(E_AXIS),
3676
-           X_probe_location = X_current, Y_probe_location = Y_current,
3677
+    float  X_current = current_position[X_AXIS],
3678
+           Y_current = current_position[Y_AXIS],
3679
+           Z_current = current_position[Z_AXIS],
3680
+           X_probe_location = X_current + X_PROBE_OFFSET_FROM_EXTRUDER,
3681
+           Y_probe_location = Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER,
3677 3682
            Z_start_location = Z_current + Z_RAISE_BEFORE_PROBING;
3678
-
3679 3683
     bool deploy_probe_for_each_reading = code_seen('E');
3680 3684
 
3681 3685
     if (code_seen('X')) {
3682
-      X_probe_location = code_value() - (X_PROBE_OFFSET_FROM_EXTRUDER);
3683
-      if (X_probe_location < X_MIN_POS || X_probe_location > X_MAX_POS) {
3684
-        out_of_range_error(PSTR("X"));
3685
-        return;
3686
-      }
3686
+      X_probe_location = code_value();
3687
+      #if DISABLED(DELTA)
3688
+        if (X_probe_location < MIN_PROBE_X || X_probe_location > MAX_PROBE_X) {
3689
+          out_of_range_error(PSTR("X"));
3690
+          return;
3691
+        }
3692
+      #endif
3687 3693
     }
3688 3694
 
3689 3695
     if (code_seen('Y')) {
3690
-      Y_probe_location = code_value() -  Y_PROBE_OFFSET_FROM_EXTRUDER;
3691
-      if (Y_probe_location < Y_MIN_POS || Y_probe_location > Y_MAX_POS) {
3692
-        out_of_range_error(PSTR("Y"));
3696
+      Y_probe_location = code_value();
3697
+      #if DISABLED(DELTA)
3698
+        if (Y_probe_location < MIN_PROBE_Y || Y_probe_location > MAX_PROBE_Y) {
3699
+          out_of_range_error(PSTR("Y"));
3700
+          return;
3701
+        }
3702
+      #endif
3703
+    }
3704
+
3705
+    #if ENABLED(DELTA)
3706
+      if (sqrt(X_probe_location * X_probe_location + Y_probe_location * Y_probe_location) > DELTA_PROBEABLE_RADIUS) {
3707
+        SERIAL_PROTOCOLPGM("? (X,Y) location outside of probeable radius.\n");
3693 3708
         return;
3694 3709
       }
3695
-    }
3710
+    #endif
3711
+
3712
+    bool seen_L = code_seen('L');
3696 3713
 
3697
-    if (code_seen('L')) {
3714
+    if (seen_L) {
3698 3715
       n_legs = code_value_short();
3699
-      if (n_legs == 1) n_legs = 2;
3700 3716
       if (n_legs < 0 || n_legs > 15) {
3701 3717
         SERIAL_PROTOCOLPGM("?Number of legs in movement not plausible (0-15).\n");
3702 3718
         return;
3703 3719
       }
3720
+      if (n_legs == 1) n_legs = 2;
3704 3721
     }
3705 3722
 
3706
-    //
3707
-    // Do all the preliminary setup work.   First raise the Z probe.
3708
-    //
3709
-
3710
-    st_synchronize();
3711
-    plan_bed_level_matrix.set_to_identity();
3712
-    plan_buffer_line(X_current, Y_current, Z_start_location, E_current, homing_feedrate[Z_AXIS] / 60, active_extruder);
3713
-    st_synchronize();
3723
+    if (code_seen('S')) {
3724
+      schizoid_flag++;
3725
+      if (!seen_L) n_legs = 7;
3726
+    }
3714 3727
 
3715
-    //
3716 3728
     // Now get everything to the specified probe point So we can safely do a probe to
3717 3729
     // get us close to the bed.  If the Z-Axis is far from the bed, we don't want to
3718 3730
     // use that as a starting point for each probe.
@@ -3720,90 +3732,112 @@ inline void gcode_M42() {
3720 3732
     if (verbose_level > 2)
3721 3733
       SERIAL_PROTOCOLPGM("Positioning the probe...\n");
3722 3734
 
3723
-    plan_buffer_line(X_probe_location, Y_probe_location, Z_start_location,
3724
-                     E_current,
3725
-                     homing_feedrate[X_AXIS] / 60,
3726
-                     active_extruder);
3727
-    st_synchronize();
3735
+    #if ENABLED(DELTA)
3736
+      reset_bed_level();    // we don't do bed level correction in M48 because we want the raw data when we probe
3737
+    #else
3738
+      plan_bed_level_matrix.set_to_identity();  // we don't do bed level correction in M48 because we wantthe raw data when we probe
3739
+    #endif
3740
+
3741
+    if (Z_start_location < Z_RAISE_BEFORE_PROBING * 2.0)
3742
+      do_blocking_move_to_z(Z_start_location);
3728 3743
 
3729
-    current_position[X_AXIS] = X_current = st_get_axis_position_mm(X_AXIS);
3730
-    current_position[Y_AXIS] = Y_current = st_get_axis_position_mm(Y_AXIS);
3731
-    current_position[Z_AXIS] = Z_current = st_get_axis_position_mm(Z_AXIS);
3732
-    current_position[E_AXIS] = E_current = st_get_axis_position_mm(E_AXIS);
3744
+    do_blocking_move_to_xy(X_probe_location - X_PROBE_OFFSET_FROM_EXTRUDER, Y_probe_location - Y_PROBE_OFFSET_FROM_EXTRUDER);
3733 3745
 
3734 3746
     //
3735 3747
     // OK, do the initial probe to get us close to the bed.
3736 3748
     // Then retrace the right amount and use that in subsequent probes
3737 3749
     //
3738
-
3739
-    deploy_z_probe();
3740
-
3741 3750
     setup_for_endstop_move();
3742
-    run_z_probe();
3743
-
3744
-    Z_current = current_position[Z_AXIS] = st_get_axis_position_mm(Z_AXIS);
3745
-    Z_start_location = Z_current + Z_RAISE_BEFORE_PROBING;
3746 3751
 
3747
-    plan_buffer_line(X_probe_location, Y_probe_location, Z_start_location,
3748
-                     E_current,
3749
-                     homing_feedrate[X_AXIS] / 60,
3750
-                     active_extruder);
3751
-    st_synchronize();
3752
-    Z_current = current_position[Z_AXIS] = st_get_axis_position_mm(Z_AXIS);
3752
+    probe_pt(X_probe_location, Y_probe_location, Z_RAISE_BEFORE_PROBING,
3753
+      deploy_probe_for_each_reading ? ProbeDeployAndStow : ProbeDeploy,
3754
+      verbose_level);
3753 3755
 
3754
-    if (deploy_probe_for_each_reading) stow_z_probe();
3756
+    raise_z_after_probing();
3755 3757
 
3756 3758
     for (uint8_t n = 0; n < n_samples; n++) {
3757
-      // Make sure we are at the probe location
3758
-      do_blocking_move_to(X_probe_location, Y_probe_location, Z_start_location); // this also updates current_position
3759
-
3759
+      randomSeed(millis());
3760
+      delay(500);
3760 3761
       if (n_legs) {
3761
-        millis_t ms = millis();
3762
-        double radius = ms % ((X_MAX_LENGTH) / 4),       // limit how far out to go
3763
-               theta = RADIANS(ms % 360L);
3764
-        float dir = (ms & 0x0001) ? 1 : -1;            // clockwise or counter clockwise
3762
+        float radius, angle = random(0.0, 360.0);
3763
+        int dir = (random(0, 10) > 5.0) ? -1 : 1;  // clockwise or counter clockwise
3765 3764
 
3766
-        //SERIAL_ECHOPAIR("starting radius: ",radius);
3767
-        //SERIAL_ECHOPAIR("   theta: ",theta);
3768
-        //SERIAL_ECHOPAIR("   direction: ",dir);
3769
-        //SERIAL_EOL;
3765
+        radius = random(
3766
+          #if ENABLED(DELTA)
3767
+            DELTA_PROBEABLE_RADIUS / 8, DELTA_PROBEABLE_RADIUS / 3
3768
+          #else
3769
+            5, X_MAX_LENGTH / 8
3770
+          #endif
3771
+        );
3772
+
3773
+        if (verbose_level > 3) {
3774
+          SERIAL_ECHOPAIR("Starting radius: ", radius);
3775
+          SERIAL_ECHOPAIR("   angle: ", angle);
3776
+          delay(100);
3777
+          if (dir > 0)
3778
+            SERIAL_ECHO(" Direction: Counter Clockwise \n");
3779
+          else
3780
+            SERIAL_ECHO(" Direction: Clockwise \n");
3781
+          delay(100);
3782
+        }
3770 3783
 
3771 3784
         for (uint8_t l = 0; l < n_legs - 1; l++) {
3772
-          ms = millis();
3773
-          theta += RADIANS(dir * (ms % 20L));
3774
-          radius += (ms % 10L) - 5L;
3775
-          if (radius < 0.0) radius = -radius;
3776
-
3777
-          X_current = X_probe_location + cos(theta) * radius;
3778
-          X_current = constrain(X_current, X_MIN_POS, X_MAX_POS);
3779
-          Y_current = Y_probe_location + sin(theta) * radius;
3780
-          Y_current = constrain(Y_current, Y_MIN_POS, Y_MAX_POS);
3781
-
3785
+          double delta_angle;
3786
+          if (schizoid_flag)
3787
+            delta_angle = dir * 2.0 * 72.0;   // The points of a 5 point star are 72 degrees apart.  We need to
3788
+          // skip a point and go to the next one on the star.
3789
+          else
3790
+            delta_angle = dir * (float) random(25, 45);   // If we do this line, we are just trying to move further
3791
+          // around the circle.
3792
+          angle += delta_angle;
3793
+          while (angle > 360.0)   // We probably do not need to keep the angle between 0 and 2*PI, but the
3794
+            angle -= 360.0;       // Arduino documentation says the trig functions should not be given values
3795
+          while (angle < 0.0)     // outside of this range.   It looks like they behave correctly with
3796
+            angle += 360.0;       // numbers outside of the range, but just to be safe we clamp them.
3797
+          X_current = X_probe_location - X_PROBE_OFFSET_FROM_EXTRUDER + cos(RADIANS(angle)) * radius;
3798
+          Y_current = Y_probe_location - Y_PROBE_OFFSET_FROM_EXTRUDER + sin(RADIANS(angle)) * radius;
3799
+          #if DISABLED(DELTA)
3800
+            X_current = constrain(X_current, X_MIN_POS, X_MAX_POS);
3801
+            Y_current = constrain(Y_current, Y_MIN_POS, Y_MAX_POS);
3802
+          #else
3803
+            // If we have gone out too far, we can do a simple fix and scale the numbers
3804
+            // back in closer to the origin.
3805
+            while (sqrt(X_current * X_current + Y_current * Y_current) > DELTA_PROBEABLE_RADIUS) {
3806
+              X_current /= 1.25;
3807
+              Y_current /= 1.25;
3808
+              if (verbose_level > 3) {
3809
+                SERIAL_ECHOPAIR("Pulling point towards center:", X_current);
3810
+                SERIAL_ECHOPAIR(", ", Y_current);
3811
+                SERIAL_EOL;
3812
+                delay(50);
3813
+              }
3814
+            }
3815
+          #endif
3782 3816
           if (verbose_level > 3) {
3817
+            SERIAL_PROTOCOL("Going to:");
3783 3818
             SERIAL_ECHOPAIR("x: ", X_current);
3784 3819
             SERIAL_ECHOPAIR("y: ", Y_current);
3820
+            SERIAL_ECHOPAIR("  z: ", current_position[Z_AXIS]);
3785 3821
             SERIAL_EOL;
3822
+            delay(55);
3786 3823
           }
3787
-
3788
-          do_blocking_move_to(X_current, Y_current, Z_current); // this also updates current_position
3789
-
3824
+          do_blocking_move_to_xy(X_current, Y_current);
3790 3825
         } // n_legs loop
3791
-
3792
-        // Go back to the probe location
3793
-        do_blocking_move_to(X_probe_location, Y_probe_location, Z_start_location); // this also updates current_position
3794
-
3795 3826
       } // n_legs
3796 3827
 
3797
-      if (deploy_probe_for_each_reading)  {
3798
-        deploy_z_probe();
3799
-        delay(1000);
3828
+      // We don't really have to do this move, but if we don't we can see a funny shift in the Z Height
3829
+      // Because the user might not have the Z_RAISE_BEFORE_PROBING height identical to the
3830
+      // Z_RAISE_BETWEEN_PROBING height.  This gets us back to the probe location at the same height that
3831
+      // we have been running around the circle at.
3832
+      do_blocking_move_to_xy(X_probe_location - X_PROBE_OFFSET_FROM_EXTRUDER, Y_probe_location - Y_PROBE_OFFSET_FROM_EXTRUDER);
3833
+      if (deploy_probe_for_each_reading)
3834
+        sample_set[n] = probe_pt(X_probe_location, Y_probe_location, Z_RAISE_BEFORE_PROBING, ProbeDeployAndStow, verbose_level);
3835
+      else {
3836
+        if (n == n_samples - 1)
3837
+          sample_set[n] = probe_pt(X_probe_location, Y_probe_location, Z_RAISE_BEFORE_PROBING, ProbeStow, verbose_level); else
3838
+          sample_set[n] = probe_pt(X_probe_location, Y_probe_location, Z_RAISE_BEFORE_PROBING, ProbeStay, verbose_level);
3800 3839
       }
3801 3840
 
3802
-      setup_for_endstop_move();
3803
-      run_z_probe();
3804
-
3805
-      sample_set[n] = current_position[Z_AXIS];
3806
-
3807 3841
       //
3808 3842
       // Get the current mean for the data points we have so far
3809 3843
       //
@@ -3821,13 +3855,13 @@ inline void gcode_M42() {
3821 3855
         sum += ss * ss;
3822 3856
       }
3823 3857
       sigma = sqrt(sum / (n + 1));
3824
-
3825 3858
       if (verbose_level > 1) {
3826 3859
         SERIAL_PROTOCOL(n + 1);
3827 3860
         SERIAL_PROTOCOLPGM(" of ");
3828 3861
         SERIAL_PROTOCOL((int)n_samples);
3829 3862
         SERIAL_PROTOCOLPGM("   z: ");
3830 3863
         SERIAL_PROTOCOL_F(current_position[Z_AXIS], 6);
3864
+        delay(50);
3831 3865
         if (verbose_level > 2) {
3832 3866
           SERIAL_PROTOCOLPGM(" mean: ");
3833 3867
           SERIAL_PROTOCOL_F(mean, 6);
@@ -3835,36 +3869,26 @@ inline void gcode_M42() {
3835 3869
           SERIAL_PROTOCOL_F(sigma, 6);
3836 3870
         }
3837 3871
       }
3838
-
3839 3872
       if (verbose_level > 0) SERIAL_EOL;
3873
+      delay(50);
3874
+      do_blocking_move_to_z(current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS);
3875
+    }  // End of probe loop code
3840 3876
 
3841
-      plan_buffer_line(X_probe_location, Y_probe_location, Z_start_location, current_position[E_AXIS], homing_feedrate[Z_AXIS] / 60, active_extruder);
3842
-      st_synchronize();
3843
-
3844
-      // Stow between
3845
-      if (deploy_probe_for_each_reading) {
3846
-        stow_z_probe();
3847
-        delay(1000);
3848
-      }
3849
-    }
3850
-
3851
-    // Stow after
3852
-    if (!deploy_probe_for_each_reading) {
3853
-      stow_z_probe();
3854
-      delay(1000);
3855
-    }
3856
-
3857
-    clean_up_after_endstop_move();
3877
+    // raise_z_after_probing();
3858 3878
 
3859 3879
     if (verbose_level > 0) {
3860 3880
       SERIAL_PROTOCOLPGM("Mean: ");
3861 3881
       SERIAL_PROTOCOL_F(mean, 6);
3862 3882
       SERIAL_EOL;
3883
+      delay(25);
3863 3884
     }
3864 3885
 
3865 3886
     SERIAL_PROTOCOLPGM("Standard Deviation: ");
3866 3887
     SERIAL_PROTOCOL_F(sigma, 6);
3867 3888
     SERIAL_EOL; SERIAL_EOL;
3889
+    delay(25);
3890
+
3891
+    clean_up_after_endstop_move();
3868 3892
   }
3869 3893
 
3870 3894
 #endif // AUTO_BED_LEVELING_FEATURE && Z_MIN_PROBE_REPEATABILITY_TEST

+ 0
- 4
Marlin/SanityCheck.h Прегледај датотеку

@@ -231,10 +231,6 @@
231 231
       #error You cannot use Z_PROBE_SLED with DELTA.
232 232
     #endif
233 233
 
234
-    #if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST)
235
-      #error Z_MIN_PROBE_REPEATABILITY_TEST is not supported with DELTA yet.
236
-    #endif
237
-
238 234
   #endif
239 235
 
240 236
 #endif

Loading…
Откажи
Сачувај