From Team 449 Wiki
PID (proportional-integral-derivative) loops are simple type of control loop that we use for controlling drive trains and mechanisms. Control loops are complex and difficult to understand; this article is intended to provide just enough information to use PID loops. For more legit information, start with the Wikipedia pages for PID Control and and Control Theory.
Our new drive control setup is based around having PID loops all the way down, such that one PID loop gives the inputs to another. The first example of that is a TurnToAngle loop with a NavX. Because the lower-level loops have handled the nitty-gritty for you, this loop can be just a simple P loop. There are 6 variables you need to tune here, all of which can be found in the map. All terms provided below are just starting points, which worked well for a 6 cim drive with no weight on it.
The proportional gain term of the loop. The inner loop we're using goes from -1 to 1, so the P term that works for us is 0.01. Like any other P term, raise it if it's going too slow and lower it if it's overshooting.
This is the number of time slices the rolling average of error counts, but you can think of it as how long you have to be at the setpoint for before the loop exits. To convert to milliseconds, multiply by loop frequency, which defaults to 20. Raise it if the loop terminates after the first overshot, and lower it if the loop takes too long to terminate after settling at the target.
The allowable error for the loop to terminate within. 1 degree seems to work well, but raise it if you can't stay within the bound very well, or if speed matters more than accuracy.
You'll want a minimum output if you have issues overcoming static friction, and you want to increase it if you're going too slow once you start relying on it, and lower it if the robot overshoots or "dances" too much. You don't want this on a driveStraight method, but it helps speed up TurnToAngle.
This can either be used with a DriveStraight to keep the angle adjustment from making radical turns, or as a tuning option alongside a large P. To use it with a large P, the idea is that you have P be large in order to go fast close to the setpoint, and cap the speed for the rest of the loop at maximum output to prevent overshoot. If you're not doing that method, you'll probably want maximum output to be too large to really do anything under normal use, and just have it in place to stop things from going toooooo bad. Most TurnToAngle methods won't need it at all.
Within this range of the target, the loop tells the motors to not move at all. This is great for preventing overshoot, and should also always be used if you're using a minimum output to prevent the robot from "dancing" around the setpoint. It MUST be SMALLER than the Absolute Tolerance. Having it be the same does not work, and results in stupid floating point errors because WPILib wrote their code wrong. Even when the deadband is smaller, the floating point errors sometimes still happen, so you need a timeout on TurnToAngle methods to terminate it eventually if you run into a floating point error. 3/4 of the absolute tolerance works fine.