Skip to content

Commit

Permalink
backport TMC2208 linear advance fix
Browse files Browse the repository at this point in the history
  • Loading branch information
queeup committed Oct 4, 2024
1 parent e7b2bad commit 460ece8
Show file tree
Hide file tree
Showing 4 changed files with 231 additions and 277 deletions.
75 changes: 37 additions & 38 deletions Marlin/src/module/planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
NOLESS(initial_rate, uint32_t(MINIMAL_STEP_RATE));
NOLESS(final_rate, uint32_t(MINIMAL_STEP_RATE));

#if ENABLED(S_CURVE_ACCELERATION)
#if EITHER(S_CURVE_ACCELERATION, LIN_ADVANCE)
uint32_t cruise_rate = initial_rate;
#endif

Expand All @@ -805,12 +805,12 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
accelerate_steps = _MIN(uint32_t(_MAX(accelerate_steps_float, 0)), block->step_event_count);
plateau_steps = 0;

#if ENABLED(S_CURVE_ACCELERATION)
#if EITHER(S_CURVE_ACCELERATION, LIN_ADVANCE)
// We won't reach the cruising rate. Let's calculate the speed we will reach
cruise_rate = final_speed(initial_rate, accel, accelerate_steps);
#endif
}
#if ENABLED(S_CURVE_ACCELERATION)
#if EITHER(S_CURVE_ACCELERATION, LIN_ADVANCE)
else // We have some plateau time, so the cruise rate will be the nominal rate
cruise_rate = block->nominal_rate;
#endif
Expand All @@ -837,6 +837,14 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
#endif
block->final_rate = final_rate;

#if ENABLED(LIN_ADVANCE)
if (block->la_advance_rate) {
const float comp = extruder_advance_K[block->extruder] * block->steps.e / block->step_event_count;
block->max_adv_steps = cruise_rate * comp;
block->final_adv_steps = final_rate * comp;
}
#endif

/**
* Laser trapezoid calculations
*
Expand Down Expand Up @@ -1183,13 +1191,6 @@ void Planner::recalculate_trapezoids() {
const float current_nominal_speed = SQRT(block->nominal_speed_sqr),
nomr = 1.0f / current_nominal_speed;
calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr);
#if ENABLED(LIN_ADVANCE)
if (block->use_advance_lead) {
const float comp = block->e_D_ratio * extruder_advance_K[active_extruder] * settings.axis_steps_per_mm[E_AXIS];
block->max_adv_steps = current_nominal_speed * comp;
block->final_adv_steps = next_entry_speed * comp;
}
#endif
}

// Reset current only to ensure next trapezoid is computed - The
Expand Down Expand Up @@ -1222,13 +1223,6 @@ void Planner::recalculate_trapezoids() {
const float next_nominal_speed = SQRT(next->nominal_speed_sqr),
nomr = 1.0f / next_nominal_speed;
calculate_trapezoid_for_block(next, next_entry_speed * nomr, float(MINIMUM_PLANNER_SPEED) * nomr);
#if ENABLED(LIN_ADVANCE)
if (next->use_advance_lead) {
const float comp = next->e_D_ratio * extruder_advance_K[active_extruder] * settings.axis_steps_per_mm[E_AXIS];
next->max_adv_steps = next_nominal_speed * comp;
next->final_adv_steps = (MINIMUM_PLANNER_SPEED) * comp;
}
#endif
}

// Reset next only to ensure its trapezoid is computed - The stepper is free to use
Expand Down Expand Up @@ -2282,9 +2276,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
// Compute and limit the acceleration rate for the trapezoid generator.
const float steps_per_mm = block->step_event_count * inverse_millimeters;
uint32_t accel;
#if ENABLED(LIN_ADVANCE)
bool use_advance_lead = false;
#endif
if (!block->steps.a && !block->steps.b && !block->steps.c) { // Is this a retract / recover move?
accel = CEIL(settings.retract_acceleration * steps_per_mm); // Convert to: acceleration steps/sec^2
TERN_(LIN_ADVANCE, block->use_advance_lead = false); // No linear advance for simple retract/recover
}
else {
#define LIMIT_ACCEL_LONG(AXIS,INDX) do{ \
Expand Down Expand Up @@ -2317,27 +2313,23 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
*
* de > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
*/
block->use_advance_lead = esteps
&& extruder_advance_K[active_extruder]
&& de > 0;

