m-lundberg / simple-pid

A simple and easy to use PID controller in Python
MIT License
767 stars 209 forks source link

Integral windup problem #38

Closed imanfreeman closed 1 year ago

imanfreeman commented 3 years ago

Hi firstly, I would like to thank you for your nice library. It is very helpful and straightforward to use. I think there is a problem in integral wind-up implementation. your code is correct, However the C code reference you have used, has a mistake in my opinion. Here in the solution- step1 has explained what should be done if output exceeds the limits. STOP INTEGRATING. How ever, in the code it stops integration only if the integral term exceeds the output limit which means integration won't stop even if the output is out of range. I have checked this and the result is here. The green curve shows the PID output which has been clamped and the cyan show the integral term (using pid.components).
Please correct me if I am wrong. Regards

eirinnm commented 2 years ago

Hi @imanfreeman, I'm quite interested in this question so I ran some simulations myself and I believe the current implementation is appropriate. The integral value does continue to increase even when the output is clamped, but it itself is clamped so that it doesn't cause a problem.

If I change the code to match your suggestion (stop integrating whenever the output is clamped), this causes the controller to get 'stuck' when changing the setpoint (as the integral value is high but doesn't change). This can be fixed by resetting the controller whenever the setpoint is changed, but I don't think that's desirable.

I'm posting this message mainly for people who might come across this library and wonder if the implementation is correct. In my tests, it works great.

m-lundberg commented 1 year ago

Hi @imanfreeman . Thanks for the feedback.

I'm not an expert in control theory, but from my understanding there are several possible approaches to dealing with integral windup, each with it's advantages and disadvantages. For this project I chose the approach used by Brett Beauregard. I believe it's a simple and effective approach, and in order to keep the "simple" part of "simple-pid", this is the only approach this library supports.