@@ -2490,9 +2490,9 @@ bool Planner::_populate_block(
2490
2490
*
2491
2491
* extruder_advance_K[extruder] : There is an advance factor set for this extruder.
2492
2492
*
2493
- * dist .e > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
2493
+ * dm .e : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
2494
2494
*/
2495
- use_advance_lead = esteps && extruder_advance_K[E_INDEX_N (extruder)] && dist. e > 0 ;
2495
+ use_advance_lead = esteps && extruder_advance_K[E_INDEX_N (extruder)] && dm. e ;
2496
2496
2497
2497
if (use_advance_lead) {
2498
2498
float e_D_ratio = (target_float.e - position_float.e ) /
@@ -2770,53 +2770,70 @@ bool Planner::_populate_block(
2770
2770
* Heavily modified. Originally adapted from Průša firmware.
2771
2771
* https://github.com/prusa3d/Prusa-Firmware
2772
2772
*/
2773
- #ifndef TRAVEL_EXTRA_XYJERK
2774
- #define TRAVEL_EXTRA_XYJERK 0 .0f
2773
+ #if defined(TRAVEL_EXTRA_XYJERK) || ENABLED(LIN_ADVANCE)
2774
+ xyze_float_t max_j = max_jerk;
2775
+ #else
2776
+ const xyze_float_t &max_j = max_jerk;
2775
2777
#endif
2776
- const float extra_xyjerk = TERN0 (HAS_EXTRUDERS, dist.e <= 0 ) ? TRAVEL_EXTRA_XYJERK : 0 .0f ;
2777
2778
2778
- if (!moves_queued || UNEAR_ZERO (previous_nominal_speed)) {
2779
- // Compute "safe" speed, limited by a jerk to/from full halt.
2779
+ #ifdef TRAVEL_EXTRA_XYJERK
2780
+ if (dist.e <= 0 ) {
2781
+ max_j.x += TRAVEL_EXTRA_XYJERK;
2782
+ max_j.y += TRAVEL_EXTRA_XYJERK;
2783
+ }
2784
+ #endif
2780
2785
2781
- float v_factor = 1 .0f ;
2782
- LOOP_LOGICAL_AXES (i) {
2783
- const float jerk = ABS (current_speed[i]), // Starting from zero, change in speed for this axis
2784
- maxj = max_jerk[i] + (i == X_AXIS || i == Y_AXIS ? extra_xyjerk : 0 .0f ); // The max jerk setting for this axis
2785
- if (jerk * v_factor > maxj) v_factor = maxj / jerk;
2786
+ #if ENABLED(LIN_ADVANCE)
2787
+ // Advance affects E_AXIS speed and therefore jerk. Add a speed correction whenever
2788
+ // LA is turned OFF. No correction is applied when LA is turned ON (because it didn't
2789
+ // perform well; it takes more time/effort to push/melt filament than the reverse).
2790
+ static uint32_t previous_advance_rate;
2791
+ static float previous_e_mm_per_step;
2792
+ if (dist.e < 0 && previous_advance_rate) {
2793
+ // Retract move after a segment with LA that ended with an E speed decrease.
2794
+ // Correct for this to allow a faster junction speed. Since the decrease always helps to
2795
+ // get E to nominal retract speed, the equation simplifies to an increase in max jerk.
2796
+ max_j.e += previous_advance_rate * previous_e_mm_per_step;
2786
2797
}
2787
- vmax_junction_sqr = sq (block->nominal_speed * v_factor);
2788
- NOLESS (minimum_planner_speed_sqr, vmax_junction_sqr);
2798
+ // Prepare for next segment.
2799
+ previous_advance_rate = block->la_advance_rate ;
2800
+ previous_e_mm_per_step = mm_per_step[E_AXIS_N (extruder)];
2801
+ #endif
2802
+
2803
+ xyze_float_t speed_diff = current_speed;
2804
+ float vmax_junction;
2805
+ const bool start_from_zero = !moves_queued || UNEAR_ZERO (previous_nominal_speed);
2806
+ if (start_from_zero) {
2807
+ // Limited by a jerk to/from full halt.
2808
+ vmax_junction = block->nominal_speed ;
2789
2809
}
2790
2810
else {
2791
2811
// Compute the maximum velocity allowed at a joint of two successive segments.
2792
2812
2793
2813
// The junction velocity will be shared between successive segments. Limit the junction velocity to their minimum.
2794
- float vmax_junction, previous_speed_factor, current_speed_factor;
2814
+ // Scale per-axis velocities for the same vmax_junction.
2795
2815
if (block->nominal_speed < previous_nominal_speed) {
2796
2816
vmax_junction = block->nominal_speed ;
2797
- previous_speed_factor = vmax_junction / previous_nominal_speed;
2798
- current_speed_factor = 1 . 0f ;
2817
+ const float previous_scale = vmax_junction / previous_nominal_speed;
2818
+ LOOP_LOGICAL_AXES (i) speed_diff[i] -= previous_speed[i] * previous_scale ;
2799
2819
}
2800
2820
else {
2801
2821
vmax_junction = previous_nominal_speed;
2802
- previous_speed_factor = 1 . 0f ;
2803
- current_speed_factor = vmax_junction / block-> nominal_speed ;
2822
+ const float current_scale = vmax_junction / block-> nominal_speed ;
2823
+ LOOP_LOGICAL_AXES (i) speed_diff[i] = speed_diff[i] * current_scale - previous_speed[i] ;
2804
2824
}
2825
+ }
2805
2826
2806
- // Now limit the jerk in all axes.
2807
- float v_factor = 1 .0f ;
2808
- LOOP_LOGICAL_AXES (i) {
2809
- // Scale per-axis velocities for the same vmax_junction.
2810
- const float v_exit = previous_speed[i] * previous_speed_factor,
2811
- v_entry = current_speed[i] * current_speed_factor;
2812
-
2813
- // Jerk is the per-axis velocity difference.
2814
- const float jerk = ABS (v_exit - v_entry),
2815
- maxj = max_jerk[i] + (i == X_AXIS || i == Y_AXIS ? extra_xyjerk : 0 .0f );
2816
- if (jerk * v_factor > maxj) v_factor = maxj / jerk;
2817
- }
2818
- vmax_junction_sqr = sq (vmax_junction * v_factor);
2827
+ // Now limit the jerk in all axes.
2828
+ float v_factor = 1 .0f ;
2829
+ LOOP_LOGICAL_AXES (i) {
2830
+ // Jerk is the per-axis velocity difference.
2831
+ const float jerk = ABS (speed_diff[i]), maxj = max_j[i];
2832
+ if (jerk * v_factor > maxj) v_factor = maxj / jerk;
2819
2833
}
2834
+ vmax_junction_sqr = sq (vmax_junction * v_factor);
2835
+
2836
+ if (start_from_zero) minimum_planner_speed_sqr = vmax_junction_sqr;
2820
2837
2821
2838
#endif // CLASSIC_JERK
2822
2839
0 commit comments