浏览代码

Merge pull request #8730 from thinkyhead/bf2_fixup_ubl

[2.0.x] UBL - Skew and Dual X Carriage
Scott Lahteine 7 年前
父节点
当前提交
c555a214d2
没有帐户链接到提交者的电子邮件

+ 4
- 3
.travis.yml 查看文件

@@ -79,13 +79,14 @@ script:
79 79
   - opt_set TEMP_SENSOR_3 20
80 80
   - opt_set TEMP_SENSOR_4 999
81 81
   - opt_set TEMP_SENSOR_BED 1
82
-  - opt_enable AUTO_BED_LEVELING_UBL DEBUG_LEVELING_FEATURE G26_MESH_EDITING ENABLE_LEVELING_FADE_HEIGHT EEPROM_SETTINGS EEPROM_CHITCHAT G3D_PANEL
82
+  - opt_enable AUTO_BED_LEVELING_UBL DEBUG_LEVELING_FEATURE G26_MESH_EDITING ENABLE_LEVELING_FADE_HEIGHT EEPROM_SETTINGS EEPROM_CHITCHAT G3D_PANEL SKEW_CORRECTION
83 83
   - opt_enable_adv CUSTOM_USER_MENUS I2C_POSITION_ENCODERS BABYSTEPPING LIN_ADVANCE NANODLP_Z_SYNC
84 84
   - build_marlin_pio ${TRAVIS_BUILD_DIR} ${TEST_PLATFORM}
85 85
   #
86
-  # And with a Sled Z Probe
86
+  # Add a Sled Z Probe, do non-segmented moves
87 87
   #
88 88
   - opt_enable Z_PROBE_SLED
89
+  - opt_disable SEGMENT_LEVELED_MOVES
89 90
   - opt_enable_adv BABYSTEP_ZPROBE_OFFSET DOUBLECLICK_FOR_Z_BABYSTEPPING
90 91
   - build_marlin_pio ${TRAVIS_BUILD_DIR} ${TEST_PLATFORM}
91 92
   #
@@ -121,7 +122,7 @@ script:
121 122
   - opt_enable ULTIMAKERCONTROLLER SDSUPPORT
122 123
   - opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632 USE_XMAX_PLUG
123 124
   - opt_enable_adv BEZIER_CURVE_SUPPORT EXPERIMENTAL_I2CBUS
124
-  - opt_enable_adv ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE LCD_INFO_MENU
125
+  - opt_enable_adv ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE LCD_INFO_MENU M114_DETAIL
125 126
   - opt_set_adv PWM_MOTOR_CURRENT {1300,1300,1250}
126 127
   - opt_set_adv I2C_SLAVE_ADDRESS 63
127 128
   - build_marlin_pio ${TRAVIS_BUILD_DIR} ${TEST_PLATFORM}

+ 54
- 1
Marlin/src/feature/bedlevel/ubl/ubl.cpp 查看文件

@@ -55,6 +55,59 @@
55 55
     safe_delay(10);
56 56
   }
57 57
 
58
+  #if ENABLED(UBL_DEVEL_DEBUGGING)
59
+
60
+    static void debug_echo_axis(const AxisEnum axis) {
61
+      if (current_position[axis] == destination[axis])
62
+        SERIAL_ECHOPGM("-------------");
63
+      else
64
+        SERIAL_ECHO_F(destination[X_AXIS], 6);
65
+    }
66
+
67
+    void debug_current_and_destination(const char *title) {
68
+
69
+      // if the title message starts with a '!' it is so important, we are going to
70
+      // ignore the status of the g26_debug_flag
71
+      if (*title != '!' && !g26_debug_flag) return;
72
+
73
+      const float de = destination[E_AXIS] - current_position[E_AXIS];
74
+
75
+      if (de == 0.0) return; // Printing moves only
76
+
77
+      const float dx = destination[X_AXIS] - current_position[X_AXIS],
78
+                  dy = destination[Y_AXIS] - current_position[Y_AXIS],
79
+                  xy_dist = HYPOT(dx, dy);
80
+
81
+      if (xy_dist == 0.0) return;
82
+
83
+      SERIAL_ECHOPGM("   fpmm=");
84
+      const float fpmm = de / xy_dist;
85
+      SERIAL_ECHO_F(fpmm, 6);
86
+
87
+      SERIAL_ECHOPGM("    current=( ");
88
+      SERIAL_ECHO_F(current_position[X_AXIS], 6);
89
+      SERIAL_ECHOPGM(", ");
90
+      SERIAL_ECHO_F(current_position[Y_AXIS], 6);
91
+      SERIAL_ECHOPGM(", ");
92
+      SERIAL_ECHO_F(current_position[Z_AXIS], 6);
93
+      SERIAL_ECHOPGM(", ");
94
+      SERIAL_ECHO_F(current_position[E_AXIS], 6);
95
+      SERIAL_ECHOPGM(" )   destination=( ");
96
+      debug_echo_axis(X_AXIS);
97
+      SERIAL_ECHOPGM(", ");
98
+      debug_echo_axis(Y_AXIS);
99
+      SERIAL_ECHOPGM(", ");
100
+      debug_echo_axis(Z_AXIS);
101
+      SERIAL_ECHOPGM(", ");
102
+      debug_echo_axis(E_AXIS);
103
+      SERIAL_ECHOPGM(" )   ");
104
+      SERIAL_ECHO(title);
105
+      SERIAL_EOL();
106
+
107
+    }
108
+
109
+  #endif // UBL_DEVEL_DEBUGGING
110
+
58 111
   int8_t unified_bed_leveling::storage_slot;
59 112
 
60 113
   float unified_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
@@ -178,7 +231,7 @@
178 231
     uint8_t error_flag = 0;
179 232
 
180 233
     if (settings.calc_num_meshes() < 1) {
181
-      SERIAL_PROTOCOLLNPGM("?Insufficient EEPROM storage for a mesh of this size.");
234
+      SERIAL_PROTOCOLLNPGM("?Mesh too big for EEPROM.");
182 235
       error_flag++;
183 236
     }
184 237
 

+ 18
- 9
Marlin/src/feature/bedlevel/ubl/ubl.h 查看文件

@@ -23,6 +23,8 @@
23 23
 #ifndef UNIFIED_BED_LEVELING_H
24 24
 #define UNIFIED_BED_LEVELING_H
25 25
 
26
+//#define UBL_DEVEL_DEBUGGING
27
+
26 28
 #include "../bedlevel.h"
27 29
 #include "../../../module/planner.h"
28 30
 #include "../../../module/motion.h"
@@ -37,7 +39,11 @@
37 39
 
38 40
 // ubl_motion.cpp
39 41
 
40
-void debug_current_and_destination(const char * const title);
42
+#if ENABLED(UBL_DEVEL_DEBUGGING)
43
+  void debug_current_and_destination(const char * const title);
44
+#else
45
+  FORCE_INLINE void debug_current_and_destination(const char * const title) { UNUSED(title); }
46
+#endif
41 47
 
42 48
 // ubl_G29.cpp
43 49
 
@@ -217,9 +223,9 @@ class unified_bed_leveling {
217 223
       const float xratio = (rx0 - mesh_index_to_xpos(x1_i)) * (1.0 / (MESH_X_DIST)),
218 224
                   z1 = z_values[x1_i][yi];
219 225
 
220
-      return z1 + xratio * (z_values[min(x1_i, GRID_MAX_POINTS_X - 2) + 1][yi] - z1);  // Don't allow x1_i+1 to be past the end of the array
221
-                                                                                       // If it is, it is clamped to the last element of the 
222
-                                                                                       // z_values[][] array and no correction is applied.
226
+      return z1 + xratio * (z_values[min(x1_i, GRID_MAX_POINTS_X - 2) + 1][yi] - z1); // Don't allow x1_i+1 to be past the end of the array
227
+                                                                                      // If it is, it is clamped to the last element of the
228
+                                                                                      // z_values[][] array and no correction is applied.
223 229
     }
224 230
 
225 231
     //
@@ -243,9 +249,9 @@ class unified_bed_leveling {
243 249
       const float yratio = (ry0 - mesh_index_to_ypos(y1_i)) * (1.0 / (MESH_Y_DIST)),
244 250
                   z1 = z_values[xi][y1_i];
245 251
 
246
-      return z1 + yratio * (z_values[xi][min(y1_i, GRID_MAX_POINTS_Y - 2) + 1] - z1);  // Don't allow y1_i+1 to be past the end of the array
247
-                                                                                       // If it is, it is clamped to the last element of the 
248
-                                                                                       // z_values[][] array and no correction is applied.
252
+      return z1 + yratio * (z_values[xi][min(y1_i, GRID_MAX_POINTS_Y - 2) + 1] - z1); // Don't allow y1_i+1 to be past the end of the array
253
+                                                                                      // If it is, it is clamped to the last element of the
254
+                                                                                      // z_values[][] array and no correction is applied.
249 255
     }
250 256
 
