Skip to content
All articles

FRC Autonomous with PathPlanner: A Beginner's Guide to Auto Routines

8 min read·

The first 15 seconds of an FRC match happen with no driver at the controls. Your robot has to drive, aim, and score entirely on its own. For years, writing that autonomous code meant hand-tuning trajectories and hoping the math worked out. Today, most competitive teams reach for one tool first: PathPlanner. It lets you draw a path on a picture of the field, attach actions to it, and hand the whole thing to your robot as a single command. This guide walks you through how it works, from the GUI to the code, in plain terms.

What PathPlanner actually is

PathPlanner is a motion profile generator for FRC robots, originally created by team 3015. It comes in two pieces that work together:

  • The PathPlanner GUI — a desktop app (available on the Microsoft Store and as a GitHub release) where you visually design paths on top of a field image.
  • PathPlannerLib (PPLib) — a vendor library you add to your robot project that reads those path files and turns them into commands your robot runs.

The split matters. The GUI is where a student with no coding experience can lay out a route. PPLib is the code side that executes it. You design in one, you run in the other, and a feature called hot reload even lets you tweak a path in the GUI and push it to a running robot without redeploying code.

Paths vs. autos: the core distinction

The single most important concept in PathPlanner is the difference between a path and an auto.

A path is one segment of motion — for example, "drive from the starting line to the first game piece." Paths are built from waypoints, which use Bézier-style anchor points (the exact spots the robot drives through) and control points (handles that shape the curve's heading and tightness). Each path carries constraints: max velocity, max acceleration, max angular velocity, and max angular acceleration, applied either globally or in constraint zones along the path.

An auto is a full routine that chains multiple paths together in sequence — "go to the piece, then go to the goal, then go back." Under the hood, an auto is essentially a sequential command group made of path-following commands. Because paths are separate files, you can reuse one path across several autos. That modularity is the whole point: build a library of clean segments, then assemble different routines from them.

ConceptWhat it isLives where
PathOne motion segment with waypoints + constraintsA .path file
AutoA sequence of paths plus commandsA .auto file
WaypointAnchor + control points shaping the curveInside a path
Event markerA trigger that fires a command mid-pathInside a path/auto

Holonomic vs. differential

PathPlanner supports both major drivetrain types, and it treats them differently. Holonomic drivetrains (swerve) can translate and rotate independently, so paths let you set rotation targets — the robot can be spinning to face a target while it drives a curve. PPLib follows these with the PPHolonomicDriveController.

Differential (tank) drivetrains can only point where they're driving, so rotation targets don't apply — heading is locked to the direction of travel. These use the PPLTVController instead. If your team runs swerve, you'll live in holonomic mode; if you run a tank or "west coast" drive, you're on the differential side.

AutoBuilder: wiring PPLib to your robot

Before PPLib can drive anything, you have to tell it how your robot moves. That's the job of AutoBuilder, configured once (ideally in your drive subsystem's constructor). AutoBuilder.configure() takes, in order:

  1. A pose supplier (this::getPose) that returns the robot's current Pose2d.
  2. A reset-pose consumer (this::resetPose) that snaps odometry to a given pose at auto start.
  3. A robot-relative speeds supplier (this::getRobotRelativeSpeeds) returning current ChassisSpeeds.
  4. A drive consumer that takes ChassisSpeeds (and feedforwards) and commands the wheels.
  5. A path-following controllerPPHolonomicDriveController for swerve.
  6. A RobotConfig describing your robot's physical properties.
  7. An alliance-flip supplier (more on that below).
  8. The drive subsystem itself (this), so commands require it.

The controller uses PIDConstants to correct error while following. The docs' starting example uses new PIDConstants(5.0, 0.0, 0.0) for both translation and rotation — proportional gain of 5.0, no integral or derivative. You'll tune those later.

RobotConfig: telling the math about your robot

