Enlazando comandos a Triggers

Además de los comandos autónomos, que se programan al inicio del período autónomo, y los comandos predeterminados, que se programan automáticamente cuando su subsistema no está en uso, la forma más común de ejecutar un comando es vinculándolo a un evento de activación, como un botón que presiona un operador humano. El paradigma basado en comandos hace que esto sea extremadamente fácil de hacer.

Como se ha mencionado anteriormente, el paradigma basado en comandos es declarativo. En consecuencia, la vinculación de los botones a los comandos se realiza de forma declarativa; la asociación de un botón y un comando se «declara» una vez, durante la inicialización del robot. La biblioteca hace entonces todo el trabajo duro de comprobar el estado del botón y programar (o cancelar) el comando según sea necesario, entre bastidores. Los usuarios sólo tienen que preocuparse de diseñar la configuración de la interfaz de usuario deseada, no de implementarla.

Command binding is done through the Trigger class (Java, C++) and its various Button subclasses (Java, C++).

Enlaces de gatillo / botón

Nota

The C++ command-based library offers two overloads of each button binding method - one that takes a forwarding reference, and one that takes a raw pointer. The forwarding reference overload transfers ownership (by either moving or copying depending on if the command is an rvalue or an lvalue) to the scheduler, while the raw pointer overload leaves the user responsible for the lifespan of the command object. It is recommended that users preferentially use the forwarding reference overload unless there is a specific need to retain a handle to the command in the calling code.

Hay varios enlaces disponibles para la clase Trigger. Todos estos enlaces programarán automáticamente un comando cuando se produzca un determinado evento de activación de botón; sin embargo, cada enlace tiene un comportamiento específico diferente. Button y sus subclases tienen enlaces con comportamientos idénticos, pero nombres ligeramente diferentes que combinan mejor con un botón en lugar de un evento de activación arbitrario.

whenActive/whenPressed

Esta vinculación programa un comando cuando un botón cambia de inactivo a activo (o, en consecuencia, cuando se presiona inicialmente un cambio de botón). El comando se programará en la iteración cuando cambie el estado, y no se programará nuevamente a menos que el botón se vuelva inactivo y luego se active nuevamente (o se suelte el botón y luego se vuelva a presionar).

whileActiveContinuous/whileHeld

Esta vinculación programa un comando repetidamente mientras un botón está activo (o, en consecuencia, mientras se mantiene presionado un botón) y lo cancela cuando el disparador se vuelve inactivo (o cuando se suelta el botón). Tenga en cuenta que programar un comando que ya se esté ejecutando no tiene ningún efecto; pero si el comando finaliza mientras el botón o gatillo aún está activo, se reprogramará.

whileActiveOnce/whenHeld

Esta vinculación programa un comando cuando un botón o gatillo cambia de inactivo a activo (o, en consecuencia, cuando se presiona un botón inicialmente) y lo cancela cuando el botón vuelve a estar inactivo (o se suelta el botón). El comando no se reprogramará si finaliza mientras el botón aún está activo.

whenInactive/whenReleased

Este enlace programa un comando cuando un botón o gatillo cambia de activo a inactivo (o, en consecuencia, cuando se suelta inicialmente un botón). El comando se programará en la iteración cuando cambie el estado y no se reprogramará a menos que el botón o gatillo se active y luego se vuelva inactivo (o se presione el botón y luego se vuelva a soltar).

toggleWhenActive/toggleWhenPressed

This binding toggles a command, scheduling it when a trigger changes from inactive to active (or a button is initially pressed), and canceling it under the same condition if the command is currently running. Note that while this functionality is supported, toggles are not a highly-recommended option for user control, as they require the driver to keep track of the robot state. The preferred method is to use two buttons; one to turn on and another to turn off. Using a StartEndCommand or a ConditionalCommand is a good way to specify the commands that you want to be want to be toggled between.

myButton.toggleWhenPressed(new StartEndCommand(mySubsystem::onMethod,
    mySubsystem::offMethod,
    mySubsystem));

cancelWhenActive/cancelWhenPressed

