Feedback Control and Autonomous Motion

Module 8: Feedback Control and Autonomous Motion

Series: FRC Technical Foundations Unit: 4 — Software and Perception Session length: ~3 hours Prerequisites: Lessons 5 and 7

What you should be able to do after this lesson

  • Explain what an encoder measures and configure one to report real-world units.
  • Describe what each of P, I, and D contributes, and tune a loop deliberately.
  • Explain why feedforward does most of the work and feedback does the rest.
  • Set up odometry and state what it is and is not good at.
  • Follow a planned path repeatably and measure the error.

Why timed autonomous does not work

The rookie approach to autonomous is open-loop: drive forward at 50% for 1.4 seconds, turn right at 40% for 0.7 seconds, stop.

It works perfectly in the shop. At competition it works in the morning and fails in the afternoon, and the reason is instructive: on a full battery the robot goes further in 1.4 seconds than on a depleted one. Carpet friction varies between venues. A slightly tighter bearing changes the deceleration. Every one of these shifts the result, and errors accumulate through the sequence.

The fix is to close the loop — to measure what actually happened and correct.

Rule 8.1 — Never build an autonomous routine on time alone. Time is acceptable as a timeout, never as the primary control.

Encoders

An encoder measures rotation. Two kinds matter.

Relative (incremental) encoders count changes from wherever they were at power-on. They report zero at boot regardless of physical position. This is what is built into a NEO or a Kraken.

Absolute encoders report true position immediately at power-on. Through-bore encoders and CANcoders are the common examples. Any mechanism whose position you must know at boot — a swerve azimuth, an arm that could start anywhere — needs one.

Units, immediately

Configure conversion factors so your code reports metres and radians rather than motor rotations. The arithmetic is trivial and the bugs avoided are not:

wheel metres = motor rotations × (1 / gear ratio) × π × wheel diameter

If your code is full of numbers like 42.7 with no unit, someone will eventually mix a gear-ratio-corrected value with a raw one, and the bug will only appear at high speed.

Zeroing and soft limits

A relative encoder needs a homing procedure: drive slowly toward a limit switch or hard stop, detect contact, and set zero. Do this on every boot for mechanisms without absolute encoders.

Soft limits then go in software, hard stops in metal — as established in Lesson 4.

PID, explained by what each term does

A feedback controller computes error — target minus measured — and produces an output from it. Three terms.

P — Proportional

Output proportional to current error. Far from target, push hard; close to target, push gently.

P alone leaves steady-state error. As error shrinks, output shrinks, until the output is too small to overcome friction or gravity and the mechanism stops just short. On an arm fighting gravity, P alone will always settle below target.

Too much P causes oscillation: the controller overshoots, error reverses, it overshoots back.

I — Integral

Accumulates error over time. If a small error persists, the integral grows until the output is large enough to eliminate it. This is the term that kills steady-state error.

I is also the term that causes the most trouble. Integral windup happens when the mechanism cannot reach its target — something is jammed, or the motor is saturated — and the integral keeps accumulating. When the obstruction clears, the controller has a huge stored output and slams the mechanism across its range.

Use I sparingly. Most FRC mechanisms need no I term at all, because feedforward handles the job better.

D — Derivative

Responds to the rate of change of error. It acts as damping, resisting fast approach and reducing overshoot.

D amplifies noise, because differentiating a noisy signal produces a very noisy result. If your encoder signal is noisy, D will make the motor buzz.

Tuning procedure

  1. Start with P, I, D all zero.
  2. Raise P until the mechanism responds briskly and oscillates slightly.
  3. Add D to damp the oscillation out.
  4. Only if a steady-state error remains that feedforward cannot fix, add a small I with a defined integral zone or clamp.
  5. Test under real load, not on an unloaded bench. An arm with a game piece behaves differently from an empty one.

Rule 8.2 — Tune with a plot, not with your eyes. Log setpoint and measured position together and look at the graph. “It looks about right” is not tuning. Use AdvantageScope or the Driver Station plots.

Feedforward does most of the work

This is the idea that separates teams that tune for three hours from teams that tune for twenty minutes.

Feedback is reactive — it only acts once an error exists. Feedforward is predictive: you model what the mechanism needs and command it directly.

A standard model:

V = kS · sign(velocity) + kG + kV · velocity + kA · acceleration

  • kS — static friction. The voltage needed to start moving at all.
  • kG — gravity. Constant for an elevator; proportional to cos(angle) for an arm.
  • kV — velocity. Voltage needed to sustain a given speed.
  • kA — acceleration. Voltage needed to accelerate the mass.

With a good feedforward, the feedback controller only has to correct the small difference between your model and reality, so P can be gentle and the whole loop is far better behaved.

For an arm, the single highest-value line of code you will write is gravity compensation:

double ff = kG * Math.cos(armAngleRadians);

That alone converts an arm that sags at every angle into one that holds position naturally.

WPILib’s SysId tool determines kS, kV, and kA empirically by running characterisation routines. Use it — it takes twenty minutes and replaces a day of guessing.

Rule 8.3 — Feedforward first, feedback second.

Motion profiles

Commanding a mechanism to jump instantly from position A to position B asks for infinite acceleration. The controller saturates, the mechanism lurches, and the structure takes an impact it did not need.

A motion profile generates a smooth sequence of intermediate setpoints respecting maximum velocity and acceleration limits. The mechanism follows a planned ramp rather than chasing a step. WPILib provides TrapezoidProfile and ProfiledPIDController for exactly this.

The mechanical benefit is as large as the control benefit: profiled mechanisms break far less often.

Odometry

Odometry estimates the robot’s pose — x, y, and heading on the field — by integrating wheel encoders and gyro readings over time.

A few things to be clear about:

  • Coordinate frames. WPILib uses a field coordinate system with the origin at a corner, x along the long axis, y across, and counter-clockwise-positive heading. Fixing the convention early prevents a whole class of sign-error bugs.
  • Heading comes from the gyro, not the wheels. Wheel-derived heading accumulates error from every slip. A Pigeon or navX is far better.
  • Odometry drifts. It is dead reckoning. Every wheel slip, every collision, every carpet-seam bump adds unrecoverable error. Over a 15-second autonomous it is usually good to a few centimetres. Over a two-minute match it can be metres off.
  • The fix is absolute correction — which is what vision provides, and why Lesson 9 comes next. SwerveDrivePoseEstimator exists to fuse odometry with vision measurements.

Rule 8.4 — Odometry tells you where you probably are. Only an absolute reference tells you where you are.

Path following

With pose estimation working, you can follow planned trajectories.

The two tools the community uses are PathPlanner, which offers a graphical editor and an event system for triggering commands mid-path, and Choreo, which computes time-optimal trajectories subject to your drivetrain’s physical constraints. Both support swerve and differential drives, and both integrate with command-based.

What matters pedagogically is that a path is not a guarantee. A path-following controller commands velocities and corrects based on pose error, so the quality of the result depends entirely on the quality of your pose estimate and the accuracy of your drivetrain characterisation. Teams that skip the characterisation step and then blame the path library are extremely common.

Measure repeatability, not accuracy. Run the same path ten times and mark where the robot ends up each time. A robot that stops in the same wrong place every time has a calibration problem you can fix in an afternoon. A robot that stops somewhere different each time has a mechanical or estimation problem, and that is much more serious.

[ANECDOTE SLOT] — An autonomous routine that behaved differently between practice and competition. Carpet differences, battery differences, and field-setup tolerance all make good material here.

🔧 Exercise 8.1 — Tune an Arm Under Changing Load

Time: 75 minutes. Equipment: An arm or linear-slide test stand with an absolute encoder, a laptop running AdvantageScope or the Driver Station plotter, a known payload.

  1. Implement position control with P only. Plot setpoint against measured position. Record steady-state error at three different arm angles.
  2. Add gravity feedforward kG · cos(θ). Re-plot. Compare steady-state error.
  3. Add D to reduce overshoot. Re-plot.
  4. Add the payload and repeat step 2’s measurement. How much did it change?
  5. Deliberately induce integral windup: add an I term, physically block the arm for five seconds, then release. Record what happens. Stand clear when you release it.

Evidence of learning: Four labelled plots, a table of steady-state error against configuration, final constants, and a written description of the windup event.

🔧 Exercise 8.2 — Square Path Accuracy

Time: 60 minutes. Equipment: A drivable chassis with encoders and a gyro, tape, a tape measure.

Program a 2 m square path returning to the start. Run it ten times in each of three configurations:

  • A: open-loop, timed.
  • B: encoder-based distance and turns.
  • C: encoder distance with gyro-corrected heading.

Mark the final position and heading each run.

Evidence of learning: A scatter plot of end positions for all three configurations, mean and standard deviation of position error, and a written explanation of why C beats B and B beats A.

🔧 Exercise 8.3 — Repeatability Under Adverse Conditions

Time: 45 minutes. Equipment: A path-following setup, a fresh battery and a depleted one.

Run the same planned path ten times on a fresh battery, then ten on a depleted one. Then run five more where a team member gently nudges the robot mid-path to simulate a collision.

Evidence of learning: A pose-error map showing all three conditions, and a recommendation for how much positional tolerance your mechanisms need to absorb.

Further reading

Next Lesson

Odometry drifts, and something has to correct it. Lesson 9 — Vision and AprilTags covers how the robot finds out where it actually is, and what it does when the camera lets it down.