@ -128,8 +128,13 @@ uint8_t Planner::delay_before_delivering; // This counter delays delivery
planner_settings_t Planner : : settings ; // Initialized by settings.load()
planner_settings_t Planner : : settings ; // Initialized by settings.load()
# if ENABLED(LASER_POWER_INLINE)
/**
* Set up inline block variables
* Set laser_power_floor based on SPEED_POWER_MIN to pevent a zero power output state with LASER_POWER_TRAP
*/
# if ENABLED(LASER_FEATURE)
laser_state_t Planner : : laser_inline ; // Current state for blocks
laser_state_t Planner : : laser_inline ; // Current state for blocks
const uint8_t laser_power_floor = cutter . pct_to_ocr ( SPEED_POWER_MIN ) ;
# endif
# endif
uint32_t Planner : : max_acceleration_steps_per_s2 [ DISTINCT_AXES ] ; // (steps/s^2) Derived from mm_per_s2
uint32_t Planner : : max_acceleration_steps_per_s2 [ DISTINCT_AXES ] ; // (steps/s^2) Derived from mm_per_s2
@ -799,6 +804,7 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
if ( plateau_steps < 0 ) {
if ( plateau_steps < 0 ) {
const float accelerate_steps_float = CEIL ( intersection_distance ( initial_rate , final_rate , accel , block - > step_event_count ) ) ;
const float accelerate_steps_float = CEIL ( intersection_distance ( initial_rate , final_rate , accel , block - > step_event_count ) ) ;
accelerate_steps = _MIN ( uint32_t ( _MAX ( accelerate_steps_float , 0 ) ) , block - > step_event_count ) ;
accelerate_steps = _MIN ( uint32_t ( _MAX ( accelerate_steps_float , 0 ) ) , block - > step_event_count ) ;
decelerate_steps = block - > step_event_count - accelerate_steps ;
plateau_steps = 0 ;
plateau_steps = 0 ;
# if ENABLED(S_CURVE_ACCELERATION)
# if ENABLED(S_CURVE_ACCELERATION)
@ -822,7 +828,7 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
// Store new block parameters
// Store new block parameters
block - > accelerate_until = accelerate_steps ;
block - > accelerate_until = accelerate_steps ;
block - > decelerate_after = accelerate_steps + plateau _steps;
block - > decelerate_after = block - > step_event_count - decelerate _steps;
block - > initial_rate = initial_rate ;
block - > initial_rate = initial_rate ;
# if ENABLED(S_CURVE_ACCELERATION)
# if ENABLED(S_CURVE_ACCELERATION)
block - > acceleration_time = acceleration_time ;
block - > acceleration_time = acceleration_time ;
@ -833,46 +839,52 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
# endif
# endif
block - > final_rate = final_rate ;
block - > final_rate = final_rate ;
# if ENABLED(LASER_POWER_TRAP)
/**
/**
* Laser trapezoid c alculations
* Laser Trapezoid C alculations
*
*
* Approximate the trapezoid with the laser , incrementing the power every ` entry_per ` while accelerating
* Approximate the trapezoid with the laser , incrementing the power every ` trap_ramp_entry_incr ` steps while accelerating ,
* and decrementing it every ` exit_power_per ` while decelerating , thus ensuring power is related to feedrate .
* and decrementing the power every ` trap_ramp_exit_decr ` while decelerating , to keep power proportional to feedrate .
* Laser power trap will reduce the initial power to no less than the laser_power_floor value . Based on the number
* of calculated accel / decel steps the power is distributed over the trapezoid entry - and exit - ramp steps .
*
*
* LASER_POWER_INLINE_TRAPEZOID_CONT doesn ' t need this as it continuously approximates
* trap_ramp_active_pwr - The active power is initially set at a reduced level factor of initial power / accel steps and
* will be additively incremented using a trap_ramp_entry_incr value for each accel step processed later in the stepper code .
* The trap_ramp_exit_decr value is calculated as power / decel steps and is also adjusted to no less than the power floor .
*
*
* Note this may behave unreliably when running with S_CURVE_ACCELERATION
* If the power = = 0 the inline mode variables need to be set to zero to prevent stepper processing . The method allows
* for simpler non - powered moves like G0 or G28 .
*
* Laser Trap Power works for all Jerk and Curve modes ; however Arc - based moves will have issues since the segments are
* usually too small .
*/
*/
# if ENABLED(LASER_POWER_INLINE_TRAPEZOID)
if ( cutter . cutter_mode = = CUTTER_MODE_CONTINUOUS ) {
if ( block - > laser . power > 0 ) { // No need to care if power == 0
if ( planner . laser_inline . status . isPowered & & planner . laser_inline . status . isEnabled ) {
const uint8_t entry_power = block - > laser . power * entry_factor ; // Power on block entry
if ( block - > laser . power > 0 ) {
# if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT)
NOLESS ( block - > laser . power , laser_power_floor ) ;
// Speedup power
block - > laser . trap_ramp_active_pwr = ( block - > laser . power - laser_power_floor ) * ( initial_rate / float ( block - > nominal_rate ) ) + laser_power_floor ;
const uint8_t entry_power_diff = block - > laser . power - entry_power ;
block - > laser . trap_ramp_entry_incr = ( block - > laser . power - block - > laser . trap_ramp_active_pwr ) / accelerate_steps ;
if ( entry_power_diff ) {
float laser_pwr = block - > laser . power * ( final_rate / float ( block - > nominal_rate ) ) ;
block - > laser . entry_per = accelerate_steps / entry_power_diff ;
NOLESS ( laser_pwr , laser_power_floor ) ;
block - > laser . power_entry = entry_power ;
block - > laser . trap_ramp_exit_decr = ( block - > laser . power - laser_pwr ) / decelerate_steps ;
# if ENABLED(DEBUG_LASER_TRAP)
SERIAL_ECHO_MSG ( " lp: " , block - > laser . power ) ;
SERIAL_ECHO_MSG ( " as: " , accelerate_steps ) ;
SERIAL_ECHO_MSG ( " ds: " , decelerate_steps ) ;
SERIAL_ECHO_MSG ( " p.trap: " , block - > laser . trap_ramp_active_pwr ) ;
SERIAL_ECHO_MSG ( " p.incr: " , block - > laser . trap_ramp_entry_incr ) ;
SERIAL_ECHO_MSG ( " p.decr: " , block - > laser . trap_ramp_exit_decr ) ;
# endif
}
}
else {
else {
block - > laser . entry_per = 0 ;
block - > laser . trap_ramp_active_pwr = 0 ;
block - > laser . power_entry = block - > laser . power ;
block - > laser . trap_ramp_entry_incr = 0 ;
block - > laser . trap_ramp_exit_decr = 0 ;
}
}
// Slowdown power
const uint8_t exit_power = block - > laser . power * exit_factor , // Power on block entry
exit_power_diff = block - > laser . power - exit_power ;
if ( exit_power_diff ) {
block - > laser . exit_per = ( block - > step_event_count - block - > decelerate_after ) / exit_power_diff ;
block - > laser . power_exit = exit_power ;
}
else {
block - > laser . exit_per = 0 ;
block - > laser . power_exit = block - > laser . power ;
}
}
# else
block - > laser . power_entry = entry_power ;
# endif
}
}
# endif
# endif // LASER_POWER_TRAP
}
}
/* PLANNER SPEED DEFINITION
/* PLANNER SPEED DEFINITION
@ -1130,10 +1142,9 @@ void Planner::recalculate_trapezoids() {
// The tail may be changed by the ISR so get a local copy.
// The tail may be changed by the ISR so get a local copy.
uint8_t block_index = block_buffer_tail ,
uint8_t block_index = block_buffer_tail ,
head_block_index = block_buffer_head ;
head_block_index = block_buffer_head ;
// Since there could be a sync block in the head of the queue, and the
// Since there could be non-move blocks in the head of the queue, and the
// next loop must not recalculate the head block (as it needs to be
// next loop must not recalculate the head block (as it needs to be
// specially handled), scan backwards to the first move block.
// specially handled), scan backwards to the first non-SYNC block.
while ( head_block_index ! = block_index ) {
while ( head_block_index ! = block_index ) {
// Go back (head always point to the first free block)
// Go back (head always point to the first free block)
@ -1203,7 +1214,7 @@ void Planner::recalculate_trapezoids() {
// Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated.
// Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated.
if ( next ) {
if ( next ) {
// Mark the last block as RECALCULATE, to prevent the Stepper ISR running it.
// Mark the next( last) block as RECALCULATE, to prevent the Stepper ISR running it.
// As the last block is always recalculated here, there is a chance the block isn't
// As the last block is always recalculated here, there is a chance the block isn't
// marked as RECALCULATE yet. That's the reason for the following line.
// marked as RECALCULATE yet. That's the reason for the following line.
block - > flag . recalculate = true ;
block - > flag . recalculate = true ;
@ -1295,7 +1306,7 @@ void Planner::recalculate() {
# endif // HAS_FAN
# endif // HAS_FAN
/**
/**
* Maintain fans , paste extruder pressure ,
* Maintain fans , paste extruder pressure , spindle / laser power
*/
*/
void Planner : : check_axes_activity ( ) {
void Planner : : check_axes_activity ( ) {
@ -1359,7 +1370,7 @@ void Planner::check_axes_activity() {
}
}
else {
else {
TERN_ ( HAS_CUTTER , cutter . refresh ( ) ) ;
TERN_ ( HAS_CUTTER , if ( cutter . cutter_mode = = CUTTER_MODE_STANDARD ) cutter . refresh ( ) ) ;
# if HAS_TAIL_FAN_SPEED
# if HAS_TAIL_FAN_SPEED
FANS_LOOP ( i ) {
FANS_LOOP ( i ) {
@ -1459,7 +1470,7 @@ void Planner::check_axes_activity() {
for ( uint8_t b = block_buffer_tail ; b ! = block_buffer_head ; b = next_block_index ( b ) ) {
for ( uint8_t b = block_buffer_tail ; b ! = block_buffer_head ; b = next_block_index ( b ) ) {
const block_t * const block = & block_buffer [ b ] ;
const block_t * const block = & block_buffer [ b ] ;
if ( NUM_AXIS_GANG ( block - > steps . x , | | block - > steps . y , | | block - > steps . z , | | block - > steps . i , | | block - > steps . j , | | block - > steps . k , | | block - > steps . u , | | block - > steps . v , | | block - > steps . w ) ) {
if ( NUM_AXIS_GANG ( block - > steps . x , | | block - > steps . y , | | block - > steps . z , | | block - > steps . i , | | block - > steps . j , | | block - > steps . k , | | block - > steps . u , | | block - > steps . v , | | block - > steps . w ) ) {
const float se = ( float ) block - > steps . e / block - > step_event_count * SQRT ( block - > nominal_speed_sqr ) ; // mm/sec
const float se = ( float ) block - > steps . e / block - > step_event_count * SQRT ( block - > nominal_speed_sqr ) ; // mm/sec;
NOLESS ( high , se ) ;
NOLESS ( high , se ) ;
}
}
}
}
@ -1781,7 +1792,7 @@ void Planner::synchronize() { while (busy()) idle(); }
bool Planner : : _buffer_steps ( const xyze_long_t & target
bool Planner : : _buffer_steps ( const xyze_long_t & target
OPTARG ( HAS_POSITION_FLOAT , const xyze_pos_t & target_float )
OPTARG ( HAS_POSITION_FLOAT , const xyze_pos_t & target_float )
OPTARG ( HAS_DIST_MM_ARG , const xyze_float_t & cart_dist_mm )
OPTARG ( HAS_DIST_MM_ARG , const xyze_float_t & cart_dist_mm )
, feedRate_t fr_mm_s , const uint8_t extruder , const_float_t millimeters /*=0.0*/
, feedRate_t fr_mm_s , const uint8_t extruder , const_float_t millimeters
) {
) {
// Wait for the next available block
// Wait for the next available block
@ -1863,8 +1874,36 @@ bool Planner::_populate_block(
) ;
) ;
/* <-- add a slash to enable
/* <-- add a slash to enable
# define _ALINE(A) " " STR_##A ":", target[_AXIS(A)], " (", int32_t(target[_AXIS(A)] - position[_AXIS(A)]), " steps)"
SERIAL_ECHOLNPGM (
SERIAL_ECHOLNPGM ( " _populate_block FR: " , fr_mm_s , LOGICAL_AXIS_MAP ( _ALINE ) ) ;
" _populate_block FR: " , fr_mm_s ,
" A: " , target . a , " ( " , da , " steps) "
# if HAS_Y_AXIS
" B: " , target . b , " ( " , db , " steps) "
# endif
# if HAS_Z_AXIS
" C: " , target . c , " ( " , dc , " steps) "
# endif
# if HAS_I_AXIS
" " STR_I " : " , target . i , " ( " , di , " steps) "
# endif
# if HAS_J_AXIS
" " STR_J " : " , target . j , " ( " , dj , " steps) "
# endif
# if HAS_K_AXIS
" " STR_K " : " , target . k , " ( " , dk , " steps) "
# endif
# if HAS_U_AXIS
" " STR_U " : " , target . u , " ( " , du , " steps) "
# endif
# if HAS_V_AXIS
" " STR_V " : " , target . v , " ( " , dv , " steps) "
# endif
# if HAS_W_AXIS
" " STR_W " : " , target . w , " ( " , dw , " steps) "
# if HAS_EXTRUDERS
" E: " , target . e , " ( " , de , " steps) "
# endif
) ;
//*/
//*/
# if EITHER(PREVENT_COLD_EXTRUSION, PREVENT_LENGTHY_EXTRUDE)
# if EITHER(PREVENT_COLD_EXTRUSION, PREVENT_LENGTHY_EXTRUDE)
@ -1962,11 +2001,34 @@ bool Planner::_populate_block(
// Set direction bits
// Set direction bits
block - > direction_bits = dm ;
block - > direction_bits = dm ;
// Update block laser power
/**
# if ENABLED(LASER_POWER_INLINE)
* Update block laser power
laser_inline . status . isPlanned = true ;
* For standard mode get the cutter . power value for processing , since it ' s
block - > laser . status = laser_inline . status ;
* only set by apply_power ( ) .
*/
# if HAS_CUTTER
switch ( cutter . cutter_mode ) {
default : break ;
case CUTTER_MODE_STANDARD : block - > cutter_power = cutter . power ; break ;
# if ENABLED(LASER_FEATURE)
/**
* For inline mode get the laser_inline variables , including power and status .
* Dynamic mode only needs to update if the feedrate has changed , since it ' s
* calculated from the current feedrate and power level .
*/
case CUTTER_MODE_CONTINUOUS :
block - > laser . power = laser_inline . power ;
block - > laser . power = laser_inline . power ;
block - > laser . status = laser_inline . status ;
break ;
case CUTTER_MODE_DYNAMIC :
if ( cutter . laser_feedrate_changed ( ) ) // Only process changes in rate
block - > laser . power = laser_inline . power = cutter . calc_dynamic_power ( ) ;
break ;
# endif
}
# endif
# endif
// Number of steps for each axis
// Number of steps for each axis
@ -2076,21 +2138,12 @@ bool Planner::_populate_block(
block - > millimeters = millimeters ;
block - > millimeters = millimeters ;
else {
else {
/**
/**
* Distance for interpretation of feedrate in accordance with LinuxCNC ( the successor of
* Distance for interpretation of feedrate in accordance with LinuxCNC ( the successor of NIST
* NIST RS274NGC interpreter - version 3 ) and its default CANON_XYZ feed reference mode .
* RS274NGC interpreter - version 3 ) and its default CANON_XYZ feed reference mode .
*
* Assume that X , Y , Z are the primary linear axes and U , V , W are secondary linear axes and A , B , C are
* Assume :
* rotational axes . Then dX , dY , dZ are the displacements of the primary linear axes and dU , dV , dW are the displacements of linear axes and
* - X , Y , Z are the primary linear axes ;
* dA , dB , dC are the displacements of rotational axes .
* - U , V , W are secondary linear axes ;
* The time it takes to execute move command with feedrate F is t = D / F , where D is the total distance , calculated as follows :
* - A , B , C are rotational axes .
*
* Then :
* - dX , dY , dZ are the displacements of the primary linear axes ;
* - dU , dV , dW are the displacements of linear axes ;
* - dA , dB , dC are the displacements of rotational axes .
*
* The time it takes to execute move command with feedrate F is t = D / F ,
* where D is the total distance , calculated as follows :
* D ^ 2 = dX ^ 2 + dY ^ 2 + dZ ^ 2
* D ^ 2 = dX ^ 2 + dY ^ 2 + dZ ^ 2
* if D ^ 2 = = 0 ( none of XYZ move but any secondary linear axes move , whether other axes are moved or not ) :
* if D ^ 2 = = 0 ( none of XYZ move but any secondary linear axes move , whether other axes are moved or not ) :
* D ^ 2 = dU ^ 2 + dV ^ 2 + dW ^ 2
* D ^ 2 = dU ^ 2 + dV ^ 2 + dW ^ 2
@ -2099,9 +2152,8 @@ bool Planner::_populate_block(
*/
*/
float distance_sqr = (
float distance_sqr = (
# if ENABLED(ARTICULATED_ROBOT_ARM)
# if ENABLED(ARTICULATED_ROBOT_ARM)
// For articulated robots, interpreting feedrate like LinuxCNC would require inverse kinematics. As a workaround,
// For articulated robots, interpreting feedrate like LinuxCNC would require inverse kinematics. As a workaround, pretend that motors sit on n mutually orthogonal
// assume that motors sit on a mutually-orthogonal axes and we can think of distance as magnitude of an n-vector
// axes and assume that we could think of distance as magnitude of an n-vector in an n-dimensional Euclidian space.
// in an n-dimensional Euclidian space.
NUM_AXIS_GANG (
NUM_AXIS_GANG (
sq ( steps_dist_mm . x ) , + sq ( steps_dist_mm . y ) , + sq ( steps_dist_mm . z ) ,
sq ( steps_dist_mm . x ) , + sq ( steps_dist_mm . y ) , + sq ( steps_dist_mm . z ) ,
+ sq ( steps_dist_mm . i ) , + sq ( steps_dist_mm . j ) , + sq ( steps_dist_mm . k ) ,
+ sq ( steps_dist_mm . i ) , + sq ( steps_dist_mm . j ) , + sq ( steps_dist_mm . k ) ,
@ -2154,9 +2206,9 @@ bool Planner::_populate_block(
/**
/**
* At this point at least one of the axes has more steps than
* At this point at least one of the axes has more steps than
* MIN_STEPS_PER_SEGMENT , ensuring the segment won ' t get dropped
* MIN_STEPS_PER_SEGMENT , ensuring the segment won ' t get dropped as
* as zero - length . It ' s important to not apply corrections to blocks
* zero - length . It ' s important to not apply corrections
* that would get dropped !
* to blocks t hat would get dropped !
*
*
* A correction function is permitted to add steps to an axis , it
* A correction function is permitted to add steps to an axis , it
* should * never * remove steps !
* should * never * remove steps !
@ -2177,7 +2229,6 @@ bool Planner::_populate_block(
TERN_ ( MIXING_EXTRUDER , mixer . populate_block ( block - > b_color ) ) ;
TERN_ ( MIXING_EXTRUDER , mixer . populate_block ( block - > b_color ) ) ;
TERN_ ( HAS_CUTTER , block - > cutter_power = cutter . power ) ;
# if HAS_FAN
# if HAS_FAN
FANS_LOOP ( i ) block - > fan_speed [ i ] = thermalManager . fan_speed [ i ] ;
FANS_LOOP ( i ) block - > fan_speed [ i ] = thermalManager . fan_speed [ i ] ;
@ -2192,9 +2243,15 @@ bool Planner::_populate_block(
# if ENABLED(AUTO_POWER_CONTROL)
# if ENABLED(AUTO_POWER_CONTROL)
if ( NUM_AXIS_GANG (
if ( NUM_AXIS_GANG (
block - > steps . x , | | block - > steps . y , | | block - > steps . z ,
block - > steps . x ,
| | block - > steps . i , | | block - > steps . j , | | block - > steps . k ,
| | block - > steps . y ,
| | block - > steps . u , | | block - > steps . v , | | block - > steps . w
| | block - > steps . z ,
| | block - > steps . i ,
| | block - > steps . j ,
| | block - > steps . k ,
| | block - > steps . u ,
| | block - > steps . v ,
| | block - > steps . w
) ) powerManager . power_on ( ) ;
) ) powerManager . power_on ( ) ;
# endif
# endif
@ -2428,7 +2485,7 @@ bool Planner::_populate_block(
if ( speed_factor < 1.0f ) {
if ( speed_factor < 1.0f ) {
current_speed * = speed_factor ;
current_speed * = speed_factor ;
block - > nominal_rate * = speed_factor ;
block - > nominal_rate * = speed_factor ;
block - > nominal_speed_sqr * = sq ( speed_factor ) ;
block - > nominal_speed_sqr = block - > nominal_speed_sqr * sq ( speed_factor ) ;
}
}
// Compute and limit the acceleration rate for the trapezoid generator.
// Compute and limit the acceleration rate for the trapezoid generator.
@ -2630,15 +2687,14 @@ bool Planner::_populate_block(
vmax_junction_sqr = sq ( float ( MINIMUM_PLANNER_SPEED ) ) ;
vmax_junction_sqr = sq ( float ( MINIMUM_PLANNER_SPEED ) ) ;
}
}
else {
else {
NOLESS ( junction_cos_theta , - 0.999999f ) ; // Check for numerical round-off to avoid divide by zero.
// Convert delta vector to unit vector
// Convert delta vector to unit vector
xyze_float_t junction_unit_vec = unit_vec - prev_unit_vec ;
xyze_float_t junction_unit_vec = unit_vec - prev_unit_vec ;
normalize_junction_vector ( junction_unit_vec ) ;
normalize_junction_vector ( junction_unit_vec ) ;
const float junction_acceleration = limit_value_by_axis_maximum ( block - > acceleration , junction_unit_vec ) ;
const float junction_acceleration = limit_value_by_axis_maximum ( block - > acceleration , junction_unit_vec ) ,
sin_theta_d2 = SQRT ( 0.5f * ( 1.0f - junction_cos_theta ) ) ; // Trig half angle identity. Always positive.
NOLESS ( junction_cos_theta , - 0.999999f ) ; // Check for numerical round-off to avoid divide by zero.
const float sin_theta_d2 = SQRT ( 0.5f * ( 1.0f - junction_cos_theta ) ) ; // Trig half angle identity. Always positive.
vmax_junction_sqr = junction_acceleration * junction_deviation_mm * sin_theta_d2 / ( 1.0f - sin_theta_d2 ) ;
vmax_junction_sqr = junction_acceleration * junction_deviation_mm * sin_theta_d2 / ( 1.0f - sin_theta_d2 ) ;
@ -2889,21 +2945,19 @@ bool Planner::_populate_block(
/**
/**
* Planner : : buffer_sync_block
* Planner : : buffer_sync_block
* Add a block to the buffer that just updates the position ,
* Add a block to the buffer that just updates the position
* or in case of LASER_SYNCHRONOUS_M106_M107 the fan PWM
* @ param sync_flag BLOCK_FLAG_SYNC_FANS & BLOCK_FLAG_LASER_PWR
* Supports LASER_SYNCHRONOUS_M106_M107 and LASER_POWER_SYNC power sync block buffer queueing .
*/
*/
void Planner : : buffer_sync_block ( TERN_ ( LASER_SYNCHRONOUS_M106_M107 , const BlockFlagBit sync_flag /*=BLOCK_BIT_SYNC_POSITION*/ ) ) {
# if DISABLED(LASER_SYNCHRONOUS_M106_M107)
void Planner : : buffer_sync_block ( const BlockFlagBit sync_flag /*=BLOCK_BIT_SYNC_POSITION*/ ) {
constexpr BlockFlagBit sync_flag = BLOCK_BIT_SYNC_POSITION ;
# endif
// Wait for the next available block
// Wait for the next available block
uint8_t next_buffer_head ;
uint8_t next_buffer_head ;
block_t * const block = get_next_free_block ( next_buffer_head ) ;
block_t * const block = get_next_free_block ( next_buffer_head ) ;
// Clear block
// Clear block
block - > reset ( ) ;
memset ( block , 0 , sizeof ( block_t ) ) ;
block - > flag . apply ( sync_flag ) ;
block - > flag . apply ( sync_flag ) ;
block - > position = position ;
block - > position = position ;
@ -2915,6 +2969,12 @@ void Planner::buffer_sync_block(TERN_(LASER_SYNCHRONOUS_M106_M107, const BlockFl
FANS_LOOP ( i ) block - > fan_speed [ i ] = thermalManager . fan_speed [ i ] ;
FANS_LOOP ( i ) block - > fan_speed [ i ] = thermalManager . fan_speed [ i ] ;
# endif
# endif
/**
* M3 - based power setting can be processed inline with a laser power sync block .
* During active moves cutter . power is processed immediately , otherwise on the next move .
*/
TERN_ ( LASER_POWER_SYNC , block - > laser . power = cutter . power ) ;
// If this is the first added movement, reload the delay, otherwise, cancel it.
// If this is the first added movement, reload the delay, otherwise, cancel it.
if ( block_buffer_head = = block_buffer_tail ) {
if ( block_buffer_head = = block_buffer_tail ) {
// If it was the first queued block, restart the 1st block delivery delay, to
// If it was the first queued block, restart the 1st block delivery delay, to
@ -3052,8 +3112,8 @@ bool Planner::buffer_segment(const abce_pos_t &abce
if ( ! _buffer_steps ( target
if ( ! _buffer_steps ( target
OPTARG ( HAS_POSITION_FLOAT , target_float )
OPTARG ( HAS_POSITION_FLOAT , target_float )
OPTARG ( HAS_DIST_MM_ARG , cart_dist_mm )
OPTARG ( HAS_DIST_MM_ARG , cart_dist_mm )
, fr_mm_s , extruder , millimeters
, fr_mm_s , extruder , millimeters )
) ) return false ;
) return false ;
stepper . wake_up ( ) ;
stepper . wake_up ( ) ;
return true ;
return true ;
@ -3120,14 +3180,6 @@ bool Planner::buffer_line(const xyze_pos_t &cart, const_feedRate_t fr_mm_s, cons
# if ENABLED(DIRECT_STEPPING)
# if ENABLED(DIRECT_STEPPING)
/**
* @ brief Add a direct stepping page block to the buffer
* and wake up the Stepper ISR to process it .
*
* @ param page_idx Page index provided by G6 I < index >
* @ param extruder The extruder to use in the move
* @ param num_steps Number of steps to process in the ISR
*/
void Planner : : buffer_page ( const page_idx_t page_idx , const uint8_t extruder , const uint16_t num_steps ) {
void Planner : : buffer_page ( const page_idx_t page_idx , const uint8_t extruder , const uint16_t num_steps ) {
if ( ! last_page_step_rate ) {
if ( ! last_page_step_rate ) {
kill ( GET_TEXT_F ( MSG_BAD_PAGE_SPEED ) ) ;
kill ( GET_TEXT_F ( MSG_BAD_PAGE_SPEED ) ) ;
@ -3212,7 +3264,7 @@ void Planner::set_machine_position_mm(const abce_pos_t &abce) {
if ( has_blocks_queued ( ) ) {
if ( has_blocks_queued ( ) ) {
//previous_nominal_speed_sqr = 0.0; // Reset planner junction speeds. Assume start from rest.
//previous_nominal_speed_sqr = 0.0; // Reset planner junction speeds. Assume start from rest.
//previous_speed.reset();
//previous_speed.reset();
buffer_sync_block ( ) ;
buffer_sync_block ( BLOCK_BIT_SYNC_POSITION ) ;
}
}
else {
else {
# if ENABLED(BACKLASH_COMPENSATION)
# if ENABLED(BACKLASH_COMPENSATION)
@ -3225,12 +3277,6 @@ void Planner::set_machine_position_mm(const abce_pos_t &abce) {
}
}
}
}
/**
* @ brief Set the Planner position in mm
* @ details Set the Planner position from a native machine position in mm
*
* @ param xyze A native ( Cartesian ) machine position
*/
void Planner : : set_position_mm ( const xyze_pos_t & xyze ) {
void Planner : : set_position_mm ( const xyze_pos_t & xyze ) {
xyze_pos_t machine = xyze ;
xyze_pos_t machine = xyze ;
TERN_ ( HAS_POSITION_MODIFIERS , apply_modifiers ( machine , true ) ) ;
TERN_ ( HAS_POSITION_MODIFIERS , apply_modifiers ( machine , true ) ) ;
@ -3259,20 +3305,14 @@ void Planner::set_position_mm(const xyze_pos_t &xyze) {
TERN_ ( IS_KINEMATIC , TERN_ ( HAS_EXTRUDERS , position_cart . e = e ) ) ;
TERN_ ( IS_KINEMATIC , TERN_ ( HAS_EXTRUDERS , position_cart . e = e ) ) ;
if ( has_blocks_queued ( ) )
if ( has_blocks_queued ( ) )
buffer_sync_block ( ) ;
buffer_sync_block ( BLOCK_BIT_SYNC_POSITION ) ;
else
else
stepper . set_axis_position ( E_AXIS , position . e ) ;
stepper . set_axis_position ( E_AXIS , position . e ) ;
}
}
# endif
# endif
/**
// Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
* @ brief Recalculate the steps / s ^ 2 acceleration rates , based on the mm / s ^ 2
* @ details Update planner movement factors after a change to certain settings :
* - max_acceleration_steps_per_s2 from settings max_acceleration_mm_per_s2 * axis_steps_per_mm ( M201 , M92 )
* - acceleration_long_cutoff based on the largest max_acceleration_steps_per_s2 ( M201 )
* - max_e_jerk for all extruders based on junction_deviation_mm ( M205 J )
*/
void Planner : : refresh_acceleration_rates ( ) {
void Planner : : refresh_acceleration_rates ( ) {
uint32_t highest_rate = 1 ;
uint32_t highest_rate = 1 ;
LOOP_DISTINCT_AXES ( i ) {
LOOP_DISTINCT_AXES ( i ) {
@ -3285,8 +3325,8 @@ void Planner::refresh_acceleration_rates() {
}
}
/**
/**
* @ brief Recalculate ' position ' and ' mm_per_step ' .
* Recalculate ' position ' and ' mm_per_step ' .
* @ details Requir ed whenever settings . axis_steps_per_mm changes !
* Must be call ed whenever settings . axis_steps_per_mm changes !
*/
*/
void Planner : : refresh_positioning ( ) {
void Planner : : refresh_positioning ( ) {
LOOP_DISTINCT_AXES ( i ) mm_per_step [ i ] = 1.0f / settings . axis_steps_per_mm [ i ] ;
LOOP_DISTINCT_AXES ( i ) mm_per_step [ i ] = 1.0f / settings . axis_steps_per_mm [ i ] ;