ESPHome  2024.4.1
pid_autotuner.h
Go to the documentation of this file.
1 #pragma once
2 
5 #include "pid_controller.h"
6 #include "pid_simulator.h"
7 
8 #include <vector>
9 
10 namespace esphome {
11 namespace pid {
12 
13 class PIDAutotuner {
14  public:
15  struct PIDResult {
16  float kp;
17  float ki;
18  float kd;
19  };
21  float output;
23  };
24 
25  void config(float output_min, float output_max) {
28  }
29  PIDAutotuneResult update(float setpoint, float process_variable);
30  bool is_finished() const { return state_ != AUTOTUNE_RUNNING; }
31 
32  void dump_config();
33 
34  void set_autotuner_id(std::string id) { this->id_ = std::move(id); }
35 
36  void set_noiseband(float noiseband) {
37  relay_function_.noiseband = noiseband;
38  // ZC detector uses 1/4 the noiseband of relay function (noise suppression)
39  frequency_detector_.noiseband = noiseband / 4;
40  }
41  void set_output_positive(float output_positive) { relay_function_.output_positive = output_positive; }
42  void set_output_negative(float output_negative) { relay_function_.output_negative = output_negative; }
43 
44  protected:
45  struct RelayFunction {
46  float update(float error);
47 
48  float current_target_error() const {
49  if (state == RELAY_FUNCTION_INIT)
50  return 0;
51  if (state == RELAY_FUNCTION_POSITIVE)
52  return -noiseband;
53  return noiseband;
54  }
55 
60  } state = RELAY_FUNCTION_INIT;
61  float noiseband = 0.5;
62  float output_positive = 1;
63  float output_negative = -1;
64  uint32_t phase_count = 0;
67  void update(uint32_t now, float error);
68 
69  bool has_enough_data() const;
70 
71  float get_mean_oscillation_period() const;
72 
73  bool is_increase_decrease_symmetrical() const;
74 
79  } state;
80  float noiseband = 0.05;
81  uint32_t last_zerocross{0};
82  std::vector<uint32_t> zerocrossing_intervals;
85  void update(float error, RelayFunction::RelayFunctionState relay_state);
86 
87  bool has_enough_data() const;
88 
89  float get_mean_oscillation_amplitude() const;
90 
91  bool is_amplitude_convergent() const;
92 
93  float phase_min = NAN;
94  float phase_max = NAN;
95  std::vector<float> phase_mins;
96  std::vector<float> phase_maxs;
99  PIDResult calculate_pid_(float kp_factor, float ki_factor, float kd_factor);
100  void print_rule_(const char *name, float kp_factor, float ki_factor, float kd_factor);
101  PIDResult get_ziegler_nichols_pid_() { return calculate_pid_(0.6f, 1.2f, 0.075f); }
102 
103  uint32_t enough_data_phase_ = 0;
104  float setpoint_ = NAN;
105  enum State {
109  float ku_;
110  float pu_;
111  std::string id_;
112 };
113 
114 } // namespace pid
115 } // namespace esphome
void config(float output_min, float output_max)
Definition: pid_autotuner.h:25
struct esphome::pid::PIDAutotuner::OscillationAmplitudeDetector amplitude_detector_
const char * name
Definition: stm32flash.h:78
void set_autotuner_id(std::string id)
Definition: pid_autotuner.h:34
struct esphome::pid::PIDAutotuner::OscillationFrequencyDetector frequency_detector_
struct esphome::pid::PIDAutotuner::RelayFunction relay_function_
PIDResult calculate_pid_(float kp_factor, float ki_factor, float kd_factor)
PIDAutotuneResult update(float setpoint, float process_variable)
void set_output_positive(float output_positive)
Definition: pid_autotuner.h:41
void set_output_negative(float output_negative)
Definition: pid_autotuner.h:42
void print_rule_(const char *name, float kp_factor, float ki_factor, float kd_factor)
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
enum esphome::pid::PIDAutotuner::State state_
void set_noiseband(float noiseband)
Definition: pid_autotuner.h:36
bool state
Definition: fan.h:34
PIDResult get_ziegler_nichols_pid_()