Fix and improve software endstops (#13386)

This commit is contained in:
Scott Lahteine
2019-03-13 05:48:36 -05:00
committed by GitHub
parent 6214c997c0
commit 87162658c4
13 changed files with 131 additions and 123 deletions

View File

@ -149,13 +149,13 @@ float cartes[XYZ];
#endif
#if HAS_SOFTWARE_ENDSTOPS
float soft_endstop_radius, soft_endstop_radius_2;
float delta_max_radius, delta_max_radius_2;
#elif IS_SCARA
constexpr float soft_endstop_radius = SCARA_PRINTABLE_RADIUS,
soft_endstop_radius_2 = sq(SCARA_PRINTABLE_RADIUS);
constexpr float delta_max_radius = SCARA_PRINTABLE_RADIUS,
delta_max_radius_2 = sq(SCARA_PRINTABLE_RADIUS);
#else // DELTA
constexpr float soft_endstop_radius = DELTA_PRINTABLE_RADIUS,
soft_endstop_radius_2 = sq(DELTA_PRINTABLE_RADIUS);
constexpr float delta_max_radius = DELTA_PRINTABLE_RADIUS,
delta_max_radius_2 = sq(DELTA_PRINTABLE_RADIUS);
#endif
#endif
@ -460,8 +460,7 @@ void clean_up_after_endstop_or_probe_move() {
bool soft_endstops_enabled = true;
// Software Endstops are based on the configured limits.
float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
soft_endstop_max[XYZ] = { X_MAX_BED, Y_MAX_BED, Z_MAX_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 } };
/**
* 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) {
// 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_max[X_AXIS] = dual_max_x;
soft_endstop[X_AXIS].min = X2_MIN_POS;
soft_endstop[X_AXIS].max = dual_max_x;
}
else if (dxc_is_duplicating()) {
// 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
soft_endstop_min[X_AXIS] = X1_MIN_POS;
soft_endstop_max[X_AXIS] = MIN(X1_MAX_POS, dual_max_x - duplicate_extruder_x_offset);
soft_endstop[X_AXIS].min = X1_MIN_POS;
soft_endstop[X_AXIS].max = MIN(X1_MAX_POS, dual_max_x - duplicate_extruder_x_offset);
}
else {
// In other modes, T0 can move from X1_MIN_POS to X1_MAX_POS
soft_endstop_min[X_AXIS] = X1_MIN_POS;
soft_endstop_max[X_AXIS] = X1_MAX_POS;
soft_endstop[X_AXIS].min = X1_MIN_POS;
soft_endstop[X_AXIS].max = X1_MAX_POS;
}
}
#elif ENABLED(DELTA)
soft_endstop_min[axis] = base_min_pos(axis);
soft_endstop_max[axis] = (axis == Z_AXIS ? delta_height
soft_endstop[axis].min = base_min_pos(axis);
soft_endstop[axis].max = (axis == Z_AXIS ? delta_height
#if HAS_BED_PROBE
- zprobe_zoffset
#endif
@ -516,11 +516,11 @@ void clean_up_after_endstop_or_probe_move() {
case X_AXIS:
case Y_AXIS:
// 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]);
soft_endstop_radius_2 = sq(soft_endstop_radius);
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);
delta_max_radius_2 = sq(delta_max_radius);
break;
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;
}
@ -531,85 +531,82 @@ void clean_up_after_endstop_or_probe_move() {
// retain the same physical limit when other tools are selected.
if (old_tool_index != new_tool_index) {
const float offs = hotend_offset[axis][new_tool_index] - hotend_offset[axis][old_tool_index];
soft_endstop_min[axis] += offs;
soft_endstop_max[axis] += offs;
soft_endstop[axis].min += offs;
soft_endstop[axis].max += offs;
}
else {
const float offs = hotend_offset[axis][active_extruder];
soft_endstop_min[axis] = base_min_pos(axis) + offs;
soft_endstop_max[axis] = base_max_pos(axis) + offs;
soft_endstop[axis].min = base_min_pos(axis) + offs;
soft_endstop[axis].max = base_max_pos(axis) + offs;
}
#else
soft_endstop_min[axis] = base_min_pos(axis);
soft_endstop_max[axis] = base_max_pos(axis);
soft_endstop[axis].min = base_min_pos(axis);
soft_endstop[axis].max = base_max_pos(axis);
#endif
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) {
SERIAL_ECHOPAIR("For ", axis_codes[axis]);
SERIAL_ECHOPAIR(" axis:\n soft_endstop_min = ", soft_endstop_min[axis]);
SERIAL_ECHOLNPAIR("\n soft_endstop_max = ", soft_endstop_max[axis]);
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING))
SERIAL_ECHOLNPAIR("Axis ", axis_codes[axis], " min:", soft_endstop[axis].min, " max:", soft_endstop[axis].max);
#endif
}
/**
* 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 // 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 IS_KINEMATIC
@ -995,7 +992,7 @@ void clamp_to_software_endstops(float target[XYZ]) {
* before calling or cold/lengthy extrusion may get missed.
*/
void prepare_move_to_destination() {
clamp_to_software_endstops(destination);
apply_motion_limits(destination);
#if ENABLED(PREVENT_COLD_EXTRUSION) || ENABLED(PREVENT_LENGTHY_EXTRUDE)

View File

@ -118,23 +118,23 @@ XYZ_DEFS(signed char, home_dir, HOME_DIR);
constexpr float hotend_offset[XYZ][HOTENDS] = { { 0 }, { 0 }, { 0 } };
#endif
typedef struct { float min, max; } axis_limits_t;
#if HAS_SOFTWARE_ENDSTOPS
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
#if HAS_HOTEND_OFFSET
, const uint8_t old_tool_index=0, const uint8_t new_tool_index=0
#endif
);
#else
constexpr bool soft_endstops_enabled = true;
constexpr float soft_endstop_min[XYZ] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS },
soft_endstop_max[XYZ] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS };
constexpr bool soft_endstops_enabled = false;
//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 } };
#define apply_motion_limits(V) NOOP
#define update_software_endstops(...) NOOP
#endif
void clamp_to_software_endstops(float target[XYZ]);
void report_current_position();
inline void set_current_from_destination() { COPY(current_position, destination); }

View File

@ -188,7 +188,7 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS]
// not linear in the distance.
bez_target[Z_AXIS] = interp(position[Z_AXIS], target[Z_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
float pos[XYZE] = { bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS], bez_target[E_AXIS] };

View File

@ -739,7 +739,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
#endif
current_position[Z_AXIS] += toolchange_settings.z_raise;
#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
planner.buffer_line(current_position, feedrate_mm_s, active_extruder);
#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.
current_position[Z_AXIS] += MAX(-zdiff, 0.0) + toolchange_settings.z_raise;
#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
if (!no_move) fast_line_to_current(Z_AXIS);
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
// Prevent a move outside physical bounds
clamp_to_software_endstops(destination);
apply_motion_limits(destination);
// Move back to the original (or tweaked) position
do_blocking_move_to(destination);