Basic Autonomous
Autonomous is where everything in Unit 5 converges: lifecycle methods set the stage, sensors provide position feedback, motor controllers execute movement, state machines sequence the steps, and SmartDashboard lets the drive team select the strategy. This lesson builds a complete, sensor-verified autonomous routine from scratch.
By the end of this lesson, you will:
- Implement a time-based autonomous that sequences multiple actions using a
Timer - Upgrade to encoder-based autonomous that uses measured distance rather than elapsed time
- Add gyroscope heading correction to keep a straight-line drive from drifting
- Chain autonomous states into a multi-step routine with drive, turn, and score actions
- Integrate
SendableChooserfrom Lesson 6 to let the drive team select the auto from the dashboard
Autonomous Is Just a State Machine With a Timer
Teleop reacts to live input — the drive team tells the robot what to do every 20ms. Autonomous has no driver; it must sequence its own behavior. The state machine pattern from Lesson 7 applies directly: each state represents one phase of the autonomous routine, and transitions fire when the phase is complete (timer expired, distance reached, sensor triggered).
The key difference from teleop state machines: autonomous transitions are driven by time and sensors, not by button presses.
Autonomous Sequence Tracer
Step through a five-state autonomous routine below. Each step shows the active state, the code that runs this cycle, and the condition that will advance to the next state. Notice how autonomousInit() primes the state and resets the hardware; autonomousPeriodic() advances it each cycle.
The Three Autonomous Approaches
The simplest approach: use Timer.getMatchTime() or a Timer object. Drive for N seconds, then stop. Fast to implement, but inaccurate — battery voltage, friction, and floor surface all affect how far the robot travels in a given time.
Encoder-based autonomous uses the distance the wheel has actually traveled to determine when to transition — much more reliable than time. Reset encoder positions in autonomousInit() and read them each cycle.
Even encoder-based autonomous drifts sideways if the left and right wheels have different friction. A gyroscope heading correction applies a small rotational correction proportional to the heading error, keeping the robot on a straight bearing while still using encoder distance for state transitions.
Auto Strategy Selector
Competition robots need multiple autonomous options for different starting positions, game piece availability, and alliance strategy. The SendableChooser from Lesson 6 feeds autonomousInit(). Select a strategy below to see the state sequence and required sensors.
The Complete Auto + Chooser Integration
The autonomous routine that works every single time at competition is the one your team ran twenty times at home before the event. Not ten times, not five. Twenty. I watch teams arrive at their first event with an autonomous they "tested once and it worked." It doesn't work at the event — different floor material, different battery state, slightly different starting position. The teams that score in auto consistently are the teams that iterated. They have a drive distance constant in Constants.java that's been adjusted to four decimal places because they tuned it on a tape measure. They don't wonder if auto will work. They know.
- Reset encoders and gyro in
autonomousInit(), notrobotInit(). You want distance measured from the start of autonomous, not from power-on. The gyro heading should be 0° at the moment auto enables, not at boot time. - Use encoder distance, not time, as your primary transition condition. Time is unreliable — battery state, floor friction, and motor configuration all affect it. The encoder measures what actually happened.
- Add a safety timeout to every auto state. If an encoder fails, the robot will never reach the target distance and will be stuck in that state for the whole auto. A secondary time-based fallback catches this:
if (autoTimer.hasElapsed(5.0)) autoState = AutoState.DONE; - Always call
drive.arcadeDrive(0, 0)in the DONE/IDLE state. Without an explicit stop command,DifferentialDrive's motor safety timer will stop motors after 100ms — but the robot will coast during that window. Explicit zero is better. - Publish distance, heading error, and state to SmartDashboard. During auto testing, watch these values update in real time. If the heading error is growing, your correction gain is too low. If the robot overshoots, the gain or speed is too high.
- Test every strategy in the chooser before competition. All three options (Do Nothing, Drive, Drive+Score) should be validated. The "Do Nothing" strategy should literally do nothing — if it accidentally drives the robot, something is wrong with your
autoInit()logic.
Knowledge Check
DRIVE_FORWARD state. The robot is stationary. The encoder distance never reaches the target. The routine never advances. What is the most likely cause and correct fix?Build a Complete, Competition-Ready Robot Program
This prompt integrates everything from Unit 5. By the end, you will have a TimedRobot program that can drive, respond to driver input, read sensors, publish diagnostics, select an autonomous strategy, and execute a multi-step autonomous routine.
- Lifecycle (L1): Structure
Robot.javacorrectly. All hardware inrobotInit(). Dashboard inrobotPeriodic(). Mode-specific logic in the appropriateinit()andperiodic()methods. No blocking calls anywhere. - Drive (L2 + L5): Implement arcade drive with deadband, negated Y-axis, and a 0.6 default speed scale (right bumper for full speed). Verify direction before proceeding.
- Sensors (L3 + L4): Add a beam break sensor. Display its raw and debounced values on SmartDashboard. Implement a basic intake state machine (L7): IDLE → INTAKING → HOLDING → EJECTING with correct transitions.
- Dashboard (L6): Add a
SendableChooserwith three autonomous options. Organize Shuffleboard into Drive and Diagnostics tabs. Confirm all values update while disabled. - Autonomous (L8): Implement at minimum two of your three auto options: "Do Nothing" (literally nothing) and "Drive Forward 1.5m" using encoder distance with gyro heading correction. Add a 4-second safety timeout to every state. Test both options by selecting from the dashboard and confirming correct behavior.
- Full Integration: Run a simulated match cycle: DS disabled → auto enabled (2 minutes) → DS disables → teleop enabled → DS disables. Confirm every transition is clean, motors stop in
disabledInit(), and the dashboard shows correct state throughout. - Capstone Reflection: Write a paragraph for each Unit 5 lesson (1–8) identifying a specific line or pattern in your final code that demonstrates that concept. This is your roadmap to Unit 6, where every one of these patterns gets promoted into the Command-Based architecture.