Kaynağa Gözat

🐛 Fix G33, Delta radii, reachable (#22795)

Luc Van Daele 2 yıl önce
ebeveyn
işleme
629498f8d4
No account linked to committer's email address

+ 1
- 1
Marlin/src/HAL/LPC1768/fast_pwm.cpp Dosyayı Görüntüle

@@ -26,7 +26,7 @@
26 26
 
27 27
 void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
28 28
   if (!LPC176x::pin_is_valid(pin)) return;
29
-  if (LPC176x::pwm_attach_pin(pin)) 
29
+  if (LPC176x::pwm_attach_pin(pin))
30 30
     LPC176x::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size);  // map 1-254 onto PWM range
31 31
 }
32 32
 

+ 30
- 41
Marlin/src/gcode/calibrate/G33.cpp Dosyayı Görüntüle

@@ -69,8 +69,6 @@ enum CalEnum : char {                        // the 7 main calibration points -
69 69
 
70 70
 float lcd_probe_pt(const xy_pos_t &xy);
71 71
 
72
-float dcr;
73
-
74 72
 void ac_home() {
75 73
   endstops.enable(true);
76 74
   TERN_(HAS_DELTA_SENSORLESS_PROBING, probe.set_homing_current(true));
@@ -177,7 +175,7 @@ static float std_dev_points(float z_pt[NPP + 1], const bool _0p_cal, const bool
177 175
  */
178 176
 static float calibration_probe(const xy_pos_t &xy, const bool stow, const bool probe_at_offset) {
179 177
   #if HAS_BED_PROBE
180
-    return probe.probe_at_point(xy, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, true, probe_at_offset);
178
+    return probe.probe_at_point(xy, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, probe_at_offset, false);
181 179
   #else
182 180
     UNUSED(stow);
183 181
     return lcd_probe_pt(xy);
@@ -187,7 +185,7 @@ static float calibration_probe(const xy_pos_t &xy, const bool stow, const bool p
187 185
 /**
188 186
  *  - Probe a grid
189 187
  */
190
-static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_points, const bool towers_set, const bool stow_after_each, const bool probe_at_offset) {
188
+static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_points, const float dcr, const bool towers_set, const bool stow_after_each, const bool probe_at_offset) {
191 189
   const bool _0p_calibration      = probe_points == 0,
192 190
              _1p_calibration      = probe_points == 1 || probe_points == -1,
193 191
              _4p_calibration      = probe_points == 2,
@@ -271,7 +269,7 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
271 269
  *  - formulae for approximative forward kinematics in the end-stop displacement matrix
272 270
  *  - definition of the matrix scaling parameters
273 271
  */
274
-static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_at_pt_axis[NPP + 1]) {
272
+static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_at_pt_axis[NPP + 1], const float dcr) {
275 273
   xyz_pos_t pos{0};
276 274
 
277 275
   LOOP_CAL_ALL(rad) {
@@ -283,7 +281,7 @@ static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_
283 281
   }
284 282
 }
285 283
 
286
-static void forward_kinematics_probe_points(abc_float_t mm_at_pt_axis[NPP + 1], float z_pt[NPP + 1]) {
284
+static void forward_kinematics_probe_points(abc_float_t mm_at_pt_axis[NPP + 1], float z_pt[NPP + 1], const float dcr) {
287 285
   const float r_quot = dcr / delta_radius;
288 286
 
289 287
   #define ZPP(N,I,A) (((1.0f + r_quot * (N)) / 3.0f) * mm_at_pt_axis[I].A)
@@ -302,19 +300,19 @@ static void forward_kinematics_probe_points(abc_float_t mm_at_pt_axis[NPP + 1],
302 300
   z_pt[_AB] = Zp1(_AB, a) + Zp1(_AB, b) + Zm2(_AB, c);
303 301
 }
304 302
 
305
-static void calc_kinematics_diff_probe_points(float z_pt[NPP + 1], abc_float_t delta_e, const float delta_r, abc_float_t delta_t) {
303
+static void calc_kinematics_diff_probe_points(float z_pt[NPP + 1], const float dcr, abc_float_t delta_e, const float delta_r, abc_float_t delta_t) {
306 304
   const float z_center = z_pt[CEN];
307 305
   abc_float_t diff_mm_at_pt_axis[NPP + 1], new_mm_at_pt_axis[NPP + 1];
308 306
 
309
-  reverse_kinematics_probe_points(z_pt, diff_mm_at_pt_axis);
307
+  reverse_kinematics_probe_points(z_pt, diff_mm_at_pt_axis, dcr);
310 308
 
311 309
   delta_radius += delta_r;
312 310
   delta_tower_angle_trim += delta_t;
313 311
   recalc_delta_settings();
314
-  reverse_kinematics_probe_points(z_pt, new_mm_at_pt_axis);
312
+  reverse_kinematics_probe_points(z_pt, new_mm_at_pt_axis, dcr);
315 313
 
316 314
   LOOP_CAL_ALL(rad) diff_mm_at_pt_axis[rad] -= new_mm_at_pt_axis[rad] + delta_e;
317
-  forward_kinematics_probe_points(diff_mm_at_pt_axis, z_pt);
315
+  forward_kinematics_probe_points(diff_mm_at_pt_axis, z_pt, dcr);
318 316
 
319 317
   LOOP_CAL_RAD(rad) z_pt[rad] -= z_pt[CEN] - z_center;
320 318
   z_pt[CEN] = z_center;
@@ -324,23 +322,23 @@ static void calc_kinematics_diff_probe_points(float z_pt[NPP + 1], abc_float_t d
324 322
   recalc_delta_settings();
325 323
 }
326 324
 
327
-static float auto_tune_h() {
325
+static float auto_tune_h(const float dcr) {
328 326
   const float r_quot = dcr / delta_radius;
329 327
   return RECIPROCAL(r_quot / (2.0f / 3.0f));  // (2/3)/CR
330 328
 }
331 329
 
332
-static float auto_tune_r() {
330
+static float auto_tune_r(const float dcr) {
333 331
   constexpr float diff = 0.01f, delta_r = diff;
334 332
   float r_fac = 0.0f, z_pt[NPP + 1] = { 0.0f };
335 333
   abc_float_t delta_e = { 0.0f }, delta_t = { 0.0f };
336 334
 
337
-  calc_kinematics_diff_probe_points(z_pt, delta_e, delta_r, delta_t);
335
+  calc_kinematics_diff_probe_points(z_pt, dcr, delta_e, delta_r, delta_t);
338 336
   r_fac = -(z_pt[__A] + z_pt[__B] + z_pt[__C] + z_pt[_BC] + z_pt[_CA] + z_pt[_AB]) / 6.0f;
339 337
   r_fac = diff / r_fac / 3.0f; // 1/(3*delta_Z)
340 338
   return r_fac;
341 339
 }
342 340
 
343
-static float auto_tune_a() {
341
+static float auto_tune_a(const float dcr) {
344 342
   constexpr float diff = 0.01f, delta_r = 0.0f;
345 343
   float a_fac = 0.0f, z_pt[NPP + 1] = { 0.0f };
346 344
   abc_float_t delta_e = { 0.0f }, delta_t = { 0.0f };
@@ -348,7 +346,7 @@ static float auto_tune_a() {
348 346
   delta_t.reset();
349 347
   LOOP_LINEAR_AXES(axis) {
350 348
     delta_t[axis] = diff;
351
-    calc_kinematics_diff_probe_points(z_pt, delta_e, delta_r, delta_t);
349
+    calc_kinematics_diff_probe_points(z_pt, dcr, delta_e, delta_r, delta_t);
352 350
     delta_t[axis] = 0;
353 351
     a_fac += z_pt[uint8_t((axis * _4P_STEP) - _7P_STEP + NPP) % NPP + 1] / 6.0f;
354 352
     a_fac -= z_pt[uint8_t((axis * _4P_STEP) + 1 + _7P_STEP)] / 6.0f;
@@ -370,7 +368,7 @@ static float auto_tune_a() {
370 368
  *      P3       Probe all positions: center, towers and opposite towers. Calibrate all.
371 369
  *      P4-P10   Probe all positions at different intermediate locations and average them.
372 370
  *
373
- *   Rn.nn  override default calibration Radius
371
+ *   Rn.nn  Temporary reduce the probe grid by the specified amount (mm)
374 372
  *
375 373
  *   T   Don't calibrate tower angle corrections
376 374
  *
@@ -386,7 +384,7 @@ static float auto_tune_a() {
386 384
  *
387 385
  *   E   Engage the probe for each point
388 386
  *
389
- *   O   Probe at offset points (this is wrong but it seems to work)
387
+ *   O   Probe at offsetted probe positions (this is wrong but it seems to work)
390 388
  *
391 389
  * With SENSORLESS_PROBING:
392 390
  *   Use these flags to calibrate stall sensitivity: (e.g., `G33 P1 Y Z` to calibrate X only.)
@@ -404,27 +402,17 @@ void GcodeSuite::G33() {
404 402
     return;
405 403
   }
406 404
 
407
-  const bool probe_at_offset = TERN0(HAS_PROBE_XY_OFFSET, parser.boolval('O')),
405
+  const bool probe_at_offset = TERN0(HAS_PROBE_XY_OFFSET, parser.seen_test('O')),
408 406
                   towers_set = !parser.seen_test('T');
409 407
 
410
-  float max_dcr = dcr = DELTA_PRINTABLE_RADIUS;
408
+  // The calibration radius is set to a calculated value
409
+  float dcr = probe_at_offset ? DELTA_PRINTABLE_RADIUS : DELTA_PRINTABLE_RADIUS - PROBING_MARGIN;
411 410
   #if HAS_PROBE_XY_OFFSET
412
-    // For offset probes the calibration radius is set to a safe but non-optimal value
413
-    dcr -= HYPOT(probe.offset_xy.x, probe.offset_xy.y);
414
-    if (probe_at_offset) {
415
-      // With probe positions both probe and nozzle need to be within the printable area
416
-      max_dcr = dcr;
417
-    }
418
-    // else with nozzle positions there is a risk of the probe being outside the bed
419
-    // but as long the nozzle stays within the printable area there is no risk of
420
-    // the effector crashing into the towers.
411
+    const float total_offset = HYPOT(probe.offset_xy.x, probe.offset_xy.y);
412
+    dcr -= probe_at_offset ? _MAX(total_offset, PROBING_MARGIN) : total_offset;
421 413
   #endif
422
-
423
-  if (parser.seenval('R')) dcr = parser.value_float();
424
-  if (!WITHIN(dcr, 0, max_dcr)) {
425
-    SERIAL_ECHOLNPGM("?calibration (R)adius implausible.");
426
-    return;
427
-  }
414
+  NOMORE(dcr, DELTA_PRINTABLE_RADIUS);
415
+  if (parser.seenval('R')) dcr -= _MAX(parser.value_float(),0);
428 416
 
429 417
   const float calibration_precision = parser.floatval('C', 0.0f);
430 418
   if (calibration_precision < 0) {
@@ -475,8 +463,9 @@ void GcodeSuite::G33() {
475 463
   SERIAL_ECHOLNPGM("G33 Auto Calibrate");
476 464
 
477 465
   // Report settings
478
-  FSTR_P const checkingac = F("Checking... AC");
479
-  SERIAL_ECHOF(checkingac);
466
+  PGM_P const checkingac = PSTR("Checking... AC");
467
+  SERIAL_ECHOPGM_P(checkingac);
468
+  SERIAL_ECHOPGM(" at radius:", dcr);
480 469
   if (verbose_level == 0) SERIAL_ECHOPGM(" (DRY-RUN)");
481 470
   SERIAL_EOL();
482 471
   ui.set_status(checkingac);
@@ -496,7 +485,7 @@ void GcodeSuite::G33() {
496 485
 
497 486
     // Probe the points
498 487
     zero_std_dev_old = zero_std_dev;
499
-    if (!probe_calibration_points(z_at_pt, probe_points, towers_set, stow_after_each, probe_at_offset)) {
488
+    if (!probe_calibration_points(z_at_pt, probe_points, dcr, towers_set, stow_after_each, probe_at_offset)) {
500 489
       SERIAL_ECHOLNPGM("Correct delta settings with M665 and M666");
501 490
       return ac_cleanup(TERN_(HAS_MULTI_HOTEND, old_tool_index));
502 491
     }
@@ -536,10 +525,10 @@ void GcodeSuite::G33() {
536 525
 
537 526
       // calculate factors
538 527
       if (_7p_9_center) dcr *= 0.9f;
539
-      h_factor = auto_tune_h();
540
-      r_factor = auto_tune_r();
541
-      a_factor = auto_tune_a();
542
-      dcr /= 0.9f;
528
+      h_factor = auto_tune_h(dcr);
529
+      r_factor = auto_tune_r(dcr);
530
+      a_factor = auto_tune_a(dcr);
531
+      if (_7p_9_center) dcr /= 0.9f;
543 532
 
544 533
       switch (probe_points) {
545 534
         case 0:

+ 1
- 1
Marlin/src/inc/SanityCheck.h Dosyayı Görüntüle

@@ -1635,7 +1635,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
1635 1635
   #if ENABLED(NOZZLE_AS_PROBE)
1636 1636
     static_assert(sanity_nozzle_to_probe_offset.x == 0 && sanity_nozzle_to_probe_offset.y == 0,
1637 1637
                   "NOZZLE_AS_PROBE requires the XY offsets in NOZZLE_TO_PROBE_OFFSET to both be 0.");
1638
-  #else
1638
+  #elif !IS_KINEMATIC
1639 1639
     static_assert(PROBING_MARGIN       >= 0, "PROBING_MARGIN must be >= 0.");
1640 1640
     static_assert(PROBING_MARGIN_BACK  >= 0, "PROBING_MARGIN_BACK must be >= 0.");
1641 1641
     static_assert(PROBING_MARGIN_FRONT >= 0, "PROBING_MARGIN_FRONT must be >= 0.");

+ 4
- 7
Marlin/src/module/probe.cpp Dosyayı Görüntüle

@@ -768,14 +768,11 @@ float Probe::probe_at_point(const_float_t rx, const_float_t ry, const ProbePtRai
768 768
 
769 769
   // On delta keep Z below clip height or do_blocking_move_to will abort
770 770
   xyz_pos_t npos = { rx, ry, TERN(DELTA, _MIN(delta_clip_start_height, current_position.z), current_position.z) };
771
-  if (probe_relative) {                                     // The given position is in terms of the probe
772
-    if (!can_reach(npos)) {
773
-      if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Position Not Reachable");
774
-      return NAN;
775
-    }
776
-    npos -= offset_xy;                                      // Get the nozzle position
771
+  if (!can_reach(npos, probe_relative)) {
772
+    if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Position Not Reachable");
773
+    return NAN;
777 774
   }
778
-  else if (!position_is_reachable(npos)) return NAN;        // The given position is in terms of the nozzle
775
+  if (probe_relative) npos -= offset_xy;  // Get the nozzle position
779 776
 
780 777
   // Move the probe to the starting XYZ
781 778
   do_blocking_move_to(npos, feedRate_t(XY_PROBE_FEEDRATE_MM_S));

+ 30
- 16
Marlin/src/module/probe.h Dosyayı Görüntüle

@@ -77,13 +77,20 @@ public:
77 77
       #if HAS_PROBE_XY_OFFSET
78 78
         // Return true if the both nozzle and the probe can reach the given point.
79 79
         // Note: This won't work on SCARA since the probe offset rotates with the arm.
80
-        static bool can_reach(const_float_t rx, const_float_t ry) {
81
-          return position_is_reachable(rx - offset_xy.x, ry - offset_xy.y) // The nozzle can go where it needs to go?
82
-              && position_is_reachable(rx, ry, ABS(PROBING_MARGIN));       // Can the nozzle also go near there?
80
+        static bool can_reach(const_float_t rx, const_float_t ry, const bool probe_relative=true) {
81
+          if (probe_relative) {
82
+            return position_is_reachable(rx - offset_xy.x, ry - offset_xy.y) // The nozzle can go where it needs to go?
83
+                && position_is_reachable(rx, ry, PROBING_MARGIN);            // Can the probe also go near there?
84
+          }
85
+          else {
86
+            return position_is_reachable(rx, ry)
87
+                && position_is_reachable(rx + offset_xy.x, ry + offset_xy.y, PROBING_MARGIN);
88
+          }
83 89
         }
84 90
       #else
85
-        static bool can_reach(const_float_t rx, const_float_t ry) {
86
-          return position_is_reachable(rx, ry, PROBING_MARGIN);
91
+        static bool can_reach(const_float_t rx, const_float_t ry, const bool=true) {
92
+          return position_is_reachable(rx, ry)
93
+              && position_is_reachable(rx, ry, PROBING_MARGIN);
87 94
         }
88 95
       #endif
89 96
 
@@ -96,10 +103,17 @@ public:
96 103
        * Example: For a probe offset of -10,+10, then for the probe to reach 0,0 the
97 104
        *          nozzle must be be able to reach +10,-10.
98 105
        */
99
-      static bool can_reach(const_float_t rx, const_float_t ry) {
100
-        return position_is_reachable(rx - offset_xy.x, ry - offset_xy.y)
101
-            && COORDINATE_OKAY(rx, min_x() - fslop, max_x() + fslop)
102
-            && COORDINATE_OKAY(ry, min_y() - fslop, max_y() + fslop);
106
+      static bool can_reach(const_float_t rx, const_float_t ry, const bool probe_relative=true) {
107
+        if (probe_relative) {
108
+          return position_is_reachable(rx - offset_xy.x, ry - offset_xy.y)
109
+              && COORDINATE_OKAY(rx, min_x() - fslop, max_x() + fslop)
110
+              && COORDINATE_OKAY(ry, min_y() - fslop, max_y() + fslop);
111
+        }
112
+        else {
113
+          return position_is_reachable(rx, ry)
114
+              && COORDINATE_OKAY(rx + offset_xy.x, min_x() - fslop, max_x() + fslop)
115
+              && COORDINATE_OKAY(ry + offset_xy.y, min_y() - fslop, max_y() + fslop);
116
+        }
103 117
       }
104 118
 
105 119
     #endif
@@ -120,7 +134,7 @@ public:
120 134
 
121 135
     static bool set_deployed(const bool) { return false; }
122 136
 
123
-    static bool can_reach(const_float_t rx, const_float_t ry) { return position_is_reachable(rx, ry); }
137
+    static bool can_reach(const_float_t rx, const_float_t ry, const bool=true) { return position_is_reachable(rx, ry); }
124 138
 
125 139
   #endif
126 140
 
@@ -132,7 +146,7 @@ public:
132 146
     #endif
133 147
   }
134 148
 
135
-  static bool can_reach(const xy_pos_t &pos) { return can_reach(pos.x, pos.y); }
149
+  static bool can_reach(const xy_pos_t &pos, const bool probe_relative=true) { return can_reach(pos.x, pos.y, probe_relative); }
136 150
 
137 151
   static bool good_bounds(const xy_pos_t &lf, const xy_pos_t &rb) {
138 152
     return (
@@ -161,30 +175,30 @@ public:
161 175
         TERN_(DELTA, DELTA_PRINTABLE_RADIUS)
162 176
         TERN_(IS_SCARA, SCARA_PRINTABLE_RADIUS)
163 177
       );
164
-      static constexpr float probe_radius(const xy_pos_t &probe_offset_xy = offset_xy) {
178
+      static constexpr float probe_radius(const xy_pos_t &probe_offset_xy=offset_xy) {
165 179
         return printable_radius - _MAX(PROBING_MARGIN, HYPOT(probe_offset_xy.x, probe_offset_xy.y));
166 180
       }
167 181
     #endif
168 182
 
169
-    static constexpr float _min_x(const xy_pos_t &probe_offset_xy = offset_xy) {
183
+    static constexpr float _min_x(const xy_pos_t &probe_offset_xy=offset_xy) {
170 184
       return TERN(IS_KINEMATIC,
171 185
         (X_CENTER) - probe_radius(probe_offset_xy),
172 186
         _MAX((X_MIN_BED) + (PROBING_MARGIN_LEFT), (X_MIN_POS) + probe_offset_xy.x)
173 187
       );
174 188
     }
175
-    static constexpr float _max_x(const xy_pos_t &probe_offset_xy = offset_xy) {
189
+    static constexpr float _max_x(const xy_pos_t &probe_offset_xy=offset_xy) {
176 190
       return TERN(IS_KINEMATIC,
177 191
         (X_CENTER) + probe_radius(probe_offset_xy),
178 192
         _MIN((X_MAX_BED) - (PROBING_MARGIN_RIGHT), (X_MAX_POS) + probe_offset_xy.x)
179 193
       );
180 194
     }
181
-    static constexpr float _min_y(const xy_pos_t &probe_offset_xy = offset_xy) {
195
+    static constexpr float _min_y(const xy_pos_t &probe_offset_xy=offset_xy) {
182 196
       return TERN(IS_KINEMATIC,
183 197
         (Y_CENTER) - probe_radius(probe_offset_xy),
184 198
         _MAX((Y_MIN_BED) + (PROBING_MARGIN_FRONT), (Y_MIN_POS) + probe_offset_xy.y)
185 199
       );
186 200
     }
187
-    static constexpr float _max_y(const xy_pos_t &probe_offset_xy = offset_xy) {
201
+    static constexpr float _max_y(const xy_pos_t &probe_offset_xy=offset_xy) {
188 202
       return TERN(IS_KINEMATIC,
189 203
         (Y_CENTER) + probe_radius(probe_offset_xy),
190 204
         _MIN((Y_MAX_BED) - (PROBING_MARGIN_BACK), (Y_MAX_POS) + probe_offset_xy.y)

Loading…
İptal
Kaydet