WPILibC++ 2027.0.0-alpha-5
Loading...
Searching...
No Matches
Command.hpp
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <functional>
8#include <optional>
9#include <string>
10
13#include "wpi/units/time.hpp"
14#include "wpi/util/SmallSet.hpp"
16
17namespace wpi::cmd {
18
19/**
20 * A state machine representing a complete action to be performed by the robot.
21 * Commands are run by the CommandScheduler, and can be composed into
22 * CommandGroups to allow users to build complicated multi-step actions without
23 * the need to roll the state machine logic themselves.
24 *
25 * <p>Commands are run synchronously from the main robot loop; no
26 * multithreading is used, unless specified explicitly from the command
27 * implementation.
28 *
29 * <p>Note: ALWAYS create a subclass by extending CommandHelper<Base, Subclass>,
30 * or decorators will not function!
31 *
32 * This class is provided by the Commands v2 VendorDep
33 *
34 * @see CommandScheduler
35 * @see CommandHelper
36 */
38 public wpi::util::SendableHelper<Command> {
39 public:
40 ~Command() override;
41
42 Command(const Command&) = default;
44 Command(Command&&) = default;
45 Command& operator=(Command&&) = default;
46
47 /**
48 * The initial subroutine of a command. Called once when the command is
49 * initially scheduled.
50 */
51 virtual void Initialize();
52
53 /**
54 * The main body of a command. Called repeatedly while the command is
55 * scheduled.
56 */
57 virtual void Execute();
58
59 /**
60 * The action to take when the command ends. Called when either the command
61 * finishes normally, or when it interrupted/canceled.
62 *
63 * @param interrupted whether the command was interrupted/canceled
64 */
65 virtual void End(bool interrupted);
66
67 /**
68 * Whether the command has finished. Once a command finishes, the scheduler
69 * will call its end() method and un-schedule it.
70 *
71 * @return whether the command has finished.
72 */
73 virtual bool IsFinished() { return false; }
74
75 /**
76 * Specifies the set of subsystems used by this command. Two commands cannot
77 * use the same subsystem at the same time. If another command is scheduled
78 * that shares a requirement, GetInterruptionBehavior() will be checked and
79 * followed. If no subsystems are required, return an empty set.
80 *
81 * <p>Note: it is recommended that user implementations contain the
82 * requirements as a field, and return that field here, rather than allocating
83 * a new set every time this is called.
84 *
85 * @return the set of subsystems that are required
86 * @see InterruptionBehavior
87 */
89
90 /**
91 * Adds the specified Subsystem requirements to the command.
92 *
93 * The scheduler will prevent two commands that require the same subsystem
94 * from being scheduled simultaneously.
95 *
96 * Note that the scheduler determines the requirements of a command when it
97 * is scheduled, so this method should normally be called from the command's
98 * constructor.
99 *
100 * While this overload can be used with {@code AddRequirements({&subsystem1,
101 * &subsystem2})}, {@code AddRequirements({&subsystem})} selects the {@code
102 * AddRequirements(Subsystem*)} overload, which will function identically but
103 * may cause warnings about redundant braces.
104 *
105 * @param requirements the Subsystem requirements to add, which can be
106 * implicitly constructed from an initializer list or a span
107 */
108 void AddRequirements(Requirements requirements);
109
110 /**
111 * Adds the specified Subsystem requirements to the command.
112 *
113 * The scheduler will prevent two commands that require the same subsystem
114 * from being scheduled simultaneously.
115 *
116 * Note that the scheduler determines the requirements of a command when it
117 * is scheduled, so this method should normally be called from the command's
118 * constructor.
119 *
120 * @param requirements the Subsystem requirements to add
121 */
123
124 /**
125 * Adds the specified Subsystem requirement to the command.
126 *
127 * The scheduler will prevent two commands that require the same subsystem
128 * from being scheduled simultaneously.
129 *
130 * Note that the scheduler determines the requirements of a command when it
131 * is scheduled, so this method should normally be called from the command's
132 * constructor.
133 *
134 * @param requirement the Subsystem requirement to add
135 */
136 void AddRequirements(Subsystem* requirement);
137
138 /**
139 * Gets the name of this Command.
140 *
141 * @return Name
142 */
143 std::string GetName() const;
144
145 /**
146 * Sets the name of this Command.
147 *
148 * @param name name
149 */
150 void SetName(std::string_view name);
151
152 /**
153 * Gets the subsystem name of this Command.
154 *
155 * @return Subsystem name
156 */
157 std::string GetSubsystem() const;
158
159 /**
160 * Sets the subsystem name of this Command.
161 *
162 * @param subsystem subsystem name
163 */
164 void SetSubsystem(std::string_view subsystem);
165
166 /**
167 * An enum describing the command's behavior when another command with a
168 * shared requirement is scheduled.
169 */
171 /**
172 * This command ends, End(true) is called, and the incoming command is
173 * scheduled normally.
174 *
175 * <p>This is the default behavior.
176 */
178 /** This command continues, and the incoming command is not scheduled. */
180 };
181
182 friend class CommandPtr;
183
184 /**
185 * Decorates this command with a timeout. If the specified timeout is
186 * exceeded before the command finishes normally, the command will be
187 * interrupted and un-scheduled.
188 *
189 * @param duration the timeout duration
190 * @return the command with the timeout added
191 */
192 CommandPtr WithTimeout(wpi::units::second_t duration) &&;
193
194 /**
195 * Decorates this command with an interrupt condition. If the specified
196 * condition becomes true before the command finishes normally, the command
197 * will be interrupted and un-scheduled.
198 *
199 * @param condition the interrupt condition
200 * @return the command with the interrupt condition added
201 */
202 CommandPtr Until(std::function<bool()> condition) &&;
203
204 /**
205 * Decorates this command with a run condition. If the specified condition
206 * becomes false before the command finishes normally, the command will be
207 * interrupted and un-scheduled.
208 *
209 * @param condition the run condition
210 * @return the command with the run condition added
211 */
212 CommandPtr OnlyWhile(std::function<bool()> condition) &&;
213
214 /**
215 * Decorates this command with a runnable to run before this command starts.
216 *
217 * @param toRun the Runnable to run
218 * @param requirements the required subsystems
219 * @return the decorated command
220 */
221 CommandPtr BeforeStarting(std::function<void()> toRun,
222 Requirements requirements = {}) &&;
223
224 /**
225 * Decorates this command with another command to run before this command
226 * starts.
227 *
228 * @param before the command to run before this one
229 * @return the decorated command
230 */
232
233 /**
234 * Decorates this command with a runnable to run after the command finishes.
235 *
236 * @param toRun the Runnable to run
237 * @param requirements the required subsystems
238 * @return the decorated command
239 */
240 CommandPtr AndThen(std::function<void()> toRun,
241 Requirements requirements = {}) &&;
242
243 /**
244 * Decorates this command with a set of commands to run after it in sequence.
245 * Often more convenient/less-verbose than constructing a
246 * SequentialCommandGroup explicitly.
247 *
248 * @param next the commands to run next
249 * @return the decorated command
250 */
252
253 /**
254 * Decorates this command to run repeatedly, restarting it when it ends, until
255 * this command is interrupted. The decorated command can still be canceled.
256 *
257 * @return the decorated command
258 */
260
261 /**
262 * Decorates this command to run "by proxy" by wrapping it in a ProxyCommand.
263 * Use this for "forking off" from command compositions when the user does not
264 * wish to extend the command's requirements to the entire command
265 * composition. ProxyCommand has unique implications and semantics, see <a
266 * href="https://docs.wpilib.org/en/stable/docs/software/commandbased/command-compositions.html#scheduling-other-commands">the
267 * WPILib docs</a> for a full explanation.
268 *
269 * <p>This overload transfers command ownership to the returned CommandPtr.
270 *
271 * @return the decorated command
272 * @see ProxyCommand
273 */
275
276 /**
277 * Decorates this command to only run if this condition is not met. If the
278 * command is already running and the condition changes to true, the command
279 * will not stop running. The requirements of this command will be kept for
280 * the new conditional command.
281 *
282 * @param condition the condition that will prevent the command from running
283 * @return the decorated command
284 */
285 CommandPtr Unless(std::function<bool()> condition) &&;
286
287 /**
288 * Decorates this command to only run if this condition is met. If the command
289 * is already running and the condition changes to false, the command will not
290 * stop running. The requirements of this command will be kept for the new
291 * conditional command.
292 *
293 * @param condition the condition that will allow the command to run
294 * @return the decorated command
295 */
296 CommandPtr OnlyIf(std::function<bool()> condition) &&;
297
298 /**
299 * Creates a new command that runs this command and the deadline in parallel,
300 * finishing (and interrupting this command) when the deadline finishes.
301 *
302 * @param deadline the deadline of the command group
303 * @return the decorated command
304 * @see DeadlineFor
305 */
307
308 /**
309 * Decorates this command with a set of commands to run parallel to it, ending
310 * when the calling command ends and interrupting all the others. Often more
311 * convenient/less-verbose than constructing a new {@link
312 * ParallelDeadlineGroup} explicitly.
313 *
314 * @param parallel the commands to run in parallel. Note the parallel commands
315 * will be interupted when the deadline command ends
316 * @return the decorated command
317 * @see WithDeadline
318 */
320
321 /**
322 * Decorates this command with a set of commands to run parallel to it, ending
323 * when the last command ends. Often more convenient/less-verbose than
324 * constructing a new {@link ParallelCommandGroup} explicitly.
325 *
326 * @param parallel the commands to run in parallel
327 * @return the decorated command
328 */
330
331 /**
332 * Decorates this command with a set of commands to run parallel to it, ending
333 * when the first command ends. Often more convenient/less-verbose than
334 * constructing a new {@link ParallelRaceGroup} explicitly.
335 *
336 * @param parallel the commands to run in parallel
337 * @return the decorated command
338 */
340
341 /**
342 * Decorates this command to run or stop when disabled.
343 *
344 * @param doesRunWhenDisabled true to run when disabled.
345 * @return the decorated command
346 */
347 CommandPtr IgnoringDisable(bool doesRunWhenDisabled) &&;
348
349 /**
350 * Decorates this command to have a different interrupt behavior.
351 *
352 * @param interruptBehavior the desired interrupt behavior
353 * @return the decorated command
354 */
356 Command::InterruptionBehavior interruptBehavior) &&;
357
358 /**
359 * Decorates this command with a lambda to call on interrupt or end, following
360 * the command's inherent Command::End(bool) method.
361 *
362 * @param end a lambda accepting a boolean parameter specifying whether the
363 * command was interrupted.
364 * @return the decorated command
365 */
366 CommandPtr FinallyDo(std::function<void(bool)> end) &&;
367
368 /**
369 * Decorates this command with a lambda to call on interrupt or end, following
370 * the command's inherent Command::End(bool) method. The provided lambda will
371 * run identically in both interrupt and end cases.
372 *
373 * @param end a lambda to run when the command ends, whether or not it was
374 * interrupted.
375 * @return the decorated command
376 */
377 CommandPtr FinallyDo(std::function<void()> end) &&;
378
379 /**
380 * Decorates this command with a lambda to call on interrupt, following the
381 * command's inherent Command::End(bool) method.
382 *
383 * @param handler a lambda to run when the command is interrupted
384 * @return the decorated command
385 */
386 CommandPtr HandleInterrupt(std::function<void()> handler) &&;
387
388 /**
389 * Decorates this Command with a name.
390 *
391 * @param name name
392 * @return the decorated Command
393 */
394 CommandPtr WithName(std::string_view name) &&;
395
396 /**
397 * Cancels this command. Will call End(true). Commands will be canceled
398 * regardless of interruption behavior.
399 */
400 void Cancel();
401
402 /**
403 * Whether or not the command is currently scheduled. Note that this does not
404 * detect whether the command is in a composition, only whether it is directly
405 * being run by the scheduler.
406 *
407 * @return Whether the command is scheduled.
408 */
409 bool IsScheduled() const;
410
411 /**
412 * Whether the command requires a given subsystem. Named "HasRequirement"
413 * rather than "requires" to avoid confusion with Command::Requires(Subsystem)
414 * -- this may be able to be changed in a few years.
415 *
416 * @param requirement the subsystem to inquire about
417 * @return whether the subsystem is required
418 */
419 bool HasRequirement(Subsystem* requirement) const;
420
421 /**
422 * Whether the command is currently grouped in a command group. Used as extra
423 * insurance to prevent accidental independent use of grouped commands.
424 */
425 bool IsComposed() const;
426
427 /**
428 * Sets whether the command is currently composed in a command composition.
429 * Can be used to "reclaim" a command if a composition is no longer going to
430 * use it. NOT ADVISED!
431 */
432 void SetComposed(bool isComposed);
433
434 /**
435 * Get the stacktrace of where this command was composed, or an empty
436 * optional. Intended for internal use.
437 *
438 * @return optional string representation of the composition site stack trace.
439 */
440 std::optional<std::string> GetPreviousCompositionSite() const;
441
442 /**
443 * Whether the given command should run when the robot is disabled. Override
444 * to return true if the command should run when disabled.
445 *
446 * @return whether the command should run when the robot is disabled
447 */
448 virtual bool RunsWhenDisabled() const { return false; }
449
450 /**
451 * How the command behaves when another command with a shared requirement is
452 * scheduled.
453 *
454 * @return a variant of InterruptionBehavior, defaulting to kCancelSelf.
455 */
459
460 /**
461 * Transfers ownership of this command to a unique pointer. Used for
462 * decorator methods.
463 */
464 virtual CommandPtr ToPtr() && = 0;
465
467
468 protected:
470
471 private:
472 /// Requirements set.
474
475 std::optional<std::string> m_previousComposition;
476};
477
478/**
479 * Checks if two commands have disjoint requirement sets.
480 *
481 * @param first The first command to check.
482 * @param second The second command to check.
483 * @return False if first and second share a requirement.
484 */
486} // namespace wpi::cmd
This file defines the SmallSet class.
@ name
Definition base.h:690
A state machine representing a complete action to be performed by the robot.
Definition Command.hpp:38
Command & operator=(const Command &rhs)
virtual bool RunsWhenDisabled() const
Whether the given command should run when the robot is disabled.
Definition Command.hpp:448
CommandPtr Unless(std::function< bool()> condition) &&
Decorates this command to only run if this condition is not met.
friend class CommandPtr
Definition Command.hpp:182
void SetComposed(bool isComposed)
Sets whether the command is currently composed in a command composition.
std::optional< std::string > GetPreviousCompositionSite() const
Get the stacktrace of where this command was composed, or an empty optional.
CommandPtr WithTimeout(wpi::units::second_t duration) &&
Decorates this command with a timeout.
CommandPtr AsProxy() &&
Decorates this command to run "by proxy" by wrapping it in a ProxyCommand.
CommandPtr BeforeStarting(std::function< void()> toRun, Requirements requirements={}) &&
Decorates this command with a runnable to run before this command starts.
CommandPtr WithInterruptBehavior(Command::InterruptionBehavior interruptBehavior) &&
Decorates this command to have a different interrupt behavior.
Command(const Command &)=default
void AddRequirements(wpi::util::SmallSet< Subsystem *, 4 > requirements)
Adds the specified Subsystem requirements to the command.
bool IsScheduled() const
Whether or not the command is currently scheduled.
bool HasRequirement(Subsystem *requirement) const
Whether the command requires a given subsystem.
bool IsComposed() const
Whether the command is currently grouped in a command group.
CommandPtr OnlyIf(std::function< bool()> condition) &&
Decorates this command to only run if this condition is met.
virtual void End(bool interrupted)
The action to take when the command ends.
CommandPtr FinallyDo(std::function< void(bool)> end) &&
Decorates this command with a lambda to call on interrupt or end, following the command's inherent Co...
std::string GetName() const
Gets the name of this Command.
InterruptionBehavior
An enum describing the command's behavior when another command with a shared requirement is scheduled...
Definition Command.hpp:170
@ kCancelSelf
This command ends, End(true) is called, and the incoming command is scheduled normally.
Definition Command.hpp:177
@ kCancelIncoming
This command continues, and the incoming command is not scheduled.
Definition Command.hpp:179
CommandPtr AndThen(CommandPtr &&next) &&
Decorates this command with a set of commands to run after it in sequence.
CommandPtr DeadlineFor(CommandPtr &&parallel) &&
Decorates this command with a set of commands to run parallel to it, ending when the calling command ...
virtual InterruptionBehavior GetInterruptionBehavior() const
How the command behaves when another command with a shared requirement is scheduled.
Definition Command.hpp:456
std::string GetSubsystem() const
Gets the subsystem name of this Command.
CommandPtr AndThen(std::function< void()> toRun, Requirements requirements={}) &&
Decorates this command with a runnable to run after the command finishes.
void Cancel()
Cancels this command.
CommandPtr RaceWith(CommandPtr &&parallel) &&
Decorates this command with a set of commands to run parallel to it, ending when the first command en...
void AddRequirements(Requirements requirements)
Adds the specified Subsystem requirements to the command.
virtual void Execute()
The main body of a command.
CommandPtr BeforeStarting(CommandPtr &&before) &&
Decorates this command with another command to run before this command starts.
CommandPtr WithName(std::string_view name) &&
Decorates this Command with a name.
void InitSendable(wpi::util::SendableBuilder &builder) override
Initializes this Sendable object.
CommandPtr AlongWith(CommandPtr &&parallel) &&
Decorates this command with a set of commands to run parallel to it, ending when the last command end...
CommandPtr WithDeadline(CommandPtr &&deadline) &&
Creates a new command that runs this command and the deadline in parallel, finishing (and interruptin...
void SetSubsystem(std::string_view subsystem)
Sets the subsystem name of this Command.
Command & operator=(Command &&)=default
virtual CommandPtr ToPtr() &&=0
Transfers ownership of this command to a unique pointer.
virtual void Initialize()
The initial subroutine of a command.
CommandPtr OnlyWhile(std::function< bool()> condition) &&
Decorates this command with a run condition.
CommandPtr HandleInterrupt(std::function< void()> handler) &&
Decorates this command with a lambda to call on interrupt, following the command's inherent Command::...
CommandPtr Repeatedly() &&
Decorates this command to run repeatedly, restarting it when it ends, until this command is interrupt...
~Command() override
void SetName(std::string_view name)
Sets the name of this Command.
CommandPtr IgnoringDisable(bool doesRunWhenDisabled) &&
Decorates this command to run or stop when disabled.
CommandPtr Until(std::function< bool()> condition) &&
Decorates this command with an interrupt condition.
Command(Command &&)=default
CommandPtr FinallyDo(std::function< void()> end) &&
Decorates this command with a lambda to call on interrupt or end, following the command's inherent Co...
virtual bool IsFinished()
Whether the command has finished.
Definition Command.hpp:73
void AddRequirements(Subsystem *requirement)
Adds the specified Subsystem requirement to the command.
virtual wpi::util::SmallSet< Subsystem *, 4 > GetRequirements() const
Specifies the set of subsystems used by this command.
Represents requirements for a command, which is a set of (pointers to) subsystems.
Definition Requirements.hpp:20
A robot subsystem.
Definition Subsystem.hpp:42
Helper class for building Sendable dashboard representations.
Definition SendableBuilder.hpp:21
A helper class for use with objects that add themselves to SendableRegistry.
Definition SendableHelper.hpp:21
Interface for Sendable objects.
Definition Sendable.hpp:16
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition SmallSet.hpp:132
Definition CommandNiDsStadiaController.hpp:15
bool RequirementsDisjoint(Command *first, Command *second)
Checks if two commands have disjoint requirement sets.