|
@@ -30,6 +30,8 @@
|
30
|
30
|
#include "../../module/planner.h"
|
31
|
31
|
#include "../../module/tool_change.h"
|
32
|
32
|
#include "../../module/endstops.h"
|
|
33
|
+#include "../../feature/bedlevel/bedlevel.h"
|
|
34
|
+
|
33
|
35
|
|
34
|
36
|
/**
|
35
|
37
|
* G425 backs away from the calibration object by various distances
|
|
@@ -60,8 +62,9 @@
|
60
|
62
|
enum side_t : uint8_t { TOP, RIGHT, FRONT, LEFT, BACK, NUM_SIDES };
|
61
|
63
|
|
62
|
64
|
struct measurements_t {
|
63
|
|
- static const float dimensions[XYZ];
|
64
|
|
- static const float true_center[XYZ]; // This cannot be constexpr since it is accessed by index in probe_side
|
|
65
|
+ static constexpr float dimensions[XYZ] = CALIBRATION_OBJECT_DIMENSIONS;
|
|
66
|
+ static constexpr float true_center[XYZ] = CALIBRATION_OBJECT_CENTER;
|
|
67
|
+
|
65
|
68
|
float obj_center[XYZ] = CALIBRATION_OBJECT_CENTER;
|
66
|
69
|
float obj_side[NUM_SIDES];
|
67
|
70
|
|
|
@@ -71,16 +74,13 @@ struct measurements_t {
|
71
|
74
|
float nozzle_outer_dimension[2] = {CALIBRATION_NOZZLE_OUTER_DIAMETER, CALIBRATION_NOZZLE_OUTER_DIAMETER};
|
72
|
75
|
};
|
73
|
76
|
|
74
|
|
-const float measurements_t::true_center[XYZ] = CALIBRATION_OBJECT_CENTER;
|
75
|
|
-
|
76
|
|
-const float measurements_t::dimensions[] = CALIBRATION_OBJECT_DIMENSIONS;
|
77
|
|
-
|
78
|
|
-#define TEMPORARY_ENDSTOP_STATE(enable) REMEMBER(tes, soft_endstops_enabled, enable); TemporaryGlobalEndstopsState tges(enable)
|
|
77
|
+#define TEMPORARY_BED_LEVELING_STATE(enable) TemporaryBedLevelingState tbls(enable)
|
|
78
|
+#define TEMPORARY_SOFT_ENDSTOP_STATE(enable) REMEMBER(tes, soft_endstops_enabled, enable);
|
79
|
79
|
|
80
|
80
|
#if ENABLED(BACKLASH_GCODE)
|
81
|
|
- #define TEMPORARY_BACKLASH_STATE(enable) REMEMBER(tbst, backlash_correction, enable)
|
|
81
|
+ #define TEMPORARY_BACKLASH_CORRECTION(value) REMEMBER(tbst, backlash_correction, value)
|
82
|
82
|
#else
|
83
|
|
- #define TEMPORARY_BACKLASH_STATE(enable)
|
|
83
|
+ #define TEMPORARY_BACKLASH_CORRECTION(value)
|
84
|
84
|
#endif
|
85
|
85
|
|
86
|
86
|
#if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
|
|
@@ -90,6 +90,20 @@ const float measurements_t::dimensions[] = CALIBRATION_OBJECT_DIMENSIONS;
|
90
|
90
|
#endif
|
91
|
91
|
|
92
|
92
|
/**
|
|
93
|
+ * A class to save and change the bed leveling state,
|
|
94
|
+ * then restore it when it goes out of scope.
|
|
95
|
+ */
|
|
96
|
+class TemporaryBedLevelingState {
|
|
97
|
+ bool saved;
|
|
98
|
+
|
|
99
|
+ public:
|
|
100
|
+ TemporaryBedLevelingState(const bool enable) : saved(planner.leveling_active) {
|
|
101
|
+ set_bed_leveling_enabled(enable);
|
|
102
|
+ }
|
|
103
|
+ ~TemporaryBedLevelingState() { set_bed_leveling_enabled(saved); }
|
|
104
|
+};
|
|
105
|
+
|
|
106
|
+/**
|
93
|
107
|
* Move to a particular location. Up to three individual axes
|
94
|
108
|
* and their destinations can be specified, in any order.
|
95
|
109
|
*/
|
|
@@ -121,10 +135,10 @@ inline void move_to(
|
121
|
135
|
* uncertainty in - How far away from the object top to park
|
122
|
136
|
*/
|
123
|
137
|
inline void park_above_object(measurements_t &m, const float uncertainty) {
|
124
|
|
- /* Move to safe distance above calibration object */
|
|
138
|
+ // Move to safe distance above calibration object
|
125
|
139
|
move_to(Z_AXIS, m.obj_center[Z_AXIS] + m.dimensions[Z_AXIS] / 2 + uncertainty);
|
126
|
140
|
|
127
|
|
- /* Move to center of calibration object in XY */
|
|
141
|
+ // Move to center of calibration object in XY
|
128
|
142
|
move_to(X_AXIS, m.obj_center[X_AXIS], Y_AXIS, m.obj_center[Y_AXIS]);
|
129
|
143
|
}
|
130
|
144
|
|
|
@@ -228,6 +242,7 @@ inline float measure(const AxisEnum axis, const int dir, const bool stop_state,
|
228
|
242
|
* to find out height of edge
|
229
|
243
|
*/
|
230
|
244
|
inline void probe_side(measurements_t &m, const float uncertainty, const side_t side, const bool probe_top_at_edge=false) {
|
|
245
|
+ const float dimensions[] = CALIBRATION_OBJECT_DIMENSIONS;
|
231
|
246
|
AxisEnum axis;
|
232
|
247
|
float dir;
|
233
|
248
|
|
|
@@ -236,7 +251,7 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
|
236
|
251
|
switch(side) {
|
237
|
252
|
case TOP: {
|
238
|
253
|
const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty);
|
239
|
|
- m.obj_center[Z_AXIS] = measurement - m.dimensions[Z_AXIS] / 2;
|
|
254
|
+ m.obj_center[Z_AXIS] = measurement - dimensions[Z_AXIS] / 2;
|
240
|
255
|
m.obj_side[TOP] = measurement;
|
241
|
256
|
return;
|
242
|
257
|
}
|
|
@@ -250,18 +265,18 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
|
250
|
265
|
|
251
|
266
|
if (probe_top_at_edge) {
|
252
|
267
|
// Probe top nearest the side we are probing
|
253
|
|
- move_to(axis, m.obj_center[axis] + (-dir) * (m.dimensions[axis] / 2 - m.nozzle_outer_dimension[axis]));
|
|
268
|
+ move_to(axis, m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 - m.nozzle_outer_dimension[axis]));
|
254
|
269
|
m.obj_side[TOP] = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty);
|
255
|
|
- m.obj_center[Z_AXIS] = m.obj_side[TOP] - m.dimensions[Z_AXIS] / 2;
|
|
270
|
+ m.obj_center[Z_AXIS] = m.obj_side[TOP] - dimensions[Z_AXIS] / 2;
|
256
|
271
|
}
|
257
|
272
|
|
258
|
273
|
// Move to safe distance to the side of the calibration object
|
259
|
|
- move_to(axis, m.obj_center[axis] + (-dir) * (m.dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2 + uncertainty));
|
|
274
|
+ move_to(axis, m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2 + uncertainty));
|
260
|
275
|
|
261
|
276
|
// Plunge below the side of the calibration object and measure
|
262
|
277
|
move_to(Z_AXIS, m.obj_side[TOP] - CALIBRATION_NOZZLE_TIP_HEIGHT * 0.7);
|
263
|
278
|
const float measurement = measure(axis, dir, true, &m.backlash[side], uncertainty);
|
264
|
|
- m.obj_center[axis] = measurement + dir * (m.dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2);
|
|
279
|
+ m.obj_center[axis] = measurement + dir * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2);
|
265
|
280
|
m.obj_side[side] = measurement;
|
266
|
281
|
}
|
267
|
282
|
|
|
@@ -272,14 +287,11 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
|
272
|
287
|
* uncertainty in - How far away from the calibration object to begin probing
|
273
|
288
|
*/
|
274
|
289
|
inline void probe_sides(measurements_t &m, const float uncertainty) {
|
275
|
|
- TEMPORARY_ENDSTOP_STATE(false);
|
276
|
|
-
|
277
|
290
|
#ifdef CALIBRATION_MEASURE_AT_TOP_EDGES
|
278
|
291
|
constexpr bool probe_top_at_edge = true;
|
279
|
292
|
#else
|
280
|
|
- /* Probing at the exact center only works if the center is flat. Probing on a washer
|
281
|
|
- * or bolt will require probing the top near the side edges, away from the center.
|
282
|
|
- */
|
|
293
|
+ // Probing at the exact center only works if the center is flat. Probing on a washer
|
|
294
|
+ // or bolt will require probing the top near the side edges, away from the center.
|
283
|
295
|
constexpr bool probe_top_at_edge = false;
|
284
|
296
|
probe_side(m, uncertainty, TOP);
|
285
|
297
|
#endif
|
|
@@ -287,9 +299,11 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
287
|
299
|
#ifdef CALIBRATION_MEASURE_RIGHT
|
288
|
300
|
probe_side(m, uncertainty, RIGHT, probe_top_at_edge);
|
289
|
301
|
#endif
|
|
302
|
+
|
290
|
303
|
#ifdef CALIBRATION_MEASURE_FRONT
|
291
|
304
|
probe_side(m, uncertainty, FRONT, probe_top_at_edge);
|
292
|
305
|
#endif
|
|
306
|
+
|
293
|
307
|
#ifdef CALIBRATION_MEASURE_LEFT
|
294
|
308
|
probe_side(m, uncertainty, LEFT, probe_top_at_edge);
|
295
|
309
|
#endif
|
|
@@ -297,7 +311,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
297
|
311
|
probe_side(m, uncertainty, BACK, probe_top_at_edge);
|
298
|
312
|
#endif
|
299
|
313
|
|
300
|
|
- /* Compute the measured center of the calibration object. */
|
|
314
|
+ // Compute the measured center of the calibration object.
|
301
|
315
|
#if HAS_X_CENTER
|
302
|
316
|
m.obj_center[X_AXIS] = (m.obj_side[LEFT] + m.obj_side[RIGHT]) / 2;
|
303
|
317
|
#endif
|
|
@@ -305,8 +319,8 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
305
|
319
|
m.obj_center[Y_AXIS] = (m.obj_side[FRONT] + m.obj_side[BACK]) / 2;
|
306
|
320
|
#endif
|
307
|
321
|
|
308
|
|
- /* Compute the outside diameter of the nozzle at the height
|
309
|
|
- * at which it makes contact with the calibration object */
|
|
322
|
+ // Compute the outside diameter of the nozzle at the height
|
|
323
|
+ // at which it makes contact with the calibration object
|
310
|
324
|
#if HAS_X_CENTER
|
311
|
325
|
m.nozzle_outer_dimension[X_AXIS] = m.obj_side[RIGHT] - m.obj_side[LEFT] - m.dimensions[X_AXIS];
|
312
|
326
|
#endif
|
|
@@ -316,8 +330,8 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
316
|
330
|
|
317
|
331
|
park_above_object(m, uncertainty);
|
318
|
332
|
|
319
|
|
- /* The positional error is the difference between the known calibration
|
320
|
|
- * object location and the measured calibration object location */
|
|
333
|
+ // The difference between the known and the measured location
|
|
334
|
+ // of the calibration object is the positional error
|
321
|
335
|
m.pos_error[X_AXIS] =
|
322
|
336
|
#if HAS_X_CENTER
|
323
|
337
|
m.true_center[X_AXIS] - m.obj_center[X_AXIS];
|
|
@@ -434,9 +448,9 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
|
434
|
448
|
// Backlash compensation should be off while measuring backlash
|
435
|
449
|
|
436
|
450
|
{
|
437
|
|
- // New scope for TEMPORARY_BACKLASH_STATE
|
438
|
|
- TEMPORARY_BACKLASH_STATE(false);
|
439
|
|
- TEMPORARY_BACKLASH_SMOOTHING(0);
|
|
451
|
+ // New scope for TEMPORARY_BACKLASH_CORRECTION
|
|
452
|
+ TEMPORARY_BACKLASH_CORRECTION(0.0f);
|
|
453
|
+ TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
440
|
454
|
|
441
|
455
|
probe_sides(m, uncertainty);
|
442
|
456
|
|
|
@@ -466,9 +480,9 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
|
466
|
480
|
// directions to take up any backlash
|
467
|
481
|
|
468
|
482
|
{
|
469
|
|
- // New scope for TEMPORARY_BACKLASH_STATE
|
470
|
|
- TEMPORARY_BACKLASH_STATE(true);
|
471
|
|
- TEMPORARY_BACKLASH_SMOOTHING(0);
|
|
483
|
+ // New scope for TEMPORARY_BACKLASH_CORRECTION
|
|
484
|
+ TEMPORARY_BACKLASH_CORRECTION(1.0f);
|
|
485
|
+ TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
472
|
486
|
move_to(
|
473
|
487
|
X_AXIS, current_position[X_AXIS] + 3,
|
474
|
488
|
Y_AXIS, current_position[Y_AXIS] + 3,
|
|
@@ -484,8 +498,9 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
|
484
|
498
|
}
|
485
|
499
|
|
486
|
500
|
inline void update_measurements(measurements_t &m, const AxisEnum axis) {
|
|
501
|
+ const float true_center[XYZ] = CALIBRATION_OBJECT_CENTER;
|
487
|
502
|
current_position[axis] += m.pos_error[axis];
|
488
|
|
- m.obj_center[axis] = m.true_center[axis];
|
|
503
|
+ m.obj_center[axis] = true_center[axis];
|
489
|
504
|
m.pos_error[axis] = 0;
|
490
|
505
|
}
|
491
|
506
|
|
|
@@ -501,8 +516,8 @@ inline void update_measurements(measurements_t &m, const AxisEnum axis) {
|
501
|
516
|
* - Call calibrate_backlash() beforehand for best accuracy
|
502
|
517
|
*/
|
503
|
518
|
inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const uint8_t extruder) {
|
504
|
|
- TEMPORARY_BACKLASH_STATE(true);
|
505
|
|
- TEMPORARY_BACKLASH_SMOOTHING(0);
|
|
519
|
+ TEMPORARY_BACKLASH_CORRECTION(1.0f);
|
|
520
|
+ TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
506
|
521
|
|
507
|
522
|
#if HOTENDS > 1
|
508
|
523
|
set_nozzle(m, extruder);
|
|
@@ -510,7 +525,7 @@ inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const
|
510
|
525
|
|
511
|
526
|
probe_sides(m, uncertainty);
|
512
|
527
|
|
513
|
|
- /* Adjust the hotend offset */
|
|
528
|
+ // Adjust the hotend offset
|
514
|
529
|
#if HOTENDS > 1
|
515
|
530
|
#if HAS_X_CENTER
|
516
|
531
|
hotend_offset[X_AXIS][extruder] += m.pos_error[X_AXIS];
|
|
@@ -545,8 +560,8 @@ inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const
|
545
|
560
|
* uncertainty in - How far away from the object to begin probing
|
546
|
561
|
*/
|
547
|
562
|
inline void calibrate_all_toolheads(measurements_t &m, const float uncertainty) {
|
548
|
|
- TEMPORARY_BACKLASH_STATE(true);
|
549
|
|
- TEMPORARY_BACKLASH_SMOOTHING(0);
|
|
563
|
+ TEMPORARY_BACKLASH_CORRECTION(1.0f);
|
|
564
|
+ TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
550
|
565
|
|
551
|
566
|
HOTEND_LOOP() calibrate_toolhead(m, uncertainty, e);
|
552
|
567
|
|
|
@@ -574,23 +589,22 @@ inline void calibrate_all() {
|
574
|
589
|
reset_nozzle_offsets();
|
575
|
590
|
#endif
|
576
|
591
|
|
577
|
|
- TEMPORARY_BACKLASH_STATE(true);
|
578
|
|
- TEMPORARY_BACKLASH_SMOOTHING(0);
|
579
|
|
-
|
|
592
|
+ TEMPORARY_BACKLASH_CORRECTION(1.0f);
|
|
593
|
+ TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
580
|
594
|
|
581
|
|
- /* Do a fast and rough calibration of the toolheads */
|
|
595
|
+ // Do a fast and rough calibration of the toolheads
|
582
|
596
|
calibrate_all_toolheads(m, CALIBRATION_MEASUREMENT_UNKNOWN);
|
583
|
597
|
|
584
|
598
|
#if ENABLED(BACKLASH_GCODE)
|
585
|
599
|
calibrate_backlash(m, CALIBRATION_MEASUREMENT_UNCERTAIN);
|
586
|
600
|
#endif
|
587
|
601
|
|
588
|
|
- /* Cycle the toolheads so the servos settle into their "natural" positions */
|
|
602
|
+ // Cycle the toolheads so the servos settle into their "natural" positions
|
589
|
603
|
#if HOTENDS > 1
|
590
|
604
|
HOTEND_LOOP() set_nozzle(m, e);
|
591
|
605
|
#endif
|
592
|
606
|
|
593
|
|
- /* Do a slow and precise calibration of the toolheads */
|
|
607
|
+ // Do a slow and precise calibration of the toolheads
|
594
|
608
|
calibrate_all_toolheads(m, CALIBRATION_MEASUREMENT_UNCERTAIN);
|
595
|
609
|
|
596
|
610
|
move_to(X_AXIS, 150); // Park nozzle away from calibration object
|
|
@@ -607,6 +621,9 @@ inline void calibrate_all() {
|
607
|
621
|
* no args - Perform entire calibration sequence (backlash + position on all toolheads)
|
608
|
622
|
*/
|
609
|
623
|
void GcodeSuite::G425() {
|
|
624
|
+ TEMPORARY_SOFT_ENDSTOP_STATE(false);
|
|
625
|
+ TEMPORARY_BED_LEVELING_STATE(false);
|
|
626
|
+
|
610
|
627
|
if (axis_unhomed_error()) return;
|
611
|
628
|
|
612
|
629
|
measurements_t m;
|