Mastering PID Control for FTC Drivetrains
A deep dive into PID controllers and how to implement them for smooth, accurate robot movement. Includes tuning tips and real-world examples.
Mastering PID Control for FTC Drivetrains
If you’ve ever watched a robot overshoot its target or oscillate back and forth trying to reach a position, you’ve seen what happens without proper control. PID control is the solution—and mastering it will take your autonomous routines from amateur to elite.
What is PID?
PID stands for Proportional-Integral-Derivative. It’s a control loop mechanism that continuously calculates an error value and applies a correction based on three terms:
- P (Proportional): Reacts to the current error
- I (Integral): Accounts for past errors (accumulated over time)
- D (Derivative): Predicts future errors (rate of change)
The Math Behind PID
The output of a PID controller is:
output = Kp * error + Ki * integral + Kd * derivative
Where:
error= target - current positionintegral= sum of all past errorsderivative= current error - previous error
Implementing PID in FTC
Here’s a reusable PID controller class:
public class PIDController {
private double Kp, Ki, Kd;
private double integral = 0;
private double previousError = 0;
private ElapsedTime timer = new ElapsedTime();
public PIDController(double Kp, double Ki, double Kd) {
this.Kp = Kp;
this.Ki = Ki;
this.Kd = Kd;
}
public double calculate(double target, double current) {
double dt = timer.seconds();
timer.reset();
// Prevent huge dt on first iteration
if (dt > 0.5) dt = 0.02;
double error = target - current;
// Proportional
double p = Kp * error;
// Integral (with anti-windup)
integral += error * dt;
integral = Math.max(-1, Math.min(1, integral)); // Clamp
double i = Ki * integral;
// Derivative
double derivative = (error - previousError) / dt;
double d = Kd * derivative;
previousError = error;
return p + i + d;
}
public void reset() {
integral = 0;
previousError = 0;
timer.reset();
}
}
Using PID for Driving a Distance
public void driveDistance(double inches, double timeout) {
PIDController pid = new PIDController(0.05, 0.001, 0.02);
ElapsedTime timer = new ElapsedTime();
double ticksPerInch = 537.7 / (4 * Math.PI); // Adjust for your motors
int targetTicks = (int)(inches * ticksPerInch);
resetEncoders();
while (opModeIsActive() && timer.seconds() < timeout) {
int currentPosition = leftMotor.getCurrentPosition();
double power = pid.calculate(targetTicks, currentPosition);
// Clamp power
power = Math.max(-0.8, Math.min(0.8, power));
setMotorPowers(power, power);
// Check if we're close enough
if (Math.abs(targetTicks - currentPosition) < 20) {
break;
}
telemetry.addData("Target", targetTicks);
telemetry.addData("Current", currentPosition);
telemetry.addData("Power", power);
telemetry.update();
}
setMotorPowers(0, 0);
}
Tuning Your PID
Tuning is where the magic happens. Here’s the Ziegler-Nichols method adapted for FTC:
Step 1: Start with P only
Set Ki and Kd to 0. Increase Kp until the robot oscillates consistently. Note this value as Ku (ultimate gain).
Step 2: Measure oscillation period
Time how long one complete oscillation takes. This is Tu.
Step 3: Calculate starting values
Kp = 0.6 * Ku
Ki = 2 * Kp / Tu
Kd = Kp * Tu / 8
Step 4: Fine-tune
From here, adjust:
- Too much overshoot? Reduce Kp or increase Kd
- Too slow? Increase Kp
- Steady-state error? Increase Ki (carefully!)
- Oscillating? Reduce Ki and increase Kd
Common PID Pitfalls
- Integral windup - Always clamp your integral term
- Derivative noise - Consider filtering or reducing Kd for noisy sensors
- Ignoring units - Make sure your gains match your units (degrees vs radians, ticks vs inches)
- Not resetting - Reset your PID controller between moves
Beyond Basic PID
Once you’ve mastered basic PID, explore:
- Feedforward control - Add a baseline power for known movements
- Motion profiling - Smooth acceleration and deceleration curves
- Cascaded PID - Inner and outer control loops
- Road Runner - A library that handles much of this for you
Recommended Tuning Values to Start
| Application | Kp | Ki | Kd |
|---|---|---|---|
| Drive distance | 0.03-0.08 | 0.001-0.01 | 0.01-0.05 |
| Turn to heading | 0.02-0.05 | 0.001-0.005 | 0.005-0.02 |
| Arm position | 0.005-0.02 | 0-0.001 | 0.001-0.01 |
Note: These are starting points. Your robot will need specific tuning.
PID control is a skill that takes practice. Don’t get discouraged if your first attempts aren’t perfect—even experienced teams spend hours tuning. The payoff is worth it!
Level Up Your Season
Dominate the competition with our other powerful tools.
FTC Secrets
The most comprehensive analytics platform for FTC. Analyze match data, scout teams, and uncover winning strategies with deep insights.
Analyze Now →FTC Coach
Your hyper-personalized assistant for the season. Master your engineering portfolio and ace judging preparation with AI-powered guidance.
Get Coached →