Feedforward: kS, kV, kA, and kG
Feedforward uses a model of your mechanism to predict the motor voltage needed for a desired motion, rather than waiting for error like PID. Feedforward does most of the work; PID corrects the rest. This is the single biggest upgrade most teams can make to their control quality.
The constants
Section titled “The constants”Feedforward voltage is built from terms, each a physical effect:
- kS (static friction): the constant voltage needed just to overcome friction and start moving. Applied in the direction of motion.
- kV (velocity): volts needed per unit of velocity. Because a DC motor’s back-EMF rises with speed, holding a steady velocity needs voltage proportional to that velocity. kV is usually the dominant term.
- kA (acceleration): volts needed per unit of acceleration, accounting for inertia. Often small; can be left at zero for simple mechanisms.
- kG (gravity): volts needed to counteract gravity. This term differs by mechanism type.
WPILib feedforward classes
Section titled “WPILib feedforward classes”WPILib provides three, matching common mechanisms:
-
SimpleMotorFeedforward(flywheels, drivetrains):volts = kS*sign(v) + kV*v + kA*a. No gravity term, since these mechanisms have no significant gravitational load. -
ElevatorFeedforward(elevators): adds a constantkGbecause gravity pulls the elevator down the same amount at every height:volts = kS*sign(v) + kG + kV*v + kA*a. -
ArmFeedforward(arms/pivots):kGis multiplied by cos(angle) because gravity’s torque on an arm depends on its angle — maximum when horizontal, zero when vertical:volts = kS*sign(v) + kG*cos(theta) + kV*v + kA*a(theta measured from horizontal).SimpleMotorFeedforward ff = new SimpleMotorFeedforward(kS, kV, kA); double ffVolts = ff.calculate(targetVelocity); double pidVolts = pid.calculate(encoder.getRate(), targetVelocity); motor.setVoltage(ffVolts + pidVolts);
Why feedforward beats more integral
Section titled “Why feedforward beats more integral”WPILib explicitly recommends a steady-state feedforward over relying on integral control. A good kV/kG predicts the holding voltage exactly, so PID has almost no error to integrate — giving faster, more stable, more repeatable motion, especially across the changing battery voltage of a match (which is why you command volts , not raw duty cycle).
Key takeaways
Section titled “Key takeaways”- Feedforward predicts the needed voltage from a model; PID only cleans up the small leftover error.
- kS = friction, kV = volts per velocity (usually dominant), kA = volts per acceleration, kG = gravity.
- Use ArmFeedforward (kG*cos(angle)) for arms, ElevatorFeedforward (constant kG) for elevators, SimpleMotorFeedforward (no kG) for flywheels/drives.
This lesson was adapted from learnfrc.com.
