Integrate FRE into tlBMC Thermal Control

Google-Bug-Id:559754428
PiperOrigin-RevId: 981443487
Change-Id: Ibe6638451e39d830b31907006cd0ea094d6881f5
diff --git a/tlbmc/collector/thermal_collector.cc b/tlbmc/collector/thermal_collector.cc
index a3af7d3..7456c04 100644
--- a/tlbmc/collector/thermal_collector.cc
+++ b/tlbmc/collector/thermal_collector.cc
@@ -37,6 +37,7 @@
 #include "tlbmc/thermal/controller/eat_controller.h"
 #include "tlbmc/thermal/controller/fan_pid_controller.h"
 #include "tlbmc/thermal/controller/first_order_adrc_controller.h"
+#include "tlbmc/thermal/controller/optimizer/pid/frequency_response_estimation/frequency_response_estimation.h"
 #include "tlbmc/thermal/controller/optimizer/pid/pid_optimizer.h"
 #include "tlbmc/thermal/controller/optimizer/pid/ziegler_nichols/differentiated_ziegler_nichols.h"
 #include "tlbmc/thermal/controller/optimizer/pid/ziegler_nichols/ziegler_nichols.h"
@@ -1261,6 +1262,12 @@
         pid_optimizer,
         thermal::optimizer::PidAutotunerDifferentiatedZieglerNichols::Create(
             pid_controller_config));
+  } else if (pid_controller_config.pid_autotuner_config()
+                 .has_frequency_response_estimation_config()) {
+    ECCLESIA_ASSIGN_OR_RETURN(
+        pid_optimizer,
+        thermal::optimizer::PidAutotunerFrequencyResponseEstimation::Create(
+            pid_controller_config));
   }
 
   if (pid_optimizer == nullptr) {
diff --git a/tlbmc/thermal/controller/optimizer/pid/frequency_response_estimation/frequency_response_estimation.cc b/tlbmc/thermal/controller/optimizer/pid/frequency_response_estimation/frequency_response_estimation.cc
index abdbe07..c5c36a9 100644
--- a/tlbmc/thermal/controller/optimizer/pid/frequency_response_estimation/frequency_response_estimation.cc
+++ b/tlbmc/thermal/controller/optimizer/pid/frequency_response_estimation/frequency_response_estimation.cc
@@ -19,6 +19,34 @@
 namespace milotic_tlbmc {
 namespace thermal {
 namespace optimizer {
+namespace {
+
+constexpr double kPi = 3.14159265358979323846;
+
+}  // namespace
+
+absl::StatusOr<std::unique_ptr<PidAutotunerFrequencyResponseEstimation>>
+PidAutotunerFrequencyResponseEstimation::Create(
+    const PidControllerConfig& config) {
+  const PidTunerFrequencyResponseEstimationConfig& fre_config =
+      config.pid_autotuner_config().frequency_response_estimation_config();
+
+  FrequencyResponseEstimationConstructParameters params = {
+      .target_bandwidth = fre_config.target_bandwidth(),
+      .target_phase_margin_deg = fre_config.target_phase_margin_deg(),
+      .sine_amplitude = fre_config.sine_amplitude(),
+      .tuning_duration_ms = fre_config.tuning_duration_sec() * 1000,
+      .target_input_value = config.setpoint(),
+      .loop_interval = static_cast<uint32_t>(
+          config.pid_loop_config().sample_time_sec() * 1000),
+      .max_output = fre_config.max_output(),
+      .min_output = fre_config.min_output(),
+      .nominal_output = fre_config.nominal_output(),
+      .loop_sign = static_cast<int8_t>(fre_config.loop_sign()),
+  };
+
+  return Create(params);
+}
 
 absl::StatusOr<std::unique_ptr<PidAutotunerFrequencyResponseEstimation>>
 PidAutotunerFrequencyResponseEstimation::Create(
diff --git a/tlbmc/thermal/controller/optimizer/pid/frequency_response_estimation/frequency_response_estimation.h b/tlbmc/thermal/controller/optimizer/pid/frequency_response_estimation/frequency_response_estimation.h
index 0725c22..8cb93f8 100644
--- a/tlbmc/thermal/controller/optimizer/pid/frequency_response_estimation/frequency_response_estimation.h
+++ b/tlbmc/thermal/controller/optimizer/pid/frequency_response_estimation/frequency_response_estimation.h
@@ -16,7 +16,6 @@
 namespace thermal {
 namespace optimizer {
 
-constexpr double kPi = 3.14159265358979323846;
 constexpr int kFrequencyMultiplierSize = 5;
 constexpr int kRegressorDimension = 2 * kFrequencyMultiplierSize + 1;
 constexpr std::array<double, kFrequencyMultiplierSize> kFrequencyMultipliers = {
@@ -34,7 +33,7 @@
   double max_output = 100.0;
   double min_output = 0.0;
   double nominal_output = 50.0;  // Baseline control output `u_0`
-  double loop_sign = 1.0;        // Sign of the coefficient gains
+  int8_t loop_sign = 1;          // Sign of the coefficient gains
 
   double rls_forgetting_factor =
       1.0;  // RLS forgetting factor `\lambda \in (0, 1]`
@@ -87,7 +86,7 @@
  public:
   static absl::StatusOr<
       std::unique_ptr<PidAutotunerFrequencyResponseEstimation>>
-  Create(const FrequencyResponseEstimationConstructParameters& params);
+  Create(const PidControllerConfig& config);
 
   void Initialize(const PidOptimizerInitializationParameters& params) final;
   double TunePid(const PidOptimizerTuningParameters& params) final;
@@ -112,6 +111,10 @@
   }
 
  protected:
+  static absl::StatusOr<
+      std::unique_ptr<PidAutotunerFrequencyResponseEstimation>>
+  Create(const FrequencyResponseEstimationConstructParameters& params);
+
   explicit PidAutotunerFrequencyResponseEstimation(
       const FrequencyResponseEstimationConstructParameters& params);
 
@@ -135,7 +138,7 @@
   double max_output_;
   double min_output_;
   double nominal_output_;
-  double loop_sign_;
+  int8_t loop_sign_;
 
   // RLS estimator params.
   DualRlsEstimator<kRegressorDimension> rls_estimator_;