Skip to content

Autonomous

James Hagborg edited this page Dec 17, 2018 · 1 revision

HYPERLib provides two abstractions for managing autonomous mode: routines and strategies. The distinction exists because in some years, such as 2018 POWER UP, game-specific data is provided at the start of the match. A routine defines a command or sequence of commands to run, together with extra data for managing preferences. A strategy associates possible values of the game-specific data with routines. In the most common use-case, the driver selects a strategy from a list on the dashboard before the match starts.

Defining a routine

To define an autonomous routine, subclass AutonomousRoutine, and override the build method. This method accepts a CommandBuilder, which you can use to build the routine. This method will be run at the start of autonomous. After it finishes, the command it generated will be run. For example, a command that drives straight at a specified speed and time:

publicclassOffWallNudgeextendsAutonomousRoutine {
@AutoPrefpublicDoublePreferencespeed, time;
@Overridepublicvoidbuild(CommandBuilderbuilder) {
builder.sequential(AutoDrive.forwardCmd(speed), time.get());
builder.sequential(Robot.driveTrain.stopDriveCmd());
}
}

The @AutoPref annotation here automatically creates preferences with the names speed and time. These are namespaced in such a way that defining preferences called speed and time in a different routine won't cause any conflicts. These preferences become accessible through the AutoViewer plugin on the dashboard.

Composing routines

It's possible to compose routines, i.e. call one routine from another. To ensure that all the relevant preferences get displayed, it's necessary to call addSubroutine. For example:

publicclassCenterToLeftSwitchNoVisionextendsAutonomousRoutine {
@AutoPrefpublicDoublePreferencefwdSpeed, fwdTime, rotateAngle, driveDist;
AutonomousRoutineoffWallNudge = addSubroutine(newOffWallNudge());
AutonomousRoutineraiseCube = addSubroutine(newRaiseCubeToSwitch());
AutonomousRoutineunGrip = addSubroutine(newUnGrip());
@Overridepublicvoidbuild(CommandBuilderbuilder) {
offWallNudge.build(builder); // Add all steps of offWallNudge in sequencebuilder.parallel(raiseCube::build); // Add all steps of raiseCube in parallelbuilder.sequential(newGyroRotateCommand(-rotateAngle.get(), true, true));
builder.sequential(newDriveToDistance(driveDist.get(), true, true));
builder.sequential(newGyroRotateCommand(rotateAngle.get(), true, true));
builder.sequential(AutoDrive.forwardCmd(fwdSpeed), fwdTime.get());
builder.sequential(Robot.driveTrain.stopDriveCmd());
unGrip.build(builder); // Add all steps of unGrip in sequence
}
}

Defining strategies

At the end of the day, the driver sees something like this:

Selecting a strategy from the autonomous chooser

This is the (abridged) code which defines this selection of strategies:

AutonomousStrategyleftSwitch = newAutonomousStrategy.Builder("Left: Priority SWITCH")
.addScenario("LLL", newLeftToSwitchVision())
.addScenario("LRL", newLeftToSwitchVision())
.addScenario("RLR", newSideCrossBaseline())
.addScenario("RRR", newSideCrossBaseline())
.addDefault(newSideCrossBaseline())
.build();
AutonomousStrategyrightSwitch = newAutonomousStrategy.Builder("Right: Priority SWITCH")
.addScenario("RRR", newRightToSwitchVision())
.addScenario("RLR", newRightToSwitchVision())
.addScenario("LRL", newSideCrossBaseline())
.addScenario("LLL", newSideCrossBaseline())
.addDefault(newSideCrossBaseline())
.build();
AutonomousStrategycenter = newAutonomousStrategy.Builder("Center: Priority SWITCH")
.addScenario("RRR", newCenterToRightSwitchVision())
.addScenario("RLR", newCenterToRightSwitchVision())
.addScenario("LRL", newCenterToLeftSwitchVision())
.addScenario("LLL", newCenterToLeftSwitchVision())
.addDefault(newDoNothing())
.build();
// This should be stored as an instance variable somewhereautoInfo = newAutonomousInfo.Builder()
.addStrategy(leftSwitch)
.addStrategy(rightSwitch)
.addDefault(center)
.build();

This should run once in robotInit, to put the chooser on the dashboard. Then in autonomousInit, we need to read the chosen value and run it:

AutonomousStrategystrat = autoInfo.getSelection();
StringfmsData = DriverStation.getInstance().getGameSpecificMessage();
AutonomousRoutinertn = strat.getRoutineForScenario(fmsData);
CommandBuilderbuilder = newCommandBuilder();
rtn.build(builder);
// autoCmd should be an instance variable, so you can cancel it when auto is doneautoCmd = builder.build()
autoCmd.start();

Clone this wiki locally