|
@@ -69,6 +69,8 @@ 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
|
+
|
72
|
74
|
void ac_home() {
|
73
|
75
|
endstops.enable(true);
|
74
|
76
|
TERN_(SENSORLESS_HOMING, probe.set_homing_current(true));
|
|
@@ -175,9 +177,9 @@ static float std_dev_points(float z_pt[NPP + 1], const bool _0p_cal, const bool
|
175
|
177
|
/**
|
176
|
178
|
* - Probe a point
|
177
|
179
|
*/
|
178
|
|
-static float calibration_probe(const xy_pos_t &xy, const bool stow) {
|
|
180
|
+static float calibration_probe(const xy_pos_t &xy, const bool stow, const bool probe_at_offset) {
|
179
|
181
|
#if HAS_BED_PROBE
|
180
|
|
- return probe.probe_at_point(xy, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, true, false);
|
|
182
|
+ return probe.probe_at_point(xy, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, true, probe_at_offset);
|
181
|
183
|
#else
|
182
|
184
|
UNUSED(stow);
|
183
|
185
|
return lcd_probe_pt(xy);
|
|
@@ -187,7 +189,7 @@ static float calibration_probe(const xy_pos_t &xy, const bool stow) {
|
187
|
189
|
/**
|
188
|
190
|
* - Probe a grid
|
189
|
191
|
*/
|
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) {
|
|
192
|
+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) {
|
191
|
193
|
const bool _0p_calibration = probe_points == 0,
|
192
|
194
|
_1p_calibration = probe_points == 1 || probe_points == -1,
|
193
|
195
|
_4p_calibration = probe_points == 2,
|
|
@@ -209,11 +211,9 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
|
209
|
211
|
|
210
|
212
|
if (!_0p_calibration) {
|
211
|
213
|
|
212
|
|
- const float dcr = delta_calibration_radius();
|
213
|
|
-
|
214
|
214
|
if (!_7p_no_intermediates && !_7p_4_intermediates && !_7p_11_intermediates) { // probe the center
|
215
|
215
|
const xy_pos_t center{0};
|
216
|
|
- z_pt[CEN] += calibration_probe(center, stow_after_each);
|
|
216
|
+ z_pt[CEN] += calibration_probe(center, stow_after_each, probe_at_offset);
|
217
|
217
|
if (isnan(z_pt[CEN])) return false;
|
218
|
218
|
}
|
219
|
219
|
|
|
@@ -224,7 +224,7 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
|
224
|
224
|
const float a = RADIANS(210 + (360 / NPP) * (rad - 1)),
|
225
|
225
|
r = dcr * 0.1;
|
226
|
226
|
const xy_pos_t vec = { cos(a), sin(a) };
|
227
|
|
- z_pt[CEN] += calibration_probe(vec * r, stow_after_each);
|
|
227
|
+ z_pt[CEN] += calibration_probe(vec * r, stow_after_each, probe_at_offset);
|
228
|
228
|
if (isnan(z_pt[CEN])) return false;
|
229
|
229
|
}
|
230
|
230
|
z_pt[CEN] /= float(_7p_2_intermediates ? 7 : probe_points);
|
|
@@ -249,7 +249,7 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
|
249
|
249
|
r = dcr * (1 - 0.1 * (zig_zag ? offset - circle : circle)),
|
250
|
250
|
interpol = FMOD(rad, 1);
|
251
|
251
|
const xy_pos_t vec = { cos(a), sin(a) };
|
252
|
|
- const float z_temp = calibration_probe(vec * r, stow_after_each);
|
|
252
|
+ const float z_temp = calibration_probe(vec * r, stow_after_each, probe_at_offset);
|
253
|
253
|
if (isnan(z_temp)) return false;
|
254
|
254
|
// split probe point to neighbouring calibration points
|
255
|
255
|
z_pt[uint8_t(LROUND(rad - interpol + NPP - 1)) % NPP + 1] += z_temp * sq(cos(RADIANS(interpol * 90)));
|
|
@@ -276,7 +276,6 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
|
276
|
276
|
static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_at_pt_axis[NPP + 1]) {
|
277
|
277
|
xyz_pos_t pos{0};
|
278
|
278
|
|
279
|
|
- const float dcr = delta_calibration_radius();
|
280
|
279
|
LOOP_CAL_ALL(rad) {
|
281
|
280
|
const float a = RADIANS(210 + (360 / NPP) * (rad - 1)),
|
282
|
281
|
r = (rad == CEN ? 0.0f : dcr);
|
|
@@ -287,7 +286,7 @@ static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_
|
287
|
286
|
}
|
288
|
287
|
|
289
|
288
|
static void forward_kinematics_probe_points(abc_float_t mm_at_pt_axis[NPP + 1], float z_pt[NPP + 1]) {
|
290
|
|
- const float r_quot = delta_calibration_radius() / delta_radius;
|
|
289
|
+ const float r_quot = dcr / delta_radius;
|
291
|
290
|
|
292
|
291
|
#define ZPP(N,I,A) (((1.0f + r_quot * (N)) / 3.0f) * mm_at_pt_axis[I].A)
|
293
|
292
|
#define Z00(I, A) ZPP( 0, I, A)
|
|
@@ -328,7 +327,7 @@ static void calc_kinematics_diff_probe_points(float z_pt[NPP + 1], abc_float_t d
|
328
|
327
|
}
|
329
|
328
|
|
330
|
329
|
static float auto_tune_h() {
|
331
|
|
- const float r_quot = delta_calibration_radius() / delta_radius;
|
|
330
|
+ const float r_quot = dcr / delta_radius;
|
332
|
331
|
return RECIPROCAL(r_quot / (2.0f / 3.0f)); // (2/3)/CR
|
333
|
332
|
}
|
334
|
333
|
|
|
@@ -373,6 +372,8 @@ static float auto_tune_a() {
|
373
|
372
|
* P3 Probe all positions: center, towers and opposite towers. Calibrate all.
|
374
|
373
|
* P4-P10 Probe all positions at different intermediate locations and average them.
|
375
|
374
|
*
|
|
375
|
+ * Rn.nn override default calibration Radius
|
|
376
|
+ *
|
376
|
377
|
* T Don't calibrate tower angle corrections
|
377
|
378
|
*
|
378
|
379
|
* Cn.nn Calibration precision; when omitted calibrates to maximum precision
|
|
@@ -387,6 +388,8 @@ static float auto_tune_a() {
|
387
|
388
|
*
|
388
|
389
|
* E Engage the probe for each point
|
389
|
390
|
*
|
|
391
|
+ * O Probe at offset points (this is wrong but it seems to work)
|
|
392
|
+ *
|
390
|
393
|
* With SENSORLESS_PROBING:
|
391
|
394
|
* Use these flags to calibrate stall sensitivity: (e.g., `G33 P1 Y Z` to calibrate X only.)
|
392
|
395
|
* X Don't activate stallguard on X.
|
|
@@ -403,7 +406,27 @@ void GcodeSuite::G33() {
|
403
|
406
|
return;
|
404
|
407
|
}
|
405
|
408
|
|
406
|
|
- const bool towers_set = !parser.seen_test('T');
|
|
409
|
+ const bool probe_at_offset = TERN0(HAS_PROBE_XY_OFFSET, parser.boolval('O')),
|
|
410
|
+ towers_set = !parser.seen_test('T');
|
|
411
|
+
|
|
412
|
+ float max_dcr = dcr = DELTA_PRINTABLE_RADIUS;
|
|
413
|
+ #if HAS_PROBE_XY_OFFSET
|
|
414
|
+ // For offset probes the calibration radius is set to a safe but non-optimal value
|
|
415
|
+ dcr -= HYPOT(probe.offset_xy.x, probe.offset_xy.y);
|
|
416
|
+ if (probe_at_offset) {
|
|
417
|
+ // With probe positions both probe and nozzle need to be within the printable area
|
|
418
|
+ max_dcr = dcr;
|
|
419
|
+ }
|
|
420
|
+ // else with nozzle positions there is a risk of the probe being outside the bed
|
|
421
|
+ // but as long the nozzle stays within the printable area there is no risk of
|
|
422
|
+ // the effector crashing into the towers.
|
|
423
|
+ #endif
|
|
424
|
+
|
|
425
|
+ if (parser.seenval('R')) dcr = parser.value_float();
|
|
426
|
+ if (!WITHIN(dcr, 0, max_dcr)) {
|
|
427
|
+ SERIAL_ECHOLNPGM("?calibration (R)adius implausible.");
|
|
428
|
+ return;
|
|
429
|
+ }
|
407
|
430
|
|
408
|
431
|
const float calibration_precision = parser.floatval('C', 0.0f);
|
409
|
432
|
if (calibration_precision < 0) {
|
|
@@ -453,18 +476,6 @@ void GcodeSuite::G33() {
|
453
|
476
|
|
454
|
477
|
SERIAL_ECHOLNPGM("G33 Auto Calibrate");
|
455
|
478
|
|
456
|
|
- const float dcr = delta_calibration_radius();
|
457
|
|
-
|
458
|
|
- if (!_1p_calibration && !_0p_calibration) { // test if the outer radius is reachable
|
459
|
|
- LOOP_CAL_RAD(axis) {
|
460
|
|
- const float a = RADIANS(210 + (360 / NPP) * (axis - 1));
|
461
|
|
- if (!position_is_reachable(cos(a) * dcr, sin(a) * dcr)) {
|
462
|
|
- SERIAL_ECHOLNPGM("?Bed calibration radius implausible.");
|
463
|
|
- return;
|
464
|
|
- }
|
465
|
|
- }
|
466
|
|
- }
|
467
|
|
-
|
468
|
479
|
// Report settings
|
469
|
480
|
PGM_P const checkingac = PSTR("Checking... AC");
|
470
|
481
|
SERIAL_ECHOPGM_P(checkingac);
|
|
@@ -487,7 +498,7 @@ void GcodeSuite::G33() {
|
487
|
498
|
|
488
|
499
|
// Probe the points
|
489
|
500
|
zero_std_dev_old = zero_std_dev;
|
490
|
|
- if (!probe_calibration_points(z_at_pt, probe_points, towers_set, stow_after_each)) {
|
|
501
|
+ if (!probe_calibration_points(z_at_pt, probe_points, towers_set, stow_after_each, probe_at_offset)) {
|
491
|
502
|
SERIAL_ECHOLNPGM("Correct delta settings with M665 and M666");
|
492
|
503
|
return ac_cleanup(TERN_(HAS_MULTI_HOTEND, old_tool_index));
|
493
|
504
|
}
|
|
@@ -526,11 +537,11 @@ void GcodeSuite::G33() {
|
526
|
537
|
#define Z0(I) ZP(0, I)
|
527
|
538
|
|
528
|
539
|
// calculate factors
|
529
|
|
- if (_7p_9_center) calibration_radius_factor = 0.9f;
|
|
540
|
+ if (_7p_9_center) dcr *= 0.9f;
|
530
|
541
|
h_factor = auto_tune_h();
|
531
|
542
|
r_factor = auto_tune_r();
|
532
|
543
|
a_factor = auto_tune_a();
|
533
|
|
- calibration_radius_factor = 1.0f;
|
|
544
|
+ dcr /= 0.9f;
|
534
|
545
|
|
535
|
546
|
switch (probe_points) {
|
536
|
547
|
case 0:
|