Skip to content

Commit

Permalink
Add explanation of bang bang and PID
Browse files Browse the repository at this point in the history
  • Loading branch information
hayschan committed May 25, 2024
1 parent b6249bc commit ff2a019
Showing 1 changed file with 54 additions and 22 deletions.
76 changes: 54 additions & 22 deletions examples/basics/README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,64 @@
# _Sample project_
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.

(See the README.md file in the upper level 'examples' directory for more information about examples.)
### Bang-Bang Control

This is the simplest buildable example. The example is used by command `idf.py create-project`
that copies the project to user specified path and set it's name. For more information follow the [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project)
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

## How to use example
We encourage the users to use the example as a template for the new projects.
A recommended way is to follow the instructions on a [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project).
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.

## Example folder contents
### Detailed Breakdown

The project **sample_project** contains one source file in C language [main.c](main/main.c). The file is located in folder [main](main).
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`.

ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt`
files that provide set of directives and instructions describing the project's source files and targets
(executable, library, or both).
```cpp
if (_bangOn && ((*_setpoint - *_input) > _bangOn)) {
*_output = _outputMax;
_lastStep = esp_timer_get_time() / 1000;
}
```
Below is short explanation of remaining files in the project folder.
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`.
```
├── CMakeLists.txt
├── main
│   ├── CMakeLists.txt
│   └── main.c
└── README.md This is the file you are currently reading
```
Additionally, the sample project contains Makefile and component.mk files, used for the legacy Make based build system.
They are not used or needed when building with CMake and idf.py.
```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).

0 comments on commit ff2a019

Please sign in to comment.