Skip to content

Commit

Permalink
E1+ Autotemp and Planner comments
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkyhead committed Mar 18, 2021
1 parent 15bda88 commit 9823a37
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 76 deletions.
2 changes: 0 additions & 2 deletions Marlin/src/lcd/extui/ui_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
171 changes: 102 additions & 69 deletions Marlin/src/module/planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
*/
Expand Down Expand Up @@ -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)

/**
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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
#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
Expand All @@ -3023,10 +3087,9 @@ 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

Expand Down Expand Up @@ -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
33 changes: 28 additions & 5 deletions Marlin/src/module/planner.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

/**
* Recalculate 'position' and 'steps_to_mm'.
* Must be called whenever settings.axis_steps_per_mm changes!
*/
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);

// 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) {
Expand Down Expand Up @@ -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
Expand All @@ -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
*/
Expand Down

1 comment on commit 9823a37

@GhostlyCrowd
Copy link
Contributor

@GhostlyCrowd GhostlyCrowd commented on 9823a37 Mar 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit breaks building on the SKR Pro for me. Reverting this commit allows me to build with bugfix up to day as of 10 minutes ago. The is error below.

Marlin\src\module\planner.cpp: In static member function 'static void Planner::set_max_feedrate(uint8_t, const float&)':
Marlin\src\module\planner.cpp:3064:20: error: binding reference of type 'float&' to 'const float' discards qualifiers
 3064 |     limit_and_warn(inMaxFeedrateMMS, axis, PSTR("Feedrate"), max_fr_edit_scaled);
      |                    ^~~~~~~~~~~~~~~~
Marlin\src\module\planner.cpp:3013:35: note:   initializing argument 1 of 'void limit_and_warn(float&, uint8_t, const char*, const xyze_float_t&)'
 3013 | inline void limit_and_warn(float &val, const uint8_t axis, PGM_P const setting_name, const xyze_float_t &max_limit) {
      |                            ~~~~~~~^~~
Marlin\src\module\planner.cpp: In static member function 'static void Planner::set_max_jerk(AxisEnum, const float&)':
Marlin\src\module\planner.cpp:3087:22: error: binding reference of type 'float&' to 'const float' discards qualifiers
 3087 |       limit_and_warn(targetValue, axis, PSTR("Jerk"), max_jerk_edit);
      |                      ^~~~~~~~~~~
Marlin\src\module\planner.cpp:3013:35: note:   initializing argument 1 of 'void limit_and_warn(float&, uint8_t, const char*, const xyze_float_t&)'
 3013 | inline void limit_and_warn(float &val, const uint8_t axis, PGM_P const setting_name, const xyze_float_t &max_limit) {
      |                            ~~~~~~~^~~
*** [.pio\build\BIGTREE_SKR_PRO\src\src\module\planner.cpp.o] Error 1

Please sign in to comment.