Add a feedRate_t data type (#15349)

This commit is contained in:
Scott Lahteine
2019-09-26 01:28:09 -05:00
committed by GitHub
parent ee7558a622
commit 455dabb183
42 changed files with 384 additions and 377 deletions

View File

@ -124,6 +124,11 @@ typedef struct { bool X, Y, Z, X2, Y2, Z2, Z3, E0, E1, E2, E3, E4, E5; } tmc
// Limit an index to an array size
#define ALIM(I,ARR) _MIN(I, COUNT(ARR) - 1)
// Defaults for reset / fill in on load
static const uint32_t _DMA[] PROGMEM = DEFAULT_MAX_ACCELERATION;
static const float _DASU[] PROGMEM = DEFAULT_AXIS_STEPS_PER_UNIT;
static const feedRate_t _DMF[] PROGMEM = DEFAULT_MAX_FEEDRATE;
/**
* Current EEPROM Layout
*
@ -1289,21 +1294,19 @@ void MarlinSettings::postprocess() {
{
// Get only the number of E stepper parameters previously stored
// Any steppers added later are set to their defaults
const uint32_t def1[] = DEFAULT_MAX_ACCELERATION;
const float def2[] = DEFAULT_AXIS_STEPS_PER_UNIT, def3[] = DEFAULT_MAX_FEEDRATE;
uint32_t tmp1[XYZ + esteppers];
float tmp2[XYZ + esteppers];
feedRate_t tmp3[XYZ + esteppers];
EEPROM_READ(tmp1); // max_acceleration_mm_per_s2
EEPROM_READ(planner.settings.min_segment_time_us);
float tmp2[XYZ + esteppers], tmp3[XYZ + esteppers];
EEPROM_READ(tmp2); // axis_steps_per_mm
EEPROM_READ(tmp3); // max_feedrate_mm_s
if (!validating) LOOP_XYZE_N(i) {
const bool in = (i < esteppers + XYZ);
planner.settings.max_acceleration_mm_per_s2[i] = in ? tmp1[i] : def1[ALIM(i, def1)];
planner.settings.axis_steps_per_mm[i] = in ? tmp2[i] : def2[ALIM(i, def2)];
planner.settings.max_feedrate_mm_s[i] = in ? tmp3[i] : def3[ALIM(i, def3)];
planner.settings.max_acceleration_mm_per_s2[i] = in ? tmp1[i] : pgm_read_dword(&_DMA[ALIM(i, _DMA)]);
planner.settings.axis_steps_per_mm[i] = in ? tmp2[i] : pgm_read_float(&_DASU[ALIM(i, _DASU)]);
planner.settings.max_feedrate_mm_s[i] = in ? tmp3[i] : pgm_read_float(&_DMF[ALIM(i, _DMF)]);
}
EEPROM_READ(planner.settings.acceleration);
@ -2205,20 +2208,18 @@ void MarlinSettings::postprocess() {
* M502 - Reset Configuration
*/
void MarlinSettings::reset() {
static const float tmp1[] PROGMEM = DEFAULT_AXIS_STEPS_PER_UNIT, tmp2[] PROGMEM = DEFAULT_MAX_FEEDRATE;
static const uint32_t tmp3[] PROGMEM = DEFAULT_MAX_ACCELERATION;
LOOP_XYZE_N(i) {
planner.settings.axis_steps_per_mm[i] = pgm_read_float(&tmp1[ALIM(i, tmp1)]);
planner.settings.max_feedrate_mm_s[i] = pgm_read_float(&tmp2[ALIM(i, tmp2)]);
planner.settings.max_acceleration_mm_per_s2[i] = pgm_read_dword(&tmp3[ALIM(i, tmp3)]);
planner.settings.max_acceleration_mm_per_s2[i] = pgm_read_dword(&_DMA[ALIM(i, _DMA)]);
planner.settings.axis_steps_per_mm[i] = pgm_read_float(&_DASU[ALIM(i, _DASU)]);
planner.settings.max_feedrate_mm_s[i] = pgm_read_float(&_DMF[ALIM(i, _DMF)]);
}
planner.settings.min_segment_time_us = DEFAULT_MINSEGMENTTIME;
planner.settings.acceleration = DEFAULT_ACCELERATION;
planner.settings.retract_acceleration = DEFAULT_RETRACT_ACCELERATION;
planner.settings.travel_acceleration = DEFAULT_TRAVEL_ACCELERATION;
planner.settings.min_feedrate_mm_s = DEFAULT_MINIMUMFEEDRATE;
planner.settings.min_travel_feedrate_mm_s = DEFAULT_MINTRAVELFEEDRATE;
planner.settings.min_feedrate_mm_s = feedRate_t(DEFAULT_MINIMUMFEEDRATE);
planner.settings.min_travel_feedrate_mm_s = feedRate_t(DEFAULT_MINTRAVELFEEDRATE);
#if HAS_CLASSIC_JERK
#ifndef DEFAULT_XJERK
@ -3039,7 +3040,7 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPAIR(
" M207 S", LINEAR_UNIT(fwretract.settings.retract_length)
, " W", LINEAR_UNIT(fwretract.settings.swap_retract_length)
, " F", MMS_TO_MMM(LINEAR_UNIT(fwretract.settings.retract_feedrate_mm_s))
, " F", LINEAR_UNIT(MMS_TO_MMM(fwretract.settings.retract_feedrate_mm_s))
, " Z", LINEAR_UNIT(fwretract.settings.retract_zraise)
);
@ -3048,7 +3049,7 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPAIR(
" M208 S", LINEAR_UNIT(fwretract.settings.retract_recover_extra)
, " W", LINEAR_UNIT(fwretract.settings.swap_retract_recover_extra)
, " F", MMS_TO_MMM(LINEAR_UNIT(fwretract.settings.retract_recover_feedrate_mm_s))
, " F", LINEAR_UNIT(MMS_TO_MMM(fwretract.settings.retract_recover_feedrate_mm_s))
);
#if ENABLED(FWRETRACT_AUTORETRACT)

View File

@ -231,12 +231,12 @@ void home_delta() {
#endif
// Move all carriages together linearly until an endstop is hit.
destination[Z_AXIS] = (delta_height
current_position[Z_AXIS] = (delta_height + 10
#if HAS_BED_PROBE
- probe_offset[Z_AXIS]
#endif
+ 10);
buffer_line_to_destination(homing_feedrate(X_AXIS));
);
line_to_current_position(homing_feedrate(X_AXIS));
planner.synchronize();
// Re-enable stealthChop if used. Disable diag1 pin on driver.

View File

@ -134,12 +134,11 @@ float destination[XYZE]; // = { 0 }
// no other feedrate is specified. Overridden for special moves.
// Set by the last G0 through G5 command's "F" parameter.
// Functions that override this for custom moves *must always* restore it!
float feedrate_mm_s = MMM_TO_MMS(1500.0f);
feedRate_t feedrate_mm_s = MMM_TO_MMS(1500);
int16_t feedrate_percentage = 100;
// Homing feedrate is const progmem - compare to constexpr in the header
const float homing_feedrate_mm_s[XYZ] PROGMEM = {
const feedRate_t homing_feedrate_mm_s[XYZ] PROGMEM = {
#if ENABLED(DELTA)
MMM_TO_MMS(HOMING_FEEDRATE_Z), MMM_TO_MMS(HOMING_FEEDRATE_Z),
#else
@ -285,29 +284,21 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
* Move the planner to the current position from wherever it last moved
* (or from wherever it has been told it is located).
*/
void line_to_current_position(const float &fr_mm_s/*=feedrate_mm_s*/) {
planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], fr_mm_s, active_extruder);
}
/**
* Move the planner to the position stored in the destination array, which is
* used by G0/G1/G2/G3/G5 and many other functions to set a destination.
*/
void buffer_line_to_destination(const float fr_mm_s) {
planner.buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], fr_mm_s, active_extruder);
void line_to_current_position(const feedRate_t &fr_mm_s/*=feedrate_mm_s*/) {
planner.buffer_line(current_position, fr_mm_s, active_extruder);
}
#if IS_KINEMATIC
/**
* Calculate delta, start a line, and set current_position to destination
* Buffer a fast move without interpolation. Set current_position to destination
*/
void prepare_uninterpolated_move_to_destination(const float &fr_mm_s/*=0.0*/) {
if (DEBUGGING(LEVELING)) DEBUG_POS("prepare_uninterpolated_move_to_destination", destination);
void prepare_fast_move_to_destination(const feedRate_t &scaled_fr_mm_s/*=MMS_SCALED(feedrate_mm_s)*/) {
if (DEBUGGING(LEVELING)) DEBUG_POS("prepare_fast_move_to_destination", destination);
#if UBL_SEGMENTED
// ubl segmented line will do z-only moves in single segment
ubl.prepare_segmented_line_to(destination, MMS_SCALED(fr_mm_s ? fr_mm_s : feedrate_mm_s));
// UBL segmented line will do Z-only moves in single segment
ubl.line_to_destination_segmented(scaled_fr_mm_s);
#else
if ( current_position[X_AXIS] == destination[X_AXIS]
&& current_position[Y_AXIS] == destination[Y_AXIS]
@ -315,7 +306,7 @@ void buffer_line_to_destination(const float fr_mm_s) {
&& current_position[E_AXIS] == destination[E_AXIS]
) return;
planner.buffer_line(destination, MMS_SCALED(fr_mm_s ? fr_mm_s : feedrate_mm_s), active_extruder);
planner.buffer_line(destination, scaled_fr_mm_s, active_extruder);
#endif
set_current_from_destination();
@ -323,14 +314,40 @@ void buffer_line_to_destination(const float fr_mm_s) {
#endif // IS_KINEMATIC
void _internal_move_to_destination(const feedRate_t &fr_mm_s/*=0.0f*/
#if IS_KINEMATIC
, const bool is_fast/*=false*/
#endif
) {
const feedRate_t old_feedrate = feedrate_mm_s;
if (fr_mm_s) feedrate_mm_s = fr_mm_s;
const uint16_t old_pct = feedrate_percentage;
feedrate_percentage = 100;
const float old_fac = planner.e_factor[active_extruder];
planner.e_factor[active_extruder] = 1.0f;
#if IS_KINEMATIC
if (is_fast)
prepare_fast_move_to_destination();
else
#endif
prepare_move_to_destination();
feedrate_mm_s = old_feedrate;
feedrate_percentage = old_pct;
planner.e_factor[active_extruder] = old_fac;
}
/**
* Plan a move to (X, Y, Z) and set the current_position
*/
void do_blocking_move_to(const float rx, const float ry, const float rz, const float &fr_mm_s/*=0.0*/) {
void do_blocking_move_to(const float rx, const float ry, const float rz, const feedRate_t &fr_mm_s/*=0.0*/) {
if (DEBUGGING(LEVELING)) DEBUG_XYZ(">>> do_blocking_move_to", rx, ry, rz);
const float z_feedrate = fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS),
xy_feedrate = fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S;
const feedRate_t z_feedrate = fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS),
xy_feedrate = fr_mm_s ? fr_mm_s : feedRate_t(XY_PROBE_FEEDRATE_MM_S);
#if ENABLED(DELTA)
@ -344,33 +361,33 @@ void do_blocking_move_to(const float rx, const float ry, const float rz, const f
// when in the danger zone
if (current_position[Z_AXIS] > delta_clip_start_height) {
if (rz > delta_clip_start_height) { // staying in the danger zone
destination[X_AXIS] = rx; // move directly (uninterpolated)
if (rz > delta_clip_start_height) { // staying in the danger zone
destination[X_AXIS] = rx; // move directly (uninterpolated)
destination[Y_AXIS] = ry;
destination[Z_AXIS] = rz;
prepare_uninterpolated_move_to_destination(); // set_current_from_destination()
prepare_internal_fast_move_to_destination(); // set_current_from_destination()
if (DEBUGGING(LEVELING)) DEBUG_POS("danger zone move", current_position);
return;
}
destination[Z_AXIS] = delta_clip_start_height;
prepare_uninterpolated_move_to_destination(); // set_current_from_destination()
prepare_internal_fast_move_to_destination(); // set_current_from_destination()
if (DEBUGGING(LEVELING)) DEBUG_POS("zone border move", current_position);
}
if (rz > current_position[Z_AXIS]) { // raising?
if (rz > current_position[Z_AXIS]) { // raising?
destination[Z_AXIS] = rz;
prepare_uninterpolated_move_to_destination(z_feedrate); // set_current_from_destination()
prepare_internal_fast_move_to_destination(z_feedrate); // set_current_from_destination()
if (DEBUGGING(LEVELING)) DEBUG_POS("z raise move", current_position);
}
destination[X_AXIS] = rx;
destination[Y_AXIS] = ry;
prepare_move_to_destination(); // set_current_from_destination()
prepare_internal_move_to_destination(); // set_current_from_destination()
if (DEBUGGING(LEVELING)) DEBUG_POS("xy move", current_position);
if (rz < current_position[Z_AXIS]) { // lowering?
if (rz < current_position[Z_AXIS]) { // lowering?
destination[Z_AXIS] = rz;
prepare_uninterpolated_move_to_destination(z_feedrate); // set_current_from_destination()
prepare_fast_move_to_destination(z_feedrate); // set_current_from_destination()
if (DEBUGGING(LEVELING)) DEBUG_POS("z lower move", current_position);
}
@ -383,17 +400,17 @@ void do_blocking_move_to(const float rx, const float ry, const float rz, const f
// If Z needs to raise, do it before moving XY
if (destination[Z_AXIS] < rz) {
destination[Z_AXIS] = rz;
prepare_uninterpolated_move_to_destination(z_feedrate);
prepare_internal_fast_move_to_destination(z_feedrate);
}
destination[X_AXIS] = rx;
destination[Y_AXIS] = ry;
prepare_uninterpolated_move_to_destination(xy_feedrate);
prepare_internal_fast_move_to_destination(xy_feedrate);
// If Z needs to lower, do it after moving XY
if (destination[Z_AXIS] > rz) {
destination[Z_AXIS] = rz;
prepare_uninterpolated_move_to_destination(z_feedrate);
prepare_internal_fast_move_to_destination(z_feedrate);
}
#else
@ -420,16 +437,16 @@ void do_blocking_move_to(const float rx, const float ry, const float rz, const f
planner.synchronize();
}
void do_blocking_move_to_x(const float &rx, const float &fr_mm_s/*=0.0*/) {
void do_blocking_move_to_x(const float &rx, const feedRate_t &fr_mm_s/*=0.0*/) {
do_blocking_move_to(rx, current_position[Y_AXIS], current_position[Z_AXIS], fr_mm_s);
}
void do_blocking_move_to_y(const float &ry, const float &fr_mm_s/*=0.0*/) {
void do_blocking_move_to_y(const float &ry, const feedRate_t &fr_mm_s/*=0.0*/) {
do_blocking_move_to(current_position[X_AXIS], ry, current_position[Z_AXIS], fr_mm_s);
}
void do_blocking_move_to_z(const float &rz, const float &fr_mm_s/*=0.0*/) {
void do_blocking_move_to_z(const float &rz, const feedRate_t &fr_mm_s/*=0.0*/) {
do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], rz, fr_mm_s);
}
void do_blocking_move_to_xy(const float &rx, const float &ry, const float &fr_mm_s/*=0.0*/) {
void do_blocking_move_to_xy(const float &rx, const float &ry, const feedRate_t &fr_mm_s/*=0.0*/) {
do_blocking_move_to(rx, ry, current_position[Z_AXIS], fr_mm_s);
}
@ -629,31 +646,31 @@ void restore_feedrate_and_scaling() {
* small incremental moves for DELTA or SCARA.
*
* For Unified Bed Leveling (Delta or Segmented Cartesian)
* the ubl.prepare_segmented_line_to method replaces this.
* the ubl.line_to_destination_segmented method replaces this.
*
* For Auto Bed Leveling (Bilinear) with SEGMENT_LEVELED_MOVES
* this is replaced by segmented_line_to_destination below.
*/
inline bool prepare_kinematic_move_to(const float (&rtarget)[XYZE]) {
inline bool line_to_destination_kinematic() {
// Get the top feedrate of the move in the XY plane
const float _feedrate_mm_s = MMS_SCALED(feedrate_mm_s);
const float scaled_fr_mm_s = MMS_SCALED(feedrate_mm_s);
const float xdiff = rtarget[X_AXIS] - current_position[X_AXIS],
ydiff = rtarget[Y_AXIS] - current_position[Y_AXIS];
const float xdiff = destination[X_AXIS] - current_position[X_AXIS],
ydiff = destination[Y_AXIS] - current_position[Y_AXIS];
// If the move is only in Z/E don't split up the move
if (!xdiff && !ydiff) {
planner.buffer_line(rtarget, _feedrate_mm_s, active_extruder);
planner.buffer_line(destination, scaled_fr_mm_s, active_extruder);
return false; // caller will update current_position
}
// Fail if attempting move outside printable radius
if (!position_is_reachable(rtarget[X_AXIS], rtarget[Y_AXIS])) return true;
if (!position_is_reachable(destination[X_AXIS], destination[Y_AXIS])) return true;
// Remaining cartesian distances
const float zdiff = rtarget[Z_AXIS] - current_position[Z_AXIS],
ediff = rtarget[E_AXIS] - current_position[E_AXIS];
const float zdiff = destination[Z_AXIS] - current_position[Z_AXIS],
ediff = destination[E_AXIS] - current_position[E_AXIS];
// Get the linear distance in XYZ
float cartesian_mm = SQRT(sq(xdiff) + sq(ydiff) + sq(zdiff));
@ -665,7 +682,7 @@ void restore_feedrate_and_scaling() {
if (UNEAR_ZERO(cartesian_mm)) return true;
// Minimum number of seconds to move the given distance
const float seconds = cartesian_mm / _feedrate_mm_s;
const float seconds = cartesian_mm / scaled_fr_mm_s;
// The number of segments-per-second times the duration
// gives the number of segments
@ -690,7 +707,7 @@ void restore_feedrate_and_scaling() {
cartesian_segment_mm = cartesian_mm * inv_segments;
#if ENABLED(SCARA_FEEDRATE_SCALING)
const float inv_duration = _feedrate_mm_s / cartesian_segment_mm;
const float inv_duration = scaled_fr_mm_s / cartesian_segment_mm;
#endif
/*
@ -717,7 +734,7 @@ void restore_feedrate_and_scaling() {
LOOP_XYZE(i) raw[i] += segment_distance[i];
if (!planner.buffer_line(raw, _feedrate_mm_s, active_extruder, cartesian_segment_mm
if (!planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, cartesian_segment_mm
#if ENABLED(SCARA_FEEDRATE_SCALING)
, inv_duration
#endif
@ -726,7 +743,7 @@ void restore_feedrate_and_scaling() {
}
// Ensure last segment arrives at target location.
planner.buffer_line(rtarget, _feedrate_mm_s, active_extruder, cartesian_segment_mm
planner.buffer_line(destination, scaled_fr_mm_s, active_extruder, cartesian_segment_mm
#if ENABLED(SCARA_FEEDRATE_SCALING)
, inv_duration
#endif
@ -746,7 +763,7 @@ void restore_feedrate_and_scaling() {
* small incremental moves. This allows the planner to
* apply more detailed bed leveling to the full move.
*/
inline void segmented_line_to_destination(const float &fr_mm_s, const float segment_size=LEVELED_SEGMENT_LENGTH) {
inline void segmented_line_to_destination(const feedRate_t &fr_mm_s, const float segment_size=LEVELED_SEGMENT_LENGTH) {
const float xdiff = destination[X_AXIS] - current_position[X_AXIS],
ydiff = destination[Y_AXIS] - current_position[Y_AXIS];
@ -784,7 +801,7 @@ void restore_feedrate_and_scaling() {
};
#if ENABLED(SCARA_FEEDRATE_SCALING)
const float inv_duration = _feedrate_mm_s / cartesian_segment_mm;
const float inv_duration = scaled_fr_mm_s / cartesian_segment_mm;
#endif
// SERIAL_ECHOPAIR("mm=", cartesian_mm);
@ -832,13 +849,14 @@ void restore_feedrate_and_scaling() {
* Returns true if current_position[] was set to destination[]
*/
inline bool prepare_move_to_destination_cartesian() {
const float scaled_fr_mm_s = MMS_SCALED(feedrate_mm_s);
#if HAS_MESH
if (planner.leveling_active && planner.leveling_active_at_z(destination[Z_AXIS])) {
#if ENABLED(AUTO_BED_LEVELING_UBL)
ubl.line_to_destination_cartesian(MMS_SCALED(feedrate_mm_s), active_extruder); // UBL's motion routine needs to know about
return true; // all moves, including Z-only moves.
ubl.line_to_destination_cartesian(scaled_fr_mm_s, active_extruder); // UBL's motion routine needs to know about
return true; // all moves, including Z-only moves.
#elif ENABLED(SEGMENT_LEVELED_MOVES)
segmented_line_to_destination(MMS_SCALED(feedrate_mm_s));
segmented_line_to_destination(scaled_fr_mm_s);
return false; // caller will update current_position
#else
/**
@ -847,9 +865,9 @@ void restore_feedrate_and_scaling() {
*/
if (current_position[X_AXIS] != destination[X_AXIS] || current_position[Y_AXIS] != destination[Y_AXIS]) {
#if ENABLED(MESH_BED_LEVELING)
mbl.line_to_destination(MMS_SCALED(feedrate_mm_s));
mbl.line_to_destination(scaled_fr_mm_s);
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
bilinear_line_to_destination(MMS_SCALED(feedrate_mm_s));
bilinear_line_to_destination(scaled_fr_mm_s);
#endif
return true;
}
@ -857,7 +875,7 @@ void restore_feedrate_and_scaling() {
}
#endif // HAS_MESH
buffer_line_to_destination(MMS_SCALED(feedrate_mm_s));
planner.buffer_line(destination, scaled_fr_mm_s, active_extruder);
return false; // caller will update current_position
}
@ -971,6 +989,8 @@ void restore_feedrate_and_scaling() {
*
* Make sure current_position[E] and destination[E] are good
* before calling or cold/lengthy extrusion may get missed.
*
* Before exit, current_position is set to destination.
*/
void prepare_move_to_destination() {
apply_motion_limits(destination);
@ -1014,14 +1034,13 @@ void prepare_move_to_destination() {
if (
#if UBL_SEGMENTED
//ubl.prepare_segmented_line_to(destination, MMS_SCALED(feedrate_mm_s)) // This doesn't seem to work correctly on UBL.
#if IS_KINEMATIC // Use Kinematic / Cartesian cases as a workaround for now.
ubl.prepare_segmented_line_to(destination, MMS_SCALED(feedrate_mm_s))
#if IS_KINEMATIC // UBL using Kinematic / Cartesian cases as a workaround for now.
ubl.line_to_destination_segmented(MMS_SCALED(feedrate_mm_s))
#else
prepare_move_to_destination_cartesian()
#endif
#elif IS_KINEMATIC
prepare_kinematic_move_to(destination)
line_to_destination_kinematic()
#else
prepare_move_to_destination_cartesian()
#endif
@ -1065,7 +1084,7 @@ bool axis_unhomed_error(uint8_t axis_bits/*=0x07*/) {
/**
* Homing bump feedrate (mm/s)
*/
float get_homing_bump_feedrate(const AxisEnum axis) {
feedRate_t get_homing_bump_feedrate(const AxisEnum axis) {
#if HOMING_Z_WITH_PROBE
if (axis == Z_AXIS) return MMM_TO_MMS(Z_PROBE_SPEED_SLOW);
#endif
@ -1075,7 +1094,7 @@ float get_homing_bump_feedrate(const AxisEnum axis) {
hbd = 10;
SERIAL_ECHO_MSG("Warning: Homing Bump Divisor < 1");
}
return homing_feedrate(axis) / hbd;
return homing_feedrate(axis) / float(hbd);
}
#if ENABLED(SENSORLESS_HOMING)
@ -1221,7 +1240,7 @@ float get_homing_bump_feedrate(const AxisEnum axis) {
/**
* Home an individual linear axis
*/
void do_homing_move(const AxisEnum axis, const float distance, const float fr_mm_s=0.0) {
void do_homing_move(const AxisEnum axis, const float distance, const feedRate_t fr_mm_s=0.0) {
if (DEBUGGING(LEVELING)) {
DEBUG_ECHOPAIR(">>> do_homing_move(", axis_codes[axis], ", ", distance, ", ");
@ -1266,12 +1285,13 @@ void do_homing_move(const AxisEnum axis, const float distance, const float fr_mm
#endif
}
const feedRate_t real_fr_mm_s = fr_mm_s ? fr_mm_s : homing_feedrate(axis);
#if IS_SCARA
// Tell the planner the axis is at 0
current_position[axis] = 0;
sync_plan_position();
current_position[axis] = distance;
planner.buffer_line(current_position, fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder);
line_to_current_position(real_fr_mm_s);
#else
float target[ABCE] = { planner.get_axis_position_mm(A_AXIS), planner.get_axis_position_mm(B_AXIS), planner.get_axis_position_mm(C_AXIS), planner.get_axis_position_mm(E_AXIS) };
target[axis] = 0;
@ -1287,7 +1307,7 @@ void do_homing_move(const AxisEnum axis, const float distance, const float fr_mm
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
, delta_mm_cart
#endif
, fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder
, real_fr_mm_s, active_extruder
);
#endif
@ -1507,7 +1527,7 @@ void homeaxis(const AxisEnum axis) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Move Away:");
do_homing_move(axis, -bump
#if HOMING_Z_WITH_PROBE
, axis == Z_AXIS ? MMM_TO_MMS(Z_PROBE_SPEED_FAST) : 0.0
, MMM_TO_MMS(axis == Z_AXIS ? Z_PROBE_SPEED_FAST : 0)
#endif
);

View File

@ -85,17 +85,16 @@ extern float cartes[XYZ];
* Feed rates are often configured with mm/m
* but the planner and stepper like mm/s units.
*/
extern const float homing_feedrate_mm_s[XYZ];
FORCE_INLINE float homing_feedrate(const AxisEnum a) { return pgm_read_float(&homing_feedrate_mm_s[a]); }
float get_homing_bump_feedrate(const AxisEnum axis);
extern const feedRate_t homing_feedrate_mm_s[XYZ];
FORCE_INLINE feedRate_t homing_feedrate(const AxisEnum a) { return pgm_read_float(&homing_feedrate_mm_s[a]); }
feedRate_t get_homing_bump_feedrate(const AxisEnum axis);
extern float feedrate_mm_s;
extern feedRate_t feedrate_mm_s;
/**
* Feedrate scaling and conversion
* Feedrate scaling
*/
extern int16_t feedrate_percentage;
#define MMS_SCALED(MM_S) ((MM_S)*feedrate_percentage*0.01f)
// The active extruder (tool). Set with T<extruder> command.
#if EXTRUDERS > 1
@ -172,34 +171,42 @@ void sync_plan_position_e();
* Move the planner to the current position from wherever it last moved
* (or from wherever it has been told it is located).
*/
void line_to_current_position(const float &fr_mm_s=feedrate_mm_s);
/**
* Move the planner to the position stored in the destination array, which is
* used by G0/G1/G2/G3/G5 and many other functions to set a destination.
*/
void buffer_line_to_destination(const float fr_mm_s);
#if IS_KINEMATIC
void prepare_uninterpolated_move_to_destination(const float &fr_mm_s=0);
#endif
void line_to_current_position(const feedRate_t &fr_mm_s=feedrate_mm_s);
void prepare_move_to_destination();
void _internal_move_to_destination(const feedRate_t &fr_mm_s=0.0f
#if IS_KINEMATIC
, const bool is_fast=false
#endif
);
inline void prepare_internal_move_to_destination(const feedRate_t &fr_mm_s=0.0f) {
_internal_move_to_destination(fr_mm_s);
}
#if IS_KINEMATIC
void prepare_fast_move_to_destination(const feedRate_t &scaled_fr_mm_s=MMS_SCALED(feedrate_mm_s));
inline void prepare_internal_fast_move_to_destination(const feedRate_t &fr_mm_s=0.0f) {
_internal_move_to_destination(fr_mm_s, true);
}
#endif
/**
* Blocking movement and shorthand functions
*/
void do_blocking_move_to(const float rx, const float ry, const float rz, const float &fr_mm_s=0);
void do_blocking_move_to_x(const float &rx, const float &fr_mm_s=0);
void do_blocking_move_to_y(const float &ry, const float &fr_mm_s=0);
void do_blocking_move_to_z(const float &rz, const float &fr_mm_s=0);
void do_blocking_move_to_xy(const float &rx, const float &ry, const float &fr_mm_s=0);
void do_blocking_move_to(const float rx, const float ry, const float rz, const feedRate_t &fr_mm_s=0.0f);
void do_blocking_move_to_x(const float &rx, const feedRate_t &fr_mm_s=0.0f);
void do_blocking_move_to_y(const float &ry, const feedRate_t &fr_mm_s=0.0f);
void do_blocking_move_to_z(const float &rz, const feedRate_t &fr_mm_s=0.0f);
void do_blocking_move_to_xy(const float &rx, const float &ry, const feedRate_t &fr_mm_s=0.0f);
FORCE_INLINE void do_blocking_move_to(const float (&raw)[XYZ], const float &fr_mm_s=0) {
FORCE_INLINE void do_blocking_move_to(const float (&raw)[XYZ], const feedRate_t &fr_mm_s=0) {
do_blocking_move_to(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], fr_mm_s);
}
FORCE_INLINE void do_blocking_move_to(const float (&raw)[XYZE], const float &fr_mm_s=0) {
FORCE_INLINE void do_blocking_move_to(const float (&raw)[XYZE], const feedRate_t &fr_mm_s=0) {
do_blocking_move_to(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], fr_mm_s);
}

View File

@ -1570,7 +1570,7 @@ bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
, const float (&delta_mm_cart)[XYZE]
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters
, feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters
) {
// If we are cleaning, do not accept queuing of movements
@ -1634,7 +1634,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
, const float (&delta_mm_cart)[XYZE]
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
, feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
) {
const int32_t da = target[A_AXIS] - position[A_AXIS],
@ -2091,7 +2091,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
#else
const float delta_mm_i = delta_mm[i];
#endif
const float cs = ABS(current_speed[i] = delta_mm_i * inverse_secs);
const feedRate_t cs = ABS(current_speed[i] = delta_mm_i * inverse_secs);
#if ENABLED(DISTINCT_E_FACTORS)
if (i == E_AXIS) i += extruder;
#endif
@ -2569,7 +2569,7 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
, const float (&delta_mm_cart)[XYZE]
#endif
, const float &fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
, const feedRate_t &fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
) {
// If we are cleaning, do not accept queuing of movements
@ -2651,9 +2651,8 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
/**
* Add a new linear movement to the buffer.
* The target is cartesian, it's translated to delta/scara if
* needed.
*
* 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)
@ -2661,7 +2660,7 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
* 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)
*/
bool Planner::buffer_line(const float &rx, const float &ry, const float &rz, const float &e, const float &fr_mm_s, const uint8_t extruder, const float millimeters
bool Planner::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
#if ENABLED(SCARA_FEEDRATE_SCALING)
, const float &inv_duration
#endif
@ -2690,10 +2689,10 @@ bool Planner::buffer_line(const float &rx, const float &ry, const float &rz, con
#if ENABLED(SCARA_FEEDRATE_SCALING)
// For SCARA scale the feed rate from mm/s to degrees/s
// i.e., Complete the angular vector in the given time.
const float duration_recip = inv_duration ? inv_duration : fr_mm_s / mm,
feedrate = HYPOT(delta[A_AXIS] - position_float[A_AXIS], delta[B_AXIS] - position_float[B_AXIS]) * duration_recip;
const float duration_recip = inv_duration ? inv_duration : fr_mm_s / mm;
const feedRate_t feedrate = HYPOT(delta[A_AXIS] - position_float[A_AXIS], delta[B_AXIS] - position_float[B_AXIS]) * duration_recip;
#else
const float feedrate = fr_mm_s;
const feedRate_t feedrate = fr_mm_s;
#endif
if (buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS]
#if ENABLED(JUNCTION_DEVIATION)

View File

@ -170,15 +170,15 @@ typedef struct block_t {
#define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1))
typedef struct {
uint32_t max_acceleration_mm_per_s2[XYZE_N], // (mm/s^2) M201 XYZE
min_segment_time_us; // (µs) M205 B
float axis_steps_per_mm[XYZE_N], // (steps) M92 XYZE - Steps per millimeter
max_feedrate_mm_s[XYZE_N], // (mm/s) M203 XYZE - Max speeds
acceleration, // (mm/s^2) M204 S - Normal acceleration. DEFAULT ACCELERATION for all printing moves.
retract_acceleration, // (mm/s^2) M204 R - Retract acceleration. Filament pull-back and push-forward while standing still in the other axes
travel_acceleration, // (mm/s^2) M204 T - Travel acceleration. DEFAULT ACCELERATION for all NON printing moves.
min_feedrate_mm_s, // (mm/s) M205 S - Minimum linear feedrate
min_travel_feedrate_mm_s; // (mm/s) M205 T - Minimum travel feedrate
uint32_t max_acceleration_mm_per_s2[XYZE_N], // (mm/s^2) M201 XYZE
min_segment_time_us; // (µs) M205 B
float axis_steps_per_mm[XYZE_N]; // (steps) M92 XYZE - Steps per millimeter
feedRate_t max_feedrate_mm_s[XYZE_N]; // (mm/s) M203 XYZE - Max speeds
float acceleration, // (mm/s^2) M204 S - Normal acceleration. DEFAULT ACCELERATION for all printing moves.
retract_acceleration, // (mm/s^2) M204 R - Retract acceleration. Filament pull-back and push-forward while standing still in the other axes
travel_acceleration; // (mm/s^2) M204 T - Travel acceleration. DEFAULT ACCELERATION for all NON printing moves.
feedRate_t min_feedrate_mm_s, // (mm/s) M205 S - Minimum linear feedrate
min_travel_feedrate_mm_s; // (mm/s) M205 T - Minimum travel feedrate
} planner_settings_t;
#if DISABLED(SKEW_CORRECTION)
@ -585,7 +585,7 @@ class Planner {
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
, const float (&delta_mm_cart)[XYZE]
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
, feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
);
/**
@ -608,7 +608,7 @@ class Planner {
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
, const float (&delta_mm_cart)[XYZE]
#endif
, float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
, feedRate_t fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
);
/**
@ -621,7 +621,7 @@ class Planner {
private:
// Allow do_homing_move to access internal functions, such as buffer_segment.
friend void do_homing_move(const AxisEnum, const float, const float);
friend void do_homing_move(const AxisEnum, const float, const feedRate_t);
#endif
/**
@ -640,14 +640,14 @@ class Planner {
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
, const float (&delta_mm_cart)[XYZE]
#endif
, const float &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
, const feedRate_t &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
);
FORCE_INLINE static bool buffer_segment(const float (&abce)[ABCE]
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
, const float (&delta_mm_cart)[XYZE]
#endif
, const float &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
, const feedRate_t &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
) {
return buffer_segment(abce[A_AXIS], abce[B_AXIS], abce[C_AXIS], abce[E_AXIS]
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
@ -660,9 +660,8 @@ class Planner {
/**
* Add a new linear movement to the buffer.
* The target is cartesian, it's translated to delta/scara if
* needed.
*
* 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)
@ -670,13 +669,13 @@ class Planner {
* 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)
*/
static bool buffer_line(const float &rx, const float &ry, const float &rz, const float &e, const float &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
#if ENABLED(SCARA_FEEDRATE_SCALING)
, const float &inv_duration=0.0
#endif
);
FORCE_INLINE static bool buffer_line(const float (&cart)[XYZE], const float &fr_mm_s, const uint8_t extruder, const float millimeters=0.0
FORCE_INLINE static bool buffer_line(const float (&cart)[XYZE], const feedRate_t &fr_mm_s, const uint8_t extruder, const float millimeters=0.0
#if ENABLED(SCARA_FEEDRATE_SCALING)
, const float &inv_duration=0.0
#endif

View File

@ -107,13 +107,18 @@ static inline float dist1(const float &x1, const float &y1, const float &x2, con
* the mitigation offered by MIN_STEP and the small computational
* power available on Arduino, I think it is not wise to implement it.
*/
void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS], const float offset[4], float fr_mm_s, uint8_t extruder) {
void cubic_b_spline(
const float position[NUM_AXIS], // current position
const float target[NUM_AXIS], // target position
const float (&offset)[4], // a pair of offsets
const feedRate_t &scaled_fr_mm_s, // mm/s scaled by feedrate %
const uint8_t extruder
) {
// Absolute first and second control points are recovered.
const float first0 = position[X_AXIS] + offset[0],
first1 = position[Y_AXIS] + offset[1],
second0 = target[X_AXIS] + offset[2],
second1 = target[Y_AXIS] + offset[3];
float t = 0;
float bez_target[4];
bez_target[X_AXIS] = position[X_AXIS];
@ -122,7 +127,7 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS]
millis_t next_idle_ms = millis() + 200UL;
while (t < 1) {
for (float t = 0; t < 1;) {
thermalManager.manage_heater();
millis_t now = millis();
@ -197,7 +202,7 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS]
const float (&pos)[XYZE] = bez_target;
#endif
if (!planner.buffer_line(pos, fr_mm_s, active_extruder, step))
if (!planner.buffer_line(pos, scaled_fr_mm_s, active_extruder, step))
break;
}
}

View File

@ -32,9 +32,9 @@
#include "../core/macros.h"
void cubic_b_spline(
const float position[NUM_AXIS], // current position
const float target[NUM_AXIS], // target position
const float offset[4], // a pair of offsets
float fr_mm_s,
uint8_t extruder
);
const float position[NUM_AXIS], // current position
const float target[NUM_AXIS], // target position
const float (&offset)[4], // a pair of offsets
const feedRate_t &scaled_fr_mm_s, // mm/s scaled by feedrate %
const uint8_t extruder
);

View File

@ -446,7 +446,7 @@ bool set_probe_deployed(const bool deploy) {
const char msg_wait_for_bed_heating[25] PROGMEM = "Wait for bed heating...\n";
#endif
static bool do_probe_move(const float z, const float fr_mm_s) {
static bool do_probe_move(const float z, const feedRate_t fr_mm_s) {
if (DEBUGGING(LEVELING)) DEBUG_POS(">>> do_probe_move", current_position);
#if HAS_HEATED_BED && ENABLED(WAIT_FOR_BED_HEATER)

View File

@ -71,12 +71,12 @@
#elif ENABLED(MAGNETIC_PARKING_EXTRUDER)
typedef struct MPESettings {
float parking_xpos[2], // M951 L R
grab_distance, // M951 I
slow_feedrate, // M951 J
fast_feedrate, // M951 H
travel_distance, // M951 D
compensation_factor; // M951 C
float parking_xpos[2], // M951 L R
grab_distance; // M951 I
feedRate_t slow_feedrate, // M951 J
fast_feedrate; // M951 H
float travel_distance, // M951 D
compensation_factor; // M951 C
} mpe_settings_t;
extern mpe_settings_t mpe_settings;