My understanding is that the standard PID controller is set up to apply motor speeds to reach a certain distance. In this scenario, the end value goes to 0 when the target is reached.
For a rate controlled system, the end value is not 0 (you don't want your motor power to go to 0 when you achieve the desired rate).
So, what we have been doing is trapping the pidWrite() method (if you extend PIDSource) or usePIDOutput() method (if you extend PIDSubSystem). We then use the value passed in by the PID control loop as a "adjustment" to the current motor power. For example:
Code:
/**
* Processes the computed PID output value to apply to our system.
*
* <p>It is important to remember that the actual PID controller that is
* making computations and calling our method will be trying to reach a
* output level of 0.0 when the target is reached. This works well when your
* PID is used to move to a certain distance (you want your motors to stop
* when you reach your target).</p>
*
* <p>However, our motors are driving a spinning wheel and we want to reach
* a certain speed (the motor will not be 0.0 when the speed is reached). In
* order to handle this condition we need to treat the new values provided
* by the PID controller as ADJUSTMENTS to the current motor power
* setting.</p>
*
* @param power The power level adjustment to apply to the motors.
*/
protected void usePIDOutput(double power) {
if (DEBUG) {
SmartDashboard.putDouble("ShooterPIDAdjust", power);
}
// Apply adjustment provided by PID controller to current power output
// level and make sure its in the range of [0, 1].
double ratePower = power + leftMotor.get();
if (ratePower > 1.0) {
ratePower = 1.0;
} else if (ratePower < 0) {
ratePower = 0;
}
// Apply the new power level to reach the target rate
applyPower(ratePower);
}
Hope that helps.