Fang-Robotics-MCB
Fang Robotics Team Codebase
Loading...
Searching...
No Matches
tap::control::CommandScheduler Class Reference

#include <command_scheduler.hpp>

Classes

struct  CommandIterator
 
struct  SubsystemIterator
 

Public Member Functions

 CommandScheduler (Drivers *drivers, bool masterScheduler=false, SafeDisconnectFunction *safeDisconnectFunction=&CommandScheduler::defaultSafeDisconnectFunction)
 
mockable ~CommandScheduler ()
 
mockable void run ()
 
mockable void addCommand (Command *commandToAdd)
 
mockable void removeCommand (Command *command, bool interrupted)
 
mockable bool isCommandScheduled (const Command *command) const
 
mockable void registerSubsystem (Subsystem *subsystem)
 
mockable void setSafeDisconnectFunction (SafeDisconnectFunction *func)
 Set the SafeDisconnectFunction to the given function.
 
mockable bool isSubsystemRegistered (const Subsystem *subsystem) const
 
mockable void runAllHardwareTests ()
 
mockable void runHardwareTest (const Subsystem *subsystem)
 
mockable void stopAllHardwareTests ()
 
mockable void stopHardwareTest (const Subsystem *subsystem)
 
mockable int countRunningHardwareTests ()
 
mockable bool isRunningTest (const Subsystem *subsystem)
 
mockable bool hasPassedTest (const Subsystem *subsystem)
 
mockable int subsystemListSize () const
 
mockable int commandListSize () const
 
mockable CommandIterator cmdMapBegin ()
 
mockable CommandIterator cmdMapEnd ()
 
mockable SubsystemIterator subMapBegin ()
 
mockable SubsystemIterator subMapEnd ()
 
mockable subsystem_scheduler_bitmap_t getRegisteredSubsystemBitmap () const
 
mockable command_scheduler_bitmap_t getAddedCommandBitmap () const
 

Static Public Member Functions

static int constructCommand (Command *command)
 
static int constructSubsystem (Subsystem *subsystem)
 
static void destructCommand (Command *command)
 
static void destructSubsystem (Subsystem *subsystem)
 

Detailed Description

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.

// A class that has Subsystem as a base class.
CoolSubsystem sub;
// A class that has Command as a base class that requires
// the subsystem above. In the constructor of the ControlCoolCommand,
// you must call `addSubsystemRequirement(sub)`, where `sub` is the
// `CoolSubsystem` defined above.
ControlCoolCommand cmd(&sub);
while (1)
{
// The subsystem will refresh forever and the command will execute until it
// is finished.
drivers->commandScheduler.run();
}
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.

Constructor & Destructor Documentation

◆ CommandScheduler()

tap::control::CommandScheduler::CommandScheduler ( Drivers drivers,
bool  masterScheduler = false,
SafeDisconnectFunction safeDisconnectFunction = &CommandScheduler::defaultSafeDisconnectFunction 
)

◆ ~CommandScheduler()

tap::control::CommandScheduler::~CommandScheduler ( )

Member Function Documentation

◆ addCommand()

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]commandToAddthe Command to be added to the scheduler.

◆ cmdMapBegin()

CommandScheduler::CommandIterator tap::control::CommandScheduler::cmdMapBegin ( )

◆ cmdMapEnd()

CommandScheduler::CommandIterator tap::control::CommandScheduler::cmdMapEnd ( )

◆ commandListSize()

int tap::control::CommandScheduler::commandListSize ( ) const
Returns
The number of commands added in the scheduler.

◆ constructCommand()

int tap::control::CommandScheduler::constructCommand ( Command command)
static

◆ constructSubsystem()

int tap::control::CommandScheduler::constructSubsystem ( Subsystem subsystem)
static

◆ countRunningHardwareTests()

int tap::control::CommandScheduler::countRunningHardwareTests ( )
Returns
the count of subsystems currently running a test.

