Skip to content

Feedforward: kS, kV, kA, and kG

learnfrc.com
learnfrc.comAuthor
Veer Bajaj
Veer BajajMaintainer

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.

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 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 constant kG because gravity pulls the elevator down the same amount at every height: volts = kS*sign(v) + kG + kV*v + kA*a.

  • ArmFeedforward (arms/pivots): kG is 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);

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).

  • 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.