if (block->use_advance_lead) {
block->e_D_ratio = (target_float.e - position_float.e) /
#if IS_KINEMATIC
block->millimeters
#else
use_advance_lead = esteps && extruder_advance_K[extruder] && de > 0;

if (use_advance_lead) {
float e_D_ratio = (target_float.e - position_float.e) /
TERN(IS_KINEMATIC, block->millimeters,
SQRT(sq(target_float.x - position_float.x)
+ sq(target_float.y - position_float.y)
+ sq(target_float.z - position_float.z))
#endif
;
);

// Check for unusual high e_D ratio to detect if a retract move was combined with the last print move due to min. steps per segment. Never execute this with advance!
// This assumes no one will use a retract length of 0mm < retr_length < ~0.2mm and no one will print 100mm wide lines using 3mm filament or 35mm wide lines using 1.75mm filament.
if (block->e_D_ratio > 3.0f)
block->use_advance_lead = false;
if (e_D_ratio > 3.0f)
use_advance_lead = false;
else {
const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[active_extruder] * block->e_D_ratio) * steps_per_mm;
// Scale E acceleration so that it will be possible to jump to the advance speed.
const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[extruder] * e_D_ratio) * steps_per_mm;
if (TERN0(LA_DEBUG, accel > max_accel_steps_per_s2))
SERIAL_ECHOLNPGM("Acceleration limited.");
NOMORE(accel, max_accel_steps_per_s2);
Expand Down Expand Up @@ -2365,13 +2357,20 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
block->acceleration_rate = (uint32_t)(accel * (sq(4096.0f) / (STEPPER_TIMER_RATE)));
#endif
#if ENABLED(LIN_ADVANCE)
if (block->use_advance_lead) {
block->advance_speed = (STEPPER_TIMER_RATE) / (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * settings.axis_steps_per_mm[E_AXIS_N(extruder)]);
block->la_advance_rate = 0;
block->la_scaling = 0;

if (use_advance_lead) {
// the Bresenham algorithm will convert this step rate into extruder steps
block->la_advance_rate = extruder_advance_K[extruder] * block->acceleration_steps_per_s2;

// reduce LA ISR frequency by calling it only often enough to ensure that there will
// never be more than four extruder steps per call
for (uint32_t dividend = block->steps.e << 1; dividend <= (block->step_event_count >> 2); dividend <<= 1)
block->la_scaling++;
#if ENABLED(LA_DEBUG)
if (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * 2 < SQRT(block->nominal_speed_sqr) * block->e_D_ratio)
SERIAL_ECHOLNPGM("More than 2 steps per eISR loop executed.");
if (block->advance_speed < 200)
SERIAL_ECHOLNPGM("eISR running at > 10kHz.");
if (block->la_advance_rate >> block->la_scaling > 10000)
SERIAL_ECHOLNPGM("eISR running at > 10kHz: ", block->la_advance_rate);
#endif
}
#endif
Expand Down
11 changes: 5 additions & 6 deletions Marlin/src/module/planner.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,10 @@ typedef struct block_t {

// Advance extrusion
#if ENABLED(LIN_ADVANCE)
bool use_advance_lead;
uint16_t advance_speed, // STEP timer value for extruder speed offset ISR
max_adv_steps, // max. advance steps to get cruising speed pressure (not always nominal_speed!)
final_adv_steps; // advance steps due to exit speed
float e_D_ratio;
uint32_t la_advance_rate; // The rate at which steps are added whilst accelerating
uint8_t la_scaling; // Scale ISR frequency down and step frequency up by 2 ^ la_scaling
uint16_t max_adv_steps, // Max advance steps to get cruising speed pressure
final_adv_steps; // Advance steps for exit speed pressure
#endif

uint32_t nominal_rate, // The nominal step rate for this block in step_events/sec
Expand Down Expand Up @@ -977,7 +976,7 @@ class Planner
return target_velocity_sqr - 2 * accel * distance;
}

#if ENABLED(S_CURVE_ACCELERATION)
#if EITHER(S_CURVE_ACCELERATION, LIN_ADVANCE)
/**
* Calculate the speed reached given initial speed, acceleration and distance
*/
Expand Down
Loading

0 comments on commit 460ece8

Please sign in to comment.