瀏覽代碼

Overhaul of the planner (#11578)

- Move FWRETRACT to the planner
- Combine leveling, skew, etc. in a single modifier method
- Have kinematic and non-kinematic moves call one planner method
Thomas Moore 6 年之前
父節點
當前提交
c437bb08f1
共有 39 個檔案被更改,包括 652 行新增594 行删除
  1. 3
    3
      Marlin/src/Marlin.cpp
  2. 0
    3
      Marlin/src/config/examples/delta/FLSUN/auto_calibrate/Configuration.h
  3. 0
    3
      Marlin/src/config/examples/delta/FLSUN/kossel/Configuration.h
  4. 0
    3
      Marlin/src/config/examples/delta/FLSUN/kossel_mini/Configuration.h
  5. 0
    3
      Marlin/src/config/examples/delta/Hatchbox_Alpha/Configuration.h
  6. 0
    3
      Marlin/src/config/examples/delta/generic/Configuration.h
  7. 0
    3
      Marlin/src/config/examples/delta/kossel_mini/Configuration.h
  8. 0
    3
      Marlin/src/config/examples/delta/kossel_pro/Configuration.h
  9. 0
    3
      Marlin/src/config/examples/delta/kossel_xl/Configuration.h
  10. 17
    70
      Marlin/src/feature/bedlevel/bedlevel.cpp
  11. 21
    52
      Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp
  12. 22
    25
      Marlin/src/feature/fwretract.cpp
  13. 2
    1
      Marlin/src/feature/fwretract.h
  14. 1
    1
      Marlin/src/feature/pause.cpp
  15. 27
    0
      Marlin/src/feature/power_loss_recovery.cpp
  16. 4
    0
      Marlin/src/feature/power_loss_recovery.h
  17. 1
    1
      Marlin/src/gcode/bedlevel/abl/G29.cpp
  18. 3
    3
      Marlin/src/gcode/calibrate/G28.cpp
  19. 1
    1
      Marlin/src/gcode/calibrate/M852.cpp
  20. 8
    3
      Marlin/src/gcode/config/M200-M205.cpp
  21. 1
    1
      Marlin/src/gcode/config/M92.cpp
  22. 1
    1
      Marlin/src/gcode/geometry/G92.cpp
  23. 1
    1
      Marlin/src/gcode/host/M114.cpp
  24. 22
    59
      Marlin/src/gcode/motion/G2_G3.cpp
  25. 2
    2
      Marlin/src/gcode/probe/G38.cpp
  26. 4
    3
      Marlin/src/inc/Conditionals_post.h
  27. 14
    7
      Marlin/src/lcd/ultralcd.cpp
  28. 35
    12
      Marlin/src/module/configuration_store.cpp
  29. 5
    5
      Marlin/src/module/delta.cpp
  30. 6
    5
      Marlin/src/module/delta.h
  31. 77
    136
      Marlin/src/module/motion.cpp
  32. 0
    23
      Marlin/src/module/motion.h
  33. 189
    56
      Marlin/src/module/planner.cpp
  34. 153
    68
      Marlin/src/module/planner.h
  35. 6
    6
      Marlin/src/module/planner_bezier.cpp
  36. 1
    1
      Marlin/src/module/probe.cpp
  37. 1
    1
      Marlin/src/module/scara.cpp
  38. 6
    5
      Marlin/src/module/scara.h
  39. 18
    18
      Marlin/src/module/tool_change.cpp

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

@@ -275,7 +275,7 @@ void quickstop_stepper() {
275 275
   planner.quick_stop();
276 276
   planner.synchronize();
277 277
   set_current_from_steppers_for_axis(ALL_AXES);
278
-  SYNC_PLAN_POSITION_KINEMATIC();
278
+  sync_plan_position();
279 279
 }
280 280
 
281 281
 void enable_all_steppers() {
@@ -465,7 +465,7 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
465 465
 
466 466
       const float olde = current_position[E_AXIS];
467 467
       current_position[E_AXIS] += EXTRUDER_RUNOUT_EXTRUDE;
468
-      planner.buffer_line_kinematic(current_position, MMM_TO_MMS(EXTRUDER_RUNOUT_SPEED), active_extruder);
468
+      planner.buffer_line(current_position, MMM_TO_MMS(EXTRUDER_RUNOUT_SPEED), active_extruder);
469 469
       current_position[E_AXIS] = olde;
470 470
       planner.set_e_position_mm(olde);
471 471
       planner.synchronize();
@@ -766,7 +766,7 @@ void setup() {
766 766
   #endif
767 767
 
768 768
   // Vital to init stepper/planner equivalent for current_position
769
-  SYNC_PLAN_POSITION_KINEMATIC();
769
+  sync_plan_position();
770 770
 
771 771
   thermalManager.init();    // Initialize temperature loop
772 772
 

+ 0
- 3
Marlin/src/config/examples/delta/FLSUN/auto_calibrate/Configuration.h 查看文件

@@ -539,9 +539,6 @@
539 539
   // and processor overload (too many expensive sqrt calls).
540 540
   #define DELTA_SEGMENTS_PER_SECOND 160
541 541
 
542
-  // Convert feedrates to apply to the Effector instead of the Carriages
543
-  #define DELTA_FEEDRATE_SCALING
544
-
545 542
   // After homing move down to a height where XY movement is unconstrained
546 543
   //#define DELTA_HOME_TO_SAFE_ZONE
547 544
 

+ 0
- 3
Marlin/src/config/examples/delta/FLSUN/kossel/Configuration.h 查看文件

@@ -539,9 +539,6 @@
539 539
   // and processor overload (too many expensive sqrt calls).
540 540
   #define DELTA_SEGMENTS_PER_SECOND 160
541 541
 
542
-  // Convert feedrates to apply to the Effector instead of the Carriages
543
-  #define DELTA_FEEDRATE_SCALING
544
-
545 542
   // After homing move down to a height where XY movement is unconstrained
546 543
   //#define DELTA_HOME_TO_SAFE_ZONE
547 544
 

+ 0
- 3
Marlin/src/config/examples/delta/FLSUN/kossel_mini/Configuration.h 查看文件

@@ -539,9 +539,6 @@
539 539
   // and processor overload (too many expensive sqrt calls).
540 540
   #define DELTA_SEGMENTS_PER_SECOND 160
541 541
 
542
-  // Convert feedrates to apply to the Effector instead of the Carriages
543
-  #define DELTA_FEEDRATE_SCALING
544
-
545 542
   // After homing move down to a height where XY movement is unconstrained
546 543
   //#define DELTA_HOME_TO_SAFE_ZONE
547 544
 

+ 0
- 3
Marlin/src/config/examples/delta/Hatchbox_Alpha/Configuration.h 查看文件

@@ -544,9 +544,6 @@
544 544
   // and processor overload (too many expensive sqrt calls).
545 545
   #define DELTA_SEGMENTS_PER_SECOND 200
546 546
 
547
-  // Convert feedrates to apply to the Effector instead of the Carriages
548
-  #define DELTA_FEEDRATE_SCALING
549
-
550 547
   // After homing move down to a height where XY movement is unconstrained
551 548
   //#define DELTA_HOME_TO_SAFE_ZONE
552 549
 

+ 0
- 3
Marlin/src/config/examples/delta/generic/Configuration.h 查看文件

@@ -529,9 +529,6 @@
529 529
   // and processor overload (too many expensive sqrt calls).
530 530
   #define DELTA_SEGMENTS_PER_SECOND 200
531 531
 
532
-  // Convert feedrates to apply to the Effector instead of the Carriages
533
-  #define DELTA_FEEDRATE_SCALING
534
-
535 532
   // After homing move down to a height where XY movement is unconstrained
536 533
   //#define DELTA_HOME_TO_SAFE_ZONE
537 534
 

+ 0
- 3
Marlin/src/config/examples/delta/kossel_mini/Configuration.h 查看文件

@@ -529,9 +529,6 @@
529 529
   // and processor overload (too many expensive sqrt calls).
530 530
   #define DELTA_SEGMENTS_PER_SECOND 200
531 531
 
532
-  // Convert feedrates to apply to the Effector instead of the Carriages
533
-  #define DELTA_FEEDRATE_SCALING
534
-
535 532
   // After homing move down to a height where XY movement is unconstrained
536 533
   //#define DELTA_HOME_TO_SAFE_ZONE
537 534
 

+ 0
- 3
Marlin/src/config/examples/delta/kossel_pro/Configuration.h 查看文件

@@ -515,9 +515,6 @@
515 515
   // and processor overload (too many expensive sqrt calls).
516 516
   #define DELTA_SEGMENTS_PER_SECOND 160
517 517
 
518
-  // Convert feedrates to apply to the Effector instead of the Carriages
519
-  #define DELTA_FEEDRATE_SCALING
520
-
521 518
   // After homing move down to a height where XY movement is unconstrained
522 519
   //#define DELTA_HOME_TO_SAFE_ZONE
523 520
 

+ 0
- 3
Marlin/src/config/examples/delta/kossel_xl/Configuration.h 查看文件

@@ -533,9 +533,6 @@
533 533
   // and processor overload (too many expensive sqrt calls).
534 534
   #define DELTA_SEGMENTS_PER_SECOND 160
535 535
 
536
-  // Convert feedrates to apply to the Effector instead of the Carriages
537
-  #define DELTA_FEEDRATE_SCALING
538
-
539 536
   // After homing move down to a height where XY movement is unconstrained
540 537
   //#define DELTA_HOME_TO_SAFE_ZONE
541 538
 

+ 17
- 70
Marlin/src/feature/bedlevel/bedlevel.cpp 查看文件

@@ -25,15 +25,12 @@
25 25
 #if HAS_LEVELING
26 26
 
27 27
 #include "bedlevel.h"
28
+#include "../../module/planner.h"
28 29
 
29 30
 #if ENABLED(MESH_BED_LEVELING) || ENABLED(PROBE_MANUALLY)
30 31
   #include "../../module/motion.h"
31 32
 #endif
32 33
 
33
-#if PLANNER_LEVELING
34
-  #include "../../module/planner.h"
35
-#endif
36
-
37 34
 #if ENABLED(PROBE_MANUALLY)
38 35
   bool g29_in_progress = false;
39 36
 #endif
@@ -79,74 +76,24 @@ void set_bed_leveling_enabled(const bool enable/*=true*/) {
79 76
 
80 77
     planner.synchronize();
81 78
 
82
-    #if ENABLED(MESH_BED_LEVELING)
83
-
84
-      if (!enable)
85
-        planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS]);
86
-
87
-      const bool enabling = enable && leveling_is_valid();
88
-      planner.leveling_active = enabling;
89
-      if (enabling) planner.unapply_leveling(current_position);
90
-
91
-    #elif ENABLED(AUTO_BED_LEVELING_UBL)
92
-      #if PLANNER_LEVELING
93
-        if (planner.leveling_active) {                   // leveling from on to off
94
-          // change unleveled current_position to physical current_position without moving steppers.
95
-          planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS]);
96
-          planner.leveling_active = false;                   // disable only AFTER calling apply_leveling
97
-        }
98
-        else {                                        // leveling from off to on
99
-          planner.leveling_active = true;                    // enable BEFORE calling unapply_leveling, otherwise ignored
100
-          // change physical current_position to unleveled current_position without moving steppers.
101
-          planner.unapply_leveling(current_position);
102
-        }
103
-      #else
104
-        // UBL equivalents for apply/unapply_leveling
105
-        #if ENABLED(SKEW_CORRECTION)
106
-          float pos[XYZ] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] };
107
-          planner.skew(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS]);
108
-        #else
109
-          const float (&pos)[XYZE] = current_position;
110
-        #endif
111
-        if (planner.leveling_active) {
112
-          current_position[Z_AXIS] += ubl.get_z_correction(pos[X_AXIS], pos[Y_AXIS]);
113
-          planner.leveling_active = false;
114
-        }
115
-        else {
116
-          planner.leveling_active = true;
117
-          current_position[Z_AXIS] -= ubl.get_z_correction(pos[X_AXIS], pos[Y_AXIS]);
118
-        }
119
-      #endif
120
-
121
-    #else // OLDSCHOOL_ABL
122
-
123
-      #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
124
-        // Force bilinear_z_offset to re-calculate next time
125
-        const float reset[XYZ] = { -9999.999, -9999.999, 0 };
126
-        (void)bilinear_z_offset(reset);
127
-      #endif
128
-
129
-      // Enable or disable leveling compensation in the planner
130
-      planner.leveling_active = enable;
131
-
132
-      if (!enable)
133
-        // When disabling just get the current position from the steppers.
134
-        // This will yield the smallest error when first converted back to steps.
135
-        set_current_from_steppers_for_axis(
136
-          #if ABL_PLANAR
137
-            ALL_AXES
138
-          #else
139
-            Z_AXIS
140
-          #endif
141
-        );
142
-      else
143
-        // When enabling, remove compensation from the current position,
144
-        // so compensation will give the right stepper counts.
145
-        planner.unapply_leveling(current_position);
79
+    #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
80
+      // Force bilinear_z_offset to re-calculate next time
81
+      const float reset[XYZ] = { -9999.999, -9999.999, 0 };
82
+      (void)bilinear_z_offset(reset);
83
+    #endif
146 84
 
147
-      SYNC_PLAN_POSITION_KINEMATIC();
85
+    if (planner.leveling_active) {      // leveling from on to off
86
+      // change unleveled current_position to physical current_position without moving steppers.
87
+      planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS]);
88
+      planner.leveling_active = false;  // disable only AFTER calling apply_leveling
89
+    }
90
+    else {                              // leveling from off to on
91
+      planner.leveling_active = true;   // enable BEFORE calling unapply_leveling, otherwise ignored
92
+      // change physical current_position to unleveled current_position without moving steppers.
93
+      planner.unapply_leveling(current_position);
94
+    }
148 95
 
149
-    #endif // OLDSCHOOL_ABL
96
+    sync_plan_position();
150 97
   }
151 98
 }
152 99
 

+ 21
- 52
Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp 查看文件

@@ -49,12 +49,11 @@
49 49
      * as possible to determine if this is the case. If this move is within the same cell, we will
50 50
      * just do the required Z-Height correction, call the Planner's buffer_line() routine, and leave
51 51
      */
52
-    #if ENABLED(SKEW_CORRECTION)
53
-      // For skew correction just adjust the destination point and we're done
52
+    #if HAS_POSITION_MODIFIERS
54 53
       float start[XYZE] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS] },
55 54
             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]);
55
+      planner.apply_modifiers(start);
56
+      planner.apply_modifiers(end);
58 57
     #else
59 58
       const float (&start)[XYZE] = current_position,
60 59
                     (&end)[XYZE] = destination;
@@ -364,47 +363,6 @@
364 363
 
365 364
 #else // UBL_SEGMENTED
366 365
 
