blob: 91cf7aad28fb0aae87b140598024cde61404be34 [file]
#include "tlbmc/thermal/controller/algorithm/dff.h"
#include <algorithm>
#include <limits>
#include "absl/log/log.h"
#include "absl/strings/str_format.h"
namespace milotic_tlbmc {
namespace thermal {
double DffThermalLoop::ApplyLowPassFilterToDisturbance(
double disturbance, bool enable_calculation_log) const {
double filtered_disturbance = GetCoeffH1() * disturbance +
GetCoeffH2() * GetLastDisturbance() +
GetCoeffH3() * GetLastFilteredDisturbance();
if (enable_calculation_log) {
LOG(WARNING)
<< "[Thermal Debug]: "
<< absl::StrFormat(
"After applying low-pass filter, filtered disturbance: %lf, "
"with input disturbance: %lf, previous disturbance: %lf, and "
"previous filtered disturbance: %lf",
filtered_disturbance, disturbance, GetLastDisturbance(),
GetLastFilteredDisturbance());
}
return filtered_disturbance;
}
double DffThermalLoop::ExecuteDffLoop(double disturbance,
bool enable_calculation_log) {
// Apply low pass filter on the disturbance measurement to attenuate
// high-frequency components that the feedforward controller cannot
// effectively handle.
double filtered_disturbance =
ApplyLowPassFilterToDisturbance(disturbance, enable_calculation_log);
double dff_value =
GetCoeffF1() * (filtered_disturbance - GetReferencePower()) +
GetCoeffF2() * (GetLastFilteredDisturbance() - GetReferencePower()) +
GetCoeffF3() * GetLastDffValue();
SetLastDisturbance(disturbance);
SetLastFilteredDisturbance(filtered_disturbance);
SetLastDffValue(dff_value);
double output = dff_value;
if (enable_calculation_log) {
LOG(WARNING) << "[Thermal Debug]: "
<< absl::StrFormat(
"F1: %lf; F2: %lf; F3: %lf; H1: %lf; H2: %lf; H3: "
"%lf; output: %lf; disturbance: %lf; last "
"disturbance: %lf; last filtered disturbance: %lf; "
"last DFF value: %lf",
GetCoeffF1(), GetCoeffF2(), GetCoeffF3(), GetCoeffH1(),
GetCoeffH2(), GetCoeffH3(), output, disturbance,
GetLastDisturbance(), GetLastFilteredDisturbance(),
GetLastDffValue());
}
// Apply slew rate clamping
double min_output = std::numeric_limits<double>::lowest();
double max_output = std::numeric_limits<double>::max();
if (GetSlewNeg() < -1.0) {
min_output = GetLastOutput() + GetSlewNeg() * GetSampleTime();
}
if (GetSlewPos() > 1.0) {
max_output = GetLastOutput() + GetSlewPos() * GetSampleTime();
}
output = std::clamp(output, min_output, max_output);
if (enable_calculation_log) {
LOG(WARNING)
<< "[Thermal Debug]: "
<< absl::StrFormat(
"Slew rate clamped DFF output: %lf (slew_neg: %lf, slew_pos: "
"%lf); last output: %lf",
output, GetSlewNeg(), GetSlewPos(), GetLastOutput());
}
SetLastOutput(output);
return output;
}
} // namespace thermal
} // namespace milotic_tlbmc