Browse Source

Fix G34 "Decreasing accuracy" bug (#17013)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
jufimu12 4 years ago
parent
commit
ac755fce82
No account linked to committer's email address
1 changed files with 47 additions and 25 deletions
  1. 47
    25
      Marlin/src/gcode/calibrate/G34_M422.cpp

+ 47
- 25
Marlin/src/gcode/calibrate/G34_M422.cpp View File

155
     // Move the Z coordinate realm towards the positive - dirty trick
155
     // Move the Z coordinate realm towards the positive - dirty trick
156
     current_position.z -= z_probe * 0.5f;
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
           z_maxdiff = 0.0f,
164
           z_maxdiff = 0.0f,
161
           amplification = z_auto_align_amplification;
165
           amplification = z_auto_align_amplification;
162
 
166
 
167
       bool adjustment_reverse = false;
171
       bool adjustment_reverse = false;
168
     #endif
172
     #endif
169
 
173
 
170
-    for (iteration = 0; iteration < z_auto_align_iterations; ++iteration) {
174
+    LOOP_L_N(iteration, z_auto_align_iterations) {
171
       if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> probing all positions.");
175
       if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> probing all positions.");
172
 
176
 
173
       SERIAL_ECHOLNPAIR("\nITERATION: ", int(iteration + 1));
177
       SERIAL_ECHOLNPAIR("\nITERATION: ", int(iteration + 1));
177
             z_measured_max = -100000.0f;
181
             z_measured_max = -100000.0f;
178
 
182
 
179
       // Probe all positions (one per Z-Stepper)
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
         // iteration odd/even --> downward / upward stepper sequence
185
         // iteration odd/even --> downward / upward stepper sequence
182
         const uint8_t iprobe = (iteration & 1) ? NUM_Z_STEPPER_DRIVERS - 1 - i : i;
186
         const uint8_t iprobe = (iteration & 1) ? NUM_Z_STEPPER_DRIVERS - 1 - i : i;
183
 
187
 
227
         // This allows the actual adjustment logic to be shared by both algorithms.
231
         // This allows the actual adjustment logic to be shared by both algorithms.
228
         linear_fit_data lfd;
232
         linear_fit_data lfd;
229
         incremental_LSF_reset(&lfd);
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
           SERIAL_ECHOLNPAIR("PROBEPT_", i + '1', ": ", z_measured[i]);
235
           SERIAL_ECHOLNPAIR("PROBEPT_", i + '1', ": ", z_measured[i]);
232
           incremental_LSF(&lfd, z_stepper_align.xy[i], z_measured[i]);
236
           incremental_LSF(&lfd, z_stepper_align.xy[i], z_measured[i]);
233
         }
237
         }
234
         finish_incremental_LSF(&lfd);
238
         finish_incremental_LSF(&lfd);
235
 
239
 
236
         z_measured_min = 100000.0f;
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
           z_measured[i] = -(lfd.A * z_stepper_align.stepper_xy[i].x + lfd.B * z_stepper_align.stepper_xy[i].y);
242
           z_measured[i] = -(lfd.A * z_stepper_align.stepper_xy[i].x + lfd.B * z_stepper_align.stepper_xy[i].y);
239
           z_measured_min = _MIN(z_measured_min, z_measured[i]);
243
           z_measured_min = _MIN(z_measured_min, z_measured[i]);
240
         }
244
         }
250
         #endif
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
       // The following correction actions are to be enabled for select Z-steppers only
282
       // The following correction actions are to be enabled for select Z-steppers only
254
       stepper.set_separate_multi_axis(true);
283
       stepper.set_separate_multi_axis(true);
255
 
284
 
256
       bool success_break = true;
285
       bool success_break = true;
257
       // Correct the individual stepper offsets
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
         // Calculate current stepper move
288
         // Calculate current stepper move
260
         float z_align_move = z_measured[zstepper] - z_measured_min;
289
         float z_align_move = z_measured[zstepper] - z_measured_min;
261
         const float z_align_abs = ABS(z_align_move);
290
         const float z_align_abs = ABS(z_align_move);
263
         #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
292
         #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
264
           // Optimize one iteration's correction based on the first measurements
293
           // Optimize one iteration's correction based on the first measurements
265
           if (z_align_abs) amplification = (iteration == 1) ? _MIN(last_z_align_move[zstepper] / z_align_abs, 2.0f) : z_auto_align_amplification;
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
             adjustment_reverse = !adjustment_reverse;
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
         // Stop early if all measured points achieve accuracy target
306
         // Stop early if all measured points achieve accuracy target
283
         if (z_align_abs > z_auto_align_accuracy) success_break = false;
307
         if (z_align_abs > z_auto_align_accuracy) success_break = false;
322
 
346
 
323
     // Restore the active tool after homing
347
     // Restore the active tool after homing
324
     #if HOTENDS > 1
348
     #if HOTENDS > 1
325
-      tool_change(old_tool_index, (
349
+      tool_change(old_tool_index, (true
326
         #if ENABLED(PARKING_EXTRUDER)
350
         #if ENABLED(PARKING_EXTRUDER)
327
-          false // Fetch the previous toolhead
328
-        #else
329
-          true
351
+          && false // Fetch the previous toolhead
330
         #endif
352
         #endif
331
       ));
353
       ));
332
     #endif
354
     #endif
367
 void GcodeSuite::M422() {
389
 void GcodeSuite::M422() {
368
 
390
 
369
   if (!parser.seen_any()) {
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
       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);
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
     #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
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
         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);
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
     #endif
397
     #endif
376
     return;
398
     return;

Loading…
Cancel
Save