Is this possible to use the Talon-SRX with a bang-bang algorithm so that the Talon checks the encoder value?
The encoder is connected to the Talon directly.
I want to do this in order to sample the encoder in a faster rate than regular code.
and another question:
What is better for getting a shooter to the target speed faster - Bang-bang or PID (using Talon SRX)?
Probably depends a lot on the mechnasim it’s attached to, and how precise you need it’s spin to be.
For instance, we have a 5 lb wheel that we have a CIMcoder + miniCIM running off a talon. When we remove power and leave the talon in coast mode, it maintains it’s speed pretty well (until it has any load obviously). It also takes a fair bit of effort to spin it up, so the bang-bang type method might actually be the preferred method. Functionally - I’d argue this is pretty much a crude PID control with a high P.
If you have a mechansim without that much inertia, under a higher load, or that you need more finely controlled - then PID is definitely a good way to go. I can say first hand that the talon has a lot of good documentation for Java. I think it does for Labview and C++ too: https://www.ctr-electronics.com/Talon%20SRX%20Software%20Reference%20Manual.pdf
It is also possible to simulate a bang-bang controller using PID, by setting the P gain very high and limiting the output so the motor can only try to move in the desired direction. This can be done using the Talon SRX API.
I’d assume that bang bang would theoretically spin up faster since it spins at full speed until it hits the target speed. However, when I tried it, when it got up to speed, the motor started making nasty noises when flickering on and off.
I found the PID + Feedforward (built into the SRX) to work great on speed control. In fact, I got great results with purely P and F. It spins up fast, goes right to the target speed, and doesn’t make the same disconcerting noises that I experienced with bang bang.
I guess the results of bang bang vary from system to system.
This is what we are currently using, though I have some experimental code that uses the pseudo-bang-bang I described before. Ours sits around ±50 RPM from the target, which turned out to be good enough for our shooter.
*Bang-bang can be a good solution to shooter wheel speed control, but if you’re using the SRX via CAN with the encoder plugged into the SRX, I’d say definitely use the SRX’s built-in PIDF speed control, which updates at 1KHz (far faster than roboRIO does PID).
I’ve heard this happen when the motor controller was set to brake mode. Another possible reason: to much free play between motor shaft and wheel (gearbox, chains, etc). See this post.
We are running a simple Bang-Bang in Java this year.
We are using separate thread to control the wheel. It measures the period of a single flag on the shooter wheel. We have two 775-Pro driving the wheel with a 60:19 reduction.
Here a a couple “gotcha’s” we encountered.
A 10ms control loop is too slow with this set up. Way too much overshoot. We went with a 5ms loop and overshoot is tolerable.
Running 2 775-Pros is overkill!
We run ours with one breaker removed for one of the motors. This helps reduce overshoot and gives us a backup in case something terrible happens.
We are using a Banner photo sensor, I believe the model is Q12RB6LV, and a single piece of Retro tape in one section of our shooter wheel. The tape spans approximately a 50 deg arc. You can see it in the photo below near the bottom of the image.
I had our programmer work with the WPILib to figure out how to get the period of a pulsed signal. I believe the command he is using is getPeriod(), at least that rings a bell.
getPeriod() returns a value in seconds and has a resolution of 1ms. This limits the number of steps in RPM we can achieve to only 15, but that is more than enough for this game. The value we read is very consistent.
We usually target a period of .025 for our default shot, but will vary it with distance to as low as .010 as needed (10ms is basically full power all the time).
getPeriod
public double getPeriod()
Get the Period of the most recent count. Returns the time interval of the most recent count. This can be used for velocity calculations to determine shaft speed. Specified by:
getPeriod in interface CounterBase Returns:
The period of the last two pulses in units of seconds.
That and the fact that the value getPeriod() produces only has 3 places to the right of the decimal point. ie. .020.
I have no problem being wrong in my interpretation, wouldn’t be the first time. But I can tell you this, our code works, and we use 3 decimal place values to control it.
Remember my disclaimer, Java is not a programming language I use.
We have 6 motors on our robot this year that use the velocity-control loop provided by the CAN Talon SRX at least some of the time. It works great and is dead simple to tune (RTM for details, but start with F from first principles or measurement then add some P until you’re happy…maybe D if you are feeling fancy).
1KHz control loop + internally low-pass filtered velocity measurement (basically a moving average filter over the last 32(?) dEncoderTicks/100ms) = I’m unlikely to use anything else for velocity control in FRC ever again