diff --git a/Marlin/src/module/temperature.h b/Marlin/src/module/temperature.h index b0cb3d778e..51fa6f1eff 100644 --- a/Marlin/src/module/temperature.h +++ b/Marlin/src/module/temperature.h @@ -177,68 +177,68 @@ typedef struct { float p, i, d, c, f; } raw_pidcf_t; /// PID classes that implement these features are expected to override these methods /// Since the finally used PID class is typedef-d, there is no need to use virtual functions template - struct PID_t{ - protected: - bool pid_reset = true; - float temp_iState = 0.0f, temp_dState = 0.0f; - float work_p = 0, work_i = 0, work_d = 0; + struct PID_t { + protected: + bool pid_reset = true; + float temp_iState = 0.0f, temp_dState = 0.0f; + float work_p = 0, work_i = 0, work_d = 0; - public: - float Kp = 0, Ki = 0, Kd = 0; - float p() const { return Kp; } - float i() const { return unscalePID_i(Ki); } - float d() const { return unscalePID_d(Kd); } - float c() const { return 1; } - float f() const { return 0; } - float pTerm() const { return work_p; } - float iTerm() const { return work_i; } - float dTerm() const { return work_d; } - float cTerm() const { return 0; } - float fTerm() const { return 0; } - void set_Kp(float p) { Kp = p; } - void set_Ki(float i) { Ki = scalePID_i(i); } - void set_Kd(float d) { Kd = scalePID_d(d); } - void set_Kc(float) {} - void set_Kf(float) {} - int low() const { return MIN_POW; } - int high() const { return MAX_POW; } - void reset() { pid_reset = true; } - void set(float p, float i, float d, float c=1, float f=0) { set_Kp(p); set_Ki(i); set_Kd(d); set_Kc(c); set_Kf(f); } - void set(const raw_pid_t &raw) { set(raw.p, raw.i, raw.d); } - void set(const raw_pidcf_t &raw) { set(raw.p, raw.i, raw.d, raw.c, raw.f); } + public: + float Kp = 0, Ki = 0, Kd = 0; + float p() const { return Kp; } + float i() const { return unscalePID_i(Ki); } + float d() const { return unscalePID_d(Kd); } + float c() const { return 1; } + float f() const { return 0; } + float pTerm() const { return work_p; } + float iTerm() const { return work_i; } + float dTerm() const { return work_d; } + float cTerm() const { return 0; } + float fTerm() const { return 0; } + void set_Kp(float p) { Kp = p; } + void set_Ki(float i) { Ki = scalePID_i(i); } + void set_Kd(float d) { Kd = scalePID_d(d); } + void set_Kc(float) {} + void set_Kf(float) {} + int low() const { return MIN_POW; } + int high() const { return MAX_POW; } + void reset() { pid_reset = true; } + void set(float p, float i, float d, float c=1, float f=0) { set_Kp(p); set_Ki(i); set_Kd(d); set_Kc(c); set_Kf(f); } + void set(const raw_pid_t &raw) { set(raw.p, raw.i, raw.d); } + void set(const raw_pidcf_t &raw) { set(raw.p, raw.i, raw.d, raw.c, raw.f); } - float get_fan_scale_output(const uint8_t) { return 0; } + float get_fan_scale_output(const uint8_t) { return 0; } - float get_extrusion_scale_output(const bool, const int32_t, const float, const int16_t) { return 0; } + float get_extrusion_scale_output(const bool, const int32_t, const float, const int16_t) { return 0; } - float get_pid_output(const float target, const float current) { - const float pid_error = target - current; - if (!target || pid_error < -(PID_FUNCTIONAL_RANGE)) { - pid_reset = true; - return 0; + float get_pid_output(const float target, const float current) { + const float pid_error = target - current; + if (!target || pid_error < -(PID_FUNCTIONAL_RANGE)) { + pid_reset = true; + return 0; + } + else if (pid_error > PID_FUNCTIONAL_RANGE) { + pid_reset = true; + return MAX_POW; + } + + if (pid_reset) { + pid_reset = false; + temp_iState = 0.0; + work_d = 0.0; + } + + const float max_power_over_i_gain = float(MAX_POW) / Ki - float(MIN_POW); + temp_iState = constrain(temp_iState + pid_error, 0, max_power_over_i_gain); + + work_p = Kp * pid_error; + work_i = Ki * temp_iState; + work_d = work_d + PID_K2 * (Kd * (temp_dState - current) - work_d); + + temp_dState = current; + + return constrain(work_p + work_i + work_d + float(MIN_POW), 0, MAX_POW); } - else if (pid_error > PID_FUNCTIONAL_RANGE) { - pid_reset = true; - return MAX_POW; - } - - if (pid_reset) { - pid_reset = false; - temp_iState = 0.0; - work_d = 0.0; - } - - const float max_power_over_i_gain = float(MAX_POW) / Ki - float(MIN_POW); - temp_iState = constrain(temp_iState + pid_error, 0, max_power_over_i_gain); - - work_p = Kp * pid_error; - work_i = Ki * temp_iState; - work_d = work_d + PID_K2 * (Kd * (temp_dState - current) - work_d); - - temp_dState = current; - - return constrain(work_p + work_i + work_d + float(MIN_POW), 0, MAX_POW); - } }; @@ -249,53 +249,53 @@ typedef struct { float p, i, d, c, f; } raw_pidcf_t; /// @brief Extrusion scaled PID class template struct PIDC_t : public PID_t { - private: - using base = PID_t; - float work_c = 0; - float prev_e_pos = 0; - int32_t lpq[LPQ_ARR_SZ] = {}; - int16_t lpq_ptr = 0; - public: - float Kc = 0; - float c() const { return Kc; } - void set_Kc(float c) { Kc = c; } - float cTerm() const { return work_c; } - void set(float p, float i, float d, float c=1, float f=0) { - base::set_Kp(p); - base::set_Ki(i); - base::set_Kd(d); - set_Kc(c); - base::set_Kf(f); - } - void set(const raw_pid_t &raw) { set(raw.p, raw.i, raw.d); } - void set(const raw_pidcf_t &raw) { set(raw.p, raw.i, raw.d, raw.c, raw.f); } - void reset() { - base::reset(); - prev_e_pos = 0; - lpq_ptr = 0; - for (uint8_t i = 0; i < LPQ_ARR_SZ; ++i) lpq[i] = 0; - } - - float get_extrusion_scale_output(const bool is_active, const int32_t e_position, const float e_mm_per_step, const int16_t lpq_len) { - work_c = 0; - if (!is_active) return work_c; - - if (e_position > prev_e_pos) { - lpq[lpq_ptr] = e_position - prev_e_pos; - prev_e_pos = e_position; + private: + using base = PID_t; + float work_c = 0; + float prev_e_pos = 0; + int32_t lpq[LPQ_ARR_SZ] = {}; + int16_t lpq_ptr = 0; + public: + float Kc = 0; + float c() const { return Kc; } + void set_Kc(float c) { Kc = c; } + float cTerm() const { return work_c; } + void set(float p, float i, float d, float c=1, float f=0) { + base::set_Kp(p); + base::set_Ki(i); + base::set_Kd(d); + set_Kc(c); + base::set_Kf(f); } - else - lpq[lpq_ptr] = 0; - - ++lpq_ptr; - - if (lpq_ptr >= LPQ_ARR_SZ || lpq_ptr >= lpq_len) + void set(const raw_pid_t &raw) { set(raw.p, raw.i, raw.d); } + void set(const raw_pidcf_t &raw) { set(raw.p, raw.i, raw.d, raw.c, raw.f); } + void reset() { + base::reset(); + prev_e_pos = 0; lpq_ptr = 0; + for (uint8_t i = 0; i < LPQ_ARR_SZ; ++i) lpq[i] = 0; + } - work_c = (lpq[lpq_ptr] * e_mm_per_step) * Kc; + float get_extrusion_scale_output(const bool is_active, const int32_t e_position, const float e_mm_per_step, const int16_t lpq_len) { + work_c = 0; + if (!is_active) return work_c; - return work_c; - } + if (e_position > prev_e_pos) { + lpq[lpq_ptr] = e_position - prev_e_pos; + prev_e_pos = e_position; + } + else + lpq[lpq_ptr] = 0; + + ++lpq_ptr; + + if (lpq_ptr >= LPQ_ARR_SZ || lpq_ptr >= lpq_len) + lpq_ptr = 0; + + work_c = (lpq[lpq_ptr] * e_mm_per_step) * Kc; + + return work_c; + } }; /// @brief Fan scaled PID, this class implements the get_fan_scale_output() method @@ -305,67 +305,67 @@ typedef struct { float p, i, d, c, f; } raw_pidcf_t; /// @tparam SCALE_LIN_FACTOR parameter from Configuration_adv.h template struct PIDF_t : public PID_t { - private: - using base = PID_t; - float work_f = 0; - public: - float Kf = 0; - float f() const { return Kf; } - void set_Kf(float f) { Kf = f; } - float fTerm() const { return work_f; } - void set(float p, float i, float d, float c=1, float f=0) { - base::set_Kp(p); - base::set_Ki(i); - base::set_Kd(d); - base::set_Kc(c); - set_Kf(f); - } - void set(const raw_pid_t &raw) { set(raw.p, raw.i, raw.d); } - void set(const raw_pidcf_t &raw) { set(raw.p, raw.i, raw.d, raw.c, raw.f); } + private: + using base = PID_t; + float work_f = 0; + public: + float Kf = 0; + float f() const { return Kf; } + void set_Kf(float f) { Kf = f; } + float fTerm() const { return work_f; } + void set(float p, float i, float d, float c=1, float f=0) { + base::set_Kp(p); + base::set_Ki(i); + base::set_Kd(d); + base::set_Kc(c); + set_Kf(f); + } + void set(const raw_pid_t &raw) { set(raw.p, raw.i, raw.d); } + void set(const raw_pidcf_t &raw) { set(raw.p, raw.i, raw.d, raw.c, raw.f); } - float get_fan_scale_output(const uint8_t fan_speed) { - work_f = 0; - if (fan_speed > SCALE_MIN_SPEED) - work_f = Kf + (SCALE_LIN_FACTOR) * fan_speed; + float get_fan_scale_output(const uint8_t fan_speed) { + work_f = 0; + if (fan_speed > SCALE_MIN_SPEED) + work_f = Kf + (SCALE_LIN_FACTOR) * fan_speed; - return work_f; - } + return work_f; + } }; /// @brief Inherits PID and PIDC - can't use proper diamond inheritance w/o virtual template struct PIDCF_t : public PIDC_t { - private: - using base = PID_t; - using cPID = PIDC_t; - float work_f = 0; - public: - float Kf = 0; - float c() const { return cPID::c(); } - float f() const { return Kf; } - void set_Kc(float c) { cPID::set_Kc(c); } - void set_Kf(float f) { Kf = f; } - float cTerm() const { return cPID::cTerm(); } - float fTerm() const { return work_f; } - void set(float p, float i, float d, float c=1, float f=0) { - base::set_Kp(p); - base::set_Ki(i); - base::set_Kd(d); - cPID::set_Kc(c); - set_Kf(f); - } - void set(const raw_pid_t &raw) { set(raw.p, raw.i, raw.d); } - void set(const raw_pidcf_t &raw) { set(raw.p, raw.i, raw.d, raw.c, raw.f); } + private: + using base = PID_t; + using cPID = PIDC_t; + float work_f = 0; + public: + float Kf = 0; + float c() const { return cPID::c(); } + float f() const { return Kf; } + void set_Kc(float c) { cPID::set_Kc(c); } + void set_Kf(float f) { Kf = f; } + float cTerm() const { return cPID::cTerm(); } + float fTerm() const { return work_f; } + void set(float p, float i, float d, float c=1, float f=0) { + base::set_Kp(p); + base::set_Ki(i); + base::set_Kd(d); + cPID::set_Kc(c); + set_Kf(f); + } + void set(const raw_pid_t &raw) { set(raw.p, raw.i, raw.d); } + void set(const raw_pidcf_t &raw) { set(raw.p, raw.i, raw.d, raw.c, raw.f); } - void reset() { cPID::reset(); } + void reset() { cPID::reset(); } - float get_fan_scale_output(const uint8_t fan_speed) { - work_f = fan_speed > (SCALE_MIN_SPEED) ? Kf + (SCALE_LIN_FACTOR) * fan_speed : 0; - return work_f; - } - float get_extrusion_scale_output(const bool is_active, const int32_t e_position, const float e_mm_per_step, const int16_t lpq_len) { - return cPID::get_extrusion_scale_output(is_active, e_position, e_mm_per_step, lpq_len); - } + float get_fan_scale_output(const uint8_t fan_speed) { + work_f = fan_speed > (SCALE_MIN_SPEED) ? Kf + (SCALE_LIN_FACTOR) * fan_speed : 0; + return work_f; + } + float get_extrusion_scale_output(const bool is_active, const int32_t e_position, const float e_mm_per_step, const int16_t lpq_len) { + return cPID::get_extrusion_scale_output(is_active, e_position, e_mm_per_step, lpq_len); + } }; typedef @@ -415,16 +415,16 @@ typedef struct { float p, i, d, c, f; } raw_pidcf_t; // A temperature sensor typedef struct TempInfo { -private: - raw_adc_t acc; - raw_adc_t raw; -public: - celsius_float_t celsius; - inline void reset() { acc = 0; } - inline void sample(const raw_adc_t s) { acc += s; } - inline void update() { raw = acc; } - void setraw(const raw_adc_t r) { raw = r; } - raw_adc_t getraw() const { return raw; } + private: + raw_adc_t acc; + raw_adc_t raw; + public: + celsius_float_t celsius; + inline void reset() { acc = 0; } + inline void sample(const raw_adc_t s) { acc += s; } + inline void update() { raw = acc; } + void setraw(const raw_adc_t r) { raw = r; } + raw_adc_t getraw() const { return raw; } } temp_info_t; #if HAS_TEMP_REDUNDANT