Basic odometry drifts; basic vision is jumpy. The art of competitive localization is fusing them with the right trust levels so the robot knows where it is to a few centimeters across a whole match. WPILib's SwerveDrivePoseEstimator does this via Kalman-style standard deviations.
Standard deviations are the trust knobs
The estimator weighs each source by its declared uncertainty. Smaller std-dev = more trust. You set odometry trust at construction and vision trust per measurement (or globally):
m_poseEstimator = new SwerveDrivePoseEstimator(
m_kinematics, gyroAngle, modulePositions, initialPose,
VecBuilder.fill(0.05, 0.05, 0.01), // state (odometry) std devs: x,y,theta
VecBuilder.fill(0.5, 0.5, 9999999)); // default vision std devs
A huge theta std-dev for vision tells the estimator to ignore vision heading and trust the gyro -- the standard MegaTag2 pattern, since the IMU is more reliable for yaw than a single tag.
Scale trust with distance and tag count
The smart move is dynamic std-devs: trust vision more when you see multiple tags up close, less when one tag is far away (where small angle errors mean large position errors).
var est = LimelightHelpers.getBotPoseEstimate_wpiBlue_MegaTag2("");
if (est != null && est.tagCount > 0) {
double xyStd = (est.tagCount >= 2) ? 0.5 : 1.2; // tighter with 2+ tags
xyStd *= (1 + est.avgTagDist * est.avgTagDist * 0.1); // looser when far
m_poseEstimator.setVisionMeasurementStdDevs(
VecBuilder.fill(xyStd, xyStd, 9999999));
m_poseEstimator.addVisionMeasurement(est.pose, est.timestampSeconds);
}
tagCount, avgTagDist, pose, and timestampSeconds are all fields on the LimelightHelpers PoseEstimate struct.
Reject obviously bad data
Guard the update: skip measurements while spinning fast (gyroRate > 720 deg/s), skip poses that land off the field or absurdly far from the current estimate, and skip when tagCount == 0. One bad teleport into the estimator can ruin an auto-align.
Latency compensation
Vision data is always a little old. The estimator latency-compensates if you pass the measurement timestamp (which MegaTag2's timestampSeconds provides) -- it rewinds, inserts the vision sample, and replays odometry forward. Never pass Timer.getFPGATimestamp() as the vision time; pass the camera's capture timestamp.
The payoff
With tuned fusion you can run closed-loop drive-to-pose for auto-scoring and trust odometry through brief vision dropouts. Validate in AdvantageScope's field view: the fused pose should track smoothly and snap gently toward tags, never teleport. This is the difference between vision that helps and vision that fights you.
Key takeaways
- Pose estimator trust is set by standard deviations: smaller = more trusted; set a huge vision theta std-dev to let the gyro own heading.
- Scale vision std-devs dynamically -- tighter with multiple/close tags, looser with one distant tag.
- Reject bad measurements: skip while spinning fast, off-field, or with zero tags before calling addVisionMeasurement().
- Pass the camera capture timestamp (MegaTag2 timestampSeconds) so the estimator latency-compensates correctly.
Keep going
Take the quiz · +10 XP with an accountMore in Advanced Techniques and Case Studies
Sources & 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 — publicly, in the corrections log.
Sources and further reading
- WPILib: Pose Estimatorsdocs.wpilib.org
- Limelight: Programming with LimelightLibdocs.limelightvision.io
- WPILib: Swerve Drive Odometrydocs.wpilib.org
Read next
Articles on this, for competition day
The lesson covers how it works. These cover what to do when it breaks.
- 15 min read
FRC Odometry and Pose Estimation: Field-Centric Control with WPILib
How an FRC robot tracks its field position with WPILib: wheel odometry vs pose estimation, gyro heading, fusing AprilTag vision, and field-centric driving.
Read - 20 min read
PhotonVision Setup for FRC: Install, Pipelines & AprilTag Pose
PhotonVision setup for FRC: install it on a Raspberry Pi or Orange Pi coprocessor, build an AprilTag pipeline, run multi-tag pose, and feed swerve odometry.
Read - 8 min read
FRC Vision: Limelight vs PhotonVision and AprilTag Tracking
Compare Limelight and PhotonVision for FRC vision: AprilTag tracking, pose estimation with addVisionMeasurement, MegaTag2, latency, calibration, and cost.
Read
Lesson quiz
RequiredAll 3 right completes the lesson. Miss one and only that question comes back — anything you already answered correctly stays banked.
0 of 3 answered
01.Why do you set a huge theta standard deviation on vision measurements in the MegaTag2 pattern?
02.In WPILib's SwerveDrivePoseEstimator, what does the vision measurement std-dev matrix represent and in what order?
03.How do larger values in the vision standard-deviation matrix affect the pose estimator?
Answer every question to submit.
All 51 lessons in Programming, Controls & Sensors
- Not started:Mini-Project: A Closed-Loop Elevator with Motion Magic
- Not started:Mini-Project: A Velocity-Controlled Shooter on REVLib
- Not started:Mini-Project: A Teleop Swerve Drive Subsystem
- Not started:Mini-Project: An Autonomous Routine with PathPlanner
- Not started:Mini-Project: Vision-Aligned Scoring with Limelight
- Not started:State-Space Control and Kalman Filtering
- Not started:Log Replay Architecture with AdvantageKit
- Not started:Advanced Pose Estimation: Multi-Tag Fusion and Standard Deviations
- Not started:Robot Coordination, Alerts, and Operator Feedback
- Not started:Case Study: Hardening Software Before an Event