Skip to main content
This is the simplest example of a working robot program. It demonstrates:
  • Basic robot structure using TimedRobot
  • Setting up a differential drive with two motors
  • Autonomous mode with timed driving
  • Teleoperated mode with joystick control
  • Proper motor inversion for drivetrain

Complete Example

package edu.wpi.first.wpilibj.examples.gettingstarted;

import edu.wpi.first.util.sendable.SendableRegistry;
import edu.wpi.first.wpilibj.TimedRobot;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.XboxController;
import edu.wpi.first.wpilibj.drive.DifferentialDrive;
import edu.wpi.first.wpilibj.motorcontrol.PWMSparkMax;

public class Robot extends TimedRobot {
  private final PWMSparkMax m_leftDrive = new PWMSparkMax(0);
  private final PWMSparkMax m_rightDrive = new PWMSparkMax(1);
  private final DifferentialDrive m_robotDrive =
      new DifferentialDrive(m_leftDrive::set, m_rightDrive::set);
  private final XboxController m_controller = new XboxController(0);
  private final Timer m_timer = new Timer();

  public Robot() {
    SendableRegistry.addChild(m_robotDrive, m_leftDrive);
    SendableRegistry.addChild(m_robotDrive, m_rightDrive);

    // We need to invert one side of the drivetrain so that positive voltages
    // result in both sides moving forward. Depending on how your robot's
    // gearbox is constructed, you might have to invert the left side instead.
    m_rightDrive.setInverted(true);
  }

  @Override
  public void autonomousInit() {
    m_timer.restart();
  }

  @Override
  public void autonomousPeriodic() {
    // Drive for 2 seconds
    if (m_timer.get() < 2.0) {
      // Drive forwards half speed, make sure to turn input squaring off
      m_robotDrive.arcadeDrive(0.5, 0.0, false);
    } else {
      m_robotDrive.stopMotor(); // stop robot
    }
  }

  @Override
  public void teleopPeriodic() {
    m_robotDrive.arcadeDrive(-m_controller.getLeftY(), -m_controller.getRightX());
  }
}

What This Example Demonstrates

Robot Structure

The robot extends TimedRobot, which automatically calls methods at 20ms intervals:
  • autonomousInit() - Called once when autonomous starts
  • autonomousPeriodic() - Called every 20ms during autonomous
  • teleopPeriodic() - Called every 20ms during teleoperated mode

Differential Drive

The DifferentialDrive class simplifies controlling a tank-style drivetrain:
  • Takes two motor controllers (left and right)
  • Provides arcadeDrive() method for single-stick driving
  • Forward/backward on one axis, turning on another

Motor Inversion

One side of the drivetrain must be inverted so both sides drive forward with positive values. This is done with setInverted(true) on the right motor.

Running in Simulation

  1. Deploy the code to your robot or simulator
  2. Enable autonomous mode to see the 2-second forward drive
  3. Switch to teleoperated mode and use an Xbox controller:
    • Left stick Y-axis: forward/backward
    • Right stick X-axis: turning

Source Location

  • Java: wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/gettingstarted/Robot.java
  • C++: wpilibcExamples/src/main/cpp/examples/GettingStarted/cpp/Robot.cpp

Build docs developers (and LLMs) love