251 257
     /**
@@ -315,8 +321,11 @@ class unified_bed_leveling {
315 321
       return i < GRID_MAX_POINTS_Y ? pgm_read_float(&_mesh_index_to_ypos[i]) : MESH_MIN_Y + i * (MESH_Y_DIST);
316 322
     }
317 323
 
318
-    static bool prepare_segmented_line_to(const float rtarget[XYZE], const float &feedrate);
319
-    static void line_to_destination_cartesian(const float &fr, uint8_t e);
324
+    #if UBL_SEGMENTED
325
+      static bool prepare_segmented_line_to(const float (&rtarget)[XYZE], const float &feedrate);
326
+    #else
327
+      static void line_to_destination_cartesian(const float &fr, const uint8_t e);
328
+    #endif
320 329
 
321 330
     #define _CMPZ(a,b) (z_values[a][b] == z_values[a][b+1])
322 331
     #define CMPZ(a) (_CMPZ(a, 0) && _CMPZ(a, 1))

+ 213
- 265
Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp 查看文件

@@ -23,93 +23,42 @@
23 23
 
24 24
 #if ENABLED(AUTO_BED_LEVELING_UBL)
25 25
 
26
-  #include "../bedlevel.h"
27
-  #include "../../../module/planner.h"
28
-  #include "../../../module/stepper.h"
29
-  #include "../../../module/motion.h"
26
+#include "../bedlevel.h"
27
+#include "../../../module/planner.h"
28
+#include "../../../module/stepper.h"
29
+#include "../../../module/motion.h"
30 30
 
31
-  #if ENABLED(DELTA)
32
-    #include "../../../module/delta.h"
33
-  #endif
34
-
35
-  #include "../../../Marlin.h"
36
-  #include <math.h>
37
-
38
-  extern float destination[XYZE];
39
-
40
-  #if AVR_AT90USB1286_FAMILY  // Teensyduino & Printrboard IDE extensions have compile errors without this
41
-    inline void set_current_from_destination() { COPY(current_position, destination); }
42
-  #else
43
-    extern void set_current_from_destination();
44
-  #endif
31
+#if ENABLED(DELTA)
32
+  #include "../../../module/delta.h"
33
+#endif
45 34
 
46
-  static void debug_echo_axis(const AxisEnum axis) {
47
-    if (current_position[axis] == destination[axis])
48
-      SERIAL_ECHOPGM("-------------");
49
-    else
50
-      SERIAL_ECHO_F(destination[X_AXIS], 6);
51
-  }
35
+#include "../../../Marlin.h"
36
+#include <math.h>
52 37
 
53
-  void debug_current_and_destination(const char *title) {
54
-
55
-    // if the title message starts with a '!' it is so important, we are going to
56
-    // ignore the status of the g26_debug_flag
57
-    if (*title != '!' && !g26_debug_flag) return;
58
-
59
-    const float de = destination[E_AXIS] - current_position[E_AXIS];
60
-
61
-    if (de == 0.0) return; // Printing moves only
62
-
63
-    const float dx = destination[X_AXIS] - current_position[X_AXIS],
64
-                dy = destination[Y_AXIS] - current_position[Y_AXIS],
65
-                xy_dist = HYPOT(dx, dy);
66
-
67
-    if (xy_dist == 0.0) return;
68
-
69
-    SERIAL_ECHOPGM("   fpmm=");
70
-    const float fpmm = de / xy_dist;
71
-    SERIAL_ECHO_F(fpmm, 6);
72
-
73
-    SERIAL_ECHOPGM("    current=( ");
74
-    SERIAL_ECHO_F(current_position[X_AXIS], 6);
75
-    SERIAL_ECHOPGM(", ");
76
-    SERIAL_ECHO_F(current_position[Y_AXIS], 6);
77
-    SERIAL_ECHOPGM(", ");
78
-    SERIAL_ECHO_F(current_position[Z_AXIS], 6);
79
-    SERIAL_ECHOPGM(", ");
80
-    SERIAL_ECHO_F(current_position[E_AXIS], 6);
81
-    SERIAL_ECHOPGM(" )   destination=( ");
82
-    debug_echo_axis(X_AXIS);
83
-    SERIAL_ECHOPGM(", ");
84
-    debug_echo_axis(Y_AXIS);
85
-    SERIAL_ECHOPGM(", ");
86
-    debug_echo_axis(Z_AXIS);
87
-    SERIAL_ECHOPGM(", ");
88
-    debug_echo_axis(E_AXIS);
89
-    SERIAL_ECHOPGM(" )   ");
90
-    SERIAL_ECHO(title);
91
-    SERIAL_EOL();
38
+#if AVR_AT90USB1286_FAMILY  // Teensyduino & Printrboard IDE extensions have compile errors without this
39
+  inline void set_current_from_destination() { COPY(current_position, destination); }
40
+#else
41
+  extern void set_current_from_destination();
42
+#endif
92 43
 
93
-  }
44
+#if !UBL_SEGMENTED
94 45
 
95
-  void unified_bed_leveling::line_to_destination_cartesian(const float &feed_rate, uint8_t extruder) {
46
+  void unified_bed_leveling::line_to_destination_cartesian(const float &feed_rate, const uint8_t extruder) {
96 47
     /**
97 48
      * Much of the nozzle movement will be within the same cell. So we will do as little computation
98 49
      * as possible to determine if this is the case. If this move is within the same cell, we will
99 50
      * just do the required Z-Height correction, call the Planner's buffer_line() routine, and leave
100 51
      */
101
-    const float start[XYZE] = {
102
-                  current_position[X_AXIS],
103
-                  current_position[Y_AXIS],
104
-                  current_position[Z_AXIS],
105
-                  current_position[E_AXIS]
106
-                },
107
-                end[XYZE] = {
108
-                  destination[X_AXIS],
109
-                  destination[Y_AXIS],
110
-                  destination[Z_AXIS],
111
-                  destination[E_AXIS]
112
-                };
52
+    #if ENABLED(SKEW_CORRECTION)
53
+      // For skew correction just adjust the destination point and we're done
54
+      float start[XYZE] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS] },
55
+            end[XYZE] = { destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS] };
56
+      planner.skew(start[X_AXIS], start[Y_AXIS], start[Z_AXIS]);
57
+      planner.skew(end[X_AXIS], end[Y_AXIS], end[Z_AXIS]);
58
+    #else
59
+      const float (&start)[XYZE] = current_position,
60
+                    (&end)[XYZE] = destination;
61
+    #endif
113 62
 
114 63
     const int cell_start_xi = get_cell_index_x(start[X_AXIS]),
115 64
               cell_start_yi = get_cell_index_y(start[Y_AXIS]),
@@ -117,13 +66,13 @@
117 66
               cell_dest_yi  = get_cell_index_y(end[Y_AXIS]);
118 67
 
119 68
     if (g26_debug_flag) {
120
-      SERIAL_ECHOPAIR(" ubl.line_to_destination(xe=", end[X_AXIS]);
121
-      SERIAL_ECHOPAIR(", ye=", end[Y_AXIS]);
122
-      SERIAL_ECHOPAIR(", ze=", end[Z_AXIS]);
123
-      SERIAL_ECHOPAIR(", ee=", end[E_AXIS]);
69
+      SERIAL_ECHOPAIR(" ubl.line_to_destination_cartesian(xe=", destination[X_AXIS]);
70
+      SERIAL_ECHOPAIR(", ye=", destination[Y_AXIS]);
71
+      SERIAL_ECHOPAIR(", ze=", destination[Z_AXIS]);
72
+      SERIAL_ECHOPAIR(", ee=", destination[E_AXIS]);
124 73
       SERIAL_CHAR(')');
125 74
       SERIAL_EOL();
126
-      debug_current_and_destination(PSTR("Start of ubl.line_to_destination()"));
75
+      debug_current_and_destination(PSTR("Start of ubl.line_to_destination_cartesian()"));
127 76
     }
128 77
 
129 78
     if (cell_start_xi == cell_dest_xi && cell_start_yi == cell_dest_yi) { // if the whole move is within the same cell,
@@ -139,11 +88,11 @@
139 88
         // Note: There is no Z Correction in this case. We are off the grid and don't know what
140 89
         // a reasonable correction would be.
141 90
 
142
-        planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS], end[E_AXIS], feed_rate, extruder);
91
+        planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS], end[E_AXIS], feed_rate, extruder);
143 92
         set_current_from_destination();
144 93
 
145 94
         if (g26_debug_flag)
146
-          debug_current_and_destination(PSTR("out of bounds in ubl.line_to_destination()"));
95
+          debug_current_and_destination(PSTR("out of bounds in ubl.line_to_destination_cartesian()"));
147 96
 
148 97
         return;
149 98
       }
@@ -183,10 +132,10 @@
183 132
        */
184 133
       if (isnan(z0)) z0 = 0.0;
185 134
 
186
-      planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z0, end[E_AXIS], feed_rate, extruder);
135
+      planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z0, end[E_AXIS], feed_rate, extruder);
187 136
 
188 137
       if (g26_debug_flag)
189
-        debug_current_and_destination(PSTR("FINAL_MOVE in ubl.line_to_destination()"));
138
+        debug_current_and_destination(PSTR("FINAL_MOVE in ubl.line_to_destination_cartesian()"));
190 139
 
191 140
       set_current_from_destination();
192 141
       return;
@@ -274,7 +223,7 @@
274 223
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
275 224
          * where the line is heading down and it is starting right on a Mesh Line boundary. For how often that
276 225
          * happens, it might be best to remove the check and always 'schedule' the move because
277
-         * the planner._buffer_line() routine will filter it if that happens.
226
+         * the planner.buffer_segment() routine will filter it if that happens.
278 227
          */
279 228
         if (ry != start[Y_AXIS]) {
280 229
           if (!inf_normalized_flag) {
@@ -287,12 +236,12 @@
287 236
             z_position = end[Z_AXIS];
288 237
           }
289 238
 
290
-          planner._buffer_line(rx, ry, z_position + z0, e_position, feed_rate, extruder);
239
+          planner.buffer_segment(rx, ry, z_position + z0, e_position, feed_rate, extruder);
291 240
         } //else printf("FIRST MOVE PRUNED  ");
292 241
       }
293 242
 
294 243
       if (g26_debug_flag)
295
-        debug_current_and_destination(PSTR("vertical move done in ubl.line_to_destination()"));
244
+        debug_current_and_destination(PSTR("vertical move done in ubl.line_to_destination_cartesian()"));
296 245
 
297 246
       //
298 247
       // Check if we are at the final destination. Usually, we won't be, but if it is on a Y Mesh Line, we are done.
@@ -338,7 +287,7 @@
338 287
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
339 288
          * where the line is heading left and it is starting right on a Mesh Line boundary. For how often
