Skip to content
Programming, Controls & Sensors·Lesson 29 of 51

The Field Coordinate System and Odometry

How WPILib defines field position, Pose2d/Rotation2d, and how wheel encoders plus the gyro track the robot.

Sign in to track progress, earn XP, and save lessons.

To navigate, a robot needs a shared definition of 'where' on the field. WPILib standardizes this.

The WPILib field coordinate system

WPILib uses the NWU (North-West-Up) convention. For the field, the origin is the bottom-right (rightmost) corner of the blue alliance wall as you stand at the blue alliance wall looking downfield. From that viewpoint:

  • The +X axis points away from you, down the field (toward the red alliance wall).
  • The +Y axis points to your left.
  • Positive rotation (theta) is counter-clockwise (CCW), following the right-hand rule. Facing straight downfield is Rotation2d.fromDegrees(0).

WPILib recommends the 'always blue origin' approach: keep the origin fixed at the blue-alliance corner for both alliances and account for your alliance in code, rather than moving the origin. This is the convention the major tools — the AprilTag field layout, PathPlanner, Choreo, and Glass/Field2d — follow, which is why it keeps everything consistent. (You may also see an alliance-relative-origin approach in older code, but the blue-origin convention is the modern standard.)

Pose2d and Rotation2d

A robot's position is a Pose2d: an (x, y) translation in meters plus a Rotation2d heading. Prefer Rotation2d.fromDegrees() / fromRadians() over juggling raw angles — Rotation2d stores sine/cosine and avoids wrap-around bugs.

Odometry

Odometry estimates the robot's Pose2d over time by combining:

  1. Wheel encoders — how far each wheel has rolled (and, for swerve, each module's angle).
  2. The gyro — the robot's heading.

WPILib provides DifferentialDriveOdometry, SwerveDriveOdometry, and MecanumDriveOdometry. Each loop you feed in the gyro angle and wheel measurements, and it integrates the motion into a new pose:

SwerveDriveOdometry odometry = new SwerveDriveOdometry(kinematics, gyro.getRotation2d(), modulePositions, startPose);
// periodic:
odometry.update(gyro.getRotation2d(), modulePositions);
Pose2d robotPose = odometry.getPoseMeters();

Why odometry alone is not enough

Odometry is smooth and updates fast, but it accumulates error: wheel slip, scrub, and gyro drift make the estimate wander from reality over a match. There is no absolute correction. The fix — covered in the vision module — is to periodically blend in absolute measurements from AprilTags using a pose estimator, which keeps the smoothness of odometry while pulling the estimate back to the truth.

Key takeaways

  • WPILib's recommended field origin is the blue-alliance bottom-left corner; +X is downfield, +Y is left, and CCW rotation is positive.
  • A Pose2d is (x, y) in meters plus a Rotation2d heading; use Rotation2d.fromDegrees to avoid wrap-around bugs.
  • Odometry fuses wheel encoders and the gyro into a pose but drifts over time, so it needs absolute correction.

Lesson quiz

Required

Answer all 3 questions correctly to complete this lesson.

1.In the WPILib field coordinate system used for 2023-2026 FRC fields, where is the origin and which way does +X point?

2.Using the WPILib field convention, what does a robot heading of 0 degrees correspond to, and which rotation direction is positive?

3.Why does encoder-and-gyro odometry drift over a match, and how does WPILib's pose estimator correct it?

Answer every question to submit.