#
Lesson 6: PID Loops (Feedforward for Friction Compensation)
#
Objective
Teachers will guide students through implementing a PID controller with feedforward to handle frictional resistance in the XRP robot’s drivetrain. Students will learn to fine-tune PID constants and use feedforward terms to improve motion smoothness.
#
Prerequisites
- Completion of Lesson 5: PID Loops - Gyro Turn.
- Robot code that can already perform basic PID turning using the gyro.
#
Teaching Notes
This lesson builds on PID control by showing how feedforward compensation can offset predictable frictional forces that cause sluggish or inconsistent performance. This mirrors real-world FRC control strategies for mechanisms like drivetrains and arms.
#
Lesson Outline
#
1. Recap: What Is Feedforward?
Feedforward adds a predictable control term that helps the PID controller overcome known system resistance.
Formula:
Output = kP * error + kI * errorSum + kD * errorRate + kS + kV * velocity
Where:
kSis the static friction compensation (voltage needed to overcome stiction).
Explain that while PID corrects errors, feedforward anticipates the required effort to move smoothly.
#
2. Example: Accounting for High Friction
Use this concept to improve the gyro turn from Lesson 5.
public class GyroTurnCommand extends CommandBase {
private final Drivetrain drivetrain;
private final ADXRS450_Gyro gyro = new ADXRS450_Gyro();
private final double targetAngle;
private final PIDController pid = new PIDController(0.02, 0.0, 0.001);
// Feedforward constants
private final double kS = 0.15; // static friction voltage
private final double kV = 0.0; // optional if you want velocity scaling
public GyroTurnCommand(Drivetrain drivetrain, double angleDegrees) {
this.drivetrain = drivetrain;
this.targetAngle = angleDegrees;
addRequirements(drivetrain);
pid.setTolerance(2.0);
}
@Override
public void execute() {
double error = targetAngle - gyro.getAngle();
double pidOutput = pid.calculate(gyro.getAngle(), targetAngle);
// Add static friction feedforward
double output = pidOutput;
if (Math.abs(pidOutput) > 0.01) {
output += Math.copySign(kS, pidOutput);
}
drivetrain.arcadeDrive(0, output);
}
@Override
public boolean isFinished() {
return pid.atSetpoint();
}
@Override
public void end(boolean interrupted) {
drivetrain.arcadeDrive(0, 0);
}
}
#
3. Tuning Process
- Start with feedforward only (
kS). Increase until the robot starts moving smoothly at low speeds, then turn it down so any PID output will move it. - Then add PID tuning from Lesson 5 to refine accuracy.
- Observe how feedforward reduces overshoot and startup lag.
#
4. Teaching Demo
- Have students compare turns with and without feedforward.
- Record both runs using AdvantageScope (next lesson) to visualize PID output and angle tracking.
#
Discussion Points
- How does friction affect turning precision?
- Why is static feedforward especially useful on small robots like the XRP?
- What other mechanisms (like arms or elevators) might need feedforward in FRC?
#
Estimated Duration
60–75 minutes (including testing and tuning)
#
Learning Outcomes
- Understand feedforward’s role in overcoming system resistance.
- Apply friction compensation to improve control smoothness.
- Tune combined PID + feedforward loops for reliable motion.