340 289
          * that happens, it might be best to remove the check and always 'schedule' the move because
341
-         * the planner._buffer_line() routine will filter it if that happens.
290
+         * the planner.buffer_segment() routine will filter it if that happens.
342 291
          */
343 292
         if (rx != start[X_AXIS]) {
344 293
           if (!inf_normalized_flag) {
@@ -351,12 +300,12 @@
351 300
             z_position = end[Z_AXIS];
352 301
           }
353 302
 
354
-          planner._buffer_line(rx, ry, z_position + z0, e_position, feed_rate, extruder);
303
+          planner.buffer_segment(rx, ry, z_position + z0, e_position, feed_rate, extruder);
355 304
         } //else printf("FIRST MOVE PRUNED  ");
356 305
       }
357 306
 
358 307
       if (g26_debug_flag)
359
-        debug_current_and_destination(PSTR("horizontal move done in ubl.line_to_destination()"));
308
+        debug_current_and_destination(PSTR("horizontal move done in ubl.line_to_destination_cartesian()"));
360 309
 
361 310
       if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
362 311
         goto FINAL_MOVE;
@@ -413,7 +362,7 @@
413 362
           e_position = end[E_AXIS];
414 363
           z_position = end[Z_AXIS];
415 364
         }
416
-        planner._buffer_line(rx, next_mesh_line_y, z_position + z0, e_position, feed_rate, extruder);
365
+        planner.buffer_segment(rx, next_mesh_line_y, z_position + z0, e_position, feed_rate, extruder);
417 366
         current_yi += dyi;
418 367
         yi_cnt--;
419 368
       }
@@ -441,7 +390,7 @@
441 390
           z_position = end[Z_AXIS];
442 391
         }
443 392
 
444
-        planner._buffer_line(next_mesh_line_x, ry, z_position + z0, e_position, feed_rate, extruder);
393
+        planner.buffer_segment(next_mesh_line_x, ry, z_position + z0, e_position, feed_rate, extruder);
445 394
         current_xi += dxi;
446 395
         xi_cnt--;
447 396
       }
@@ -450,7 +399,7 @@
450 399
     }
451 400
 
452 401
     if (g26_debug_flag)
453
-      debug_current_and_destination(PSTR("generic move done in ubl.line_to_destination()"));
402
+      debug_current_and_destination(PSTR("generic move done in ubl.line_to_destination_cartesian()"));
454 403
 
455 404
     if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
456 405
       goto FINAL_MOVE;
@@ -458,223 +407,222 @@
458 407
     set_current_from_destination();
459 408
   }
460 409
 
461
-  #if UBL_DELTA
410
+#else // UBL_SEGMENTED
462 411
 
463
-    // macro to inline copy exactly 4 floats, don't rely on sizeof operator
464
-    #define COPY_XYZE( target, source ) { \
465
-                target[X_AXIS] = source[X_AXIS]; \
466
-                target[Y_AXIS] = source[Y_AXIS]; \
467
-                target[Z_AXIS] = source[Z_AXIS]; \
468
-                target[E_AXIS] = source[E_AXIS]; \
469
-            }
412
+  #if IS_SCARA // scale the feed rate from mm/s to degrees/s
413
+    static float scara_feed_factor, scara_oldA, scara_oldB;
414
+  #endif
470 415
 
471
-    #if IS_SCARA // scale the feed rate from mm/s to degrees/s
472
-      static float scara_feed_factor, scara_oldA, scara_oldB;
473
-    #endif
416
+  // We don't want additional apply_leveling() performed by regular buffer_line or buffer_line_kinematic,
417
+  // so we call buffer_segment directly here.  Per-segmented leveling and kinematics performed first.
474 418
 
475
-    // We don't want additional apply_leveling() performed by regular buffer_line or buffer_line_kinematic,
476
-    // so we call _buffer_line directly here.  Per-segmented leveling and kinematics performed first.
419
+  inline void _O2 ubl_buffer_segment_raw(const float (&in_raw)[XYZE], const float &fr) {
477 420
 
478
-    inline void _O2 ubl_buffer_segment_raw(const float raw[XYZE], const float &fr) {
421
+    #if ENABLED(SKEW_CORRECTION)
422
+      float raw[XYZE] = { in_raw[X_AXIS], in_raw[Y_AXIS], in_raw[Z_AXIS] };
423
+      planner.skew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]);
424
+    #else
425
+      const float (&raw)[XYZE] = in_raw;
426
+    #endif
479 427
 
480
-      #if ENABLED(DELTA)  // apply delta inverse_kinematics
428
+    #if ENABLED(DELTA)  // apply delta inverse_kinematics
481 429
 
482
-        DELTA_RAW_IK();
483
-        planner._buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], fr, active_extruder);
430
+      DELTA_RAW_IK();
431
+      planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_AXIS], fr, active_extruder);
484 432
 
485
-      #elif IS_SCARA  // apply scara inverse_kinematics (should be changed to save raw->logical->raw)
433
+    #elif IS_SCARA  // apply scara inverse_kinematics (should be changed to save raw->logical->raw)
486 434
 
487
-        inverse_kinematics(raw);  // this writes delta[ABC] from raw[XYZE]
488
-                                  // should move the feedrate scaling to scara inverse_kinematics
435
+      inverse_kinematics(raw);  // this writes delta[ABC] from raw[XYZE]
436
+                                // should move the feedrate scaling to scara inverse_kinematics
489 437
 
490
-        const float adiff = FABS(delta[A_AXIS] - scara_oldA),
491
-                    bdiff = FABS(delta[B_AXIS] - scara_oldB);
492
-        scara_oldA = delta[A_AXIS];
493
-        scara_oldB = delta[B_AXIS];
494
-        float s_feedrate = max(adiff, bdiff) * scara_feed_factor;
438
+      const float adiff = FABS(delta[A_AXIS] - scara_oldA),
439
+                  bdiff = FABS(delta[B_AXIS] - scara_oldB);
440
+      scara_oldA = delta[A_AXIS];
441
+      scara_oldB = delta[B_AXIS];
442
+      float s_feedrate = max(adiff, bdiff) * scara_feed_factor;
495 443
 
496
-        planner._buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], s_feedrate, active_extruder);
444
+      planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_AXIS], s_feedrate, active_extruder);
497 445
 
498
-      #else // CARTESIAN
446
+    #else // CARTESIAN
499 447
 
500
-        planner._buffer_line(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], raw[E_AXIS], fr, active_extruder);
448
+      planner.buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], in_raw[E_AXIS], fr, active_extruder);
501 449
 
502
-      #endif
503
-    }
450
+    #endif
451
+  }
504 452
 
505
-    #if IS_SCARA
506
-      #define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm
507
-    #elif ENABLED(DELTA)
508
-      #define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DELTA_SEGMENTS_PER_SECOND)
509
-    #else // CARTESIAN
510
-      #ifdef LEVELED_SEGMENT_LENGTH
511
-        #define DELTA_SEGMENT_MIN_LENGTH LEVELED_SEGMENT_LENGTH
512
-      #else
513
-        #define DELTA_SEGMENT_MIN_LENGTH 1.00 // mm (similar to G2/G3 arc segmentation)
514
-      #endif
453
+  #if IS_SCARA
454
+    #define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm
455
+  #elif ENABLED(DELTA)
456
+    #define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DELTA_SEGMENTS_PER_SECOND)
457
+  #else // CARTESIAN
458
+    #ifdef LEVELED_SEGMENT_LENGTH
459
+      #define DELTA_SEGMENT_MIN_LENGTH LEVELED_SEGMENT_LENGTH
460
+    #else
461
+      #define DELTA_SEGMENT_MIN_LENGTH 1.00 // mm (similar to G2/G3 arc segmentation)
515 462
     #endif
463
+  #endif
516 464
 
