WPILibC++  2020.3.2-60-g3011ebe
CommandScheduler.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2019-2020 FIRST. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in the root directory of */
5 /* the project. */
6 /*----------------------------------------------------------------------------*/
7 
8 #pragma once
9 
10 #include <initializer_list>
11 #include <memory>
12 #include <utility>
13 
14 #include <frc/ErrorBase.h>
15 #include <frc/WPIErrors.h>
16 #include <frc/Watchdog.h>
17 #include <frc/smartdashboard/Sendable.h>
18 #include <frc/smartdashboard/SendableHelper.h>
19 #include <units/units.h>
20 #include <wpi/ArrayRef.h>
21 #include <wpi/FunctionExtras.h>
22 
23 namespace frc2 {
24 class Command;
25 class Subsystem;
26 
34 class CommandScheduler final : public frc::Sendable,
35  public frc::ErrorBase,
36  public frc::SendableHelper<CommandScheduler> {
37  public:
43  static CommandScheduler& GetInstance();
44 
46  CommandScheduler(const CommandScheduler&) = delete;
47  CommandScheduler& operator=(const CommandScheduler&) = delete;
48 
49  using Action = std::function<void(const Command&)>;
50 
55  void SetPeriod(units::second_t period);
56 
63  void AddButton(wpi::unique_function<void()> button);
64 
68  void ClearButtons();
69 
80  void Schedule(bool interruptible, Command* command);
81 
88  void Schedule(Command* command);
89 
100  void Schedule(bool interruptible, wpi::ArrayRef<Command*> commands);
101 
112  void Schedule(bool interruptible, std::initializer_list<Command*> commands);
113 
120  void Schedule(wpi::ArrayRef<Command*> commands);
121 
128  void Schedule(std::initializer_list<Command*> commands);
129 
146  void Run();
147 
156  void RegisterSubsystem(Subsystem* subsystem);
157 
165  void UnregisterSubsystem(Subsystem* subsystem);
166 
167  void RegisterSubsystem(std::initializer_list<Subsystem*> subsystems);
169 
170  void UnregisterSubsystem(std::initializer_list<Subsystem*> subsystems);
172 
184  template <class T, typename = std::enable_if_t<std::is_base_of_v<
185  Command, std::remove_reference_t<T>>>>
186  void SetDefaultCommand(Subsystem* subsystem, T&& defaultCommand) {
187  if (!defaultCommand.HasRequirement(subsystem)) {
188  wpi_setWPIErrorWithContext(
189  CommandIllegalUse, "Default commands must require their subsystem!");
190  return;
191  }
192  if (defaultCommand.IsFinished()) {
193  wpi_setWPIErrorWithContext(CommandIllegalUse,
194  "Default commands should not end!");
195  return;
196  }
197  SetDefaultCommandImpl(subsystem,
198  std::make_unique<std::remove_reference_t<T>>(
199  std::forward<T>(defaultCommand)));
200  }
201 
209  Command* GetDefaultCommand(const Subsystem* subsystem) const;
210 
219  void Cancel(Command* command);
220 
229  void Cancel(wpi::ArrayRef<Command*> commands);
230 
239  void Cancel(std::initializer_list<Command*> commands);
240 
244  void CancelAll();
245 
255  double TimeSinceScheduled(const Command* command) const;
256 
265  bool IsScheduled(wpi::ArrayRef<const Command*> commands) const;
266 
275  bool IsScheduled(std::initializer_list<const Command*> commands) const;
276 
285  bool IsScheduled(const Command* command) const;
286 
294  Command* Requiring(const Subsystem* subsystem) const;
295 
299  void Disable();
300 
304  void Enable();
305 
312  void OnCommandInitialize(Action action);
313 
319  void OnCommandExecute(Action action);
320 
327  void OnCommandInterrupt(Action action);
328 
334  void OnCommandFinish(Action action);
335 
336  void InitSendable(frc::SendableBuilder& builder) override;
337 
338  private:
339  // Constructor; private as this is a singleton
341 
342  void SetDefaultCommandImpl(Subsystem* subsystem,
343  std::unique_ptr<Command> command);
344 
345  class Impl;
346  std::unique_ptr<Impl> m_impl;
347 
348  frc::Watchdog m_watchdog;
349 
350  friend class CommandTestBase;
351 };
352 } // namespace frc2
frc2::CommandScheduler::Run
void Run()
Runs a single iteration of the scheduler.
frc2::CommandScheduler::CancelAll
void CancelAll()
Cancels all commands that are currently scheduled.
FunctionExtras.h
wpi::unique_function
Definition: FunctionExtras.h:43
frc2::CommandScheduler::UnregisterSubsystem
void UnregisterSubsystem(Subsystem *subsystem)
Un-registers subsystems with the scheduler.
frc2::CommandScheduler::Cancel
void Cancel(Command *command)
Cancels a command.
frc2::CommandScheduler::Requiring
Command * Requiring(const Subsystem *subsystem) const
Returns the command currently requiring a given subsystem.
wpi::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:42
frc2::CommandScheduler::OnCommandFinish
void OnCommandFinish(Action action)
Adds an action to perform on the finishing of any command by the scheduler.
frc2::CommandScheduler::TimeSinceScheduled
double TimeSinceScheduled(const Command *command) const
Returns the time since a given command was scheduled.
frc2::CommandScheduler::Enable
void Enable()
Enables the command scheduler.
frc2::CommandScheduler::GetInstance
static CommandScheduler & GetInstance()
Returns the Scheduler instance.
frc2::CommandScheduler::OnCommandExecute
void OnCommandExecute(Action action)
Adds an action to perform on the execution of any command by the scheduler.
frc2::CommandScheduler::IsScheduled
bool IsScheduled(wpi::ArrayRef< const Command * > commands) const
Whether the given commands are running.
frc2::CommandScheduler::SetPeriod
void SetPeriod(units::second_t period)
Changes the period of the loop overrun watchdog.
frc2::Command
A state machine representing a complete action to be performed by the robot.
Definition: Command.h:52
frc2::CommandScheduler::ClearButtons
void ClearButtons()
Removes all button bindings from the scheduler.
frc2::CommandScheduler
The scheduler responsible for running Commands.
Definition: CommandScheduler.h:34
frc2::CommandScheduler::OnCommandInitialize
void OnCommandInitialize(Action action)
Adds an action to perform on the initialization of any command by the scheduler.
frc::Watchdog
A class that's a wrapper around a watchdog timer.
Definition: Watchdog.h:33
frc::ErrorBase
Base class for most objects.
Definition: ErrorBase.h:104
frc2::CommandScheduler::Disable
void Disable()
Disables the command scheduler.
frc2::CommandScheduler::InitSendable
void InitSendable(frc::SendableBuilder &builder) override
Initializes this Sendable object.
frc2::CommandScheduler::AddButton
void AddButton(wpi::unique_function< void()> button)
Adds a button binding to the scheduler, which will be polled to schedule commands.
frc::Sendable
Interface for Sendable objects.
Definition: Sendable.h:17
frc2::CommandScheduler::Schedule
void Schedule(bool interruptible, Command *command)
Schedules a command for execution.
frc2::Subsystem
A robot subsystem.
Definition: Subsystem.h:39
frc2::CommandScheduler::SetDefaultCommand
void SetDefaultCommand(Subsystem *subsystem, T &&defaultCommand)
Sets the default command for a subsystem.
Definition: CommandScheduler.h:186
frc2::CommandScheduler::RegisterSubsystem
void RegisterSubsystem(Subsystem *subsystem)
Registers subsystems with the scheduler.
frc2::CommandScheduler::GetDefaultCommand
Command * GetDefaultCommand(const Subsystem *subsystem) const
Gets the default command associated with this subsystem.
frc::SendableHelper
A helper class for use with objects that add themselves to SendableRegistry.
Definition: SendableHelper.h:28
frc::SendableBuilder
Definition: SendableBuilder.h:23
frc2::CommandScheduler::OnCommandInterrupt
void OnCommandInterrupt(Action action)
Adds an action to perform on the interruption of any command by the scheduler.