|
@@ -24,6 +24,8 @@
|
24
|
24
|
|
25
|
25
|
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
|
26
|
26
|
|
|
27
|
+#include "../../feature/z_stepper_align.h"
|
|
28
|
+
|
27
|
29
|
#include "../gcode.h"
|
28
|
30
|
#include "../../module/planner.h"
|
29
|
31
|
#include "../../module/stepper.h"
|
|
@@ -45,68 +47,6 @@
|
45
|
47
|
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
|
46
|
48
|
#include "../../core/debug_out.h"
|
47
|
49
|
|
48
|
|
-//
|
49
|
|
-// Sanity check G34 / M422 settings
|
50
|
|
-//
|
51
|
|
-constexpr xy_pos_t test_z_stepper_align_xy[] = Z_STEPPER_ALIGN_XY;
|
52
|
|
-
|
53
|
|
-#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
54
|
|
-
|
55
|
|
- static_assert(COUNT(test_z_stepper_align_xy) >= NUM_Z_STEPPER_DRIVERS,
|
56
|
|
- "Z_STEPPER_ALIGN_XY requires at least three {X,Y} entries (Z, Z2, Z3, ...)."
|
57
|
|
- );
|
58
|
|
-
|
59
|
|
- constexpr float test_z_stepper_align_stepper_xy[][XY] = Z_STEPPER_ALIGN_STEPPER_XY;
|
60
|
|
- static_assert(
|
61
|
|
- COUNT(test_z_stepper_align_stepper_xy) == NUM_Z_STEPPER_DRIVERS,
|
62
|
|
- "Z_STEPPER_ALIGN_STEPPER_XY requires three {X,Y} entries (one per Z stepper)."
|
63
|
|
- );
|
64
|
|
-
|
65
|
|
-#else
|
66
|
|
-
|
67
|
|
- static_assert(COUNT(test_z_stepper_align_xy) == NUM_Z_STEPPER_DRIVERS,
|
68
|
|
- #if NUM_Z_STEPPER_DRIVERS == 4
|
69
|
|
- "Z_STEPPER_ALIGN_XY requires four {X,Y} entries (Z, Z2, Z3, and Z4)."
|
70
|
|
- #elif NUM_Z_STEPPER_DRIVERS == 3
|
71
|
|
- "Z_STEPPER_ALIGN_XY requires three {X,Y} entries (Z, Z2, and Z3)."
|
72
|
|
- #else
|
73
|
|
- "Z_STEPPER_ALIGN_XY requires two {X,Y} entries (Z and Z2)."
|
74
|
|
- #endif
|
75
|
|
- );
|
76
|
|
-
|
77
|
|
-#endif
|
78
|
|
-
|
79
|
|
-constexpr xyz_pos_t dpo = NOZZLE_TO_PROBE_OFFSET;
|
80
|
|
-
|
81
|
|
-#define LTEST(N) (test_z_stepper_align_xy[N].x >= _MAX(X_MIN_BED + MIN_PROBE_EDGE_LEFT, X_MIN_POS + dpo.x) - 0.00001f)
|
82
|
|
-#define RTEST(N) (test_z_stepper_align_xy[N].x <= _MIN(X_MAX_BED - MIN_PROBE_EDGE_RIGHT, X_MAX_POS + dpo.x) + 0.00001f)
|
83
|
|
-#define FTEST(N) (test_z_stepper_align_xy[N].y >= _MAX(Y_MIN_BED + MIN_PROBE_EDGE_FRONT, Y_MIN_POS + dpo.y) - 0.00001f)
|
84
|
|
-#define BTEST(N) (test_z_stepper_align_xy[N].y <= _MIN(Y_MAX_BED - MIN_PROBE_EDGE_BACK, Y_MAX_POS + dpo.y) + 0.00001f)
|
85
|
|
-
|
86
|
|
-static_assert(LTEST(0) && RTEST(0), "The 1st Z_STEPPER_ALIGN_XY X is unreachable with the default probe X offset.");
|
87
|
|
-static_assert(FTEST(0) && BTEST(0), "The 1st Z_STEPPER_ALIGN_XY Y is unreachable with the default probe Y offset.");
|
88
|
|
-static_assert(LTEST(1) && RTEST(1), "The 2nd Z_STEPPER_ALIGN_XY X is unreachable with the default probe X offset.");
|
89
|
|
-static_assert(FTEST(1) && BTEST(1), "The 2nd Z_STEPPER_ALIGN_XY Y is unreachable with the default probe Y offset.");
|
90
|
|
-#if NUM_Z_STEPPER_DRIVERS >= 3
|
91
|
|
- static_assert(LTEST(2) && RTEST(2), "The 3rd Z_STEPPER_ALIGN_XY X is unreachable with the default probe X offset.");
|
92
|
|
- static_assert(FTEST(2) && BTEST(2), "The 3rd Z_STEPPER_ALIGN_XY Y is unreachable with the default probe Y offset.");
|
93
|
|
- #if NUM_Z_STEPPER_DRIVERS >= 4
|
94
|
|
- static_assert(LTEST(3) && RTEST(3), "The 4th Z_STEPPER_ALIGN_XY X is unreachable with the default probe X offset.");
|
95
|
|
- static_assert(FTEST(3) && BTEST(3), "The 4th Z_STEPPER_ALIGN_XY Y is unreachable with the default probe Y offset.");
|
96
|
|
- #endif
|
97
|
|
-#endif
|
98
|
|
-
|
99
|
|
-//
|
100
|
|
-// G34 / M422 shared data
|
101
|
|
-//
|
102
|
|
-static xy_pos_t z_stepper_align_pos[] = Z_STEPPER_ALIGN_XY;
|
103
|
|
-
|
104
|
|
-#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
105
|
|
- static xy_pos_t z_stepper_align_stepper_pos[] = Z_STEPPER_ALIGN_STEPPER_XY;
|
106
|
|
-#endif
|
107
|
|
-
|
108
|
|
-#define G34_PROBE_COUNT COUNT(z_stepper_align_pos)
|
109
|
|
-
|
110
|
50
|
inline void set_all_z_lock(const bool lock) {
|
111
|
51
|
stepper.set_z_lock(lock);
|
112
|
52
|
stepper.set_z2_lock(lock);
|
|
@@ -201,11 +141,11 @@ void GcodeSuite::G34() {
|
201
|
141
|
// iteration this will be re-calculated based on the actual bed position
|
202
|
142
|
float z_probe = Z_BASIC_CLEARANCE + (G34_MAX_GRADE) * 0.01f * (
|
203
|
143
|
#if NUM_Z_STEPPER_DRIVERS == 3
|
204
|
|
- SQRT(_MAX(HYPOT2(z_stepper_align_pos[0].x - z_stepper_align_pos[0].y, z_stepper_align_pos[1].x - z_stepper_align_pos[1].y),
|
205
|
|
- HYPOT2(z_stepper_align_pos[1].x - z_stepper_align_pos[1].y, z_stepper_align_pos[2].x - z_stepper_align_pos[2].y),
|
206
|
|
- HYPOT2(z_stepper_align_pos[2].x - z_stepper_align_pos[2].y, z_stepper_align_pos[0].x - z_stepper_align_pos[0].y)))
|
|
144
|
+ SQRT(_MAX(HYPOT2(z_stepper_align.xy[0].x - z_stepper_align.xy[0].y, z_stepper_align.xy[1].x - z_stepper_align.xy[1].y),
|
|
145
|
+ HYPOT2(z_stepper_align.xy[1].x - z_stepper_align.xy[1].y, z_stepper_align.xy[2].x - z_stepper_align.xy[2].y),
|
|
146
|
+ HYPOT2(z_stepper_align.xy[2].x - z_stepper_align.xy[2].y, z_stepper_align.xy[0].x - z_stepper_align.xy[0].y)))
|
207
|
147
|
#else
|
208
|
|
- HYPOT(z_stepper_align_pos[0].x - z_stepper_align_pos[0].y, z_stepper_align_pos[1].x - z_stepper_align_pos[1].y)
|
|
148
|
+ HYPOT(z_stepper_align.xy[0].x - z_stepper_align.xy[0].y, z_stepper_align.xy[1].x - z_stepper_align.xy[1].y)
|
209
|
149
|
#endif
|
210
|
150
|
);
|
211
|
151
|
|
|
@@ -216,31 +156,39 @@ void GcodeSuite::G34() {
|
216
|
156
|
current_position.z -= z_probe * 0.5f;
|
217
|
157
|
|
218
|
158
|
float last_z_align_move[NUM_Z_STEPPER_DRIVERS] = ARRAY_N(NUM_Z_STEPPER_DRIVERS, 10000.0f, 10000.0f, 10000.0f),
|
219
|
|
- z_measured[G34_PROBE_COUNT] = { 0 },
|
|
159
|
+ z_measured[NUM_Z_STEPPER_DRIVERS] = { 0 },
|
220
|
160
|
z_maxdiff = 0.0f,
|
221
|
161
|
amplification = z_auto_align_amplification;
|
222
|
162
|
|
223
|
163
|
uint8_t iteration;
|
224
|
164
|
bool err_break = false;
|
|
165
|
+
|
|
166
|
+ #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
|
167
|
+ bool adjustment_reverse = false;
|
|
168
|
+ #endif
|
|
169
|
+
|
225
|
170
|
for (iteration = 0; iteration < z_auto_align_iterations; ++iteration) {
|
226
|
171
|
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> probing all positions.");
|
227
|
172
|
|
228
|
173
|
SERIAL_ECHOLNPAIR("\nITERATION: ", int(iteration + 1));
|
229
|
174
|
|
230
|
175
|
// Initialize minimum value
|
231
|
|
- float z_measured_min = 100000.0f,
|
|
176
|
+ float z_measured_min = 100000.0f,
|
232
|
177
|
z_measured_max = -100000.0f;
|
233
|
178
|
|
234
|
179
|
// Probe all positions (one per Z-Stepper)
|
235
|
|
- for (uint8_t i = 0; i < G34_PROBE_COUNT; ++i) {
|
|
180
|
+ for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i) {
|
236
|
181
|
// iteration odd/even --> downward / upward stepper sequence
|
237
|
|
- const uint8_t iprobe = (iteration & 1) ? G34_PROBE_COUNT - 1 - i : i;
|
|
182
|
+ const uint8_t iprobe = (iteration & 1) ? NUM_Z_STEPPER_DRIVERS - 1 - i : i;
|
238
|
183
|
|
239
|
184
|
// Safe clearance even on an incline
|
240
|
185
|
if (iteration == 0 || i > 0) do_blocking_move_to_z(z_probe);
|
241
|
186
|
|
|
187
|
+ if (DEBUGGING(LEVELING))
|
|
188
|
+ DEBUG_ECHOLNPAIR_P(PSTR("Probing X"), z_stepper_align.xy[iprobe].x, SP_Y_STR, z_stepper_align.xy[iprobe].y);
|
|
189
|
+
|
242
|
190
|
// Probe a Z height for each stepper.
|
243
|
|
- const float z_probed_height = probe.probe_at_point(z_stepper_align_pos[iprobe], raise_after, 0, true);
|
|
191
|
+ const float z_probed_height = probe.probe_at_point(z_stepper_align.xy[iprobe], raise_after, 0, true);
|
244
|
192
|
if (isnan(z_probed_height)) {
|
245
|
193
|
SERIAL_ECHOLNPGM("Probing failed.");
|
246
|
194
|
err_break = true;
|
|
@@ -279,15 +227,15 @@ void GcodeSuite::G34() {
|
279
|
227
|
// This allows the actual adjustment logic to be shared by both algorithms.
|
280
|
228
|
linear_fit_data lfd;
|
281
|
229
|
incremental_LSF_reset(&lfd);
|
282
|
|
- for (uint8_t i = 0; i < G34_PROBE_COUNT; ++i) {
|
283
|
|
- SERIAL_ECHOLNPAIR("PROBEPT_", int(i + 1), ": ", z_measured[i]);
|
284
|
|
- incremental_LSF(&lfd, z_stepper_align_pos[i], z_measured[i]);
|
|
230
|
+ for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i) {
|
|
231
|
+ SERIAL_ECHOLNPAIR("PROBEPT_", i + '1', ": ", z_measured[i]);
|
|
232
|
+ incremental_LSF(&lfd, z_stepper_align.xy[i], z_measured[i]);
|
285
|
233
|
}
|
286
|
234
|
finish_incremental_LSF(&lfd);
|
287
|
235
|
|
288
|
236
|
z_measured_min = 100000.0f;
|
289
|
237
|
for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i) {
|
290
|
|
- z_measured[i] = -(lfd.A * z_stepper_align_stepper_pos[i].x + lfd.B * z_stepper_align_stepper_pos[i].y);
|
|
238
|
+ z_measured[i] = -(lfd.A * z_stepper_align.stepper_xy[i].x + lfd.B * z_stepper_align.stepper_xy[i].y);
|
291
|
239
|
z_measured_min = _MIN(z_measured_min, z_measured[i]);
|
292
|
240
|
}
|
293
|
241
|
|
|
@@ -309,8 +257,8 @@ void GcodeSuite::G34() {
|
309
|
257
|
// Correct the individual stepper offsets
|
310
|
258
|
for (uint8_t zstepper = 0; zstepper < NUM_Z_STEPPER_DRIVERS; ++zstepper) {
|
311
|
259
|
// Calculate current stepper move
|
312
|
|
- const float z_align_move = z_measured[zstepper] - z_measured_min,
|
313
|
|
- z_align_abs = ABS(z_align_move);
|
|
260
|
+ float z_align_move = z_measured[zstepper] - z_measured_min;
|
|
261
|
+ const float z_align_abs = ABS(z_align_move);
|
314
|
262
|
|
315
|
263
|
#if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
316
|
264
|
// Optimize one iteration's correction based on the first measurements
|
|
@@ -318,10 +266,14 @@ void GcodeSuite::G34() {
|
318
|
266
|
#endif
|
319
|
267
|
|
320
|
268
|
// Check for less accuracy compared to last move
|
321
|
|
- if (last_z_align_move[zstepper] < z_align_abs - 1.0) {
|
|
269
|
+ if (last_z_align_move[zstepper] < z_align_abs * 0.7f) {
|
322
|
270
|
SERIAL_ECHOLNPGM("Decreasing accuracy detected.");
|
323
|
|
- err_break = true;
|
324
|
|
- break;
|
|
271
|
+ #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
|
272
|
+ adjustment_reverse = !adjustment_reverse;
|
|
273
|
+ #else
|
|
274
|
+ err_break = true;
|
|
275
|
+ break;
|
|
276
|
+ #endif
|
325
|
277
|
}
|
326
|
278
|
|
327
|
279
|
// Remember the alignment for the next iteration
|
|
@@ -342,6 +294,13 @@ void GcodeSuite::G34() {
|
342
|
294
|
#endif
|
343
|
295
|
}
|
344
|
296
|
|
|
297
|
+ #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
|
298
|
+ // Decreasing accuracy was detected so move was inverted.
|
|
299
|
+ // Will match reversed Z steppers on dual steppers. Triple will need more work to map.
|
|
300
|
+ if (adjustment_reverse)
|
|
301
|
+ z_align_move = -z_align_move;
|
|
302
|
+ #endif
|
|
303
|
+
|
345
|
304
|
// Do a move to correct part of the misalignment for the current stepper
|
346
|
305
|
do_blocking_move_to_z(amplification * z_align_move + current_position.z);
|
347
|
306
|
} // for (zstepper)
|
|
@@ -406,12 +365,13 @@ void GcodeSuite::G34() {
|
406
|
365
|
* Y<pos> : Y position to set (Unchanged if omitted)
|
407
|
366
|
*/
|
408
|
367
|
void GcodeSuite::M422() {
|
|
368
|
+
|
409
|
369
|
if (!parser.seen_any()) {
|
410
|
|
- for (uint8_t i = 0; i < G34_PROBE_COUNT; ++i)
|
411
|
|
- SERIAL_ECHOLNPAIR_P(PSTR("M422 S"), i + 1, SP_X_STR, z_stepper_align_pos[i].x, SP_Y_STR, z_stepper_align_pos[i].y);
|
|
370
|
+ for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i)
|
|
371
|
+ SERIAL_ECHOLNPAIR_P(PSTR("M422 S"), i + '1', SP_X_STR, z_stepper_align.xy[i].x, SP_Y_STR, z_stepper_align.xy[i].y);
|
412
|
372
|
#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
413
|
373
|
for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i)
|
414
|
|
- SERIAL_ECHOLNPAIR_P(PSTR("M422 W"), i + 1, SP_X_STR, z_stepper_align_stepper_pos[i].x, SP_Y_STR, z_stepper_align_stepper_pos[i].y);
|
|
374
|
+ SERIAL_ECHOLNPAIR_P(PSTR("M422 W"), i + '1', SP_X_STR, z_stepper_align.stepper_xy[i].x, SP_Y_STR, z_stepper_align.stepper_xy[i].y);
|
415
|
375
|
#endif
|
416
|
376
|
return;
|
417
|
377
|
}
|
|
@@ -427,9 +387,9 @@ void GcodeSuite::M422() {
|
427
|
387
|
|
428
|
388
|
xy_pos_t *pos_dest = (
|
429
|
389
|
#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
430
|
|
- !is_probe_point ? z_stepper_align_stepper_pos :
|
|
390
|
+ !is_probe_point ? z_stepper_align.stepper_xy :
|
431
|
391
|
#endif
|
432
|
|
- z_stepper_align_pos
|
|
392
|
+ z_stepper_align.xy
|
433
|
393
|
);
|
434
|
394
|
|
435
|
395
|
if (!is_probe_point
|
|
@@ -451,7 +411,7 @@ void GcodeSuite::M422() {
|
451
|
411
|
int8_t position_index;
|
452
|
412
|
if (is_probe_point) {
|
453
|
413
|
position_index = parser.intval('S') - 1;
|
454
|
|
- if (!WITHIN(position_index, 0, int8_t(G34_PROBE_COUNT) - 1)) {
|
|
414
|
+ if (!WITHIN(position_index, 0, int8_t(NUM_Z_STEPPER_DRIVERS) - 1)) {
|
455
|
415
|
SERIAL_ECHOLNPGM("?(S) Z-ProbePosition index invalid.");
|
456
|
416
|
return;
|
457
|
417
|
}
|