E1+ Autotemp and Planner comments

This commit is contained in:
Scott Lahteine 2021-03-16 15:12:28 -05:00
parent 15bda88d04
commit 9823a37362
3 changed files with 131 additions and 77 deletions

View File

@ -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

View File

@ -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,11 +3087,10 @@ 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
uint16_t Planner::block_buffer_runtime() { uint16_t Planner::block_buffer_runtime() {
@ -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

View File

@ -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
*/ */