So I was watching worlds yesterday and today and I was amazed by some of the shooters at worlds that were able to shoot so consistently and so fast once they picked up a ball. For our team it took us at least 1 to 2 seconds to oscillate to the right speed and then once we reached that speed only then could we shoot. I was wondering if knew how these teams were able to reach the speeds so fast and then were able to shoot the ball with almost little to no error. Also does anybody know any teams with a public repository for code that can shoot almost immediately after picking up a ball. I’ve looked at a lot of the teams but most of there code is pretty complex so I was just wondering if anybody knew any teams that could shoot fast and had pretty simple code to understand.
Use a feed-forward with some P gain, rather than relying only on PID feedback.
Consider using an external encoder if you’re using NEO motors - there’s some filtering on the velocity of the motor’s internal encoder that can impact situations like this.
Be sure the “shoot” RPM is at about 50% - 75% of the maximum possible speed of the shooter wheel.
Be sure you have enough motors that the shooter can get from stopped to your shoot rpm in about 1 second.
Some teams keep their shooter running for the entire match (some will turn it off for endgames). This means you don’t have as much inertia to overcome from rest every time you shoot, and once spinning, flywheels don’t draw nearly as much current as they do initially from a start/stop bit.
That’s not as important for this game like it was for IR, since it’s only 2 balls per cycle, so more power from additional motors helps a lot to get up to speed from rest as well.
Gerthworn’s point are great and are likely most of what you need to do. some other things you might want to think about after doing them and maybe have already done:
Tune the allowed error for “shoot” RPM. Too high and you’ll miss and too low and you will not shoot. My team set it be 0.5% of the target RPM and that was good for us.
Start running the motors as soon as you detect a ball entering the robot to save a few fractions of a second.
Really, this is the key. If you get your feed-forward tuned just perfectly (while using voltage compensation!), you should use a small amount of P gain and see no oscillations. Once we got ours tuned well we could expect to get up to stable speed in 2-3 tenths of a second (we had a relatively light flywheel for how much power we had though).
You can calculate the energy stored in spooling up the flywheel and compare it to the energy used keeping the flywheel running over the duration of the match. One spool up plus full match for a high inertia flywheel is going to be less energy than maybe 3-4 spool ups. It was really a shocking amount of energy for our system. One other detail: idle at your minimum shooting speed… That way you don’t have to brake to get down for the close shot!
For our dual 6" Fairlane shooter, 2 NEOs, 0.75 step down ratio, 2100 RPM idling speed, that 179 Joules. Our idling current was only 0.1 Amps per NEO. So, idling for 3 minutes costs you 180 Joules (0.2 Amps * 12 Volts * 3 minutes * 60 seconds/minute). Spool up and hold for the match is 359 Joules of energy. So, 2 spool ups is the same energy cost as spool and hold!
For a lower inertia flywheel this calculation may come out differently! Also, you might find that the gyroscopic action of the flywheel might mess with a turret or maybe turning the robot fast.
How do you use voltage compensation, just set it to true? Besides , does using feedforward with some P gain means that l should set the P value of the motor first and use a feedforward to calculate the speed of it? Besides , how do you calculate your feedforward ? Do you use Sysid? Is there any tips when tuning the feedforward gains using Sysid?
To get values for P and F(eedforward), there may be fancy ways to do it, but we just take 15 minutes and do it this way:
Set P to 0
Take a random guess with F
Keep tuning F until it is getting extremely close to the target speed (within 0.1-1%).
Now, add in P.
Pick a P value high enough to respond well when a ball goes through, but not one so high that it causes ANY oscillation at any (high or low) target speeds
Thanks , so if l tell my TalonFX that the 12V is the max voltage and when the battery is 11V it will use more voltage to get to the speed. Is that right?
You want to set the max voltage somewhat lower than your battery voltage (10V is a common number). The TalonFX can’t send the motor more voltage than your battery has to offer, so voltage compensation works by slowing you down a tad on a full battery in the name of consistency.
The F value should work for all speeds (except maybe at the extremes - very slow and very fast). F isn’t a static number that gets added to the voltage. It’s a factor that scales the input request to the output.
Conceptually, you could implement F yourself like this:
kF = 0.001 //Value found by tuning
targetSpeed = 500
motor.set(kF*targetSpeed)
So no, P will not carry it on up. The “F” part of the control loop will ask for more voltage when a higher speed is requested. P is honestly just for insurance/faster recovery/ getting up to speed.
You don’t really need to tune the feedforward gains for SysId, you just run the program and get the gains.
Then you just use the SimpleMotorFeedforward object to calculate the voltage needed for your set points (make sure your units are right) and pass it into whatever control loop you’re using (iirc CTRE lets you plug in the feedforward into their control loops).
Question to further this discussion because it’s something I’ve long wondered, but a bit long-winded (either that or I just have a way of making everything I say long-winded ). The thread title is pretty general so the more useful it is for future lookers the better.
Setting up a shooter to function at a fixed speed is pretty straightforward forward all things considered, even once you consider PID and other fancy features for keeping the shooter wheel at speed and consistent.
What I want to know is more related to characterizing your shooter such that speed & hood angle can be adjusted based on distance, movement direction (since we live in the age of swerving and shooting while moving now), etc.
Now I’m an engineering student so 3 methods come to mind, but looking at how consistent top-tier teams are with shooting, I can’t envision those methods being that level of foolproof but I’d love to be wrong.
Dynamics (spicy physics) Characterisation: you use dynamics to write a function that takes in the distance, height, and other world parameters you can measure that define where your target is and spits out the RPM needed. This is relatively simple since my algebra skills are no longer limited by my 3-hour exam window, and asking some of my profs how they would tackle a problem like this, this is what they swear by. But raw physics is only as accurate as the assumptions you’ve made and with the level of shooter consistency we see year after year with top tier teams, something tells me this can’t be the only thing going on, especially once things like backspin, and slipping along the hood are in play. You could try to account for them by using coefficients that you tune in later but that seems really tedious.
Look-up Table: This is how I would do this if you told me to get this set up today. Using a table with location ( XY or any other pair of variables [r & theta comes to mind for this actually]) on the row and column of the table at specified intervals, you can manually set output parameters that correspond to each location via trial and error. Then on the field, the code can interpolate between boxes to shoot “anywhere”. This seems really plausible to me assuming you have a good way to take in the parameters and get more accurate the more fine the intervals between your boxes are, and you don’t actually need to do any fancy physics either. However, Unless you want to get into the world of double, or even triple interpolation, trying to do this for shooting on the move seems like a nightmare.
Turn it into a simple function and tune coefficients based on trial and error. I assume for the average team, this is likely what happens, and you end up with a shooter that works really well in a location or to but is meh at best everywhere else. You can probably try to make the shooter speed and hood angle just a simple function of distance and height, and if you have the ability to swerve or a turret, you can just try offsets based on the heading. This is jank and probably won’t work very well but I have seen it attempted and work well enough for teams who have decided they only really need a few places to shoot from well.
If anyone here is from a team that has an insanely accurate and consistent shooter, I’d love to learn how you did this so I can pass that knowledge on.
Your feedforward should assume there are no disturbances, since it’s trying to capture the ideal scenario for your flywheel. You can then use PID to compensate for any disturbances (e,g. a ball coming into contact causing it to decelerate).
Thanks that , but when calculating the simplefeedforward gains of a drivetrain, l need to put a robot on the ground to calculate the extra voltage which needs to be added to compensate the friction and so on. But , as your saying goes, does it mean that l just don’t need to put my drivetrain on the ground? How can it be explained?
By “ideal scenario” I meant “nominal ideal scenario”. Your drivetrain will typically be contacting carpet, so your feedforward should account for that. On the other hand, your flywheel will be spending more time not in contact with anything, so it should model that scenario.
8033 shot about 95% during day 1 of Turing and used an interpolated lookup table to determine speed and hood angle. The nice thing about the table is that tweaking behavior at a specific distance from the hub is simple to understand and to carry out without breaking anything else. We didn’t attempt shooting on the move though so I can’t speak to how we’d have adapted it. Maybe for Chezy if we get in and the team is feeling motivated
For IR@H we had taken samples and derived a continuous function, but with a static flywheel speed it was simpler to do so.