517
-    /**
518
-     * Prepare a segmented linear move for DELTA/SCARA/CARTESIAN with UBL and FADE semantics.
519
-     * This calls planner._buffer_line multiple times for small incremental moves.
520
-     * Returns true if did NOT move, false if moved (requires current_position update).
521
-     */
465
+  /**
466
+   * Prepare a segmented linear move for DELTA/SCARA/CARTESIAN with UBL and FADE semantics.
467
+   * This calls planner.buffer_segment multiple times for small incremental moves.
468
+   * Returns true if did NOT move, false if moved (requires current_position update).
469
+   */
470
+
471
+  bool _O2 unified_bed_leveling::prepare_segmented_line_to(const float (&rtarget)[XYZE], const float &feedrate) {
472
+
473
+    if (!position_is_reachable(rtarget[X_AXIS], rtarget[Y_AXIS]))  // fail if moving outside reachable boundary
474
+      return true; // did not move, so current_position still accurate
475
+
476
+    const float total[XYZE] = {
477
+      rtarget[X_AXIS] - current_position[X_AXIS],
478
+      rtarget[Y_AXIS] - current_position[Y_AXIS],
479
+      rtarget[Z_AXIS] - current_position[Z_AXIS],
480
+      rtarget[E_AXIS] - current_position[E_AXIS]
481
+    };
482
+
483
+    const float cartesian_xy_mm = HYPOT(total[X_AXIS], total[Y_AXIS]);  // total horizontal xy distance
484
+
485
+    #if IS_KINEMATIC
486
+      const float seconds = cartesian_xy_mm / feedrate;                                  // seconds to move xy distance at requested rate
487
+      uint16_t segments = lroundf(delta_segments_per_second * seconds),                  // preferred number of segments for distance @ feedrate
488
+               seglimit = lroundf(cartesian_xy_mm * (1.0 / (DELTA_SEGMENT_MIN_LENGTH))); // number of segments at minimum segment length
489
+      NOMORE(segments, seglimit);                                                        // limit to minimum segment length (fewer segments)
490
+    #else
491
+      uint16_t segments = lroundf(cartesian_xy_mm * (1.0 / (DELTA_SEGMENT_MIN_LENGTH))); // cartesian fixed segment length
492
+    #endif
522 493
 
523
-    bool _O2 unified_bed_leveling::prepare_segmented_line_to(const float rtarget[XYZE], const float &feedrate) {
524
-
525
-      if (!position_is_reachable(rtarget[X_AXIS], rtarget[Y_AXIS]))  // fail if moving outside reachable boundary
526
-        return true; // did not move, so current_position still accurate
527
-
528
-      const float total[XYZE] = {
529
-        rtarget[X_AXIS] - current_position[X_AXIS],
530
-        rtarget[Y_AXIS] - current_position[Y_AXIS],
531
-        rtarget[Z_AXIS] - current_position[Z_AXIS],
532
-        rtarget[E_AXIS] - current_position[E_AXIS]
533
-      };
534
-
535
-      const float cartesian_xy_mm = HYPOT(total[X_AXIS], total[Y_AXIS]);  // total horizontal xy distance
536
-
537
-      #if IS_KINEMATIC
538
-        const float seconds = cartesian_xy_mm / feedrate;                                  // seconds to move xy distance at requested rate
539
-        uint16_t segments = lroundf(delta_segments_per_second * seconds),                  // preferred number of segments for distance @ feedrate
540
-                 seglimit = lroundf(cartesian_xy_mm * (1.0 / (DELTA_SEGMENT_MIN_LENGTH))); // number of segments at minimum segment length
541
-        NOMORE(segments, seglimit);                                                        // limit to minimum segment length (fewer segments)
542
-      #else
543
-        uint16_t segments = lroundf(cartesian_xy_mm * (1.0 / (DELTA_SEGMENT_MIN_LENGTH))); // cartesian fixed segment length
544
-      #endif
545
-
546
-      NOLESS(segments, 1);                        // must have at least one segment
547
-      const float inv_segments = 1.0 / segments;  // divide once, multiply thereafter
548
-
549
-      #if IS_SCARA // scale the feed rate from mm/s to degrees/s
550
-        scara_feed_factor = cartesian_xy_mm * inv_segments * feedrate;
551
-        scara_oldA = stepper.get_axis_position_degrees(A_AXIS);
552
-        scara_oldB = stepper.get_axis_position_degrees(B_AXIS);
553
-      #endif
554
-
555
-      const float diff[XYZE] = {
556
-        total[X_AXIS] * inv_segments,
557
-        total[Y_AXIS] * inv_segments,
558
-        total[Z_AXIS] * inv_segments,
559
-        total[E_AXIS] * inv_segments
560
-      };
561
-
562
-      // Note that E segment distance could vary slightly as z mesh height
563
-      // changes for each segment, but small enough to ignore.
564
-
565
-      float raw[XYZE] = {
566
-        current_position[X_AXIS],
567
-        current_position[Y_AXIS],
568
-        current_position[Z_AXIS],
569
-        current_position[E_AXIS]
570
-      };
571
-
572
-      // Only compute leveling per segment if ubl active and target below z_fade_height.
573
-      if (!planner.leveling_active || !planner.leveling_active_at_z(rtarget[Z_AXIS])) {   // no mesh leveling
574
-        while (--segments) {
575
-          LOOP_XYZE(i) raw[i] += diff[i];
576
-          ubl_buffer_segment_raw(raw, feedrate);
577
-        }
578
-        ubl_buffer_segment_raw(rtarget, feedrate);
579
-        return false; // moved but did not set_current_from_destination();
494
+    NOLESS(segments, 1);                        // must have at least one segment
495
+    const float inv_segments = 1.0 / segments;  // divide once, multiply thereafter
496
+
497
+    #if IS_SCARA // scale the feed rate from mm/s to degrees/s
498
+      scara_feed_factor = cartesian_xy_mm * inv_segments * feedrate;
499
+      scara_oldA = stepper.get_axis_position_degrees(A_AXIS);
500
+      scara_oldB = stepper.get_axis_position_degrees(B_AXIS);
501
+    #endif
502
+
503
+    const float diff[XYZE] = {
504
+      total[X_AXIS] * inv_segments,
505
+      total[Y_AXIS] * inv_segments,
506
+      total[Z_AXIS] * inv_segments,
507
+      total[E_AXIS] * inv_segments
508
+    };
509
+
510
+    // Note that E segment distance could vary slightly as z mesh height
511
+    // changes for each segment, but small enough to ignore.
512
+
513
+    float raw[XYZE] = {
514
+      current_position[X_AXIS],
515
+      current_position[Y_AXIS],
516
+      current_position[Z_AXIS],
517
+      current_position[E_AXIS]
518
+    };
519
+
520
+    // Only compute leveling per segment if ubl active and target below z_fade_height.
521
+    if (!planner.leveling_active || !planner.leveling_active_at_z(rtarget[Z_AXIS])) {   // no mesh leveling
522
+      while (--segments) {
523
+        LOOP_XYZE(i) raw[i] += diff[i];
524
+        ubl_buffer_segment_raw(raw, feedrate);
580 525
       }
526
+      ubl_buffer_segment_raw(rtarget, feedrate);
527
+      return false; // moved but did not set_current_from_destination();
528
+    }
581 529
 
582
-      // Otherwise perform per-segment leveling
530
+    // Otherwise perform per-segment leveling
583 531
 
584
-      #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
585
-        const float fade_scaling_factor = planner.fade_scaling_factor_for_z(rtarget[Z_AXIS]);
586
-      #endif
532
+    #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
533
+      const float fade_scaling_factor = planner.fade_scaling_factor_for_z(rtarget[Z_AXIS]);
534
+    #endif
587 535
 
588
-      // increment to first segment destination
589
-      LOOP_XYZE(i) raw[i] += diff[i];
536
+    // increment to first segment destination
537
+    LOOP_XYZE(i) raw[i] += diff[i];
590 538
 
591
-      for(;;) {  // for each mesh cell encountered during the move
539
+    for(;;) {  // for each mesh cell encountered during the move
592 540
 
593
-        // Compute mesh cell invariants that remain constant for all segments within cell.
594
-        // Note for cell index, if point is outside the mesh grid (in MESH_INSET perimeter)
595
-        // the bilinear interpolation from the adjacent cell within the mesh will still work.
596
-        // Inner loop will exit each time (because out of cell bounds) but will come back
597
-        // in top of loop and again re-find same adjacent cell and use it, just less efficient
598
-        // for mesh inset area.
541
+      // Compute mesh cell invariants that remain constant for all segments within cell.
542
+      // Note for cell index, if point is outside the mesh grid (in MESH_INSET perimeter)
543
+      // the bilinear interpolation from the adjacent cell within the mesh will still work.
544
+      // Inner loop will exit each time (because out of cell bounds) but will come back
545
+      // in top of loop and again re-find same adjacent cell and use it, just less efficient
546
+      // for mesh inset area.
599 547
 
600
-        int8_t cell_xi = (raw[X_AXIS] - (MESH_MIN_X)) * (1.0 / (MESH_X_DIST)),
601
-               cell_yi = (raw[Y_AXIS] - (MESH_MIN_Y)) * (1.0 / (MESH_X_DIST));
548
+      int8_t cell_xi = (raw[X_AXIS] - (MESH_MIN_X)) * (1.0 / (MESH_X_DIST)),
549
+             cell_yi = (raw[Y_AXIS] - (MESH_MIN_Y)) * (1.0 / (MESH_X_DIST));
602 550
 
603
-        cell_xi = constrain(cell_xi, 0, (GRID_MAX_POINTS_X) - 1);
604
-        cell_yi = constrain(cell_yi, 0, (GRID_MAX_POINTS_Y) - 1);
551
+      cell_xi = constrain(cell_xi, 0, (GRID_MAX_POINTS_X) - 1);
552
+      cell_yi = constrain(cell_yi, 0, (GRID_MAX_POINTS_Y) - 1);
605 553
 
606
-        const float x0 = mesh_index_to_xpos(cell_xi),   // 64 byte table lookup avoids mul+add
607
-                    y0 = mesh_index_to_ypos(cell_yi);
554
+      const float x0 = mesh_index_to_xpos(cell_xi),   // 64 byte table lookup avoids mul+add
555
+                  y0 = mesh_index_to_ypos(cell_yi);
608 556
 
609
-        float z_x0y0 = z_values[cell_xi  ][cell_yi  ],  // z at lower left corner
610
-              z_x1y0 = z_values[cell_xi+1][cell_yi  ],  // z at upper left corner
611
-              z_x0y1 = z_values[cell_xi  ][cell_yi+1],  // z at lower right corner
612
-              z_x1y1 = z_values[cell_xi+1][cell_yi+1];  // z at upper right corner
557
+      float z_x0y0 = z_values[cell_xi  ][cell_yi  ],  // z at lower left corner
558
+            z_x1y0 = z_values[cell_xi+1][cell_yi  ],  // z at upper left corner
559
+            z_x0y1 = z_values[cell_xi  ][cell_yi+1],  // z at lower right corner
560
+            z_x1y1 = z_values[cell_xi+1][cell_yi+1];  // z at upper right corner
613 561
 
614
-        if (isnan(z_x0y0)) z_x0y0 = 0;              // ideally activating planner.leveling_active (G29 A)
615
-        if (isnan(z_x1y0)) z_x1y0 = 0;              //   should refuse if any invalid mesh points
616
-        if (isnan(z_x0y1)) z_x0y1 = 0;              //   in order to avoid isnan tests per cell,
617
-        if (isnan(z_x1y1)) z_x1y1 = 0;              //   thus guessing zero for undefined points
562
+      if (isnan(z_x0y0)) z_x0y0 = 0;              // ideally activating planner.leveling_active (G29 A)
563
+      if (isnan(z_x1y0)) z_x1y0 = 0;              //   should refuse if any invalid mesh points
564
+      if (isnan(z_x0y1)) z_x0y1 = 0;              //   in order to avoid isnan tests per cell,
565
+      if (isnan(z_x1y1)) z_x1y1 = 0;              //   thus guessing zero for undefined points
618 566
 
619
-        float cx = raw[X_AXIS] - x0,   // cell-relative x and y
620
-              cy = raw[Y_AXIS] - y0;
567
+      float cx = raw[X_AXIS] - x0,   // cell-relative x and y
568
+            cy = raw[Y_AXIS] - y0;
621 569
 
622
-        const float z_xmy0 = (z_x1y0 - z_x0y0) * (1.0 / (MESH_X_DIST)),   // z slope per x along y0 (lower left to lower right)
623
-                    z_xmy1 = (z_x1y1 - z_x0y1) * (1.0 / (MESH_X_DIST));   // z slope per x along y1 (upper left to upper right)
570
+      const float z_xmy0 = (z_x1y0 - z_x0y0) * (1.0 / (MESH_X_DIST)),   // z slope per x along y0 (lower left to lower right)
571
+                  z_xmy1 = (z_x1y1 - z_x0y1) * (1.0 / (MESH_X_DIST));   // z slope per x along y1 (upper left to upper right)
624 572
 
625
-              float z_cxy0 = z_x0y0 + z_xmy0 * cx;            // z height along y0 at cx (changes for each cx in cell)
573
+            float z_cxy0 = z_x0y0 + z_xmy0 * cx;            // z height along y0 at cx (changes for each cx in cell)
626 574
 
627
-        const float z_cxy1 = z_x0y1 + z_xmy1 * cx,            // z height along y1 at cx
628
-                    z_cxyd = z_cxy1 - z_cxy0;                 // z height difference along cx from y0 to y1
575
+      const float z_cxy1 = z_x0y1 + z_xmy1 * cx,            // z height along y1 at cx
576
+                  z_cxyd = z_cxy1 - z_cxy0;                 // z height difference along cx from y0 to y1
629 577
 
630
-              float z_cxym = z_cxyd * (1.0 / (MESH_Y_DIST));  // z slope per y along cx from y0 to y1 (changes for each cx in cell)
578
+            float z_cxym = z_cxyd * (1.0 / (MESH_Y_DIST));  // z slope per y along cx from y0 to y1 (changes for each cx in cell)
631 579
 
632
-        //    float z_cxcy = z_cxy0 + z_cxym * cy;            // interpolated mesh z height along cx at cy (do inside the segment loop)
580
+      //    float z_cxcy = z_cxy0 + z_cxym * cy;            // interpolated mesh z height along cx at cy (do inside the segment loop)
633 581
 
634
-        // As subsequent segments step through this cell, the z_cxy0 intercept will change
635
-        // and the z_cxym slope will change, both as a function of cx within the cell, and
636
-        // each change by a constant for fixed segment lengths.
582
+      // As subsequent segments step through this cell, the z_cxy0 intercept will change
583
+      // and the z_cxym slope will change, both as a function of cx within the cell, and
584
+      // each change by a constant for fixed segment lengths.
637 585
 
638
-        const float z_sxy0 = z_xmy0 * diff[X_AXIS],                                     // per-segment adjustment to z_cxy0
639
-                    z_sxym = (z_xmy1 - z_xmy0) * (1.0 / (MESH_Y_DIST)) * diff[X_AXIS];  // per-segment adjustment to z_cxym
586
+      const float z_sxy0 = z_xmy0 * diff[X_AXIS],                                     // per-segment adjustment to z_cxy0
587
+                  z_sxym = (z_xmy1 - z_xmy0) * (1.0 / (MESH_Y_DIST)) * diff[X_AXIS];  // per-segment adjustment to z_cxym
640 588
 
641
-        for(;;) {  // for all segments within this mesh cell
589
+      for(;;) {  // for all segments within this mesh cell
642 590
 
643
-          if (--segments == 0)                      // if this is last segment, use rtarget for exact
644
-            COPY(raw, rtarget);
591
+        if (--segments == 0)                      // if this is last segment, use rtarget for exact
592
+          COPY(raw, rtarget);
645 593
 
646
-          const float z_cxcy = (z_cxy0 + z_cxym * cy) // interpolated mesh z height along cx at cy
647
-            #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
648
-              * fade_scaling_factor                   // apply fade factor to interpolated mesh height
649
-            #endif
650
-          ;
594
+        const float z_cxcy = (z_cxy0 + z_cxym * cy) // interpolated mesh z height along cx at cy
595
+          #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
596
+            * fade_scaling_factor                   // apply fade factor to interpolated mesh height
597
+          #endif
598
+        ;
651 599
 
652
-          const float z = raw[Z_AXIS];
653
-          raw[Z_AXIS] += z_cxcy;
654
-          ubl_buffer_segment_raw(raw, feedrate);
655
-          raw[Z_AXIS] = z;
600
+        const float z = raw[Z_AXIS];
601
+        raw[Z_AXIS] += z_cxcy;
602
+        ubl_buffer_segment_raw(raw, feedrate);
603
+        raw[Z_AXIS] = z;
656 604
 
657
-          if (segments == 0)                        // done with last segment
658
-            return false;                           // did not set_current_from_destination()
605
+        if (segments == 0)                        // done with last segment
606
+          return false;                           // did not set_current_from_destination()
659 607
 
660
-          LOOP_XYZE(i) raw[i] += diff[i];
608
+        LOOP_XYZE(i) raw[i] += diff[i];
661 609
 
662
-          cx += diff[X_AXIS];
663
-          cy += diff[Y_AXIS];
610
+        cx += diff[X_AXIS];
611
+        cy += diff[Y_AXIS];
664 612
 
665
-          if (!WITHIN(cx, 0, MESH_X_DIST) || !WITHIN(cy, 0, MESH_Y_DIST))    // done within this cell, break to next
666
-            break;
613
+        if (!WITHIN(cx, 0, MESH_X_DIST) || !WITHIN(cy, 0, MESH_Y_DIST))    // done within this cell, break to next
614
+          break;
667 615
 
668
-          // Next segment still within same mesh cell, adjust the per-segment
669
-          // slope and intercept to compute next z height.
616
+        // Next segment still within same mesh cell, adjust the per-segment
617
+        // slope and intercept to compute next z height.
670 618
 
671
-          z_cxy0 += z_sxy0;   // adjust z_cxy0 by per-segment z_sxy0
672
-          z_cxym += z_sxym;   // adjust z_cxym by per-segment z_sxym
619
+        z_cxy0 += z_sxy0;   // adjust z_cxy0 by per-segment z_sxy0
620
+        z_cxym += z_sxym;   // adjust z_cxym by per-segment z_sxym
673 621
 
674
-        } // segment loop
675
-      } // cell loop
676
-    }
622
+      } // segment loop
623
+    } // cell loop
624
+  }
677 625
 
678
-  #endif // UBL_DELTA
626
+#endif // UBL_SEGMENTED
679 627
 
680 628
 #endif // AUTO_BED_LEVELING_UBL

+ 4
- 4
Marlin/src/gcode/bedlevel/G26.cpp 查看文件

@@ -220,7 +220,7 @@ mesh_index_pair find_closest_circle_to_print(const float &X, const float &Y) {
220 220
 void G26_line_to_destination(const float &feed_rate) {
221 221
   const float save_feedrate = feedrate_mm_s;
222 222
   feedrate_mm_s = feed_rate;      // use specified feed rate
223
-  prepare_move_to_destination();  // will ultimately call ubl.line_to_destination_cartesian or ubl.prepare_linear_move_to for UBL_DELTA
223
+  prepare_move_to_destination();  // will ultimately call ubl.line_to_destination_cartesian or ubl.prepare_linear_move_to for UBL_SEGMENTED
224 224
   feedrate_mm_s = save_feedrate;  // restore global feed rate
225 225
 }
226 226
 
@@ -261,16 +261,16 @@ void move_to(const float &rx, const float &ry, const float &z, const float &e_de
261 261
   set_destination_from_current();
262 262
 }
263 263
 
264
-FORCE_INLINE void move_to(const float where[XYZE], const float &de) { move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], de); }
264
+FORCE_INLINE void move_to(const float (&where)[XYZE], const float &de) { move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], de); }
265 265
 
