@@ -2490,9 +2490,9 @@ bool Planner::_populate_block(
24902490 *
24912491 * extruder_advance_K[extruder] : There is an advance factor set for this extruder.
24922492 *
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)
24942494 */
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 ;
24962496
24972497 if (use_advance_lead) {
24982498 float e_D_ratio = (target_float.e - position_float.e ) /
@@ -2770,53 +2770,70 @@ bool Planner::_populate_block(
27702770 * Heavily modified. Originally adapted from Průša firmware.
27712771 * https://github.com/prusa3d/Prusa-Firmware
27722772 */
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;
27752777 #endif
2776- const float extra_xyjerk = TERN0 (HAS_EXTRUDERS, dist.e <= 0 ) ? TRAVEL_EXTRA_XYJERK : 0 .0f ;
27772778
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
27802785
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;
27862797 }
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 ;
27892809 }
27902810 else {
27912811 // Compute the maximum velocity allowed at a joint of two successive segments.
27922812
27932813 // 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.
27952815 if (block->nominal_speed < previous_nominal_speed) {
27962816 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 ;
27992819 }
28002820 else {
28012821 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] ;
28042824 }
2825+ }
28052826
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;
28192833 }
2834+ vmax_junction_sqr = sq (vmax_junction * v_factor);
2835+
2836+ if (start_from_zero) minimum_planner_speed_sqr = vmax_junction_sqr;
28202837
28212838 #endif // CLASSIC_JERK
28222839
0 commit comments