Tuning the PIDs
The default gains in the example get the robot moving, but every drivetrain is different. Plan on 20-30 minutes with the robot on a field.
How PID works (30-second version)
Each tick, the controller computes an output from the error (target − current):
- kP (proportional) — the workhorse. Output proportional to error.
- kI (integral) — accumulates leftover error. Rarely needed on drivetrains; leave at 0 unless the robot consistently stops short.
- kD (derivative) — reacts to how fast the error is shrinking. Damps oscillation and overshoot.
Tune angular first
Turning affects driving (moveToPoint uses both controllers), so tune the angular controller first. Use a simple test routine:
void autonomous() {
chassis.setPose(0, 0, 0);
chassis.turnToHeading(90, 2000);
chassis.waitUntilDone();
pros::delay(1000);
chassis.turnToHeading(0, 2000);
}
- Set
kI = 0,kD = 0, and start with the examplekP. - Raise
kPuntil the robot turns quickly and oscillates slightly around the target (overshoots, comes back, overshoots less...). - Raise
kDuntil the oscillation just disappears. If the robot gets twitchy or grinds,kDis too high. - Repeat 2-3: you can usually push
kPhigher oncekDis damping it. - Test with several angles (45°, 90°, 180°) — a tune that only works for
90° turns has too little
kPor too muchkD.
Then tune lateral
Same procedure with a drive test:
Test at 24" and 48". Watch for:
- Stops short, no oscillation → raise
kP. - Overshoots / wiggles at the end → raise
kD(or lowerkP). - Jerks violently at the start → lower the
slewvalue in your lateral settings (it limits acceleration). If the start feels sluggish, raise it.
Exit conditions
Once the gains are good, tighten the exit conditions to stop wasted time at the end of motions:
| Field | Meaning | Make smaller when... | Make larger when... |
|---|---|---|---|
smallError / smallErrorTimeout |
"settled" window | motions end sloppy | motions hang at the end |
largeError / largeErrorTimeout |
"good enough" bailout | accuracy matters | speed matters |
A motion exits when error stays inside smallError for
smallErrorTimeout ms, or inside largeError for largeErrorTimeout
ms, or at the motion's overall timeout.
Verifying odometry accuracy
Bad odometry looks exactly like a bad tune, so verify tracking before blaming the PID:
- With the pose printed on the brain screen, push the robot by hand in a big square back to its start. The pose should return to within ~1" and ~2°.
- If x/y drift when you spin the robot in place, a tracking wheel
offsetis wrong (see below). - If distances are consistently a few percent off, the wheel
diameteris wrong: drive an exact distance and scale the diameter byactual / reported.
Calibrating offsets by spinning
Spin the robot in place exactly 10 times (use the printed heading: 3600°). If the pose translates while spinning, adjust the offset of each tracking wheel:
Tweak until 10 spins move the pose less than an inch.
IMU scaling
If heading reads 3590° after exactly 10 physical rotations, your IMU under-reports by ~0.3%. Small IMU error is normal; tracking-wheel heading (two parallel wheels, no IMU) can actually beat a poorly-scaled IMU if your build quality is good.