266
-void retract_filament(const float where[XYZE]) {
266
+void retract_filament(const float (&where)[XYZE]) {
267 267
   if (!g26_retracted) { // Only retract if we are not already retracted!
268 268
     g26_retracted = true;
269 269
     move_to(where, -1.0 * g26_retraction_multiplier);
270 270
   }
271 271
 }
272 272
 
273
-void recover_filament(const float where[XYZE]) {
273
+void recover_filament(const float (&where)[XYZE]) {
274 274
   if (g26_retracted) { // Only un-retract if we are retracted.
275 275
     move_to(where, 1.2 * g26_retraction_multiplier);
276 276
     g26_retracted = false;

+ 9
- 4
Marlin/src/gcode/host/M114.cpp 查看文件

@@ -28,7 +28,7 @@
28 28
 
29 29
 #if ENABLED(M114_DETAIL)
30 30
 
31
-  void report_xyze(const float pos[XYZE], const uint8_t n = 4, const uint8_t precision = 3) {
31
+  void report_xyze(const float pos[], const uint8_t n = 4, const uint8_t precision = 3) {
32 32
     char str[12];
33 33
     for (uint8_t i = 0; i < n; i++) {
34 34
       SERIAL_CHAR(' ');
@@ -39,7 +39,7 @@
39 39
     SERIAL_EOL();
40 40
   }
41 41
 
42
-  inline void report_xyz(const float pos[XYZ]) { report_xyze(pos, 3); }
42
+  inline void report_xyz(const float pos[]) { report_xyze(pos, 3); }
43 43
 
44 44
   void report_current_position_detail() {
45 45
 
@@ -80,8 +80,13 @@
80 80
     #endif
81 81
 
82 82
     SERIAL_PROTOCOLPGM("Stepper:");
83
-    const float step_count[XYZE] = { stepper.position(X_AXIS), stepper.position(Y_AXIS), stepper.position(Z_AXIS), stepper.position(E_AXIS) };
84
-    report_xyze(step_count, 4, 0);
83
+    LOOP_XYZE(i) {
84
+      SERIAL_CHAR(' ');
85
+      SERIAL_CHAR(axis_codes[i]);
86
+      SERIAL_CHAR(':');
87
+      SERIAL_PROTOCOL(stepper.position((AxisEnum)i));
88
+    }
89
+    SERIAL_EOL();
85 90
 
86 91
     #if IS_SCARA
87 92
       const float deg[XYZ] = {

+ 9
- 9
Marlin/src/gcode/motion/G2_G3.cpp 查看文件

@@ -44,9 +44,9 @@
44 44
  * options for G2/G3 arc generation. In future these options may be GCode tunable.
45 45
  */
46 46
 void plan_arc(
47
-  float rtarget[XYZE], // Destination position
48
-  float *offset,       // Center of rotation relative to current_position
49
-  uint8_t clockwise    // Clockwise?
47
+  const float (&cart)[XYZE],  // Destination position
48
+  const float (&offset)[2],   // Center of rotation relative to current_position
49
+  const uint8_t clockwise     // Clockwise?
50 50
 ) {
51 51
   #if ENABLED(CNC_WORKSPACE_PLANES)
52 52
     AxisEnum p_axis, q_axis, l_axis;
@@ -66,10 +66,10 @@ void plan_arc(
66 66
   const float radius = HYPOT(r_P, r_Q),
67 67
               center_P = current_position[p_axis] - r_P,
68 68
               center_Q = current_position[q_axis] - r_Q,
69
-              rt_X = rtarget[p_axis] - center_P,
70
-              rt_Y = rtarget[q_axis] - center_Q,
71
-              linear_travel = rtarget[l_axis] - current_position[l_axis],
72
-              extruder_travel = rtarget[E_AXIS] - current_position[E_AXIS];
69
+              rt_X = cart[p_axis] - center_P,
70
+              rt_Y = cart[q_axis] - center_Q,
71
+              linear_travel = cart[l_axis] - current_position[l_axis],
72
+              extruder_travel = cart[E_AXIS] - current_position[E_AXIS];
73 73
 
74 74
   // CCW angle of rotation between position and target from the circle center. Only one atan2() trig computation required.
75 75
   float angular_travel = ATAN2(r_P * rt_Y - r_Q * rt_X, r_P * rt_X + r_Q * rt_Y);
@@ -77,7 +77,7 @@ void plan_arc(
77 77
   if (clockwise) angular_travel -= RADIANS(360);
78 78
 
79 79
   // Make a circle if the angular rotation is 0 and the target is current position
80
-  if (angular_travel == 0 && current_position[p_axis] == rtarget[p_axis] && current_position[q_axis] == rtarget[q_axis])
80
+  if (angular_travel == 0 && current_position[p_axis] == cart[p_axis] && current_position[q_axis] == cart[q_axis])
81 81
     angular_travel = RADIANS(360);
82 82
 
83 83
   const float mm_of_travel = HYPOT(angular_travel * radius, FABS(linear_travel));
@@ -177,7 +177,7 @@ void plan_arc(
177 177
   }
178 178
 
179 179
   // Ensure last segment arrives at target location.
180
-  planner.buffer_line_kinematic(rtarget, fr_mm_s, active_extruder);
180
+  planner.buffer_line_kinematic(cart, fr_mm_s, active_extruder);
181 181
 
182 182
   // As far as the parser is concerned, the position is now == target. In reality the
183 183
   // motion control system might still be processing the action and the real tool position

+ 2
- 2
Marlin/src/gcode/motion/G5.cpp 查看文件

@@ -27,7 +27,7 @@
27 27
 #include "../../module/motion.h"
28 28
 #include "../../module/planner_bezier.h"
29 29
 
30
-void plan_cubic_move(const float offset[4]) {
30
+void plan_cubic_move(const float (&offset)[4]) {
31 31
   cubic_b_spline(current_position, destination, offset, MMS_SCALED(feedrate_mm_s), active_extruder);
32 32
 
33 33
   // As far as the parser is concerned, the position is now == destination. In reality the
@@ -62,7 +62,7 @@ void GcodeSuite::G5() {
62 62
 
63 63
     get_destination_from_command();
64 64
 
65
-    const float offset[] = {
65
+    const float offset[4] = {
66 66
       parser.linearval('I'),
67 67
       parser.linearval('J'),
68 68
       parser.linearval('P'),

+ 9
- 9
Marlin/src/inc/Conditionals_post.h 查看文件

@@ -977,15 +977,15 @@
977 977
 /**
978 978
  * Set granular options based on the specific type of leveling
979 979
  */
980
-#define UBL_DELTA  (ENABLED(AUTO_BED_LEVELING_UBL) && (ENABLED(DELTA) || ENABLED(SEGMENT_LEVELED_MOVES)))
981
-#define ABL_PLANAR (ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_3POINT))
982
-#define ABL_GRID   (ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR))
983
-#define OLDSCHOOL_ABL         (ABL_PLANAR || ABL_GRID)
984
-#define HAS_ABL               (OLDSCHOOL_ABL || ENABLED(AUTO_BED_LEVELING_UBL))
985
-#define HAS_LEVELING          (HAS_ABL || ENABLED(MESH_BED_LEVELING))
986
-#define HAS_AUTOLEVEL         (HAS_ABL && DISABLED(PROBE_MANUALLY))
987
-#define HAS_MESH              (ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(MESH_BED_LEVELING))
988
-#define PLANNER_LEVELING      (OLDSCHOOL_ABL || ENABLED(MESH_BED_LEVELING) || UBL_DELTA)
980
+#define UBL_SEGMENTED  (ENABLED(AUTO_BED_LEVELING_UBL) && (ENABLED(DELTA) || ENABLED(SEGMENT_LEVELED_MOVES)))
981
+#define ABL_PLANAR     (ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_3POINT))
982
+#define ABL_GRID       (ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR))
983
+#define OLDSCHOOL_ABL  (ABL_PLANAR || ABL_GRID)
984
+#define HAS_ABL        (OLDSCHOOL_ABL || ENABLED(AUTO_BED_LEVELING_UBL))
985
+#define HAS_LEVELING   (HAS_ABL || ENABLED(MESH_BED_LEVELING))
986
+#define HAS_AUTOLEVEL  (HAS_ABL && DISABLED(PROBE_MANUALLY))
987
+#define HAS_MESH       (ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(MESH_BED_LEVELING))
988
+#define PLANNER_LEVELING      (OLDSCHOOL_ABL || ENABLED(MESH_BED_LEVELING))
989 989
 #define HAS_PROBING_PROCEDURE (HAS_ABL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST))
990 990
 #if HAS_PROBING_PROCEDURE
991 991
   #define PROBE_BED_WIDTH abs(RIGHT_PROBE_BED_POSITION - (LEFT_PROBE_BED_POSITION))

+ 1
- 4
Marlin/src/inc/SanityCheck.h 查看文件

@@ -603,7 +603,7 @@ static_assert(1 >= 0
603 603
     #error "Delta probably shouldn't use Z_MIN_PROBE_ENDSTOP. Comment out this line to continue."
604 604
   #elif DISABLED(USE_XMAX_PLUG) && DISABLED(USE_YMAX_PLUG) && DISABLED(USE_ZMAX_PLUG)
605 605
     #error "You probably want to use Max Endstops for DELTA!"
606
-  #elif ENABLED(ENABLE_LEVELING_FADE_HEIGHT) && DISABLED(AUTO_BED_LEVELING_BILINEAR) && !UBL_DELTA
606
+  #elif ENABLED(ENABLE_LEVELING_FADE_HEIGHT) && DISABLED(AUTO_BED_LEVELING_BILINEAR) && !UBL_SEGMENTED
607 607
     #error "ENABLE_LEVELING_FADE_HEIGHT on DELTA requires AUTO_BED_LEVELING_BILINEAR or AUTO_BED_LEVELING_UBL."
608 608
   #elif ENABLED(DELTA_AUTO_CALIBRATION) && !(HAS_BED_PROBE || ENABLED(ULTIPANEL))
609 609
     #error "DELTA_AUTO_CALIBRATION requires a probe or LCD Controller."
@@ -1497,9 +1497,6 @@ static_assert(COUNT(sanity_arr_3) <= XYZE_N, "DEFAULT_MAX_ACCELERATION has too m
1497 1497
 #endif
1498 1498
 
1499 1499
 #if ENABLED(SKEW_CORRECTION)
1500
-  #if ENABLED(AUTO_BED_LEVELING_UBL) && !ENABLED(SEGMENT_LEVELED_MOVES)
1501
-    #error "SKEW_CORRECTION with AUTO_BED_LEVELING_UBL requires SEGMENT_LEVELED_MOVES."
1502
-  #endif
1503 1500
   #if !defined(XY_SKEW_FACTOR) && !(defined(XY_DIAG_AC) && defined(XY_DIAG_BD) && defined(XY_SIDE_AD))
1504 1501
     #error "SKEW_CORRECTION requires XY_SKEW_FACTOR or XY_DIAG_AC, XY_DIAG_BD, XY_SIDE_AD."
1505 1502
   #endif

+ 17
- 9
Marlin/src/module/motion.cpp 查看文件

@@ -264,7 +264,7 @@ void buffer_line_to_destination(const float fr_mm_s) {
264 264
 
265 265
     gcode.refresh_cmd_timeout();
266 266
 
267
-    #if UBL_DELTA
267
+    #if UBL_SEGMENTED
268 268
       // ubl segmented line will do z-only moves in single segment
269 269
       ubl.prepare_segmented_line_to(destination, MMS_SCALED(fr_mm_s ? fr_mm_s : feedrate_mm_s));
270 270
     #else
@@ -495,7 +495,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
495 495
 
496 496
 #endif
497 497
 
498
-#if !UBL_DELTA
498
+#if !UBL_SEGMENTED
499 499
 #if IS_KINEMATIC
500 500
 
501 501
   #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
@@ -517,13 +517,19 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
517 517
   /**
518 518
    * Prepare a linear move in a DELTA or SCARA setup.
519 519
    *
520
+   * Called from prepare_move_to_destination as the
521
+   * default Delta/SCARA segmenter.
522
+   *
520 523
    * This calls planner.buffer_line several times, adding
521 524
    * small incremental moves for DELTA or SCARA.
522 525
    *
523 526
    * For Unified Bed Leveling (Delta or Segmented Cartesian)
524 527
    * the ubl.prepare_segmented_line_to method replaces this.
528
+   *
529
+   * For Auto Bed Leveling (Bilinear) with SEGMENT_LEVELED_MOVES
530
+   * this is replaced by segmented_line_to_destination below.
525 531
    */
526
-  inline bool prepare_kinematic_move_to(float rtarget[XYZE]) {
532
+  inline bool prepare_kinematic_move_to(const float (&rtarget)[XYZE]) {
527 533
 
528 534
     // Get the top feedrate of the move in the XY plane
529 535
     const float _feedrate_mm_s = MMS_SCALED(feedrate_mm_s);
@@ -756,7 +762,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
756 762
   }
757 763
 
758 764
 #endif // !IS_KINEMATIC
759
-#endif // !UBL_DELTA
765
+#endif // !UBL_SEGMENTED
760 766
 
761 767
 #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
762 768
   bool extruder_duplication_enabled = false;                              // Used in Dual X mode 2
@@ -790,7 +796,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
790 796
    *
791 797
    * Return true if current_position[] was set to destination[]
792 798
    */
793
-  inline bool prepare_move_to_destination_dualx() {
799
+  inline bool dual_x_carriage_unpark() {
794 800
     if (active_extruder_parked) {
795 801
       switch (dual_x_carriage_mode) {
796 802
         case DXC_FULL_CONTROL_MODE:
@@ -859,7 +865,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
859 865
           break;
860 866
       }
861 867
     }
862
-    return prepare_move_to_destination_cartesian();
868
+    return false;
863 869
   }
864 870
 
865 871
 #endif // DUAL_X_CARRIAGE
@@ -900,13 +906,15 @@ void prepare_move_to_destination() {
900 906
 
901 907
   #endif // PREVENT_COLD_EXTRUSION || PREVENT_LENGTHY_EXTRUDE
902 908
 
909
+  #if ENABLED(DUAL_X_CARRIAGE)
910
+    if (dual_x_carriage_unpark()) return;
911
+  #endif
912
+
903 913
   if (
904
-    #if UBL_DELTA // Also works for CARTESIAN (smaller segments follow mesh more closely)
914
+    #if UBL_SEGMENTED
905 915
       ubl.prepare_segmented_line_to(destination, MMS_SCALED(feedrate_mm_s))
906 916
     #elif IS_KINEMATIC
907 917
       prepare_kinematic_move_to(destination)
908
-    #elif ENABLED(DUAL_X_CARRIAGE)
909
-      prepare_move_to_destination_dualx()
910 918
     #else
911 919
       prepare_move_to_destination_cartesian()
912 920
     #endif

+ 14
- 28
Marlin/src/module/planner.cpp 查看文件

@@ -580,14 +580,7 @@ void Planner::calculate_volumetric_multipliers() {
580 580
   void Planner::apply_leveling(float &rx, float &ry, float &rz) {
581 581
 
582 582
     #if ENABLED(SKEW_CORRECTION)
583
-      if (WITHIN(rx, X_MIN_POS + 1, X_MAX_POS) && WITHIN(ry, Y_MIN_POS + 1, Y_MAX_POS)) {
584
-        const float tempry = ry - (rz * planner.yz_skew_factor),
585
-                    temprx = rx - (ry * planner.xy_skew_factor) - (rz * (planner.xz_skew_factor - (planner.xy_skew_factor * planner.yz_skew_factor)));
586
-        if (WITHIN(temprx, X_MIN_POS, X_MAX_POS) && WITHIN(tempry, Y_MIN_POS, Y_MAX_POS)) {
587
-          rx = temprx;
588
-          ry = tempry;
589
-        }
590
-      }
583
+      skew(rx, ry, rz);
591 584
     #endif
592 585
 
593 586
     if (!leveling_active) return;
@@ -616,7 +609,7 @@ void Planner::calculate_volumetric_multipliers() {
616 609
       #endif
617 610
 
618 611
       rz += (
619
-        #if ENABLED(AUTO_BED_LEVELING_UBL) // UBL_DELTA
612
+        #if ENABLED(AUTO_BED_LEVELING_UBL)
620 613
           ubl.get_z_correction(rx, ry) * fade_scaling_factor
621 614
         #elif ENABLED(MESH_BED_LEVELING)
622 615
           mbl.get_z(rx, ry
@@ -678,14 +671,7 @@ void Planner::calculate_volumetric_multipliers() {
678 671
     }
679 672
 
680 673
     #if ENABLED(SKEW_CORRECTION)
681
-      if (WITHIN(raw[X_AXIS], X_MIN_POS, X_MAX_POS) && WITHIN(raw[Y_AXIS], Y_MIN_POS, Y_MAX_POS)) {
682
-        const float temprx = raw[X_AXIS] + raw[Y_AXIS] * planner.xy_skew_factor + raw[Z_AXIS] * planner.xz_skew_factor,
683
-                    tempry = raw[Y_AXIS] + raw[Z_AXIS] * planner.yz_skew_factor;
684
-        if (WITHIN(temprx, X_MIN_POS, X_MAX_POS) && WITHIN(tempry, Y_MIN_POS, Y_MAX_POS)) {
685
-          raw[X_AXIS] = temprx;
686
-          raw[Y_AXIS] = tempry;
687
-        }
688
-      }
674
+      unskew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]);
689 675
     #endif
690 676
   }
691 677
 
@@ -1365,7 +1351,7 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE], float fr_mm_s, const
1365 1351
 } // _buffer_steps()
1366 1352
 
1367 1353
 /**
1368
- * Planner::_buffer_line
1354
+ * Planner::buffer_segment
1369 1355
  *
1370 1356
  * Add a new linear movement to the buffer in axis units.
1371 1357
  *
@@ -1375,7 +1361,7 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE], float fr_mm_s, const
1375 1361
  *  fr_mm_s   - (target) speed of the move
1376 1362
  *  extruder  - target extruder
1377 1363
  */
1378
-void Planner::_buffer_line(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder) {
1364
+void Planner::buffer_segment(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder) {
1379 1365
   // When changing extruders recalculate steps corresponding to the E position
1380 1366
   #if ENABLED(DISTINCT_E_FACTORS)
1381 1367
     if (last_extruder != extruder && axis_steps_per_mm[E_AXIS_N] != axis_steps_per_mm[E_AXIS + last_extruder]) {
@@ -1394,7 +1380,7 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const
1394 1380
   };
1395 1381
 
1396 1382
   /* <-- add a slash to enable
1397
-    SERIAL_ECHOPAIR("  _buffer_line FR:", fr_mm_s);
1383
+    SERIAL_ECHOPAIR("  buffer_segment FR:", fr_mm_s);
1398 1384
     #if IS_KINEMATIC
1399 1385
       SERIAL_ECHOPAIR(" A:", a);
1400 1386
       SERIAL_ECHOPAIR(" (", position[A_AXIS]);
@@ -1441,7 +1427,7 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const
1441 1427
 
1442 1428
   stepper.wake_up();
1443 1429
 
1444
-} // _buffer_line()
1430
+} // buffer_segment()
1445 1431
 
1446 1432
 /**
1447 1433
  * Directly set the planner XYZ position (and stepper positions)
@@ -1466,18 +1452,18 @@ void Planner::_set_position_mm(const float &a, const float &b, const float &c, c
1466 1452
   ZERO(previous_speed);
1467 1453
 }
1468 1454
 
1469
-void Planner::set_position_mm_kinematic(const float position[NUM_AXIS]) {
1455
+void Planner::set_position_mm_kinematic(const float (&cart)[XYZE]) {
1470 1456
   #if PLANNER_LEVELING
1471
-    float lpos[XYZ] = { position[X_AXIS], position[Y_AXIS], position[Z_AXIS] };
1472
-    apply_leveling(lpos);
1457
+    float raw[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] };
1458
+    apply_leveling(raw);
1473 1459
   #else
1474
-    const float * const lpos = position;
1460
+    const float (&raw)[XYZE] = cart;
1475 1461
   #endif
1476 1462
   #if IS_KINEMATIC
1477
-    inverse_kinematics(lpos);
1478
-    _set_position_mm(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], position[E_AXIS]);
1463
+    inverse_kinematics(raw);
1464
+    _set_position_mm(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS]);
1479 1465
   #else
1480
-    _set_position_mm(lpos[X_AXIS], lpos[Y_AXIS], lpos[Z_AXIS], position[E_AXIS]);
1466
+    _set_position_mm(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_AXIS]);
1481 1467
   #endif
1482 1468
 }
1483 1469
 

+ 34
- 10
Marlin/src/module/planner.h 查看文件

@@ -146,7 +146,7 @@ class Planner {
146 146
      *            head!=tail : blocks are in the buffer
147 147
      *   head==(tail-1)%size : the buffer is full
148 148
      *
149
-     *  Writer of head is Planner::_buffer_line().
149
+     *  Writer of head is Planner::buffer_segment().
150 150
      *  Reader of tail is Stepper::isr(). Always consider tail busy / read-only
151 151
      */
152 152
     static block_t block_buffer[BLOCK_BUFFER_SIZE];
@@ -345,6 +345,30 @@ class Planner {
345 345
 
346 346
     #endif
347 347
 
348
+    #if ENABLED(SKEW_CORRECTION)
349
+
350
+      FORCE_INLINE static void skew(float &cx, float &cy, const float &cz) {
351
+        if (WITHIN(cx, X_MIN_POS + 1, X_MAX_POS) && WITHIN(cy, Y_MIN_POS + 1, Y_MAX_POS)) {
352
+          const float sx = cx - (cy * xy_skew_factor) - (cz * (xz_skew_factor - (xy_skew_factor * yz_skew_factor))),
353
+                      sy = cy - (cz * yz_skew_factor);
354
+          if (WITHIN(sx, X_MIN_POS, X_MAX_POS) && WITHIN(sy, Y_MIN_POS, Y_MAX_POS)) {
355
+            cx = sx; cy = sy;
356
+          }
357
+        }
358
+      }
359
+
360
+      FORCE_INLINE static void unskew(float &cx, float &cy, const float &cz) {
361
+        if (WITHIN(cx, X_MIN_POS, X_MAX_POS) && WITHIN(cy, Y_MIN_POS, Y_MAX_POS)) {
362
+          const float sx = cx + cy * xy_skew_factor + cz * xz_skew_factor,
363
+                      sy = cy + cz * yz_skew_factor;
364
+          if (WITHIN(sx, X_MIN_POS, X_MAX_POS) && WITHIN(sy, Y_MIN_POS, Y_MAX_POS)) {
365
+            cx = sx; cy = sy;
366
+          }
367
+        }
368
+      }
369
+
370
+    #endif // SKEW_CORRECTION
371
+
348 372
     #if PLANNER_LEVELING
349 373
 
350 374
       #define ARG_X float rx
@@ -356,7 +380,7 @@ class Planner {
356 380
        * as it will be given to the planner and steppers.
357 381
        */
358 382
       static void apply_leveling(float &rx, float &ry, float &rz);
359
-      static void apply_leveling(float raw[XYZ]) { apply_leveling(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
383
+      static void apply_leveling(float (&raw)[XYZ]) { apply_leveling(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
360 384
       static void unapply_leveling(float raw[XYZ]);
361 385
 
362 386
     #else
@@ -379,7 +403,7 @@ class Planner {
379 403
     static void _buffer_steps(const int32_t (&target)[XYZE], float fr_mm_s, const uint8_t extruder);
380 404
 
381 405
     /**
382
-     * Planner::_buffer_line
406
+     * Planner::buffer_segment
383 407
      *
384 408
      * Add a new linear movement to the buffer in axis units.
385 409
      *
@@ -389,7 +413,7 @@ class Planner {
389 413
      *  fr_mm_s   - (target) speed of the move
390 414
      *  extruder  - target extruder
391 415
      */
392
-    static void _buffer_line(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder);
416
+    static void buffer_segment(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder);
393 417
 
394 418
     static void _set_position_mm(const float &a, const float &b, const float &c, const float &e);
395 419
 
@@ -409,7 +433,7 @@ class Planner {
409 433
       #if PLANNER_LEVELING && IS_CARTESIAN
410 434
         apply_leveling(rx, ry, rz);
411 435
       #endif
412
-      _buffer_line(rx, ry, rz, e, fr_mm_s, extruder);
436
+      buffer_segment(rx, ry, rz, e, fr_mm_s, extruder);
413 437
     }
414 438
 
415 439
     /**
@@ -421,18 +445,18 @@ class Planner {
421 445
      *  fr_mm_s  - (target) speed of the move (mm/s)
422 446
      *  extruder - target extruder
423 447
      */
424
-    FORCE_INLINE static void buffer_line_kinematic(const float cart[XYZE], const float &fr_mm_s, const uint8_t extruder) {
448
+    FORCE_INLINE static void buffer_line_kinematic(const float (&cart)[XYZE], const float &fr_mm_s, const uint8_t extruder) {
425 449
       #if PLANNER_LEVELING
426 450
         float raw[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] };
427 451
         apply_leveling(raw);
428 452
       #else
429
-        const float * const raw = cart;
453
+        const float (&raw)[XYZE] = cart;
430 454
       #endif
431 455
       #if IS_KINEMATIC
432 456
         inverse_kinematics(raw);
433
-        _buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS], fr_mm_s, extruder);
457
+        buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS], fr_mm_s, extruder);
434 458
       #else
435
-        _buffer_line(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_AXIS], fr_mm_s, extruder);
459
+        buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_AXIS], fr_mm_s, extruder);
436 460
       #endif
437 461
     }
438 462
 
@@ -451,7 +475,7 @@ class Planner {
451 475
       #endif
452 476
       _set_position_mm(rx, ry, rz, e);
453 477
     }
454
-    static void set_position_mm_kinematic(const float position[NUM_AXIS]);
478
+    static void set_position_mm_kinematic(const float (&cart)[XYZE]);
455 479
     static void set_position_mm(const AxisEnum axis, const float &v);
456 480
     FORCE_INLINE static void set_z_position_mm(const float &z) { set_position_mm(Z_AXIS, z); }
457 481
     FORCE_INLINE static void set_e_position_mm(const float &e) { set_position_mm(AxisEnum(E_AXIS), e); }

+ 1
- 1
Marlin/src/module/probe.cpp 查看文件

@@ -107,7 +107,7 @@ inline void do_probe_raise(const float z_raise) {
107 107
 
108 108
 #elif ENABLED(Z_PROBE_ALLEN_KEY)
109 109
 
110
-  FORCE_INLINE void do_blocking_move_to(const float raw[XYZ], const float &fr_mm_s) {
110
+  FORCE_INLINE void do_blocking_move_to(const float (&raw)[XYZ], const float &fr_mm_s) {
111 111
     do_blocking_move_to(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], fr_mm_s);
112 112
   }
113 113
 

+ 3
- 3
Marlin/src/module/stepper.cpp 查看文件

@@ -1193,7 +1193,7 @@ void Stepper::set_e_position(const long &e) {
1193 1193
 /**
1194 1194
  * Get a stepper's position in steps.
1195 1195
  */
1196
-long Stepper::position(AxisEnum axis) {
1196
+long Stepper::position(const AxisEnum axis) {
1197 1197
   CRITICAL_SECTION_START;
1198 1198
   const long count_pos = count_position[axis];
1199 1199
   CRITICAL_SECTION_END;
@@ -1204,7 +1204,7 @@ long Stepper::position(AxisEnum axis) {
1204 1204
  * Get an axis position according to stepper position(s)
1205 1205
  * For CORE machines apply translation from ABC to XYZ.
1206 1206
  */
1207
-float Stepper::get_axis_position_mm(AxisEnum axis) {
1207
+float Stepper::get_axis_position_mm(const AxisEnum axis) {
1208 1208
   float axis_steps;
1209 1209
   #if IS_CORE
1210 1210
     // Requesting one of the "core" axes?
@@ -1242,7 +1242,7 @@ void Stepper::quick_stop() {
1242 1242
   #endif
1243 1243
 }
1244 1244
 
1245
-void Stepper::endstop_triggered(AxisEnum axis) {
1245
+void Stepper::endstop_triggered(const AxisEnum axis) {
1246 1246
 
1247 1247
   #if IS_CORE
1248 1248
 

+ 6
- 6
Marlin/src/module/stepper.h 查看文件

@@ -183,7 +183,7 @@ class Stepper {
183 183
     //
184 184
     // Get the position of a stepper, in steps
185 185
     //
186
-    static long position(AxisEnum axis);
186
+    static long position(const AxisEnum axis);
187 187
 
188 188
     //
189 189
     // Report the positions of the steppers, in steps
@@ -193,13 +193,13 @@ class Stepper {
193 193
     //
194 194
     // Get the position (mm) of an axis based on stepper position(s)
195 195
     //
196
-    static float get_axis_position_mm(AxisEnum axis);
196
+    static float get_axis_position_mm(const AxisEnum axis);
197 197
 
198 198
     //
199 199
     // SCARA AB axes are in degrees, not mm
200 200
     //
201 201
     #if IS_SCARA
202
-      FORCE_INLINE static float get_axis_position_degrees(AxisEnum axis) { return get_axis_position_mm(axis); }
202
+      FORCE_INLINE static float get_axis_position_degrees(const AxisEnum axis) { return get_axis_position_mm(axis); }
203 203
     #endif
204 204
 
205 205
     //
@@ -221,7 +221,7 @@ class Stepper {
221 221
     //
222 222
     // The direction of a single motor
223 223
     //
224
-    FORCE_INLINE static bool motor_direction(AxisEnum axis) { return TEST(last_direction_bits, axis); }
224
+    FORCE_INLINE static bool motor_direction(const AxisEnum axis) { return TEST(last_direction_bits, axis); }
225 225
 
226 226
     #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM
227 227
       static void digitalPotWrite(const int16_t address, const int16_t value);
@@ -263,12 +263,12 @@ class Stepper {
263 263
     //
264 264
     // Handle a triggered endstop
265 265
     //
266
-    static void endstop_triggered(AxisEnum axis);
266
+    static void endstop_triggered(const AxisEnum axis);
267 267
 
268 268
     //
269 269
     // Triggered position of an axis in mm (not core-savvy)
270 270
     //
271
-    FORCE_INLINE static float triggered_position_mm(AxisEnum axis) {
271
+    FORCE_INLINE static float triggered_position_mm(const AxisEnum axis) {
272 272
       return endstops_trigsteps[axis] * planner.steps_to_mm[axis];
273 273
     }
274 274
 

正在加载...
取消
保存