diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index 04e8ec5bba..c95426154f 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -1999,7 +1999,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, if (was_enabled) ENABLE_STEPPER_DRIVER_INTERRUPT(); #endif - block->nominal_speed_sqr = sq(block->millimeters * inverse_secs); // (mm/sec)^2 Always > 0 + block->nominal_speed_sqr = sq(block->millimeters * inverse_secs); // (mm/sec)^2 Always > 0 block->nominal_rate = CEIL(block->step_event_count * inverse_secs); // (step/sec) Always > 0 #if ENABLED(FILAMENT_WIDTH_SENSOR) @@ -2007,28 +2007,38 @@ bool Planner::_populate_block(block_t * const block, bool split_move, filwidth.advance_e(delta_mm.e); #endif - // Calculate and limit speed in mm/sec for each axis + // Calculate and limit speed in mm/sec + xyze_float_t current_speed; float speed_factor = 1.0f; // factor <1 decreases speed - LOOP_XYZE(i) { - #if BOTH(MIXING_EXTRUDER, RETRACT_SYNC_MIXING) - // In worst case, only one extruder running, no change is needed. - // In best case, all extruders run the same amount, we can divide by MIXING_STEPPERS - float delta_mm_i = 0; - if (i == E_AXIS && mixer.get_current_vtool() == MIXER_AUTORETRACT_TOOL) - delta_mm_i = delta_mm.e / MIXING_STEPPERS; - else - delta_mm_i = delta_mm.e; - #else - const float delta_mm_i = delta_mm[i]; - #endif - const feedRate_t cs = ABS(current_speed[i] = delta_mm_i * inverse_secs); - #if ENABLED(DISTINCT_E_FACTORS) - if (i == E_AXIS) i += extruder; - #endif - if (cs > settings.max_feedrate_mm_s[i]) NOMORE(speed_factor, settings.max_feedrate_mm_s[i] / cs); + + // Linear axes first with less logic + LOOP_XYZ(i) { + current_speed[i] = delta_mm[i] * inverse_secs; + const feedRate_t cs = ABS(current_speed[i]), + max_fr = settings.max_feedrate_mm_s[i]; + if (cs > max_fr) NOMORE(speed_factor, max_fr / cs); } + // Limit speed on extruders, if any + #if EXTRUDERS + { + current_speed.e = delta_mm.e * inverse_secs; + #if BOTH(MIXING_EXTRUDER, RETRACT_SYNC_MIXING) + // Move all mixing extruders at the specified rate + if (mixer.get_current_vtool() == MIXER_AUTORETRACT_TOOL) + current_speed.e *= MIXING_STEPPERS; + #endif + const feedRate_t cs = ABS(current_speed.e), + max_fr = (settings.max_feedrate_mm_s[E_AXIS_N(extruder)] + #if BOTH(MIXING_EXTRUDER, RETRACT_SYNC_MIXING) + * MIXING_STEPPERS + #endif + ); + if (cs > max_fr) NOMORE(speed_factor, max_fr / cs); + } + #endif + // Max segment time in µs. #ifdef XY_FREQUENCY_LIMIT