367
-  #if IS_SCARA // scale the feed rate from mm/s to degrees/s
368
-    static float scara_feed_factor, scara_oldA, scara_oldB;
369
-  #endif
370
-
371
-  // We don't want additional apply_leveling() performed by regular buffer_line or buffer_line_kinematic,
372
-  // so we call buffer_segment directly here.  Per-segmented leveling and kinematics performed first.
373
-
374
-  inline void _O2 ubl_buffer_segment_raw(const float (&in_raw)[XYZE], const float &fr) {
375
-
376
-    #if ENABLED(SKEW_CORRECTION)
377
-      float raw[XYZE] = { in_raw[X_AXIS], in_raw[Y_AXIS], in_raw[Z_AXIS] };
378
-      planner.skew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]);
379
-    #else
380
-      const float (&raw)[XYZE] = in_raw;
381
-    #endif
382
-
383
-    #if ENABLED(DELTA)  // apply delta inverse_kinematics
384
-
385
-      DELTA_IK(raw);
386
-      planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_AXIS], fr, active_extruder);
387
-
388
-    #elif IS_SCARA  // apply scara inverse_kinematics (should be changed to save raw->logical->raw)
389
-
390
-      inverse_kinematics(raw);  // this writes delta[ABC] from raw[XYZE]
391
-                                // should move the feedrate scaling to scara inverse_kinematics
392
-
393
-      const float adiff = ABS(delta[A_AXIS] - scara_oldA),
394
-                  bdiff = ABS(delta[B_AXIS] - scara_oldB);
395
-      scara_oldA = delta[A_AXIS];
396
-      scara_oldB = delta[B_AXIS];
397
-      float s_feedrate = MAX(adiff, bdiff) * scara_feed_factor;
398
-
399
-      planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_AXIS], s_feedrate, active_extruder);
400
-
401
-    #else // CARTESIAN
402
-
403
-      planner.buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], in_raw[E_AXIS], fr, active_extruder);
404
-
405
-    #endif
406
-  }
407
-
408 366
   #if IS_SCARA
409 367
     #define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm
410 368
   #elif ENABLED(DELTA)
@@ -449,10 +407,9 @@
449 407
     NOLESS(segments, 1U);                        // must have at least one segment
450 408
     const float inv_segments = 1.0f / segments;  // divide once, multiply thereafter
451 409
 
452
-    #if IS_SCARA // scale the feed rate from mm/s to degrees/s
453
-      scara_feed_factor = cartesian_xy_mm * inv_segments * feedrate;
454
-      scara_oldA = planner.get_axis_position_degrees(A_AXIS);
455
-      scara_oldB = planner.get_axis_position_degrees(B_AXIS);
410
+    const float segment_xyz_mm = HYPOT(cartesian_xy_mm, total[Z_AXIS]) * inv_segments;   // length of each segment
411
+    #if ENABLED(SCARA_FEEDRATE_SCALING)
412
+      const float inv_duration = feedrate / segment_xyz_mm;
456 413
     #endif
457 414
 
458 415
     const float diff[XYZE] = {
@@ -476,9 +433,17 @@
476 433
     if (!planner.leveling_active || !planner.leveling_active_at_z(rtarget[Z_AXIS])) {   // no mesh leveling
477 434
       while (--segments) {
478 435
         LOOP_XYZE(i) raw[i] += diff[i];
479
-        ubl_buffer_segment_raw(raw, feedrate);
436
+        planner.buffer_line(raw, feedrate, active_extruder, segment_xyz_mm
437
+          #if ENABLED(SCARA_FEEDRATE_SCALING)
438
+            , inv_duration
439
+          #endif
440
+        );
480 441
       }
481
-      ubl_buffer_segment_raw(rtarget, feedrate);
442
+      planner.buffer_line(rtarget, feedrate, active_extruder, segment_xyz_mm
443
+        #if ENABLED(SCARA_FEEDRATE_SCALING)
444
+          , inv_duration
445
+        #endif
446
+      );
482 447
       return false; // moved but did not set_current_from_destination();
483 448
     }
484 449
 
@@ -554,7 +519,11 @@
554 519
 
555 520
         const float z = raw[Z_AXIS];
556 521
         raw[Z_AXIS] += z_cxcy;
557
-        ubl_buffer_segment_raw(raw, feedrate);
522
+        planner.buffer_line(raw, feedrate, active_extruder, segment_xyz_mm
523
+          #if ENABLED(SCARA_FEEDRATE_SCALING)
524
+            , inv_duration
525
+          #endif
526
+        );
558 527
         raw[Z_AXIS] = z;
559 528
 
560 529
         if (segments == 0)                        // done with last segment

+ 22
- 25
Marlin/src/feature/fwretract.cpp 查看文件

@@ -54,6 +54,7 @@ float FWRetract::retract_length,                     // M207 S - G10 Retract len
54 54
       FWRetract::swap_retract_length,                // M207 W - G10 Swap Retract length
55 55
       FWRetract::swap_retract_recover_length,        // M208 W - G11 Swap Recover length
56 56
       FWRetract::swap_retract_recover_feedrate_mm_s, // M208 R - G11 Swap Recover feedrate
57
+      FWRetract::current_retract[EXTRUDERS],         // Retract value used by planner
57 58
       FWRetract::current_hop;
58 59
 
59 60
 void FWRetract::reset() {
@@ -73,6 +74,7 @@ void FWRetract::reset() {
73 74
     #if EXTRUDERS > 1
74 75
       retracted_swap[i] = false;
75 76
     #endif
77
+    current_retract[i] = 0.0;
76 78
   }
77 79
 }
78 80
 
@@ -84,9 +86,6 @@ void FWRetract::reset() {
84 86
  *
85 87
  * To simplify the logic, doubled retract/recover moves are ignored.
86 88
  *
87
- * Note: Z lift is done transparently to the planner. Aborting
88
- *       a print between G10 and G11 may corrupt the Z position.
89
- *
90 89
  * Note: Auto-retract will apply the set Z hop in addition to any Z hop
91 90
  *       included in the G-code. Use M207 Z0 to to prevent double hop.
92 91
  */
@@ -95,9 +94,6 @@ void FWRetract::retract(const bool retracting
95 94
     , bool swapping /* =false */
96 95
   #endif
97 96
 ) {
98
-
99
-  static float current_hop = 0.0;  // Total amount lifted, for use in recover
100
-
101 97
   // Prevent two retracts or recovers in a row
102 98
   if (retracted[active_extruder] == retracting) return;
103 99
 
@@ -129,48 +125,50 @@ void FWRetract::retract(const bool retracting
129 125
   //*/
130 126
 
131 127
   const float old_feedrate_mm_s = feedrate_mm_s,
132
-              renormalize = RECIPROCAL(planner.e_factor[active_extruder]),
133
-              base_retract = swapping ? swap_retract_length : retract_length,
134
-              old_z = current_position[Z_AXIS],
135
-              old_e = current_position[E_AXIS];
128
+              unscale_e = RECIPROCAL(planner.e_factor[active_extruder]),
129
+              unscale_fr = 100.0 / feedrate_percentage, // Disable feedrate scaling for retract moves
130
+              base_retract = swapping ? swap_retract_length : retract_length;
136 131
 
137 132
   // The current position will be the destination for E and Z moves
138 133
   set_destination_from_current();
139 134
 
140 135
   if (retracting) {
141 136
     // Retract by moving from a faux E position back to the current E position
142
-    feedrate_mm_s = retract_feedrate_mm_s;
143
-    destination[E_AXIS] -= base_retract * renormalize;
137
+    feedrate_mm_s = retract_feedrate_mm_s * unscale_fr;
138
+    current_retract[active_extruder] = base_retract * unscale_e;
144 139
     prepare_move_to_destination();                        // set_current_to_destination
140
+    planner.synchronize();                                // Wait for move to complete
145 141
 
146 142
     // Is a Z hop set, and has the hop not yet been done?
147 143
     if (retract_zlift > 0.01 && !current_hop) {           // Apply hop only once
148 144
       current_hop += retract_zlift;                       // Add to the hop total (again, only once)
149
-      destination[Z_AXIS] += retract_zlift;               // Raise Z by the zlift (M207 Z) amount
150
-      feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS];  // Maximum Z feedrate
145
+      feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS] * unscale_fr;  // Maximum Z feedrate
151 146
       prepare_move_to_destination();                      // Raise up, set_current_to_destination
147
+      planner.synchronize();                              // Wait for move to complete
152 148
     }
153 149
   }
154 150
   else {
155 151
     // If a hop was done and Z hasn't changed, undo the Z hop
156 152
     if (current_hop) {
157
-      current_position[Z_AXIS] += current_hop;            // Restore the actual Z position
158
-      SYNC_PLAN_POSITION_KINEMATIC();                     // Unspoof the position planner
159
-      feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS];  // Z feedrate to max
153
+      current_hop = 0.0;
154
+      feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS] * unscale_fr;  // Z feedrate to max
160 155
       prepare_move_to_destination();                      // Lower Z, set_current_to_destination
161
-      current_hop = 0.0;                                  // Clear the hop amount
156
+      planner.synchronize();                              // Wait for move to complete
162 157
     }
163 158
 
164
-    destination[E_AXIS] += (base_retract + (swapping ? swap_retract_recover_length : retract_recover_length)) * renormalize;
165
-    feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s;
159
+    const float extra_recover = swapping ? swap_retract_recover_length : retract_recover_length;
160
+    if (extra_recover != 0.0) {
161
+      current_position[E_AXIS] -= extra_recover;          // Adjust the current E position by the extra amount to recover
162
+      sync_plan_position_e();                             // Sync the planner position so the extra amount is recovered
163
+    }
164
+
165
+    current_retract[active_extruder] = 0.0;
166
+    feedrate_mm_s = (swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s) * unscale_fr;
166 167
     prepare_move_to_destination();                        // Recover E, set_current_to_destination
168
+    planner.synchronize();                                // Wait for move to complete
167 169
   }
168 170
 
169 171
   feedrate_mm_s = old_feedrate_mm_s;                      // Restore original feedrate
170
-  current_position[Z_AXIS] = old_z;                       // Restore Z and E positions
171
-  current_position[E_AXIS] = old_e;
172
-  SYNC_PLAN_POSITION_KINEMATIC();                         // As if the move never took place
173
-
174 172
   retracted[active_extruder] = retracting;                // Active extruder now retracted / recovered
175 173
 
176 174
   // If swap retract/recover update the retracted_swap flag too
@@ -194,7 +192,6 @@ void FWRetract::retract(const bool retracting
194 192
     SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]);
195 193
     SERIAL_ECHOLNPAIR("current_hop ", current_hop);
196 194
   //*/
197
-
198 195
 }
199 196
 
200 197
 #endif // FWRETRACT

+ 2
- 1
Marlin/src/feature/fwretract.h 查看文件

@@ -46,7 +46,8 @@ public:
46 46
                swap_retract_length,                // M207 W - G10 Swap Retract length
47 47
                swap_retract_recover_length,        // M208 W - G11 Swap Recover length
48 48
                swap_retract_recover_feedrate_mm_s, // M208 R - G11 Swap Recover feedrate
49
-               current_hop;
49
+               current_retract[EXTRUDERS],         // Retract value used by planner
50
+               current_hop;                        // Hop value used by planner
50 51
 
51 52
   FWRetract() { reset(); }
52 53
 

+ 1
- 1
Marlin/src/feature/pause.cpp 查看文件

