El planificador de comandos

El CommandScheduler (Java, C++) es la clase responsable de correr los comandos. Cada repetición (normalmente una vez cada 20ms) el scheduler sondea todos los botones registrados, programa los comandos para su ejecución en consecuencia, ejecuta los cuerpos de comando de todos los comandos programados y finaliza los comandos que han finalizado o están interrumpidos

El CommandScheduler también ejecuta el método periodic() de cada `` Subsistema`` registrado.

Uso del programador de comandos

El CommandScheduler es un singleton, lo que significa que es una clase accesible globalmente con una sola instancia. En consecuencia, para acceder al programador, los usuarios deben llamar al comando CommandScheduler.getInstance().

En su mayor parte, los usuarios no tienen que llamar directamente a los métodos del planificador; casi todos los métodos importantes del planificador tienen envoltorios de conveniencia en otros lugares. (ej. en las interfaces de los comandos Command y Subsystem ).

Sin embargo, hay una excepción: los usuarios deben llamar a CommandScheduler.getInstance().run() del método robotPeriodic() de su clase Robot . Si no se hace esto, el programador nunca se ejecutará y el marco de comandos no funcionará. La plantilla de proyecto a base de comandos proporcionada ya tiene esta llamada incluida.

El método schedule()

Flow diagram showing how a scheduled command is evaluated to be run.

Para programar un comando, los usuarios llaman al metodo schedule() (Java, C++. Este metodo toma un comando (y opcionalmente, una especificación de si el comando es interrupible), e intenta añadirlo a la lista de comandos que se están corriendo en este momento, pendiente de si ya se está ejecutando o si sus requisitos están disponibles. si es añadido, su método initialize() es llamado.

La secuencia de ejecución del programador

Nota

El método initialize() de cada Comando es llamado cuando el comando es programado, lo cual no es necesariamente cuando un programador este ejecutándose (a menos que ese comando este atado a un botón).

Flow diagram that show the sequence of each individual command.

¿Qué hace en realidad una sola iteración del método run() del planificador (Java, C++)? La siguiente sección aborda sobre la lógica de la iteración del programador.

Paso 1: ejecutar los métodos periódicos del subsistema

Primero, el programador ejecuta el método periodic() de cada Subsistema registrado.

Paso 2: Activadores de programación de comandos

Nota

Para obtener más información sobre cómo funcionan los enlaces de activadores, consulte Enlazando comandos a Triggers

En segundo lugar, el programador sondea el estado de todos los desencadenantes registrados para ver si se debe programar algún comando nuevo que se haya vinculado a esos desencadenantes. Si se cumplen las condiciones para programar un comando vinculado, se programa el comando y se ejecuta su método Initialize().

Paso 3: ejecutar/finalizar comandos programados

En tercer lugar, el planificador llama al método execute() de cada comando programado actualmente, y luego verifica si el comando ha terminado llamando al método isFinished(). Si el comando ha finalizado, también se llama al método end(), y el comando se desprograma y se liberan los subsistemas necesarios.

Tenga en cuenta que esta secuencia de llamadas se realiza en orden para cada comando; por lo tanto, un comando puede tener su método end() llamado antes de que otro tenga su método execute() llamado. Los comandos se manejan en el orden en que fueron programados.

Paso 4: Programar comandos predeterminados

Finalmente, cualquier Subsistema registrado tiene su comando predeterminado programado (si lo tiene). Tenga en cuenta que en este momento se llamará al método initialize() del comando predeterminado.

Deshabilitar el programador

El planificador se puede desactivar llamando a CommandScheduler.getInstance().disable(). Cuando está deshabilitado, los comandos schedule() y run() del programador no harán nada.

El programador se puede volver a habilitar al llamar a CommandScheduler.getInstance().enable().

Métodos de eventos de comando

Ocasionalmente, es deseable que el programador ejecute una acción personalizada siempre que se produzca un determinado evento de comando (inicialización, ejecución o finalización). Esto se puede hacer con los siguientes tres métodos:

onCommandInitialize

El método onCommandInitialize (Java, C++) ejecuta una acción específica cuando un comando es inicializado.

onCommandExecute

El método onCommandExecute (Java, C++) ejecuta una acción específica cuando un comando es ejecutado.

onCommandFinish

El método onCommandFinish (Java, C++) ejecuta una acción especificada cada vez que un comando termina normalmente (es decir, el método isFinished() devuelve true).

onCommandInterrupt

El método onCommandInterrupt (Java, C++) ejecuta una acción especificada cada vez que un comando se interrumpe (es decir, al ser cancelado explícitamente o por otro comando que comparte uno de sus requisitos).

Un caso de uso típico para estos métodos es añadir marcadores en un registro de eventos cada vez que se produce un evento de programación de comandos, como se demuestra en el proyecto de ejemplo SchedulerEventLogging (Java, C++):

50
51
52
53
54
55
56
    // Set the scheduler to log Shuffleboard events for command initialize, interrupt, finish
    CommandScheduler.getInstance().onCommandInitialize(command -> Shuffleboard.addEventMarker(
        "Command initialized", command.getName(), EventImportance.kNormal));
    CommandScheduler.getInstance().onCommandInterrupt(command -> Shuffleboard.addEventMarker(
        "Command interrupted", command.getName(), EventImportance.kNormal));
    CommandScheduler.getInstance().onCommandFinish(command -> Shuffleboard.addEventMarker(
        "Command finished", command.getName(), EventImportance.kNormal));