Pitching Machine Control - PID Needed?

Like many teams we are considering a “pitching machine” type of shooting mechanism. The idea would be to use a motor driven wheel with an encoder on it and control the RPM via code to ensure consistent shooting.

The question is: should we use PID to control the RPM or just do a lookup table and some basic checks for RPM and time. This is a bit of an argument between myself and another mentor. The students arn’t yet to this point so we are trying to educate ourselves so we can give them good advice for things to look into.

Personally, I’m heavily in favor of using PID so we can “close the loop” on the RPM and really control it. One of the other mentors is suggesting a simple look-up table as the good simple approach and I want to know if I’m overcomplicating this or not. I usually am, so I figured I’d ask you experts. I get beat up a lot on the whole KISS principle on the team so I figured I’d ask here. I’m almost always going to suggest we do what the real-world industry does when there is a question and sometimes that leads to more complex things than people want, for better or for worse.

One concern I have with not using PID, even if the system is simple, is that PID accounts automatically for the unknown. If we say a motor setting of 10 = 500 RPM and that’s it, how long do we wait to reach 500 RPM? It seems we’d need to get the RPM checked frequently and when it hits 500 RPM we are ready to shoot. But that means if the battery is under more or less load and/or drained more at the end of the match the RPM might be missed, might take longer, might fluctuate, etc. So now we add in an error rate to account for variability in the RPM due to outside influences. Wait a minute - arn’t we now starting down the path of making a bad version of PID?

In my mind, PID doesn’t remove these problems, but it can handle them automatically. We take the RPM and compare it to the error rate and when tuned properly we should be able to hold a good RPM with minor fluctuations consistently. When error rate is low enough - shoot. PID also lets us change RPM quickly by overshooting and then correcting down. This is faster than a simple 10 = 500, 20 = 1000. PID might shoot to 40-50 to get closer to 1000 and then back it off fast. Again, tuning is key with all of this and while tuning is a pain in the rear this is a reasonably simple tuning all told.

So, am I off my rocker? Over thinking the problem? Thanks!



PS: To make this post useful for others and try and pay back the community for all my dumb questions, here is a very good PID library written for the Arduino and likely easily ported to the cRio (not positive of this, I’ve not dug into the code much):

And here is a superb series of blog posts for this library and how he handles many of the problems with basic PID control:

And finally, here is a detailed write-up based on that same code but ported to mbed. This write up shows the details of using it to control velocity and tuning it:

That last write up shows a good “moderate” tuning for their application but if they were to switch tunings from moderate to aggressive when the differential was high they could actually get a better response. Not really sure why they didn’t use all their derived tunings for more responsiveness and better holding but switching tunings based on the change needed is a great trick and a good optimization once you get the base-tuning dialed in. The Arduino examples show this.

If you’re familiar with what each constant does, PID should be somewhat simple to just throw on and test on the final shooter.

The combination of your two ideas is actually better, do some testing and record battery voltage, victor output and wheel rpm. Develop a rough correlation between voltage, victor output and rpm.

Use this, it’ll get you pretty close to a constant speed. Now, Throw a control loop on as well. The control loop now just deals with the slight difference between the predicted and actual speed, and will also cause the wheel to spinup faster.

I know a LOT of teams in 2006 actually went to full bang-bang control on spinup (literal full speed), as a flywheel takes a while to respond.

A flywheel is a somewhat forgiving device to control because it has a LOT of momentum ideally.

In my experience from Lunacy, a shooter wheel is going to take a small amount of time to spin up to speed, whether from shooting the first ball or after other balls. The spool-up time obviously depends on many factors but I’m going to assume that is not negligible and will have to be minimized. Also, the rpm of the shooter wheel(s) may have to be adjusted depending on which basket and how far away you are shooting from.

What I am planning on doing (for now, barring other complications) is having a shooter with closed-loop speed using a KOP encoder. We will determine when the shooter is built/tuned well for the balls what the desired rpm of the shooter is (for a certain goal, say shooting from 5’ away at the 2nd level goal) and how long it takes to get there. If the desired rpm is somewhat consistent from shooting one ball to the next and the spool-up time is somewhat consistent we will use a variation of a LUT. If these values are not consistent or we find from a strategy point that we will want to adjust these in a match more accurately we will use a closed-loop solution.

Also, my opinion is that as long as you start with a fresh battery for every match and aren’t doing anything “crazy” the battery voltage will not impact the spool-up time/speed to a noticable level. These opinions are entirely subject to verification and am only stating these as from my experience in Lunacy. This is not a apples-to-apples comparison but I think it makes a somewhat valid comparison, we were shooting a lot more balls in Lunacy but didn’t worry as much about accuracy. During our testing phase we will also determine if the battery voltage discussion is a major or minor concern and adjust appropriately.

Finally my other opinion on this matter is that it will be a much bigger effort to be able to control the angle/speed of the ball coming out of the robot from a Driver perspective and/or using other sensors to help with this. This includes development of this control method along with the time it will take the Drivers to learn and use it in a quick manner.

Also, I forgot to mention that if you happen to be using Labview there are a some really great PID tools built-in along with some pretty great examples. I think the other programming languages do this as well but can only speak for Labview.

Based on past experience… you’ll see a difference in what your robot can do at the beginning of a match versus the end of a match (as the battery drains), and an even bigger difference if you don’t use a fully charged battery. The speed controllers don’t provide 12V to the motor - they provide battery voltage to the motor, which may not be 12V (and, in fact, it fluctuates quite a bit when you’re driving around doing things).

I’m a big fan of using a feedback loop for this situation (and, in fact, we’ll be putting an encoder on our shooter to allow good speed control). Does it need to be full-blown PID, or can you get by with something simpler?

In 2006, we used a relatively light shooting wheel (two skyway wheels). We designed it so that our “normal” shooting speed was 80% of full speed. When we ran it open loop at 80%, it would take about 1.5 seconds to get back to speed after shooting a ball. With PID control, it took 0.7 seconds. A shooting wheel with more inertia would have made both of these better.

I would recommend starting with open loop control, and if the students aren’t happy with the result, then you can start teaching PID.

This a key point. Teams need to realize it is not the surface speed of the wheel that directly matters, but rather the energy stored in this flywheel. One could make the trade off of longer initial spinup time for a much decreased energy loss per shot.

1 Like

No need to port another PID library to the cRIO, WPLib already has a PID class. We used it last year to control our arm.

Thanks for all the useful discussion everyone.

Thanks for bringing this up. I’d not seen this yet in the big PDF file. If it’s already built into the system this seems to be an easy choice to me. The concern was adding more code on the students but a quick look in the PDF shows they’ve made this as easy as possible. Even the sensor and controller we’d be using has already been set up for us.

Any advice on using this in practice? Is it a good implementation or any gotchas we need to know? Thanks!