🏗️ Support for up to 6 linear axes (#19112)
Co-authored-by: Scott Lahteine <github@thinkyhead.com>
This commit is contained in:
committed by
Scott Lahteine
parent
d3c56a76e7
commit
c1fca91103
@ -89,7 +89,7 @@ bool relative_mode; // = false;
|
||||
#define Z_INIT_POS Z_HOME_POS
|
||||
#endif
|
||||
|
||||
xyze_pos_t current_position = LOGICAL_AXIS_ARRAY(0, X_HOME_POS, Y_HOME_POS, Z_INIT_POS);
|
||||
xyze_pos_t current_position = LOGICAL_AXIS_ARRAY(0, X_HOME_POS, Y_HOME_POS, Z_INIT_POS, I_HOME_POS, J_HOME_POS, K_HOME_POS);
|
||||
|
||||
/**
|
||||
* Cartesian Destination
|
||||
@ -143,7 +143,7 @@ xyz_pos_t cartes;
|
||||
|
||||
#if IS_KINEMATIC
|
||||
|
||||
abc_pos_t delta;
|
||||
abce_pos_t delta;
|
||||
|
||||
#if HAS_SCARA_OFFSET
|
||||
abc_pos_t scara_home_offset;
|
||||
@ -196,7 +196,14 @@ inline void report_more_positions() {
|
||||
inline void report_logical_position(const xyze_pos_t &rpos) {
|
||||
const xyze_pos_t lpos = rpos.asLogical();
|
||||
SERIAL_ECHOPAIR_P(
|
||||
LIST_N(DOUBLE(LINEAR_AXES), X_LBL, lpos.x, SP_Y_LBL, lpos.y, SP_Z_LBL, lpos.z)
|
||||
LIST_N(DOUBLE(LINEAR_AXES),
|
||||
X_LBL, lpos.x,
|
||||
SP_Y_LBL, lpos.y,
|
||||
SP_Z_LBL, lpos.z,
|
||||
SP_I_LBL, lpos.i,
|
||||
SP_J_LBL, lpos.j,
|
||||
SP_K_LBL, lpos.k
|
||||
)
|
||||
#if HAS_EXTRUDERS
|
||||
, SP_E_LBL, lpos.e
|
||||
#endif
|
||||
@ -209,7 +216,10 @@ void report_real_position() {
|
||||
get_cartesian_from_steppers();
|
||||
xyze_pos_t npos = LOGICAL_AXIS_ARRAY(
|
||||
planner.get_axis_position_mm(E_AXIS),
|
||||
cartes.x, cartes.y, cartes.z
|
||||
cartes.x, cartes.y, cartes.z,
|
||||
planner.get_axis_position_mm(I_AXIS),
|
||||
planner.get_axis_position_mm(J_AXIS),
|
||||
planner.get_axis_position_mm(K_AXIS)
|
||||
);
|
||||
|
||||
TERN_(HAS_POSITION_MODIFIERS, planner.unapply_modifiers(npos, true));
|
||||
@ -334,20 +344,21 @@ void sync_plan_position() {
|
||||
void get_cartesian_from_steppers() {
|
||||
#if ENABLED(DELTA)
|
||||
forward_kinematics(planner.get_axis_positions_mm());
|
||||
#else
|
||||
#if IS_SCARA
|
||||
forward_kinematics(
|
||||
planner.get_axis_position_degrees(A_AXIS)
|
||||
, planner.get_axis_position_degrees(B_AXIS)
|
||||
#if ENABLED(AXEL_TPARA)
|
||||
, planner.get_axis_position_degrees(C_AXIS)
|
||||
#endif
|
||||
);
|
||||
#else
|
||||
cartes.x = planner.get_axis_position_mm(X_AXIS);
|
||||
cartes.y = planner.get_axis_position_mm(Y_AXIS);
|
||||
#endif
|
||||
#elif IS_SCARA
|
||||
forward_kinematics(
|
||||
planner.get_axis_position_degrees(A_AXIS), planner.get_axis_position_degrees(B_AXIS)
|
||||
OPTARG(AXEL_TPARA, planner.get_axis_position_degrees(C_AXIS))
|
||||
);
|
||||
cartes.z = planner.get_axis_position_mm(Z_AXIS);
|
||||
#else
|
||||
LINEAR_AXIS_CODE(
|
||||
cartes.x = planner.get_axis_position_mm(X_AXIS),
|
||||
cartes.y = planner.get_axis_position_mm(Y_AXIS),
|
||||
cartes.z = planner.get_axis_position_mm(Z_AXIS),
|
||||
cartes.i = planner.get_axis_position_mm(I_AXIS),
|
||||
cartes.j = planner.get_axis_position_mm(J_AXIS),
|
||||
cartes.k = planner.get_axis_position_mm(K_AXIS)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -366,13 +377,9 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
|
||||
get_cartesian_from_steppers();
|
||||
xyze_pos_t pos = cartes;
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
pos.e = planner.get_axis_position_mm(E_AXIS);
|
||||
#endif
|
||||
TERN_(HAS_EXTRUDERS, pos.e = planner.get_axis_position_mm(E_AXIS));
|
||||
|
||||
#if HAS_POSITION_MODIFIERS
|
||||
planner.unapply_modifiers(pos, true);
|
||||
#endif
|
||||
TERN_(HAS_POSITION_MODIFIERS, planner.unapply_modifiers(pos, true));
|
||||
|
||||
if (axis == ALL_AXES_ENUM)
|
||||
current_position = pos;
|
||||
@ -385,7 +392,7 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
|
||||
* (or from wherever it has been told it is located).
|
||||
*/
|
||||
void line_to_current_position(const_feedRate_t fr_mm_s/*=feedrate_mm_s*/) {
|
||||
planner.buffer_line(current_position, fr_mm_s, active_extruder);
|
||||
planner.buffer_line(current_position, fr_mm_s);
|
||||
}
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
@ -411,7 +418,7 @@ void line_to_current_position(const_feedRate_t fr_mm_s/*=feedrate_mm_s*/) {
|
||||
#else
|
||||
if (current_position == destination) return;
|
||||
|
||||
planner.buffer_line(destination, scaled_fr_mm_s, active_extruder);
|
||||
planner.buffer_line(destination, scaled_fr_mm_s);
|
||||
#endif
|
||||
|
||||
current_position = destination;
|
||||
@ -449,25 +456,26 @@ void _internal_move_to_destination(const_feedRate_t fr_mm_s/*=0.0f*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Plan a move to (X, Y, Z) with separation of the XY and Z components.
|
||||
* Plan a move to (X, Y, Z, [I, [J, [K]]]) and set the current_position
|
||||
* Plan a move to (X, Y, Z) with separation of Z from other components.
|
||||
*
|
||||
* - If Z is moving up, the Z move is done before XY.
|
||||
* - If Z is moving down, the Z move is done after XY.
|
||||
* - If Z is moving up, the Z move is done before XY, etc.
|
||||
* - If Z is moving down, the Z move is done after XY, etc.
|
||||
* - Delta may lower Z first to get into the free motion zone.
|
||||
* - Before returning, wait for the planner buffer to empty.
|
||||
*/
|
||||
void do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(const float rx, const float ry, const float rz),
|
||||
const_feedRate_t fr_mm_s/*=0.0f*/
|
||||
) {
|
||||
void do_blocking_move_to(LINEAR_AXIS_ARGS(const float), const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
DEBUG_SECTION(log_move, "do_blocking_move_to", DEBUGGING(LEVELING));
|
||||
if (DEBUGGING(LEVELING)) DEBUG_XYZ("> ", LINEAR_AXIS_LIST(rx, ry, rz));
|
||||
if (DEBUGGING(LEVELING)) DEBUG_XYZ("> ", LINEAR_AXIS_ARGS());
|
||||
|
||||
const feedRate_t z_feedrate = fr_mm_s ?: homing_feedrate(Z_AXIS),
|
||||
xy_feedrate = fr_mm_s ?: feedRate_t(XY_PROBE_FEEDRATE_MM_S);
|
||||
const feedRate_t xy_feedrate = fr_mm_s ?: feedRate_t(XY_PROBE_FEEDRATE_MM_S);
|
||||
|
||||
#if HAS_Z_AXIS
|
||||
const feedRate_t z_feedrate = fr_mm_s ?: homing_feedrate(Z_AXIS);
|
||||
#endif
|
||||
|
||||
#if EITHER(DELTA, IS_SCARA)
|
||||
if (!position_is_reachable(rx, ry)) return;
|
||||
if (!position_is_reachable(x, y)) return;
|
||||
destination = current_position; // sync destination at the start
|
||||
#endif
|
||||
|
||||
@ -479,8 +487,8 @@ void do_blocking_move_to(
|
||||
|
||||
// when in the danger zone
|
||||
if (current_position.z > delta_clip_start_height) {
|
||||
if (rz > delta_clip_start_height) { // staying in the danger zone
|
||||
destination.set(rx, ry, rz); // move directly (uninterpolated)
|
||||
if (z > delta_clip_start_height) { // staying in the danger zone
|
||||
destination.set(x, y, z); // move directly (uninterpolated)
|
||||
prepare_internal_fast_move_to_destination(); // set current_position from destination
|
||||
if (DEBUGGING(LEVELING)) DEBUG_POS("danger zone move", current_position);
|
||||
return;
|
||||
@ -490,18 +498,18 @@ void do_blocking_move_to(
|
||||
if (DEBUGGING(LEVELING)) DEBUG_POS("zone border move", current_position);
|
||||
}
|
||||
|
||||
if (rz > current_position.z) { // raising?
|
||||
destination.z = rz;
|
||||
if (z > current_position.z) { // raising?
|
||||
destination.z = z;
|
||||
prepare_internal_fast_move_to_destination(z_feedrate); // set current_position from destination
|
||||
if (DEBUGGING(LEVELING)) DEBUG_POS("z raise move", current_position);
|
||||
}
|
||||
|
||||
destination.set(rx, ry);
|
||||
destination.set(x, y);
|
||||
prepare_internal_move_to_destination(); // set current_position from destination
|
||||
if (DEBUGGING(LEVELING)) DEBUG_POS("xy move", current_position);
|
||||
|
||||
if (rz < current_position.z) { // lowering?
|
||||
destination.z = rz;
|
||||
if (z < current_position.z) { // lowering?
|
||||
destination.z = z;
|
||||
prepare_internal_fast_move_to_destination(z_feedrate); // set current_position from destination
|
||||
if (DEBUGGING(LEVELING)) DEBUG_POS("z lower move", current_position);
|
||||
}
|
||||
@ -509,36 +517,40 @@ void do_blocking_move_to(
|
||||
#elif IS_SCARA
|
||||
|
||||
// If Z needs to raise, do it before moving XY
|
||||
if (destination.z < rz) {
|
||||
destination.z = rz;
|
||||
if (destination.z < z) {
|
||||
destination.z = z;
|
||||
prepare_internal_fast_move_to_destination(z_feedrate);
|
||||
}
|
||||
|
||||
destination.set(rx, ry);
|
||||
destination.set(x, y);
|
||||
prepare_internal_fast_move_to_destination(xy_feedrate);
|
||||
|
||||
// If Z needs to lower, do it after moving XY
|
||||
if (destination.z > rz) {
|
||||
destination.z = rz;
|
||||
if (destination.z > z) {
|
||||
destination.z = z;
|
||||
prepare_internal_fast_move_to_destination(z_feedrate);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// If Z needs to raise, do it before moving XY
|
||||
if (current_position.z < rz) {
|
||||
current_position.z = rz;
|
||||
line_to_current_position(z_feedrate);
|
||||
}
|
||||
#if HAS_Z_AXIS
|
||||
// If Z needs to raise, do it before moving XY
|
||||
if (current_position.z < z) {
|
||||
current_position.z = z;
|
||||
line_to_current_position(z_feedrate);
|
||||
}
|
||||
#endif
|
||||
|
||||
current_position.set(rx, ry);
|
||||
current_position.set(x, y);
|
||||
line_to_current_position(xy_feedrate);
|
||||
|
||||
// If Z needs to lower, do it after moving XY
|
||||
if (current_position.z > rz) {
|
||||
current_position.z = rz;
|
||||
line_to_current_position(z_feedrate);
|
||||
}
|
||||
#if HAS_Z_AXIS
|
||||
// If Z needs to lower, do it after moving XY
|
||||
if (current_position.z > z) {
|
||||
current_position.z = z;
|
||||
line_to_current_position(z_feedrate);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -546,53 +558,94 @@ void do_blocking_move_to(
|
||||
}
|
||||
|
||||
void do_blocking_move_to(const xy_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(LINEAR_AXIS_LIST(raw.x, raw.y, current_position.z, current_position.i), fr_mm_s);
|
||||
do_blocking_move_to(LINEAR_AXIS_LIST(raw.x, raw.y, current_position.z, current_position.i, current_position.j, current_position.k), fr_mm_s);
|
||||
}
|
||||
void do_blocking_move_to(const xyz_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(LINEAR_AXIS_LIST(raw.x, raw.y, raw.z), fr_mm_s);
|
||||
do_blocking_move_to(LINEAR_AXIS_ELEM(raw), fr_mm_s);
|
||||
}
|
||||
void do_blocking_move_to(const xyze_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(LINEAR_AXIS_LIST(raw.x, raw.y, raw.z), fr_mm_s);
|
||||
do_blocking_move_to(LINEAR_AXIS_ELEM(raw), fr_mm_s);
|
||||
}
|
||||
|
||||
void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(rx, current_position.y, current_position.z),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
void do_blocking_move_to_y(const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(current_position.x, ry, current_position.z),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
void do_blocking_move_to_z(const_float_t rz, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to_xy_z(current_position, rz, fr_mm_s);
|
||||
}
|
||||
|
||||
void do_blocking_move_to_xy(const_float_t rx, const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(rx, ry, current_position.z),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
void do_blocking_move_to_xy(const xy_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to_xy(raw.x, raw.y, fr_mm_s);
|
||||
}
|
||||
|
||||
void do_blocking_move_to_xy_z(const xy_pos_t &raw, const_float_t z, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(raw.x, raw.y, z),
|
||||
LINEAR_AXIS_LIST(rx, current_position.y, current_position.z, current_position.i, current_position.j, current_position.k),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
|
||||
void do_z_clearance(const_float_t zclear, const bool lower_allowed/*=false*/) {
|
||||
float zdest = zclear;
|
||||
if (!lower_allowed) NOLESS(zdest, current_position.z);
|
||||
do_blocking_move_to_z(_MIN(zdest, Z_MAX_POS), TERN(HAS_BED_PROBE, z_probe_fast_mm_s, homing_feedrate(Z_AXIS)));
|
||||
}
|
||||
#if HAS_Y_AXIS
|
||||
void do_blocking_move_to_y(const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(current_position.x, ry, current_position.z, current_position.i, current_position.j, current_position.k),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_Z_AXIS
|
||||
void do_blocking_move_to_z(const_float_t rz, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to_xy_z(current_position, rz, fr_mm_s);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINEAR_AXES == 4
|
||||
void do_blocking_move_to_i(const_float_t ri, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to_xyz_i(current_position, ri, fr_mm_s);
|
||||
}
|
||||
void do_blocking_move_to_xyz_i(const xyze_pos_t &raw, const_float_t i, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(raw.x, raw.y, raw.z, i, fr_mm_s);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINEAR_AXES >= 5
|
||||
void do_blocking_move_to_i(const_float_t ri, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to_xyz_i(current_position, ri, fr_mm_s);
|
||||
}
|
||||
void do_blocking_move_to_xyz_i(const xyze_pos_t &raw, const_float_t i, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(raw.x, raw.y, raw.z, i, raw.j, fr_mm_s);
|
||||
}
|
||||
void do_blocking_move_to_j(const_float_t rj, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to_xyzi_j(current_position, rj, fr_mm_s);
|
||||
}
|
||||
void do_blocking_move_to_xyzi_j(const xyze_pos_t &raw, const_float_t j, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(raw.x, raw.y, raw.z, raw.i, j, fr_mm_s);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINEAR_AXES >= 6
|
||||
void do_blocking_move_to_k(const_float_t rk, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to_xyzij_k(current_position, rk, fr_mm_s);
|
||||
}
|
||||
void do_blocking_move_to_xyzij_k(const xyze_pos_t &raw, const_float_t k, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(raw.x, raw.y, raw.z, raw.i, raw.j, k, fr_mm_s);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
void do_blocking_move_to_xy(const_float_t rx, const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(rx, ry, current_position.z, current_position.i, current_position.j, current_position.k),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
void do_blocking_move_to_xy(const xy_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to_xy(raw.x, raw.y, fr_mm_s);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_Z_AXIS
|
||||
void do_blocking_move_to_xy_z(const xy_pos_t &raw, const_float_t z, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(raw.x, raw.y, z, current_position.i, current_position.j, current_position.k),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
void do_z_clearance(const_float_t zclear, const bool lower_allowed/*=false*/) {
|
||||
float zdest = zclear;
|
||||
if (!lower_allowed) NOLESS(zdest, current_position.z);
|
||||
do_blocking_move_to_z(_MIN(zdest, Z_MAX_POS), TERN(HAS_BED_PROBE, z_probe_fast_mm_s, homing_feedrate(Z_AXIS)));
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Prepare to do endstop or probe moves with custom feedrates.
|
||||
@ -618,8 +671,8 @@ void restore_feedrate_and_scaling() {
|
||||
// Software Endstops are based on the configured limits.
|
||||
soft_endstops_t soft_endstop = {
|
||||
true, false,
|
||||
LINEAR_AXIS_ARRAY(X_MIN_POS, Y_MIN_POS, Z_MIN_POS),
|
||||
LINEAR_AXIS_ARRAY(X_MAX_BED, Y_MAX_BED, Z_MAX_POS)
|
||||
LINEAR_AXIS_ARRAY(X_MIN_POS, Y_MIN_POS, Z_MIN_POS, I_MIN_POS, J_MIN_POS, K_MIN_POS),
|
||||
LINEAR_AXIS_ARRAY(X_MAX_BED, Y_MAX_BED, Z_MAX_POS, I_MAX_POS, J_MAX_POS, K_MAX_POS)
|
||||
};
|
||||
|
||||
/**
|
||||
@ -746,25 +799,59 @@ void restore_feedrate_and_scaling() {
|
||||
#endif
|
||||
}
|
||||
|
||||
if (axis_was_homed(Y_AXIS)) {
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_Y)
|
||||
NOLESS(target.y, soft_endstop.min.y);
|
||||
#endif
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_Y)
|
||||
NOMORE(target.y, soft_endstop.max.y);
|
||||
#endif
|
||||
}
|
||||
#if HAS_Y_AXIS
|
||||
if (axis_was_homed(Y_AXIS)) {
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_Y)
|
||||
NOLESS(target.y, soft_endstop.min.y);
|
||||
#endif
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_Y)
|
||||
NOMORE(target.y, soft_endstop.max.y);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if (axis_was_homed(Z_AXIS)) {
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_Z)
|
||||
NOLESS(target.z, soft_endstop.min.z);
|
||||
#endif
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_Z)
|
||||
NOMORE(target.z, soft_endstop.max.z);
|
||||
#endif
|
||||
}
|
||||
#if HAS_Z_AXIS
|
||||
if (axis_was_homed(Z_AXIS)) {
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_Z)
|
||||
NOLESS(target.z, soft_endstop.min.z);
|
||||
#endif
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_Z)
|
||||
NOMORE(target.z, soft_endstop.max.z);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if LINEAR_AXES >= 4 // TODO (DerAndere): Find out why this was missing / removed
|
||||
if (axis_was_homed(I_AXIS)) {
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_I)
|
||||
NOLESS(target.i, soft_endstop.min.i);
|
||||
#endif
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_I)
|
||||
NOMORE(target.i, soft_endstop.max.i);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if LINEAR_AXES >= 5
|
||||
if (axis_was_homed(J_AXIS)) {
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_J)
|
||||
NOLESS(target.j, soft_endstop.min.j);
|
||||
#endif
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_J)
|
||||
NOMORE(target.j, soft_endstop.max.j);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if LINEAR_AXES >= 6
|
||||
if (axis_was_homed(K_AXIS)) {
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_K)
|
||||
NOLESS(target.k, soft_endstop.min.k);
|
||||
#endif
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_K)
|
||||
NOMORE(target.k, soft_endstop.max.k);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#else // !HAS_SOFTWARE_ENDSTOPS
|
||||
@ -824,7 +911,7 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
|
||||
|
||||
// If the move is only in Z/E don't split up the move
|
||||
if (!diff.x && !diff.y) {
|
||||
planner.buffer_line(destination, scaled_fr_mm_s, active_extruder);
|
||||
planner.buffer_line(destination, scaled_fr_mm_s);
|
||||
return false; // caller will update current_position
|
||||
}
|
||||
|
||||
@ -880,15 +967,11 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
|
||||
while (--segments) {
|
||||
segment_idle(next_idle_ms);
|
||||
raw += segment_distance;
|
||||
if (!planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, cartesian_segment_mm
|
||||
OPTARG(SCARA_FEEDRATE_SCALING, inv_duration)
|
||||
)) break;
|
||||
if (!planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, cartesian_segment_mm OPTARG(SCARA_FEEDRATE_SCALING, inv_duration))) break;
|
||||
}
|
||||
|
||||
// Ensure last segment arrives at target location.
|
||||
planner.buffer_line(destination, scaled_fr_mm_s, active_extruder, cartesian_segment_mm
|
||||
OPTARG(SCARA_FEEDRATE_SCALING, inv_duration)
|
||||
);
|
||||
planner.buffer_line(destination, scaled_fr_mm_s, active_extruder, cartesian_segment_mm OPTARG(SCARA_FEEDRATE_SCALING, inv_duration));
|
||||
|
||||
return false; // caller will update current_position
|
||||
}
|
||||
@ -910,7 +993,7 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
|
||||
|
||||
// If the move is only in Z/E don't split up the move
|
||||
if (!diff.x && !diff.y) {
|
||||
planner.buffer_line(destination, fr_mm_s, active_extruder);
|
||||
planner.buffer_line(destination, fr_mm_s);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -947,18 +1030,12 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
|
||||
while (--segments) {
|
||||
segment_idle(next_idle_ms);
|
||||
raw += segment_distance;
|
||||
if (!planner.buffer_line(raw, fr_mm_s, active_extruder, cartesian_segment_mm
|
||||
OPTARG(SCARA_FEEDRATE_SCALING, inv_duration)
|
||||
)) break;
|
||||
if (!planner.buffer_line(raw, fr_mm_s, active_extruder, cartesian_segment_mm OPTARG(SCARA_FEEDRATE_SCALING, inv_duration))) break;
|
||||
}
|
||||
|
||||
// Since segment_distance is only approximate,
|
||||
// the final move must be to the exact destination.
|
||||
planner.buffer_line(destination, fr_mm_s, active_extruder, cartesian_segment_mm
|
||||
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||
, inv_duration
|
||||
#endif
|
||||
);
|
||||
planner.buffer_line(destination, fr_mm_s, active_extruder, cartesian_segment_mm OPTARG(SCARA_FEEDRATE_SCALING, inv_duration));
|
||||
}
|
||||
|
||||
#endif // SEGMENT_LEVELED_MOVES
|
||||
@ -998,7 +1075,7 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
|
||||
}
|
||||
#endif // HAS_MESH
|
||||
|
||||
planner.buffer_line(destination, scaled_fr_mm_s, active_extruder);
|
||||
planner.buffer_line(destination, scaled_fr_mm_s);
|
||||
return false; // caller will update current_position
|
||||
}
|
||||
|
||||
@ -1080,12 +1157,12 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
|
||||
// Un-park the active extruder
|
||||
//
|
||||
const feedRate_t fr_zfast = planner.settings.max_feedrate_mm_s[Z_AXIS];
|
||||
#define CURPOS current_position
|
||||
#define RAISED raised_parked_position
|
||||
// 1. Move to the raised parked XYZ. Presumably the tool is already at XY.
|
||||
if (planner.buffer_line(RAISED.x, RAISED.y, RAISED.z, CURPOS.e, fr_zfast, active_extruder)) {
|
||||
xyze_pos_t raised = raised_parked_position; raised.e = current_position.e;
|
||||
if (planner.buffer_line(raised, fr_zfast)) {
|
||||
// 2. Move to the current native XY and raised Z. Presumably this is a null move.
|
||||
if (planner.buffer_line(CURPOS.x, CURPOS.y, RAISED.z, CURPOS.e, PLANNER_XY_FEEDRATE(), active_extruder)) {
|
||||
xyze_pos_t curpos = current_position; curpos.z = raised_parked_position.z;
|
||||
if (planner.buffer_line(curpos, PLANNER_XY_FEEDRATE())) {
|
||||
// 3. Lower Z back down
|
||||
line_to_current_position(fr_zfast);
|
||||
}
|
||||
@ -1099,21 +1176,24 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
|
||||
case DXC_MIRRORED_MODE:
|
||||
case DXC_DUPLICATION_MODE:
|
||||
if (active_extruder == 0) {
|
||||
xyze_pos_t new_pos = current_position;
|
||||
// Restore planner to parked head (T1) X position
|
||||
xyze_pos_t pos_now = current_position;
|
||||
pos_now.x = inactive_extruder_x;
|
||||
planner.set_position_mm(pos_now);
|
||||
|
||||
// Keep the same X or add the duplication X offset
|
||||
xyze_pos_t new_pos = pos_now;
|
||||
if (dual_x_carriage_mode == DXC_DUPLICATION_MODE)
|
||||
new_pos.x += duplicate_extruder_x_offset;
|
||||
else
|
||||
new_pos.x = inactive_extruder_x;
|
||||
// Move duplicate extruder into correct duplication position.
|
||||
|
||||
// Move duplicate extruder into the correct position
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Set planner X", inactive_extruder_x, " ... Line to X", new_pos.x);
|
||||
planner.set_position_mm(inactive_extruder_x, current_position.y, current_position.z, current_position.e);
|
||||
if (!planner.buffer_line(new_pos, planner.settings.max_feedrate_mm_s[X_AXIS], 1)) break;
|
||||
|
||||
planner.synchronize();
|
||||
sync_plan_position();
|
||||
|
||||
set_duplication_enabled(true);
|
||||
idex_set_parked(false);
|
||||
sync_plan_position(); // Extra sync for good measure
|
||||
set_duplication_enabled(true); // Enable Duplication
|
||||
idex_set_parked(false); // No longer parked
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("set_duplication_enabled(true)\nidex_set_parked(false)");
|
||||
}
|
||||
else if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Active extruder not 0");
|
||||
@ -1207,22 +1287,24 @@ void prepare_line_to_destination() {
|
||||
};
|
||||
// Clear test bits that are trusted
|
||||
LINEAR_AXIS_CODE(
|
||||
set_should(axis_bits, X_AXIS),
|
||||
set_should(axis_bits, Y_AXIS),
|
||||
set_should(axis_bits, Z_AXIS)
|
||||
set_should(axis_bits, X_AXIS), set_should(axis_bits, Y_AXIS), set_should(axis_bits, Z_AXIS),
|
||||
set_should(axis_bits, I_AXIS), set_should(axis_bits, J_AXIS), set_should(axis_bits, K_AXIS)
|
||||
);
|
||||
return axis_bits;
|
||||
}
|
||||
|
||||
bool homing_needed_error(linear_axis_bits_t axis_bits/*=linear_bits*/) {
|
||||
if ((axis_bits = axes_should_home(axis_bits))) {
|
||||
PGM_P home_first = GET_TEXT(MSG_HOME_FIRST);
|
||||
PGM_P home_first = GET_TEXT(MSG_HOME_FIRST); // TODO: (DerAndere) Set this up for extra axes
|
||||
char msg[strlen_P(home_first)+1];
|
||||
sprintf_P(msg, home_first,
|
||||
LINEAR_AXIS_LIST(
|
||||
TEST(axis_bits, X_AXIS) ? "X" : "",
|
||||
TEST(axis_bits, Y_AXIS) ? "Y" : "",
|
||||
TEST(axis_bits, Z_AXIS) ? "Z" : ""
|
||||
TEST(axis_bits, Z_AXIS) ? "Z" : "",
|
||||
TEST(axis_bits, I_AXIS) ? AXIS4_STR : "",
|
||||
TEST(axis_bits, J_AXIS) ? AXIS5_STR : "",
|
||||
TEST(axis_bits, K_AXIS) ? AXIS6_STR : ""
|
||||
)
|
||||
);
|
||||
SERIAL_ECHO_START();
|
||||
@ -1374,6 +1456,9 @@ void prepare_line_to_destination() {
|
||||
case X_AXIS: if (ENABLED(X_SPI_SENSORLESS)) endstops.tmc_spi_homing.x = false; break;
|
||||
case Y_AXIS: if (ENABLED(Y_SPI_SENSORLESS)) endstops.tmc_spi_homing.y = false; break;
|
||||
case Z_AXIS: if (ENABLED(Z_SPI_SENSORLESS)) endstops.tmc_spi_homing.z = false; break;
|
||||
case I_AXIS: if (ENABLED(I_SPI_SENSORLESS)) endstops.tmc_spi_homing.i = false; break;
|
||||
case J_AXIS: if (ENABLED(J_SPI_SENSORLESS)) endstops.tmc_spi_homing.j = false; break;
|
||||
case K_AXIS: if (ENABLED(K_SPI_SENSORLESS)) endstops.tmc_spi_homing.k = false; break;
|
||||
default: break;
|
||||
}
|
||||
#endif
|
||||
@ -1446,12 +1531,7 @@ void prepare_line_to_destination() {
|
||||
|
||||
// Set delta/cartesian axes directly
|
||||
target[axis] = distance; // The move will be towards the endstop
|
||||
planner.buffer_segment(target
|
||||
#if HAS_DIST_MM_ARG
|
||||
, cart_dist_mm
|
||||
#endif
|
||||
, home_fr_mm_s, active_extruder
|
||||
);
|
||||
planner.buffer_segment(target OPTARG(HAS_DIST_MM_ARG, cart_dist_mm), home_fr_mm_s, active_extruder);
|
||||
#endif
|
||||
|
||||
planner.synchronize();
|
||||
@ -1531,6 +1611,30 @@ void prepare_line_to_destination() {
|
||||
stepperBackoutDir = INVERT_Z_DIR ? effectorBackoutDir : -effectorBackoutDir;
|
||||
break;
|
||||
#endif
|
||||
#ifdef I_MICROSTEPS
|
||||
case I_AXIS:
|
||||
phasePerUStep = PHASE_PER_MICROSTEP(I);
|
||||
phaseCurrent = stepperI.get_microstep_counter();
|
||||
effectorBackoutDir = -I_HOME_DIR;
|
||||
stepperBackoutDir = INVERT_I_DIR ? effectorBackoutDir : -effectorBackoutDir;
|
||||
break;
|
||||
#endif
|
||||
#ifdef J_MICROSTEPS
|
||||
case J_AXIS:
|
||||
phasePerUStep = PHASE_PER_MICROSTEP(J);
|
||||
phaseCurrent = stepperJ.get_microstep_counter();
|
||||
effectorBackoutDir = -J_HOME_DIR;
|
||||
stepperBackoutDir = INVERT_J_DIR ? effectorBackoutDir : -effectorBackoutDir;
|
||||
break;
|
||||
#endif
|
||||
#ifdef K_MICROSTEPS
|
||||
case K_AXIS:
|
||||
phasePerUStep = PHASE_PER_MICROSTEP(K);
|
||||
phaseCurrent = stepperK.get_microstep_counter();
|
||||
effectorBackoutDir = -K_HOME_DIR;
|
||||
stepperBackoutDir = INVERT_K_DIR ? effectorBackoutDir : -effectorBackoutDir;
|
||||
break;
|
||||
#endif
|
||||
default: return;
|
||||
}
|
||||
|
||||
@ -1583,11 +1687,18 @@ void prepare_line_to_destination() {
|
||||
#else
|
||||
#define _CAN_HOME(A) (axis == _AXIS(A) && ( \
|
||||
ENABLED(A##_SPI_SENSORLESS) \
|
||||
|| (_AXIS(A) == Z_AXIS && ENABLED(HOMING_Z_WITH_PROBE)) \
|
||||
|| TERN0(HAS_Z_AXIS, TERN0(HOMING_Z_WITH_PROBE, _AXIS(A) == Z_AXIS)) \
|
||||
|| TERN0(A##_HOME_TO_MIN, A##_MIN_PIN > -1) \
|
||||
|| TERN0(A##_HOME_TO_MAX, A##_MAX_PIN > -1) \
|
||||
))
|
||||
if (!_CAN_HOME(X) && !_CAN_HOME(Y) && !_CAN_HOME(Z)) return;
|
||||
if (LINEAR_AXIS_GANG(
|
||||
!_CAN_HOME(X),
|
||||
&& !_CAN_HOME(Y),
|
||||
&& !_CAN_HOME(Z),
|
||||
&& !_CAN_HOME(I),
|
||||
&& !_CAN_HOME(J),
|
||||
&& !_CAN_HOME(K))
|
||||
) return;
|
||||
#endif
|
||||
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(">>> homeaxis(", AS_CHAR(AXIS_CHAR(axis)), ")");
|
||||
@ -1636,9 +1747,9 @@ void prepare_line_to_destination() {
|
||||
|
||||
// Determine if a homing bump will be done and the bumps distance
|
||||
// When homing Z with probe respect probe clearance
|
||||
const bool use_probe_bump = TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && home_bump_mm(Z_AXIS));
|
||||
const bool use_probe_bump = TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && home_bump_mm(axis));
|
||||
const float bump = axis_home_dir * (
|
||||
use_probe_bump ? _MAX(TERN0(HOMING_Z_WITH_PROBE, Z_CLEARANCE_BETWEEN_PROBES), home_bump_mm(Z_AXIS)) : home_bump_mm(axis)
|
||||
use_probe_bump ? _MAX(TERN0(HOMING_Z_WITH_PROBE, Z_CLEARANCE_BETWEEN_PROBES), home_bump_mm(axis)) : home_bump_mm(axis)
|
||||
);
|
||||
|
||||
//
|
||||
|
Reference in New Issue
Block a user