Just wondering if anyone has a good solution for pulling off some sort of PID on some shooter wheels that can only spin one direction. We’re using encoder feedback to get the current speed of the shooter wheels and we have setpoints for how fast we want them to be spinning.
The issue is that the error is so far off that the shooter wheels spin up very fast and overshoot (even with an extremely low P and no I/D). We had to set the motor power so that if the PID sends a value less than 0, that it’s set to 0. What we’re experiencing is the motor power going between full on and full off.
Your problem is similar to what we implemented in 2006 for our shooter wheel. From your description, it sounds like the error you’re using for PID is the speed difference and the result of the PID calculation is sent directly to the speed controller. This isn’t what you want to do.
The way to accomplish this is to get a PWM value that typically gives you the correct steady state shooter speed, or close enough to it. Then use the speed difference as the error in your PID calculation. Now use the PID result not as your absolute PWM value, but instead add it to the typical steady state PWM value. This way if you’re going too slow, you’ll get an extra boost of power and if you’re going too fast, you’ll decrease power slightly instead of shutting the motor off or running it in reverse.
For example, through experimentation you learn that a PWM value of .7 usually gives you a shooter speed of 1000 RPM when there are no balls running through it. Run PID on the difference between your current shooter speed and 1000. Add the result of the PID calculation to .7 and set your speed controller to that value.
The PID calculation should not give you huge numbers, but the steady state PWM value + the maximum PID result you see should be enough to give you full power on the speed controller.
If your controller is overshooting your setpoint as you are describing then you could have an underdamped system. You can add some damping by implementing D control. To understand why, you can think about your system as a free swinging frictionless pendulum. With no damping, the pendulum will continuously swing and will settle on a set point. If you add a little damping (e.g. friction) the pendulum will eventually settle on a point. Add enough friction and the pendulum will swing directly to a point without overshooting at all. You can think of D control like adding virtual friction to your system. You’ll notice that the equation for D control and the equation for friction are the same with your D gain equivalent to the coefficient of friction.
However, unless you have a relatively heavy wheel with low friction bearings I would suspect that the mechanical system itself has enough damping to prevent the kind of rail to rail oscillation that you are referring to. I would guess that P control is sufficient. When you say “extremely low” for your P gain, what do you mean? How “high” or “low” this value is would depend on the units you are using for your inputs and outputs. Don’t be afraid to set this value even lower. I believe my students tuned our robot’s shooter with a P gain in the 1e-5 range.
I made my own encoder rate counter using a timed 30ms loop and a feedback node to find the rate/30ms. This was done because the rate function in the get encoder vi put out too large a number and was pretty unstable (could range 40%).
Scale above rate to 0->1. 1 is max speed.
Using a customized PID controller (Using only the I term…maybe a little P), I can now control the wheel rate. Unfortunately, I had to set the I term a little high to prevent stalling, so there is a suboptimal amount of oscillation and overshoot, but it doesn’t take that long to settle, so it’s okay. I have the I term reset whenever the target speed is 0. My loop runs every 30ms, but I can’t remember my gains right now. (make sure you limit your I term and stuff…Another note, the PID controller in LV has a really strange way of doing I and D…doesn’t use kI and kD, it uses like ti td…)
Using this method, you don’t have to know a “nominal” PWM value because it finds it for you. I suggest not going with a pure P, since it’ll slow down the closer it gets to the setpoint until settles between the initial and set points. I may/may not be able to get around to posting an example, so if you want it, just ask. (We use LV, so if you’re looking for C++, I can’t provide an example, but the theory remains the same).
labview’s PID controller is a little weird… first off set the limits to +/- 100 (for some reason this is neccesary), and scale that to the motor output (1.27x + 127)
you might want to graph the PV and PID output for this part…
secondly, push up the P gain until you get a limit cycle on the velocity (when the velocity jumps back and forth between the setpoint with about equal amplitude)
thirdly, give it small amounts of D until you see the PV settle out quickly to the setpoint when you change it/jump it.
fourthly, if it appears to never quite get to the setpoint (shouldnt happen often in a velocity controller with low load), give it some I until it appears to compensate.
Thats my [unofficial] method of tuning these PID loops… its not the right way but it works for me almost every time.
Also, if you are trying to tune with kP, kI and kD (not labview’s kP, Ti, Td), keep the following in mind:
kP = kP
kI proportional to kP/Ti
Kd proportional to kP * Td
Depending on how you build any PID controller you may or may not get the steady state to the setpoint. Mathematically, your steady state error depends on the number of integrals and the input function.
We had to implement such a PID system for our shooter. I kind of accidently stumbled upon the solution. I first collected some data points for what motor power corresponded to what shooter RPM. I graphed them in a spreadsheet program and got out a power equation to use in my program. We are using NI LabView. The program sets an rpm for the shooter then runs it through the equation. This puts out a power to send to the motor that is mostly accurate but off by some (due to low battery, friction, etc). The output of this equation is then multiplied by one 1 + the output of our PID block. The PID has a range of -.5 to .5 and uses the difference between desired and actual speed as the process variable. The setpoint is a constant representing zero error. Based on this, its able to increase/decrease the power of the base equation by up to 50% by generating this coefficient. I then just played around while running the vi on my computer till I couldn’t hear the sound of the wheel adjusting for the set speed. This system keeps the average error at about 2% and no greater than 10%. As for our PID values, we are not using the D term at all, an extremely low proportional value, and .028 for our integral value (of course, these are things you’ll need to adjust for your own shooter). I hope this bit of info helped, and good luck!