diff --git a/Marlin/src/gcode/bedlevel/G26.cpp b/Marlin/src/gcode/bedlevel/G26.cpp index 21fa08fc10..1e436ffd96 100644 --- a/Marlin/src/gcode/bedlevel/G26.cpp +++ b/Marlin/src/gcode/bedlevel/G26.cpp @@ -306,7 +306,7 @@ typedef struct { LIMIT(e.x, X_MIN_POS + 1, X_MAX_POS - 1); #endif - if (position_is_reachable(s.x, s.y) && position_is_reachable(e.x, e.y)) + if (position_is_reachable(s) && position_is_reachable(e)) print_line_from_here_to_there(s, e); } } diff --git a/Marlin/src/gcode/calibrate/M665.cpp b/Marlin/src/gcode/calibrate/M665.cpp index aa21471b60..7dc657a61b 100644 --- a/Marlin/src/gcode/calibrate/M665.cpp +++ b/Marlin/src/gcode/calibrate/M665.cpp @@ -86,13 +86,13 @@ * * Parameters: * - * S[segments-per-second] - Segments-per-second + * S[segments] - Segments-per-second * * Without NO_WORKSPACE_OFFSETS: * - * P[theta-psi-offset] - Theta-Psi offset, added to the shoulder (A/X) angle - * T[theta-offset] - Theta offset, added to the elbow (B/Y) angle - * Z[z-offset] - Z offset, added to Z + * P[theta-psi-offset] - Theta-Psi offset, added to the shoulder (A/X) angle + * T[theta-offset] - Theta offset, added to the elbow (B/Y) angle + * Z[z-offset] - Z offset, added to Z * * A, P, and X are all aliases for the shoulder angle * B, T, and Y are all aliases for the elbow angle @@ -152,18 +152,35 @@ * * Parameters: * - * S[segments-per-second] - Segments-per-second + * S[segments] - Segments-per-second + * L[left] - Work area minimum X + * R[right] - Work area maximum X + * T[top] - Work area maximum Y + * B[bottom] - Work area minimum Y + * H[length] - Maximum belt length */ void GcodeSuite::M665() { - if (parser.seenval('S')) - segments_per_second = parser.value_float(); - else - M665_report(); + if (!parser.seen_any()) return M665_report(); + if (parser.seenval('S')) segments_per_second = parser.value_float(); + if (parser.seenval('L')) draw_area_min.x = parser.value_linear_units(); + if (parser.seenval('R')) draw_area_max.x = parser.value_linear_units(); + if (parser.seenval('T')) draw_area_max.y = parser.value_linear_units(); + if (parser.seenval('B')) draw_area_min.y = parser.value_linear_units(); + if (parser.seenval('H')) polargraph_max_belt_len = parser.value_linear_units(); + draw_area_size.x = draw_area_max.x - draw_area_min.x; + draw_area_size.y = draw_area_max.y - draw_area_min.y; } void GcodeSuite::M665_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_POLARGRAPH_SETTINGS " (" STR_S_SEG_PER_SEC ")")); - SERIAL_ECHOLNPGM(" M665 S", segments_per_second); + report_heading_etc(forReplay, F(STR_POLARGRAPH_SETTINGS)); + SERIAL_ECHOLNPGM_P( + PSTR(" M665 S"), LINEAR_UNIT(segments_per_second), + PSTR(" L"), LINEAR_UNIT(draw_area_min.x), + PSTR(" R"), LINEAR_UNIT(draw_area_max.x), + SP_T_STR, LINEAR_UNIT(draw_area_max.y), + SP_B_STR, LINEAR_UNIT(draw_area_min.y), + PSTR(" H"), LINEAR_UNIT(polargraph_max_belt_len) + ); } #endif diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 3c5e98e705..808483c4e7 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -930,7 +930,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { #endif #if IS_KINEMATIC - case 665: M665(); break; // M665: Set Delta/SCARA parameters + case 665: M665(); break; // M665: Set Kinematics parameters #endif #if ENABLED(DELTA) || HAS_EXTRA_ENDSTOPS diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index 343550c95b..d8ba1466a2 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -262,6 +262,7 @@ * M605 - Set Dual X-Carriage movement mode: "M605 S [X] [R]". (Requires DUAL_X_CARRIAGE) * M665 - Set delta configurations: "M665 H L R S B X Y Z (Requires DELTA) * Set SCARA configurations: "M665 S P T Z (Requires MORGAN_SCARA or MP_SCARA) + * Set Polargraph draw area and belt length: "M665 S L R T B H" * M666 - Set/get offsets for delta (Requires DELTA) or dual endstops. (Requires [XYZ]_DUAL_ENDSTOPS) * M672 - Set/Reset Duet Smart Effector's sensitivity. (Requires DUET_SMART_EFFECTOR and SMART_EFFECTOR_MOD_PIN) * M701 - Load filament (Requires FILAMENT_LOAD_UNLOAD_GCODES) diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 4b8c667497..d565082e71 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -293,6 +293,73 @@ void report_current_position_projected() { #endif +#if IS_KINEMATIC + + bool position_is_reachable(const_float_t rx, const_float_t ry, const float inset/*=0*/) { + + bool can_reach; + + #if ENABLED(DELTA) + + can_reach = HYPOT2(rx, ry) <= sq(DELTA_PRINTABLE_RADIUS - inset + fslop); + + #elif ENABLED(AXEL_TPARA) + + const float R2 = HYPOT2(rx - TPARA_OFFSET_X, ry - TPARA_OFFSET_Y); + can_reach = ( + R2 <= sq(L1 + L2) - inset + #if MIDDLE_DEAD_ZONE_R > 0 + && R2 >= sq(float(MIDDLE_DEAD_ZONE_R)) + #endif + ); + + #elif IS_SCARA + + const float R2 = HYPOT2(rx - SCARA_OFFSET_X, ry - SCARA_OFFSET_Y); + can_reach = ( + R2 <= sq(L1 + L2) - inset + #if MIDDLE_DEAD_ZONE_R > 0 + && R2 >= sq(float(MIDDLE_DEAD_ZONE_R)) + #endif + ); + + #elif ENABLED(POLARGRAPH) + + const float d1 = rx - (draw_area_min.x), + d2 = (draw_area_max.x) - rx, + y = ry - (draw_area_max.y), + a = HYPOT(d1, y), + b = HYPOT(d2, y); + + can_reach = ( + a < polargraph_max_belt_len + 1 + && b < polargraph_max_belt_len + 1 + && (a + b) > _MIN(draw_area_size.x, draw_area_size.y) + ); + + #endif + + return can_reach; + } + +#else // CARTESIAN + + // Return true if the given position is within the machine bounds. + bool position_is_reachable(const_float_t rx, const_float_t ry) { + if (!COORDINATE_OKAY(ry, Y_MIN_POS - fslop, Y_MAX_POS + fslop)) return false; + #if ENABLED(DUAL_X_CARRIAGE) + if (active_extruder) + return COORDINATE_OKAY(rx, X2_MIN_POS - fslop, X2_MAX_POS + fslop); + else + return COORDINATE_OKAY(rx, X1_MIN_POS - fslop, X1_MAX_POS + fslop); + #else + return COORDINATE_OKAY(rx, X_MIN_POS - fslop, X_MAX_POS + fslop); + #endif + } + +#endif // CARTESIAN + + void home_if_needed(const bool keeplev/*=false*/) { if (!all_axes_trusted()) gcode.home_all_axes(keeplev); } diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index 0a43459765..ec37a77933 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -504,63 +504,21 @@ void home_if_needed(const bool keeplev=false); #endif // Return true if the given point is within the printable area - inline bool position_is_reachable(const_float_t rx, const_float_t ry, const float inset=0) { - #if ENABLED(DELTA) - - return HYPOT2(rx, ry) <= sq(DELTA_PRINTABLE_RADIUS - inset + fslop); - - #elif ENABLED(POLARGRAPH) - - const float x1 = rx - (X_MIN_POS), x2 = (X_MAX_POS) - rx, y = ry - (Y_MAX_POS), - a = HYPOT(x1, y), b = HYPOT(x2, y); - return a < (POLARGRAPH_MAX_BELT_LEN) + 1 - && b < (POLARGRAPH_MAX_BELT_LEN) + 1 - && (a + b) > _MIN(X_BED_SIZE, Y_BED_SIZE); - - #elif ENABLED(AXEL_TPARA) - - const float R2 = HYPOT2(rx - TPARA_OFFSET_X, ry - TPARA_OFFSET_Y); - return ( - R2 <= sq(L1 + L2) - inset - #if MIDDLE_DEAD_ZONE_R > 0 - && R2 >= sq(float(MIDDLE_DEAD_ZONE_R)) - #endif - ); - - #elif IS_SCARA - - const float R2 = HYPOT2(rx - SCARA_OFFSET_X, ry - SCARA_OFFSET_Y); - return ( - R2 <= sq(L1 + L2) - inset - #if MIDDLE_DEAD_ZONE_R > 0 - && R2 >= sq(float(MIDDLE_DEAD_ZONE_R)) - #endif - ); - - #endif - } + bool position_is_reachable(const_float_t rx, const_float_t ry, const float inset=0); inline bool position_is_reachable(const xy_pos_t &pos, const float inset=0) { return position_is_reachable(pos.x, pos.y, inset); } -#else // CARTESIAN +#else // Return true if the given position is within the machine bounds. - inline bool position_is_reachable(const_float_t rx, const_float_t ry) { - if (!COORDINATE_OKAY(ry, Y_MIN_POS - fslop, Y_MAX_POS + fslop)) return false; - #if ENABLED(DUAL_X_CARRIAGE) - if (active_extruder) - return COORDINATE_OKAY(rx, X2_MIN_POS - fslop, X2_MAX_POS + fslop); - else - return COORDINATE_OKAY(rx, X1_MIN_POS - fslop, X1_MAX_POS + fslop); - #else - return COORDINATE_OKAY(rx, X_MIN_POS - fslop, X_MAX_POS + fslop); - #endif + bool position_is_reachable(const_float_t rx, const_float_t ry); + inline bool position_is_reachable(const xy_pos_t &pos) { + return position_is_reachable(pos.x, pos.y); } - inline bool position_is_reachable(const xy_pos_t &pos) { return position_is_reachable(pos.x, pos.y); } -#endif // CARTESIAN +#endif /** * Duplication mode diff --git a/Marlin/src/module/polargraph.cpp b/Marlin/src/module/polargraph.cpp index b7eeeee8af..42f99304d7 100644 --- a/Marlin/src/module/polargraph.cpp +++ b/Marlin/src/module/polargraph.cpp @@ -39,8 +39,15 @@ float segments_per_second; // Initialized by settings.load() +xy_pos_t draw_area_min = { X_MIN_POS, Y_MIN_POS }, + draw_area_max = { X_MAX_POS, Y_MAX_POS }; + +xy_float_t draw_area_size = { X_MAX_POS - X_MIN_POS, Y_MAX_POS - Y_MIN_POS }; + +float polargraph_max_belt_len = HYPOT(draw_area_size.x, draw_area_size.y); + void inverse_kinematics(const xyz_pos_t &raw) { - const float x1 = raw.x - (X_MIN_POS), x2 = (X_MAX_POS) - raw.x, y = raw.y - (Y_MAX_POS); + const float x1 = raw.x - (draw_area_min.x), x2 = (draw_area_max.x) - raw.x, y = raw.y - (draw_area_max.y); delta.set(HYPOT(x1, y), HYPOT(x2, y), raw.z); } diff --git a/Marlin/src/module/polargraph.h b/Marlin/src/module/polargraph.h index 0406034253..b465de3287 100644 --- a/Marlin/src/module/polargraph.h +++ b/Marlin/src/module/polargraph.h @@ -29,5 +29,8 @@ #include "../core/macros.h" extern float segments_per_second; +extern xy_pos_t draw_area_min, draw_area_max; +extern xy_float_t draw_area_size; +extern float polargraph_max_belt_len; void inverse_kinematics(const xyz_pos_t &raw);