![]() |
PID question
I've seen several PID sources posted on the forum, and all of them divide the proportional output by 100, the integral output by 1000 and the derivative output by 10. Then the return value of the PID goes something like this:
Code:
return Limit_Mix(2000 + 127 + P + I - D);Thanks, Jedd Edit - Another question? How do most people find reasonable constants for the gains of P, I and D? |
Re: PID question
We do this to gain precision and avoid overflow.
At least I do :D |
Re: PID question
I don't think it is realistically possible to choose constants that keep the output between 0 and 254. As for the division thing, it lets you get decimal precision without making the uC do floating point operations, which it is very bad at. (ex 34/100 is the same as .34, but the robot executes it much faster)
To find gains, we just make the setpoint something near the middle of the mechanism's travel (to keep oscillations from damaging the mechanism). Then we link the P, I, and D constants to an analog input on the OI. After that we twiddle the knobs in this order: increase P until it gets near the setpoint, increase I until it reaches the setpoint, and finish by increasing D until any oscillations present are damped. We then use the numbers determined this way as our constants. It actually takes very little time to do it this way, I think it took us maybe 20 minutes to tune three loops last year. |
Re: PID question
Ah, gotcha. Thanks.
One more thing. The code posted in this thread: http://www.chiefdelphi.com/forums/sh...ad.php?t=56663 will only return a value between 0 and 255, right? It wouldn't be suitable for use with a potentiometer(?). |
Re: PID question
I don't see any complete PID implementations in that thread... I would recommend reading these two documents if you intend to code a PID loop: Matt Krass's whitepaper, and PID without a PhD. If you want to get a little more advanced you can search around the forum to find out how to go about writing generalized PID functions. (PID without a PhD actually uses a generalized function, but I don't think it talks about it specifically)
|
Re: PID question
Quote:
I have written an attempt at a generic PID function (rough draft of it at least). Code:
typedef char bool;Edit - I'm pretty confident it works, but I don't know for sure. I need to make a test case for it (I don't have access to the robot), but I don't know how to really. Does anyone know how to setup an example? |
Re: PID question
It looks good at first glance, but you may want to do the dividing trick (especially on I, that usually ends up as a quite small constant) to improve accuracy/speed. I would also make sure to limit the output to 0-254... I can see no way that you can be certain not to exceed the 0-254 range. If you do, the consequences can be dire for both your robot's mechanical well-being, and bystanders' (ask Billfred what a robot arm can do if you're too close... you really don't want to get an uppercut from your robot). A quick Limit_Mix() call is cheap insurance against accidentally causing major robot damage and/or bodily harm.
|
Re: PID question
I added the divide by x's in there to increase precision... basically this robot controller cannot do floating point calculations, so i had to tell the controller to divide by something to get some amount of precision.
when i divide by ten, you are essentially getting precision of control to 1 decimal place, 100 is two, and 1000 is three. kI is divided by 1000 because typically very small changes in that constant can have a very large impact on the system. likewise, larger changes on kD wont have such a great impact. and yes, the function is limited to 0-255. |
Re: PID question
Thanks a lot! Totally clear on PID now. Hopefully finding the magic gain constants won't be too difficult :)
|
| All times are GMT -5. The time now is 23:21. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi