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 position
  • integral = sum of all past errors
  • derivative = 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

  1. Integral windup - Always clamp your integral term
  2. Derivative noise - Consider filtering or reducing Kd for noisy sensors
  3. Ignoring units - Make sure your gains match your units (degrees vs radians, ticks vs inches)
  4. 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
ApplicationKpKiKd
Drive distance0.03-0.080.001-0.010.01-0.05
Turn to heading0.02-0.050.001-0.0050.005-0.02
Arm position0.005-0.020-0.0010.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!

Explore FIRST® Robotics

FIRST® (For Inspiration and Recognition of Science and Technology) is a global robotics community preparing young people for the future. Discover the ultimate sport for the mind and see how you can get involved in STEM and robotics!

Learn More at firstinspires.org