@@ -120,7 +120,7 @@ static bool ensure_safe_temperature(const AdvancedPauseMode mode=ADVANCED_PAUSE_
120 120
 static void do_pause_e_move(const float &length, const float &fr) {
121 121
   set_destination_from_current();
122 122
   destination[E_AXIS] += length / planner.e_factor[active_extruder];
123
-  planner.buffer_line_kinematic(destination, fr, active_extruder);
123
+  planner.buffer_line(destination, fr, active_extruder);
124 124
   set_current_from_destination();
125 125
   planner.synchronize();
126 126
 }

+ 27
- 0
Marlin/src/feature/power_loss_recovery.cpp 查看文件

@@ -39,6 +39,10 @@
39 39
 #include "../sd/cardreader.h"
40 40
 #include "../core/serial.h"
41 41
 
42
+#if ENABLED(FWRETRACT)
43
+  #include "fwretract.h"
44
+#endif
45
+
42 46
 // Recovery data
43 47
 job_recovery_info_t job_recovery_info;
44 48
 JobRecoveryPhase job_recovery_phase = JOB_RECOVERY_IDLE;
@@ -90,6 +94,15 @@ extern uint8_t commands_in_queue, cmd_queue_index_r;
90 94
           SERIAL_PROTOCOLPAIR("leveling: ", int(job_recovery_info.leveling));
91 95
           SERIAL_PROTOCOLLNPAIR(" fade: ", int(job_recovery_info.fade));
92 96
         #endif
97
+        #if ENABLED(FWRETRACT)
98
+          SERIAL_PROTOCOLPGM("retract: ");
99
+          for (int8_t e = 0; e < EXTRUDERS; e++) {
100
+            SERIAL_PROTOCOL(job_recovery_info.retract[e]);
101
+            if (e < EXTRUDERS - 1) SERIAL_CHAR(',');
102
+          }
103
+          SERIAL_EOL();
104
+          SERIAL_PROTOCOLLNPAIR("retract_hop: ", job_recovery_info.retract_hop);
105
+        #endif
93 106
         SERIAL_PROTOCOLLNPAIR("cmd_queue_index_r: ", int(job_recovery_info.cmd_queue_index_r));
94 107
         SERIAL_PROTOCOLLNPAIR("commands_in_queue: ", int(job_recovery_info.commands_in_queue));
95 108
         if (recovery)
@@ -160,6 +173,15 @@ void check_print_job_recovery() {
160 173
           }
161 174
         #endif
162 175
 
176
+        #if ENABLED(FWRETRACT)
177
+          for (uint8_t e = 0; e < EXTRUDERS; e++) {
178
+            if (job_recovery_info.retract[e] != 0.0)
179
+              fwretract.current_retract[e] = job_recovery_info.retract[e];
180
+              fwretract.retracted[e] = true;
181
+          }
182
+          fwretract.current_hop = job_recovery_info.retract_hop;
183
+        #endif
184
+
163 185
         dtostrf(job_recovery_info.current_position[Z_AXIS] + 2, 1, 3, str_1);
164 186
         dtostrf(job_recovery_info.current_position[E_AXIS]
165 187
           #if ENABLED(SAVE_EACH_CMD_MODE)
@@ -256,6 +278,11 @@ void save_job_recovery_info() {
256 278
       );
257 279
     #endif
258 280
 
281
+    #if ENABLED(FWRETRACT)
282
+      COPY(job_recovery_info.retract, fwretract.current_retract);
283
+      job_recovery_info.retract_hop = fwretract.current_hop;
284
+    #endif
285
+
259 286
     // Commands in the queue
260 287
     job_recovery_info.cmd_queue_index_r = cmd_queue_index_r;
261 288
     job_recovery_info.commands_in_queue = commands_in_queue;

+ 4
- 0
Marlin/src/feature/power_loss_recovery.h 查看文件

@@ -60,6 +60,10 @@ typedef struct {
60 60
     float fade;
61 61
   #endif
62 62
 
63
+  #if ENABLED(FWRETRACT)
64
+    float retract[EXTRUDERS], retract_hop;
65
+  #endif
66
+
63 67
   // Command queue
64 68
   uint8_t cmd_queue_index_r, commands_in_queue;
65 69
   char command_queue[BUFSIZE][MAX_CMD_SIZE];

+ 1
- 1
Marlin/src/gcode/bedlevel/abl/G29.cpp 查看文件

@@ -989,7 +989,7 @@ G29_TYPE GcodeSuite::G29() {
989 989
   KEEPALIVE_STATE(IN_HANDLER);
990 990
 
991 991
   if (planner.leveling_active)
992
-    SYNC_PLAN_POSITION_KINEMATIC();
992
+    sync_plan_position();
993 993
 
994 994
   #if HAS_BED_PROBE && defined(Z_AFTER_PROBING)
995 995
     move_z_after_probing();

+ 3
- 3
Marlin/src/gcode/calibrate/G28.cpp 查看文件

@@ -101,7 +101,7 @@
101 101
       if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Z_SAFE_HOMING >>>");
102 102
     #endif
103 103
 
104
-    SYNC_PLAN_POSITION_KINEMATIC();
104
+    sync_plan_position();
105 105
 
106 106
     /**
107 107
      * Move the Z probe (or just the nozzle) to the safe homing point
@@ -182,7 +182,7 @@ void GcodeSuite::G28(const bool always_home_all) {
182 182
   #if ENABLED(MARLIN_DEV_MODE)
183 183
     if (parser.seen('S')) {
184 184
       LOOP_XYZ(a) set_axis_is_at_home((AxisEnum)a);
185
-      SYNC_PLAN_POSITION_KINEMATIC();
185
+      sync_plan_position();
186 186
       SERIAL_ECHOLNPGM("Simulated Homing");
187 187
       report_current_position();
188 188
       #if ENABLED(DEBUG_LEVELING_FEATURE)
@@ -357,7 +357,7 @@ void GcodeSuite::G28(const bool always_home_all) {
357 357
       } // home_all || homeZ
358 358
     #endif // Z_HOME_DIR < 0
359 359
 
360
-    SYNC_PLAN_POSITION_KINEMATIC();
360
+    sync_plan_position();
361 361
 
362 362
   #endif // !DELTA (G28)
363 363
 

+ 1
- 1
Marlin/src/gcode/calibrate/M852.cpp 查看文件

@@ -87,7 +87,7 @@ void GcodeSuite::M852() {
87 87
   // When skew is changed the current position changes
88 88
   if (setval) {
89 89
     set_current_from_steppers_for_axis(ALL_AXES);
90
-    SYNC_PLAN_POSITION_KINEMATIC();
90
+    sync_plan_position();
91 91
     report_current_position();
92 92
   }
93 93
 

+ 8
- 3
Marlin/src/gcode/config/M200-M205.cpp 查看文件

@@ -136,14 +136,17 @@ void GcodeSuite::M205() {
136 136
       const float junc_dev = parser.value_linear_units();
137 137
       if (WITHIN(junc_dev, 0.01f, 0.3f)) {
138 138
         planner.junction_deviation_mm = junc_dev;
139
-        planner.recalculate_max_e_jerk();
139
+        #if ENABLED(LIN_ADVANCE)
140
+          planner.recalculate_max_e_jerk();
141
+        #endif
140 142
       }
141 143
       else {
142 144
         SERIAL_ERROR_START();
143 145
         SERIAL_ERRORLNPGM("?J out of range (0.01 to 0.3)");
144 146
       }
145 147
     }
146
-  #else
148
+  #endif
149
+  #if HAS_CLASSIC_JERK
147 150
     if (parser.seen('X')) planner.max_jerk[X_AXIS] = parser.value_linear_units();
148 151
     if (parser.seen('Y')) planner.max_jerk[Y_AXIS] = parser.value_linear_units();
149 152
     if (parser.seen('Z')) {
@@ -153,6 +156,8 @@ void GcodeSuite::M205() {
153 156
           SERIAL_ECHOLNPGM("WARNING! Low Z Jerk may lead to unwanted pauses.");
154 157
       #endif
155 158
     }
156
-    if (parser.seen('E')) planner.max_jerk[E_AXIS] = parser.value_linear_units();
159
+    #if DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE)
160
+      if (parser.seen('E')) planner.max_jerk[E_AXIS] = parser.value_linear_units();
161
+    #endif
157 162
   #endif
158 163
 }

+ 1
- 1
Marlin/src/gcode/config/M92.cpp 查看文件

@@ -39,7 +39,7 @@ void GcodeSuite::M92() {
39 39
         const float value = parser.value_per_axis_unit((AxisEnum)(E_AXIS + TARGET_EXTRUDER));
40 40
         if (value < 20) {
41 41
           float factor = planner.axis_steps_per_mm[E_AXIS + TARGET_EXTRUDER] / value; // increase e constants if M92 E14 is given for netfab.
42
-          #if DISABLED(JUNCTION_DEVIATION)
42
+          #if HAS_CLASSIC_JERK && (DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE))
43 43
             planner.max_jerk[E_AXIS] *= factor;
44 44
           #endif
45 45
           planner.max_feedrate_mm_s[E_AXIS + TARGET_EXTRUDER] *= factor;

+ 1
- 1
Marlin/src/gcode/geometry/G92.cpp 查看文件

@@ -92,7 +92,7 @@ void GcodeSuite::G92() {
92 92
       COPY(coordinate_system[active_coordinate_system], position_shift);
93 93
   #endif
94 94
 
95
-  if    (didXYZ) SYNC_PLAN_POSITION_KINEMATIC();
95
+  if    (didXYZ) sync_plan_position();
96 96
   else if (didE) sync_plan_position_e();
97 97
 
98 98
   report_current_position();

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

@@ -56,7 +56,7 @@
56 56
 
57 57
     float leveled[XYZ] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] };
58 58
 
59
-    #if PLANNER_LEVELING
59
+    #if HAS_LEVELING
60 60
       SERIAL_PROTOCOLPGM("Leveled:");
61 61
       planner.apply_leveling(leveled);
62 62
       report_xyz(leveled);

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

@@ -35,10 +35,6 @@
35 35
   #include "../../module/scara.h"
36 36
 #endif
37 37
 
38
-#if HAS_FEEDRATE_SCALING && ENABLED(AUTO_BED_LEVELING_BILINEAR)
39
-  #include "../../feature/bedlevel/abl/abl.h"
40
-#endif
41
-
42 38
 #if N_ARC_CORRECTION < 1
43 39
   #undef N_ARC_CORRECTION
44 40
   #define N_ARC_CORRECTION 1
@@ -139,20 +135,12 @@ void plan_arc(
139 135
 
140 136
   const float fr_mm_s = MMS_SCALED(feedrate_mm_s);
141 137
 
142
-  millis_t next_idle_ms = millis() + 200UL;
143
-
144
-  #if HAS_FEEDRATE_SCALING
145
-    // SCARA needs to scale the feed rate from mm/s to degrees/s
146
-    const float inv_segment_length = 1.0f / float(MM_PER_ARC_SEGMENT),
147
-                inverse_secs = inv_segment_length * fr_mm_s;
148
-    float oldA = planner.position_float[A_AXIS],
149
-          oldB = planner.position_float[B_AXIS]
150
-          #if ENABLED(DELTA_FEEDRATE_SCALING)
151
-            , oldC = planner.position_float[C_AXIS]
152
-          #endif
153
-          ;
138
+  #if ENABLED(SCARA_FEEDRATE_SCALING)
139
+    const float inv_duration = fr_mm_s / MM_PER_ARC_SEGMENT;
154 140
   #endif
155 141
 
142
+  millis_t next_idle_ms = millis() + 200UL;
143
+
156 144
   #if N_ARC_CORRECTION > 1
157 145
     int8_t arc_recalc_count = N_ARC_CORRECTION;
158 146
   #endif
@@ -196,57 +184,32 @@ void plan_arc(
196 184
 
197 185
     clamp_to_software_endstops(raw);
198 186
 
199
-    #if HAS_FEEDRATE_SCALING
200
-      inverse_kinematics(raw);
201
-      ADJUST_DELTA(raw);
187
+    #if HAS_LEVELING && !PLANNER_LEVELING
188
+      planner.apply_leveling(raw);
202 189
     #endif
203 190
 
204
-    #if ENABLED(SCARA_FEEDRATE_SCALING)
205
-      // For SCARA scale the feed rate from mm/s to degrees/s
206
-      // i.e., Complete the angular vector in the given time.
207
-      if (!planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], raw[Z_AXIS], raw[E_AXIS], HYPOT(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB) * inverse_secs, active_extruder, MM_PER_ARC_SEGMENT))
208
-        break;
209
-      oldA = delta[A_AXIS]; oldB = delta[B_AXIS];
210
-    #elif ENABLED(DELTA_FEEDRATE_SCALING)
211
-      // For DELTA scale the feed rate from Effector mm/s to Carriage mm/s
212
-      // i.e., Complete the linear vector in the given time.
213
-      if (!planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], SQRT(sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC)) * inverse_secs, active_extruder, MM_PER_ARC_SEGMENT))
214
-        break;
215
-      oldA = delta[A_AXIS]; oldB = delta[B_AXIS]; oldC = delta[C_AXIS];
216
-    #elif HAS_UBL_AND_CURVES
217
-      float pos[XYZ] = { raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS] };
218
-      planner.apply_leveling(pos);
219
-      if (!planner.buffer_segment(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS], raw[E_AXIS], fr_mm_s, active_extruder, MM_PER_ARC_SEGMENT))
220
-        break;
221
-    #else
222
-      if (!planner.buffer_line_kinematic(raw, fr_mm_s, active_extruder))
223
-        break;
224
-    #endif
191
+    if (!planner.buffer_line(raw, fr_mm_s, active_extruder, MM_PER_ARC_SEGMENT
192
+      #if ENABLED(SCARA_FEEDRATE_SCALING)
193
+        , inv_duration
194
+      #endif
195
+    ))
196
+      break;
225 197
   }
226 198
 
227 199
   // Ensure last segment arrives at target location.
228
-  #if HAS_FEEDRATE_SCALING
229
-    inverse_kinematics(cart);
230
-    ADJUST_DELTA(cart);
231
-  #endif
200
+  COPY(raw, cart);
232 201
 
233
-  #if ENABLED(SCARA_FEEDRATE_SCALING)
234
-    const float diff2 = HYPOT2(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB);
235
-    if (diff2)
236
-      planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], cart[Z_AXIS], cart[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder, MM_PER_ARC_SEGMENT);
237
-  #elif ENABLED(DELTA_FEEDRATE_SCALING)
238
-    const float diff2 = sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC);
239
-    if (diff2)
240
-      planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder, MM_PER_ARC_SEGMENT);
241
-  #elif HAS_UBL_AND_CURVES
242
-    float pos[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] };
243
-    planner.apply_leveling(pos);
244
-    planner.buffer_segment(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS], cart[E_AXIS], fr_mm_s, active_extruder, MM_PER_ARC_SEGMENT);
245
-  #else
246
-    planner.buffer_line_kinematic(cart, fr_mm_s, active_extruder);
202
+  #if HAS_LEVELING && !PLANNER_LEVELING
203
+    planner.apply_leveling(raw);
247 204
   #endif
248 205
 
249
-  COPY(current_position, cart);
206
+  planner.buffer_line(raw, fr_mm_s, active_extruder, MM_PER_ARC_SEGMENT
207
+    #if ENABLED(SCARA_FEEDRATE_SCALING)
208
+      , inv_duration
209
+    #endif
210
+  );
211
+
212
+  COPY(current_position, raw);
250 213
 } // plan_arc
251 214
 
252 215
 /**

+ 2
- 2
Marlin/src/gcode/probe/G38.cpp 查看文件

@@ -56,7 +56,7 @@ static bool G38_run_probe() {
56 56
 
57 57
   endstops.hit_on_purpose();
58 58
   set_current_from_steppers_for_axis(ALL_AXES);
59
-  SYNC_PLAN_POSITION_KINEMATIC();
59
+  sync_plan_position();
60 60
 
61 61
   if (G38_endstop_hit) {
62 62
 
@@ -82,7 +82,7 @@ static bool G38_run_probe() {
82 82
       G38_move = false;
83 83
 
84 84
       set_current_from_steppers_for_axis(ALL_AXES);
85
-      SYNC_PLAN_POSITION_KINEMATIC();
85
+      sync_plan_position();
86 86
     #endif
87 87
   }
88 88
 

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

@@ -49,6 +49,8 @@
49 49
 #define IS_KINEMATIC (ENABLED(DELTA) || IS_SCARA)
50 50
 #define IS_CARTESIAN !IS_KINEMATIC
51 51
 
52
+#define HAS_CLASSIC_JERK (IS_KINEMATIC || DISABLED(JUNCTION_DEVIATION))
53
+
52 54
 /**
53 55
  * Axis lengths and center
54 56
  */
@@ -1173,10 +1175,9 @@
1173 1175
 #define HAS_LEVELING   (HAS_ABL || ENABLED(MESH_BED_LEVELING))
1174 1176
 #define HAS_AUTOLEVEL  (HAS_ABL && DISABLED(PROBE_MANUALLY))
1175 1177
 #define HAS_MESH       (ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(MESH_BED_LEVELING))
1176
-#define PLANNER_LEVELING      (OLDSCHOOL_ABL || ENABLED(MESH_BED_LEVELING) || UBL_SEGMENTED || ENABLED(SKEW_CORRECTION))
1178
+#define PLANNER_LEVELING      (HAS_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL))
1177 1179
 #define HAS_PROBING_PROCEDURE (HAS_ABL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST))
1178
-#define HAS_UBL_AND_CURVES (ENABLED(AUTO_BED_LEVELING_UBL) && !PLANNER_LEVELING && (ENABLED(ARC_SUPPORT) || ENABLED(BEZIER_CURVE_SUPPORT)))
1179
-#define HAS_FEEDRATE_SCALING (ENABLED(SCARA_FEEDRATE_SCALING) || ENABLED(DELTA_FEEDRATE_SCALING))
1180
+#define HAS_POSITION_MODIFIERS (ENABLED(FWRETRACT) || HAS_LEVELING || ENABLED(SKEW_CORRECTION))
1180 1181
 
1181 1182
 #if ENABLED(AUTO_BED_LEVELING_UBL)
1182 1183
   #undef LCD_BED_LEVELING

+ 14
- 7
Marlin/src/lcd/ultralcd.cpp 查看文件

@@ -841,7 +841,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
841 841
   }
842 842
 
843 843
   inline void line_to_current_z() {
844
-    planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[Z_AXIS]), active_extruder);
844
+    planner.buffer_line(current_position, MMM_TO_MMS(manual_feedrate_mm_m[Z_AXIS]), active_extruder);
845 845
   }
846 846
 
847 847
   inline void line_to_z(const float &z) {
@@ -1892,7 +1892,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
1892 1892
             break;
1893 1893
         #endif
1894 1894
       }
1895
-      planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[X_AXIS]), active_extruder);
1895
+      planner.buffer_line(current_position, MMM_TO_MMS(manual_feedrate_mm_m[X_AXIS]), active_extruder);
1896 1896
       line_to_z(0.0);
1897 1897
       if (++bed_corner > 3
1898 1898
         #if ENABLED(LEVEL_CENTER_TOO)
@@ -2432,7 +2432,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
2432 2432
     void ubl_map_move_to_xy() {
2433 2433
       current_position[X_AXIS] = pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]);
2434 2434
       current_position[Y_AXIS] = pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]);
2435
-      planner.buffer_line_kinematic(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder);
2435
+      planner.buffer_line(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder);
2436 2436
     }
2437 2437
 