RobotConfig (loaded with RobotConfig.fromGUISettings()) pulls the physical numbers you entered in the GUI: robot mass in kg, moment of inertia (MOI), trackwidth, wheel radius, drive gearing, wheel coefficient of friction, drive motor type, and drive current limit. PathPlanner uses these to generate trajectories that are actually achievable. The docs stress measuring your true max drive speed on the real robot — driving it in a straight line as fast as possible on a charged battery — rather than copying a theoretical spec (they suggest about 85% of the module's free speed only as a fallback when you can't measure). It encodes how much motor torque you can really use to accelerate.

Named commands and event markers

Driving is only half of auto. You also need to intake, shoot, or score while moving. That's where named commands come in. In your code you register a command under a string name:

NamedCommands.registerCommand("intakeNote", intake.runIntakeCommand());

Then in the GUI you drop an event marker on a path and type intakeNote. When the auto reaches that marker, PPLib looks up the registered command and runs it. One critical rule from the docs: named commands must be registered before you create any PathPlannerAuto or path, so do your registration in RobotContainer right after subsystems are built. This is the seam where PathPlanner plugs straight into command-based programming — your navigation stays in the path files, your behaviors stay as reusable commands.

How it ties into odometry and pose estimation

PathPlanner can only follow a path if the robot knows where it is. That knowledge comes from odometry — WPILib tracks position from wheel encoders and a gyro using classes like SwerveDriveOdometry and SwerveDriveKinematics, updated every loop in your subsystem's periodic(). The getPose and resetPose methods you handed AutoBuilder are exactly the bridge to this system.

Odometry drifts over time, especially after contact. Many teams upgrade to a pose estimator (e.g. SwerveDrivePoseEstimator), which fuses encoder/gyro odometry with vision measurements from AprilTag cameras to stay accurate. If you want to go deeper on vision, our programming track covers it.

Alliance flipping and the field origin

FRC fields are mirrored between red and blue. PathPlanner keeps the field coordinate origin on the blue side and mirrors your paths for red. You design once, and the alliance-flip supplier — which returns true when DriverStation.getAlliance() reports Red — handles the rest. A common beginner bug is testing on blue, then watching the robot drive into a wall on red because flipping wasn't wired up.

Selecting and running an auto

To let drivers pick a routine, AutoBuilder can build a dashboard chooser for you:

autoChooser = AutoBuilder.buildAutoChooser();
SmartDashboard.putData("Auto Chooser", autoChooser);

buildAutoChooser() returns a SendableChooser pre-populated with every auto in your project (defaulting to Commands.none()). In autonomousInit(), you grab the selected command and schedule it.

Pathfinding: paths you didn't draw

PPLib also generates paths on the fly using the AD* algorithm. pathfindToPose and pathfindThenFollowPath let the robot navigate around obstacles to a target at runtime — useful for auto-aligning to a scoring location during teleop. The tradeoff: you give up control of heading at the start and end of an on-the-fly path, so it's less ideal for tank drives or precision approaches unless you chain it into a pre-planned path.

Common pitfalls

  • Asking for the impossible. PathPlanner will happily generate a path your robot physically can't follow. If the robot overshoots or cuts corners, lower your constraints or fix your RobotConfig.
  • Forgetting registration order. Register named commands before creating autos, or the markers silently do nothing.
  • Skipping odometry verification. If getPose is wrong, every path is wrong. Confirm your odometry tracks reality before blaming the path.
  • Untuned PID. The default 5.0 P gain is a starting point, not a finish line.

Choreo: the alternative

The main alternative is Choreo, a time-optimal trajectory planner. The philosophy differs: Choreo solves for the fastest trajectory your robot can actually follow, cutting down on tweaking, while PathPlanner gives you more manual control at the cost of more tuning. Choreo trajectories are pre-generated and don't regenerate to match the robot's real starting state, and it can't do on-the-fly pathfinding. Helpfully, PathPlanner offers Choreo interop, so you can use Choreo trajectories inside a PPLib workflow. Many teams use both.

Autonomous is where good programming wins matches. Start simple — one path, one named command — get it reliable, then build up. Ready to write the code? Dive into our Programming track.

Keep reading

Learn every department of FRC — free

393+ structured lessons, quizzes, and team tools. Built by an FRC student, for the community.

Browse the guides