-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Computation of i_term_ #32
Comments
What this is implementing is that gain changes will only affect the samples after which it was changed. I don't know if this is what was originally intended or not, but I get the feeling that the original implementation assumed constant gains, where this was not a problem. The dynamic_reconfigure interface was added much later.
Not quite, as It would seem reasonable to expect that if you modify the integral gain (and in particular set it to zero), it should affect the whole integration window, so how about:
p_error_int_ += dt.toSec() * p_error_;
i_term_ = gains.i_gain_* p_error_int_;
Patches and tests welcome :-) |
You are right, my mistake, I was only thinking in the reset functionality and forgot about the integration scheme! The change does not modify the control law, it is only useful for tunning and changing the gains dynamically properly, I believe. However, I'm not sure what happens with performance when adjusting the gains online, so I will test and come back with an answer or a patch. Cheers |
Correct, but now that there is the dynamic_reconfigure interface, it is an important improvement. Thanks for catching it. |
The original way of doing actually made much more sense, since it prevented the output from being discontinuous when the integral gain is changed. For example, if the integrator has converged to what the output has to be to maintain zero steady state error and then the integrator gain is doubled, all the sudden the output will be doubled(!). It makes more sense to integrate the current gain * current error (the original behavior), which avoids this. See https://en.wikipedia.org/wiki/PID_controller#Bumpless_Operation for a similar solution. Yes, this does imply that changing to a zero integrator gain will result in a constant, unchanging output offset until the controller is reset, but that's better than sudden, potentially large jumps in the output. In addition, if your integrator has actually converged to something nonzero, it means that you probably do need an integrator term in your controller and you shouldn't be setting the I gain to zero anyway! |
I'm not an expert on the topic, so thanks for the comment, since it made me go and investigate more on PID design. I found this PhD thesis, and this summary taken from that thesis and other papers. All diagrams make sense to me, and the chosen structure varies according to the application, such as the anti-windup opt requested in #34 for a quadrotor control. As far as I understand, the bumpless operation (or transfer, which is the most-used term in the literature and also by matlab), is meant to be used when transitioning between Manual and Automatic control. Don't know if there are too many use-cases in (autonomous) robotics, but still valid as an argument for a generic PID controller implementation. However, in the Wikipedia link you provide, it says literally A partial implementation... to refer to something like the original way of doing it. Based on this, my suggestion would be to keep the new way, which makes |
Before creating any pull request, I'd like to raise this for discussion.
Lines 282 and 315 in
pid.cpp
, explicitly:Shouldn't this term be:
Note that, for instance, setting
gains.i_gain_
to zero online in the current implementation does not remove the integratedi_term_
so far, and it won't until you reset the controller./cc @manuelbonilla
The text was updated successfully, but these errors were encountered: