While tuning our feed forward control for our shooter this year, we noticed a substantial difference in accuracy between a low speed and a high speed when using a single feed forward constant.
Now, we could have tuned it and taken the data over the range, done a regression to get a feed-forward equation, and used that for a feed forward for the shooter. However, I recall that repeated calls to the ‘set’ command for the pdif constants really hurts the can bus. So sending a new feed forward for each input would be problematic.
What’s the solution for a system like this where the feed forward appears to need to be non-constant and you’re using the onboard speed control built into something like the falcon?
I suppose you could also create a formula that modifies the input speed to correct for the feed forward not being accurate enough.
Is this a situation where you would use both a feed forward (Kf) and an arbitrary feed forward too?
This is what the characterization tool finds you. It effectively models outputVolts = kS + kV * targetVelocity*, where kS is your “static” gain, and kV is your “velocity” gain. It sounds like you were only using kS, which can work in a lot of scenarios, but not in your specific system.
You do not need to recalculate this every loop cycle, as it’s based on the target velocity, not the current measured velocity. You only need to do this once per setpoint. If you’re changing your setpoint, you’re already making a call to the CAN bus anyway.
The Spark MAX supports taking in an arbitrary feed forward in volts or percent out when calling spark.getPIDController().setReference(...).
I haven’t done in-depth work with the CTRE API for a few years now but I would be surprised if it did not support the same thing.
You can characterize a flywheel very easily yourself by hand. Increase kS until it barely starts to move. That’s your kS. Throw 6V at the motors and measure the velocity. Then solve the formula mentioned above for kV.
* It also measures kA, for acceleration, but you don’t need it.
where velocityTicksPer100ms and ffVolts are placeholder variables for the actual values you want to use there. Note that the CTRE API uses percent out as the unit for the arbitrary feedforward, hence the division by 12. Because of this, you should also enable voltage compensation on the motor controller to make that division valid:
In general: expand your feedforward equation to account for more things. In particular, as the above posts mention, kS is usually non-negligible and should be included. If the feedforward is still not good enough, it can sometimes rate to implement the feedforward as a lookup-table to account for nonlinearities in the system response.
In general, gain scheduling should never be necessary for a mechanism whose dynamics do not fundamentally change during operation.
First we start with the feed forward constant. We pick the range of values of the shooter we are going to be operating in and then adjust the fed forward to get us to those values.
Next, we start increasing p while switching back and forth between our min and max operating speeds until we get a healthy oscillation. The we add d until the oscillation damps.
Then we go back and touch up the feed forward once more if needed.