| #ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_THERMAL_CONTROLLER_DFF_H_ |
| #define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_THERMAL_CONTROLLER_DFF_H_ |
| |
| #include "thermal_config.pb.h" |
| |
| namespace milotic_tlbmc { |
| namespace thermal { |
| |
| /* |
| * `DffThermalLoop` is the Dynamic Feedforward thermal loop, which is usually |
| * used as an additional term to stablize the PID thermal loop: go/dff-neutron |
| * |
| * This feedforward controller will take signals that are causatively related |
| * with temperature increment, and derive a supportive setpoint, to provide a |
| * compensation to the feedback controllers (e.g., PID) to help the system |
| * converge to a stable setpoint more swiftly. |
| * |
| * This class is not thread-safe. |
| * |
| * More materials can be found at: |
| * https://control.com/textbook/basic-process-control-strategies/feedforward-with-dynamic-compensation/ |
| */ |
| class DffThermalLoop { |
| public: |
| DffThermalLoop() = default; |
| |
| explicit DffThermalLoop(const DffLoopConfig& dff_params) |
| : dff_params_(dff_params) { |
| // If no valid sample time is provided, set it to 1 by default. |
| if (dff_params.sample_time_sec() <= 0) { |
| dff_params_.set_sample_time_sec(1.0); |
| } |
| } |
| |
| /* |
| * `ExecuteDffLoop` performs exactly one iteration of a DFF loop with the |
| * current input. |
| */ |
| double ExecuteDffLoop(double disturbance, |
| bool enable_calculation_log = false); |
| |
| void SetLastDisturbance(double last_disturbance) { |
| last_disturbance_ = last_disturbance; |
| } |
| void SetLastFilteredDisturbance(double last_filtered_disturbance) { |
| last_filtered_disturbance_ = last_filtered_disturbance; |
| } |
| void SetLastDffValue(double last_dff_value) { |
| last_dff_value_ = last_dff_value; |
| } |
| void SetLastOutput(double last_dff_output) { last_output_ = last_dff_output; } |
| |
| double GetLastDisturbance() const { return last_disturbance_; } |
| double GetLastFilteredDisturbance() const { |
| return last_filtered_disturbance_; |
| } |
| double GetLastDffValue() const { return last_dff_value_; } |
| double GetLastOutput() const { return last_output_; } |
| |
| double GetSampleTime() const { return dff_params_.sample_time_sec(); } |
| void SetCoeffH1(double coeff_h1) { dff_params_.set_coeff_h1(coeff_h1); } |
| double GetCoeffH1() const { return dff_params_.coeff_h1(); } |
| void SetCoeffH2(double coeff_h2) { dff_params_.set_coeff_h2(coeff_h2); } |
| double GetCoeffH2() const { return dff_params_.coeff_h2(); } |
| void SetCoeffH3(double coeff_h3) { dff_params_.set_coeff_h3(coeff_h3); } |
| double GetCoeffH3() const { return dff_params_.coeff_h3(); } |
| void SetCoeffF1(double coeff_f1) { dff_params_.set_coeff_f1(coeff_f1); } |
| double GetCoeffF1() const { return dff_params_.coeff_f1(); } |
| void SetCoeffF2(double coeff_f2) { dff_params_.set_coeff_f2(coeff_f2); } |
| double GetCoeffF2() const { return dff_params_.coeff_f2(); } |
| void SetCoeffF3(double coeff_f3) { dff_params_.set_coeff_f3(coeff_f3); } |
| double GetCoeffF3() const { return dff_params_.coeff_f3(); } |
| void SetReferencePower(double reference_power) { |
| dff_params_.set_reference_power(reference_power); |
| } |
| double GetReferencePower() const { return dff_params_.reference_power(); } |
| double GetOutputLimitMax() const { return dff_params_.output_limit_max(); } |
| double GetOutputLimitMin() const { return dff_params_.output_limit_min(); } |
| double GetSlewNeg() const { return dff_params_.slew_neg(); } |
| double GetSlewPos() const { return dff_params_.slew_pos(); } |
| |
| protected: |
| /* |
| * `ApplyLowPassFilterToDisturbance` applies a low pass filter to the |
| * disturbance signal, in order to mitigate the effects of high-frequency |
| * noise in the disturbance signal. This will help prevent noise amplification |
| * and reduce the risk of instability. |
| * |
| * This is usually done before the DFF calculation. |
| * |
| * Reference: |
| * https://web.mit.edu/6.055/notes/r09-abstraction-low-pass.pdf |
| */ |
| double ApplyLowPassFilterToDisturbance( |
| double disturbance, bool enable_calculation_log = false) const; |
| |
| private: |
| double last_disturbance_ = 0.0; // The last disturbance value. |
| double last_filtered_disturbance_ = |
| 0.0; // The last filtered disturbance value. |
| double last_dff_value_ = 0.0; // The last DFF calculated value. |
| double last_output_ = 0.0; // The last output (e.g., DFF value affected by |
| // slew rate clamping). |
| |
| DffLoopConfig dff_params_; // The parameters for this DFF thermal loop. |
| }; |
| |
| } // namespace thermal |
| } // namespace milotic_tlbmc |
| |
| #endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_THERMAL_CONTROLLER_DFF_H_ |