-
Notifications
You must be signed in to change notification settings - Fork 3
Operator Interface
HYPERLib provides annotations that allow you to define the operator
interface decalaritively. This means that the code looks like a
configuration file that specifies how the OI is layed out, rather than
a sequence of instructions to run. The OI is handled by the OI
class provided by HYPERLib. The constructor to this class takes as
input a class, called the OI map, whose contents define the layout
of the OI.
The OI map contains an inner class for each joystick,
annotated with a @MapJoystick
annotation. Each of these contains
several commands as instance variables, which are annotated either by
@WhenPressed
, @WhenReleased
, or @WhileHeld
. For example:
public class OIMap {
@MapJoystick(port = 0,
role = Role.LEFT_OPERATOR_JOYSTICK,
type = Type.LOGITECH_2_AXIS)
public static class LeftOperator {
// This should be your default template for "typical" buttons.
// Everything MUST be public and SHOULD be final.
// You probably won't refer back to these fields in other parts of the
// code. The name of the field will show up in joystick diagrams.
@WhileHeld(1) public final Command liftUp = Robot.lifter.liftUpCmd();
@WhileHeld(2) public final Command liftDown = Robot.lifter.liftDownCmd();
@WhenPressed(3) public final Command shoot = Robot.shooter.shootCmd();
}
@MapJoystick(port = 2,
role = Role.LEFT_DRIVER_JOYSTICK,
type = Type.LOGITECH_2_AXIS)
public static class LeftDriver {
// In this example, these functions return oneShot's which
// change the value of some boolean, and do NOT require any
// subsystem (so they don't interrupt driving).
// This has the effect of driving slow while button 1 is held.
// A @WhileHeld for slow mode with a default fast mode would also work,
// but this makes it easier to mix and match modes, like forwards/backwards,
// and is easy to change to having a "fast button" and "slow button".
@WhenPressed(1) public final Command slowMode = Robot.driving.slowModeCmd();
@WhenReleased(1) public final Command fastMode = Robot.driving.fastModeCmd();
}
@MapJoystick(port = 3,
role = Role.RIGHT_DRIVER_JOYSTICK,
type = Type.LOGITECH_2_AXIS)
public static class RightDriver {
// This joystick has no commands on its buttons, but we
// still want to declare it so that we can read its position
// for driving.
}
}
Initializing the OI takes two steps: creating the OI object and
joysticks, and then creating the commands. We want to do the first as
early as possible, so other code can reference the joysticks, but we
want to make the Commands as late as possible, since they typically
reference subsystems and other parts of the robot code. The
HYPERRobot
provides some abstract methods to take care of the
ordering for you:
public class Robot extends HYPERRobot {
public static final OI oi;
@Override
protected void initOI() {
oi = new OI(OIMap.class);
}
@Override
protected void initCommands() {
oi.initCommands();
}
/* ... other overrides ... */
}
To access the position of joysticks, use the appropriate getters in
the OI
class to get WPILib Joystick
objects, which have methods to read
the position of each axis. Going with the above example,
// Get a WPILib Joystick object
Joystick js = Robot.oi.leftDriver();
// Read coordinates
double x = js.getX();
double y = js.getY();
// Use x and y to do something useful, like set motor speeds
HYPERLib also provides support for validating the OI and generating diagrams of the controls. As we move to gradle, we're working on getting this to run automatically as part of the build process. There are many other possibilities as well. For example, we could generate the diagrams on the robot and host them over HTTP, so the driver station can display them automatically.