-
Notifications
You must be signed in to change notification settings - Fork 3
Autonomous
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.
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:
public class OffWallNudge extends AutonomousRoutine {
@AutoPref public DoublePreference speed, time;
@Override
public void build(CommandBuilder builder) {
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.
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:
public class CenterToLeftSwitchNoVision extends AutonomousRoutine {
@AutoPref public DoublePreference fwdSpeed, fwdTime, rotateAngle, driveDist;
AutonomousRoutine offWallNudge = addSubroutine(new OffWallNudge());
AutonomousRoutine raiseCube = addSubroutine(new RaiseCubeToSwitch());
AutonomousRoutine unGrip = addSubroutine(new UnGrip());
@Override
public void build(CommandBuilder builder) {
offWallNudge.build(builder); // Add all steps of offWallNudge in sequence
builder.parallel(raiseCube::build); // Add all steps of raiseCube in parallel
builder.sequential(new GyroRotateCommand(-rotateAngle.get(), true, true));
builder.sequential(new DriveToDistance(driveDist.get(), true, true));
builder.sequential(new GyroRotateCommand(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
}
}
At the end of the day, the driver sees something like this:
This is the (abridged) code which defines this selection of strategies:
AutonomousStrategy leftSwitch = new AutonomousStrategy.Builder("Left: Priority SWITCH")
.addScenario("LLL", new LeftToSwitchVision())
.addScenario("LRL", new LeftToSwitchVision())
.addScenario("RLR", new SideCrossBaseline())
.addScenario("RRR", new SideCrossBaseline())
.addDefault(new SideCrossBaseline())
.build();
AutonomousStrategy rightSwitch = new AutonomousStrategy.Builder("Right: Priority SWITCH")
.addScenario("RRR", new RightToSwitchVision())
.addScenario("RLR", new RightToSwitchVision())
.addScenario("LRL", new SideCrossBaseline())
.addScenario("LLL", new SideCrossBaseline())
.addDefault(new SideCrossBaseline())
.build();
AutonomousStrategy center = new AutonomousStrategy.Builder("Center: Priority SWITCH")
.addScenario("RRR", new CenterToRightSwitchVision())
.addScenario("RLR", new CenterToRightSwitchVision())
.addScenario("LRL", new CenterToLeftSwitchVision())
.addScenario("LLL", new CenterToLeftSwitchVision())
.addDefault(new DoNothing())
.build();
// This should be stored as an instance variable somewhere
autoInfo = new AutonomousInfo.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:
AutonomousStrategy strat = autoInfo.getSelection();
String fmsData = DriverStation.getInstance().getGameSpecificMessage();
AutonomousRoutine rtn = strat.getRoutineForScenario(fmsData);
CommandBuilder builder = new CommandBuilder();
rtn.build(builder);
// autoCmd should be an instance variable, so you can cancel it when auto is done
autoCmd = builder.build()
autoCmd.start();