From 893092ff7f20b69e6a7f0e37ed89b235f09d90a4 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 30 Oct 2017 14:13:13 -0500 Subject: [PATCH] Kinematic clamp_to_software_endstops --- Marlin/Marlin_main.cpp | 61 +++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index a35e1f81c..10b1bdd45 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -472,11 +472,14 @@ float filament_size[EXTRUDERS], volumetric_multiplier[EXTRUDERS]; #endif // Software Endstops are based on the configured limits. -#if HAS_SOFTWARE_ENDSTOPS - bool soft_endstops_enabled = true; -#endif 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 }; +#if HAS_SOFTWARE_ENDSTOPS + bool soft_endstops_enabled = true; + #if IS_KINEMATIC + float soft_endstop_radius, soft_endstop_radius_2; + #endif +#endif #if FAN_COUNT > 0 int16_t fanSpeeds[FAN_COUNT] = { 0 }; @@ -1464,8 +1467,17 @@ bool get_target_extruder_from_command(const uint16_t code) { #endif #if ENABLED(DELTA) - if (axis == Z_AXIS) - delta_clip_start_height = soft_endstop_max[axis] - delta_safe_distance_from_top(); + switch(axis) { + case X_AXIS: + case Y_AXIS: + // Get a minimum radius for clamping + soft_endstop_radius = MIN3(FABS(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); + break; + case Z_AXIS: + delta_clip_start_height = soft_endstop_max[axis] - delta_safe_distance_from_top(); + default: break; + } #endif } @@ -12045,33 +12057,38 @@ void ok_to_send() { #if HAS_SOFTWARE_ENDSTOPS - /** - * Constrain the given coordinates to the software endstops. - */ - /** * Constrain the given coordinates to the software endstops. * - * NOTE: This will only apply to Z on DELTA and SCARA. XY is - * constrained to a circle on these kinematic systems. + * 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 ENABLED(MIN_SOFTWARE_ENDSTOP_X) - NOLESS(target[X_AXIS], soft_endstop_min[X_AXIS]); - #endif - #if ENABLED(MIN_SOFTWARE_ENDSTOP_Y) - NOLESS(target[Y_AXIS], soft_endstop_min[Y_AXIS]); + #if IS_KINEMATIC + const float dist_2 = HYPOT2(target[X_AXIS], target[Y_AXIS]); + 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 ENABLED(MIN_SOFTWARE_ENDSTOP_X) + NOLESS(target[X_AXIS], soft_endstop_min[X_AXIS]); + #endif + #if ENABLED(MIN_SOFTWARE_ENDSTOP_Y) + NOLESS(target[Y_AXIS], soft_endstop_min[Y_AXIS]); + #endif + #if ENABLED(MAX_SOFTWARE_ENDSTOP_X) + NOMORE(target[X_AXIS], soft_endstop_max[X_AXIS]); + #endif + #if ENABLED(MAX_SOFTWARE_ENDSTOP_Y) + NOMORE(target[Y_AXIS], soft_endstop_max[Y_AXIS]); + #endif #endif #if ENABLED(MIN_SOFTWARE_ENDSTOP_Z) NOLESS(target[Z_AXIS], soft_endstop_min[Z_AXIS]); #endif - #if ENABLED(MAX_SOFTWARE_ENDSTOP_X) - NOMORE(target[X_AXIS], soft_endstop_max[X_AXIS]); - #endif - #if ENABLED(MAX_SOFTWARE_ENDSTOP_Y) - NOMORE(target[Y_AXIS], soft_endstop_max[Y_AXIS]); - #endif #if ENABLED(MAX_SOFTWARE_ENDSTOP_Z) NOMORE(target[Z_AXIS], soft_endstop_max[Z_AXIS]); #endif