Ok, I didn't talk about the process for determining the gains.
There are several methods for tuning the gains. This is the method I use. The first step is to determine which terms you need.
P only:
If you only need P, you initially ask yourself this question:
-At what point would I start to slow down the motor of I was driving the mechanism manually? What is the value of Error at this point (irrelevant of sign)
-What is the range of my motor(in FRC this number is usually +-1, sometimes it's 127 in 8-bit systems)
-Divide these numbers. Motor on top, Error on bottom. Then, at that exact error, the Motor will be the maximum motor possible. At less error, you will get less power. At more error, you won't get more because you've saturated the output.
Once you've got an initial ballpark gain, you can run the system through various error and range tests (By setting the starting position and setpoint to different things and letting it try to find the position). You manually tweak as necessary. It's a balancing act between overshoot and time to target, you need to prioritize as you wish.
PI:
-Start with P only and get a good P gain
-Decrease P slightly (90% or so of what it was) and add I. I, in many of my PI position controllers, is roughly 10% of P.
-If you are getting oscillation, look at the windup of the integral (graphs help here). Limiting the max range of the in positional controllers is usually a good thing.
-It's mostly just playing around with the numbers until you're happy.
PID:
-I have not manually tuned a PID controller before. I use the Ultimate Stability ("Zeigler-Nichols") auto-tuning method when I need all three terms. I recommend reading about it elsewhere, it basically goes like this:
-Find the P gain at which the system oscillates at the same amplitude indefinitely. This is the Ultimate Gain (kU)
-Find the period of oscillation. In my case, timing was in loops (timing was deterministic enough for no dt-compensated math), so I counted loops in my data captures between peaks of the oscillation. If I was multiplying I and D by dt, I would use Milliseconds (or the units of dt) instead.
-Use some magic formulas which I found on The Internet to determine the gains for P, I, and D. I found the Internet (I particularly liked
this site for these numbers). Note that you end up with tI and tD, you need to convert them to kI and kD. kI = kP / tI, kD = kP*tD
This method worked well for all of the VRC arms I tuned (many). My tolerances were rather large (+-1" at the end of a 24" arm) and I was useful to deal with varying weight. I tuned with one game piece, since I could hold two game pieces, and it seemed to be close enough.
(Note: An LUT is a Look-Up Table. Basically all control systems I deal with in Powertrain are heavily based on interpolated lookup tables.)