Robodox Guide to velocity control using PID

Many many many teams utilized a shooter wheel design this year and could have benefitted greatly from a guide on how to utilize the WPILibrary PIDController function for velocity control. That is exactly the purpose of this guide, however late in the season it is, it can still help teams in the future and those of use ( like myself) who just couldn’t go without getting it done anyways. Happy to answer any questions or address any concerns.

Implementing PID for Velocity Control.pdf (295 KB)

Implementing PID for Velocity Control.pdf (295 KB)

I’ve been thinking of a different way to control the velocity of a spinner using PWM and the basic GetRate() function of an encoder. It starts of with a while loop and the shooter motor.

while(encoder->GetRate() <= setpoint) {jag->Set(i); i+= .001}

This way, it ramps up, but the only fear I have of this method is that I am unfamiliar with the way GetRate() works. If it gets back data per second, then we have a problem with this formula. If it works like the CANJaguar feature, there should be no problems with this method.

Note: We used CANJaguars this year and plugged the encoder into the Jaguar itself to use the Speed PID feature.

As far as I know and recall, GetRate() returns data per second.

I’ll modify my formula and see if I can use it with the CANJaguar PWM feature and using the GetSpeed() function. I’ll do it as soon as I possibly can. We can always use Ether’s method of the “bang bang” control style.

GetRate() works great for velocity control… in fact in my tests it works better for noise control than using raw/time way.

In our code we work with radians per second as the preferred unit of measurment, and we do not need to normalize to use PID… I did however rewrite the PID class from 2011 to something more direct that does not use any threading. Instead the main loop is timed and each time change call uses a delta time parameter (double in units of seconds). And this gets factored in for the error computation. This will take care of uneven time-slices which is why the threading was used. Finally on the averaging… don’t use a smooth blend type of average because this will introduce extra latency on your actual time. Instead use either a priority queue or a fixed number averager (or both) also use the kalman filter… I use all three of these… to combat the worst case encoder noisy-ness… like when the shaking of the motor caused the encoder to bust out of its casing and lose values per revolution.

The re-written PID controller source is here:

The averagers are also in here in the Misc.h file

I’d be interested in seeing your test plan, test setup, and test results, if you would be willing to share them.

I have all my work on this here:

This is due for an update on the latest and greatest achievements that show how to beat latency with some tested velocity graphs. I’ll get to that eventually, but what is there now is still worth a read.

Going here:

Has a list of all the articles I’ve written… check out “getting encoders to work”, “Gettting arm to work”, and “Weight Mass? what’s the difference?”

On a side note not yet written there is a new technique I call “use the force” this gets me the 0ms latency, and I’ve got this working for speed control, but eventually wish to get this for fixed point… I’ll explain this one in these articles at some point.

Here’s a sneak peak of it: