|
@ -134,12 +134,11 @@ float destination[XYZE]; // = { 0 } |
|
|
// no other feedrate is specified. Overridden for special moves.
|
|
|
// no other feedrate is specified. Overridden for special moves.
|
|
|
// Set by the last G0 through G5 command's "F" parameter.
|
|
|
// Set by the last G0 through G5 command's "F" parameter.
|
|
|
// Functions that override this for custom moves *must always* restore it!
|
|
|
// 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; |
|
|
int16_t feedrate_percentage = 100; |
|
|
|
|
|
|
|
|
// Homing feedrate is const progmem - compare to constexpr in the header
|
|
|
// 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) |
|
|
#if ENABLED(DELTA) |
|
|
MMM_TO_MMS(HOMING_FEEDRATE_Z), MMM_TO_MMS(HOMING_FEEDRATE_Z), |
|
|
MMM_TO_MMS(HOMING_FEEDRATE_Z), MMM_TO_MMS(HOMING_FEEDRATE_Z), |
|
|
#else |
|
|
#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 |
|
|
* Move the planner to the current position from wherever it last moved |
|
|
* (or from wherever it has been told it is located). |
|
|
* (or from wherever it has been told it is located). |
|
|
*/ |
|
|
*/ |
|
|
void line_to_current_position(const float &fr_mm_s/*=feedrate_mm_s*/) { |
|
|
void line_to_current_position(const feedRate_t &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); |
|
|
planner.buffer_line(current_position, 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); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#if IS_KINEMATIC |
|
|
#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*/) { |
|
|
void prepare_fast_move_to_destination(const feedRate_t &scaled_fr_mm_s/*=MMS_SCALED(feedrate_mm_s)*/) { |
|
|
if (DEBUGGING(LEVELING)) DEBUG_POS("prepare_uninterpolated_move_to_destination", destination); |
|
|
if (DEBUGGING(LEVELING)) DEBUG_POS("prepare_fast_move_to_destination", destination); |
|
|
|
|
|
|
|
|
#if UBL_SEGMENTED |
|
|
#if UBL_SEGMENTED |
|
|
// ubl segmented line will do z-only moves in single segment
|
|
|
// 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.line_to_destination_segmented(scaled_fr_mm_s); |
|
|
#else |
|
|
#else |
|
|
if ( current_position[X_AXIS] == destination[X_AXIS] |
|
|
if ( current_position[X_AXIS] == destination[X_AXIS] |
|
|
&& current_position[Y_AXIS] == destination[Y_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] |
|
|
&& current_position[E_AXIS] == destination[E_AXIS] |
|
|
) return; |
|
|
) 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 |
|
|
#endif |
|
|
|
|
|
|
|
|
set_current_from_destination(); |
|
|
set_current_from_destination(); |
|
@ -323,14 +314,40 @@ void buffer_line_to_destination(const float fr_mm_s) { |
|
|
|
|
|
|
|
|
#endif // IS_KINEMATIC
|
|
|
#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 |
|
|
* 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); |
|
|
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), |
|
|
const feedRate_t 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; |
|
|
xy_feedrate = fr_mm_s ? fr_mm_s : feedRate_t(XY_PROBE_FEEDRATE_MM_S); |
|
|
|
|
|
|
|
|
#if ENABLED(DELTA) |
|
|
#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
|
|
|
// when in the danger zone
|
|
|
if (current_position[Z_AXIS] > delta_clip_start_height) { |
|
|
if (current_position[Z_AXIS] > delta_clip_start_height) { |
|
|
if (rz > delta_clip_start_height) { // staying in the danger zone
|
|
|
if (rz > delta_clip_start_height) { // staying in the danger zone
|
|
|
destination[X_AXIS] = rx; // move directly (uninterpolated)
|
|
|
destination[X_AXIS] = rx; // move directly (uninterpolated)
|
|
|
destination[Y_AXIS] = ry; |
|
|
destination[Y_AXIS] = ry; |
|
|
destination[Z_AXIS] = rz; |
|
|
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); |
|
|
if (DEBUGGING(LEVELING)) DEBUG_POS("danger zone move", current_position); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
destination[Z_AXIS] = delta_clip_start_height; |
|
|
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 (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; |
|
|
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); |
|
|
if (DEBUGGING(LEVELING)) DEBUG_POS("z raise move", current_position); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
destination[X_AXIS] = rx; |
|
|
destination[X_AXIS] = rx; |
|
|
destination[Y_AXIS] = ry; |
|
|
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 (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; |
|
|
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); |
|
|
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 Z needs to raise, do it before moving XY
|
|
|
if (destination[Z_AXIS] < rz) { |
|
|
if (destination[Z_AXIS] < rz) { |
|
|
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[X_AXIS] = rx; |
|
|
destination[Y_AXIS] = ry; |
|
|
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 Z needs to lower, do it after moving XY
|
|
|
if (destination[Z_AXIS] > rz) { |
|
|
if (destination[Z_AXIS] > rz) { |
|
|
destination[Z_AXIS] = rz; |
|
|
destination[Z_AXIS] = rz; |
|
|
prepare_uninterpolated_move_to_destination(z_feedrate); |
|
|
prepare_internal_fast_move_to_destination(z_feedrate); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#else |
|
|
#else |
|
@ -420,16 +437,16 @@ void do_blocking_move_to(const float rx, const float ry, const float rz, const f |
|
|
|
|
|
|
|
|
planner.synchronize(); |
|
|
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); |
|
|
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); |
|
|
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); |
|
|
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); |
|
|
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. |
|
|
* small incremental moves for DELTA or SCARA. |
|
|
* |
|
|
* |
|
|
* For Unified Bed Leveling (Delta or Segmented Cartesian) |
|
|
* 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 |
|
|
* For Auto Bed Leveling (Bilinear) with SEGMENT_LEVELED_MOVES |
|
|
* this is replaced by segmented_line_to_destination below. |
|
|
* 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
|
|
|
// 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], |
|
|
const float xdiff = destination[X_AXIS] - current_position[X_AXIS], |
|
|
ydiff = rtarget[Y_AXIS] - current_position[Y_AXIS]; |
|
|
ydiff = destination[Y_AXIS] - current_position[Y_AXIS]; |
|
|
|
|
|
|
|
|
// If the move is only in Z/E don't split up the move
|
|
|
// If the move is only in Z/E don't split up the move
|
|
|
if (!xdiff && !ydiff) { |
|
|
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
|
|
|
return false; // caller will update current_position
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Fail if attempting move outside printable radius
|
|
|
// 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
|
|
|
// Remaining cartesian distances
|
|
|
const float zdiff = rtarget[Z_AXIS] - current_position[Z_AXIS], |
|
|
const float zdiff = destination[Z_AXIS] - current_position[Z_AXIS], |
|
|
ediff = rtarget[E_AXIS] - current_position[E_AXIS]; |
|
|
ediff = destination[E_AXIS] - current_position[E_AXIS]; |
|
|
|
|
|
|
|
|
// Get the linear distance in XYZ
|
|
|
// Get the linear distance in XYZ
|
|
|
float cartesian_mm = SQRT(sq(xdiff) + sq(ydiff) + sq(zdiff)); |
|
|
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; |
|
|
if (UNEAR_ZERO(cartesian_mm)) return true; |
|
|
|
|
|
|
|
|
// Minimum number of seconds to move the given distance
|
|
|
// 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
|
|
|
// The number of segments-per-second times the duration
|
|
|
// gives the number of segments
|
|
|
// gives the number of segments
|
|
@ -690,7 +707,7 @@ void restore_feedrate_and_scaling() { |
|
|
cartesian_segment_mm = cartesian_mm * inv_segments; |
|
|
cartesian_segment_mm = cartesian_mm * inv_segments; |
|
|
|
|
|
|
|
|
#if ENABLED(SCARA_FEEDRATE_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 |
|
|
#endif |
|
|
|
|
|
|
|
|
/*
|
|
|
/*
|
|
@ -717,7 +734,7 @@ void restore_feedrate_and_scaling() { |
|
|
|
|
|
|
|
|
LOOP_XYZE(i) raw[i] += segment_distance[i]; |
|
|
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) |
|
|
#if ENABLED(SCARA_FEEDRATE_SCALING) |
|
|
, inv_duration |
|
|
, inv_duration |
|
|
#endif |
|
|
#endif |
|
@ -726,7 +743,7 @@ void restore_feedrate_and_scaling() { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Ensure last segment arrives at target location.
|
|
|
// 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) |
|
|
#if ENABLED(SCARA_FEEDRATE_SCALING) |
|
|
, inv_duration |
|
|
, inv_duration |
|
|
#endif |
|
|
#endif |
|
@ -746,7 +763,7 @@ void restore_feedrate_and_scaling() { |
|
|
* small incremental moves. This allows the planner to |
|
|
* small incremental moves. This allows the planner to |
|
|
* apply more detailed bed leveling to the full move. |
|
|
* 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], |
|
|
const float xdiff = destination[X_AXIS] - current_position[X_AXIS], |
|
|
ydiff = destination[Y_AXIS] - current_position[Y_AXIS]; |
|
|
ydiff = destination[Y_AXIS] - current_position[Y_AXIS]; |
|
@ -784,7 +801,7 @@ void restore_feedrate_and_scaling() { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
#if ENABLED(SCARA_FEEDRATE_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 |
|
|
#endif |
|
|
|
|
|
|
|
|
// SERIAL_ECHOPAIR("mm=", cartesian_mm);
|
|
|
// SERIAL_ECHOPAIR("mm=", cartesian_mm);
|
|
@ -832,13 +849,14 @@ void restore_feedrate_and_scaling() { |
|
|
* Returns true if current_position[] was set to destination[] |
|
|
* Returns true if current_position[] was set to destination[] |
|
|
*/ |
|
|
*/ |
|
|
inline bool prepare_move_to_destination_cartesian() { |
|
|
inline bool prepare_move_to_destination_cartesian() { |
|
|
|
|
|
const float scaled_fr_mm_s = MMS_SCALED(feedrate_mm_s); |
|
|
#if HAS_MESH |
|
|
#if HAS_MESH |
|
|
if (planner.leveling_active && planner.leveling_active_at_z(destination[Z_AXIS])) { |
|
|
if (planner.leveling_active && planner.leveling_active_at_z(destination[Z_AXIS])) { |
|
|
#if ENABLED(AUTO_BED_LEVELING_UBL) |
|
|
#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
|
|
|
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.
|
|
|
return true; // all moves, including Z-only moves.
|
|
|
#elif ENABLED(SEGMENT_LEVELED_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
|
|
|
return false; // caller will update current_position
|
|
|
#else |
|
|
#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 (current_position[X_AXIS] != destination[X_AXIS] || current_position[Y_AXIS] != destination[Y_AXIS]) { |
|
|
#if ENABLED(MESH_BED_LEVELING) |
|
|
#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) |
|
|
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR) |
|
|
bilinear_line_to_destination(MMS_SCALED(feedrate_mm_s)); |
|
|
bilinear_line_to_destination(scaled_fr_mm_s); |
|
|
#endif |
|
|
#endif |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
@ -857,7 +875,7 @@ void restore_feedrate_and_scaling() { |
|
|
} |
|
|
} |
|
|
#endif // HAS_MESH
|
|
|
#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
|
|
|
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 |
|
|
* Make sure current_position[E] and destination[E] are good |
|
|
* before calling or cold/lengthy extrusion may get missed. |
|
|
* before calling or cold/lengthy extrusion may get missed. |
|
|
|
|
|
* |
|
|
|
|
|
* Before exit, current_position is set to destination. |
|
|
*/ |
|
|
*/ |
|
|
void prepare_move_to_destination() { |
|
|
void prepare_move_to_destination() { |
|
|
apply_motion_limits(destination); |
|
|
apply_motion_limits(destination); |
|
@ -1014,14 +1034,13 @@ void prepare_move_to_destination() { |
|
|
|
|
|
|
|
|
if ( |
|
|
if ( |
|
|
#if UBL_SEGMENTED |
|
|
#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 // UBL using Kinematic / Cartesian cases as a workaround for now.
|
|
|
#if IS_KINEMATIC // Use Kinematic / Cartesian cases as a workaround for now.
|
|
|
ubl.line_to_destination_segmented(MMS_SCALED(feedrate_mm_s)) |
|
|
ubl.prepare_segmented_line_to(destination, MMS_SCALED(feedrate_mm_s)) |
|
|
|
|
|
#else |
|
|
#else |
|
|
prepare_move_to_destination_cartesian() |
|
|
prepare_move_to_destination_cartesian() |
|
|
#endif |
|
|
#endif |
|
|
#elif IS_KINEMATIC |
|
|
#elif IS_KINEMATIC |
|
|
prepare_kinematic_move_to(destination) |
|
|
line_to_destination_kinematic() |
|
|
#else |
|
|
#else |
|
|
prepare_move_to_destination_cartesian() |
|
|
prepare_move_to_destination_cartesian() |
|
|
#endif |
|
|
#endif |
|
@ -1065,7 +1084,7 @@ bool axis_unhomed_error(uint8_t axis_bits/*=0x07*/) { |
|
|
/**
|
|
|
/**
|
|
|
* Homing bump feedrate (mm/s) |
|
|
* 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 HOMING_Z_WITH_PROBE |
|
|
if (axis == Z_AXIS) return MMM_TO_MMS(Z_PROBE_SPEED_SLOW); |
|
|
if (axis == Z_AXIS) return MMM_TO_MMS(Z_PROBE_SPEED_SLOW); |
|
|
#endif |
|
|
#endif |
|
@ -1075,7 +1094,7 @@ float get_homing_bump_feedrate(const AxisEnum axis) { |
|
|
hbd = 10; |
|
|
hbd = 10; |
|
|
SERIAL_ECHO_MSG("Warning: Homing Bump Divisor < 1"); |
|
|
SERIAL_ECHO_MSG("Warning: Homing Bump Divisor < 1"); |
|
|
} |
|
|
} |
|
|
return homing_feedrate(axis) / hbd; |
|
|
return homing_feedrate(axis) / float(hbd); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#if ENABLED(SENSORLESS_HOMING) |
|
|
#if ENABLED(SENSORLESS_HOMING) |
|
@ -1221,7 +1240,7 @@ float get_homing_bump_feedrate(const AxisEnum axis) { |
|
|
/**
|
|
|
/**
|
|
|
* Home an individual linear 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)) { |
|
|
if (DEBUGGING(LEVELING)) { |
|
|
DEBUG_ECHOPAIR(">>> do_homing_move(", axis_codes[axis], ", ", distance, ", "); |
|
|
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 |
|
|
#endif |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const feedRate_t real_fr_mm_s = fr_mm_s ? fr_mm_s : homing_feedrate(axis); |
|
|
#if IS_SCARA |
|
|
#if IS_SCARA |
|
|
// Tell the planner the axis is at 0
|
|
|
// Tell the planner the axis is at 0
|
|
|
current_position[axis] = 0; |
|
|
current_position[axis] = 0; |
|
|
sync_plan_position(); |
|
|
sync_plan_position(); |
|
|
current_position[axis] = distance; |
|
|
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 |
|
|
#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) }; |
|
|
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; |
|
|
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) |
|
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION) |
|
|
, delta_mm_cart |
|
|
, delta_mm_cart |
|
|
#endif |
|
|
#endif |
|
|
, fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder |
|
|
, real_fr_mm_s, active_extruder |
|
|
); |
|
|
); |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
@ -1507,7 +1527,7 @@ void homeaxis(const AxisEnum axis) { |
|
|
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Move Away:"); |
|
|
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Move Away:"); |
|
|
do_homing_move(axis, -bump |
|
|
do_homing_move(axis, -bump |
|
|
#if HOMING_Z_WITH_PROBE |
|
|
#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 |
|
|
#endif |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|