Skip to content

The Field Coordinate System and Odometry

learnfrc.com
learnfrc.comAuthor
Veer Bajaj
Veer BajajMaintainer

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

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

  • The +X axis points away from you, down the field.
  • 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.)

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 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();

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.

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

This lesson was adapted from learnfrc.com.