On This Page

CommandScheduler

When you are first taught to program, you are usually shown what is called the “imperative” style. That means that you are in control of what happens when. In a command-based robot, you have to use an “event-driven” style. You must learn how to break your code up into small pieces that execute quickly and rely on the CommandScheduler to call them at the right time.

The CommandScheduler will manage commands, calling their four lifecycle methods (initialize, execute, isFinished, end). It will also call the periodic methods of your subsystems and test any triggers you may have (mostly this will be joystick buttons). It is also responsible for managing the requirements of two commands, so two commands with overlapping requirements are never scheduled at the same time.

There are a number of ways to invoke the CommandScheduler:

CommandScheduler.getInstance().run() 🔗

Trigger methods 🔗

Command.schedule() 🔗

Command.cance() 🔗

Putting it all together 🔗

Workflow of CommandScheduler
This shows the workflow of the CommandScheduler in Java. The C++ implemention has almost identical behaviour. This diagram dooes not show command event methods

This is a rough outline of how everything gets run.

TimedRobot.startCompetition has an endless loop which polls its time-based priority queue for callbacks that are ready to run. Runnables are added to that priority queue using TimedRobot.addPeriodic. By default, the only thing on that queue is IterativeRobotBase.loopFunc.

IterativeRobotBase.loopFunc does:

  1. Calls <oldMode>Exit and <newMode>Init if the mode is changing
  2. Calls <mode>Periodic (e.g. autoPeriodic and telopPeriodic)
  3. Calls robotPeriodic
  4. Updates SmartDashbaord and LiveWindow properties
  5. Does loop overrun reporting

By default, the only thing robotPeriodic does is to call CommandScheduler.run.

CommandScheduler.run does the following:

  1. Calls subsystem periodic methods
  2. Polls its EventLoop
  3. For all scheduled commands, call execute, isFinished and/or possibly end.
  4. Enact pending calls to schedule and cancel
  5. Schedule default commands
  6. Does its own loop overrun reporting

When EventLoop.poll is called, it runs every registered Runnable. Runnables are registered using EventLoop.bind. By default, the only way Runnables are added to the CommandScheduler’s EventLoop is by calling one of the binding methods on a Trigger.

See also 🔗