|
@@ -155,8 +155,12 @@ void GcodeSuite::G34() {
|
155
|
155
|
// Move the Z coordinate realm towards the positive - dirty trick
|
156
|
156
|
current_position.z -= z_probe * 0.5f;
|
157
|
157
|
|
158
|
|
- float last_z_align_move[NUM_Z_STEPPER_DRIVERS] = ARRAY_N(NUM_Z_STEPPER_DRIVERS, 10000.0f, 10000.0f, 10000.0f),
|
159
|
|
- z_measured[NUM_Z_STEPPER_DRIVERS] = { 0 },
|
|
158
|
+ #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
|
159
|
+ float last_z_align_move[NUM_Z_STEPPER_DRIVERS] = ARRAY_N(NUM_Z_STEPPER_DRIVERS, 10000.0f, 10000.0f, 10000.0f);
|
|
160
|
+ #else
|
|
161
|
+ float last_z_align_level_indicator = 10000.0f;
|
|
162
|
+ #endif
|
|
163
|
+ float z_measured[NUM_Z_STEPPER_DRIVERS] = { 0 },
|
160
|
164
|
z_maxdiff = 0.0f,
|
161
|
165
|
amplification = z_auto_align_amplification;
|
162
|
166
|
|
|
@@ -167,7 +171,7 @@ void GcodeSuite::G34() {
|
167
|
171
|
bool adjustment_reverse = false;
|
168
|
172
|
#endif
|
169
|
173
|
|
170
|
|
- for (iteration = 0; iteration < z_auto_align_iterations; ++iteration) {
|
|
174
|
+ LOOP_L_N(iteration, z_auto_align_iterations) {
|
171
|
175
|
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> probing all positions.");
|
172
|
176
|
|
173
|
177
|
SERIAL_ECHOLNPAIR("\nITERATION: ", int(iteration + 1));
|
|
@@ -177,7 +181,7 @@ void GcodeSuite::G34() {
|
177
|
181
|
z_measured_max = -100000.0f;
|
178
|
182
|
|
179
|
183
|
// Probe all positions (one per Z-Stepper)
|
180
|
|
- for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i) {
|
|
184
|
+ LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) {
|
181
|
185
|
// iteration odd/even --> downward / upward stepper sequence
|
182
|
186
|
const uint8_t iprobe = (iteration & 1) ? NUM_Z_STEPPER_DRIVERS - 1 - i : i;
|
183
|
187
|
|
|
@@ -227,14 +231,14 @@ void GcodeSuite::G34() {
|
227
|
231
|
// This allows the actual adjustment logic to be shared by both algorithms.
|
228
|
232
|
linear_fit_data lfd;
|
229
|
233
|
incremental_LSF_reset(&lfd);
|
230
|
|
- for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i) {
|
|
234
|
+ LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) {
|
231
|
235
|
SERIAL_ECHOLNPAIR("PROBEPT_", i + '1', ": ", z_measured[i]);
|
232
|
236
|
incremental_LSF(&lfd, z_stepper_align.xy[i], z_measured[i]);
|
233
|
237
|
}
|
234
|
238
|
finish_incremental_LSF(&lfd);
|
235
|
239
|
|
236
|
240
|
z_measured_min = 100000.0f;
|
237
|
|
- for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i) {
|
|
241
|
+ LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) {
|
238
|
242
|
z_measured[i] = -(lfd.A * z_stepper_align.stepper_xy[i].x + lfd.B * z_stepper_align.stepper_xy[i].y);
|
239
|
243
|
z_measured_min = _MIN(z_measured_min, z_measured[i]);
|
240
|
244
|
}
|
|
@@ -250,12 +254,37 @@ void GcodeSuite::G34() {
|
250
|
254
|
#endif
|
251
|
255
|
);
|
252
|
256
|
|
|
257
|
+ #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
|
258
|
+ // Check if the applied corrections go in the correct direction.
|
|
259
|
+ // Calculate the sum of the absolute deviations from the mean of the probe measurements.
|
|
260
|
+ // Compare to the last iteration to ensure it's getting better.
|
|
261
|
+
|
|
262
|
+ // Calculate mean value as a reference
|
|
263
|
+ float z_measured_mean = 0.0f;
|
|
264
|
+ LOOP_L_N(zstepper, NUM_Z_STEPPER_DRIVERS) z_measured_mean += z_measured[zstepper];
|
|
265
|
+ z_measured_mean /= NUM_Z_STEPPER_DRIVERS;
|
|
266
|
+
|
|
267
|
+ // Calculate the sum of the absolute deviations from the mean value
|
|
268
|
+ float z_align_level_indicator = 0.0f;
|
|
269
|
+ LOOP_L_N(zstepper, NUM_Z_STEPPER_DRIVERS)
|
|
270
|
+ z_align_level_indicator += ABS(z_measured[zstepper] - z_measured_mean);
|
|
271
|
+
|
|
272
|
+ // If it's getting worse, stop and throw an error
|
|
273
|
+ if (last_z_align_level_indicator < z_align_level_indicator * 0.7f) {
|
|
274
|
+ SERIAL_ECHOLNPGM("Decreasing accuracy detected.");
|
|
275
|
+ err_break = true;
|
|
276
|
+ break;
|
|
277
|
+ }
|
|
278
|
+
|
|
279
|
+ last_z_align_level_indicator = z_align_level_indicator;
|
|
280
|
+ #endif
|
|
281
|
+
|
253
|
282
|
// The following correction actions are to be enabled for select Z-steppers only
|
254
|
283
|
stepper.set_separate_multi_axis(true);
|
255
|
284
|
|
256
|
285
|
bool success_break = true;
|
257
|
286
|
// Correct the individual stepper offsets
|
258
|
|
- for (uint8_t zstepper = 0; zstepper < NUM_Z_STEPPER_DRIVERS; ++zstepper) {
|
|
287
|
+ LOOP_L_N(zstepper, NUM_Z_STEPPER_DRIVERS) {
|
259
|
288
|
// Calculate current stepper move
|
260
|
289
|
float z_align_move = z_measured[zstepper] - z_measured_min;
|
261
|
290
|
const float z_align_abs = ABS(z_align_move);
|
|
@@ -263,21 +292,16 @@ void GcodeSuite::G34() {
|
263
|
292
|
#if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
264
|
293
|
// Optimize one iteration's correction based on the first measurements
|
265
|
294
|
if (z_align_abs) amplification = (iteration == 1) ? _MIN(last_z_align_move[zstepper] / z_align_abs, 2.0f) : z_auto_align_amplification;
|
266
|
|
- #endif
|
267
|
295
|
|
268
|
|
- // Check for less accuracy compared to last move
|
269
|
|
- if (last_z_align_move[zstepper] < z_align_abs * 0.7f) {
|
270
|
|
- SERIAL_ECHOLNPGM("Decreasing accuracy detected.");
|
271
|
|
- #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
|
296
|
+ // Check for less accuracy compared to last move
|
|
297
|
+ if (last_z_align_move[zstepper] < z_align_abs * 0.7f) {
|
|
298
|
+ SERIAL_ECHOLNPGM("Decreasing accuracy detected.");
|
272
|
299
|
adjustment_reverse = !adjustment_reverse;
|
273
|
|
- #else
|
274
|
|
- err_break = true;
|
275
|
|
- break;
|
276
|
|
- #endif
|
277
|
|
- }
|
|
300
|
+ }
|
278
|
301
|
|
279
|
|
- // Remember the alignment for the next iteration
|
280
|
|
- last_z_align_move[zstepper] = z_align_abs;
|
|
302
|
+ // Remember the alignment for the next iteration
|
|
303
|
+ last_z_align_move[zstepper] = z_align_abs;
|
|
304
|
+ #endif
|
281
|
305
|
|
282
|
306
|
// Stop early if all measured points achieve accuracy target
|
283
|
307
|
if (z_align_abs > z_auto_align_accuracy) success_break = false;
|
|
@@ -322,11 +346,9 @@ void GcodeSuite::G34() {
|
322
|
346
|
|
323
|
347
|
// Restore the active tool after homing
|
324
|
348
|
#if HOTENDS > 1
|
325
|
|
- tool_change(old_tool_index, (
|
|
349
|
+ tool_change(old_tool_index, (true
|
326
|
350
|
#if ENABLED(PARKING_EXTRUDER)
|
327
|
|
- false // Fetch the previous toolhead
|
328
|
|
- #else
|
329
|
|
- true
|
|
351
|
+ && false // Fetch the previous toolhead
|
330
|
352
|
#endif
|
331
|
353
|
));
|
332
|
354
|
#endif
|
|
@@ -367,10 +389,10 @@ void GcodeSuite::G34() {
|
367
|
389
|
void GcodeSuite::M422() {
|
368
|
390
|
|
369
|
391
|
if (!parser.seen_any()) {
|
370
|
|
- for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i)
|
|
392
|
+ LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS)
|
371
|
393
|
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);
|
372
|
394
|
#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
373
|
|
- for (uint8_t i = 0; i < NUM_Z_STEPPER_DRIVERS; ++i)
|
|
395
|
+ LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS)
|
374
|
396
|
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);
|
375
|
397
|
#endif
|
376
|
398
|
return;
|