We achieved reasonably good velocity control using PID, but it required making a custom PIDOutput sink. Basically, what we did is - instead of treating the output to the PID loop as a value to send to the motor, we treated it as a difference to apply to the current value being sent to the motor, and limited this change to +/- .25 in order to keep it from changing too erratically.
As a rough sketch:
Code:
//global variables just for demonstration purposes
//set these up!
Jaguar jag;
Encoder enc;
float p, i, d;
class spd_control : public PIDOutput {
float speed;
public:
void PIDWrite(float offset) {
speed = coerce(speed + offset, -1.0f, 1.0f);
jag.Set(speed);
}
};
spd_control jag_spd_ctl;
PIDController control(p, i, d, enc, jag_spd_ctl);
control.SetInputRange(0.0, MAX_SPEED);
control.SetTolerance(TOLERANCE);
control.SetOutputRange(-0.25, 0.25);
*Horrible* code, but you get the idea.