@@ -788,7 +788,7 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
788788 NOLESS (initial_rate, uint32_t (MINIMAL_STEP_RATE ));
789789 NOLESS (final_rate, uint32_t (MINIMAL_STEP_RATE ));
790790
791- #if ENABLED (S_CURVE_ACCELERATION)
791+ #if EITHER (S_CURVE_ACCELERATION, LIN_ADVANCE )
792792 // If we have some plateau time, the cruise rate will be the nominal rate
793793 uint32_t cruise_rate = block->nominal_rate ;
794794 #endif
@@ -820,7 +820,7 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
820820 accelerate_steps = _MIN (uint32_t (_MAX (accelerate_steps_float, 0 )), block->step_event_count );
821821 decelerate_steps = block->step_event_count - accelerate_steps;
822822
823- #if ENABLED (S_CURVE_ACCELERATION)
823+ #if EITHER (S_CURVE_ACCELERATION, LIN_ADVANCE )
824824 // We won't reach the cruising rate. Let's calculate the speed we will reach
825825 cruise_rate = final_speed (initial_rate, accel, accelerate_steps);
826826 #endif
@@ -849,6 +849,14 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
849849 #endif
850850 block->final_rate = final_rate;
851851
852+ #if ENABLED(LIN_ADVANCE)
853+ if (block->la_advance_rate ) {
854+ const float comp = extruder_advance_K[block->extruder ] * block->steps .e / block->step_event_count ;
855+ block->max_adv_steps = cruise_rate * comp;
856+ block->final_adv_steps = final_rate * comp;
857+ }
858+ #endif
859+
852860 #if ENABLED(LASER_POWER_TRAP)
853861 /* *
854862 * Laser Trapezoid Calculations
@@ -899,75 +907,76 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
899907 #endif // LASER_POWER_TRAP
900908}
901909
902- /* PLANNER SPEED DEFINITION
903- +--------+ <- current->nominal_speed
904- / \
905- current->entry_speed -> + \
906- | + <- next->entry_speed (aka exit speed)
907- +-------------+
908- time -->
909-
910- Recalculates the motion plan according to the following basic guidelines:
911-
912- 1. Go over every feasible block sequentially in reverse order and calculate the junction speeds
913- (i.e. current->entry_speed) such that:
914- a. No junction speed exceeds the pre-computed maximum junction speed limit or nominal speeds of
915- neighboring blocks.
916- b. A block entry speed cannot exceed one reverse-computed from its exit speed (next->entry_speed)
917- with a maximum allowable deceleration over the block travel distance.
918- c. The last (or newest appended) block is planned from a complete stop (an exit speed of zero).
919- 2. Go over every block in chronological (forward) order and dial down junction speed values if
920- a. The exit speed exceeds the one forward-computed from its entry speed with the maximum allowable
921- acceleration over the block travel distance.
922-
923- When these stages are complete, the planner will have maximized the velocity profiles throughout the all
924- of the planner blocks, where every block is operating at its maximum allowable acceleration limits. In
925- other words, for all of the blocks in the planner, the plan is optimal and no further speed improvements
926- are possible. If a new block is added to the buffer, the plan is recomputed according to the said
927- guidelines for a new optimal plan.
928-
929- To increase computational efficiency of these guidelines, a set of planner block pointers have been
930- created to indicate stop-compute points for when the planner guidelines cannot logically make any further
931- changes or improvements to the plan when in normal operation and new blocks are streamed and added to the
932- planner buffer. For example, if a subset of sequential blocks in the planner have been planned and are
933- bracketed by junction velocities at their maximums (or by the first planner block as well), no new block
934- added to the planner buffer will alter the velocity profiles within them. So we no longer have to compute
935- them. Or, if a set of sequential blocks from the first block in the planner (or a optimal stop-compute
936- point) are all accelerating, they are all optimal and can not be altered by a new block added to the
937- planner buffer, as this will only further increase the plan speed to chronological blocks until a maximum
938- junction velocity is reached. However, if the operational conditions of the plan changes from infrequently
939- used feed holds or feedrate overrides, the stop-compute pointers will be reset and the entire plan is
940- recomputed as stated in the general guidelines.
941-
942- Planner buffer index mapping:
943- - block_buffer_tail: Points to the beginning of the planner buffer. First to be executed or being executed.
944- - block_buffer_head: Points to the buffer block after the last block in the buffer. Used to indicate whether
945- the buffer is full or empty. As described for standard ring buffers, this block is always empty.
946- - block_buffer_planned: Points to the first buffer block after the last optimally planned block for normal
947- streaming operating conditions. Use for planning optimizations by avoiding recomputing parts of the
948- planner buffer that don't change with the addition of a new block, as describe above. In addition,
949- this block can never be less than block_buffer_tail and will always be pushed forward and maintain
950- this requirement when encountered by the Planner::release_current_block() routine during a cycle.
951-
952- NOTE: Since the planner only computes on what's in the planner buffer, some motions with many short
953- segments (e.g., complex curves) may seem to move slowly. This is because there simply isn't
954- enough combined distance traveled in the entire buffer to accelerate up to the nominal speed and
955- then decelerate to a complete stop at the end of the buffer, as stated by the guidelines. If this
956- happens and becomes an annoyance, there are a few simple solutions:
957-
958- - Maximize the machine acceleration. The planner will be able to compute higher velocity profiles
959- within the same combined distance.
960-
961- - Maximize line motion(s) distance per block to a desired tolerance. The more combined distance the
962- planner has to use, the faster it can go.
963-
964- - Maximize the planner buffer size. This also will increase the combined distance for the planner to
965- compute over. It also increases the number of computations the planner has to perform to compute an
966- optimal plan, so select carefully.
967-
968- - Use G2/G3 arcs instead of many short segments. Arcs inform the planner of a safe exit speed at the
969- end of the last segment, which alleviates this problem.
970- */
910+ /* *
911+ * PLANNER SPEED DEFINITION
912+ * +--------+ <- current->nominal_speed
913+ * / \
914+ * current->entry_speed -> + \
915+ * | + <- next->entry_speed (aka exit speed)
916+ * +-------------+
917+ * time -->
918+ *
919+ * Recalculates the motion plan according to the following basic guidelines:
920+ *
921+ * 1. Go over every feasible block sequentially in reverse order and calculate the junction speeds
922+ * (i.e. current->entry_speed) such that:
923+ * a. No junction speed exceeds the pre-computed maximum junction speed limit or nominal speeds of
924+ * neighboring blocks.
925+ * b. A block entry speed cannot exceed one reverse-computed from its exit speed (next->entry_speed)
926+ * with a maximum allowable deceleration over the block travel distance.
927+ * c. The last (or newest appended) block is planned from a complete stop (an exit speed of zero).
928+ * 2. Go over every block in chronological (forward) order and dial down junction speed values if
929+ * a. The exit speed exceeds the one forward-computed from its entry speed with the maximum allowable
930+ * acceleration over the block travel distance.
931+ *
932+ * When these stages are complete, the planner will have maximized the velocity profiles throughout the all
933+ * of the planner blocks, where every block is operating at its maximum allowable acceleration limits. In
934+ * other words, for all of the blocks in the planner, the plan is optimal and no further speed improvements
935+ * are possible. If a new block is added to the buffer, the plan is recomputed according to the said
936+ * guidelines for a new optimal plan.
937+ *
938+ * To increase computational efficiency of these guidelines, a set of planner block pointers have been
939+ * created to indicate stop-compute points for when the planner guidelines cannot logically make any further
940+ * changes or improvements to the plan when in normal operation and new blocks are streamed and added to the
941+ * planner buffer. For example, if a subset of sequential blocks in the planner have been planned and are
942+ * bracketed by junction velocities at their maximums (or by the first planner block as well), no new block
943+ * added to the planner buffer will alter the velocity profiles within them. So we no longer have to compute
944+ * them. Or, if a set of sequential blocks from the first block in the planner (or a optimal stop-compute
945+ * point) are all accelerating, they are all optimal and can not be altered by a new block added to the
946+ * planner buffer, as this will only further increase the plan speed to chronological blocks until a maximum
947+ * junction velocity is reached. However, if the operational conditions of the plan changes from infrequently
948+ * used feed holds or feedrate overrides, the stop-compute pointers will be reset and the entire plan is
949+ * recomputed as stated in the general guidelines.
950+ *
951+ * Planner buffer index mapping:
952+ * - block_buffer_tail: Points to the beginning of the planner buffer. First to be executed or being executed.
953+ * - block_buffer_head: Points to the buffer block after the last block in the buffer. Used to indicate whether
954+ * the buffer is full or empty. As described for standard ring buffers, this block is always empty.
955+ * - block_buffer_planned: Points to the first buffer block after the last optimally planned block for normal
956+ * streaming operating conditions. Use for planning optimizations by avoiding recomputing parts of the
957+ * planner buffer that don't change with the addition of a new block, as describe above. In addition,
958+ * this block can never be less than block_buffer_tail and will always be pushed forward and maintain
959+ * this requirement when encountered by the Planner::release_current_block() routine during a cycle.
960+ *
961+ * NOTE: Since the planner only computes on what's in the planner buffer, some motions with many short
962+ * segments (e.g., complex curves) may seem to move slowly. This is because there simply isn't
963+ * enough combined distance traveled in the entire buffer to accelerate up to the nominal speed and
964+ * then decelerate to a complete stop at the end of the buffer, as stated by the guidelines. If this
965+ * happens and becomes an annoyance, there are a few simple solutions:
966+ *
967+ * - Maximize the machine acceleration. The planner will be able to compute higher velocity profiles
968+ * within the same combined distance.
969+ *
970+ * - Maximize line motion(s) distance per block to a desired tolerance. The more combined distance the
971+ * planner has to use, the faster it can go.
972+ *
973+ * - Maximize the planner buffer size. This also will increase the combined distance for the planner to
974+ * compute over. It also increases the number of computations the planner has to perform to compute an
975+ * optimal plan, so select carefully.
976+ *
977+ * - Use G2/G3 arcs instead of many short segments. Arcs inform the planner of a safe exit speed at the
978+ * end of the last segment, which alleviates this problem.
979+ */
971980
972981// The kernel called by recalculate() when scanning the plan from last to first entry.
973982void Planner::reverse_pass_kernel (block_t * const current, const block_t * const next
@@ -1211,13 +1220,6 @@ void Planner::recalculate_trapezoids(TERN_(HINTS_SAFE_EXIT_SPEED, const_float_t
12111220 // NOTE: Entry and exit factors always > 0 by all previous logic operations.
12121221 const float nomr = 1 .0f / block->nominal_speed ;
12131222 calculate_trapezoid_for_block (block, current_entry_speed * nomr, next_entry_speed * nomr);
1214- #if ENABLED(LIN_ADVANCE)
1215- if (block->use_advance_lead ) {
1216- const float comp = block->e_D_ratio * extruder_advance_K[active_extruder] * settings.axis_steps_per_mm [E_AXIS ];
1217- block->max_adv_steps = block->nominal_speed * comp;
1218- block->final_adv_steps = next_entry_speed * comp;
1219- }
1220- #endif
12211223 }
12221224
12231225 // Reset current only to ensure next trapezoid is computed - The
@@ -1251,13 +1253,6 @@ void Planner::recalculate_trapezoids(TERN_(HINTS_SAFE_EXIT_SPEED, const_float_t
12511253
12521254 const float nomr = 1 .0f / block->nominal_speed ;
12531255 calculate_trapezoid_for_block (block, current_entry_speed * nomr, next_entry_speed * nomr);
1254- #if ENABLED(LIN_ADVANCE)
1255- if (block->use_advance_lead ) {
1256- const float comp = block->e_D_ratio * extruder_advance_K[active_extruder] * settings.axis_steps_per_mm [E_AXIS ];
1257- block->max_adv_steps = block->nominal_speed * comp;
1258- block->final_adv_steps = next_entry_speed * comp;
1259- }
1260- #endif
12611256 }
12621257
12631258 // Reset block to ensure its trapezoid is computed - The stepper is free to use
@@ -2502,13 +2497,15 @@ bool Planner::_populate_block(
25022497 // Compute and limit the acceleration rate for the trapezoid generator.
25032498 const float steps_per_mm = block->step_event_count * inverse_millimeters;
25042499 uint32_t accel;
2500+ #if ENABLED(LIN_ADVANCE)
2501+ bool use_advance_lead = false ;
2502+ #endif
25052503 if (NUM_AXIS_GANG (
25062504 !block->steps .a , && !block->steps .b , && !block->steps .c ,
25072505 && !block->steps .i , && !block->steps .j , && !block->steps .k ,
25082506 && !block->steps .u , && !block->steps .v , && !block->steps .w )
25092507 ) { // Is this a retract / recover move?
25102508 accel = CEIL (settings.retract_acceleration * steps_per_mm); // Convert to: acceleration steps/sec^2
2511- TERN_ (LIN_ADVANCE , block->use_advance_lead = false ); // No linear advance for simple retract/recover
25122509 }
25132510 else {
25142511 #define LIMIT_ACCEL_LONG (AXIS,INDX ) do { \
@@ -2535,33 +2532,29 @@ bool Planner::_populate_block(
25352532 /* *
25362533 * Use LIN_ADVANCE for blocks if all these are true:
25372534 *
2538- * esteps : This is a print move, because we checked for A, B, C steps before.
2535+ * esteps : This is a print move, because we checked for A, B, C steps before.
25392536 *
2540- * extruder_advance_K[active_extruder ] : There is an advance factor set for this extruder.
2537+ * extruder_advance_K[extruder ] : There is an advance factor set for this extruder.
25412538 *
2542- * de > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
2539+ * de > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
25432540 */
2544- block->use_advance_lead = esteps
2545- && extruder_advance_K[active_extruder]
2546- && de > 0 ;
2547-
2548- if (block->use_advance_lead ) {
2549- block->e_D_ratio = (target_float.e - position_float.e ) /
2550- #if IS_KINEMATIC
2551- block->millimeters
2552- #else
2541+ use_advance_lead = esteps && extruder_advance_K[extruder] && de > 0 ;
2542+
2543+ if (use_advance_lead) {
2544+ float e_D_ratio = (target_float.e - position_float.e ) /
2545+ TERN (IS_KINEMATIC , block->millimeters ,
25532546 SQRT (sq (target_float.x - position_float.x )
25542547 + sq (target_float.y - position_float.y )
25552548 + sq (target_float.z - position_float.z ))
2556- #endif
2557- ;
2549+ );
25582550
25592551 // 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!
25602552 // 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.
2561- if (block-> e_D_ratio > 3 .0f )
2562- block-> use_advance_lead = false ;
2553+ if (e_D_ratio > 3 .0f )
2554+ use_advance_lead = false ;
25632555 else {
2564- const uint32_t max_accel_steps_per_s2 = MAX_E_JERK (extruder) / (extruder_advance_K[active_extruder] * block->e_D_ratio ) * steps_per_mm;
2556+ // Scale E acceleration so that it will be possible to jump to the advance speed.
2557+ const uint32_t max_accel_steps_per_s2 = MAX_E_JERK (extruder) / (extruder_advance_K[extruder] * e_D_ratio) * steps_per_mm;
25652558 if (TERN0 (LA_DEBUG , accel > max_accel_steps_per_s2))
25662559 SERIAL_ECHOLNPGM (" Acceleration limited." );
25672560 NOMORE (accel, max_accel_steps_per_s2);
@@ -2593,13 +2586,21 @@ bool Planner::_populate_block(
25932586 block->acceleration_rate = (uint32_t )(accel * (float (1UL << 24 ) / (STEPPER_TIMER_RATE )));
25942587 #endif
25952588 #if ENABLED(LIN_ADVANCE)
2596- if (block->use_advance_lead ) {
2597- 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)]);
2589+ block->la_advance_rate = 0 ;
2590+ block->la_scaling = 0 ;
2591+
2592+ if (use_advance_lead) {
2593+ // the Bresenham algorithm will convert this step rate into extruder steps
2594+ block->la_advance_rate = extruder_advance_K[extruder] * block->acceleration_steps_per_s2 ;
2595+
2596+ // reduce LA ISR frequency by calling it only often enough to ensure that there will
2597+ // never be more than four extruder steps per call
2598+ for (uint32_t dividend = block->steps .e << 1 ; dividend <= (block->step_event_count >> 2 ); dividend <<= 1 )
2599+ block->la_scaling ++;
2600+
25982601 #if ENABLED(LA_DEBUG)
2599- if (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * 2 < block->nominal_speed * block->e_D_ratio )
2600- SERIAL_ECHOLNPGM (" More than 2 steps per eISR loop executed." );
2601- if (block->advance_speed < 200 )
2602- SERIAL_ECHOLNPGM (" eISR running at > 10kHz." );
2602+ if (block->la_advance_rate >> block->la_scaling > 10000 )
2603+ SERIAL_ECHOLNPGM (" eISR running at > 10kHz: " , block->la_advance_rate );
26032604 #endif
26042605 }
26052606 #endif
0 commit comments