2438 2438
     /**
@@ -2911,7 +2911,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
2911 2911
 
2912 2912
       #else
2913 2913
 
2914
-        planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]), manual_move_axis == E_AXIS ? manual_move_e_index : active_extruder);
2914
+        planner.buffer_line(current_position, MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]), manual_move_axis == E_AXIS ? manual_move_e_index : active_extruder);
2915 2915
         manual_move_axis = (int8_t)NO_AXIS;
2916 2916
 
2917 2917
       #endif
@@ -3746,8 +3746,13 @@ void lcd_quick_feedback(const bool clear_buttons) {
3746 3746
       MENU_BACK(MSG_ADVANCED_SETTINGS);
3747 3747
 
3748 3748
       #if ENABLED(JUNCTION_DEVIATION)
3749
-        MENU_ITEM_EDIT_CALLBACK(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.01f, 0.3f, planner.recalculate_max_e_jerk);
3750
-      #else
3749
+        #if ENABLED(LIN_ADVANCE)
3750
+          MENU_ITEM_EDIT_CALLBACK(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.01f, 0.3f, planner.recalculate_max_e_jerk);
3751
+        #else
3752
+          MENU_ITEM_EDIT(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.01f, 0.3f);
3753
+        #endif
3754
+      #endif
3755
+      #if HAS_CLASSIC_JERK
3751 3756
         MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VA_JERK, &planner.max_jerk[A_AXIS], 1, 990);
3752 3757
         MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VB_JERK, &planner.max_jerk[B_AXIS], 1, 990);
3753 3758
         #if ENABLED(DELTA)
@@ -3755,7 +3760,9 @@ void lcd_quick_feedback(const bool clear_buttons) {
3755 3760
         #else
3756 3761
           MENU_MULTIPLIER_ITEM_EDIT(float52sign, MSG_VC_JERK, &planner.max_jerk[C_AXIS], 0.1f, 990);
3757 3762
         #endif
3758
-        MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VE_JERK, &planner.max_jerk[E_AXIS], 1, 990);
3763
+        #if DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE)
3764
+          MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VE_JERK, &planner.max_jerk[E_AXIS], 1, 990);
3765
+        #endif
3759 3766
       #endif
3760 3767
 
3761 3768
       END_MENU();

+ 35
- 12
Marlin/src/module/configuration_store.cpp 查看文件

@@ -428,12 +428,20 @@ void MarlinSettings::postprocess() {
428 428
     EEPROM_WRITE(planner.min_feedrate_mm_s);
429 429
     EEPROM_WRITE(planner.min_travel_feedrate_mm_s);
430 430
 
431
-    #if ENABLED(JUNCTION_DEVIATION)
431
+    #if HAS_CLASSIC_JERK
432
+      EEPROM_WRITE(planner.max_jerk);
433
+      #if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
434
+        dummy = float(DEFAULT_EJERK);
435
+        EEPROM_WRITE(dummy);
436
+      #endif
437
+    #else
432 438
       const float planner_max_jerk[] = { float(DEFAULT_XJERK), float(DEFAULT_YJERK), float(DEFAULT_ZJERK), float(DEFAULT_EJERK) };
433 439
       EEPROM_WRITE(planner_max_jerk);
440
+    #endif
441
+
442
+    #if ENABLED(JUNCTION_DEVIATION)
434 443
       EEPROM_WRITE(planner.junction_deviation_mm);
435 444
     #else
436
-      EEPROM_WRITE(planner.max_jerk);
437 445
       dummy = 0.02f;
438 446
       EEPROM_WRITE(dummy);
439 447
     #endif
@@ -1062,11 +1070,18 @@ void MarlinSettings::postprocess() {
1062 1070
       EEPROM_READ(planner.min_feedrate_mm_s);
1063 1071
       EEPROM_READ(planner.min_travel_feedrate_mm_s);
1064 1072
 
1065
-      #if ENABLED(JUNCTION_DEVIATION)
1073
+      #if HAS_CLASSIC_JERK
1074
+        EEPROM_READ(planner.max_jerk);
1075
+        #if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
1076
+          EEPROM_READ(dummy);
1077
+        #endif
1078
+      #else
1066 1079
         for (uint8_t q = 4; q--;) EEPROM_READ(dummy);
1080
+      #endif
1081
+
1082
+      #if ENABLED(JUNCTION_DEVIATION)
1067 1083
         EEPROM_READ(planner.junction_deviation_mm);
1068 1084
       #else
1069
-        EEPROM_READ(planner.max_jerk);
1070 1085
         EEPROM_READ(dummy);
1071 1086
       #endif
1072 1087
 
@@ -1808,11 +1823,15 @@ void MarlinSettings::reset(PORTARG_SOLO) {
1808 1823
 
1809 1824
   #if ENABLED(JUNCTION_DEVIATION)
1810 1825
     planner.junction_deviation_mm = float(JUNCTION_DEVIATION_MM);
1811
-  #else
1826
+  #endif
1827
+
1828
+  #if HAS_CLASSIC_JERK
1812 1829
     planner.max_jerk[X_AXIS] = DEFAULT_XJERK;
1813 1830
     planner.max_jerk[Y_AXIS] = DEFAULT_YJERK;
1814 1831
     planner.max_jerk[Z_AXIS] = DEFAULT_ZJERK;
1815
-    planner.max_jerk[E_AXIS] = DEFAULT_EJERK;
1832
+    #if DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE)
1833
+      planner.max_jerk[E_AXIS] = DEFAULT_EJERK;
1834
+    #endif
1816 1835
   #endif
1817 1836
 
1818 1837
   #if HAS_HOME_OFFSET
@@ -2243,11 +2262,12 @@ void MarlinSettings::reset(PORTARG_SOLO) {
2243 2262
       SERIAL_ECHOPGM_P(port, "Advanced: B<min_segment_time_us> S<min_feedrate> T<min_travel_feedrate>");
2244 2263
       #if ENABLED(JUNCTION_DEVIATION)
2245 2264
         SERIAL_ECHOPGM_P(port, " J<junc_dev>");
2246
-      #else
2247
-        SERIAL_ECHOPGM_P(port, " X<max_x_jerk> Y<max_y_jerk> Z<max_z_jerk>");
2248 2265
       #endif
2249
-      #if DISABLED(JUNCTION_DEVIATION) || ENABLED(LIN_ADVANCE)
2250
-        SERIAL_ECHOPGM_P(port, " E<max_e_jerk>");
2266
+      #if HAS_CLASSIC_JERK
2267
+        SERIAL_ECHOPGM_P(port, " X<max_x_jerk> Y<max_y_jerk> Z<max_z_jerk>");
2268
+        #if DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE)
2269
+          SERIAL_ECHOPGM_P(port, " E<max_e_jerk>");
2270
+        #endif
2251 2271
       #endif
2252 2272
       SERIAL_EOL_P(port);
2253 2273
     }
@@ -2258,11 +2278,14 @@ void MarlinSettings::reset(PORTARG_SOLO) {
2258 2278
 
2259 2279
     #if ENABLED(JUNCTION_DEVIATION)
2260 2280
       SERIAL_ECHOPAIR_P(port, " J", LINEAR_UNIT(planner.junction_deviation_mm));
2261
-    #else
2281
+    #endif
2282
+    #if HAS_CLASSIC_JERK
2262 2283
       SERIAL_ECHOPAIR_P(port, " X", LINEAR_UNIT(planner.max_jerk[X_AXIS]));
2263 2284
       SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.max_jerk[Y_AXIS]));
2264 2285
       SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.max_jerk[Z_AXIS]));
2265
-      SERIAL_ECHOPAIR_P(port, " E", LINEAR_UNIT(planner.max_jerk[E_AXIS]));
2286
+      #if DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE)
2287
+        SERIAL_ECHOPAIR_P(port, " E", LINEAR_UNIT(planner.max_jerk[E_AXIS]));
2288
+      #endif
2266 2289
     #endif
2267 2290
 
2268 2291
     SERIAL_EOL_P(port);

+ 5
- 5
Marlin/src/module/delta.cpp 查看文件

@@ -101,7 +101,7 @@ void recalc_delta_settings() {
101 101
     SERIAL_ECHOLNPAIR(" C:", delta[C_AXIS]);      \
102 102
   }while(0)
103 103
 
104
-void inverse_kinematics(const float raw[XYZ]) {
104
+void inverse_kinematics(const float (&raw)[XYZ]) {
105 105
   #if HAS_HOTEND_OFFSET
106 106
     // Delta hotend offsets must be applied in Cartesian space with no "spoofing"
107 107
     const float pos[XYZ] = {
@@ -224,6 +224,7 @@ void home_delta() {
224 224
   #endif
225 225
   // Init the current position of all carriages to 0,0,0
226 226
   ZERO(current_position);
227
+  ZERO(destination);
227 228
   sync_plan_position();
228 229
 
229 230
   // Disable stealthChop if used. Enable diag1 pin on driver.
@@ -232,9 +233,8 @@ void home_delta() {
232 233
   #endif
233 234
 
234 235
   // Move all carriages together linearly until an endstop is hit.
235
-  current_position[X_AXIS] = current_position[Y_AXIS] = current_position[Z_AXIS] = (delta_height + 10);
236
-  feedrate_mm_s = homing_feedrate(X_AXIS);
237
-  line_to_current_position();
236
+  destination[Z_AXIS] = (delta_height + 10);
237
+  buffer_line_to_destination(homing_feedrate(X_AXIS));
238 238
   planner.synchronize();
239 239
 
240 240
   // Re-enable stealthChop if used. Disable diag1 pin on driver.
@@ -256,7 +256,7 @@ void home_delta() {
256 256
   // give the impression that they are the same.
257 257
   LOOP_XYZ(i) set_axis_is_at_home((AxisEnum)i);
258 258
 
259
-  SYNC_PLAN_POSITION_KINEMATIC();
259
+  sync_plan_position();
260 260
 
261 261
   #if ENABLED(DEBUG_LEVELING_FEATURE)
262 262
     if (DEBUGGING(LEVELING)) DEBUG_POS("<<< home_delta", current_position);

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

@@ -24,8 +24,7 @@
24 24
  * delta.h - Delta-specific functions
25 25
  */
26 26
 
27
-#ifndef __DELTA_H__
28
-#define __DELTA_H__
27
+#pragma once
29 28
 
30 29
 extern float delta_height,
31 30
              delta_endstop_adj[ABC],
@@ -78,7 +77,11 @@ void recalc_delta_settings();
78 77
   delta[C_AXIS] = DELTA_Z(V, C_AXIS); \
79 78
 }while(0)
80 79
 
81
-void inverse_kinematics(const float raw[XYZ]);
80
+void inverse_kinematics(const float (&raw)[XYZ]);
81
+FORCE_INLINE void inverse_kinematics(const float (&raw)[XYZE]) {
82
+  const float raw_xyz[XYZ] = { raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS] };
83
+  inverse_kinematics(raw_xyz);
84
+}
82 85
 
83 86
 /**
84 87
  * Calculate the highest Z position where the
@@ -118,5 +121,3 @@ FORCE_INLINE void forward_kinematics_DELTA(const float (&point)[ABC]) {
118 121
 }
119 122
 
120 123
 void home_delta();
121
-
122
-#endif // __DELTA_H__

+ 77
- 136
Marlin/src/module/motion.cpp 查看文件

@@ -75,7 +75,7 @@ bool relative_mode; // = false;
75 75
  * Cartesian Current Position
76 76
  *   Used to track the native machine position as moves are queued.
77 77
  *   Used by 'buffer_line_to_current_position' to do a move after changing it.
78
- *   Used by 'SYNC_PLAN_POSITION_KINEMATIC' to update 'planner.position'.
78
+ *   Used by 'sync_plan_position' to update 'planner.position'.
79 79
  */
80 80
 float current_position[XYZE] = { 0 };
81 81
 