Esta vinculación cancela un comando cuando un botón o gatillo cambia de inactivo a activo(o, en consecuencia, cuando un botón es presionado inicialmente). el comando es cancelado en la iteración cuando el estado cambia, y no será cancelado a menos que el botón o gatillo cambie de inactivo a activo de nuevo (o se suelte el botón y se vuelva a presionar). Note que cancelar un comando que no funciona al momento no tiene efecto.

Vincular un comando a un botón del joystick

La manera más común para desencadenar un comando es vincular un comando a un botón en un joystick o algún otro DIH (dispositivo para intervención humana). Para hace resto , los usuarios deben de utilizar la clase JoystickButton.

Crear un JoystickButton

In order to create a JoystickButton, we first need a Joystick. All types of joysticks (including gamepads) are represented in code by the GenericHID class (Java, C++), or one of its subclasses:

Joystick exampleStick = new Joystick(1); // Creates a joystick on port 1
XboxController exampleController = new XboxController(2); // Creates an XboxController on port 2.

Nota

When creating a JoystickButton with an XboxController, it is usually a good idea to use the button enum (Java, C++) to get the button number corresponding to a given button.

After the joystick is instantiated, users can then pass it to a JoystickButton object (Java, C++):

JoystickButton exampleButton = new JoystickButton(exampleStick, 1); // Creates a new JoystickButton object for button 1 on exampleStick

Vincular un comando a un JoystickButton

Nota

En la biblioteca a base de comandos de C++ no necesita llegar después de la llamada a un método de vinculación, entonces los métodos de vinculación podrán ser llamados solamente de manera temporal.

Poniéndolo todo junto, es muy sencillo vincular un botón a un JoystickButton:

// Binds an ExampleCommand to be scheduled when the trigger of the example joystick is pressed
exampleButton.whenPressed(new ExampleCommand());

Es útil notar que los métodos de vinculación de comandos todos devuelven el gatillo/botón al cual fueron inicialmente vinculados a , entonces puede ser encadenado a vincular múltiples comandos a diferentes estados del mismo botón. Por ejemplo:

exampleButton
    // Binds a FooCommand to be scheduled when the `X` button of the driver gamepad is pressed
    .whenPressed(new FooCommand())
    // Binds a BarCommand to be scheduled when that same button is released
    .whenReleased(new BarCommand());

Recuerde que la vinculación de botones es declarativa: los vínculos solo se necesitan declarar una vez, idealmente durante la inicialización del robot. La biblioteca maneja el resto.

Componer botones

La clase Trigger``(incluye sus subclases ``Button) puede estar compuesta para crear botones compuestos a través de los métodos and(), or(), y negate() (o, en C++, los operadores &&, ||, y ! ). Por ejemplo:

// Binds an ExampleCommand to be scheduled when both the 'X' and 'Y' buttons of the driver gamepad are pressed
new JoystickButton(exampleController, XBoxController.Button.kX.value)
    .and(new JoystickButton(exampleController, XboxController.Button.kY.value))
    .whenActive(new ExampleCommand());

Note que estos métodos devuelven un Trigger, no un Button, entonces los nombres de métodos de vinculación Trigger deben ser usados cuando los botones se componen.

Debouncing Triggers

To avoid rapid repeated activation, triggers (especially those originating from digital inputs) can be debounced with the WPILib Debouncer class using the debounce method:

// debounces exampleButton with a 0.1s debounce time, rising edges only
exampleButton.debounce(0.1).whenActive(new ExampleCommand());

// debounces exampleButton with a 0.1s debounce time, both rising and falling edges
exampleButton.debounce(0.1, Debouncer.DebounceType.kBoth).whenActive(new ExampleCommand());

Crear tu botón personalizado

While binding to HID buttons is by far the most common use case, advanced users may occasionally want to bind commands to arbitrary triggering events. This can be easily done by simply writing your own subclass of Trigger or Button:

public class ExampleTrigger extends Trigger {
  @Override
  public boolean get() {
    // This returns whether the trigger is active
  }
}

Alternativamente, esto también se puede realizar en línea pasando un lambda al constructor de un trigger o un button:

// Here it is assumed that "condition" is an object with a method "get" that returns whether the trigger should be active
Trigger exampleTrigger = new Trigger(condition::get);