We do this and the logic is pretty simple.
Code:
motorL.set(straightControllerResult + turnControllerResult);
motorR.set(straightControllerResult - turnControllerResult);
Where straight controller and turn controller are separate PID controllers, using the drive encoders for distance and the gyro for angle respectively.
We did something similar to Joe (we don't use the WPILib PIDController, but we have a similar modular output system in ours).
Code:
private class DTOutput implements PIDOuput {
boolean isStraight = false;
double t,s;
public DTOutput(boolean isStraightController) {
isStraight = isStraightController;
}
public void set(double val) {
if (isStraight)
s = val;
else
t = val;
drive(t+s,t-s);
}
...
straightController = new PIDController(whatever, new DTOutput(true));
..
Inelegant that we need to cache the values, but it gets the job done.