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) { | ||||
|     planner.set_max_acceleration(axis, value); | ||||
|     planner.reset_acceleration_rates(); | ||||
|   } | ||||
|  | ||||
|   void setAxisMaxAcceleration_mm_s2(const float &value, const extruder_t extruder) { | ||||
|     UNUSED_E(extruder); | ||||
|     planner.set_max_acceleration(E_AXIS_N(extruder - E0), value); | ||||
|     planner.reset_acceleration_rates(); | ||||
|   } | ||||
|  | ||||
|   #if HAS_FILAMENT_SENSOR | ||||
|   | ||||
| @@ -1248,32 +1248,6 @@ void Planner::recalculate() { | ||||
|   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, | ||||
|  */ | ||||
| @@ -1398,6 +1372,72 @@ void Planner::check_axes_activity() { | ||||
|   #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) | ||||
|  | ||||
|   /** | ||||
| @@ -2959,13 +2999,17 @@ void Planner::reset_acceleration_rates() { | ||||
|   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() { | ||||
|   LOOP_XYZE_N(i) steps_to_mm[i] = 1.0f / settings.axis_steps_per_mm[i]; | ||||
|   set_position_mm(current_position); | ||||
|   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) { | ||||
|   const uint8_t lim_axis = axis > E_AXIS ? E_AXIS : axis; | ||||
|   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) | ||||
|     #ifdef 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; | ||||
|       const xyze_float_t max_acc_edit_scaled = max_accel_edit * 2; | ||||
|     #endif | ||||
|     limit_and_warn(targetValue, axis, PSTR("Acceleration"), max_acc_edit_scaled); | ||||
|     limit_and_warn(inMaxAccelMMS2, axis, PSTR("Acceleration"), max_acc_edit_scaled); | ||||
|   #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) | ||||
|   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) | ||||
|     #ifdef 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; | ||||
|       const xyze_float_t max_fr_edit_scaled = max_fr_edit * 2; | ||||
|     #endif | ||||
|     limit_and_warn(targetValue, axis, PSTR("Feedrate"), max_fr_edit_scaled); | ||||
|     limit_and_warn(inMaxFeedrateMMS, axis, PSTR("Feedrate"), max_fr_edit_scaled); | ||||
|   #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 | ||||
|  | ||||
|   /** | ||||
|    * 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) | ||||
|       constexpr xyze_float_t max_jerk_edit = | ||||
|         #ifdef MAX_JERK_EDIT_VALUES | ||||
| @@ -3023,11 +3087,10 @@ void Planner::set_max_jerk(const AxisEnum axis, float targetValue) { | ||||
|       limit_and_warn(targetValue, axis, PSTR("Jerk"), max_jerk_edit); | ||||
|     #endif | ||||
|     max_jerk[axis] = targetValue; | ||||
|   #else | ||||
|     UNUSED(axis); UNUSED(targetValue); | ||||
|   #endif | ||||
|   } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if HAS_WIRED_LCD | ||||
|  | ||||
|   uint16_t Planner::block_buffer_runtime() { | ||||
| @@ -3069,33 +3132,3 @@ void Planner::set_max_jerk(const AxisEnum axis, float targetValue) { | ||||
|   } | ||||
|  | ||||
| #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 | ||||
|      */ | ||||
|  | ||||
|     // Recalculate steps/s^2 accelerations based on mm/s^2 settings | ||||
|     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 | ||||
|       FORCE_INLINE static void refresh_e_factor(const uint8_t e) { | ||||
| @@ -883,9 +898,9 @@ class Planner { | ||||
|     #if ENABLED(AUTOTEMP) | ||||
|       static float autotemp_min, autotemp_max, autotemp_factor; | ||||
|       static bool autotemp_enabled; | ||||
|       static void getHighESpeed(); | ||||
|       static void autotemp_M104_M109(); | ||||
|       static void autotemp_update(); | ||||
|       static void autotemp_M104_M109(); | ||||
|       static void getHighESpeed(); | ||||
|     #endif | ||||
|  | ||||
|     #if HAS_LINEAR_E_JERK | ||||
| @@ -898,6 +913,14 @@ class Planner { | ||||
|  | ||||
|   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 | ||||
|      */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user