From 267c247da78af3544d16202d1a0f288e7d7420b7 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 3 Nov 2017 20:50:44 -0500 Subject: [PATCH] Cleanup Nozzle class, fix XY vs Z move order --- Marlin/nozzle.cpp | 315 +++++++++++++++++++--------------------------- Marlin/nozzle.h | 57 ++++----- Marlin/point_t.h | 30 +---- 3 files changed, 157 insertions(+), 245 deletions(-) diff --git a/Marlin/nozzle.cpp b/Marlin/nozzle.cpp index eec8bfa39..105829d1d 100644 --- a/Marlin/nozzle.cpp +++ b/Marlin/nozzle.cpp @@ -1,238 +1,185 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "MarlinConfig.h" + +#if ENABLED(NOZZLE_CLEAN_FEATURE) || ENABLED(NOZZLE_PARK_FEATURE) + #include "nozzle.h" #include "Marlin.h" #include "point_t.h" -/** - * @brief Stroke clean pattern - * @details Wipes the nozzle back and forth in a linear movement - * - * @param start point_t defining the starting point - * @param end point_t defining the ending point - * @param strokes number of strokes to execute - */ -void Nozzle::stroke( - _UNUSED point_t const &start, - _UNUSED point_t const &end, - _UNUSED uint8_t const &strokes -) { - #if ENABLED(NOZZLE_CLEAN_FEATURE) - +#if ENABLED(NOZZLE_CLEAN_FEATURE) + + /** + * @brief Stroke clean pattern + * @details Wipes the nozzle back and forth in a linear movement + * + * @param start point_t defining the starting point + * @param end point_t defining the ending point + * @param strokes number of strokes to execute + */ + void Nozzle::stroke(const point_t &start, const point_t &end, const uint8_t &strokes) { #if ENABLED(NOZZLE_CLEAN_GOBACK) - // Store the current coords - point_t const initial = { - current_position[X_AXIS], - current_position[Y_AXIS], - current_position[Z_AXIS], - current_position[E_AXIS] - }; - #endif // NOZZLE_CLEAN_GOBACK + const float ix = current_position[X_AXIS], iy = current_position[Y_AXIS], iz = current_position[Z_AXIS]; + #endif // Move to the starting point - do_blocking_move_to_xy(start.x, start.y); - do_blocking_move_to_z(start.z); + do_blocking_move_to(start.x, start.y, start.z); // Start the stroke pattern - for (uint8_t i = 0; i < (strokes >>1); i++) { + for (uint8_t i = 0; i < (strokes >> 1); i++) { do_blocking_move_to_xy(end.x, end.y); do_blocking_move_to_xy(start.x, start.y); } #if ENABLED(NOZZLE_CLEAN_GOBACK) - // Move the nozzle to the initial point - do_blocking_move_to(initial.x, initial.y, initial.z); - #endif // NOZZLE_CLEAN_GOBACK - - #endif // NOZZLE_CLEAN_FEATURE -} - -/** - * @brief Zig-zag clean pattern - * @details Apply a zig-zag cleanning pattern - * - * @param start point_t defining the starting point - * @param end point_t defining the ending point - * @param strokes number of strokes to execute - * @param objects number of objects to create - */ -void Nozzle::zigzag( - _UNUSED point_t const &start, - _UNUSED point_t const &end, - _UNUSED uint8_t const &strokes, - _UNUSED uint8_t const &objects -) { - #if ENABLED(NOZZLE_CLEAN_FEATURE) - const float A = nozzle_clean_horizontal ? nozzle_clean_height : nozzle_clean_length, // [twice the] Amplitude - P = (nozzle_clean_horizontal ? nozzle_clean_length : nozzle_clean_height) / (objects << 1); // Period - - // Don't allow impossible triangles - if (A <= 0.0f || P <= 0.0f ) return; + do_blocking_move_to(ix, iy, iz); + #endif + } + + /** + * @brief Zig-zag clean pattern + * @details Apply a zig-zag cleaning pattern + * + * @param start point_t defining the starting point + * @param end point_t defining the ending point + * @param strokes number of strokes to execute + * @param objects number of triangles to do + */ + void Nozzle::zigzag(const point_t &start, const point_t &end, const uint8_t &strokes, const uint8_t &objects) { + const float diffx = end.x - start.x, diffy = end.y - start.y; + if (!diffx || !diffy) return; #if ENABLED(NOZZLE_CLEAN_GOBACK) - // Store the current coords - point_t const initial = { - current_position[X_AXIS], - current_position[Y_AXIS], - current_position[Z_AXIS], - current_position[E_AXIS] - }; - #endif // NOZZLE_CLEAN_GOBACK + const float ix = current_position[X_AXIS], iy = current_position[Y_AXIS], iz = current_position[Z_AXIS]; + #endif - for (uint8_t j = 0; j < strokes; j++) { - for (uint8_t i = 0; i < (objects << 1); i++) { - float const x = start.x + ( nozzle_clean_horizontal ? i * P : (A/P) * (P - FABS(FMOD((i*P), (2*P)) - P)) ); - float const y = start.y + (!nozzle_clean_horizontal ? i * P : (A/P) * (P - FABS(FMOD((i*P), (2*P)) - P)) ); + do_blocking_move_to(start.x, start.y, start.z); - do_blocking_move_to_xy(x, y); - if (i == 0) do_blocking_move_to_z(start.z); + const uint8_t zigs = objects << 1; + const bool horiz = FABS(diffx) >= FABS(diffy); // Do a horizontal wipe? + const float P = (horiz ? diffx : diffy) / zigs; // Period of each zig / zag + point_t *side; + for (uint8_t j = 0; j < strokes; j++) { + for (int8_t i = 0; i < zigs; i++) { + side = (i & 1) ? &end : &start; + if (horiz) + do_blocking_move_to_xy(start.x + i * P, side->y); + else + do_blocking_move_to_xy(side->x, start.y + i * P); } - - for (int i = (objects << 1); i > -1; i--) { - float const x = start.x + ( nozzle_clean_horizontal ? i * P : (A/P) * (P - FABS(FMOD((i*P), (2*P)) - P)) ); - float const y = start.y + (!nozzle_clean_horizontal ? i * P : (A/P) * (P - FABS(FMOD((i*P), (2*P)) - P)) ); - - do_blocking_move_to_xy(x, y); + for (int8_t i = zigs; i >= 0; i--) { + side = (i & 1) ? &end : &start; + if (horiz) + do_blocking_move_to_xy(start.x + i * P, side->y); + else + do_blocking_move_to_xy(side->x, start.y + i * P); } } #if ENABLED(NOZZLE_CLEAN_GOBACK) - // Move the nozzle to the initial point - do_blocking_move_to_z(initial.z); - do_blocking_move_to_xy(initial.x, initial.y); - #endif // NOZZLE_CLEAN_GOBACK - - #endif // NOZZLE_CLEAN_FEATURE -} - - -/** - * @brief Circular clean pattern - * @details Apply a circular cleaning pattern - * - * @param start point_t defining the middle of circle - * @param strokes number of strokes to execute - * @param radius radius of circle - */ -void Nozzle::circle( - _UNUSED point_t const &start, - _UNUSED point_t const &middle, - _UNUSED uint8_t const &strokes, - _UNUSED float const &radius -) { - #if ENABLED(NOZZLE_CLEAN_FEATURE) + do_blocking_move_to(ix, iy, iz); + #endif + } + + /** + * @brief Circular clean pattern + * @details Apply a circular cleaning pattern + * + * @param start point_t defining the middle of circle + * @param strokes number of strokes to execute + * @param radius radius of circle + */ + void Nozzle::circle(const point_t &start, const point_t &middle, const uint8_t &strokes, const float &radius) { if (strokes == 0) return; #if ENABLED(NOZZLE_CLEAN_GOBACK) - // Store the current coords - point_t const initial = { - current_position[X_AXIS], - current_position[Y_AXIS], - current_position[Z_AXIS], - current_position[E_AXIS] - }; - #endif // NOZZLE_CLEAN_GOBACK - - if (start.z <= current_position[Z_AXIS]) { - // Order of movement is pretty darn important here - do_blocking_move_to_xy(start.x, start.y); - do_blocking_move_to_z(start.z); - } - else { - do_blocking_move_to_z(start.z); - do_blocking_move_to_xy(start.x, start.y); - } + const float ix = current_position[X_AXIS], iy = current_position[Y_AXIS], iz = current_position[Z_AXIS]; + #endif - float x, y; - for (uint8_t s = 0; s < strokes; s++) { - for (uint8_t i = 0; i < NOZZLE_CLEAN_CIRCLE_FN; i++) { - x = middle.x + sin((M_2_PI / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius; - y = middle.y + cos((M_2_PI / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius; + do_blocking_move_to(start.x, start.y, start.z); - do_blocking_move_to_xy(x, y); - } - } + for (uint8_t s = 0; s < strokes; s++) + for (uint8_t i = 0; i < NOZZLE_CLEAN_CIRCLE_FN; i++) + do_blocking_move_to_xy( + middle.x + sin((M_2_PI / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius, + middle.y + cos((M_2_PI / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius + ); // Let's be safe do_blocking_move_to_xy(start.x, start.y); #if ENABLED(NOZZLE_CLEAN_GOBACK) - // Move the nozzle to the initial point - if (start.z <= initial.z) { - // As above order is important - do_blocking_move_to_z(initial.z); - do_blocking_move_to_xy(initial.x, initial.y); - } - else { - do_blocking_move_to_xy(initial.x, initial.y); - do_blocking_move_to_z(initial.z); - } - #endif // NOZZLE_CLEAN_GOBACK - - #endif // NOZZLE_CLEAN_FEATURE -} - -/** - * @brief Clean the nozzle - * @details Starts the selected clean procedure pattern - * - * @param pattern one of the available patterns - * @param argument depends on the cleaning pattern - */ -void Nozzle::clean( - _UNUSED uint8_t const &pattern, - _UNUSED uint8_t const &strokes, - _UNUSED float const &radius, - _UNUSED uint8_t const &objects -) { - #if ENABLED(NOZZLE_CLEAN_FEATURE) - #if ENABLED(DELTA) - if (current_position[Z_AXIS] > delta_clip_start_height) - do_blocking_move_to_z(delta_clip_start_height); + do_blocking_move_to(ix, iy, iz); #endif + } + + /** + * @brief Clean the nozzle + * @details Starts the selected clean procedure pattern + * + * @param pattern one of the available patterns + * @param argument depends on the cleaning pattern + */ + void Nozzle::clean(const uint8_t &pattern, const uint8_t &strokes, const float &radius, const uint8_t &objects/*=0*/) { switch (pattern) { case 1: - Nozzle::zigzag( - NOZZLE_CLEAN_START_POINT, - NOZZLE_CLEAN_END_POINT, strokes, objects); + zigzag(NOZZLE_CLEAN_START_POINT, NOZZLE_CLEAN_END_POINT, strokes, objects); break; case 2: - Nozzle::circle( - NOZZLE_CLEAN_START_POINT, - NOZZLE_CLEAN_CIRCLE_MIDDLE, strokes, radius); + circle(NOZZLE_CLEAN_START_POINT, NOZZLE_CLEAN_CIRCLE_MIDDLE, strokes, radius); break; default: - Nozzle::stroke( - NOZZLE_CLEAN_START_POINT, - NOZZLE_CLEAN_END_POINT, strokes); + stroke(NOZZLE_CLEAN_START_POINT, NOZZLE_CLEAN_END_POINT, strokes); } - #endif // NOZZLE_CLEAN_FEATURE -} - -void Nozzle::park( - _UNUSED uint8_t const &z_action -) { - #if ENABLED(NOZZLE_PARK_FEATURE) - float const z = current_position[Z_AXIS]; - point_t const park = NOZZLE_PARK_POINT; - - switch(z_action) { - case 1: // force Z-park height + } + +#endif // NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + + void Nozzle::park(const uint8_t &z_action) { + const point_t park = NOZZLE_PARK_POINT; + + switch (z_action) { + case 1: // Go to Z-park height do_blocking_move_to_z(park.z); break; case 2: // Raise by Z-park height - do_blocking_move_to_z( - (z + park.z > Z_MAX_POS) ? Z_MAX_POS : z + park.z); + do_blocking_move_to_z(min(current_position[Z_AXIS] + park.z, Z_MAX_POS)); break; - default: // Raise to Z-park height if lower - if (current_position[Z_AXIS] < park.z) - do_blocking_move_to_z(park.z); + default: // Raise to at least the Z-park height + do_blocking_move_to_z(max(park.z, current_position[Z_AXIS])); } do_blocking_move_to_xy(park.x, park.y); + } + +#endif // NOZZLE_PARK_FEATURE - #endif // NOZZLE_PARK_FEATURE -} +#endif // NOZZLE_CLEAN_FEATURE || NOZZLE_PARK_FEATURE diff --git a/Marlin/nozzle.h b/Marlin/nozzle.h index 2fbe98fb0..6024fd344 100644 --- a/Marlin/nozzle.h +++ b/Marlin/nozzle.h @@ -26,14 +26,6 @@ #include "Marlin.h" #include "point_t.h" -#if ENABLED(NOZZLE_CLEAN_FEATURE) - constexpr float nozzle_clean_start_point[4] = NOZZLE_CLEAN_START_POINT, - nozzle_clean_end_point[4] = NOZZLE_CLEAN_END_POINT, - nozzle_clean_length = FABS(nozzle_clean_start_point[X_AXIS] - nozzle_clean_end_point[X_AXIS]), //abs x size of wipe pad - nozzle_clean_height = FABS(nozzle_clean_start_point[Y_AXIS] - nozzle_clean_end_point[Y_AXIS]); //abs y size of wipe pad - constexpr bool nozzle_clean_horizontal = nozzle_clean_length >= nozzle_clean_height; //whether to zig-zag horizontally or vertically -#endif // NOZZLE_CLEAN_FEATURE - /** * @brief Nozzle class * @@ -41,6 +33,9 @@ */ class Nozzle { private: + + #if ENABLED(NOZZLE_CLEAN_FEATURE) + /** * @brief Stroke clean pattern * @details Wipes the nozzle back and forth in a linear movement @@ -49,11 +44,7 @@ class Nozzle { * @param end point_t defining the ending point * @param strokes number of strokes to execute */ - static void stroke( - _UNUSED point_t const &start, - _UNUSED point_t const &end, - _UNUSED uint8_t const &strokes - ) _Os; + static void stroke(const point_t &start, const point_t &end, const uint8_t &strokes) _Os; /** * @brief Zig-zag clean pattern @@ -64,12 +55,7 @@ class Nozzle { * @param strokes number of strokes to execute * @param objects number of objects to create */ - static void zigzag( - _UNUSED point_t const &start, - _UNUSED point_t const &end, - _UNUSED uint8_t const &strokes, - _UNUSED uint8_t const &objects - ) _Os; + static void zigzag(const point_t &start, const point_t &end, const uint8_t &strokes, const uint8_t &objects) _Os; /** * @brief Circular clean pattern @@ -79,14 +65,14 @@ class Nozzle { * @param strokes number of strokes to execute * @param radius radius of circle */ - static void circle( - _UNUSED point_t const &start, - _UNUSED point_t const &middle, - _UNUSED uint8_t const &strokes, - _UNUSED float const &radius - ) _Os; + static void circle(const point_t &start, const point_t &middle, const uint8_t &strokes, const float &radius) _Os; + + #endif // NOZZLE_CLEAN_FEATURE public: + + #if ENABLED(NOZZLE_CLEAN_FEATURE) + /** * @brief Clean the nozzle * @details Starts the selected clean procedure pattern @@ -94,16 +80,15 @@ class Nozzle { * @param pattern one of the available patterns * @param argument depends on the cleaning pattern */ - static void clean( - _UNUSED uint8_t const &pattern, - _UNUSED uint8_t const &strokes, - _UNUSED float const &radius, - _UNUSED uint8_t const &objects = 0 - ) _Os; - - static void park( - _UNUSED uint8_t const &z_action - ) _Os; + static void clean(const uint8_t &pattern, const uint8_t &strokes, const float &radius, const uint8_t &objects=0) _Os; + + #endif // NOZZLE_CLEAN_FEATURE + + #if ENABLED(NOZZLE_PARK_FEATURE) + + static void park(const uint8_t &z_action) _Os; + + #endif }; -#endif +#endif // __NOZZLE_H__ diff --git a/Marlin/point_t.h b/Marlin/point_t.h index 360abce64..37ade7eba 100644 --- a/Marlin/point_t.h +++ b/Marlin/point_t.h @@ -31,22 +31,9 @@ * @param x The x-coordinate of the point. * @param y The y-coordinate of the point. * @param z The z-coordinate of the point. - * @param e The e-coordinate of the point. */ struct point_t { - float x; - float y; - float z; - float e; - - /** - * @brief Two dimensional point constructor - * - * @param x The x-coordinate of the point. - * @param y The y-coordinate of the point. - */ - point_t(float const x, float const y) - : point_t(x, y, NAN, NAN) {} + float x, y, z; /** * @brief Three dimensional point constructor @@ -55,23 +42,16 @@ struct point_t { * @param y The y-coordinate of the point. * @param z The z-coordinate of the point. */ - point_t(float const x, float const y, float const z) - : point_t(x, y, z, NAN) {} + point_t(const float x, const float y, const float z) : x(x), y(y), z(z) {} /** - * @brief Tree dimensional point constructor with extrusion length + * @brief Two dimensional point constructor * * @param x The x-coordinate of the point. * @param y The y-coordinate of the point. - * @param z The z-coordinate of the point. - * @param e The e-coordinate of the point. */ - point_t(float const x, float const y, float const z, float const e) { - this->x = x; - this->y = y; - this->z = z; - this->e = e; - } + point_t(const float x, const float y) : point_t(x, y, NAN) {} + }; #endif // __POINT_T__