Skip to main content

Reforged Gamepad

While Listeners may be quite versatile, they often aren't the prettiest and most concise, especially for TeleOps, where you may have many controls mapped to many buttons.

This is where the Reforged Gamepad come in! It turns your TeleOp from this:

boolean gamepad1AWasPreviouslyTrue = false; // Mutable state
boolean gamepad2BWasPreviouslyTrue = false; // Gamepad1 vs 2, have to be paying attention!

@Override
public void loop() {
// Can't tell if this is the driver or not at first glance
// Also ugly to read and takes a second to mentally parse
if (gamepad1.a && !gamepad1AWasPreviouslyTrue) {
// Do something on the rising edge
}

// This one is the co-driver, but it's not obvious
if (!gamepad2.b && gamepad2BWasPreviouslyTrue) {
// Do something on the falling edge
}

// Have to do this for every button too...
gamepad1AWasPreviouslyTrue = gamepad1.a;
gamepad2BWasPreviouslyTrue = gamepad2.b;
}

into this!:

(LinearOpMode btw)
@Override
public void runOpMode() throws InterruptedException {
ReforgedGamepad driver = new ReforgedGamepad(gamepad1);
ReforgedGamepad codriver = new ReforgedGamepad(gamepad2);

driver.a.onRise(() -> ...); // Self describing
codriver.a.onFall(() -> ...); // And no unnecessary logic or mutable state

Scheduler.launchOnStart(this)
}

Behind the pretty veil, it's essentially just a collection of pre-made listeners, but it does come with one extra handy feature: You can get the value of any button without having to use the raw gamepad.

driver.a.get(); // Returns the current state of the A button (i.e. if it's pressed or not)

driver.right_stick_x.get(); // Returns the current state of the right stick's X axis
note

I understand that you may not be entirely sure what this syntax means, but read on and come back to it later if you need to.

Construction

Constructs a new Reforged Gamepad from a given gamepad. You'll likely construct two in your programs; one for the driver, and one for the co-driver.

Params
  • gamepad: Gamepad - The gamepad to wrap
    ReforgedGamepad driver = new ReforgedGamepad(gamepad1);
    ReforgedGamepad codriver = new ReforgedGamepad(gamepad2);

    Boolean triggers

    Boolean triggers refer to buttons that are either pressed or not pressed (i.e. either true or false).

    The ReforgedGamepad should support all the buttons on the gamepad.

    driver.a.onRise(() -> ...); // Do something when the A button is pressed
    driver.a.onFall(() -> ...); // Do something when the A button is released

    // Method chaining works too
    driver.b.whileHigh(() -> ...) // Do something while the B button is pressed
    .whileLow(() -> ...); // Do something while the B button is not pressed

    // All the normal Listener methods work with it
    driver.a.and(() -> lift.height() > 500)
    .onRise(() -> ...); // Do something when the A button is pressed and the lift is above 500

    driver.dpad_up.and(driver.right_bumper)
    .onRise(() -> ...); // Do something when the D-Pad up and the right bumper are pressed

    // You can also access the raw gamepad
    driver.gamepad

    // And you can get the value of any button without having to use the raw gamepad
    driver.a.get(); // Returns the current state of the A button (i.e. if it's pressed or not)

    Analog triggers

    Analog triggers are gamepad components which return a float value (e.g. the joysticks or triggers).

    These can be accessed through functions, passing in a deadzone parameter, which is a float between 0 and 1

    The ReforgedGamepad compares the absolute value of the analog trigger to the deadzone, and becomes true if the abs value is greater than the deadzone.

    driver.left_stick_x(.1).onRise(() -> ...); // Do something when it becomes either >.1 or <-.1

    driver.left_sick_x.onRise(() -> ...); // Shorthand for driver.left_stick_x(.1).onRise(() -> ...);
    // It always returns the same object, it's mainly for convenience

    driver.right_trigger(.5).whileHigh(() -> ...); // Do something while the right trigger is pressed > halfway

    driver.left_stick_x.get(); // Returns the current value of the left stick's X axis (as a float)
    // No reason to pass in a deadzone here, that creates an unnecessary object

    // Normal listener methods still work with it
    driver.touchpad_finger_2_x(.1).or(driver.a)
    .onRise(() -> ...); // Do something when touchpad_finger_2_x >.1 or the A button is pressed

    It's a relatively simple class, but it's powerful nevertheless.

    Practical usage example

    These are in Kotlin, but the concept still carries through to Java