Programación basada en comandos, Versión 2020: ¿Qué cambió?

This article provides a summary of changes from the original command-based framework to the 2020 rewrite. This summary is not necessarily comprehensive - for rigorous documentation, as always, refer to the API docs (Java, C++).

Ubicación del paquete

The new command-based framework is located in the wpilibj2 package for Java, and in the frc2 namespace for C++. The new framework must be installed using the instructions: Bibliotecas de comandos de WPILib.

Cambios arquitectónicos mas grandes

La estructura general del framework para la programación basada en comandos ha permanecido predominantemente igual. Aun así hay algunos cambios estructurales de los que los usuarios deberían estar al tanto:

Comandos y Subsistemas como interfaces

Command (Java, C++) and Subsystem (Java, C++) are both now interfaces as opposed to abstract classes, allowing advanced users more potential flexibility. CommandBase and SubsystemBase abstract base classes are still provided for convenience, but are not required. For more information, see Comandos and Subsistemas.

Clases grupales de múltiples comandos

The CommandGroup class no longer exists, and has been replaced by a number of narrower classes that can be recursively composed to create more-complicated group structures. For more information see Command Compositions.

Definiciones de comandos in-line

Previously, users were required to write a subclass of Command in almost all cases where a command was needed. Many of the new commands are designed to allow inline definition of command functionality, and so can be used without the need for an explicit subclass. For more information, see Included Command Types.

Inyección de dependencias de comando

Aun sin un cambio real al código de la librería, el patrón de uso recomendado para el nuevo framework de programación basada en comandos utiliza inyección de dependencias de subsistemas en los comandos, permitiendo que los subsistemas no sean declarados como globales. Este es un patrón mas limpio, de mayor mantenibilidad y mas reusable que el subsistema global promovido previamente. Para mas información véase Estructuración de un proyecto de robot basado en comandos.

Pertenencia de Comando (Solo para C++)

El framework de comandos anterior requería a los usuarios el usar punteros en crudo para todos los comandos, resultando en una perdida de memoria casi inevitable en todos los proyectos basados en comandos de C++, así como la oportunidad para que errores comunes se presentaran, como la doble locación de un comando dentro de un grupos de comandos

El framework ofrece gestión de propiedad para todos los comandos. Los comandos predeterminados y los comandos vinculados a botones generalmente son propiedad del planificador, y los comandos de componentes son propiedad de sus grupos de comandos encapsulantes. Como resultado, los usuarios generalmente nunca deberían asignar un comando en montón con `` nuevo “” a menos que haya una muy buena razón para hacerlo.

La transferencia de propiedad se hace usando perfect forwarding, lo que significa que los rvalues seran moved y los lvalues seran copied (rvalue/lvalue explanation).

Cambios al Planificador

  • Scheduler has been renamed to CommandScheduler (Java, C++).

  • La interrupbilidad de los comandos ahora es responsabilidad del planificador, no de los comandos, y se puede especificar durante la llamada a `` schedule “”.

  • Los usuarios ahora pueden pasar acciones al planificador que se realizan cada vez que un comando se programa, interrumpe o finaliza normalmente. Esto es muy útil para casos como el registro de eventos.

Cambios al Subsistema

Nota

Para mas información sobre subsistemas, véase Subsistemas.

  • As noted earlier, Subsystem is now an interface (Java, C++); the closest equivalent of the old Subsystem is the new SubsystemBase class. Many of the Sendable-related constructor overloads have been removed to reduce clutter; users can call the setters directly from their own constructor, if needed.

  • initDefaultCommand ha sido removido; los subsistemas no necesitan más «conocer» sus comandos por default , los que mejor se registran directamente con CommandScheduler. El nuevo método setDefaultCommand simplemente envuelve la llamada CommandScheduler .

  • Los subsistemas ya no «conocen» los comandos que los requieren en ese momento; esto es manejado exclusivamente por el `` CommandScheduler``. Sin embargo, se proporciona un contenedor de conveniencia en el método `` CommandScheduler``.

Cambios a Comandos

Nota

Para mas información sobre comandos, véase Comandos.

  • As noted earlier, Command is now an interface (Java, C++); the closest equivalent of the old Command is the new CommandBase class. Many of the Sendable-related constructor overloads have been removed to reduce clutter; users can call the setters directly from their own constructor, if needed.

  • Los comandos ya no manejan su propio estado de programación; ahora es responsabilidad del planificador.

  • El método interrupted() ha sido unido al método end(), lo cual ahora agrega un parámetro que especifica si el comando fue interrumpido o no («false» si finalizó normalmente)

  • El método requires()``ha cambiado su nombre a ``addRequirement().

  • void setRunsWhenDisabled(boolean disabled) has been replaced by an overridable runsWhenDisabled method.

  • void setInterruptible(boolean interruptible) has been replaced by an overridable getInterruptionBehavior method.

  • Several «decorator» methods have been added to allow easy inline modification of commands (e.g. adding a timeout).

  • (C++ only) In order to allow the decorators to work with the command ownership model, a CRTP is used via the CommandHelper class. Any user-defined Command subclass Foo must extend CommandHelper<Foo, Base> where Base is the desired base class.

Cambios a PIDSubsystem/PIDCommand

  • Después de los cambios en el PIDController, estas clases ahora se ejecutan sincrónicamente desde el loop principal del robot.

  • El `` PIDController`` ahora se inyecta a través del constructor, eliminando muchos de los métodos de reenvío. Se puede modificar después de la construcción con `` getController() ``.

  • PIDCommand está pensado en gran medida para su uso en línea, como se muestra en el ejemplo GyroDriveCommands (Java, C++).

  • Si los usuarios desean utilizar el PIDCommand mas «tradicionalmente», sobreescribir los metodos protegidos returnPIDInput() y usePIDOutput(double output) ha sido reemplazado modificando los campos m_measurement y m_useOutput . De manera similar, en vez de llamar a setSetpoint, los usuarios pueden modificar el campo protegido m_setpoint .