This capstone ties vision to motion: use a Limelight 3 to aim the robot at an AprilTag and to feed field-relative pose into your estimator, then run a command that auto-aligns and scores.
Simple aim: proportional control on tx#
Limelight publishes the horizontal angle to the target as tx (degrees). A P-only controller that spins the robot until tx is ~0 is the classic first vision feature. Use the LimelightHelpers wrapper for clean reads:
public Command aimAtTag() {
final double kP = 0.035;
return run(() -> {
double tx = LimelightHelpers.getTX("");
double omega = -tx * kP; // degrees -> turn rate
m_swerve.drive(0, 0, omega);
}).until(() -> Math.abs(LimelightHelpers.getTX("")) < 1.0);
}
Add a small minimum command so the robot doesn't stall just shy of centered, and a deadband so it doesn't jitter when already aligned.
Robust localization: MegaTag2 fusion#
For scoring from a distance you want full field pose, not just an angle. MegaTag2 uses your gyro heading to disambiguate tag pose, dramatically reducing the ambiguity that hurt the original MegaTag. First send the robot's yaw to the Limelight every loop, then pull the estimate and feed it to your SwerveDrivePoseEstimator:
public void updateVision() {
LimelightHelpers.SetRobotOrientation("",
m_swerve.getHeading().getDegrees(), 0, 0, 0, 0, 0);
var mt2 = LimelightHelpers.getBotPoseEstimate_wpiBlue_MegaTag2("");
if (mt2 != null && mt2.tagCount > 0
&& Math.abs(m_gyro.getRate()) < 360) { // ignore while spinning fast (Limelight's documented MegaTag2 rejection threshold)
m_poseEstimator.setVisionMeasurementStdDevs(
VecBuilder.fill(0.7, 0.7, 9999999)); // trust x/y, not vision yaw
m_poseEstimator.addVisionMeasurement(
mt2.pose, mt2.timestampSeconds);
}
}
Call updateVision() from the drivetrain's periodic(). Setting the rotation standard deviation huge tells the estimator to ignore vision yaw and keep trusting the gyro -- the standard MegaTag2 pattern, since MegaTag2 relies on your gyro for heading.
The scoring sequence#
Now compose: aim, drive to a known scoring pose using your odometry, then trigger the mechanism only when settled:
public Command autoScore(Pose2d scorePose) {
return aimAtTag()
.andThen(m_swerve.driveToPose(scorePose))
.andThen(Commands.waitUntil(m_swerve::atPose))
.andThen(m_arm.scoreL4());
}
Configure the pipeline correctly#
In the Limelight web UI, select AprilTag (Classic 36h11) -- the family FRC has used since 2024 -- and set the tag size to 165.1 mm for current FRC field tags. Limelight pushes targeting data faster than the default NetworkTables rate so you get fresh data each loop. Validate the fused pose in AdvantageScope's Odometry/3D view: the robot's vision pose should snap onto the real field position and stay stable as you drive, with no teleporting when a tag enters or leaves view.
the part worth keeping
Key takeaways
- tx-based proportional aiming (LimelightHelpers.getTX) is the simplest reliable first vision feature; add a min command and deadband.
- MegaTag2 needs your gyro yaw via SetRobotOrientation each loop, then returns a robust field pose via getBotPoseEstimate_wpiBlue_MegaTag2.
- Feed vision into addVisionMeasurement() and set the rotation std-dev huge so the gyro owns heading.
- Configure the pipeline as AprilTag Classic 36h11 (FRC's family since 2024) with 165.1 mm tag size, and verify the fused pose in AdvantageScope.
Programming, Controls & SensorsWorked Examples and Mini-Projectslesson 5 of 5
Keep going
Take the quiz+10 XP with an accountwhere 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.limelightvision.ioLimelight: Programming with LimelightLib
- docs.limelightvision.ioLimelight: Robot Localization with MegaTag2
- docs.wpilib.orgWPILib: Pose Estimators
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.
- 8 min readFRC Vision: Limelight vs PhotonVision and AprilTag TrackingCompare Limelight and PhotonVision for FRC vision: AprilTag tracking, pose estimation with addVisionMeasurement, MegaTag2, latency, calibration, and cost./blogread it
- 15 min readFRC Odometry and Pose Estimation: Field-Centric Control with WPILibHow an FRC robot tracks its field position with WPILib: wheel odometry vs pose estimation, gyro heading, fusing AprilTag vision, and field-centric driving./blogread it
- 20 min readPhotonVision Setup for FRC: Install, Pipelines & AprilTag PosePhotonVision 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./blogread it
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
01On a Limelight, what does the 'tx' value represent when aiming the robot at an AprilTag?
02In the MegaTag2 fusion pattern, what does calling SetRobotOrientation each loop accomplish?
03Why does the fusion code set the pose estimator's rotation standard deviation to a huge value?
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