I have (for the most part) successfully implemented motion magic on my team’s elevator.
Although it works smoothly, there are a few flaws with the way I have implemented it.
As it raises to a position, it gets within 20ish native units of the target. In terms of accuracy, this is sufficient. The problem with this, however, is the only reason it holds its position is due to it not reaching the target. The arb feedforward term + PDF (not using I) is enough to hold it just under the setpoint, but not move the mechanism.
Although this seems to work well, I’m not satisfied with it.
Adding to the first problem, when moving the elevator back to the bottom, since it never reaches the setpoint, it stalls the motor. This basically means that if the robot is enabled, the motor is always stalled. Ideally, I would like the motor to receive 0 voltage at the bottom position, but apply just enough voltage to hold the mechanism.
So, what are you guys doing to apply a constant voltage once your elevator has reached its setpoint, but apply 0 voltage at the bottom?
For the second issue, last year, we just had a check in our code to see if we were within ~.25" of the bottom and trying to go down or stay still, and set to open loop control with 0 power if that was the case.
For the first, from what I’ve heard, you can resolve the issue by switching to position PID after you get close to your target to hold position.
you don’t really need f but I recommend just using P and I then setting an integral zone, then you can drive it off of encoder position. That’s what I did with our robot and it works like a charm
Just to clarify, motion magic requires a kF value. This is for the velocity feedforward that is calculated and updated internally on the talon throughout the motion.
For mechanisms where gravity has an effect, you can use add an arbitrary feedforward to compensate. This arbitrary feedforward value is added to the final output calculated by motion magic.
Last year, our elevator used positional PID in the hold state, and this worked well for us. Basically, once the elevator had reached its target and was no longer moving, the elevator would switch to the hold state until the operator (or autonomous code) commanded it to move to a new position.
Assuming that the target is reached, does MotionMagic ignore the arbfeedfwd value for a total output of 0, or does it just zero the output generated by PIDF?
ArbitraryFeedFwd is always added. Many use-cases require this, such as gravity compensation on a lift/elevator - which you typically want even after reaching the target.
Note that we used position PID for moving the elevator as well, but had a different set of gains for holding. We also did not use any sort of feedforward value to compensate for gravity. I would not say that is the best approach, but it worked well enough that no one bothered to implement any better control code. 2018 was not a year where you needed particularly precise elevator motion.