mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2024-11-27 05:48:43 +00:00
Fix and improve software endstops (#13386)
This commit is contained in:
parent
6214c997c0
commit
87162658c4
@ -328,8 +328,8 @@ bool I2CPositionEncoder::test_axis() {
|
|||||||
|
|
||||||
float startCoord[NUM_AXIS] = { 0 }, endCoord[NUM_AXIS] = { 0 };
|
float startCoord[NUM_AXIS] = { 0 }, endCoord[NUM_AXIS] = { 0 };
|
||||||
|
|
||||||
const float startPosition = soft_endstop_min[encoderAxis] + 10,
|
const float startPosition = soft_endstop[encoderAxis].min + 10,
|
||||||
endPosition = soft_endstop_max[encoderAxis] - 10,
|
endPosition = soft_endstop[encoderAxis].max - 10,
|
||||||
feedrate = FLOOR(MMM_TO_MMS((encoderAxis == Z_AXIS) ? HOMING_FEEDRATE_Z : HOMING_FEEDRATE_XY));
|
feedrate = FLOOR(MMM_TO_MMS((encoderAxis == Z_AXIS) ? HOMING_FEEDRATE_Z : HOMING_FEEDRATE_XY));
|
||||||
|
|
||||||
ec = false;
|
ec = false;
|
||||||
@ -390,7 +390,7 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
|
|||||||
ec = false;
|
ec = false;
|
||||||
|
|
||||||
startDistance = 20;
|
startDistance = 20;
|
||||||
endDistance = soft_endstop_max[encoderAxis] - 20;
|
endDistance = soft_endstop[encoderAxis].max - 20;
|
||||||
travelDistance = endDistance - startDistance;
|
travelDistance = endDistance - startDistance;
|
||||||
|
|
||||||
LOOP_NA(i) {
|
LOOP_NA(i) {
|
||||||
|
@ -212,7 +212,7 @@ G29_TYPE GcodeSuite::G29() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_SOFTWARE_ENDSTOPS && ENABLED(PROBE_MANUALLY)
|
#if HAS_SOFTWARE_ENDSTOPS && ENABLED(PROBE_MANUALLY)
|
||||||
ABL_VAR bool enable_soft_endstops = true;
|
ABL_VAR bool saved_soft_endstops_state = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ABL_GRID
|
#if ABL_GRID
|
||||||
@ -494,7 +494,7 @@ G29_TYPE GcodeSuite::G29() {
|
|||||||
if (seenA && g29_in_progress) {
|
if (seenA && g29_in_progress) {
|
||||||
SERIAL_ECHOLNPGM("Manual G29 aborted");
|
SERIAL_ECHOLNPGM("Manual G29 aborted");
|
||||||
#if HAS_SOFTWARE_ENDSTOPS
|
#if HAS_SOFTWARE_ENDSTOPS
|
||||||
soft_endstops_enabled = enable_soft_endstops;
|
soft_endstops_enabled = saved_soft_endstops_state;
|
||||||
#endif
|
#endif
|
||||||
set_bed_leveling_enabled(abl_should_enable);
|
set_bed_leveling_enabled(abl_should_enable);
|
||||||
g29_in_progress = false;
|
g29_in_progress = false;
|
||||||
@ -519,7 +519,7 @@ G29_TYPE GcodeSuite::G29() {
|
|||||||
if (abl_probe_index == 0) {
|
if (abl_probe_index == 0) {
|
||||||
// For the initial G29 S2 save software endstop state
|
// For the initial G29 S2 save software endstop state
|
||||||
#if HAS_SOFTWARE_ENDSTOPS
|
#if HAS_SOFTWARE_ENDSTOPS
|
||||||
enable_soft_endstops = soft_endstops_enabled;
|
saved_soft_endstops_state = soft_endstops_enabled;
|
||||||
#endif
|
#endif
|
||||||
// Move close to the bed before the first point
|
// Move close to the bed before the first point
|
||||||
do_blocking_move_to_z(0);
|
do_blocking_move_to_z(0);
|
||||||
@ -617,7 +617,7 @@ G29_TYPE GcodeSuite::G29() {
|
|||||||
|
|
||||||
// Re-enable software endstops, if needed
|
// Re-enable software endstops, if needed
|
||||||
#if HAS_SOFTWARE_ENDSTOPS
|
#if HAS_SOFTWARE_ENDSTOPS
|
||||||
soft_endstops_enabled = enable_soft_endstops;
|
soft_endstops_enabled = saved_soft_endstops_state;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -641,7 +641,7 @@ G29_TYPE GcodeSuite::G29() {
|
|||||||
|
|
||||||
// Re-enable software endstops, if needed
|
// Re-enable software endstops, if needed
|
||||||
#if HAS_SOFTWARE_ENDSTOPS
|
#if HAS_SOFTWARE_ENDSTOPS
|
||||||
soft_endstops_enabled = enable_soft_endstops;
|
soft_endstops_enabled = saved_soft_endstops_state;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!dryrun) {
|
if (!dryrun) {
|
||||||
|
@ -59,7 +59,7 @@ void GcodeSuite::G29() {
|
|||||||
|
|
||||||
static int mbl_probe_index = -1;
|
static int mbl_probe_index = -1;
|
||||||
#if HAS_SOFTWARE_ENDSTOPS
|
#if HAS_SOFTWARE_ENDSTOPS
|
||||||
static bool enable_soft_endstops;
|
static bool saved_soft_endstops_state;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MeshLevelingState state = (MeshLevelingState)parser.byteval('S', (int8_t)MeshReport);
|
MeshLevelingState state = (MeshLevelingState)parser.byteval('S', (int8_t)MeshReport);
|
||||||
@ -99,7 +99,7 @@ void GcodeSuite::G29() {
|
|||||||
if (mbl_probe_index == 0) {
|
if (mbl_probe_index == 0) {
|
||||||
#if HAS_SOFTWARE_ENDSTOPS
|
#if HAS_SOFTWARE_ENDSTOPS
|
||||||
// For the initial G29 S2 save software endstop state
|
// For the initial G29 S2 save software endstop state
|
||||||
enable_soft_endstops = soft_endstops_enabled;
|
saved_soft_endstops_state = soft_endstops_enabled;
|
||||||
#endif
|
#endif
|
||||||
// Move close to the bed before the first point
|
// Move close to the bed before the first point
|
||||||
do_blocking_move_to_z(0);
|
do_blocking_move_to_z(0);
|
||||||
@ -108,7 +108,7 @@ void GcodeSuite::G29() {
|
|||||||
// Save Z for the previous mesh position
|
// Save Z for the previous mesh position
|
||||||
mbl.set_zigzag_z(mbl_probe_index - 1, current_position[Z_AXIS]);
|
mbl.set_zigzag_z(mbl_probe_index - 1, current_position[Z_AXIS]);
|
||||||
#if HAS_SOFTWARE_ENDSTOPS
|
#if HAS_SOFTWARE_ENDSTOPS
|
||||||
soft_endstops_enabled = enable_soft_endstops;
|
soft_endstops_enabled = saved_soft_endstops_state;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// If there's another point to sample, move there with optional lift.
|
// If there's another point to sample, move there with optional lift.
|
||||||
|
@ -38,13 +38,13 @@ void GcodeSuite::M211() {
|
|||||||
if (parser.seen('S')) soft_endstops_enabled = parser.value_bool();
|
if (parser.seen('S')) soft_endstops_enabled = parser.value_bool();
|
||||||
serialprint_onoff(soft_endstops_enabled);
|
serialprint_onoff(soft_endstops_enabled);
|
||||||
SERIAL_ECHOPGM(MSG_SOFT_MIN);
|
SERIAL_ECHOPGM(MSG_SOFT_MIN);
|
||||||
SERIAL_ECHOPAIR( MSG_X, LOGICAL_X_POSITION(soft_endstop_min[X_AXIS]));
|
SERIAL_ECHOPAIR( MSG_X, LOGICAL_X_POSITION(soft_endstop[X_AXIS].min));
|
||||||
SERIAL_ECHOPAIR(" " MSG_Y, LOGICAL_Y_POSITION(soft_endstop_min[Y_AXIS]));
|
SERIAL_ECHOPAIR(" " MSG_Y, LOGICAL_Y_POSITION(soft_endstop[Y_AXIS].min));
|
||||||
SERIAL_ECHOPAIR(" " MSG_Z, LOGICAL_Z_POSITION(soft_endstop_min[Z_AXIS]));
|
SERIAL_ECHOPAIR(" " MSG_Z, LOGICAL_Z_POSITION(soft_endstop[Z_AXIS].min));
|
||||||
SERIAL_ECHOPGM(MSG_SOFT_MAX);
|
SERIAL_ECHOPGM(MSG_SOFT_MAX);
|
||||||
SERIAL_ECHOPAIR( MSG_X, LOGICAL_X_POSITION(soft_endstop_max[X_AXIS]));
|
SERIAL_ECHOPAIR( MSG_X, LOGICAL_X_POSITION(soft_endstop[X_AXIS].max));
|
||||||
SERIAL_ECHOPAIR(" " MSG_Y, LOGICAL_Y_POSITION(soft_endstop_max[Y_AXIS]));
|
SERIAL_ECHOPAIR(" " MSG_Y, LOGICAL_Y_POSITION(soft_endstop[Y_AXIS].max));
|
||||||
SERIAL_ECHOLNPAIR(" " MSG_Z, LOGICAL_Z_POSITION(soft_endstop_max[Z_AXIS]));
|
SERIAL_ECHOLNPAIR(" " MSG_Z, LOGICAL_Z_POSITION(soft_endstop[Z_AXIS].max));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -127,7 +127,7 @@ void GcodeSuite::M240() {
|
|||||||
parser.seenval('Y') ? RAW_Y_POSITION(parser.value_linear_units()) : photo_position[Y_AXIS],
|
parser.seenval('Y') ? RAW_Y_POSITION(parser.value_linear_units()) : photo_position[Y_AXIS],
|
||||||
(parser.seenval('Z') ? parser.value_linear_units() : photo_position[Z_AXIS]) + current_position[Z_AXIS]
|
(parser.seenval('Z') ? parser.value_linear_units() : photo_position[Z_AXIS]) + current_position[Z_AXIS]
|
||||||
};
|
};
|
||||||
clamp_to_software_endstops(raw);
|
apply_motion_limits(raw);
|
||||||
do_blocking_move_to(raw, fr_mm_s);
|
do_blocking_move_to(raw, fr_mm_s);
|
||||||
|
|
||||||
#ifdef PHOTO_SWITCH_POSITION
|
#ifdef PHOTO_SWITCH_POSITION
|
||||||
|
@ -190,7 +190,7 @@ void plan_arc(
|
|||||||
#endif
|
#endif
|
||||||
raw[E_AXIS] += extruder_per_segment;
|
raw[E_AXIS] += extruder_per_segment;
|
||||||
|
|
||||||
clamp_to_software_endstops(raw);
|
apply_motion_limits(raw);
|
||||||
|
|
||||||
#if HAS_LEVELING && !PLANNER_LEVELING
|
#if HAS_LEVELING && !PLANNER_LEVELING
|
||||||
planner.apply_leveling(raw);
|
planner.apply_leveling(raw);
|
||||||
|
@ -2121,3 +2121,14 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
|
|||||||
#error "Both SERVICE_NAME_3 and SERVICE_INTERVAL_3 are required."
|
#error "Both SERVICE_NAME_3 and SERVICE_INTERVAL_3 are required."
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Require soft endstops for certain setups
|
||||||
|
*/
|
||||||
|
#if DISABLED(MIN_SOFTWARE_ENDSTOPS) || DISABLED(MAX_SOFTWARE_ENDSTOPS)
|
||||||
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
#error "DUAL_X_CARRIAGE requires both MIN_ and MAX_SOFTWARE_ENDSTOPS."
|
||||||
|
#elif HAS_HOTEND_OFFSET
|
||||||
|
#error "MIN_ and MAX_SOFTWARE_ENDSTOPS are both required with offset hotends."
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
@ -213,26 +213,26 @@ namespace ExtUI {
|
|||||||
if (soft_endstops_enabled) switch (axis) {
|
if (soft_endstops_enabled) switch (axis) {
|
||||||
case X_AXIS:
|
case X_AXIS:
|
||||||
#if ENABLED(MIN_SOFTWARE_ENDSTOP_X)
|
#if ENABLED(MIN_SOFTWARE_ENDSTOP_X)
|
||||||
min = soft_endstop_min[X_AXIS];
|
min = soft_endstop[X_AXIS].min;
|
||||||
#endif
|
#endif
|
||||||
#if ENABLED(MAX_SOFTWARE_ENDSTOP_X)
|
#if ENABLED(MAX_SOFTWARE_ENDSTOP_X)
|
||||||
max = soft_endstop_max[X_AXIS];
|
max = soft_endstop[X_AXIS].max;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case Y_AXIS:
|
case Y_AXIS:
|
||||||
#if ENABLED(MIN_SOFTWARE_ENDSTOP_Y)
|
#if ENABLED(MIN_SOFTWARE_ENDSTOP_Y)
|
||||||
min = soft_endstop_min[Y_AXIS];
|
min = soft_endstop[Y_AXIS].min;
|
||||||
#endif
|
#endif
|
||||||
#if ENABLED(MAX_SOFTWARE_ENDSTOP_Y)
|
#if ENABLED(MAX_SOFTWARE_ENDSTOP_Y)
|
||||||
max = soft_endstop_max[Y_AXIS];
|
max = soft_endstop[Y_AXIS].max;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case Z_AXIS:
|
case Z_AXIS:
|
||||||
#if ENABLED(MIN_SOFTWARE_ENDSTOP_Z)
|
#if ENABLED(MIN_SOFTWARE_ENDSTOP_Z)
|
||||||
min = soft_endstop_min[Z_AXIS];
|
min = soft_endstop[Z_AXIS].min;
|
||||||
#endif
|
#endif
|
||||||
#if ENABLED(MAX_SOFTWARE_ENDSTOP_Z)
|
#if ENABLED(MAX_SOFTWARE_ENDSTOP_Z)
|
||||||
max = soft_endstop_max[Z_AXIS];
|
max = soft_endstop[Z_AXIS].max;
|
||||||
#endif
|
#endif
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
@ -86,26 +86,26 @@ static void _lcd_move_xyz(PGM_P name, AxisEnum axis) {
|
|||||||
if (soft_endstops_enabled) switch (axis) {
|
if (soft_endstops_enabled) switch (axis) {
|
||||||
case X_AXIS:
|
case X_AXIS:
|
||||||
#if ENABLED(MIN_SOFTWARE_ENDSTOP_X)
|
#if ENABLED(MIN_SOFTWARE_ENDSTOP_X)
|
||||||
min = soft_endstop_min[X_AXIS];
|
min = soft_endstop[X_AXIS].min;
|
||||||
#endif
|
#endif
|
||||||
#if ENABLED(MAX_SOFTWARE_ENDSTOP_X)
|
#if ENABLED(MAX_SOFTWARE_ENDSTOP_X)
|
||||||
max = soft_endstop_max[X_AXIS];
|
max = soft_endstop[X_AXIS].max;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case Y_AXIS:
|
case Y_AXIS:
|
||||||
#if ENABLED(MIN_SOFTWARE_ENDSTOP_Y)
|
#if ENABLED(MIN_SOFTWARE_ENDSTOP_Y)
|
||||||
min = soft_endstop_min[Y_AXIS];
|
min = soft_endstop[Y_AXIS].min;
|
||||||
#endif
|
#endif
|
||||||
#if ENABLED(MAX_SOFTWARE_ENDSTOP_Y)
|
#if ENABLED(MAX_SOFTWARE_ENDSTOP_Y)
|
||||||
max = soft_endstop_max[Y_AXIS];
|
max = soft_endstop[Y_AXIS].max;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case Z_AXIS:
|
case Z_AXIS:
|
||||||
#if ENABLED(MIN_SOFTWARE_ENDSTOP_Z)
|
#if ENABLED(MIN_SOFTWARE_ENDSTOP_Z)
|
||||||
min = soft_endstop_min[Z_AXIS];
|
min = soft_endstop[Z_AXIS].min;
|
||||||
#endif
|
#endif
|
||||||
#if ENABLED(MAX_SOFTWARE_ENDSTOP_Z)
|
#if ENABLED(MAX_SOFTWARE_ENDSTOP_Z)
|
||||||
max = soft_endstop_max[Z_AXIS];
|
max = soft_endstop[Z_AXIS].max;
|
||||||
#endif
|
#endif
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
@ -149,13 +149,13 @@ float cartes[XYZ];
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_SOFTWARE_ENDSTOPS
|
#if HAS_SOFTWARE_ENDSTOPS
|
||||||
float soft_endstop_radius, soft_endstop_radius_2;
|
float delta_max_radius, delta_max_radius_2;
|
||||||
#elif IS_SCARA
|
#elif IS_SCARA
|
||||||
constexpr float soft_endstop_radius = SCARA_PRINTABLE_RADIUS,
|
constexpr float delta_max_radius = SCARA_PRINTABLE_RADIUS,
|
||||||
soft_endstop_radius_2 = sq(SCARA_PRINTABLE_RADIUS);
|
delta_max_radius_2 = sq(SCARA_PRINTABLE_RADIUS);
|
||||||
#else // DELTA
|
#else // DELTA
|
||||||
constexpr float soft_endstop_radius = DELTA_PRINTABLE_RADIUS,
|
constexpr float delta_max_radius = DELTA_PRINTABLE_RADIUS,
|
||||||
soft_endstop_radius_2 = sq(DELTA_PRINTABLE_RADIUS);
|
delta_max_radius_2 = sq(DELTA_PRINTABLE_RADIUS);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -460,8 +460,7 @@ void clean_up_after_endstop_or_probe_move() {
|
|||||||
bool soft_endstops_enabled = true;
|
bool soft_endstops_enabled = true;
|
||||||
|
|
||||||
// Software Endstops are based on the configured limits.
|
// Software Endstops are based on the configured limits.
|
||||||
float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
|
axis_limits_t soft_endstop[XYZ] = { { X_MIN_BED, X_MAX_BED }, { Y_MIN_BED, Y_MAX_BED }, { Z_MIN_POS, Z_MAX_POS } };
|
||||||
soft_endstop_max[XYZ] = { X_MAX_BED, Y_MAX_BED, Z_MAX_POS };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Software endstops can be used to monitor the open end of
|
* Software endstops can be used to monitor the open end of
|
||||||
@ -487,26 +486,27 @@ void clean_up_after_endstop_or_probe_move() {
|
|||||||
|
|
||||||
if (new_tool_index != 0) {
|
if (new_tool_index != 0) {
|
||||||
// T1 can move from X2_MIN_POS to X2_MAX_POS or X2 home position (whichever is larger)
|
// T1 can move from X2_MIN_POS to X2_MAX_POS or X2 home position (whichever is larger)
|
||||||
soft_endstop_min[X_AXIS] = X2_MIN_POS;
|
soft_endstop[X_AXIS].min = X2_MIN_POS;
|
||||||
soft_endstop_max[X_AXIS] = dual_max_x;
|
soft_endstop[X_AXIS].max = dual_max_x;
|
||||||
}
|
}
|
||||||
else if (dxc_is_duplicating()) {
|
else if (dxc_is_duplicating()) {
|
||||||
// In Duplication Mode, T0 can move as far left as X1_MIN_POS
|
// In Duplication Mode, T0 can move as far left as X1_MIN_POS
|
||||||
// but not so far to the right that T1 would move past the end
|
// but not so far to the right that T1 would move past the end
|
||||||
soft_endstop_min[X_AXIS] = X1_MIN_POS;
|
soft_endstop[X_AXIS].min = X1_MIN_POS;
|
||||||
soft_endstop_max[X_AXIS] = MIN(X1_MAX_POS, dual_max_x - duplicate_extruder_x_offset);
|
soft_endstop[X_AXIS].max = MIN(X1_MAX_POS, dual_max_x - duplicate_extruder_x_offset);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// In other modes, T0 can move from X1_MIN_POS to X1_MAX_POS
|
// In other modes, T0 can move from X1_MIN_POS to X1_MAX_POS
|
||||||
soft_endstop_min[X_AXIS] = X1_MIN_POS;
|
soft_endstop[X_AXIS].min = X1_MIN_POS;
|
||||||
soft_endstop_max[X_AXIS] = X1_MAX_POS;
|
soft_endstop[X_AXIS].max = X1_MAX_POS;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif ENABLED(DELTA)
|
#elif ENABLED(DELTA)
|
||||||
|
|
||||||
soft_endstop_min[axis] = base_min_pos(axis);
|
soft_endstop[axis].min = base_min_pos(axis);
|
||||||
soft_endstop_max[axis] = (axis == Z_AXIS ? delta_height
|
soft_endstop[axis].max = (axis == Z_AXIS ? delta_height
|
||||||
#if HAS_BED_PROBE
|
#if HAS_BED_PROBE
|
||||||
- zprobe_zoffset
|
- zprobe_zoffset
|
||||||
#endif
|
#endif
|
||||||
@ -516,11 +516,11 @@ void clean_up_after_endstop_or_probe_move() {
|
|||||||
case X_AXIS:
|
case X_AXIS:
|
||||||
case Y_AXIS:
|
case Y_AXIS:
|
||||||
// Get a minimum radius for clamping
|
// Get a minimum radius for clamping
|
||||||
soft_endstop_radius = MIN(ABS(MAX(soft_endstop_min[X_AXIS], soft_endstop_min[Y_AXIS])), soft_endstop_max[X_AXIS], soft_endstop_max[Y_AXIS]);
|
delta_max_radius = MIN(ABS(MAX(soft_endstop[X_AXIS].min, soft_endstop[Y_AXIS].min)), soft_endstop[X_AXIS].max, soft_endstop[Y_AXIS].max);
|
||||||
soft_endstop_radius_2 = sq(soft_endstop_radius);
|
delta_max_radius_2 = sq(delta_max_radius);
|
||||||
break;
|
break;
|
||||||
case Z_AXIS:
|
case Z_AXIS:
|
||||||
delta_clip_start_height = soft_endstop_max[axis] - delta_safe_distance_from_top();
|
delta_clip_start_height = soft_endstop[axis].max - delta_safe_distance_from_top();
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,85 +531,82 @@ void clean_up_after_endstop_or_probe_move() {
|
|||||||
// retain the same physical limit when other tools are selected.
|
// retain the same physical limit when other tools are selected.
|
||||||
if (old_tool_index != new_tool_index) {
|
if (old_tool_index != new_tool_index) {
|
||||||
const float offs = hotend_offset[axis][new_tool_index] - hotend_offset[axis][old_tool_index];
|
const float offs = hotend_offset[axis][new_tool_index] - hotend_offset[axis][old_tool_index];
|
||||||
soft_endstop_min[axis] += offs;
|
soft_endstop[axis].min += offs;
|
||||||
soft_endstop_max[axis] += offs;
|
soft_endstop[axis].max += offs;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const float offs = hotend_offset[axis][active_extruder];
|
const float offs = hotend_offset[axis][active_extruder];
|
||||||
soft_endstop_min[axis] = base_min_pos(axis) + offs;
|
soft_endstop[axis].min = base_min_pos(axis) + offs;
|
||||||
soft_endstop_max[axis] = base_max_pos(axis) + offs;
|
soft_endstop[axis].max = base_max_pos(axis) + offs;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
soft_endstop_min[axis] = base_min_pos(axis);
|
soft_endstop[axis].min = base_min_pos(axis);
|
||||||
soft_endstop_max[axis] = base_max_pos(axis);
|
soft_endstop[axis].max = base_max_pos(axis);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) {
|
if (DEBUGGING(LEVELING))
|
||||||
SERIAL_ECHOPAIR("For ", axis_codes[axis]);
|
SERIAL_ECHOLNPAIR("Axis ", axis_codes[axis], " min:", soft_endstop[axis].min, " max:", soft_endstop[axis].max);
|
||||||
SERIAL_ECHOPAIR(" axis:\n soft_endstop_min = ", soft_endstop_min[axis]);
|
#endif
|
||||||
SERIAL_ECHOLNPAIR("\n soft_endstop_max = ", soft_endstop_max[axis]);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constrain the given coordinates to the software endstops.
|
||||||
|
*
|
||||||
|
* For DELTA/SCARA the XY constraint is based on the smallest
|
||||||
|
* radius within the set software endstops.
|
||||||
|
*/
|
||||||
|
void apply_motion_limits(float target[XYZ]) {
|
||||||
|
|
||||||
|
if (!soft_endstops_enabled) return;
|
||||||
|
|
||||||
|
#if IS_KINEMATIC
|
||||||
|
|
||||||
|
#if HAS_HOTEND_OFFSET && ENABLED(DELTA)
|
||||||
|
// The effector center position will be the target minus the hotend offset.
|
||||||
|
const float offx = hotend_offset[X_AXIS][active_extruder], offy = hotend_offset[Y_AXIS][active_extruder];
|
||||||
|
#else
|
||||||
|
// SCARA needs to consider the angle of the arm through the entire move, so for now use no tool offset.
|
||||||
|
constexpr float offx = 0, offy = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const float dist_2 = HYPOT2(target[X_AXIS] - offx, target[Y_AXIS] - offy);
|
||||||
|
if (dist_2 > delta_max_radius_2) {
|
||||||
|
const float ratio = (delta_max_radius) / SQRT(dist_2); // 200 / 300 = 0.66
|
||||||
|
target[X_AXIS] *= ratio;
|
||||||
|
target[Y_AXIS] *= ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_X)
|
||||||
|
NOLESS(target[X_AXIS], soft_endstop[X_AXIS].min);
|
||||||
|
#endif
|
||||||
|
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_X)
|
||||||
|
NOMORE(target[X_AXIS], soft_endstop[X_AXIS].max);
|
||||||
|
#endif
|
||||||
|
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_Y)
|
||||||
|
NOLESS(target[Y_AXIS], soft_endstop[Y_AXIS].min);
|
||||||
|
#endif
|
||||||
|
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_Y)
|
||||||
|
NOMORE(target[Y_AXIS], soft_endstop[Y_AXIS].max);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_Z)
|
||||||
|
NOLESS(target[Z_AXIS], soft_endstop[Z_AXIS].min);
|
||||||
|
#endif
|
||||||
|
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_Z)
|
||||||
|
NOMORE(target[Z_AXIS], soft_endstop[Z_AXIS].max);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAS_SOFTWARE_ENDSTOPS
|
#endif // HAS_SOFTWARE_ENDSTOPS
|
||||||
|
|
||||||
/**
|
|
||||||
* Constrain the given coordinates to the software endstops.
|
|
||||||
*
|
|
||||||
* For DELTA/SCARA the XY constraint is based on the smallest
|
|
||||||
* radius within the set software endstops.
|
|
||||||
*/
|
|
||||||
void clamp_to_software_endstops(float target[XYZ]) {
|
|
||||||
|
|
||||||
if (!soft_endstops_enabled) return;
|
|
||||||
|
|
||||||
#if IS_KINEMATIC
|
|
||||||
|
|
||||||
#if HAS_HOTEND_OFFSET && ENABLED(DELTA)
|
|
||||||
// The effector center position will be the target minus the hotend offset.
|
|
||||||
const float offx = hotend_offset[X_AXIS][active_extruder], offy = hotend_offset[Y_AXIS][active_extruder];
|
|
||||||
#else
|
|
||||||
// SCARA needs to consider the angle of the arm through the entire move, so for now use no tool offset.
|
|
||||||
constexpr float offx = 0, offy = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const float dist_2 = HYPOT2(target[X_AXIS] - offx, target[Y_AXIS] - offy);
|
|
||||||
if (dist_2 > soft_endstop_radius_2) {
|
|
||||||
const float ratio = (soft_endstop_radius) / SQRT(dist_2); // 200 / 300 = 0.66
|
|
||||||
target[X_AXIS] *= ratio;
|
|
||||||
target[Y_AXIS] *= ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_X)
|
|
||||||
NOLESS(target[X_AXIS], soft_endstop_min[X_AXIS]);
|
|
||||||
#endif
|
|
||||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_X)
|
|
||||||
NOMORE(target[X_AXIS], soft_endstop_max[X_AXIS]);
|
|
||||||
#endif
|
|
||||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_Y)
|
|
||||||
NOLESS(target[Y_AXIS], soft_endstop_min[Y_AXIS]);
|
|
||||||
#endif
|
|
||||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_Y)
|
|
||||||
NOMORE(target[Y_AXIS], soft_endstop_max[Y_AXIS]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_Z)
|
|
||||||
NOLESS(target[Z_AXIS], soft_endstop_min[Z_AXIS]);
|
|
||||||
#endif
|
|
||||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_Z)
|
|
||||||
NOMORE(target[Z_AXIS], soft_endstop_max[Z_AXIS]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !UBL_SEGMENTED
|
#if !UBL_SEGMENTED
|
||||||
#if IS_KINEMATIC
|
#if IS_KINEMATIC
|
||||||
|
|
||||||
@ -995,7 +992,7 @@ void clamp_to_software_endstops(float target[XYZ]) {
|
|||||||
* before calling or cold/lengthy extrusion may get missed.
|
* before calling or cold/lengthy extrusion may get missed.
|
||||||
*/
|
*/
|
||||||
void prepare_move_to_destination() {
|
void prepare_move_to_destination() {
|
||||||
clamp_to_software_endstops(destination);
|
apply_motion_limits(destination);
|
||||||
|
|
||||||
#if ENABLED(PREVENT_COLD_EXTRUSION) || ENABLED(PREVENT_LENGTHY_EXTRUDE)
|
#if ENABLED(PREVENT_COLD_EXTRUSION) || ENABLED(PREVENT_LENGTHY_EXTRUDE)
|
||||||
|
|
||||||
|
@ -118,23 +118,23 @@ XYZ_DEFS(signed char, home_dir, HOME_DIR);
|
|||||||
constexpr float hotend_offset[XYZ][HOTENDS] = { { 0 }, { 0 }, { 0 } };
|
constexpr float hotend_offset[XYZ][HOTENDS] = { { 0 }, { 0 }, { 0 } };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct { float min, max; } axis_limits_t;
|
||||||
#if HAS_SOFTWARE_ENDSTOPS
|
#if HAS_SOFTWARE_ENDSTOPS
|
||||||
extern bool soft_endstops_enabled;
|
extern bool soft_endstops_enabled;
|
||||||
extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ];
|
extern axis_limits_t soft_endstop[XYZ];
|
||||||
|
void apply_motion_limits(float target[XYZ]);
|
||||||
void update_software_endstops(const AxisEnum axis
|
void update_software_endstops(const AxisEnum axis
|
||||||
#if HAS_HOTEND_OFFSET
|
#if HAS_HOTEND_OFFSET
|
||||||
, const uint8_t old_tool_index=0, const uint8_t new_tool_index=0
|
, const uint8_t old_tool_index=0, const uint8_t new_tool_index=0
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
constexpr bool soft_endstops_enabled = true;
|
constexpr bool soft_endstops_enabled = false;
|
||||||
constexpr float soft_endstop_min[XYZ] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS },
|
//constexpr axis_limits_t soft_endstop[XYZ] = { { X_MIN_POS, X_MAX_POS }, { Y_MIN_POS, Y_MAX_POS }, { Z_MIN_POS, Z_MAX_POS } };
|
||||||
soft_endstop_max[XYZ] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS };
|
#define apply_motion_limits(V) NOOP
|
||||||
#define update_software_endstops(...) NOOP
|
#define update_software_endstops(...) NOOP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void clamp_to_software_endstops(float target[XYZ]);
|
|
||||||
|
|
||||||
void report_current_position();
|
void report_current_position();
|
||||||
|
|
||||||
inline void set_current_from_destination() { COPY(current_position, destination); }
|
inline void set_current_from_destination() { COPY(current_position, destination); }
|
||||||
|
@ -188,7 +188,7 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS]
|
|||||||
// not linear in the distance.
|
// not linear in the distance.
|
||||||
bez_target[Z_AXIS] = interp(position[Z_AXIS], target[Z_AXIS], t);
|
bez_target[Z_AXIS] = interp(position[Z_AXIS], target[Z_AXIS], t);
|
||||||
bez_target[E_AXIS] = interp(position[E_AXIS], target[E_AXIS], t);
|
bez_target[E_AXIS] = interp(position[E_AXIS], target[E_AXIS], t);
|
||||||
clamp_to_software_endstops(bez_target);
|
apply_motion_limits(bez_target);
|
||||||
|
|
||||||
#if HAS_LEVELING && !PLANNER_LEVELING
|
#if HAS_LEVELING && !PLANNER_LEVELING
|
||||||
float pos[XYZE] = { bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS], bez_target[E_AXIS] };
|
float pos[XYZE] = { bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS], bez_target[E_AXIS] };
|
||||||
|
@ -739,7 +739,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
|
|||||||
#endif
|
#endif
|
||||||
current_position[Z_AXIS] += toolchange_settings.z_raise;
|
current_position[Z_AXIS] += toolchange_settings.z_raise;
|
||||||
#if HAS_SOFTWARE_ENDSTOPS
|
#if HAS_SOFTWARE_ENDSTOPS
|
||||||
NOMORE(current_position[Z_AXIS], soft_endstop_max[Z_AXIS]);
|
NOMORE(current_position[Z_AXIS], soft_endstop[Z_AXIS].max);
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line(current_position, feedrate_mm_s, active_extruder);
|
planner.buffer_line(current_position, feedrate_mm_s, active_extruder);
|
||||||
#endif
|
#endif
|
||||||
@ -771,7 +771,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
|
|||||||
// SWITCHING_NOZZLE_TWO_SERVOS, as both nozzles will lift instead.
|
// SWITCHING_NOZZLE_TWO_SERVOS, as both nozzles will lift instead.
|
||||||
current_position[Z_AXIS] += MAX(-zdiff, 0.0) + toolchange_settings.z_raise;
|
current_position[Z_AXIS] += MAX(-zdiff, 0.0) + toolchange_settings.z_raise;
|
||||||
#if HAS_SOFTWARE_ENDSTOPS
|
#if HAS_SOFTWARE_ENDSTOPS
|
||||||
NOMORE(current_position[Z_AXIS], soft_endstop_max[Z_AXIS]);
|
NOMORE(current_position[Z_AXIS], soft_endstop[Z_AXIS].max);
|
||||||
#endif
|
#endif
|
||||||
if (!no_move) fast_line_to_current(Z_AXIS);
|
if (!no_move) fast_line_to_current(Z_AXIS);
|
||||||
move_nozzle_servo(tmp_extruder);
|
move_nozzle_servo(tmp_extruder);
|
||||||
@ -840,7 +840,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Prevent a move outside physical bounds
|
// Prevent a move outside physical bounds
|
||||||
clamp_to_software_endstops(destination);
|
apply_motion_limits(destination);
|
||||||
|
|
||||||
// Move back to the original (or tweaked) position
|
// Move back to the original (or tweaked) position
|
||||||
do_blocking_move_to(destination);
|
do_blocking_move_to(destination);
|
||||||
|
Loading…
Reference in New Issue
Block a user