Feedforward: predict, don't just react#
Where PID reacts to error, feedforward predicts the output a mechanism needs to follow a desired motion — before any error appears. Combining feedforward (the bulk of the output) with PID (small corrections) gives the best of both: responsive and accurate.
WPILib provides feedforward classes:
SimpleMotorFeedforward— for flywheels and drivetrains (no gravity load):SimpleMotorFeedforward ff = new SimpleMotorFeedforward(kS, kV, kA); double volts = ff.calculate(targetVelocity); motor.setVoltage(volts);ArmFeedforward— adds akG(gravity) term that depends on arm angle.ElevatorFeedforward— adds a constantkGto fight gravity on an elevator.
The gains mean:
- kS — voltage to overcome static friction.
- kV — voltage per unit of velocity (the big one).
- kA — voltage per unit of acceleration.
- kG — voltage to hold against gravity (arm/elevator only).
You find these with the SysId characterization tool. (API note: as of WPILib 2025 the two-argument calculate(velocity, acceleration) overload is deprecated in favor of calculateWithVelocities(currentVel, nextVel), which discretizes correctly; the single-argument calculate(velocity) form is not deprecated and is fine for learning.)
Combining feedforward and PID#
The combination is simply adding their outputs:
double output = ff.calculate(targetVel) + pid.calculate(measuredVel, targetVel);
motor.setVoltage(output);
Feedforward does most of the work; PID cleans up the rest.
Motion profiling: smooth setpoints#
Feeding a mechanism a giant instant jump ("go from 0 to 90 degrees NOW") causes a violent move. A motion profile generates a smooth path of intermediate setpoints over time. WPILib's TrapezoidProfile ramps velocity up, cruises, then ramps down — a trapezoid shape — bounded by max velocity and max acceleration constraints.
ProfiledPIDController: the convenient combo#
Combining a profile with PID is so common that WPILib bundles them into ProfiledPIDController: it internally generates trapezoid setpoints and runs PID to follow them.
ProfiledPIDController controller = new ProfiledPIDController(
kP, kI, kD,
new TrapezoidProfile.Constraints(maxVel, maxAccel));
double output = controller.calculate(encoder.getPosition(), goalPosition)
+ feedforward.calculate(controller.getSetpoint().velocity);
motor.setVoltage(output);
This is the gold-standard pattern for an arm or elevator: a profile for smoothness, feedforward for prediction, PID for accuracy.
Why this matters for competition#
Well-tuned feedforward + motion profiling makes mechanisms fast and repeatable — an arm that snaps to scoring position without overshoot, a flywheel that holds RPM through a shot. The difference between "it kind of works" and "it works every time" is usually here. The same profiling idea scales up to whole-robot paths, which is the next module.
the part worth keeping
Key takeaways
- Feedforward predicts required output; PID corrects the remainder. Add their outputs.
- Use SimpleMotorFeedforward (flywheel/drive), ArmFeedforward, or ElevatorFeedforward (adds kG).
- Find kS/kV/kA/kG with the SysId characterization tool.
- TrapezoidProfile generates smooth velocity-limited setpoints.
- ProfiledPIDController bundles profile + PID — the standard pattern for arms and elevators.
Programming, Controls & SensorsMotors, Sensors, and Closed-Loop Controllesson 4 of 4
Keep going
Take the quiz+10 XP with an accountMore in Motors, Sensors, and Closed-Loop Control
where this came from
Sources and corrections
This lesson is AI-assisted: drafted from primary sources, then reviewed and edited by hand. Errors still get through. When one is reported we fix it and write down what changed, in public, in the corrections log.
sources and further reading
- docs.wpilib.orgFeedforward Control in WPILib
- docs.wpilib.orgCombining Feedforward and PID Control
- docs.wpilib.orgCombining Motion Profiling and PID (ProfiledPIDController)
clipped to this lesson
Articles that go further on this
The lesson gets you through the topic. These go wider on it, and they read in one sitting.
answer sheet
Lesson quiz
All 3 right completes the lesson. Miss one and only that question comes back, anything you already answered correctly stays banked.
0 of 3 answered
01In WPILib's SimpleMotorFeedforward, what does the kV gain represent?
02How does feedforward control fundamentally differ from PID feedback control?
03What does WPILib's TrapezoidProfile / motion profiling provide inside a ProfiledPIDController?
Answer every question to submit.
All 51 lessons in Programming, Controls & Sensorsopenclose
01 / prerequisites
02 / foundations-tools-and-first-program
03 / robot-program-and-command-based
04 / motors-and-control
05 / autonomous-trajectories-simulation
06 / sensing-fundamentals
07 / encoders
08 / gyros-imus-orientation
09 / closed-loop-control
10 / vision-pose-estimation
11 / worked-examples-mini-projects
- Not read yet:Mini-Project: A Closed-Loop Elevator with Motion Magic
- Not read yet:Mini-Project: A Velocity-Controlled Shooter on REVLib
- Not read yet:Mini-Project: A Teleop Swerve Drive Subsystem
- Not read yet:Mini-Project: An Autonomous Routine with PathPlanner
- Not read yet:Mini-Project: Vision-Aligned Scoring with Limelight
12 / common-mistakes-troubleshooting
13 / advanced-techniques-case-studies
- Not read yet:State-Space Control and Kalman Filtering
- Not read yet:Log Replay Architecture with AdvantageKit
- Not read yet:Advanced Pose Estimation: Multi-Tag Fusion and Standard Deviations
- Not read yet:Robot Coordination, Alerts, and Operator Feedback
- Not read yet:Case Study: Hardening Software Before an Event