Prusa MINI Firmware overview
|
#include <planner.h>
|
static void | reset_acceleration_rates () |
|
static void | refresh_positioning () |
|
static void | set_max_acceleration (const uint8_t axis, float targetValue) |
|
static void | set_max_feedrate (const uint8_t axis, float targetValue) |
|
static void | set_max_jerk (const AxisEnum axis, float targetValue) |
|
static void | check_axes_activity () |
|
static void | calculate_volumetric_multipliers () |
|
static FORCE_INLINE float | fade_scaling_factor_for_z (const float &) |
|
static FORCE_INLINE bool | leveling_active_at_z (const float &) |
|
static void | apply_leveling (xyz_pos_t &raw) |
|
static void | unapply_leveling (xyz_pos_t &raw) |
|
static FORCE_INLINE void | force_unapply_leveling (xyz_pos_t &raw) |
|
static FORCE_INLINE void | apply_modifiers (xyze_pos_t &pos, bool leveling=false) |
|
static FORCE_INLINE void | unapply_modifiers (xyze_pos_t &pos, bool leveling=false) |
|
static FORCE_INLINE uint8_t | movesplanned () |
|
static FORCE_INLINE uint8_t | nonbusy_movesplanned () |
|
static FORCE_INLINE void | clear_block_buffer () |
|
static FORCE_INLINE bool | is_full () |
|
static FORCE_INLINE uint8_t | moves_free () |
|
static FORCE_INLINE block_t * | get_next_free_block (uint8_t &next_buffer_head, const uint8_t count=1) |
|
static bool | _buffer_steps (const xyze_long_t &target, const xyze_pos_t &target_float, feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters=0.0) |
|
static bool | _populate_block (block_t *const block, bool split_move, const xyze_long_t &target, const xyze_pos_t &target_float, feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters=0.0) |
|
static void | buffer_sync_block () |
|
static bool | buffer_segment (const float &a, const float &b, const float &c, const float &e, const feedRate_t &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0) |
|
static FORCE_INLINE bool | buffer_segment (abce_pos_t &abce, const feedRate_t &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0) |
|
static bool | buffer_line (const float &rx, const float &ry, const float &rz, const float &e, const feedRate_t &fr_mm_s, const uint8_t extruder, const float millimeters=0.0) |
|
static FORCE_INLINE bool | buffer_line (const xyze_pos_t &cart, const feedRate_t &fr_mm_s, const uint8_t extruder, const float millimeters=0.0) |
|
static void | set_position_mm (const float &rx, const float &ry, const float &rz, const float &e) |
|
static FORCE_INLINE void | set_position_mm (const xyze_pos_t &cart) |
|
static void | set_e_position_mm (const float &e) |
|
static void | set_machine_position_mm (const float &a, const float &b, const float &c, const float &e) |
|
static FORCE_INLINE void | set_machine_position_mm (const abce_pos_t &abce) |
|
static float | get_axis_position_mm (const AxisEnum axis) |
|
static void | quick_stop () |
|
static void | endstop_triggered (const AxisEnum axis) |
|
static float | triggered_position_mm (const AxisEnum axis) |
|
static void | synchronize () |
|
static void | finish_and_disable () |
|
static void | tick () |
|
static FORCE_INLINE bool | has_blocks_queued () |
|
static block_t * | get_current_block () |
|
static FORCE_INLINE void | discard_current_block () |
|
◆ Planner()
Instance Methods
Class and Instance Methods
◆ init()
236 #if HAS_POSITION_FLOAT
240 position_cart.reset();
242 previous_speed.
reset();
243 previous_nominal_speed_sqr = 0;
◆ reset_acceleration_rates()
void Planner::reset_acceleration_rates |
( |
| ) |
|
|
static |
Static (class) Methods
2789 #if ENABLED(DISTINCT_E_FACTORS)
2790 #define AXIS_CONDITION (i < E_AXIS || i == E_AXIS_N(active_extruder))
2792 #define AXIS_CONDITION true
2794 uint32_t highest_rate = 1;
2799 cutoff_long = 4294967295UL / highest_rate;
2800 #if HAS_LINEAR_E_JERK
2801 recalculate_max_e_jerk();
◆ refresh_positioning()
void Planner::refresh_positioning |
( |
| ) |
|
|
static |
◆ set_max_acceleration()
2825 #if ENABLED(LIMITED_MAX_ACCEL_EDITING)
2826 #ifdef MAX_ACCEL_EDIT_VALUES
2827 constexpr
xyze_float_t max_accel_edit = MAX_ACCEL_EDIT_VALUES;
2828 const xyze_float_t &max_acc_edit_scaled = max_accel_edit;
2831 max_acc_edit_scaled = max_accel_edit * 2;
◆ set_max_feedrate()
2842 #if ENABLED(LIMITED_MAX_FR_EDITING)
2843 #ifdef MAX_FEEDRATE_EDIT_VALUES
2844 constexpr
xyze_float_t max_fr_edit = MAX_FEEDRATE_EDIT_VALUES;
2848 max_fr_edit_scaled = max_fr_edit * 2;
◆ set_max_jerk()
2856 #if HAS_CLASSIC_JERK
2857 #if ENABLED(LIMITED_JERK_EDITING)
2859 #ifdef MAX_JERK_EDIT_VALUES
2860 MAX_JERK_EDIT_VALUES
2862 { (DEFAULT_XJERK) * 2, (DEFAULT_YJERK) * 2,
2868 max_jerk[axis] = targetValue;
◆ check_axes_activity()
void Planner::check_axes_activity |
( |
| ) |
|
|
static |
Maintain fans, paste extruder pressure,
1182 #if ANY(DISABLE_X, DISABLE_Y, DISABLE_Z, DISABLE_E)
1190 #if ENABLED(BARICUDA)
1201 #if FAN_COUNT > 0 || ENABLED(BARICUDA)
1210 #if ENABLED(BARICUDA)
1212 tail_valve_pressure = block->valve_pressure;
1215 tail_e_to_p_pressure = block->e_to_p_pressure;
1219 #if ANY(DISABLE_X, DISABLE_Y, DISABLE_Z, DISABLE_E)
1237 #if ENABLED(BARICUDA)
1250 #if ENABLED(DISABLE_X)
1253 #if ENABLED(DISABLE_Y)
1256 #if ENABLED(DISABLE_Z)
1259 #if ENABLED(DISABLE_E)
1268 #if FAN_KICKSTART_TIME > 0
1270 #define KICKSTART_FAN(f) \
1271 if (tail_fan_speed[f]) { \
1272 millis_t ms = millis(); \
1273 if (fan_kick_end[f] == 0) { \
1274 fan_kick_end[f] = ms + FAN_KICKSTART_TIME; \
1275 tail_fan_speed[f] = 255; \
1276 } else if (PENDING(ms, fan_kick_end[f])) \
1277 tail_fan_speed[f] = 255; \
1278 } else fan_kick_end[f] = 0
1280 #define KICKSTART_FAN(f) NOOP
1283 #if FAN_MIN_PWM != 0 || FAN_MAX_PWM != 255
1284 #define CALC_FAN_SPEED(f) (tail_fan_speed[f] ? map(tail_fan_speed[f], 1, 255, FAN_MIN_PWM, FAN_MAX_PWM) : 0)
1286 #define CALC_FAN_SPEED(f) tail_fan_speed[f]
1289 #if ENABLED(FAN_SOFT_PWM)
1290 #define _FAN_SET(F) thermalManager.soft_pwm_amount_fan[F] = CALC_FAN_SPEED(F);
1291 #elif ENABLED(FAST_PWM_FAN)
1292 #define _FAN_SET(F) set_pwm_duty(FAN##F##_PIN, CALC_FAN_SPEED(F));
1294 #define _FAN_SET(F) analogWrite(pin_t(FAN##F##_PIN), CALC_FAN_SPEED(F));
1296 #define FAN_SET(F) do{ KICKSTART_FAN(F); _FAN_SET(F); }while(0)
1308 #endif // FAN_COUNT > 0
1310 #if ENABLED(AUTOTEMP)
1314 #if ENABLED(BARICUDA)
◆ calculate_volumetric_multipliers()
static void Planner::calculate_volumetric_multipliers |
( |
| ) |
|
|
static |
◆ fade_scaling_factor_for_z()
◆ leveling_active_at_z()
◆ apply_leveling()
Apply leveling to transform a cartesian position as it will be given to the planner and steppers.
rx, ry, rz - Cartesian positions in mm Leveled XYZ on completion
1392 #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
1395 constexpr
float fade_scaling_factor = 1.0;
1399 #if ENABLED(MESH_BED_LEVELING)
1401 #
if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
1402 , fade_scaling_factor
1405 #elif ENABLED(AUTO_BED_LEVELING_UBL)
◆ unapply_leveling()
1429 #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
1432 constexpr
float fade_scaling_factor = 1.0;
1436 #if ENABLED(MESH_BED_LEVELING)
1438 #
if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
1439 , fade_scaling_factor
1442 #elif ENABLED(AUTO_BED_LEVELING_UBL)
1452 #if ENABLED(SKEW_CORRECTION)
◆ force_unapply_leveling()
◆ apply_modifiers()
509 #if ENABLED(SKEW_CORRECTION)
515 #if ENABLED(FWRETRACT)
◆ unapply_modifiers()
530 #if ENABLED(FWRETRACT)
531 unapply_retract(pos);
536 #if ENABLED(SKEW_CORRECTION)
◆ movesplanned()
◆ nonbusy_movesplanned()
◆ clear_block_buffer()
◆ is_full()
◆ moves_free()
◆ get_next_free_block()
Planner::get_next_free_block
- Get the next head indices (passed by reference)
- Wait for the number of spaces to open up in the planner
- Return the first head block
◆ _buffer_steps()
Planner::_buffer_steps
Add a new linear movement to the buffer (in terms of steps).
target - target position in steps units fr_mm_s - (target) speed of the move extruder - target extruder millimeters - the length of the movement, if known
Returns true if movement was buffered, false otherwise
Planner::_buffer_steps
Add a new linear movement to the planner queue (in terms of steps).
target - target position in steps units target_float - target position in direct (mm, degrees) units. optional fr_mm_s - (target) speed of the move extruder - target extruder millimeters - the length of the movement, if known
Returns true if movement was properly queued, false otherwise
1603 , fr_mm_s, extruder, millimeters
◆ _populate_block()
Planner::_populate_block
Fills a new linear movement in the block (in terms of steps).
target - target position in steps units fr_mm_s - (target) speed of the move extruder - target extruder millimeters - the length of the movement, if known
Returns true is movement is acceptable, false otherwise
Planner::_populate_block
Fills a new linear movement in the block (in terms of steps).
target - target position in steps units fr_mm_s - (target) speed of the move extruder - target extruder
Returns true is movement is acceptable, false otherwise
This part of the code calculates the total length of the movement. For cartesian bots, the X_AXIS is the real X movement and same for Y_AXIS. But for corexy bots, that is not true. The "X_AXIS" and "Y_AXIS" motors (that should be named to A_AXIS and B_AXIS) cannot be used for X and Y length, because A=X+Y and B=X-Y. So we need to create other 2 "AXIS", named X_HEAD and Y_HEAD, meaning the real displacement of the Head. Having the real displacement of the head, we can calculate the total movement length and apply the desired speed.
At this point at least one of the axes has more steps than MIN_STEPS_PER_SEGMENT, ensuring the segment won't get dropped as zero-length. It's important to not apply corrections to blocks that would get dropped!
A correction function is permitted to add steps to an axis, it should never remove steps!
1652 const int32_t da = target.
a - position.
a,
1653 db = target.
b - position.
b,
1654 dc = target.
c - position.
c;
1657 int32_t de = target.
e - position.
e;
1659 constexpr int32_t de = 0;
1673 #if EITHER(PREVENT_COLD_EXTRUSION, PREVENT_LENGTHY_EXTRUDE)
1675 #if ENABLED(PREVENT_COLD_EXTRUSION)
1677 position.
e = target.
e;
1678 #if HAS_POSITION_FLOAT
1684 #endif // PREVENT_COLD_EXTRUSION
1685 #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
1686 const float e_steps =
ABS(de * e_factor[extruder]);
1688 if (e_steps > max_e_steps) {
1689 #if ENABLED(MIXING_EXTRUDER)
1690 bool ignore_e =
false;
1691 float collector[MIXING_STEPPERS];
1694 if (e_steps * collector[e] > max_e_steps) { ignore_e =
true;
break; }
1696 constexpr
bool ignore_e =
true;
1699 position.
e = target.
e;
1700 #if HAS_POSITION_FLOAT
1707 #endif // PREVENT_LENGTHY_EXTRUDE
1709 #endif // PREVENT_COLD_EXTRUSION || PREVENT_LENGTHY_EXTRUDE
1718 if (CORESIGN(da - db) < 0)
SBI(dm,
B_AXIS);
1724 if (CORESIGN(da - dc) < 0)
SBI(dm,
C_AXIS);
1730 if (CORESIGN(db - dc) < 0)
SBI(dm,
C_AXIS);
1739 const float esteps_float = de * e_factor[extruder];
1740 const uint32_t esteps =
ABS(esteps_float) + 0.5f;
1742 constexpr uint32_t esteps = 0;
1822 sq(delta_mm.head.x) +
sq(delta_mm.head.y) +
sq(delta_mm.z)
1824 sq(delta_mm.head.x) +
sq(delta_mm.y) +
sq(delta_mm.head.z)
1826 sq(delta_mm.x) +
sq(delta_mm.head.y) +
sq(delta_mm.head.z)
1828 sq(delta_mm.x) +
sq(delta_mm.y) +
sq(delta_mm.z)
1841 #if ENABLED(BACKLASH_COMPENSATION)
1855 #if ENABLED(MIXING_EXTRUDER)
1867 #if ENABLED(BARICUDA)
1876 #if ENABLED(AUTO_POWER_CONTROL)
1887 #if DISABLED(Z_LATE_ENABLE)
1905 #if DISABLED(Z_LATE_ENABLE)
1913 #if ENABLED(AUTO_POWER_CONTROL)
1917 #if ENABLED(DISABLE_INACTIVE_EXTRUDER) // Enable only the selected extruder
1919 #define DISABLE_IDLE_E(N) if (!g_uc_extruder_last_move[N]) disable_E##N();
1922 if (g_uc_extruder_last_move[
i] > 0) g_uc_extruder_last_move[
i]--;
1936 #endif // EXTRUDERS > 5
1937 #endif // EXTRUDERS > 4
1938 #endif // EXTRUDERS > 3
1939 #endif // EXTRUDERS > 2
1940 #endif // EXTRUDERS > 1
1943 #if HAS_DUPLICATION_MODE
1961 #endif // EXTRUDERS > 5
1962 #endif // EXTRUDERS > 4
1963 #endif // EXTRUDERS > 3
1964 #endif // EXTRUDERS > 2
2020 #endif // EXTRUDERS > 5
2021 #endif // EXTRUDERS > 4
2022 #endif // EXTRUDERS > 3
2023 #endif // EXTRUDERS > 2
2024 #endif // EXTRUDERS > 1
2042 const float inverse_millimeters = 1.0f / block->
millimeters;
2046 float inverse_secs = fr_mm_s * inverse_millimeters;
2052 #if EITHER(SLOWDOWN, ULTRA_LCD) || defined(XY_FREQUENCY_LIMIT)
2054 uint32_t segment_time_us =
LROUND(1000000.0f / inverse_secs);
2057 #if ENABLED(SLOWDOWN)
2062 inverse_secs = 1000000.0f / nst;
2063 #if defined(XY_FREQUENCY_LIMIT) || HAS_SPI_LCD
2064 segment_time_us = nst;
2075 block_buffer_runtime_us += segment_time_us;
2076 block->segment_time_us = segment_time_us;
2084 #if ENABLED(FILAMENT_WIDTH_SENSOR)
2085 if (extruder == FILAMENT_SENSOR_EXTRUDER_NUM)
2091 float speed_factor = 1.0f;
2093 #if BOTH(MIXING_EXTRUDER, RETRACT_SYNC_MIXING)
2096 float delta_mm_i = 0;
2098 delta_mm_i = delta_mm.e / MIXING_STEPPERS;
2100 delta_mm_i = delta_mm.e;
2102 const float delta_mm_i = delta_mm[
i];
2104 const feedRate_t cs =
ABS(current_speed[
i] = delta_mm_i * inverse_secs);
2105 #if ENABLED(DISTINCT_E_FACTORS)
2112 #ifdef XY_FREQUENCY_LIMIT
2115 const unsigned char direction_change = block->
direction_bits ^ old_direction_bits;
2117 segment_time_us =
LROUND((
float)segment_time_us / speed_factor);
2119 uint32_t xs0 = axis_segment_time_us[0].x,
2120 xs1 = axis_segment_time_us[1].x,
2121 xs2 = axis_segment_time_us[2].x,
2122 ys0 = axis_segment_time_us[0].y,
2123 ys1 = axis_segment_time_us[1].y,
2124 ys2 = axis_segment_time_us[2].y;
2127 xs2 = axis_segment_time_us[2].x = xs1;
2128 xs1 = axis_segment_time_us[1].x = xs0;
2131 xs0 = axis_segment_time_us[0].x = xs0 + segment_time_us;
2134 ys2 = axis_segment_time_us[2].y = axis_segment_time_us[1].y;
2135 ys1 = axis_segment_time_us[1].y = axis_segment_time_us[0].y;
2138 ys0 = axis_segment_time_us[0].y = ys0 + segment_time_us;
2140 const uint32_t max_x_segment_time =
_MAX(xs0, xs1, xs2),
2141 max_y_segment_time =
_MAX(ys0, ys1, ys2),
2142 min_xy_segment_time =
_MIN(max_x_segment_time, max_y_segment_time);
2143 if (min_xy_segment_time < MAX_FREQ_TIME_US) {
2144 const float low_sf = speed_factor * min_xy_segment_time / (MAX_FREQ_TIME_US);
2145 NOMORE(speed_factor, low_sf);
2147 #endif // XY_FREQUENCY_LIMIT
2150 if (speed_factor < 1.0f) {
2151 current_speed *= speed_factor;
2162 #if ENABLED(LIN_ADVANCE)
2163 block->use_advance_lead =
false;
2167 #define LIMIT_ACCEL_LONG(AXIS,INDX) do{ \
2168 if (block->steps[AXIS] && max_acceleration_steps_per_s2[AXIS+INDX] < accel) { \
2169 const uint32_t comp = max_acceleration_steps_per_s2[AXIS+INDX] * block->step_event_count; \
2170 if (accel * block->steps[AXIS] > comp) accel = comp / block->steps[AXIS]; \
2174 #define LIMIT_ACCEL_FLOAT(AXIS,INDX) do{ \
2175 if (block->steps[AXIS] && max_acceleration_steps_per_s2[AXIS+INDX] < accel) { \
2176 const float comp = (float)max_acceleration_steps_per_s2[AXIS+INDX] * (float)block->step_event_count; \
2177 if ((float)accel * (float)block->steps[AXIS] > comp) accel = comp / (float)block->steps[AXIS]; \
2184 #if ENABLED(LIN_ADVANCE)
2186 #if DISABLED(CLASSIC_JERK)
2187 #if ENABLED(DISTINCT_E_FACTORS)
2188 #define MAX_E_JERK max_e_jerk[extruder]
2190 #define MAX_E_JERK max_e_jerk
2193 #define MAX_E_JERK max_jerk.e
2206 block->use_advance_lead = esteps
2210 if (block->use_advance_lead) {
2223 if (block->e_D_ratio > 3.0f)
2224 block->use_advance_lead =
false;
2226 const uint32_t max_accel_steps_per_s2 = MAX_E_JERK / (extruder_advance_K[
active_extruder] * block->e_D_ratio) * steps_per_mm;
2227 #if ENABLED(LA_DEBUG)
2228 if (accel > max_accel_steps_per_s2)
SERIAL_ECHOLNPGM(
"Acceleration limited.");
2230 NOMORE(accel, max_accel_steps_per_s2);
2235 #if ENABLED(DISTINCT_E_FACTORS)
2236 #define ACCEL_IDX extruder
2257 #if DISABLED(S_CURVE_ACCELERATION)
2260 #if ENABLED(LIN_ADVANCE)
2261 if (block->use_advance_lead) {
2263 #if ENABLED(LA_DEBUG)
2266 if (block->advance_speed < 200)
2272 float vmax_junction_sqr;
2274 #if DISABLED(CLASSIC_JERK)
2313 #if IS_KINEMATIC && DISABLED(CLASSIC_JERK)
2316 { delta_mm.
x, delta_mm.y, delta_mm.z, delta_mm.e }
2319 unit_vec *= inverse_millimeters;
2321 #if IS_CORE && DISABLED(CLASSIC_JERK)
2327 normalize_junction_vector(unit_vec);
2331 if (moves_queued && !
UNEAR_ZERO(previous_nominal_speed_sqr)) {
2334 float junction_cos_theta = (-prev_unit_vec.
x * unit_vec.
x) + (-prev_unit_vec.
y * unit_vec.
y)
2335 + (-prev_unit_vec.
z * unit_vec.
z) + (-prev_unit_vec.
e * unit_vec.
e);
2338 if (junction_cos_theta > 0.999999f) {
2343 NOLESS(junction_cos_theta, -0.999999f);
2346 xyze_float_t junction_unit_vec = unit_vec - prev_unit_vec;
2347 normalize_junction_vector(junction_unit_vec);
2349 const float junction_acceleration = limit_value_by_axis_maximum(block->
acceleration, junction_unit_vec),
2350 sin_theta_d2 =
SQRT(0.5f * (1.0f - junction_cos_theta));
2352 vmax_junction_sqr = (junction_acceleration * junction_deviation_mm * sin_theta_d2) / (1.0f - sin_theta_d2);
2356 const float junction_theta = (
RADIANS(-40) *
sq(junction_cos_theta) -
RADIANS(50)) * junction_cos_theta +
RADIANS(90) - 0.18f;
2359 if (junction_theta >
RADIANS(135)) {
2360 const float limit_sqr = block->
millimeters / (
RADIANS(180) - junction_theta) * junction_acceleration;
2361 NOMORE(vmax_junction_sqr, limit_sqr);
2370 vmax_junction_sqr = 0;
2372 prev_unit_vec = unit_vec;
2376 #ifdef USE_CACHED_SQRT
2377 #define CACHED_SQRT(N, V) \
2378 static float saved_V, N; \
2379 if (V != saved_V) { N = SQRT(V); saved_V = V; }
2381 #define CACHED_SQRT(N, V) const float N = SQRT(V)
2384 #if HAS_CLASSIC_JERK
2393 static float previous_safe_speed;
2396 float safe_speed = nominal_speed;
2399 #if HAS_LINEAR_E_JERK
2405 const float jerk =
ABS(current_speed[
i]),
2409 const float mjerk = nominal_speed * maxj;
2410 if (jerk * safe_speed > mjerk) safe_speed = mjerk / jerk;
2413 safe_speed *= maxj / jerk;
2419 float vmax_junction;
2420 if (moves_queued && !
UNEAR_ZERO(previous_nominal_speed_sqr)) {
2431 CACHED_SQRT(previous_nominal_speed, previous_nominal_speed_sqr);
2433 vmax_junction =
_MIN(nominal_speed, previous_nominal_speed);
2436 const float smaller_speed_factor = vmax_junction / previous_nominal_speed;
2437 #if HAS_LINEAR_E_JERK
2444 float v_exit = previous_speed[axis] * smaller_speed_factor,
2445 v_entry = current_speed[axis];
2448 v_entry *= v_factor;
2452 const float jerk = (v_exit > v_entry)
2454 ( (v_entry > 0 || v_exit < 0) ? (v_exit - v_entry) :
_MAX(v_exit, -v_entry) )
2456 ( (v_entry < 0 || v_exit > 0) ? (v_entry - v_exit) :
_MAX(-v_exit, v_entry) );
2458 if (jerk > max_jerk[axis]) {
2459 v_factor *= max_jerk[axis] / jerk;
2463 if (limited) vmax_junction *= v_factor;
2466 const float vmax_junction_threshold = vmax_junction * 0.99f;
2467 if (previous_safe_speed > vmax_junction_threshold && safe_speed > vmax_junction_threshold)
2468 vmax_junction = safe_speed;
2471 vmax_junction = safe_speed;
2473 previous_safe_speed = safe_speed;
2475 #if DISABLED(CLASSIC_JERK)
2476 vmax_junction_sqr =
_MIN(vmax_junction_sqr,
sq(vmax_junction));
2478 vmax_junction_sqr =
sq(vmax_junction);
2481 #endif // Classic Jerk Limiting
2504 previous_speed = current_speed;
2509 #if HAS_POSITION_FLOAT
2513 #if ENABLED(GRADIENT_MIX)
2514 mixer.gradient_control(target_float.
z);
2517 #if ENABLED(POWER_LOSS_RECOVERY)
◆ buffer_sync_block()
void Planner::buffer_sync_block |
( |
| ) |
|
|
static |
◆ buffer_segment() [1/2]
Planner::buffer_segment
Add a new linear movement to the buffer in axis units.
Leveling and kinematics should be applied ahead of calling this.
a,b,c,e - target positions in mm and/or degrees fr_mm_s - (target) speed of the move extruder - target extruder millimeters - the length of the movement, if known
2579 #if ENABLED(DISTINCT_E_FACTORS)
2582 last_extruder = extruder;
2595 #if HAS_POSITION_FLOAT
2601 position.
e = target.
e;
2602 #if HAS_POSITION_FLOAT
2644 , fr_mm_s, extruder, millimeters
◆ buffer_segment() [2/2]
661 , fr_mm_s, extruder, millimeters);
◆ buffer_line() [1/2]
Add a new linear movement to the buffer. The target is cartesian. It's translated to delta/scara if needed.
rx,ry,rz,e - target position in mm or degrees fr_mm_s - (target) speed of the move (mm/s) extruder - target extruder millimeters - the length of the movement, if known inv_duration - the reciprocal if the duration of the movement, if known (kinematic only if feeedrate scaling is enabled)
2669 #if HAS_POSITION_MODIFIERS
2675 #if DISABLED(CLASSIC_JERK)
2677 rx - position_cart.
x, ry - position_cart.y,
2678 rz - position_cart.z, e - position_cart.e
2681 const xyz_pos_t delta_mm_cart = { rx - position_cart.
x, ry - position_cart.y, rz - position_cart.z };
2684 float mm = millimeters;
2686 mm = (delta_mm_cart.
x != 0.0 || delta_mm_cart.
y != 0.0) ? delta_mm_cart.
magnitude() :
ABS(delta_mm_cart.
z);
2690 #if ENABLED(SCARA_FEEDRATE_SCALING)
2693 const float duration_recip = inv_duration ?: fr_mm_s / mm;
2702 , feedrate, extruder, mm
2704 position_cart.set(rx, ry, rz, e);
◆ buffer_line() [2/2]
688 return buffer_line(cart.
x, cart.
y, cart.
z, cart.
e, fr_mm_s, extruder, millimeters
689 #
if ENABLED(SCARA_FEEDRATE_SCALING)
◆ set_position_mm() [1/2]
Set the planner.position and individual stepper positions. Used by G92, G28, G29, and other procedures.
The supplied position is in the cartesian coordinate space and is translated in to machine space as needed. Modifiers such as leveling and skew are also applied.
Multiplies by axis_steps_per_mm[] and does necessary conversion for COREXY / COREXZ / COREYZ to set the corresponding stepper positions.
Clears previous speed values.
2743 #if HAS_POSITION_MODIFIERS
2753 position_cart.set(rx, ry, rz, e);
◆ set_position_mm() [2/2]
◆ set_e_position_mm()
void Planner::set_e_position_mm |
( |
const float & |
e | ) |
|
|
static |
Setters for planner position (also setting stepper position).
2766 #if ENABLED(DISTINCT_E_FACTORS)
2769 #if ENABLED(FWRETRACT)
2772 const float e_new = e;
2775 #if HAS_POSITION_FLOAT
2779 position_cart.e = e;
◆ set_machine_position_mm() [1/2]
Set the planner.position and individual stepper positions.
The supplied position is in machine space, and no additional conversions are applied.
Directly set the planner ABC position (and stepper positions) converting mm (or angles for SCARA) into steps.
The provided ABC position is in machine units.
2722 #if ENABLED(DISTINCT_E_FACTORS)
2725 #if HAS_POSITION_FLOAT
◆ set_machine_position_mm() [2/2]
◆ get_axis_position_mm()
Get an axis position according to stepper position(s) For CORE machines apply translation from ABC to XYZ.
1530 if (axis == CORE_AXIS_1 || axis == CORE_AXIS_2) {
1543 axis_steps = (axis == CORE_AXIS_2 ? CORESIGN(p1 - p2) : p1 + p2) * 0.5f;
◆ quick_stop()
void Planner::quick_stop |
( |
| ) |
|
|
static |
1495 clear_block_buffer_runtime();
◆ endstop_triggered()
◆ triggered_position_mm()
◆ synchronize()
void Planner::synchronize |
( |
| ) |
|
|
static |
Block until all buffered steps are executed / cleaned
1559 #
if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
1560 || (
READ(CLOSED_LOOP_ENABLE_PIN) && !
READ(CLOSED_LOOP_MOVE_COMPLETE_PIN))
◆ finish_and_disable()
void Planner::finish_and_disable |
( |
| ) |
|
|
static |
◆ tick()
static void Planner::tick |
( |
| ) |
|
|
static |
753 #if ENABLED(SD_FINISHED_STEPPERRELEASE) && defined(SD_FINISHED_RELEASECOMMAND)
◆ has_blocks_queued()
Does the buffer have any blocks queued?
◆ get_current_block()
static block_t* Planner::get_current_block |
( |
| ) |
|
|
static |
The current block. nullptr if the buffer is empty. This also marks the block as busy. WARNING: Called from Stepper ISR context!
793 block_buffer_runtime_us -= block->segment_time_us;
809 clear_block_buffer_runtime();
◆ discard_current_block()
"Discard" the block and "release" the memory. Called when the current block is no longer needed. NB: There MUST be a current block to call this function!!
◆ block_buffer
The move buffer, calculated in stepper steps
block_buffer is a ring buffer...
head,tail : indexes for write,read
head==tail : the buffer is empty
head!=tail : blocks are in the buffer
head==(tail-1)size : the buffer is full
Writer of head is Planner::buffer_segment(). Reader of tail is Stepper::isr(). Always consider tail busy / read-only
A ring buffer of moves described in steps
◆ block_buffer_head
volatile uint8_t Planner::block_buffer_head |
|
static |
◆ block_buffer_nonbusy
volatile uint8_t Planner::block_buffer_nonbusy |
|
static |
◆ block_buffer_planned
volatile uint8_t Planner::block_buffer_planned |
|
static |
◆ block_buffer_tail
volatile uint8_t Planner::block_buffer_tail |
|
static |
◆ cleaning_buffer_counter
uint16_t Planner::cleaning_buffer_counter |
|
static |
◆ delay_before_delivering
uint8_t Planner::delay_before_delivering |
|
static |
◆ settings
◆ max_acceleration_steps_per_s2
uint32_t Planner::max_acceleration_steps_per_s2 |
|
static |
◆ steps_to_mm
float Planner::steps_to_mm |
|
static |
◆ leveling_active
bool Planner::leveling_active = false |
|
static |
◆ bed_level_matrix
◆ position_float
◆ skew_factor
#define enable_E2()
Definition: Marlin.h:276
#define WITHIN(N, L, H)
Definition: macros.h:195
static void buffer_sync_block()
Definition: planner.cpp:2529
T z
Definition: types.h:286
#define enable_E0()
Definition: Marlin.h:260
static void set_machine_position_mm(const float &a, const float &b, const float &c, const float &e)
Definition: planner.cpp:2721
static FORCE_INLINE bool tooColdToExtrude(const uint8_t)
Definition: temperature.h:314
#define NOLESS(v, n)
Definition: macros.h:127
#define DEFAULT_EJERK
Definition: Configuration_A3ides_2209_MINI.h:733
#define MIXER_POPULATE_BLOCK()
Definition: mixing.h:72
#define sq(x)
Definition: wiring_constants.h:83
T z
Definition: types.h:383
#define LIMIT_ACCEL_LONG(AXIS, INDX)
#define DEFAULT_MAX_ACCELERATION
Definition: Configuration_A3ides_2209_MINI.h:696
feedRate_t min_feedrate_mm_s
Definition: planner.h:186
volatile uint8_t flag
Definition: planner.h:97
T x
Definition: types.h:286
static float get_z(const xy_pos_t &pos)
Definition: mesh_bed_leveling.h:107
void disable_e_steppers()
Definition: Marlin.cpp:293
feedRate_t max_feedrate_mm_s[XYZE_N]
Definition: planner.h:182
#define MSG_ERR_COLD_EXTRUDE_STOP
Definition: language.h:242
static matrix_3x3 bed_level_matrix
Definition: planner.h:278
#define enable_E5()
Definition: Marlin.h:300
#define CORE_IS_XY
Definition: Conditionals_post.h:101
static cutter_power_t power
Definition: spindle_laser.h:48
GCodeQueue queue
Definition: queue.cpp:28
#define BLOCK_MOD(n)
Definition: planner.h:176
constexpr xy_pos_t level_fulcrum
Definition: planner.cpp:1369
#define enable_E3()
Definition: Marlin.h:284
#define UNEAR_ZERO(x)
Definition: macros.h:269
static uint32_t command_sdpos()
Definition: power_loss_recovery.h:135
Stepper stepper
Definition: stepper.cpp:82
static bool buffer_segment(const float &a, const float &b, const float &c, const float &e, const feedRate_t &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0)
Definition: planner.cpp:2568
float retract_acceleration
Definition: planner.h:183
#define _MAX(V...)
Definition: macros.h:346
uint32_t acceleration_steps_per_s2
Definition: planner.h:147
static uint32_t max_acceleration_steps_per_s2[XYZE_N]
Definition: planner.h:253
static bool _buffer_steps(const xyze_long_t &target, const xyze_pos_t &target_float, feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters=0.0)
Definition: planner.cpp:1578
static bool leveling_active
Definition: planner.h:276
#define MIN_STEPS_PER_SEGMENT
Definition: Configuration_A3ides_2209_MINI_adv.h:1108
static void advance_e(const float &e_move)
Definition: filwidth.h:80
#define disable_Z()
Definition: Marlin.h:143
T e
Definition: types.h:383
static FORCE_INLINE uint8_t movesplanned()
Definition: planner.h:543
uint8_t i
Definition: screen_test_graph.c:72
#define _MIN(V...)
Definition: macros.h:333
#define LOOP_XYZE_N(VAR)
Definition: types.h:62
static volatile uint8_t block_buffer_tail
Definition: planner.h:227
static void wake_up()
Definition: stepper.cpp:342
static void endstop_triggered(const AxisEnum axis)
Definition: stepper.cpp:2237
#define disable_Y()
Definition: Marlin.h:104
#define enable_Z()
Definition: Marlin.h:142
#define CACHED_SQRT(N, V)
#define IS_KINEMATIC
Definition: Conditionals_LCD.h:545
PrintJobRecovery recovery
abce_ulong_t steps
Definition: planner.h:107
static volatile uint8_t block_buffer_head
Definition: planner.h:227
#define STEPPER_ISR_ENABLED()
Definition: HAL.h:143
float feedRate_t
Definition: types.h:80
static matrix_3x3 transpose(const matrix_3x3 &original)
Definition: vector_3.cpp:131
static xyze_pos_t position_float
Definition: planner.h:292
bool extruder_duplication_enabled
Definition: motion.cpp:876
static void set_axis_position(const AxisEnum a, const int32_t &v)
Definition: stepper.h:446
SpindleLaser cutter
Definition: spindle_laser.cpp:33
void set_to_identity()
Definition: vector_3.cpp:94
Definition: vector_3.h:73
static FORCE_INLINE block_t * get_next_free_block(uint8_t &next_buffer_head, const uint8_t count=1)
Definition: planner.h:564
#define HEATER_2_PIN
Definition: pins_COHESION3D_REMIX.h:116
#define NOMORE(v, n)
Definition: macros.h:133
cutter_power_t cutter_power
Definition: planner.h:153
FI T magnitude() const
Definition: types.h:295
int8_t pin_t
Definition: HAL.h:65
#define ABS(a)
Definition: macros.h:266
static volatile uint8_t block_buffer_nonbusy
Definition: planner.h:227
static block_t block_buffer[BLOCK_BUFFER_SIZE]
Definition: planner.h:226
#define E_AXIS_N(E)
Definition: Conditionals_LCD.h:454
#define AUTO_BED_LEVELING_BILINEAR
Definition: Configuration_A3ides_2209_MINI.h:1092
static FORCE_INLINE void clear_block_buffer()
Definition: planner.h:549
T a
Definition: types.h:384
#define SERIAL_ECHO_MSG(S)
Definition: serial.h:183
abce_long_t position
Definition: planner.h:108
#define RADIANS(d)
Definition: macros.h:98
T c
Definition: types.h:384
#define PSTR(str)
Definition: pgmspace.h:31
xyze_pos_t current_position
Definition: motion.cpp:102
static FORCE_INLINE void apply_modifiers(xyze_pos_t &pos, bool leveling=false)
Definition: planner.h:499
#define LROUND(x)
Definition: macros.h:285
#define HAS_LEVELING
Definition: Conditionals_post.h:1408
void add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const uint8_t dm, block_t *const block)
#define BLOCK_BUFFER_SIZE
Definition: Configuration_A3ides_2209_MINI_adv.h:1167
void apply_rotation_xyz(const matrix_3x3 &matrix, float &_x, float &_y, float &_z)
Definition: vector_3.cpp:88
void init()
Definition: planner.cpp:234
T b
Definition: types.h:384
float entry_speed_sqr
Definition: planner.h:100
uint32_t acceleration_rate
Definition: planner.h:133
FilamentWidthSensor filwidth
#define ENABLE_STEPPER_DRIVER_INTERRUPT()
Definition: HAL.h:141
#define LOOP_XYZ(VAR)
Definition: types.h:60
float travel_acceleration
Definition: planner.h:183
float axis_steps_per_mm[XYZE_N]
Definition: planner.h:181
#define DISABLED(V...)
Definition: macros.h:178
float millimeters
Definition: planner.h:100
#define CEIL(x)
Definition: macros.h:283
#define HAS_POSITION_FLOAT
Definition: planner.h:174
float nominal_speed_sqr
Definition: planner.h:100
static void refresh_collector(const float proportion=1.0, const uint8_t t=selected_vtool, float(&c)[MIXING_STEPPERS]=collector)
float acceleration
Definition: planner.h:183
static int32_t triggered_position(const AxisEnum axis)
Definition: stepper.cpp:2258
T x
Definition: types.h:383
uint8_t baricuda_valve_pressure
uint32_t max_acceleration_mm_per_s2[XYZE_N]
Definition: planner.h:179
static void reset_acceleration_rates()
Definition: planner.cpp:2788
#define HEATER_1_PIN
Definition: pins_RAMPS_LINUX.h:196
static bool buffer_line(const float &rx, const float &ry, const float &rz, const float &e, const feedRate_t &fr_mm_s, const uint8_t extruder, const float millimeters=0.0)
Definition: planner.cpp:2663
#define enable_X()
Definition: Marlin.h:76
list a
Definition: createSpeedLookupTable.py:29
static FORCE_INLINE void quick_stop()
Definition: stepper.h:375
#define enable_Y()
Definition: Marlin.h:103
void disable_all_steppers()
Definition: Marlin.cpp:308
static float get_z_correction(const float &rx0, const float &ry0)
Definition: ubl.h:238
FI void set(const T px)
Definition: types.h:391
#define SQRT(x)
Definition: macros.h:281
T x
Definition: types.h:185
float max_entry_speed_sqr
Definition: planner.h:100
#define MIXER_STEPPER_LOOP(VAR)
Definition: mixing.h:68
#define BLOCK_DELAY_FOR_1ST_MOVE
Definition: planner.cpp:109
#define enable_E1()
Definition: Marlin.h:268
const uint8_t[]
Definition: 404_html.c:3
#define DEFAULT_MAX_FEEDRATE
Definition: Configuration_A3ides_2209_MINI.h:687
float bilinear_z_offset(const xy_pos_t &raw)
uint8_t direction_bits
Definition: planner.h:136
#define DISABLE_STEPPER_DRIVER_INTERRUPT()
Definition: HAL.h:142
#define HYPOT(x, y)
Definition: macros.h:287
T y
Definition: types.h:286
static float steps_to_mm[XYZE_N]
Definition: planner.h:254
static uint16_t cleaning_buffer_counter
Definition: planner.h:231
void inverse_kinematics(const xyz_pos_t &raw)
#define disable_X()
Definition: Marlin.h:77
uint32_t step_event_count
Definition: planner.h:110
#define enable_E4()
Definition: Marlin.h:292
#define MSG_ERR_LONG_EXTRUDE_STOP
Definition: language.h:243
void limit_and_warn(float &val, const uint8_t axis, PGM_P const setting_name, const xyze_float_t &max_limit)
Definition: planner.cpp:2812
static bool _populate_block(block_t *const block, bool split_move, const xyze_long_t &target, const xyze_pos_t &target_float, feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters=0.0)
Definition: planner.cpp:1641
static FORCE_INLINE uint8_t moves_free()
Definition: planner.h:555
#define EXTRUDERS
Definition: Configuration_A3ides_2209_MINI.h:148
#define DEBUGGING(F)
Definition: serial.h:47
#define FAN_COUNT
Definition: Conditionals_post.h:1292
float acceleration
Definition: planner.h:100
#define MINIMUM_PLANNER_SPEED
Definition: Configuration_A3ides_2209_MINI_adv.h:545
static FORCE_INLINE float fade_scaling_factor_for_z(const float &)
Definition: planner.h:445
uint8_t baricuda_e_to_p_pressure
static FORCE_INLINE uint8_t nonbusy_movesplanned()
Definition: planner.h:546
uint32_t nominal_rate
Definition: planner.h:147
#define TEST(n, b)
Definition: macros.h:81
T y
Definition: types.h:185
static int32_t position(const AxisEnum axis)
Definition: stepper.cpp:2214
static void inject_P(PGM_P const pgcode)
Definition: queue.cpp:206
#define SBI(A, B)
Definition: macros.h:85
static planner_settings_t settings
Definition: planner.h:251
#define SERIAL_ECHOLNPGM(S)
Definition: serial.h:174
static void set_position_mm(const float &rx, const float &ry, const float &rz, const float &e)
Definition: planner.cpp:2741
static void apply_leveling(xyz_pos_t &raw)
Definition: planner.cpp:1381
list b
Definition: createSpeedLookupTable.py:30
void analogWrite(uint32_t ulPin, uint32_t ulValue)
Definition: wiring_analog.c:12
#define LOOP_XYZE(VAR)
Definition: types.h:61
void idle()
Definition: Marlin.cpp:629
#define READ(IO)
Definition: fastio.h:95
#define CORE_IS_XZ
Definition: Conditionals_post.h:102
feedRate_t min_travel_feedrate_mm_s
Definition: planner.h:186
static void unapply_leveling(xyz_pos_t &raw)
Definition: planner.cpp:1415
Temperature thermalManager
Definition: temperature.cpp:89
#define UNUSED(X)
Definition: stm32f4xx_hal_def.h:74
FI void reset()
Definition: types.h:387
static volatile uint8_t block_buffer_planned
Definition: planner.h:227
static constexpr uint8_t extruder
Definition: planner.h:115
uint32_t millis_t
Definition: millis_t.h:26
#define LIMIT_ACCEL_FLOAT(AXIS, INDX)
#define CORE_IS_YZ
Definition: Conditionals_post.h:103
static FORCE_INLINE uint8_t get_current_vtool()
Definition: mixing.h:111
static uint8_t delay_before_delivering
Definition: planner.h:232
constexpr uint8_t active_extruder
Definition: motion.h:107
static void set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e)
Definition: stepper.h:437
uint32_t min_segment_time_us
Definition: planner.h:179
#define ENABLED(V...)
Definition: macros.h:177
static FORCE_INLINE bool has_blocks_queued()
Definition: planner.h:762
T y
Definition: types.h:383
static void refresh()
Definition: spindle_laser.h:56
#define STEPPER_TIMER_RATE
Definition: HAL.h:133
#define EXTRUDE_MAXLENGTH
Definition: Configuration_A3ides_2209_MINI.h:524