acowley / roshask

Haskell client library for the ROS robotics framework.
BSD 3-Clause "New" or "Revised" License
107 stars 18 forks source link

Is the integral term correct in PID functions? #43

Open tmorgan opened 8 years ago

tmorgan commented 8 years ago

In Ros.Util.PID

        scale = dt / 3
        integral = scale * (e1 + 4 * e2 + e3)
        output = kp * e3 + ki * integral + kd * derivative

I see the PID is a non-interactive kind, and I was just checking to see if there was any anti integral windup protection, but regardless of that I don't understand the integral calculation as it is. 2x weighted average of errors? Normally the integral term would accumulate, no? (So that even a very small ki term would bring a PID back to the set point eventually even if the kp term doesn't.) e.g. output = kp * e3 + ki * e3 + previousIntegral + kd * derivative. Of course that means changing the function signatures to return the I term and also using another IORef in the stateful functions. (As I'm not really a process control person, apologies if this is off base - or If I shouldn't have used an issue.)

acowley commented 8 years ago

This is a great question, thanks for bringing it up! I'd guess that the use of a finite sliding window only makes sense if the controller is applied to a system in fits and spurts so you don't want to figure out when to start and stop the integrator when the system isn't under the influence of this controller.

That is a pretty specific set of circumstances that only a computer scientist would make primary (hi!) :)

I imagine I wrote it this way for a combination of me being wrong and it originally being used in a switching controller setting. I don't think it makes much sense, either. It would be better to do things as you suggest, and perhaps provide a mechanism to zero out the integrator. If you open a PR that makes this change, I'll be happy to merge it.