@@ -218,15 +218,22 @@ void get_cartesian_from_steppers() {
218 218
  * may have been applied.
219 219
  *
220 220
  * To prevent small shifts in axis position always call
221
- * SYNC_PLAN_POSITION_KINEMATIC after updating axes with this.
221
+ * sync_plan_position after updating axes with this.
222 222
  *
223 223
  * To keep hosts in sync, always call report_current_position
224 224
  * after updating the current_position.
225 225
  */
226 226
 void set_current_from_steppers_for_axis(const AxisEnum axis) {
227 227
   get_cartesian_from_steppers();
228
-  #if PLANNER_LEVELING
229
-    planner.unapply_leveling(cartes);
228
+
229
+  #if HAS_POSITION_MODIFIERS
230
+    float pos[XYZE] = { cartes[X_AXIS], cartes[Y_AXIS], cartes[Z_AXIS], current_position[E_AXIS] };
231
+    planner.unapply_modifiers(pos
232
+      #if HAS_LEVELING
233
+        , true
234
+      #endif
235
+    );
236
+    const float (&cartes)[XYZE] = pos;
230 237
   #endif
231 238
   if (axis == ALL_AXES)
232 239
     COPY(current_position, cartes);
@@ -252,13 +259,6 @@ void buffer_line_to_destination(const float fr_mm_s) {
252 259
 
253 260
 #if IS_KINEMATIC
254 261
 
255
-  void sync_plan_position_kinematic() {
256
-    #if ENABLED(DEBUG_LEVELING_FEATURE)
257
-      if (DEBUGGING(LEVELING)) DEBUG_POS("sync_plan_position_kinematic", current_position);
258
-    #endif
259
-    planner.set_position_mm_kinematic(current_position);
260
-  }
261
-
262 262
   /**
263 263
    * Calculate delta, start a line, and set current_position to destination
264 264
    */
@@ -277,7 +277,7 @@ void buffer_line_to_destination(const float fr_mm_s) {
277 277
         && current_position[E_AXIS] == destination[E_AXIS]
278 278
       ) return;
279 279
 
280
-      planner.buffer_line_kinematic(destination, MMS_SCALED(fr_mm_s ? fr_mm_s : feedrate_mm_s), active_extruder);
280
+      planner.buffer_line(destination, MMS_SCALED(fr_mm_s ? fr_mm_s : feedrate_mm_s), active_extruder);
281 281
     #endif
282 282
 
283 283
     set_current_from_destination();
@@ -538,7 +538,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
538 538
 
539 539
     // If the move is only in Z/E don't split up the move
540 540
     if (!xdiff && !ydiff) {
541
-      planner.buffer_line_kinematic(rtarget, _feedrate_mm_s, active_extruder);
541
+      planner.buffer_line(rtarget, _feedrate_mm_s, active_extruder);
542 542
       return false; // caller will update current_position
543 543
     }
544 544
 
@@ -580,53 +580,22 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
580 580
                   ydiff * inv_segments,
581 581
                   zdiff * inv_segments,
582 582
                   ediff * inv_segments
583
-                };
584
-
585
-    #if !HAS_FEEDRATE_SCALING
586
-      const float cartesian_segment_mm = cartesian_mm * inv_segments;
583
+                },
584
+                cartesian_segment_mm = cartesian_mm * inv_segments;
585
+    
586
+    #if ENABLED(SCARA_FEEDRATE_SCALING)
587
+      const float inv_duration = _feedrate_mm_s / cartesian_segment_mm;
587 588
     #endif
588 589
 
589 590
     /*
590 591
     SERIAL_ECHOPAIR("mm=", cartesian_mm);
591 592
     SERIAL_ECHOPAIR(" seconds=", seconds);
592 593
     SERIAL_ECHOPAIR(" segments=", segments);
593
-    #if !HAS_FEEDRATE_SCALING
594
-      SERIAL_ECHOPAIR(" segment_mm=", cartesian_segment_mm);
595
-    #endif
594
+    SERIAL_ECHOPAIR(" segment_mm=", cartesian_segment_mm);
596 595
     SERIAL_EOL();
597 596
     //*/
598 597
 
599
-    #if HAS_FEEDRATE_SCALING
600
-      // SCARA needs to scale the feed rate from mm/s to degrees/s
601
-      // i.e., Complete the angular vector in the given time.
602
-      const float segment_length = cartesian_mm * inv_segments,
603
-                  inv_segment_length = 1.0f / segment_length, // 1/mm/segs
604
-                  inverse_secs = inv_segment_length * _feedrate_mm_s;
605
-
606
-      float oldA = planner.position_float[A_AXIS],
607
-            oldB = planner.position_float[B_AXIS]
608
-            #if ENABLED(DELTA_FEEDRATE_SCALING)
609
-              , oldC = planner.position_float[C_AXIS]
610
-            #endif
611
-            ;
612
-
613
-      /*
614
-      SERIAL_ECHOPGM("Scaled kinematic move: ");
615
-      SERIAL_ECHOPAIR(" segment_length (inv)=", segment_length);
616
-      SERIAL_ECHOPAIR(" (", inv_segment_length);
617
-      SERIAL_ECHOPAIR(") _feedrate_mm_s=", _feedrate_mm_s);
618
-      SERIAL_ECHOPAIR(" inverse_secs=", inverse_secs);
619
-      SERIAL_ECHOPAIR(" oldA=", oldA);
620
-      SERIAL_ECHOPAIR(" oldB=", oldB);
621
-      #if ENABLED(DELTA_FEEDRATE_SCALING)
622
-        SERIAL_ECHOPAIR(" oldC=", oldC);
623
-      #endif
624
-      SERIAL_EOL();
625
-      safe_delay(5);
626
-      //*/
627
-    #endif
628
-
629
-     // Get the current position as starting point
598
+    // Get the current position as starting point
630 599
     float raw[XYZE];
631 600
     COPY(raw, current_position);
632 601
 
@@ -642,78 +611,20 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
642 611
 
643 612
       LOOP_XYZE(i) raw[i] += segment_distance[i];
644 613
 
645
-      #if ENABLED(DELTA) && HOTENDS < 2
646
-        DELTA_IK(raw); // Delta can inline its kinematics
647
-      #else
648
-        inverse_kinematics(raw);
649
-      #endif
650
-      ADJUST_DELTA(raw); // Adjust Z if bed leveling is enabled
651
-
652
-      #if ENABLED(SCARA_FEEDRATE_SCALING)
653
-        // For SCARA scale the feed rate from mm/s to degrees/s
654
-        // i.e., Complete the angular vector in the given time.
655
-        if (!planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], raw[Z_AXIS], raw[E_AXIS], HYPOT(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB) * inverse_secs, active_extruder, segment_length))
656
-          break;
657
-        /*
658
-        SERIAL_ECHO(segments);
659
-        SERIAL_ECHOPAIR(": X=", raw[X_AXIS]); SERIAL_ECHOPAIR(" Y=", raw[Y_AXIS]);
660
-        SERIAL_ECHOPAIR(" A=", delta[A_AXIS]); SERIAL_ECHOPAIR(" B=", delta[B_AXIS]);
661
-        SERIAL_ECHOLNPAIR(" F", HYPOT(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB) * inverse_secs * 60);
662
-        safe_delay(5);
663
-        //*/
664
-        oldA = delta[A_AXIS]; oldB = delta[B_AXIS];
665
-      #elif ENABLED(DELTA_FEEDRATE_SCALING)
666
-        // For DELTA scale the feed rate from Effector mm/s to Carriage mm/s
667
-        // i.e., Complete the linear vector in the given time.
668
-        if (!planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], SQRT(sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC)) * inverse_secs, active_extruder, segment_length))
669
-          break;
670
-        /*
671
-        SERIAL_ECHO(segments);
672
-        SERIAL_ECHOPAIR(": X=", raw[X_AXIS]); SERIAL_ECHOPAIR(" Y=", raw[Y_AXIS]);
673
-        SERIAL_ECHOPAIR(" A=", delta[A_AXIS]); SERIAL_ECHOPAIR(" B=", delta[B_AXIS]); SERIAL_ECHOPAIR(" C=", delta[C_AXIS]);
674
-        SERIAL_ECHOLNPAIR(" F", SQRT(sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC)) * inverse_secs * 60);
675
-        safe_delay(5);
676
-        //*/
677
-        oldA = delta[A_AXIS]; oldB = delta[B_AXIS]; oldC = delta[C_AXIS];
678
-      #else
679
-        if (!planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], _feedrate_mm_s, active_extruder, cartesian_segment_mm))
680
-          break;
681
-      #endif
614
+      if (!planner.buffer_line(raw, _feedrate_mm_s, active_extruder, cartesian_segment_mm
615
+        #if ENABLED(SCARA_FEEDRATE_SCALING)
616
+          , inv_duration
617
+        #endif
618
+      ))
619
+        break;
682 620
     }
683 621
 
684 622
     // Ensure last segment arrives at target location.
685
-    #if HAS_FEEDRATE_SCALING
686
-      inverse_kinematics(rtarget);
687
-      ADJUST_DELTA(rtarget);
688
-    #endif
689
-
690
-    #if ENABLED(SCARA_FEEDRATE_SCALING)
691
-      const float diff2 = HYPOT2(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB);
692
-      if (diff2) {
693
-        planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], rtarget[Z_AXIS], rtarget[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder, segment_length);
694
-        /*
695
-        SERIAL_ECHOPAIR("final: A=", delta[A_AXIS]); SERIAL_ECHOPAIR(" B=", delta[B_AXIS]);
696
-        SERIAL_ECHOPAIR(" adiff=", delta[A_AXIS] - oldA); SERIAL_ECHOPAIR(" bdiff=", delta[B_AXIS] - oldB);
697
-        SERIAL_ECHOLNPAIR(" F", SQRT(diff2) * inverse_secs * 60);
698
-        SERIAL_EOL();
699
-        safe_delay(5);
700
-        //*/
701
-      }
702
-    #elif ENABLED(DELTA_FEEDRATE_SCALING)
703
-      const float diff2 = sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC);
704
-      if (diff2) {
705
-        planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], rtarget[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder, segment_length);
706
-        /*
707
-        SERIAL_ECHOPAIR("final: A=", delta[A_AXIS]); SERIAL_ECHOPAIR(" B=", delta[B_AXIS]); SERIAL_ECHOPAIR(" C=", delta[C_AXIS]);
708
-        SERIAL_ECHOPAIR(" adiff=", delta[A_AXIS] - oldA); SERIAL_ECHOPAIR(" bdiff=", delta[B_AXIS] - oldB); SERIAL_ECHOPAIR(" cdiff=", delta[C_AXIS] - oldC);
709
-        SERIAL_ECHOLNPAIR(" F", SQRT(diff2) * inverse_secs * 60);
710
-        SERIAL_EOL();
711
-        safe_delay(5);
712
-        //*/
713
-      }
714
-    #else
715
-      planner.buffer_line_kinematic(rtarget, _feedrate_mm_s, active_extruder, cartesian_segment_mm);
716
-    #endif
623
+    planner.buffer_line(rtarget, _feedrate_mm_s, active_extruder, cartesian_segment_mm
624
+      #if ENABLED(SCARA_FEEDRATE_SCALING)
625
+        , inv_duration
626
+      #endif
627
+    );
717 628
 
718 629
     return false; // caller will update current_position
719 630
   }
@@ -736,7 +647,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
736 647
 
737 648
       // If the move is only in Z/E don't split up the move
738 649
       if (!xdiff && !ydiff) {
739
-        planner.buffer_line_kinematic(destination, fr_mm_s, active_extruder);
650
+        planner.buffer_line(destination, fr_mm_s, active_extruder);
740 651
         return;
741 652
       }
742 653
 
@@ -766,6 +677,10 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
766 677
                     ediff * inv_segments
767 678
                   };
768 679
 
680
+      #if ENABLED(SCARA_FEEDRATE_SCALING)
681
+        const float inv_duration = _feedrate_mm_s / cartesian_segment_mm;
682
+      #endif
683
+
769 684
       // SERIAL_ECHOPAIR("mm=", cartesian_mm);
770 685
       // SERIAL_ECHOLNPAIR(" segments=", segments);
771 686
       // SERIAL_ECHOLNPAIR(" segment_mm=", cartesian_segment_mm);
@@ -783,13 +698,21 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
783 698
           idle();
784 699
         }
785 700
         LOOP_XYZE(i) raw[i] += segment_distance[i];
786
-        if (!planner.buffer_line_kinematic(raw, fr_mm_s, active_extruder, cartesian_segment_mm))
701
+        if (!planner.buffer_line(raw, fr_mm_s, active_extruder, cartesian_segment_mm
702
+          #if ENABLED(SCARA_FEEDRATE_SCALING)
703
+            , inv_duration
704
+          #endif
705
+        ))
787 706
           break;
788 707
       }
789 708
 
790 709
       // Since segment_distance is only approximate,
791 710
       // the final move must be to the exact destination.
792
-      planner.buffer_line_kinematic(destination, fr_mm_s, active_extruder, cartesian_segment_mm);
711
+      planner.buffer_line(destination, fr_mm_s, active_extruder, cartesian_segment_mm
712
+        #if ENABLED(SCARA_FEEDRATE_SCALING)
713
+          , inv_duration
714
+        #endif
715
+      );
793 716
     }
794 717
 
795 718
   #endif // SEGMENT_LEVELED_MOVES
@@ -922,7 +845,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
922 845
               planner.max_feedrate_mm_s[X_AXIS], 1)
923 846
             ) break;
924 847
             planner.synchronize();
925
-            SYNC_PLAN_POSITION_KINEMATIC();
848
+            sync_plan_position();
926 849
             extruder_duplication_enabled = true;
927 850
             active_extruder_parked = false;
928 851
             #if ENABLED(DEBUG_LEVELING_FEATURE)
