Switch Reactor

It is very common in FRC robot code to register some function that should be called when some switch or button changes state. Strongback’s switch reactor framework makes this very easy and lightweight.

For example, the following code fragment shows how to use the reactor to submit a command whenever a Gamepad’s left trigger button is pressed, and submit a different command when the same trigger is released:

SwitchReactor reactor = Strongback.switchReactor();
Gamepad gamepad = ...
reactor.onTriggered(gamepad.getRightTrigger(),()->Strongback.submit(new FireRepeatedlyCommand()));
reactor.onUnTriggered(gamepad.getRightTrigger(),()->Strongback.submit(new StopFireCommand()));

When the Gamepad’s right trigger is pressed, the lambda on line 3 will create and submit a FireRepeatedlyCommand. When the Gamepad’s right trigger is released, the lambda on line 4 will create and submit a StopFireCommand.

Submitting a new command when a switch becomes triggered or untriggered is common enough that Strongback provides methods that make this a little easier. The following code is functionally identical to the previous sample, but is a little easier to read:

SwitchReactor reactor = Strongback.switchReactor();
Gamepad gamepad = ...
reactor.onTriggeredSubmit(gamepad.getRightTrigger(),FireRepeatedlyCommand::new);
reactor.onUnTriggeredSubmit(gamepad.getRightTrigger(),StopFireCommand::new);

Of course, you don’t always want to submit a command. For example, your robot might have a button that changes the drive system gears from low to high gear. The TankDrive component’s highGear() method switches to high gear, and lowGear() switches to low gear. We can use method references and register these methods to respond when the joystick’s trigger is pressed and held or released:

SwitchReactor reactor = Strongback.switchReactor();
FlightStick joystick = ...
TankDrive chassis = ...
reactor.whileTriggered(joystick.getTrigger(),chassis::highGear);
reactor.whileUnTriggered(gamepad.getRightTrigger(),chassis:lowGear);

These functions are called only when the switch state changes, so pressing and holding the joystick trigger will result in one call to TankDrive.highGear(), and then releasing will result in a single call to TankDrive.lowGear().

As you can see from the examples, the switch reactor can be accessed using the Strongback.switchReactor() method. The org.strongback.SwitchReactor interface returned by that method is quite simple:

@ThreadSafe
public interface SwitchReactor {

    /**
     * Submit a {@link Command} the moment when the specified {@link Switch} is triggered.
     *
     * @param swtch the {@link Switch}
     * @param commandSupplier the supplier of the command to submit; may not be null but
     * may return a null command
     */
    public void onTriggeredSubmit(Switch swtch, Supplier<Command> commandSupplier);

    /**
     * Submit a {@link Command} the moment when the specified {@link Switch} is untriggered.
     *
     * @param swtch the {@link Switch}
     * @param commandSupplier the supplier of the command to submit; may not be null but
     * may return a null command
     */
    public void onUntriggeredSubmit(Switch swtch, Supplier<Command> commandSupplier);

    /**
     * Register a {@link Runnable} function that is to be called the moment
     * when the specified {@link Switch} is triggered.
     *
     * @param swtch the {@link Switch}
     * @param function the function to execute when the switch is triggered
     */
    public void onTriggered(Switch swtch, Runnable function);

    /**
     * Register a {@link Runnable} function that is to be called the moment
     * when the specified {@link Switch} is untriggered.
     *
     * @param swtch the {@link Switch}
     * @param function the function to execute when the switch is untriggered
     */
    public void onUntriggered(Switch swtch, Runnable function);

    /**
     * Register a {@link Runnable} function to be called repeatedly whenever
     * the specified {@link Switch} is in the triggered state.
     *
     * @param swtch the {@link Switch}
     * @param function the function to execute while the switch remains triggered
     */
    public void whileTriggered(Switch swtch, Runnable function);

    /**
     * Register a {@link Runnable} function to be called repeatedly whenever
     * the specified {@link Switch} is not in the triggered state.
     *
     * @param swtch the {@link Switch}
     * @param function the function to execute while the switch remains untriggered
     */
    public void whileUntriggered(Switch swtch, Runnable function);
}

At this time, once a function is registered it will continue to operate.

results matching ""

    No results matching ""