Update/compute advance steps inside calculate_trapezoid_for_block
Do not store the block e_D ratio, store directly the computed compression factor so that we can recompute the advance steps quickly and update them in sync with the acceleration rates.
This commit is contained in:
parent
048628083a
commit
0239f4bce1
@ -261,6 +261,13 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
uint16_t final_adv_steps = 0;
|
||||
if (block->use_advance_lead) {
|
||||
final_adv_steps = exit_speed * block->adv_comp;
|
||||
}
|
||||
#endif
|
||||
|
||||
CRITICAL_SECTION_START; // Fill variables used by the stepper in a critical section
|
||||
// This block locks the interrupts globally for 4.38 us,
|
||||
// which corresponds to a maximum repeat frequency of 228.57 kHz.
|
||||
@ -271,6 +278,9 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit
|
||||
block->decelerate_after = accelerate_steps+plateau_steps;
|
||||
block->initial_rate = initial_rate;
|
||||
block->final_rate = final_rate;
|
||||
#ifdef LIN_ADVANCE
|
||||
block->final_adv_steps = final_adv_steps;
|
||||
#endif
|
||||
}
|
||||
CRITICAL_SECTION_END;
|
||||
}
|
||||
@ -399,18 +409,8 @@ void planner_recalculate(const float &safe_final_speed)
|
||||
}
|
||||
// Recalculate if current block entry or exit junction speed has changed.
|
||||
if ((prev->flag | current->flag) & BLOCK_FLAG_RECALCULATE) {
|
||||
// @wavexx: FIXME: the following check is not really enough. calculate_trapezoid does block
|
||||
// the isr to update the rates, but we don't. we should update atomically
|
||||
if (!prev->busy) {
|
||||
// NOTE: Entry and exit factors always > 0 by all previous logic operations.
|
||||
calculate_trapezoid_for_block(prev, prev->entry_speed, current->entry_speed);
|
||||
#ifdef LIN_ADVANCE
|
||||
if (prev->use_advance_lead) {
|
||||
const float comp = prev->e_D_ratio * extruder_advance_K * cs.axis_steps_per_unit[E_AXIS];
|
||||
prev->final_adv_steps = current->entry_speed * comp;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// NOTE: Entry and exit factors always > 0 by all previous logic operations.
|
||||
calculate_trapezoid_for_block(prev, prev->entry_speed, current->entry_speed);
|
||||
// Reset current only to ensure next trapezoid is computed.
|
||||
prev->flag &= ~BLOCK_FLAG_RECALCULATE;
|
||||
}
|
||||
@ -424,13 +424,6 @@ void planner_recalculate(const float &safe_final_speed)
|
||||
// Last/newest block in buffer. Exit speed is set with safe_final_speed. Always recalculated.
|
||||
current = block_buffer + prev_block_index(block_buffer_head);
|
||||
calculate_trapezoid_for_block(current, current->entry_speed, safe_final_speed);
|
||||
#ifdef LIN_ADVANCE
|
||||
if (current->use_advance_lead) {
|
||||
const float comp = current->e_D_ratio * extruder_advance_K * cs.axis_steps_per_unit[E_AXIS];
|
||||
current->max_adv_steps = current->nominal_speed * comp;
|
||||
current->final_adv_steps = safe_final_speed * comp;
|
||||
}
|
||||
#endif
|
||||
current->flag &= ~BLOCK_FLAG_RECALCULATE;
|
||||
|
||||
// SERIAL_ECHOLNPGM("planner_recalculate - 4");
|
||||
@ -1005,6 +998,9 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||
block->nominal_rate *= speed_factor;
|
||||
}
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
float e_D_ratio = 0;
|
||||
#endif
|
||||
// Compute and limit the acceleration rate for the trapezoid generator.
|
||||
// block->step_event_count ... event count of the fastest axis
|
||||
// block->millimeters ... Euclidian length of the XYZ movement or the E length, if no XYZ movement.
|
||||
@ -1022,7 +1018,7 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
/**
|
||||
* Use LIN_ADVANCE for blocks if all these are true:
|
||||
* Use LIN_ADVANCE within this block if all these are true:
|
||||
*
|
||||
* block->steps_e : This is a print move, because we checked for X, Y, Z steps before.
|
||||
* extruder_advance_K : There is an advance factor set.
|
||||
@ -1034,19 +1030,19 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||
&& delta_mm[E_AXIS] > 0
|
||||
&& abs(delta_mm[Z_AXIS]) < 0.5;
|
||||
if (block->use_advance_lead) {
|
||||
block->e_D_ratio = (e - position_float[E_AXIS]) /
|
||||
sqrt(sq(x - position_float[X_AXIS])
|
||||
+ sq(y - position_float[Y_AXIS])
|
||||
+ sq(z - position_float[Z_AXIS]));
|
||||
e_D_ratio = (e - position_float[E_AXIS]) /
|
||||
sqrt(sq(x - position_float[X_AXIS])
|
||||
+ sq(y - position_float[Y_AXIS])
|
||||
+ sq(z - position_float[Z_AXIS]));
|
||||
|
||||
// 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.0)
|
||||
if (e_D_ratio > 3.0)
|
||||
block->use_advance_lead = false;
|
||||
else {
|
||||
const uint32_t max_accel_steps_per_s2 = cs.max_jerk[E_AXIS] / (extruder_advance_K * block->e_D_ratio) * steps_per_mm;
|
||||
const uint32_t max_accel_steps_per_s2 = cs.max_jerk[E_AXIS] / (extruder_advance_K * e_D_ratio) * steps_per_mm;
|
||||
if (block->acceleration_st > max_accel_steps_per_s2) {
|
||||
block->acceleration_st = max_accel_steps_per_s2;
|
||||
#ifdef LA_DEBUG
|
||||
@ -1089,11 +1085,16 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||
|
||||
block->acceleration_rate = (long)((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0)));
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
#ifdef LIN_ADVANCE
|
||||
if (block->use_advance_lead) {
|
||||
// the nominal speed doesn't change past this point: calculate the compression ratio for the
|
||||
// segment and the required advance steps
|
||||
block->adv_comp = extruder_advance_K * e_D_ratio * cs.axis_steps_per_unit[E_AXIS];
|
||||
block->max_adv_steps = block->nominal_speed * block->adv_comp;
|
||||
|
||||
// to save more space we avoid another copy of calc_timer and go through slow division, but we
|
||||
// still need to replicate the *exact* same step grouping policy (see below)
|
||||
float advance_speed = (extruder_advance_K * block->e_D_ratio * block->acceleration * cs.axis_steps_per_unit[E_AXIS]);
|
||||
float advance_speed = (extruder_advance_K * e_D_ratio * block->acceleration * cs.axis_steps_per_unit[E_AXIS]);
|
||||
if (advance_speed > MAX_STEP_FREQUENCY) advance_speed = MAX_STEP_FREQUENCY;
|
||||
block->advance_rate = (F_CPU / 8.0) / advance_speed;
|
||||
if (block->advance_rate > 20000) {
|
||||
@ -1116,7 +1117,7 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||
SERIAL_ECHOLNPGM("LA: More than 2 steps per eISR loop executed.");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Start with a safe speed.
|
||||
// Safe speed is the speed, from which the machine may halt to stop immediately.
|
||||
|
@ -117,7 +117,7 @@ typedef struct {
|
||||
max_adv_steps, // max. advance steps to get cruising speed pressure (not always nominal_speed!)
|
||||
final_adv_steps; // advance steps due to exit speed
|
||||
uint8_t advance_step_loops; // Number of stepper ticks for each advance isr
|
||||
float e_D_ratio;
|
||||
float adv_comp; // Precomputed E compression factor
|
||||
#endif
|
||||
|
||||
uint16_t sdlen;
|
||||
|
@ -430,7 +430,8 @@ FORCE_INLINE void stepper_next_block()
|
||||
nextAdvanceISR = ADV_NEVER;
|
||||
e_steps = 0;
|
||||
|
||||
// incrementally lose pressure
|
||||
// incrementally lose pressure to give a chance for
|
||||
// a new LA block to be scheduled and recover
|
||||
if(current_adv_steps)
|
||||
--current_adv_steps;
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user