@@ -1092,7 +1015,7 @@ inline float get_homing_bump_feedrate(const AxisEnum axis) {
1092 1015
 /**
1093 1016
  * Home an individual linear axis
1094 1017
  */
1095
-static void do_homing_move(const AxisEnum axis, const float distance, const float fr_mm_s=0.0) {
1018
+void do_homing_move(const AxisEnum axis, const float distance, const float fr_mm_s=0.0) {
1096 1019
 
1097 1020
   #if ENABLED(DEBUG_LEVELING_FEATURE)
1098 1021
     if (DEBUGGING(LEVELING)) {
@@ -1139,18 +1062,29 @@ static void do_homing_move(const AxisEnum axis, const float distance, const floa
1139 1062
     #endif
1140 1063
   }
1141 1064
 
1142
-  // Tell the planner the axis is at 0
1143
-  current_position[axis] = 0;
1144
-
1145 1065
   #if IS_SCARA
1146
-    SYNC_PLAN_POSITION_KINEMATIC();
1066
+    // Tell the planner the axis is at 0
1067
+    current_position[axis] = 0;
1068
+    sync_plan_position();
1147 1069
     current_position[axis] = distance;
1148
-    inverse_kinematics(current_position);
1149
-    planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], current_position[E_AXIS], fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder);
1070
+    planner.buffer_line(current_position, fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder);
1150 1071
   #else
1151
-    sync_plan_position();
1152
-    current_position[axis] = distance; // Set delta/cartesian axes directly
1153
-    planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder);
1072
+    float target[ABCE] = { planner.get_axis_position_mm(A_AXIS), planner.get_axis_position_mm(B_AXIS), planner.get_axis_position_mm(C_AXIS), planner.get_axis_position_mm(E_AXIS) };
1073
+    target[axis] = 0;
1074
+    planner.set_machine_position_mm(target);
1075
+    target[axis] = distance;
1076
+
1077
+    #if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
1078
+      const float delta_mm_cart[XYZE] = {0, 0, 0, 0};
1079
+    #endif
1080
+
1081
+    // Set delta/cartesian axes directly
1082
+    planner.buffer_segment(target
1083
+      #if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
1084
+        , delta_mm_cart
1085
+      #endif
1086
+      , fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder
1087
+    );
1154 1088
   #endif
1155 1089
 
1156 1090
   planner.synchronize();
@@ -1349,7 +1283,14 @@ void homeaxis(const AxisEnum axis) {
1349 1283
     if (axis == Z_AXIS && set_bltouch_deployed(true)) return;
1350 1284
   #endif
1351 1285
 
1352
-  do_homing_move(axis, 1.5f * max_length(axis) * axis_home_dir);
1286
+  do_homing_move(axis, 1.5f * max_length(
1287
+    #if ENABLED(DELTA)
1288
+      Z_AXIS
1289
+    #else
1290
+      axis
1291
+    #endif
1292
+    ) * axis_home_dir
1293
+  );
1353 1294
 
1354 1295
   #if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH)
1355 1296
     // BLTOUCH needs to be stowed after trigger to rearm itself
@@ -1481,7 +1422,7 @@ void homeaxis(const AxisEnum axis) {
1481 1422
   #if IS_SCARA
1482 1423
 
1483 1424
     set_axis_is_at_home(axis);
1484
-    SYNC_PLAN_POSITION_KINEMATIC();
1425
+    sync_plan_position();
1485 1426
 
1486 1427
   #elif ENABLED(DELTA)
1487 1428
 

+ 0
- 23
Marlin/src/module/motion.h 查看文件

@@ -129,13 +129,6 @@ void set_current_from_steppers_for_axis(const AxisEnum axis);
129 129
 void sync_plan_position();
130 130
 void sync_plan_position_e();
131 131
 
132
-#if IS_KINEMATIC
133
-  void sync_plan_position_kinematic();
134
-  #define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position_kinematic()
135
-#else
136
-  #define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position()
137
-#endif
138
-
139 132
 /**
140 133
  * Move the planner to the current position from wherever it last moved
141 134
  * (or from wherever it has been told it is located).
@@ -354,20 +347,4 @@ void homeaxis(const AxisEnum axis);
354 347
   void set_home_offset(const AxisEnum axis, const float v);
355 348
 #endif
356 349
 
357
-#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
358
-  #if ENABLED(DELTA)
359
-    #define ADJUST_DELTA(V) \
360
-      if (planner.leveling_active) { \
361
-        const float zadj = bilinear_z_offset(V); \
362
-        delta[A_AXIS] += zadj; \
363
-        delta[B_AXIS] += zadj; \
364
-        delta[C_AXIS] += zadj; \
365
-      }
366
-  #else
367
-    #define ADJUST_DELTA(V) if (planner.leveling_active) { delta[Z_AXIS] += bilinear_z_offset(V); }
368
-  #endif
369
-#else
370
-  #define ADJUST_DELTA(V) NOOP
371
-#endif
372
-
373 350
 #endif // MOTION_H

+ 189
- 56
Marlin/src/module/planner.cpp 查看文件

@@ -133,8 +133,13 @@ float Planner::max_feedrate_mm_s[XYZE_N],     // (mm/s) M203 XYZE - Max speeds
133 133
       float Planner::max_e_jerk;
134 134
     #endif
135 135
   #endif
136
-#else
137
-  float Planner::max_jerk[XYZE];              // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
136
+#endif
137
+#if HAS_CLASSIC_JERK
138
+  #if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
139
+    float Planner::max_jerk[XYZ];             // (mm/s^2) M205 XYZ - The largest speed change requiring no acceleration.
140
+  #else
141
+    float Planner::max_jerk[XYZE];            // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
142
+  #endif
138 143
 #endif
139 144
 
140 145
 #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
@@ -220,6 +225,10 @@ float Planner::previous_speed[NUM_AXIS],
220 225
   float Planner::position_float[XYZE]; // Needed for accurate maths. Steps cannot be used!
221 226
 #endif
222 227
 
228
+#if IS_KINEMATIC
229
+  float Planner::position_cart[XYZE];
230
+#endif
231
+
223 232
 #if ENABLED(ULTRA_LCD)
224 233
   volatile uint32_t Planner::block_buffer_runtime_us = 0;
225 234
 #endif
@@ -235,6 +244,9 @@ void Planner::init() {
235 244
   #if HAS_POSITION_FLOAT
236 245
     ZERO(position_float);
237 246
   #endif
247
+  #if IS_KINEMATIC
248
+    ZERO(position_cart);
249
+  #endif
238 250
   ZERO(previous_speed);
239 251
   previous_nominal_speed_sqr = 0;
240 252
   #if ABL_PLANAR
@@ -1354,17 +1366,12 @@ void Planner::check_axes_activity() {
1354 1366
   }
1355 1367
 #endif
1356 1368
 
1357
-#if PLANNER_LEVELING || HAS_UBL_AND_CURVES
1369
+#if HAS_LEVELING
1358 1370
   /**
1359 1371
    * rx, ry, rz - Cartesian positions in mm
1360 1372
    *              Leveled XYZ on completion
1361 1373
    */
1362 1374
   void Planner::apply_leveling(float &rx, float &ry, float &rz) {
1363
-
1364
-    #if ENABLED(SKEW_CORRECTION)
1365
-      skew(rx, ry, rz);
1366
-    #endif
1367
-
1368 1375
     if (!leveling_active) return;
1369 1376
 
1370 1377
     #if ABL_PLANAR
@@ -1406,10 +1413,6 @@ void Planner::check_axes_activity() {
1406 1413
     #endif
1407 1414
   }
1408 1415
 
1409
-#endif
1410
-
1411
-#if PLANNER_LEVELING
1412
-
1413 1416
   void Planner::unapply_leveling(float raw[XYZ]) {
1414 1417
 
1415 1418
     if (leveling_active) {
@@ -1456,7 +1459,23 @@ void Planner::check_axes_activity() {
1456 1459
     #endif
1457 1460
   }
1458 1461
 
1459
-#endif // PLANNER_LEVELING
1462
+#endif // HAS_LEVELING
1463
+
1464
+#if ENABLED(FWRETRACT)
1465
+  /**
1466
+   * rz, e - Cartesian positions in mm
1467
+   */
1468
+  void Planner::apply_retract(float &rz, float &e) {
1469
+    rz += fwretract.current_hop;
1470
+    e -= fwretract.current_retract[active_extruder];
1471
+  }
1472
+
1473
+  void Planner::unapply_retract(float &rz, float &e) {
1474
+    rz -= fwretract.current_hop;
1475
+    e += fwretract.current_retract[active_extruder];
1476
+  }
1477
+
1478
+#endif
1460 1479
 
1461 1480
 void Planner::quick_stop() {
1462 1481
 
@@ -1554,6 +1573,7 @@ void Planner::synchronize() {
1554 1573
  * Add a new linear movement to the planner queue (in terms of steps).
1555 1574
  *
1556 1575
  *  target      - target position in steps units
1576
+ *  target_float - target position in direct (mm, degrees) units. optional
1557 1577
  *  fr_mm_s     - (target) speed of the move
1558 1578
  *  extruder    - target extruder
1559 1579
  *  millimeters - the length of the movement, if known
@@ -1562,7 +1582,10 @@ void Planner::synchronize() {
1562 1582
  */
1563 1583
 bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
1564 1584
   #if HAS_POSITION_FLOAT
1565
-    , const float (&target_float)[XYZE]
1585
+    , const float (&target_float)[ABCE]
1586
+  #endif
1587
+  #if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
1588
+    , const float (&delta_mm_cart)[XYZE]
1566 1589
   #endif
1567 1590
   , float fr_mm_s, const uint8_t extruder, const float &millimeters
1568 1591
 ) {
@@ -1579,6 +1602,9 @@ bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
1579 1602
     #if HAS_POSITION_FLOAT
1580 1603
       , target_float
1581 1604
     #endif
1605
+    #if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
1606
+      , delta_mm_cart
1607
+    #endif
1582 1608
     , fr_mm_s, extruder, millimeters
1583 1609
   )) {
1584 1610
     // Movement was not queued, probably because it was too short.
@@ -1618,9 +1644,12 @@ bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
1618 1644
  * Returns true is movement is acceptable, false otherwise
1619 1645
  */
1620 1646
 bool Planner::_populate_block(block_t * const block, bool split_move,
1621
-  const int32_t (&target)[XYZE]
1647
+  const int32_t (&target)[ABCE]
1622 1648
   #if HAS_POSITION_FLOAT
1623
-    , const float (&target_float)[XYZE]
1649
+    , const float (&target_float)[ABCE]
1650
+  #endif
1651
+  #if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
1652
+    , const float (&delta_mm_cart)[XYZE]
1624 1653
   #endif
1625 1654
   , float fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
1626 1655
 ) {
@@ -2243,12 +2272,21 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
2243 2272
     // Unit vector of previous path line segment
2244 2273
     static float previous_unit_vec[XYZE];
2245 2274
 
2246
-    float unit_vec[] = {
2247
-      delta_mm[A_AXIS] * inverse_millimeters,
2248
-      delta_mm[B_AXIS] * inverse_millimeters,
2249
-      delta_mm[C_AXIS] * inverse_millimeters,
2250
-      delta_mm[E_AXIS] * inverse_millimeters
2251
-    };
2275
+    #if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
2276
+      float unit_vec[] = {
2277
+        delta_mm_cart[X_AXIS] * inverse_millimeters,
2278
+        delta_mm_cart[Y_AXIS] * inverse_millimeters,
2279
+        delta_mm_cart[Z_AXIS] * inverse_millimeters,
2280
+        delta_mm_cart[E_AXIS] * inverse_millimeters
2281
+      };
2282
+    #else
2283
+      float unit_vec[] = {
2284
+        delta_mm[X_AXIS] * inverse_millimeters,
2285
+        delta_mm[Y_AXIS] * inverse_millimeters,
2286
+        delta_mm[Z_AXIS] * inverse_millimeters,
2287
+        delta_mm[E_AXIS] * inverse_millimeters
2288
+      };
2289
+    #endif
2252 2290
 
2253 2291
     // Skip first block or when previous_nominal_speed is used as a flag for homing and offset cycles.
2254 2292
     if (moves_queued && !UNEAR_ZERO(previous_nominal_speed_sqr)) {
@@ -2302,7 +2340,9 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
2302 2340
 
2303 2341
     COPY(previous_unit_vec, unit_vec);
2304 2342
 
2305
-  #else // Classic Jerk Limiting
2343
+  #endif
2344
+
2345
+  #if HAS_CLASSIC_JERK
2306 2346
 
2307 2347
     /**
2308 2348
      * Adapted from Průša MKS firmware
@@ -2317,7 +2357,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
2317 2357
     float safe_speed = nominal_speed;
2318 2358
 
2319 2359
     uint8_t limited = 0;
2320
-    LOOP_XYZE(i) {
2360
+    #if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
2361
+      LOOP_XYZ(i)
2362
+    #else
2363
+      LOOP_XYZE(i)
2364
+    #endif
2365
+    {
2321 2366
       const float jerk = ABS(current_speed[i]),   // cs : Starting from zero, change in speed for this axis
2322 2367
                   maxj = max_jerk[i];             // mj : The max jerk setting for this axis
2323 2368
       if (jerk > maxj) {                          // cs > mj : New current speed too fast?
@@ -2349,7 +2394,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
2349 2394
 
2350 2395
       // Now limit the jerk in all axes.
2351 2396
       const float smaller_speed_factor = vmax_junction / previous_nominal_speed;
2352
-      LOOP_XYZE(axis) {
2397
+      #if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
2398
+        LOOP_XYZ(axis)
2399
+      #else
2400
+        LOOP_XYZE(axis)
2401
+      #endif
2402
+      {
2353 2403
         // Limit an axis. We have to differentiate: coasting, reversal of an axis, full stop.
2354 2404
         float v_exit = previous_speed[axis] * smaller_speed_factor,
2355 2405
               v_entry = current_speed[axis];
@@ -2381,7 +2431,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
2381 2431
       vmax_junction = safe_speed;
2382 2432
 
2383 2433
     previous_safe_speed = safe_speed;
2384
-    vmax_junction_sqr = sq(vmax_junction);
2434
+
2435
+    #if ENABLED(JUNCTION_DEVIATION)
2436
+      vmax_junction_sqr = MIN(vmax_junction_sqr, sq(vmax_junction));
2437
+    #else
2438
+      vmax_junction_sqr = sq(vmax_junction);
2439
+    #endif
2385 2440
 
2386 2441
   #endif // Classic Jerk Limiting
2387 2442
 
@@ -2466,7 +2521,12 @@ void Planner::buffer_sync_block() {
2466 2521
  *  extruder    - target extruder
2467 2522
  *  millimeters - the length of the movement, if known
2468 2523
  */
2469
-bool Planner::buffer_segment(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/) {
2524
+bool Planner::buffer_segment(const float &a, const float &b, const float &c, const float &e
2525
+  #if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
2526
+    , const float (&delta_mm_cart)[XYZE]
2527
+  #endif
2528
+  , const float &fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
2529
+) {
2470 2530
 
2471 2531
   // If we are cleaning, do not accept queuing of movements
2472 2532
   if (cleaning_buffer_counter) return false;
@@ -2534,6 +2594,9 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
2534 2594
       #if HAS_POSITION_FLOAT
2535 2595
         , target_float
2536 2596
       #endif
2597
+      #if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
2598
+        , delta_mm_cart
2599
+      #endif
2537 2600
       , fr_mm_s, extruder, millimeters
2538 2601
     )
2539 2602
   ) return false;
@@ -2543,24 +2606,84 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
2543 2606
 } // buffer_segment()
2544 2607
 
2545 2608
 /**
2546
- * Directly set the planner XYZ position (and stepper positions)
2609
+ * Add a new linear movement to the buffer.
2610
+ * The target is cartesian, it's translated to delta/scara if
2611
+ * needed.
2612
+ *
2613
+ *
2614
+ *  rx,ry,rz,e   - target position in mm or degrees
2615
+ *  fr_mm_s      - (target) speed of the move (mm/s)
2616
+ *  extruder     - target extruder
2617
+ *  millimeters  - the length of the movement, if known
2618
+ *  inv_duration - the reciprocal if the duration of the movement, if known (kinematic only if feeedrate scaling is enabled) 
2619
+ */
2620
+bool Planner::buffer_line(const float &rx, const float &ry, const float &rz, const float &e, const float &fr_mm_s, const uint8_t extruder, const float millimeters
2621
+  #if ENABLED(SCARA_FEEDRATE_SCALING)
2622
+    , const float &inv_duration
2623
+  #endif
2624
+) {
2625
+  float raw[XYZE] = { rx, ry, rz, e };
2626
+  #if HAS_POSITION_MODIFIERS
2627
+    apply_modifiers(raw);
2628
+  #endif
2629
+
2630
+  #if IS_KINEMATIC
2631
+    const float delta_mm_cart[] = {
2632
+      rx - position_cart[X_AXIS],
2633
+      ry - position_cart[Y_AXIS],
2634
+      rz - position_cart[Z_AXIS]
2635
+      #if ENABLED(JUNCTION_DEVIATION)
2636
+        , e - position_cart[E_AXIS]
2637
+      #endif
2638
+    };
2639
+
2640
+    float mm = millimeters;
2641
+    if (mm == 0.0)
2642
+      mm = (delta_mm_cart[X_AXIS] != 0.0 || delta_mm_cart[Y_AXIS] != 0.0) ? SQRT(sq(delta_mm_cart[X_AXIS]) + sq(delta_mm_cart[Y_AXIS]) + sq(delta_mm_cart[Z_AXIS])) : fabs(delta_mm_cart[Z_AXIS]);
2643
+
2644
+    inverse_kinematics(raw);
2645
+
2646
+    #if ENABLED(SCARA_FEEDRATE_SCALING)
2647
+      // For SCARA scale the feed rate from mm/s to degrees/s
2648
+      // i.e., Complete the angular vector in the given time.
2649
+      const float duration_recip = inv_duration ? inv_duration : fr_mm_s / mm,
2650
+                  feedrate = HYPOT(delta[A_AXIS] - position_float[A_AXIS], delta[B_AXIS] - position_float[B_AXIS]) * duration_recip;
2651
+    #else
2652
+      const float feedrate = fr_mm_s;
2653
+    #endif
2654
+    if (buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS]
2655
+      #if ENABLED(JUNCTION_DEVIATION)
2656
+        , delta_mm_cart
2657
+      #endif
2658
+      , feedrate, extruder, mm
2659
+    )) {
2660
+      position_cart[X_AXIS] = rx;
2661
+      position_cart[Y_AXIS] = ry;
2662
+      position_cart[Z_AXIS] = rz;
2663
+      position_cart[E_AXIS] = e;
2664
+      return true;
2665
+    }
2666
+    else
2667
+      return false;
2668
+  #else
2669
+    return buffer_segment(raw, fr_mm_s, extruder, millimeters);
2670
+  #endif
2671
+} // buffer_line()
2672
+
2673
+/**
2674
+ * Directly set the planner ABC position (and stepper positions)
2547 2675
  * converting mm (or angles for SCARA) into steps.
2548 2676
  *
2549
- * On CORE machines stepper ABC will be translated from the given XYZ.
2677
+ * The provided ABC position is in machine units.
2550 2678
  */
2551 2679
 
2552
-void Planner::_set_position_mm(const float &a, const float &b, const float &c, const float &e) {
2680
+void Planner::set_machine_position_mm(const float &a, const float &b, const float &c, const float &e) {
2553 2681
   #if ENABLED(DISTINCT_E_FACTORS)
2554 2682
     last_extruder = active_extruder;
2555 2683
   #endif
2556 2684
   position[A_AXIS] = LROUND(a * axis_steps_per_mm[A_AXIS]);
2557 2685
   position[B_AXIS] = LROUND(b * axis_steps_per_mm[B_AXIS]);
2558
-  position[C_AXIS] = LROUND(axis_steps_per_mm[C_AXIS] * (c +(
2559
-    #if !IS_KINEMATIC && ENABLED(AUTO_BED_LEVELING_UBL)
2560
-      leveling_active ? ubl.get_z_correction(a, b) :
2561
-    #endif
2562
-    0)
2563
-  ));
2686
+  position[C_AXIS] = LROUND(c * axis_steps_per_mm[C_AXIS]);
2564 2687
   position[E_AXIS] = LROUND(e * axis_steps_per_mm[_EINDEX]);
2565 2688
   #if HAS_POSITION_FLOAT
2566 2689
     position_float[A_AXIS] = a;
@@ -2577,44 +2700,54 @@ void Planner::_set_position_mm(const float &a, const float &b, const float &c, c
2577 2700
     stepper.set_position(position[A_AXIS], position[B_AXIS], position[C_AXIS], position[E_AXIS]);
2578 2701
 }
2579 2702
 
2580
-void Planner::set_position_mm_kinematic(const float (&cart)[XYZE]) {
2581
-  #if PLANNER_LEVELING
2582
-    float raw[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] };
2583
-    apply_leveling(raw);
2584
-  #else
2585
-    const float (&raw)[XYZE] = cart;
2703
+void Planner::set_position_mm(const float &rx, const float &ry, const float &rz, const float &e) {
2704
+  float raw[XYZE] = { rx, ry, rz, e };
2705
+  #if HAS_POSITION_MODIFIERS
2706
+    apply_modifiers(raw
2707
+      #if HAS_LEVELING
2708
+        , true
2709
+      #endif
2710
+    );
2586 2711
   #endif
2587 2712
   #if IS_KINEMATIC
2713
+    position_cart[X_AXIS] = rx;
2714
+    position_cart[Y_AXIS] = ry;
2715
+    position_cart[Z_AXIS] = rz;
2716
+    position_cart[E_AXIS] = e;
2717
+
2588 2718
     inverse_kinematics(raw);
2589
-    _set_position_mm(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS]);
2719
+    set_machine_position_mm(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS]);
2590 2720
   #else
2591
-    _set_position_mm(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_AXIS]);
2721
+    set_machine_position_mm(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], raw[E_AXIS]);
2592 2722
   #endif
2593 2723
 }
2594 2724
 
2595 2725
 /**
2596 2726
  * Setters for planner position (also setting stepper position).
2597 2727
  */
2598
-void Planner::set_position_mm(const AxisEnum axis, const float &v) {
2728
+void Planner::set_e_position_mm(const float &e) {
2599 2729
   #if ENABLED(DISTINCT_E_FACTORS)
2600
-    const uint8_t axis_index = axis + (axis == E_AXIS ? active_extruder : 0);
2730
+    const uint8_t axis_index = E_AXIS + active_extruder;
2601 2731
     last_extruder = active_extruder;
2602 2732
   #else
2603
-    const uint8_t axis_index = axis;
2733
+    const uint8_t axis_index = E_AXIS;
2604 2734
   #endif
2605
-  position[axis] = LROUND(axis_steps_per_mm[axis_index] * (v + (
2606
-    #if ENABLED(AUTO_BED_LEVELING_UBL)
2607
-      axis == Z_AXIS && leveling_active ? ubl.get_z_correction(current_position[X_AXIS], current_position[Y_AXIS]) :
2608
-    #endif
2609
-    0)
2610
-  ));
2735
+  #if ENABLED(FWRETRACT)
2736
+    float e_new = e - fwretract.current_retract[active_extruder];
2737
+  #else
2738
+    const float e_new = e;
2739
+  #endif
2740
+  position[E_AXIS] = LROUND(axis_steps_per_mm[axis_index] * e_new);
2611 2741
   #if HAS_POSITION_FLOAT
2612
-    position_float[axis] = v;
2742
+    position_float[E_AXIS] = e_new;
2743
+  #endif
2744
+  #if IS_KINEMATIC
2745
+    position_cart[E_AXIS] = e;
2613 2746
   #endif
2614 2747
   if (has_blocks_queued())
2615 2748
     buffer_sync_block();
2616 2749
   else
2617
-    stepper.set_position(axis, position[axis]);
2750
+    stepper.set_position(E_AXIS, position[E_AXIS]);
2618 2751
 }
2619 2752
 
2620 2753
 // Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
@@ -2638,7 +2771,7 @@ void Planner::reset_acceleration_rates() {
2638 2771
 // Recalculate position, steps_to_mm if axis_steps_per_mm changes!
2639 2772
 void Planner::refresh_positioning() {
2640 2773
   LOOP_XYZE_N(i) steps_to_mm[i] = 1.0f / axis_steps_per_mm[i];
2641
-  set_position_mm_kinematic(current_position);
2774
+  set_position_mm(current_position);
2642 2775
   reset_acceleration_rates();
2643 2776
 }
2644 2777
 

+ 153
- 68
Marlin/src/module/planner.h 查看文件

@@ -45,6 +45,10 @@
45 45
   #include "../libs/vector_3.h"
46 46
 #endif
47 47
 
48
+#if ENABLED(FWRETRACT)
49
+  #include "../feature/fwretract.h"
50
+#endif
51
+
48 52
 enum BlockFlagBit : char {
49 53
   // Recalculate trapezoids on entry junction. For optimization.
50 54
   BLOCK_BIT_RECALCULATE,
@@ -151,7 +155,7 @@ typedef struct {
151 155
 
152 156
 } block_t;
153 157
 
154
-#define HAS_POSITION_FLOAT (ENABLED(LIN_ADVANCE) || HAS_FEEDRATE_SCALING)
158
+#define HAS_POSITION_FLOAT (ENABLED(LIN_ADVANCE) || ENABLED(SCARA_FEEDRATE_SCALING))
155 159
 
156 160
 #define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1))
157 161
 
@@ -210,14 +214,22 @@ class Planner {
210 214
     #if ENABLED(JUNCTION_DEVIATION)
211 215
       static float junction_deviation_mm;       // (mm) M205 J
212 216
       #if ENABLED(LIN_ADVANCE)
213
-        #if ENABLED(DISTINCT_E_FACTORS)
214
-          static float max_e_jerk[EXTRUDERS];   // Calculated from junction_deviation_mm
217
+        static float max_e_jerk                 // Calculated from junction_deviation_mm
218
+          #if ENABLED(DISTINCT_E_FACTORS)
219
+            [EXTRUDERS]
220
+          #endif
221
+        ;
222
+      #endif
223
+    #endif
224
+
225
+    #if HAS_CLASSIC_JERK
226
+      static float max_jerk[
227
+        #if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
228
+          XYZ                                    // (mm/s^2) M205 XYZ - The largest speed change requiring no acceleration.
215 229
         #else
216
-          static float max_e_jerk;
230
+          XYZE                                   // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
217 231
         #endif
218
-      #endif
219
-    #else
220
-      static float max_jerk[XYZE];              // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
232
+      ];
221 233
     #endif
222 234
 
223 235
     #if HAS_LEVELING
@@ -240,6 +252,10 @@ class Planner {
240 252
       static float position_float[XYZE];
241 253
     #endif
242 254
 
255
+    #if IS_KINEMATIC
256
+      static float position_cart[XYZE];
257
+    #endif
258
+
243 259
     #if ENABLED(SKEW_CORRECTION)
244 260
       #if ENABLED(SKEW_CORRECTION_GCODE)
245 261
         static float xy_skew_factor;
@@ -410,6 +426,8 @@ class Planner {
410 426
           }
411 427
         }
412 428
       }
429
+      FORCE_INLINE static void skew(float (&raw)[XYZ]) { skew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
430
+      FORCE_INLINE static void skew(float (&raw)[XYZE]) { skew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
413 431
 
414 432
       FORCE_INLINE static void unskew(float &cx, float &cy, const float &cz) {
415 433
         if (WITHIN(cx, X_MIN_POS, X_MAX_POS) && WITHIN(cy, Y_MIN_POS, Y_MAX_POS)) {
@@ -420,29 +438,76 @@ class Planner {
420 438
           }
421 439
         }
422 440
       }
441
+      FORCE_INLINE static void unskew(float (&raw)[XYZ]) { unskew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
442
+      FORCE_INLINE static void unskew(float (&raw)[XYZE]) { unskew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
423 443
 
424 444
     #endif // SKEW_CORRECTION
425 445
 
426
-    #if PLANNER_LEVELING || HAS_UBL_AND_CURVES
446
+    #if HAS_LEVELING
427 447
       /**
428 448
        * Apply leveling to transform a cartesian position
429 449
        * as it will be given to the planner and steppers.
430 450
        */
431 451
       static void apply_leveling(float &rx, float &ry, float &rz);
432 452
       FORCE_INLINE static void apply_leveling(float (&raw)[XYZ]) { apply_leveling(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
433
-    #endif
453
+      FORCE_INLINE static void apply_leveling(float (&raw)[XYZE]) { apply_leveling(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
434 454
 
435
-    #if PLANNER_LEVELING
436
-      #define ARG_X float rx
437
-      #define ARG_Y float ry
438
-      #define ARG_Z float rz
439 455
       static void unapply_leveling(float raw[XYZ]);
440
-    #else
441
-      #define ARG_X const float &rx
442
-      #define ARG_Y const float &ry
443
-      #define ARG_Z const float &rz
444 456
     #endif
445 457
 
458
+    #if ENABLED(FWRETRACT)
459
+      static void apply_retract(float &rz, float &e);
460
+      FORCE_INLINE static void apply_retract(float (&raw)[XYZE]) { apply_retract(raw[Z_AXIS], raw[E_AXIS]); }
461
+      static void unapply_retract(float &rz, float &e);
462
+      FORCE_INLINE static void unapply_retract(float (&raw)[XYZE]) { unapply_retract(raw[Z_AXIS], raw[E_AXIS]); }
463
+    #endif
464
+
465
+    #if HAS_POSITION_MODIFIERS
466
+      FORCE_INLINE static void apply_modifiers(float (&pos)[XYZE]
467
+        #if HAS_LEVELING
468
+          , bool leveling =
469
+          #if PLANNER_LEVELING
470
+            true
471
+          #else
472
+            false
473
+          #endif
474
+        #endif
475
+      ) {
476
+        #if ENABLED(SKEW_CORRECTION)
477
+          skew(pos);
478
+        #endif
479
+        #if HAS_LEVELING
480
+          if (leveling)
481
+            apply_leveling(pos);
482
+        #endif
483
+        #if ENABLED(FWRETRACT)
484
+          apply_retract(pos);
485
+        #endif
486
+      }
487
+
488
+      FORCE_INLINE static void unapply_modifiers(float (&pos)[XYZE]
489
+        #if HAS_LEVELING
490
+          , bool leveling =
491
+          #if PLANNER_LEVELING
492
+            true
493
+          #else
494
+            false
495
+          #endif
496
+        #endif
497
+      ) {
498
+        #if ENABLED(FWRETRACT)
499
+          unapply_retract(pos);
500
+        #endif
501
+        #if HAS_LEVELING
502
+          if (leveling)
503
+            unapply_leveling(pos);
504
+        #endif
505
+        #if ENABLED(SKEW_CORRECTION)
506
+          unskew(pos);
507
+        #endif
508
+      }
509
+    #endif // HAS_POSITION_MODIFIERS
510
+
446 511
     // Number of moves currently in the planner including the busy block, if any
447 512
     FORCE_INLINE static uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail); }
448 513
 
@@ -489,7 +554,10 @@ class Planner {
489 554
      */
490 555
     static bool _buffer_steps(const int32_t (&target)[XYZE]
491 556
       #if HAS_POSITION_FLOAT
492
-        , const float (&target_float)[XYZE]
557
+        , const float (&target_float)[ABCE]
558
+      #endif
559
+      #if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
560
+        , const float (&delta_mm_cart)[XYZE]
493 561
       #endif
494 562
       , float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
495 563
     );
@@ -511,6 +579,9 @@ class Planner {
511 579
       #if HAS_POSITION_FLOAT
512 580
         , const float (&target_float)[XYZE]
513 581
       #endif
582
+      #if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
583
+        , const float (&delta_mm_cart)[XYZE]
584
+      #endif
514 585
       , float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
515 586
     );
516 587
 
@@ -520,6 +591,13 @@ class Planner {
520 591
      */
521 592
     static void buffer_sync_block();
522 593
 
594
+  #if IS_KINEMATIC
595
+    private:
596
+
597
+      // Allow do_homing_move to access internal functions, such as buffer_segment.
598
+      friend void do_homing_move(const AxisEnum, const float, const float);
599
+  #endif
600
+
523 601
     /**
524 602
      * Planner::buffer_segment
525 603
      *
@@ -532,74 +610,83 @@ class Planner {
532 610
      *  extruder    - target extruder
533 611
      *  millimeters - the length of the movement, if known
534 612
      */
535
-    static bool buffer_segment(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0);
536
-
537
-    static void _set_position_mm(const float &a, const float &b, const float &c, const float &e);
613
+    static bool buffer_segment(const float &a, const float &b, const float &c, const float &e
614
+      #if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
615
+        , const float (&delta_mm_cart)[XYZE]
616
+      #endif
617
+      , const float &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
618
+    );
538 619
 
539
-    /**
540
-     * Add a new linear movement to the buffer.
541
-     * The target is NOT translated to delta/scara
542
-     *
543
-     * Leveling will be applied to input on cartesians.
544
-     * Kinematic machines should call buffer_line_kinematic (for leveled moves).
545
-     * (Cartesians may also call buffer_line_kinematic.)
546
-     *
547
-     *  rx,ry,rz,e   - target position in mm or degrees
548
-     *  fr_mm_s      - (target) speed of the move (mm/s)
549
-     *  extruder     - target extruder
550
-     *  millimeters  - the length of the movement, if known
551
-     */
552
-    FORCE_INLINE static bool buffer_line(ARG_X, ARG_Y, ARG_Z, const float &e, const float &fr_mm_s, const uint8_t extruder, const float millimeters = 0.0) {
553
-      #if PLANNER_LEVELING && IS_CARTESIAN
554
-        apply_leveling(rx, ry, rz);
620
+    FORCE_INLINE static bool buffer_segment(const float (&abce)[ABCE]
621
+      #if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
622
+        , const float (&delta_mm_cart)[XYZE]
555 623
       #endif
556
-      return buffer_segment(rx, ry, rz, e, fr_mm_s, extruder, millimeters);
624
+      , const float &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
625
+    ) {
626
+      return buffer_segment(abce[A_AXIS], abce[B_AXIS], abce[C_AXIS], abce[E_AXIS]
627
+        #if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
628
+          , delta_mm_cart
629
+        #endif
630
+        , fr_mm_s, extruder, millimeters);
557 631
     }
558 632
 
633
+  public:
634
+
559 635
     /**
560 636
      * Add a new linear movement to the buffer.
561 637
      * The target is cartesian, it's translated to delta/scara if
562 638
      * needed.
563 639
      *
564
-     *  cart         - x,y,z,e CARTESIAN target in mm
640
+     *
641
+     *  rx,ry,rz,e   - target position in mm or degrees
565 642
      *  fr_mm_s      - (target) speed of the move (mm/s)
566 643
      *  extruder     - target extruder
567 644
      *  millimeters  - the length of the movement, if known
645
+     *  inv_duration - the reciprocal if the duration of the movement, if known (kinematic only if feeedrate scaling is enabled) 
568 646
      */
569
-    FORCE_INLINE static bool buffer_line_kinematic(const float (&cart)[XYZE], const float &fr_mm_s, const uint8_t extruder, const float millimeters = 0.0) {
570
-      #if PLANNER_LEVELING
571
-        float raw[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] };
572
-        apply_leveling(raw);
573
-      #else
574
-        const float (&raw)[XYZE] = cart;
647
+    static bool buffer_line(const float &rx, const float &ry, const float &rz, const float &e, const float &fr_mm_s, const uint8_t extruder, const float millimeters=0.0
648
+      #if ENABLED(SCARA_FEEDRATE_SCALING)
649
+        , const float &inv_duration=0.0
575 650
       #endif
576
-      #if IS_KINEMATIC
577
-        inverse_kinematics(raw);
578
-        return buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS], fr_mm_s, extruder, millimeters);
579
-      #else
580
-        return buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_AXIS], fr_mm_s, extruder, millimeters);
651
+    );
652
+
653
+    FORCE_INLINE static bool buffer_line(const float (&cart)[XYZE], const float &fr_mm_s, const uint8_t extruder, const float millimeters=0.0
654
+      #if ENABLED(SCARA_FEEDRATE_SCALING)
655
+        , const float &inv_duration=0.0
581 656
       #endif
657
+    ) {
658
+      return buffer_line(cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS], cart[E_AXIS], fr_mm_s, extruder, millimeters
659
+        #if ENABLED(SCARA_FEEDRATE_SCALING)
660
+          , inv_duration
661
+        #endif
662
+      );
582 663
     }
583 664
 
584 665
     /**
585 666
      * Set the planner.position and individual stepper positions.
586 667
      * Used by G92, G28, G29, and other procedures.
668
+     * 
669
+     * The supplied position is in the cartesian coordinate space and is
670
+     * translated in to machine space as needed. Modifiers such as leveling
671
+     * and skew are also applied.
587 672
      *
588 673
      * Multiplies by axis_steps_per_mm[] and does necessary conversion
589 674
      * for COREXY / COREXZ / COREYZ to set the corresponding stepper positions.
590 675
      *
591 676
      * Clears previous speed values.
592 677
      */
593
-    FORCE_INLINE static void set_position_mm(ARG_X, ARG_Y, ARG_Z, const float &e) {
594
-      #if PLANNER_LEVELING && IS_CARTESIAN
595
-        apply_leveling(rx, ry, rz);
596
-      #endif
597
-      _set_position_mm(rx, ry, rz, e);
598
-    }
599
-    static void set_position_mm_kinematic(const float (&cart)[XYZE]);
600
-    static void set_position_mm(const AxisEnum axis, const float &v);
601
-    FORCE_INLINE static void set_z_position_mm(const float &z) { set_position_mm(Z_AXIS, z); }
602
-    FORCE_INLINE static void set_e_position_mm(const float &e) { set_position_mm(E_AXIS, e); }
678
+    static void set_position_mm(const float &rx, const float &ry, const float &rz, const float &e);
679
+    FORCE_INLINE static void set_position_mm(const float (&cart)[XYZE]) { set_position_mm(cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS], cart[E_AXIS]); }
680
+    static void set_e_position_mm(const float &e);
681
+
682
+    /**
683
+     * Set the planner.position and individual stepper positions.
684
+     * 
685
+     * The supplied position is in machine space, and no additional
686
+     * conversions are applied.
687
+     */
688
+    static void set_machine_position_mm(const float &a, const float &b, const float &c, const float &e);
689
+    FORCE_INLINE static void set_machine_position_mm(const float (&abce)[ABCE]) { set_machine_position_mm(abce[A_AXIS], abce[B_AXIS], abce[C_AXIS], abce[E_AXIS]); }
603 690
 
604 691
     /**
605 692
      * Get an axis position according to stepper position(s)
@@ -756,16 +843,14 @@ class Planner {
756 843
       static void autotemp_M104_M109();
757 844
     #endif
758 845
 
759
-    #if ENABLED(JUNCTION_DEVIATION)
846
+    #if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
760 847
       FORCE_INLINE static void recalculate_max_e_jerk() {
761 848
         #define GET_MAX_E_JERK(N) SQRT(SQRT(0.5) * junction_deviation_mm * (N) * RECIPROCAL(1.0 - SQRT(0.5)))
762
-        #if ENABLED(LIN_ADVANCE)
763
-          #if ENABLED(DISTINCT_E_FACTORS)
764
-            for (uint8_t i = 0; i < EXTRUDERS; i++)
765
-              max_e_jerk[i] = GET_MAX_E_JERK(max_acceleration_mm_per_s2[E_AXIS + i]);
766
-          #else
767
-            max_e_jerk = GET_MAX_E_JERK(max_acceleration_mm_per_s2[E_AXIS]);
768
-          #endif
849
+        #if ENABLED(DISTINCT_E_FACTORS)
850
+          for (uint8_t i = 0; i < EXTRUDERS; i++)
851
+            max_e_jerk[i] = GET_MAX_E_JERK(max_acceleration_mm_per_s2[E_AXIS + i]);
852
+        #else
853
+          max_e_jerk = GET_MAX_E_JERK(max_acceleration_mm_per_s2[E_AXIS]);
769 854
         #endif
770 855
       }
771 856
     #endif

+ 6
- 6
Marlin/src/module/planner_bezier.cpp 查看文件

@@ -190,15 +190,15 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS]
190 190
     bez_target[E_AXIS] = interp(position[E_AXIS], target[E_AXIS], t);
191 191
     clamp_to_software_endstops(bez_target);
192 192
 
193
-    #if HAS_UBL_AND_CURVES
194
-      float pos[XYZ] = { bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS] };
193
+    #if HAS_LEVELING && !PLANNER_LEVELING
194
+      float pos[XYZE] = { bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS], bez_target[E_AXIS] };
195 195
       planner.apply_leveling(pos);
196
-      if (!planner.buffer_segment(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS], bez_target[E_AXIS], fr_mm_s, active_extruder))
197
-        break;
198 196
     #else
199
-      if (!planner.buffer_line_kinematic(bez_target, fr_mm_s, extruder))
200
-        break;
197
+      const float (&pos)[XYZE] = bez_target;
201 198
     #endif
199
+
200
+    if (!planner.buffer_line(pos, fr_mm_s, active_extruder, step))
201
+      break;
202 202
   }
203 203
 }
204 204
 

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

@@ -537,7 +537,7 @@ static bool do_probe_move(const float z, const float fr_mm_s) {
537 537
   set_current_from_steppers_for_axis(Z_AXIS);
538 538
 
539 539
   // Tell the planner where we actually are
540
-  SYNC_PLAN_POSITION_KINEMATIC();
540
+  sync_plan_position();
541 541
 
542 542
   #if ENABLED(DEBUG_LEVELING_FEATURE)
543 543
     if (DEBUGGING(LEVELING)) DEBUG_POS("<<< do_probe_move", current_position);

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

@@ -104,7 +104,7 @@ void forward_kinematics_SCARA(const float &a, const float &b) {
104 104
  * Maths and first version by QHARLEY.
105 105
  * Integrated into Marlin and slightly restructured by Joachim Cerny.
106 106
  */
107
-void inverse_kinematics(const float raw[XYZ]) {
107
+void inverse_kinematics(const float (&raw)[XYZ]) {
108 108
 
109 109
   static float C2, S2, SK1, SK2, THETA, PSI;
110 110
 

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

@@ -24,8 +24,7 @@
24 24
  * scara.h - SCARA-specific functions
25 25
  */
26 26
 
27
-#ifndef __SCARA_H__
28
-#define __SCARA_H__
27
+#pragma once
29 28
 
30 29
 #include "../core/macros.h"
31 30
 
@@ -38,9 +37,11 @@ float constexpr L1 = SCARA_LINKAGE_1, L2 = SCARA_LINKAGE_2,
38 37
 
39 38
 void scara_set_axis_is_at_home(const AxisEnum axis);
40 39
 
41
-void inverse_kinematics(const float raw[XYZ]);
40
+void inverse_kinematics(const float (&raw)[XYZ]);
41
+FORCE_INLINE void inverse_kinematics(const float (&raw)[XYZE]) {
42
+  const float raw_xyz[XYZ] = { raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS] };
43
+  inverse_kinematics(raw_xyz);
44
+}
42 45
 void forward_kinematics_SCARA(const float &a, const float &b);
43 46
 
44 47
 void scara_report_positions();
45
-
46
-#endif // __SCARA_H__

+ 18
- 18
Marlin/src/module/tool_change.cpp 查看文件

@@ -134,7 +134,7 @@
134 134
       #if ENABLED(DEBUG_LEVELING_FEATURE)
135 135
         if (DEBUGGING(LEVELING)) DEBUG_POS("(1) Raise Z-Axis", current_position);
136 136
       #endif
137
-      planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
137
+      planner.buffer_line(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
138 138
       planner.synchronize();
139 139
 
140 140
       // STEP 2
@@ -145,7 +145,7 @@
145 145
           DEBUG_POS("Moving ParkPos", current_position);
146 146
         }
147 147
       #endif
148
-      planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
148
+      planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
149 149
       planner.synchronize();
150 150
 
151 151
       // STEP 3
@@ -163,7 +163,7 @@
163 163
       #if ENABLED(DEBUG_LEVELING_FEATURE)
164 164
         if (DEBUGGING(LEVELING)) DEBUG_POS("Move away from parked extruder", current_position);
165 165
       #endif
166
-      planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
166
+      planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
167 167
       planner.synchronize();
168 168
 
169 169
       // STEP 5
@@ -178,12 +178,12 @@
178 178
 
179 179
       // STEP 6
180 180
       current_position[X_AXIS] = grabpos + (tmp_extruder ? -10 : 10);
181
-      planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
181
+      planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
182 182
       current_position[X_AXIS] = grabpos;
183 183
       #if ENABLED(DEBUG_LEVELING_FEATURE)
184 184
         if (DEBUGGING(LEVELING)) DEBUG_POS("(6) Unpark extruder", current_position);
185 185
       #endif
186
-      planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS]/2, active_extruder);
186
+      planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS]/2, active_extruder);
187 187
       planner.synchronize();
188 188
 
189 189
       // Step 7
@@ -191,7 +191,7 @@
191 191
       #if ENABLED(DEBUG_LEVELING_FEATURE)
192 192
         if (DEBUGGING(LEVELING)) DEBUG_POS("(7) Move midway between hotends", current_position);
193 193
       #endif
194
-      planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
194
+      planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
195 195
       planner.synchronize();
196 196
       #if ENABLED(DEBUG_LEVELING_FEATURE)
197 197
         SERIAL_ECHOLNPGM("Autopark done.");
@@ -241,7 +241,7 @@
241 241
     #if ENABLED(DEBUG_LEVELING_FEATURE)
242 242
       if (DEBUGGING(LEVELING)) DEBUG_POS("(1) Raise Z-Axis", current_position);
243 243
     #endif
244
-    planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
244
+    planner.buffer_line(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
245 245
     planner.synchronize();
246 246
 
247 247
     // STEP 2
@@ -252,14 +252,14 @@
252 252
         DEBUG_POS("Move X SwitchPos", current_position);
253 253
       }
254 254
     #endif
255
-    planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
255
+    planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
256 256
     planner.synchronize();
257 257
 
258 258
     current_position[Y_AXIS] = SWITCHING_TOOLHEAD_Y_POS - SWITCHING_TOOLHEAD_Y_SECURITY;
259 259
     #if ENABLED(DEBUG_LEVELING_FEATURE)
260 260
       if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos + Security", current_position);
261 261
     #endif
262
-    planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder);
262
+    planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder);
263 263
     planner.synchronize();
264 264
 
265 265
     // STEP 3
@@ -273,14 +273,14 @@
273 273
     #if ENABLED(DEBUG_LEVELING_FEATURE)
274 274
       if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos", current_position);
275 275
     #endif
276
-    planner.buffer_line_kinematic(current_position,(planner.max_feedrate_mm_s[Y_AXIS] * 0.5), active_extruder);
276
+    planner.buffer_line(current_position,(planner.max_feedrate_mm_s[Y_AXIS] * 0.5), active_extruder);
277 277
     planner.synchronize();
278 278
     safe_delay(200);
279 279
     current_position[Y_AXIS] -= SWITCHING_TOOLHEAD_Y_CLEAR;
280 280
     #if ENABLED(DEBUG_LEVELING_FEATURE)
281 281
       if (DEBUGGING(LEVELING)) DEBUG_POS("Move back Y clear", current_position);
282 282
     #endif
283
-    planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder); // move away from docked toolhead
283
+    planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder); // move away from docked toolhead
284 284
     planner.synchronize();
285 285
 
286 286
     // STEP 4
@@ -291,13 +291,13 @@
291 291
     #if ENABLED(DEBUG_LEVELING_FEATURE)
292 292
       if (DEBUGGING(LEVELING)) DEBUG_POS("Move to new toolhead X", current_position);
293 293
     #endif
294
-    planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
294
+    planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
295 295
     planner.synchronize();
296 296
     current_position[Y_AXIS] = SWITCHING_TOOLHEAD_Y_POS - SWITCHING_TOOLHEAD_Y_SECURITY;
297 297
     #if ENABLED(DEBUG_LEVELING_FEATURE)
298 298
       if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos + Security", current_position);
299 299
     #endif
300
-    planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder);
300
+    planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder);
301 301
     planner.synchronize();
302 302
 
303 303
     // STEP 5
@@ -308,7 +308,7 @@
308 308
     #if ENABLED(DEBUG_LEVELING_FEATURE)
309 309
       if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos", current_position);
310 310
     #endif
311
-    planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Y_AXIS] * 0.5, active_extruder);
311
+    planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS] * 0.5, active_extruder);
312 312
     planner.synchronize();
