Class for handling all the commands you would like to currently run. Interfaces with the Subsystem and Command classes to provide a means of safely scheduling multiple Commands and Subsystems. Checks are provided while scheduling such that multiple commands that require the same subsystem cannot run at the same time. Suppose for example that you have a Command that moves a mechanical arm Subsystem to some position and another Command that moves the same arm to a different position. Obvious issues arise if one attempts to tell the Subsystem to do two things at once. Using this class will disallow these two Commands from being executed at the same time.
For the the above reasons, you cannot map the same command instance to two different input states at the same time. You must declare a separate instance of the command (these can be the same class) for each mapping, or use a ComprisedCommand with your own scheduling logic.
This class contains a map of Subsystems -> Commands. The Subsystems will be refreshed each time the CommandScheduler is ran. If there are commands associated with the Subsystem, the CommandScheduler will execute these commands as well. Additional less important features are explained in more detail in the function definitions.
The goal of this class is for the user to interace directly as little as possible. Aside from calling run each time to update the scheduler, the user should be interacting with the Command, ComprisedCommand, Subsystem, and CommandMapper classes to add and remove commands from the scheduler.
The main use case will be to be refreshing all the main subsystems running on the robot. You should access the main scheduler via the global tap::Drivers * instance, which should have an instance of a CommandScheduler called commandScheduler. The below example code registers a subsystem (sub) and adds a command (cmd) to the scheduler. Then the scheduler is run over and over, in a loop.
CoolSubsystem sub;
ControlCoolCommand cmd(&sub);
while (1)
{
}
control::CommandScheduler commandScheduler
Definition drivers.hpp:141
mockable void addCommand(Command *commandToAdd)
Definition command_scheduler.cpp:252
mockable void registerSubsystem(Subsystem *subsystem)
Definition command_scheduler.cpp:333
mockable void run()
Definition command_scheduler.cpp:168
The second use case for a CommandScheduler is in the ComprisedCommand class. Here, you utilize the CommandScheduler to coordinate multiple commands inside a single command. The usage is exactly the same as using the main CommandScheduler.
| void tap::control::CommandScheduler::addCommand |
( |
Command * |
commandToAdd | ) |
|
Attempts to add a Command to the scheduler. There are a number of ways this function can fail. If failure does occur, an error will be added to the error handler.
These are the following reasons why adding a Command fails:
- The commandToAdd is
nullptr
- The commandToAdd has no Subsystem requirements.
- The commandToAdd has Subsystems not in the CommandScheduler.
If a Command is successfully added to the CommandScheduler, any Subsystems that the commandToAdd requires that have Commands running will be ended (and the interrupted flag for that Command set to true).
If a Command is successfully added, the Command's initialize() function will be called.
- Note
- If the
commandToAdd was already scheduled, it will be interrupted (its end() will be called) and then the command will be rescheduled.
- Parameters
-
| [in] | commandToAdd | the Command to be added to the scheduler. |
| void tap::control::CommandScheduler::run |
( |
| ) |
|
Calls the refresh() function for all Subsystems and the associated execute() function for all Commands. A Subsystem is guarenteed to be refreshed no more than one time each time the mainScheduler's run function is called. The same goes for a Command. This includes even if multiple CommandSchedulers are running in ComprisedCommands that have shared Subsystems.
If any Subsystem that is in the scheduler does not have a Command controlling it but does have a default command (via the Subsystem's getDefaultCommand()), the default command is added to the scheduler.
If any Command is finished after execution, the Command is removed from the scheduler. The Command's end() function is called, passing in isInterrupted = false.
- Note
- checks the run time of the scheduler. An error is added to the error handler if the time is greater than
MAX_ALLOWABLE_SCHEDULER_RUNTIME (in microseconds).