We are starting to figure out how we want to control the speed of our shooter wheel and we are trying to figure out which sensor to use.
We are looking at a simple encoder that uses an LED and detector to give the number of pulses a wheel turns. This is all we really need and would be easier for us to use hardware wise than a quadrature encoder which is overkill for this application.
All we want is speed, and we want to use PIDController to tell the motor what to do to maintain that speed.
I am stuck at the usual complete lack of examples available in the WPI Users Guide. I believe I want to use the Counter class, but I don’t know if its a PIDSource. Can PIDController control speed based or is it only for distance?
Does anyone have a sample bit of code that uses Counter and PIDController to control speed they can share please? Are we barking up the wrong tree?
After trying to figure out the problem for a week, we have just decided to put the encoders that come in the kit of parts on a jackshaft from the shooter wheel and use our PID code from last year’s robot as an example which will hopefully work.
We’ll be changing the PIDSource from GetDistance to GetRate and then hopefully we can set our PIDSet to a number and the PIDController will be able to get there after tweaking P and I.
Are there any particular pitfalls or problems that teams have run into when PID’ing to rate versus PID’ing to distance?
We really are clueless on how to get the WPILib stuff to work for us on anything that doesn’t have an example to learn from, so we are hoping the code we finally got working last year will be good enough. Does anyone have any code from traction control during Lunacy they would be willing to share? I assume that was PID to speed and would be very helpful.
Thanks.
Editing to add that we are using Victors, and have no plans to even try and conquer the Jaguar CAN bus and all that jazz.
There is one common pitfall associated with switching from distance to rate/speed as the process variable.
Consider a position control loop as implemented by WPIlib:
Motor Voltage = Kp*error + Ki*error_sum + Kd*(error-error_last)
Error is in units of distance; the output is in units of percentage of motor voltage (roughly, speed). When you have zero error (and zero error_sum and zero error_last…e.g. you are exactly at your goal) in a position control loop, you command a zero motor speed. This make sense; stopping will leave you at your goal.
Now consider what would happen if you implemented the same loop, but switch the “error” units from distance to speed. When you have zero error in a velocity control loop, you do NOT want to command a zero motor speed. That would slow the motor and result in MORE error. Your best bet is probably to command the motor to keep going whatever speed it was at last!
There are two ways you can get your velocity controller behaving in this situation:
(1) You need to treat P and I as if they were actually D and P, respectively! This makes sense; you are basically taking the time-derivative of position, which is speed, but are still commanding the same quantity (voltage). Hence the meaning of your gains changes to reflect the derivative of the input.
(2) You can make a slight tweak to the way the PID output is used. Instead of
Output = ...
you can simply accumulate the output:
Output = Output + ...
Using the second method, you can think of your output not being “Voltage”, per se, but rather “Change in Voltage”. In other words, you are taking the derivative of the left side of the equation as well as the right.
Thanks for the information. You bring up a very good point. Does this mean I have to write my own PIDController class or something to do speed, or is the WPILib PIDController smart enough to set it’s PIDOutput to something compatible with speed?
We have only ever got PIDs to work on distance, and only because it was simply a matter of calling the PIDController class correctly.