313 313
 
314 314
     safe_delay(200);
@@ -319,7 +319,7 @@
319 319
     #if ENABLED(DEBUG_LEVELING_FEATURE)
320 320
       if (DEBUGGING(LEVELING)) DEBUG_POS("Move back Y clear", current_position);
321 321
     #endif
322
-    planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder); // move away from docked toolhead
322
+    planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder); // move away from docked toolhead
323 323
     planner.synchronize();
324 324
 
325 325
     // STEP 6
@@ -524,7 +524,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
524 524
             #if ENABLED(SWITCHING_NOZZLE)
525 525
               // Always raise by at least 1 to avoid workpiece
526 526
               current_position[Z_AXIS] += MAX(-zdiff, 0.0) + 1;
527
-              planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
527
+              planner.buffer_line(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
528 528
               move_nozzle_servo(tmp_extruder);
529 529
             #endif
530 530
           #endif
@@ -549,7 +549,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
549 549
         #endif // !DUAL_X_CARRIAGE
550 550
 
551 551
         // Tell the planner the new "current position"
552
-        SYNC_PLAN_POSITION_KINEMATIC();
552
+        sync_plan_position();
553 553
 
554 554
         #if ENABLED(DELTA)
555 555
           //LOOP_XYZ(i) update_software_endstops(i); // or modify the constrain function
@@ -563,7 +563,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
563 563
           #if DISABLED(SWITCHING_NOZZLE)
564 564
             // Do a small lift to avoid the workpiece in the move back (below)
565 565
             current_position[Z_AXIS] += 1.0;
566
-            planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
566
+            planner.buffer_line(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
567 567
           #endif
568 568
           #if ENABLED(DEBUG_LEVELING_FEATURE)
569 569
             if (DEBUGGING(LEVELING)) DEBUG_POS("Move back", destination);

Loading…
取消
儲存