E1+ Autotemp and Planner comments
This commit is contained in:
		| @@ -587,13 +587,11 @@ namespace ExtUI { | |||||||
|  |  | ||||||
|   void setAxisMaxAcceleration_mm_s2(const float &value, const axis_t axis) { |   void setAxisMaxAcceleration_mm_s2(const float &value, const axis_t axis) { | ||||||
|     planner.set_max_acceleration(axis, value); |     planner.set_max_acceleration(axis, value); | ||||||
|     planner.reset_acceleration_rates(); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void setAxisMaxAcceleration_mm_s2(const float &value, const extruder_t extruder) { |   void setAxisMaxAcceleration_mm_s2(const float &value, const extruder_t extruder) { | ||||||
|     UNUSED_E(extruder); |     UNUSED_E(extruder); | ||||||
|     planner.set_max_acceleration(E_AXIS_N(extruder - E0), value); |     planner.set_max_acceleration(E_AXIS_N(extruder - E0), value); | ||||||
|     planner.reset_acceleration_rates(); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   #if HAS_FILAMENT_SENSOR |   #if HAS_FILAMENT_SENSOR | ||||||
|   | |||||||
| @@ -1248,32 +1248,6 @@ void Planner::recalculate() { | |||||||
|   recalculate_trapezoids(); |   recalculate_trapezoids(); | ||||||
| } | } | ||||||
|  |  | ||||||
| #if ENABLED(AUTOTEMP) |  | ||||||
|  |  | ||||||
|   void Planner::getHighESpeed() { |  | ||||||
|     static float oldt = 0; |  | ||||||
|  |  | ||||||
|     if (!autotemp_enabled) return; |  | ||||||
|     if (thermalManager.degTargetHotend(0) + 2 < autotemp_min) return; // probably temperature set to zero. |  | ||||||
|  |  | ||||||
|     float high = 0.0; |  | ||||||
|     for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) { |  | ||||||
|       block_t* block = &block_buffer[b]; |  | ||||||
|       if (block->steps.x || block->steps.y || block->steps.z) { |  | ||||||
|         const float se = (float)block->steps.e / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec; |  | ||||||
|         NOLESS(high, se); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     float t = autotemp_min + high * autotemp_factor; |  | ||||||
|     LIMIT(t, autotemp_min, autotemp_max); |  | ||||||
|     if (t < oldt) t = t * (1 - float(AUTOTEMP_OLDWEIGHT)) + oldt * float(AUTOTEMP_OLDWEIGHT); |  | ||||||
|     oldt = t; |  | ||||||
|     thermalManager.setTargetHotend(t, 0); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| #endif // AUTOTEMP |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Maintain fans, paste extruder pressure, |  * Maintain fans, paste extruder pressure, | ||||||
|  */ |  */ | ||||||
| @@ -1398,6 +1372,72 @@ void Planner::check_axes_activity() { | |||||||
|   #endif |   #endif | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #if ENABLED(AUTOTEMP) | ||||||
|  |  | ||||||
|  |   #if ENABLED(AUTOTEMP_PROPORTIONAL) | ||||||
|  |     void Planner::_autotemp_update_from_hotend() { | ||||||
|  |       const int16_t target = thermalManager.degTargetHotend(active_extruder); | ||||||
|  |       autotemp_min = target + AUTOTEMP_MIN_P; | ||||||
|  |       autotemp_max = target + AUTOTEMP_MAX_P; | ||||||
|  |     } | ||||||
|  |   #endif | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * Called after changing tools to: | ||||||
|  |    *  - Reset or re-apply the default proportional autotemp factor. | ||||||
|  |    *  - Enable autotemp if the factor is non-zero. | ||||||
|  |    */ | ||||||
|  |   void Planner::autotemp_update() { | ||||||
|  |     _autotemp_update_from_hotend(); | ||||||
|  |     autotemp_factor = TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0); | ||||||
|  |     autotemp_enabled = autotemp_factor != 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * Called by the M104/M109 commands after setting Hotend Temperature | ||||||
|  |    * | ||||||
|  |    */ | ||||||
|  |   void Planner::autotemp_M104_M109() { | ||||||
|  |     _autotemp_update_from_hotend(); | ||||||
|  |  | ||||||
|  |     if (parser.seenval('S')) autotemp_min = parser.value_celsius(); | ||||||
|  |     if (parser.seenval('B')) autotemp_max = parser.value_celsius(); | ||||||
|  |  | ||||||
|  |     // When AUTOTEMP_PROPORTIONAL is enabled, F0 disables autotemp. | ||||||
|  |     // Normally, leaving off F also disables autotemp. | ||||||
|  |     autotemp_factor = parser.seen('F') ? parser.value_float() : TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0); | ||||||
|  |     autotemp_enabled = autotemp_factor != 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * Called every so often to adjust the hotend target temperature | ||||||
|  |    * based on the extrusion speed, which is calculated from the blocks | ||||||
|  |    * currently in the planner. | ||||||
|  |    */ | ||||||
|  |   void Planner::getHighESpeed() { | ||||||
|  |     static float oldt = 0; | ||||||
|  |  | ||||||
|  |     if (!autotemp_enabled) return; | ||||||
|  |     if (thermalManager.degTargetHotend(active_extruder) < autotemp_min - 2) return; // Below the min? | ||||||
|  |  | ||||||
|  |     float high = 0.0; | ||||||
|  |     for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) { | ||||||
|  |       block_t* block = &block_buffer[b]; | ||||||
|  |       if (block->steps.x || block->steps.y || block->steps.z) { | ||||||
|  |         const float se = (float)block->steps.e / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec; | ||||||
|  |         NOLESS(high, se); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     float t = autotemp_min + high * autotemp_factor; | ||||||
|  |     LIMIT(t, autotemp_min, autotemp_max); | ||||||
|  |     if (t < oldt) t *= (1.0f - (AUTOTEMP_OLDWEIGHT)) + oldt * (AUTOTEMP_OLDWEIGHT); | ||||||
|  |     oldt = t; | ||||||
|  |     thermalManager.setTargetHotend(t, active_extruder); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #if DISABLED(NO_VOLUMETRICS) | #if DISABLED(NO_VOLUMETRICS) | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -2959,13 +2999,17 @@ void Planner::reset_acceleration_rates() { | |||||||
|   TERN_(HAS_LINEAR_E_JERK, recalculate_max_e_jerk()); |   TERN_(HAS_LINEAR_E_JERK, recalculate_max_e_jerk()); | ||||||
| } | } | ||||||
|  |  | ||||||
| // Recalculate position, steps_to_mm if settings.axis_steps_per_mm changes! | /** | ||||||
|  |  * Recalculate 'position' and 'steps_to_mm'. | ||||||
|  |  * Must be called whenever settings.axis_steps_per_mm changes! | ||||||
|  |  */ | ||||||
| void Planner::refresh_positioning() { | void Planner::refresh_positioning() { | ||||||
|   LOOP_XYZE_N(i) steps_to_mm[i] = 1.0f / settings.axis_steps_per_mm[i]; |   LOOP_XYZE_N(i) steps_to_mm[i] = 1.0f / settings.axis_steps_per_mm[i]; | ||||||
|   set_position_mm(current_position); |   set_position_mm(current_position); | ||||||
|   reset_acceleration_rates(); |   reset_acceleration_rates(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Apply limits to a variable and give a warning if the value was out of range | ||||||
| inline void limit_and_warn(float &val, const uint8_t axis, PGM_P const setting_name, const xyze_float_t &max_limit) { | inline void limit_and_warn(float &val, const uint8_t axis, PGM_P const setting_name, const xyze_float_t &max_limit) { | ||||||
|   const uint8_t lim_axis = axis > E_AXIS ? E_AXIS : axis; |   const uint8_t lim_axis = axis > E_AXIS ? E_AXIS : axis; | ||||||
|   const float before = val; |   const float before = val; | ||||||
| @@ -2978,7 +3022,14 @@ inline void limit_and_warn(float &val, const uint8_t axis, PGM_P const setting_n | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void Planner::set_max_acceleration(const uint8_t axis, float targetValue) { | /** | ||||||
|  |  * For the specified 'axis' set the Maximum Acceleration to the given value (mm/s^2) | ||||||
|  |  * The value may be limited with warning feedback, if configured. | ||||||
|  |  * Calls reset_acceleration_rates to precalculate planner terms in steps. | ||||||
|  |  * | ||||||
|  |  * This hard limit is applied as a block is being added to the planner queue. | ||||||
|  |  */ | ||||||
|  | void Planner::set_max_acceleration(const uint8_t axis, const float &inMaxAccelMMS2) { | ||||||
|   #if ENABLED(LIMITED_MAX_ACCEL_EDITING) |   #if ENABLED(LIMITED_MAX_ACCEL_EDITING) | ||||||
|     #ifdef MAX_ACCEL_EDIT_VALUES |     #ifdef MAX_ACCEL_EDIT_VALUES | ||||||
|       constexpr xyze_float_t max_accel_edit = MAX_ACCEL_EDIT_VALUES; |       constexpr xyze_float_t max_accel_edit = MAX_ACCEL_EDIT_VALUES; | ||||||
| @@ -2987,15 +3038,21 @@ void Planner::set_max_acceleration(const uint8_t axis, float targetValue) { | |||||||
|       constexpr xyze_float_t max_accel_edit = DEFAULT_MAX_ACCELERATION; |       constexpr xyze_float_t max_accel_edit = DEFAULT_MAX_ACCELERATION; | ||||||
|       const xyze_float_t max_acc_edit_scaled = max_accel_edit * 2; |       const xyze_float_t max_acc_edit_scaled = max_accel_edit * 2; | ||||||
|     #endif |     #endif | ||||||
|     limit_and_warn(targetValue, axis, PSTR("Acceleration"), max_acc_edit_scaled); |     limit_and_warn(inMaxAccelMMS2, axis, PSTR("Acceleration"), max_acc_edit_scaled); | ||||||
|   #endif |   #endif | ||||||
|   settings.max_acceleration_mm_per_s2[axis] = targetValue; |   settings.max_acceleration_mm_per_s2[axis] = inMaxAccelMMS2; | ||||||
|  |  | ||||||
|   // Update steps per s2 to agree with the units per s2 (since they are used in the planner) |   // Update steps per s2 to agree with the units per s2 (since they are used in the planner) | ||||||
|   reset_acceleration_rates(); |   reset_acceleration_rates(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Planner::set_max_feedrate(const uint8_t axis, float targetValue) { | /** | ||||||
|  |  * For the specified 'axis' set the Maximum Feedrate to the given value (mm/s) | ||||||
|  |  * The value may be limited with warning feedback, if configured. | ||||||
|  |  * | ||||||
|  |  * This hard limit is applied as a block is being added to the planner queue. | ||||||
|  |  */ | ||||||
|  | void Planner::set_max_feedrate(const uint8_t axis, const float &inMaxFeedrateMMS) { | ||||||
|   #if ENABLED(LIMITED_MAX_FR_EDITING) |   #if ENABLED(LIMITED_MAX_FR_EDITING) | ||||||
|     #ifdef MAX_FEEDRATE_EDIT_VALUES |     #ifdef MAX_FEEDRATE_EDIT_VALUES | ||||||
|       constexpr xyze_float_t max_fr_edit = MAX_FEEDRATE_EDIT_VALUES; |       constexpr xyze_float_t max_fr_edit = MAX_FEEDRATE_EDIT_VALUES; | ||||||
| @@ -3004,13 +3061,20 @@ void Planner::set_max_feedrate(const uint8_t axis, float targetValue) { | |||||||
|       constexpr xyze_float_t max_fr_edit = DEFAULT_MAX_FEEDRATE; |       constexpr xyze_float_t max_fr_edit = DEFAULT_MAX_FEEDRATE; | ||||||
|       const xyze_float_t max_fr_edit_scaled = max_fr_edit * 2; |       const xyze_float_t max_fr_edit_scaled = max_fr_edit * 2; | ||||||
|     #endif |     #endif | ||||||
|     limit_and_warn(targetValue, axis, PSTR("Feedrate"), max_fr_edit_scaled); |     limit_and_warn(inMaxFeedrateMMS, axis, PSTR("Feedrate"), max_fr_edit_scaled); | ||||||
|   #endif |   #endif | ||||||
|   settings.max_feedrate_mm_s[axis] = targetValue; |   settings.max_feedrate_mm_s[axis] = inMaxFeedrateMMS; | ||||||
| } | } | ||||||
|  |  | ||||||
| void Planner::set_max_jerk(const AxisEnum axis, float targetValue) { | #if HAS_CLASSIC_JERK | ||||||
|   #if HAS_CLASSIC_JERK |  | ||||||
|  |   /** | ||||||
|  |    * For the specified 'axis' set the Maximum Jerk (instant change) to the given value (mm/s) | ||||||
|  |    * The value may be limited with warning feedback, if configured. | ||||||
|  |    * | ||||||
|  |    * This hard limit is applied (to the block start speed) as the block is being added to the planner queue. | ||||||
|  |    */ | ||||||
|  |   void Planner::set_max_jerk(const AxisEnum axis, const float &targetValue) { | ||||||
|     #if ENABLED(LIMITED_JERK_EDITING) |     #if ENABLED(LIMITED_JERK_EDITING) | ||||||
|       constexpr xyze_float_t max_jerk_edit = |       constexpr xyze_float_t max_jerk_edit = | ||||||
|         #ifdef MAX_JERK_EDIT_VALUES |         #ifdef MAX_JERK_EDIT_VALUES | ||||||
| @@ -3023,10 +3087,9 @@ void Planner::set_max_jerk(const AxisEnum axis, float targetValue) { | |||||||
|       limit_and_warn(targetValue, axis, PSTR("Jerk"), max_jerk_edit); |       limit_and_warn(targetValue, axis, PSTR("Jerk"), max_jerk_edit); | ||||||
|     #endif |     #endif | ||||||
|     max_jerk[axis] = targetValue; |     max_jerk[axis] = targetValue; | ||||||
|   #else |   } | ||||||
|     UNUSED(axis); UNUSED(targetValue); |  | ||||||
|   #endif | #endif | ||||||
| } |  | ||||||
|  |  | ||||||
| #if HAS_WIRED_LCD | #if HAS_WIRED_LCD | ||||||
|  |  | ||||||
| @@ -3069,33 +3132,3 @@ void Planner::set_max_jerk(const AxisEnum axis, float targetValue) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if ENABLED(AUTOTEMP) |  | ||||||
|  |  | ||||||
| void Planner::autotemp_update() { |  | ||||||
|   #if ENABLED(AUTOTEMP_PROPORTIONAL) |  | ||||||
|     const int16_t target = thermalManager.degTargetHotend(active_extruder); |  | ||||||
|     autotemp_min = target + AUTOTEMP_MIN_P; |  | ||||||
|     autotemp_max = target + AUTOTEMP_MAX_P; |  | ||||||
|   #endif |  | ||||||
|   autotemp_factor = TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0); |  | ||||||
|   autotemp_enabled = autotemp_factor != 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|   void Planner::autotemp_M104_M109() { |  | ||||||
|  |  | ||||||
|     #if ENABLED(AUTOTEMP_PROPORTIONAL) |  | ||||||
|       const int16_t target = thermalManager.degTargetHotend(active_extruder); |  | ||||||
|       autotemp_min = target + AUTOTEMP_MIN_P; |  | ||||||
|       autotemp_max = target + AUTOTEMP_MAX_P; |  | ||||||
|     #endif |  | ||||||
|  |  | ||||||
|     if (parser.seenval('S')) autotemp_min = parser.value_celsius(); |  | ||||||
|     if (parser.seenval('B')) autotemp_max = parser.value_celsius(); |  | ||||||
|  |  | ||||||
|     // When AUTOTEMP_PROPORTIONAL is enabled, F0 disables autotemp. |  | ||||||
|     // Normally, leaving off F also disables autotemp. |  | ||||||
|     autotemp_factor = parser.seen('F') ? parser.value_float() : TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0); |  | ||||||
|     autotemp_enabled = autotemp_factor != 0; |  | ||||||
|   } |  | ||||||
| #endif |  | ||||||
|   | |||||||
| @@ -460,12 +460,27 @@ class Planner { | |||||||
|      * Static (class) Methods |      * Static (class) Methods | ||||||
|      */ |      */ | ||||||
|  |  | ||||||
|  |     // Recalculate steps/s^2 accelerations based on mm/s^2 settings | ||||||
|     static void reset_acceleration_rates(); |     static void reset_acceleration_rates(); | ||||||
|     static void refresh_positioning(); |  | ||||||
|     static void set_max_acceleration(const uint8_t axis, float targetValue); |  | ||||||
|     static void set_max_feedrate(const uint8_t axis, float targetValue); |  | ||||||
|     static void set_max_jerk(const AxisEnum axis, float targetValue); |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Recalculate 'position' and 'steps_to_mm'. | ||||||
|  |      * Must be called whenever settings.axis_steps_per_mm changes! | ||||||
|  |      */ | ||||||
|  |     static void refresh_positioning(); | ||||||
|  |  | ||||||
|  |     // For an axis set the Maximum Acceleration in mm/s^2 | ||||||
|  |     static void set_max_acceleration(const uint8_t axis, const float &inMaxAccelMMS2); | ||||||
|  |  | ||||||
|  |     // For an axis set the Maximum Feedrate in mm/s | ||||||
|  |     static void set_max_feedrate(const uint8_t axis, const float &inMaxFeedrateMMS); | ||||||
|  |  | ||||||
|  |     // For an axis set the Maximum Jerk (instant change) in mm/s | ||||||
|  |     #if HAS_CLASSIC_JERK | ||||||
|  |       static void set_max_jerk(const AxisEnum axis, const float &inMaxJerkMMS); | ||||||
|  |     #else | ||||||
|  |       static inline void set_max_jerk(const AxisEnum, const float&) {} | ||||||
|  |     #endif | ||||||
|  |  | ||||||
|     #if EXTRUDERS |     #if EXTRUDERS | ||||||
|       FORCE_INLINE static void refresh_e_factor(const uint8_t e) { |       FORCE_INLINE static void refresh_e_factor(const uint8_t e) { | ||||||
| @@ -883,9 +898,9 @@ class Planner { | |||||||
|     #if ENABLED(AUTOTEMP) |     #if ENABLED(AUTOTEMP) | ||||||
|       static float autotemp_min, autotemp_max, autotemp_factor; |       static float autotemp_min, autotemp_max, autotemp_factor; | ||||||
|       static bool autotemp_enabled; |       static bool autotemp_enabled; | ||||||
|       static void getHighESpeed(); |  | ||||||
|       static void autotemp_M104_M109(); |  | ||||||
|       static void autotemp_update(); |       static void autotemp_update(); | ||||||
|  |       static void autotemp_M104_M109(); | ||||||
|  |       static void getHighESpeed(); | ||||||
|     #endif |     #endif | ||||||
|  |  | ||||||
|     #if HAS_LINEAR_E_JERK |     #if HAS_LINEAR_E_JERK | ||||||
| @@ -898,6 +913,14 @@ class Planner { | |||||||
|  |  | ||||||
|   private: |   private: | ||||||
|  |  | ||||||
|  |     #if ENABLED(AUTOTEMP) | ||||||
|  |       #if ENABLED(AUTOTEMP_PROPORTIONAL) | ||||||
|  |         static void _autotemp_update_from_hotend(); | ||||||
|  |       #else | ||||||
|  |         static inline void _autotemp_update_from_hotend() {} | ||||||
|  |       #endif | ||||||
|  |     #endif | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get the index of the next / previous block in the ring buffer |      * Get the index of the next / previous block in the ring buffer | ||||||
|      */ |      */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user