[pidcontroller] Add ability to limit the I-part (#12565)
* [pidcontroller] Add ability to limit the I-part * Apply iMinValue & iMaxValue to the integral result accumulator Signed-off-by: Fabian Wolter <github@fabian-wolter.de> * Set iMinResult, iMaxResult default value to NaN Co-authored-by: Lenno Nagel <lenno@nagel.ee>
This commit is contained in:
@@ -24,7 +24,7 @@ Select the Item you like to control in the "Item Action" and leave the command e
|
||||
### Trigger
|
||||
|
||||
This module triggers whenever the `input` or the `setpoint` changes or the `loopTime` expires.
|
||||
Every trigger calculates the P, the I and the D part and sums them up to form the `output` value.
|
||||
Every trigger calculates the P-, the I- and the D-part and sums them up to form the `output` value.
|
||||
This is then transferred to the action module.
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
@@ -35,18 +35,25 @@ This is then transferred to the action module.
|
||||
| `ki` | Decimal | I: [Integral Gain](#integral-i-gain-parameter) Parameter | Y |
|
||||
| `kd` | Decimal | D: [Derivative Gain](#derivative-d-gain-parameter) Parameter | Y |
|
||||
| `kdTimeConstant` | Decimal | D-T1: [Derivative Gain Time Constant](#derivative-time-constant-d-t1-parameter) in sec. | Y |
|
||||
| `commandItem` | String | Send a String "RESET" to this item to reset the I and the D part to 0. | N |
|
||||
| `commandItem` | String | Send a String "RESET" to this item to reset the I- and the D-part to 0. | N |
|
||||
| `loopTime` | Decimal | The interval the output value will be updated in milliseconds. Note: the output will also be updated when the input value or the setpoint changes. | Y |
|
||||
| `pInspector` | Item | Name of the debug Item for the current P part | N |
|
||||
| `iInspector` | Item | Name of the debug Item for the current I part | N |
|
||||
| `dInspector` | Item | Name of the debug Item for the current D part | N |
|
||||
| `integralMinValue` | Decimal | The I-part will be limited (min) to this value. | N |
|
||||
| `integralMaxValue` | Decimal | The I-part will be limited (max) to this value. | N |
|
||||
| `pInspector` | Item | Name of the debug Item for the current P-part | N |
|
||||
| `iInspector` | Item | Name of the debug Item for the current I-part | N |
|
||||
| `dInspector` | Item | Name of the debug Item for the current D-part | N |
|
||||
| `eInspector` | Item | Name of the debug Item for the current regulation difference (error) | N |
|
||||
|
||||
The `loopTime` should be max a tenth of the system response.
|
||||
E.g. the heating needs 10 min to heat up the room, the loop time should be max 1 min.
|
||||
Lower values won't harm, but need more calculation resources.
|
||||
|
||||
You can view the internal P, I and D parts of the controller with the inspector Items.
|
||||
The I-part can be limited via `integralMinValue`/`integralMaxValue`.
|
||||
This is useful if the regulation cannot meet its setpoint from time to time.
|
||||
E.g. a heating controller in the summer, which can not cool (min limit) or when the heating valve is already at 100% and the room is only slowly heating up (max limit).
|
||||
When controlling a heating valve, reasonable values are 0% (min limit) and 100% (max limit).
|
||||
|
||||
You can view the internal P-, I- and D-parts of the controller with the inspector Items.
|
||||
These values are useful when tuning the controller.
|
||||
They are updated every time the output is updated.
|
||||
|
||||
@@ -54,7 +61,7 @@ They are updated every time the output is updated.
|
||||
|
||||
Parameter: `kp`
|
||||
|
||||
A value of 0 disables the P part.
|
||||
A value of 0 disables the P-part.
|
||||
|
||||
A value of 1 sets the output to the current setpoint deviation (error).
|
||||
E.g. the setpoint is 25°C and the measured value is 20°C, the output will be set to 5.
|
||||
@@ -67,7 +74,7 @@ Parameter: `ki`
|
||||
The purpose of this parameter is to let the output drift towards the setpoint.
|
||||
The bigger this parameter, the faster the drifting.
|
||||
|
||||
A value of 0 disables the I part.
|
||||
A value of 0 disables the I-part.
|
||||
|
||||
A value of 1 adds the current setpoint deviation (error) to the output each `loopTime` (in milliseconds).
|
||||
E.g. (`loopTimeMs=1000`) the setpoint is 25°C and the measured value is 20°C, the output will be set to 5 after 1 sec.
|
||||
@@ -81,7 +88,7 @@ Parameter: `kd`
|
||||
The purpose of this parameter is to react to sudden changes (e.g. an opened window) and also to damp the regulation.
|
||||
This makes the regulation more resilient against oscillations, i.e. bigger `kp` and `ki` values can be set.
|
||||
|
||||
A value of 0 disables the D part.
|
||||
A value of 0 disables the D-part.
|
||||
|
||||
A value of 1 sets the output to the difference between the last setpoint deviation (error) and the current.
|
||||
E.g. the setpoint is 25°C and the measured value is 20°C (error=5°C).
|
||||
@@ -91,13 +98,13 @@ When the temperature drops to 10°C due to an opened window (error=15°C), the o
|
||||
|
||||
Parameter: `kdTimeConstant`
|
||||
|
||||
The purpose of this parameter is to slow down the impact of the D part.
|
||||
The purpose of this parameter is to slow down the impact of the D-part.
|
||||
|
||||
This parameter behaves like a [low-pass](https://en.wikipedia.org/wiki/Low-pass_filter) filter.
|
||||
The D part will become 63% of its actual value after `kdTimeConstant` seconds and 99% after 5 times `kdTimeConstant`. E.g. `kdTimeConstant` is set to 10s, the D part will become 99% after 50s.
|
||||
The D-part will become 63% of its actual value after `kdTimeConstant` seconds and 99% after 5 times `kdTimeConstant`. E.g. `kdTimeConstant` is set to 10s, the D-part will become 99% after 50s.
|
||||
|
||||
Higher values lead to a longer lasting impact of the D part (stretching) after a change in the setpoint deviation (error).
|
||||
The "stretching" also results in a lower amplitude, i.e. if you increase this value, you might want to also increase `kd` to keep the height of the D part at the same level.
|
||||
Higher values lead to a longer lasting impact of the D-part (stretching) after a change in the setpoint deviation (error).
|
||||
The "stretching" also results in a lower amplitude, i.e. if you increase this value, you might want to also increase `kd` to keep the height of the D-part at the same level.
|
||||
|
||||
## Tuning
|
||||
|
||||
@@ -108,7 +115,7 @@ This results in quite reasonable working systems in most cases.
|
||||
So, this will be described in the following.
|
||||
|
||||
To be able to proceed with this method, you need to visualize the input and the output value of the PID controller over time.
|
||||
It's also good to visualize the individual P, I and D parts (these are forming the output value) via the inspector items.
|
||||
It's also good to visualize the individual P-, I- and D-parts (these are forming the output value) via the inspector items.
|
||||
The visualization could be done by adding a persistence and use Grafana for example.
|
||||
|
||||
After you added a [Rule](https://www.openhab.org/docs/configuration/rules-dsl.html) with above trigger and action module and configured those, proceed with the following steps:
|
||||
@@ -121,7 +128,7 @@ E.g. the time it takes from opening the heater valve and seeing an effect of the
|
||||
3. Decrease `kp` a bit, that the system doesn't oscillate anymore
|
||||
4. Repeat the two steps for the `ki` parameter (keep `kp` set)
|
||||
5. Repeat the two steps for the `kd` parameter (keep `kp` and `ki` set)
|
||||
6. As the D part acts as a damper, you should now be able to increase `kp` and `ki` further without resulting in oscillations
|
||||
6. As the D-part acts as a damper, you should now be able to increase `kp` and `ki` further without resulting in oscillations
|
||||
|
||||
After each modification of above parameters, test the system response by introducing a setpoint deviation (error).
|
||||
This can be done either by changing the setpoint (e.g. 20°C -> 25°C) or by forcing the measured value to change (e.g. by opening a window).
|
||||
|
||||
Reference in New Issue
Block a user