In the `AutoPID` algorithm, the decision to use bang-bang control or PID control is based on the current error relative to the set bang-bang thresholds. ### Bang-Bang Control Bang-bang control is used when the error between the setpoint and the input is outside the defined bang-bang thresholds. Specifically: - **Bang-On Threshold**: If the error is greater than the `_bangOn` threshold, the output is set to `_outputMax`. - **Bang-Off Threshold**: If the error is greater than the `_bangOff` threshold, but in the opposite direction, the output is set to `_outputMin`. ### PID Control PID control is used when the error is within the bang-bang thresholds. This means that the system is close enough to the setpoint that finer control is required. In this case, the PID calculations are performed to adjust the output. ### Detailed Breakdown 1. **Bang-Bang On Control**: - If the difference between the setpoint and the input (`*_setpoint - *_input`) is greater than `_bangOn`, the output is set to `_outputMax`. ```cpp if (_bangOn && ((*_setpoint - *_input) > _bangOn)) { *_output = _outputMax; _lastStep = esp_timer_get_time() / 1000; } ``` 2. **Bang-Bang Off Control**: - If the difference between the input and the setpoint (`*_input - *_setpoint`) is greater than `_bangOff`, the output is set to `_outputMin`. ```cpp else if (_bangOff && ((*_input - *_setpoint) > _bangOff)) { *_output = _outputMin; _lastStep = esp_timer_get_time() / 1000; } ``` 3. **PID Control**: - If the error is within the bang-bang thresholds, PID control is used. The time step `_dT` is checked to see if enough time has passed since the last update. If so, PID calculations are performed: ```cpp else { //otherwise use PID control unsigned long _dT = (esp_timer_get_time() / 1000) - _lastStep; //calculate time since last update if (_dT >= _timeStep) { //if long enough, do PID calculations _lastStep = esp_timer_get_time() / 1000; double _error = *_setpoint - *_input; _integral += (_error + _previousError) / 2 * _dT / 1000.0; //Riemann sum integral double _dError = (_error - _previousError) / _dT / 1000.0; //derivative _previousError = _error; double PID = (_Kp * _error) + (_Ki * _integral) + (_Kd * _dError); *_output = std::clamp(PID, _outputMin, _outputMax); } } ``` ### Summary - **Bang-Bang Control**: - Used when the error is outside the bang-bang thresholds (`_bangOn` or `_bangOff`). - Provides a simple on/off control by setting the output to `_outputMax` or `_outputMin`. - **PID Control**: - Used when the error is within the bang-bang thresholds. - Provides finer control by calculating the output using the PID algorithm. This hybrid approach allows the `AutoPID` algorithm to quickly react when the error is large (using bang-bang control) and finely adjust the output when the error is small (using PID control).
To create a project from this example, run:
idf.py create-project-from-example "hayschan/autopid_for_esp_idf=1.0.2:basics"