◆ destructCommand()

void tap::control::CommandScheduler::destructCommand ( Command command)
static

◆ destructSubsystem()

void tap::control::CommandScheduler::destructSubsystem ( Subsystem subsystem)
static

◆ getAddedCommandBitmap()

mockable command_scheduler_bitmap_t tap::control::CommandScheduler::getAddedCommandBitmap ( ) const
inline

◆ getRegisteredSubsystemBitmap()

mockable subsystem_scheduler_bitmap_t tap::control::CommandScheduler::getRegisteredSubsystemBitmap ( ) const
inline

◆ hasPassedTest()

bool tap::control::CommandScheduler::hasPassedTest ( const Subsystem subsystem)
Parameters
[in]subsystemthe subsystem to check
Returns
true if the test command has passed, false otherwise.

◆ isCommandScheduled()

bool tap::control::CommandScheduler::isCommandScheduled ( const Command command) const
Returns
true if the CommandScheduler contains the requrested Command. false otherwise.

◆ isRunningTest()

bool tap::control::CommandScheduler::isRunningTest ( const Subsystem subsystem)
Parameters
[in]subsystemthe subsystem to check
Returns
true if the test command is running, false otherwise.

◆ isSubsystemRegistered()

bool tap::control::CommandScheduler::isSubsystemRegistered ( const Subsystem subsystem) const
Parameters
[in]subsystemthe subsystem to check
Returns
true if the Subsystem is already scheduled, false otherwise.

◆ registerSubsystem()

void tap::control::CommandScheduler::registerSubsystem ( Subsystem subsystem)

Adds the given Subsystem to the CommandScheduler. The subsystem is added with the currently scheduled Command as nullptr.

Parameters
[in]subsystemthe Subsystem to add. Must be not nullptr and not registered already (check via isSubsystemRegistered()), otherwise an error is added to the error handler.

◆ removeCommand()

void tap::control::CommandScheduler::removeCommand ( Command command,
bool  interrupted 
)

Removes the given Command completely from the CommandScheduler. This means removing all instances of the command pointer from the Subsystem -> Command map (since a single Subsystem can map to multiple Commands).

Parameters
[in]commandthe Command to remove. Must not be nullptr. If the Command is not in the scheduler, nothing is removed.
[in]interruptedan argument passed in to the Command's end() function when removing the desired Command.

◆ run()

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).

◆ runAllHardwareTests()

void tap::control::CommandScheduler::runAllHardwareTests ( )

Runs all hardware tests from subsystems that have a test command.

◆ runHardwareTest()

void tap::control::CommandScheduler::runHardwareTest ( const Subsystem subsystem)

Runs the hardware test command, if available, for the specific subsystem.

Parameters
[in]subsystemthe subsystem to run

◆ setSafeDisconnectFunction()

void tap::control::CommandScheduler::setSafeDisconnectFunction ( SafeDisconnectFunction func)

Set the SafeDisconnectFunction to the given function.

Parameters
[in]functhe function that the CommandScheduler will use to determine what constitutes a "disconnected" state.

◆ stopAllHardwareTests()

void tap::control::CommandScheduler::stopAllHardwareTests ( )

Stop all hardware tests from subsystems that have a running test command.

◆ stopHardwareTest()

void tap::control::CommandScheduler::stopHardwareTest ( const Subsystem subsystem)

Stops the hardware test command, if running, for the specific subsystem.

Parameters
[in]subsystemthe subsystem to stop

◆ subMapBegin()

CommandScheduler::SubsystemIterator tap::control::CommandScheduler::subMapBegin ( )

◆ subMapEnd()

CommandScheduler::SubsystemIterator tap::control::CommandScheduler::subMapEnd ( )

◆ subsystemListSize()

int tap::control::CommandScheduler::subsystemListSize ( ) const
Returns
The number of subsystems registered with the scheduler.

The documentation for this class was generated from the following files: