Choosing an Autonomous Program¶
Often teams have more than one autonomous program, either for competitive reasons or for testing new software. Programs often vary by adding things like time delays, different strategies, etc. The methods to choose the strategy to run usually involves switches, joystick buttons, knobs or other hardware based inputs.
With the SmartDashboard you can simply display a widget on the screen to choose the autonomous program that you would like to run. And with command based programs, that program is encapsulated in one of several commands. This article shows how to select an autonomous program with only a few lines of code and a nice looking user interface.
Creating the SendableChooser Object¶
In RobotContainer
, create a variable to hold a reference to a SendableChooser
object. Two or more commands can be created and stored in new variables. Using the SendableChooser
, one can choose between them. In this example, SimpleAuto
and ComplexAuto
are shown as options.
// A simple auto routine that drives forward a specified distance, and then stops.
private final Command m_simpleAuto =
new DriveDistance(AutoConstants.kAutoDriveDistanceInches, AutoConstants.kAutoDriveSpeed,
m_robotDrive);
// A complex auto routine that drives forward, drops a hatch, and then drives backward.
private final Command m_complexAuto = new ComplexAuto(m_robotDrive, m_hatchSubsystem);
// A chooser for autonomous commands
SendableChooser<Command> m_chooser = new SendableChooser<>();
// The autonomous routines
DriveDistance m_simpleAuto{AutoConstants::kAutoDriveDistanceInches,
AutoConstants::kAutoDriveSpeed, &m_drive};
ComplexAuto m_complexAuto{&m_drive, &m_hatch};
// The chooser for the autonomous routines
frc::SendableChooser<frc2::Command*> m_chooser;
Setting up SendableChooser¶
Imagine that you have two autonomous programs to choose between and they are encapsulated in commands SimpleAuto
and ComplexAuto
. To choose between them:
In RobotContainer
, create a SendableChooser
object and add instances of the two commands to it. There can be any number of commands, and the one added as a default (setDefaultOption
), becomes the one that is initially selected. Notice that each command is included in an setDefaultOption()
or addOption()
method call on the SendableChooser
instance.
// Add commands to the autonomous command chooser
m_chooser.setDefaultOption("Simple Auto", m_simpleAuto);
m_chooser.addOption("Complex Auto", m_complexAuto);
// Put the chooser on the dashboard
SmartDashboard.putData(m_chooser);
// Add commands to the autonomous command chooser
m_chooser.SetDefaultOption("Simple Auto", &m_simpleAuto);
m_chooser.AddOption("Complex Auto", &m_complexAuto);
// Put the chooser on the dashboard
frc::SmartDashboard::PutData(&m_chooser);
Starting an Autonomous Command¶
In Robot.java
, when the autonomous period starts, the SendableChooser
object is polled to get the selected command and that command must be scheduled.
public Command getAutonomousCommand() {
return m_chooser.getSelected();
}
public void autonomousInit() {
m_autonomousCommand = m_robotContainer.getAutonomousCommand();
// schedule the autonomous command (example)
if (m_autonomousCommand != null) {
m_autonomousCommand.schedule();
}
}
frc2::Command* RobotContainer::GetAutonomousCommand() {
// Runs the chosen command in autonomous
return m_chooser.GetSelected();
}
void Robot::AutonomousInit() {
m_autonomousCommand = m_container.GetAutonomousCommand();
if (m_autonomousCommand != nullptr) {
m_autonomousCommand->Schedule();
}
}
Running the Scheduler during Autonomous¶
In Robot.java
, this will run the scheduler every driver station update period (about every 20ms) and cause the selected autonomous command to run.
Note
Running the scheduler can occur in the autonomousPeriodic()
function or robotPeriodic()
, both will function similarly in autonomous mode.
public void robotPeriodic() {
CommandScheduler.getInstance().run();
}
void Robot::RobotPeriodic() { frc2::CommandScheduler::GetInstance().Run(); }
Canceling the Autonomous Command¶
In Robot.java
, when the teleop period begins, the autonomous command will be canceled.
public void teleopInit() {
// This makes sure that the autonomous stops running when
// teleop starts running. If you want the autonomous to
// continue until interrupted by another command, remove
// this line or comment it out.
if (m_autonomousCommand != null) {
m_autonomousCommand.cancel();
}
}
void Robot::TeleopInit() {
// This makes sure that the autonomous stops running when
// teleop starts running. If you want the autonomous to
// continue until interrupted by another command, remove
// this line or comment it out.
if (m_autonomousCommand != nullptr) {
m_autonomousCommand->Cancel();
m_autonomousCommand = nullptr;
}
}
SmartDashboard Display¶
When the SmartDashboard is run, the choices from the SendableChooser
are automatically displayed. You can simply pick an option before the autonomous period begins and the corresponding command will run.