View Full Version : Keep the engine speed
Luan Motta
14-01-2013, 13:39
We want that the motor remains at the same speed all the time with encoder.
Maybe we need to use the PID controller.
How we will do this in java?
DjScribbles
14-01-2013, 15:32
Last year, we used a "Bang Bang" controller, which Mr. Ether helped us implement (though he got the idea from another member here, IIRC) for controlling our shooter wheel.
My C++ (similar enough to Java to help) source code from last year lives here:
https://github.com/TeamExcel/Project2012/blob/master/Robot2012.cpp
Lines 1063 and 1346 are most interesting for you.
The basic proposition is that a PID controller is overkill, or the wrong tool for the job; when you power the wheel, the RPM will increase, when you don't power the wheel, the RPM will decrease. Since you have direct control over what you want to change (speed of the wheel), you simply apply power when the wheel isn't going fast enough, and remove power once it is going fast enough; it won't continue going faster when you remove power, so you don't have to reduce power as you approach the setpoint (one of the features of a PID), and once you pass your setpoint removing power is the best way to reduce your speed (rather than applying power in the negative direction).
Our output to the motor uses a voltage ramp to prevent any big snap on/off actions (ie if the motor is off, quickly ramp up the voltage toward 100%, rather than jumping there instantly), other than that, it's "On" when too slow, and "Off" when too fast.
Make sure you are not in "brake" mode on your motor controller (a jumper on the Jaguar controls this).
Jon Stratis
14-01-2013, 15:37
We had this working for our drive train last year, and we program in Java. If you send an e-mail to 2177@therobettes.com, I'll make sure our programmers send you a code sample of what we did!
BradAMiller
14-01-2013, 19:40
If you want to use the PIDController class for this, be sure to use the FeedFoward term. It is documented partway down this page:
http://wpilib.screenstepslive.com/s/3120/m/7912/l/79828-operating-the-robot-with-feedback-from-sensors-pid-control
but basically, you need to give the motor a base value that is close the desired motor speed. The P, I, and D adjustments will be added to the FeedForward term in the calculations.
Brad
F22Rapture
14-01-2013, 20:15
Is there a way to hook an encoder to the CIMs if we aren't using a gearbox?
Radical Pi
14-01-2013, 21:17
I'm not sure of how one would do that (I'm not very mechanically minded), but there are other ways to measure the speed of a wheel. On our shooter last year we had a beam sensor which detected the spokes of the wheel instead of an encoder. It runs into some trouble at lower speeds, but the cRIO's counters are perfectly capable of measuring the speed of something like that
On our shooter last year we had a beam sensor which detected the spokes of the wheel instead of an encoder. It runs into some trouble at lower speeds
Did you ask the FPGA for the spoke count and then divide the change in spoke count by the elapsed time,
or
Did you ask the FPGA for the elapsed time (using the microtimer) between the last two counts ?
nighterfighter
14-01-2013, 21:34
http://www.chiefdelphi.com/forums/showthread.php?t=105679
jwakeman
15-01-2013, 00:30
If you want to use the PIDController class for this, be sure to use the FeedFoward term. It is documented partway down this page:
http://wpilib.screenstepslive.com/s/3120/m/7912/l/79828-operating-the-robot-with-feedback-from-sensors-pid-control
but basically, you need to give the motor a base value that is close the desired motor speed. The P, I, and D adjustments will be added to the FeedForward term in the calculations.
Brad
Happy to see a feed forward term was added to the PIDController class this year!
Radical Pi
15-01-2013, 00:43
Did you ask the FPGA for the spoke count and then divide the change in spoke count by the elapsed time,
or
Did you ask the FPGA for the elapsed time (using the microtimer) between the last two counts ?
The latter (via GetPeriod()). The issue was that the FPGA declared the motor stalled below certain speeds. We considered the other method for a bit, but decided that it wasn't really necessary to implement since the problematic speeds were so slow that the ball wouldn't even get out of the shooter.
Tom Line
15-01-2013, 08:57
Last year, we used a "Bang Bang" controller, which Mr. Ether helped us implement (though he got the idea from another member here, IIRC) for controlling our shooter wheel.
My C++ (similar enough to Java to help) source code from last year lives here:
https://github.com/TeamExcel/Project2012/blob/master/Robot2012.cpp
Lines 1063 and 1346 are most interesting for you.
The basic proposition is that a PID controller is overkill, or the wrong tool for the job; when you power the wheel, the RPM will increase, when you don't power the wheel, the RPM will decrease. Since you have direct control over what you want to change (speed of the wheel), you simply apply power when the wheel isn't going fast enough, and remove power once it is going fast enough; it won't continue going faster when you remove power, so you don't have to reduce power as you approach the setpoint (one of the features of a PID), and once you pass your setpoint removing power is the best way to reduce your speed (rather than applying power in the negative direction).
Our output to the motor uses a voltage ramp to prevent any big snap on/off actions (ie if the motor is off, quickly ramp up the voltage toward 100%, rather than jumping there instantly), other than that, it's "On" when too slow, and "Off" when too fast.
Make sure you are not in "brake" mode on your motor controller (a jumper on the Jaguar controls this).
A bang-bang controller tends to be limited in situations where your rotational inertia is not high. The result is an unstable speed that oscillates approximately just above your set point.
If you are using pneumatic wheels or something else with a reasonably high moment of inertia (I haven't done calculations to determine the cross over) then bang-bang is fine. Otherwise, you will probably want to look at PID. Or you can combine the two using a conditional to switch from bang-bang to PID when you are within a certain range of your setpoint.
EricS-Team180
15-01-2013, 09:43
Last year, we controlled our shooter wheel using a gear tooth counter as a sensor and a PID function based on BradAMiller's PIDController class. We
overloaded the Calculate function in the class (if I remember correctly...don't have the code here) based on a vi of a PID method posted, here, on CD by Kevin Harrial of Team 2168. (We re-wrote it in C++) Without the speed control we measured ~5.0sec recovery time after shooting a ball. With the PID we reduced that to ~0.5sec. 10x improvement! With the closed loop control, the drive team could shoot fast with good repeatability. In addition to the gear tooth sensor, we also tried a TachGen. It worked great, but it put us over the robot cost limit.
I haven't looked at Brad's method for this year, but that addition of the FF is a good one! :)
Eric
A bang-bang controller tends to be limited in situations where your rotational inertia is not high. The result is an unstable speed that oscillates approximately just above your set point.
If you are using pneumatic wheels or something else with a reasonably high moment of inertia (I haven't done calculations to determine the cross over) then bang-bang is fine
You can make it work with lower inertia wheels with just a few extra lines of code.
Instead of banging between 0% and 100% when you're near the setpoint, reduce the amplitude of the banging.
To do this, you need to have an idea of what the nominal required voltage is at each setpoint speed you want to control.
For a simple example, let's say you want to control the speed at 3000 rpm and you've found it takes approx 60% of full voltage to do that.
Change your bang-bang code from this:
if (speed > 3000) bang 0%
else bang 100%
...to this:
if (speed > 3000 + 200) bang 0%
else if (speed > 3000) bang 60% - 20%
else if (speed > 3000 - 200) bang 60% + 20%
else bang 100%
The numbers above in bold black are your setpoint and your estimated voltage% at setpoint.
The numbers above in red are "tuning parameters".
Making the 20% number larger improves spinup recovery time. Making it smaller reduces the amplitude of oscillations. Don't make it too small or you'll have essentially open-loop operation.
Making the "200" number smaller improves spinup recovery time. If you make it too small the extra lines of code have no effect - you've essentially got 0-100% bang-bang.
BitTwiddler
15-01-2013, 16:35
What is the advantage of using the "bang-bang" method of speed control versus PID?
Better use of the motor power band perhaps?
What is the advantage of using the "bang-bang" method of speed control versus PID?
If you've got enough inertia and can use the simple on/off logic, it requires no tuning and very little code.
Since the code is so simple, you can run it at higher speed without sucking up too much processing time.
It has the fastest spin-up and recovery time.
BitTwiddler
15-01-2013, 16:47
If you've got enough inertia and can use the simple on/off logic, it requires no tuning and very little code.
Since the code is so simple, you can run it at higher speed without sucking up too much processing time.
It has the fastest spin-up and recovery time.
Good to know. Last year we had problems with motor speed recovery time and this may be the solution. Thanks.
Luan Motta
15-01-2013, 23:54
Ok. Thanks everyone. I will try to put these codes in our robot.
vBulletin® v3.6.4, Copyright ©2000-2017, Jelsoft Enterprises Ltd.