Unify LA for all trapezoid steps
Handle uniformly compression & decompression at any stage of the trapezoid. Compared to before, this now enables LA compression also in the cruising step (handling the converse of a chained wipe), as well as decompression during acceleration. Both of these can happen as a result of jerk moves, but are incredibly rare. This is mostly needed to allow rapid decompression directly at the acceleration step during travels between a retraction&deretraction. We also check for the pressure level in a single place, reducing code size as well as disabling LA earlier when not needed for the rest of the block.
This commit is contained in:
parent
13b0e27cd7
commit
ae4abdf11f
@ -1065,10 +1065,12 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||
* delta_mm[E_AXIS] >= 0 : Extruding or traveling, but _not_ retracting.
|
||||
* |delta_mm[Z_AXIS]| < 0.5 : Z is only moved for leveling (_not_ for priming)
|
||||
*/
|
||||
block->use_advance_lead = extruder_advance_K
|
||||
block->use_advance_lead = extruder_advance_K > 0
|
||||
&& delta_mm[E_AXIS] >= 0
|
||||
&& abs(delta_mm[Z_AXIS]) < 0.5;
|
||||
if (block->use_advance_lead) {
|
||||
// all extrusion moves with LA require a compression which is proportional to the
|
||||
// extrusion_length to distance ratio (e/D)
|
||||
e_D_ratio = (e - position_float[E_AXIS]) /
|
||||
sqrt(sq(x - position_float[X_AXIS])
|
||||
+ sq(y - position_float[Y_AXIS])
|
||||
|
@ -117,8 +117,8 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1};
|
||||
void advance_isr();
|
||||
|
||||
static const uint16_t ADV_NEVER = 0xFFFF;
|
||||
static const uint8_t ADV_INIT = 0b01;
|
||||
static const uint8_t ADV_DECELERATE = 0b10;
|
||||
static const uint8_t ADV_INIT = 0b01; // initialize LA
|
||||
static const uint8_t ADV_ACC_VARY = 0b10; // varying acceleration phase
|
||||
|
||||
static uint16_t nextMainISR;
|
||||
static uint16_t nextAdvanceISR;
|
||||
@ -130,9 +130,10 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1};
|
||||
static uint16_t current_adv_steps;
|
||||
static uint16_t target_adv_steps;
|
||||
|
||||
static int8_t e_steps;
|
||||
static uint8_t e_step_loops;
|
||||
static int8_t LA_phase;
|
||||
static int8_t e_steps; // scheduled e-steps during each isr loop
|
||||
static uint8_t e_step_loops; // e-steps to execute at most in each isr loop
|
||||
static uint8_t e_extruding; // current move is an extrusion move
|
||||
static int8_t LA_phase; // LA compensation phase
|
||||
|
||||
#define _NEXT_ISR(T) main_Rate = nextMainISR = T
|
||||
#else
|
||||
@ -366,11 +367,17 @@ FORCE_INLINE void stepper_next_block()
|
||||
counter_y.lo = counter_x.lo;
|
||||
counter_z.lo = counter_x.lo;
|
||||
counter_e.lo = counter_x.lo;
|
||||
#ifdef LIN_ADVANCE
|
||||
e_extruding = current_block->steps_e.lo != 0;
|
||||
#endif
|
||||
} else {
|
||||
counter_x.wide = -(current_block->step_event_count.wide >> 1);
|
||||
counter_y.wide = counter_x.wide;
|
||||
counter_z.wide = counter_x.wide;
|
||||
counter_e.wide = counter_x.wide;
|
||||
#ifdef LIN_ADVANCE
|
||||
e_extruding = current_block->steps_e.wide != 0;
|
||||
#endif
|
||||
}
|
||||
step_events_completed.wide = 0;
|
||||
// Set directions.
|
||||
@ -806,7 +813,7 @@ FORCE_INLINE void isr() {
|
||||
#ifdef LIN_ADVANCE
|
||||
if (current_block->use_advance_lead) {
|
||||
if (step_events_completed.wide <= (unsigned long int)step_loops)
|
||||
la_state = ADV_INIT;
|
||||
la_state = ADV_INIT | ADV_ACC_VARY;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -825,10 +832,9 @@ FORCE_INLINE void isr() {
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
if (current_block->use_advance_lead) {
|
||||
la_state = ADV_DECELERATE;
|
||||
if (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops) {
|
||||
target_adv_steps = current_block->final_adv_steps;
|
||||
la_state |= ADV_INIT;
|
||||
la_state = ADV_INIT | ADV_ACC_VARY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -842,17 +848,10 @@ FORCE_INLINE void isr() {
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
if(current_block->use_advance_lead) {
|
||||
if(current_adv_steps < target_adv_steps) {
|
||||
// after reaching cruising speed, halt compression. if we couldn't accumulate the
|
||||
// required pressure in the acceleration phase due to lost ticks it's unlikely we
|
||||
// could undo all of it during deceleration either
|
||||
target_adv_steps = current_adv_steps;
|
||||
}
|
||||
else if (!nextAdvanceISR && current_adv_steps > target_adv_steps) {
|
||||
// we're cruising in a block with excess backpressure and without a previous
|
||||
// acceleration phase - this *cannot* happen during a regular block, but it's
|
||||
// likely in result of chained a wipe move. release the pressure earlier by
|
||||
// forcedly enabling LA while cruising!
|
||||
if (!nextAdvanceISR) {
|
||||
// Due to E-jerk, there can be discontinuities in pressure state where an
|
||||
// acceleration or deceleration can be skipped or joined with the previous block.
|
||||
// If LA was not previously active, re-check the pressure level
|
||||
la_state = ADV_INIT;
|
||||
}
|
||||
}
|
||||
@ -865,10 +864,23 @@ FORCE_INLINE void isr() {
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
// avoid multiple instances or function calls to advance_spread
|
||||
if (la_state & ADV_INIT) eISR_Err = current_block->advance_rate / 4;
|
||||
if (la_state & ADV_INIT) {
|
||||
if (current_adv_steps == target_adv_steps) {
|
||||
// nothing to be done in this phase
|
||||
la_state = 0;
|
||||
}
|
||||
else {
|
||||
eISR_Err = current_block->advance_rate / 4;
|
||||
if ((la_state & ADV_ACC_VARY) && e_extruding && (current_adv_steps > target_adv_steps)) {
|
||||
// LA could reverse the direction of extrusion in this phase
|
||||
LA_phase = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (la_state & ADV_INIT || nextAdvanceISR != ADV_NEVER) {
|
||||
// update timers & phase for the next iteration
|
||||
advance_spread(main_Rate);
|
||||
if (la_state & ADV_DECELERATE) {
|
||||
if (LA_phase >= 0) {
|
||||
if (step_loops == e_step_loops)
|
||||
LA_phase = (eISR_Rate > main_Rate);
|
||||
else {
|
||||
|
Loading…
Reference in New Issue
Block a user