diff --git a/source/docs/software/advanced-controls/controllers/pidcontroller.rst b/source/docs/software/advanced-controls/controllers/pidcontroller.rst index 9db0a9b238..a81e735990 100644 --- a/source/docs/software/advanced-controls/controllers/pidcontroller.rst +++ b/source/docs/software/advanced-controls/controllers/pidcontroller.rst @@ -2,7 +2,7 @@ .. note:: This article focuses on in-code implementation of PID control in WPILib. For a conceptual explanation of the working of a PIDController, see :ref:`docs/software/advanced-controls/introduction/introduction-to-pid:Introduction to PID` -.. note:: For a guide on implementing PID control through the :ref:`command-based framework `, see :ref:`docs/software/commandbased/pid-subsystems-commands:PID Control in Command-based`. +.. note:: For a guide on implementing PID control through the :ref:`command-based framework `, see :ref:`docs/software/commandbased/commands-v2/pid-subsystems-commands:PID Control in Command-based`. WPILib supports PID control of mechanisms through the ``PIDController`` class ([Java](https://github.wpilib.org/allwpilib/docs/release/java/edu/wpi/first/math/controller/PIDController.html), [C++](https://github.wpilib.org/allwpilib/docs/release/cpp/classfrc_1_1_p_i_d_controller.html), :external:py:class:`Python `). This class handles the feedback loop calculation for the user, as well as offering methods for returning the error, setting tolerances, and checking if the control loop has reached its setpoint within the specified tolerances. diff --git a/source/docs/software/advanced-controls/controllers/profiled-pidcontroller.rst b/source/docs/software/advanced-controls/controllers/profiled-pidcontroller.rst index e5b67ed833..f9e14afbf2 100644 --- a/source/docs/software/advanced-controls/controllers/profiled-pidcontroller.rst +++ b/source/docs/software/advanced-controls/controllers/profiled-pidcontroller.rst @@ -1,6 +1,6 @@ # Combining Motion Profiling and PID Control with ProfiledPIDController -.. note:: For a guide on implementing the ``ProfiledPIDController`` class in the :ref:`command-based framework ` framework, see :ref:`docs/software/commandbased/profilepid-subsystems-commands:Combining Motion Profiling and PID in Command-Based`. +.. note:: For a guide on implementing the ``ProfiledPIDController`` class in the :ref:`command-based framework ` framework, see :ref:`docs/software/commandbased/commands-v2/profilepid-subsystems-commands:Combining Motion Profiling and PID in Command-Based`. In the previous article, we saw how to use the ``TrapezoidProfile`` class to create and use a trapezoidal motion profile. The example code from that article demonstrates manually composing the ``TrapezoidProfile`` class with the external PID control feature of a "smart" motor controller. diff --git a/source/docs/software/advanced-controls/controllers/trapezoidal-profiles.rst b/source/docs/software/advanced-controls/controllers/trapezoidal-profiles.rst index 50c1688337..73e32711c0 100644 --- a/source/docs/software/advanced-controls/controllers/trapezoidal-profiles.rst +++ b/source/docs/software/advanced-controls/controllers/trapezoidal-profiles.rst @@ -4,7 +4,7 @@ .. note:: This article covers the in-code generation of trapezoidal motion profiles. Documentation describing the involved concepts in more detail is forthcoming. -.. note:: For a guide on implementing the ``TrapezoidProfile`` class in the :ref:`command-based framework ` framework, see :doc:`/docs/software/commandbased/profile-subsystems-commands`. +.. note:: For a guide on implementing the ``TrapezoidProfile`` class in the :ref:`command-based framework ` framework, see :doc:`/docs/software/commandbased/commands-v2/profile-subsystems-commands`. .. note:: The ``TrapezoidProfile`` class, used on its own, is most useful when composed with a custom controller (such as a "smart" motor controller with a built-in PID functionality). To integrate it with a WPILib ``PIDController``, see :doc:`profiled-pidcontroller`. diff --git a/source/docs/software/basic-programming/functions-as-data.rst b/source/docs/software/basic-programming/functions-as-data.rst index a9dfb7823c..f74cbbbc1e 100644 --- a/source/docs/software/basic-programming/functions-as-data.rst +++ b/source/docs/software/basic-programming/functions-as-data.rst @@ -10,7 +10,7 @@ Typically, code that calls a function is coupled to (depends on) the definition For example, WPILib offers several ways for users to execute certain code whenever a joystick button is pressed - one of the easiest and cleanest ways to do this is to allow the user to *pass a function* to one of the WPILib joystick methods. This way, the user only has to write the code that deals with the interesting and team-specific things (e.g., "move my robot arm") and not the boring, error-prone, and universal thing ("properly read button inputs from a standard joystick"). -For another example, the :ref:`Command-based framework ` is built on ``Command`` objects that refer to methods defined on various ``Subsystem`` classes. Many of the included ``Command`` types (such as ``InstantCommand`` and ``RunCommand``) work with *any* function - not just functions associated with a single ``Subsystem``. To support building commands generically, we need to support passing functions from a ``Subsystem`` (which interacts with the hardware) to a ``Command`` (which interacts with the scheduler). +For another example, the :ref:`Command-based framework ` is built on ``Command`` objects that refer to methods defined on various ``Subsystem`` classes. Many of the included ``Command`` types (such as ``InstantCommand`` and ``RunCommand``) work with *any* function - not just functions associated with a single ``Subsystem``. To support building commands generically, we need to support passing functions from a ``Subsystem`` (which interacts with the hardware) to a ``Command`` (which interacts with the scheduler). In these cases, we want to be able to pass a single function as a piece of data, as if it were a variable - it doesn't make sense to ask the user to provide an entire class, when we really just want them to give us a single appropriately-shaped function. @@ -24,7 +24,7 @@ Java represents functions-as-data as instances of [functional interfaces](https: This might sound complicated, but in the context of WPILib we don't really need to worry much about using the functional interfaces themselves - the code that does that is internal to WPILib. Instead, all we need to know is how to pass a function that we've written to a method that takes a functional interface as a parameter. For a simple example, consider the signature of ``Commands.runOnce`` (which creates an ``InstantCommand`` that, when scheduled, runs the given function once and then terminates): -.. note:: The ``requirements`` parameter is explained in the :ref:`Command-based documentation `, and will not be discussed here. +.. note:: The ``requirements`` parameter is explained in the :ref:`Command-based documentation `, and will not be discussed here. ```java public static Command runOnce(Runnable action, Subsystem... requirements) ``` @@ -104,7 +104,7 @@ In WPILibC, function types are represented with the ``std::function`` class (htt This sounds a lot more complicated than it is to use in practice. Let's look at the call signature of ``cmd::RunOnce`` (which creates an ``InstantCommand`` that, when scheduled, runs the given function once and then terminates): -.. note:: The ``requirements`` parameter is explained in the :ref:`Command-based documentation `, and will not be discussed here. +.. note:: The ``requirements`` parameter is explained in the :ref:`Command-based documentation `, and will not be discussed here. ```c++ CommandPtr RunOnce( diff --git a/source/docs/software/basic-programming/joystick.rst b/source/docs/software/basic-programming/joystick.rst index d03b3326e8..ccfe704cf8 100644 --- a/source/docs/software/basic-programming/joystick.rst +++ b/source/docs/software/basic-programming/joystick.rst @@ -4,7 +4,7 @@ A joystick can be used with the Driver Station program to control the robot. Almost any "controller" that can be recognized by Windows can be used as a joystick. Joysticks are accessed using the ``GenericHID`` class. This class has three relevant subclasses for preconfigured joysticks. You may also implement your own for other controllers by extending ``GenericHID``. The first is ``Joystick`` which is useful for standard flight joysticks. The second is ``XboxController`` which works for the Xbox 360, Xbox One, or Logitech F310 (in XInput mode). Finally, the ``PS4Controller`` class is ideal for using that controller. Each axis of the controller ranges from -1 to 1. -The command based way to use the these classes is detailed in the section: :ref:`docs/software/commandbased/binding-commands-to-triggers:Binding Commands to Triggers`. +The command based way to use the these classes is detailed in the section: :ref:`docs/software/commandbased/commands-v2/binding-commands-to-triggers:Binding Commands to Triggers`. ## Driver Station Joysticks @@ -136,7 +136,7 @@ An axis can be used with ``.getRawAxis(int index)`` (if not using any of the cla ## Button Usage -.. note:: Usage such as the following is for code not using the command-based framework. For button usage in the command-based framework, see :ref:`docs/software/commandbased/binding-commands-to-triggers:Binding Commands to Triggers`. +.. note:: Usage such as the following is for code not using the command-based framework. For button usage in the command-based framework, see :ref:`docs/software/commandbased/commands-v2/binding-commands-to-triggers:Binding Commands to Triggers`. Unlike an axis, you will usually want to use the ``pressed`` and ``released`` methods to respond to button input. These will return true if the button has been activated since the last check. This is helpful for taking an action once when the event occurs but not having to continuously do it while the button is held down. diff --git a/source/docs/software/commandbased/binding-commands-to-triggers.rst b/source/docs/software/commandbased/commands-v2/binding-commands-to-triggers.rst similarity index 100% rename from source/docs/software/commandbased/binding-commands-to-triggers.rst rename to source/docs/software/commandbased/commands-v2/binding-commands-to-triggers.rst diff --git a/source/docs/software/commandbased/command-compositions.rst b/source/docs/software/commandbased/commands-v2/command-compositions.rst similarity index 99% rename from source/docs/software/commandbased/command-compositions.rst rename to source/docs/software/commandbased/commands-v2/command-compositions.rst index dab8864386..81614de750 100644 --- a/source/docs/software/commandbased/command-compositions.rst +++ b/source/docs/software/commandbased/commands-v2/command-compositions.rst @@ -327,4 +327,4 @@ Command compositions can also be written as a constructor-only subclass of the m :lines: 7- :lineno-match: -The advantages and disadvantages of this subclassing approach in comparison to others are discussed in :ref:`docs/software/commandbased/organizing-command-based:Subclassing Command Groups`. +The advantages and disadvantages of this subclassing approach in comparison to others are discussed in :ref:`docs/software/commandbased/commands-v2/organizing-command-based:Subclassing Command Groups`. diff --git a/source/docs/software/commandbased/command-scheduler.rst b/source/docs/software/commandbased/commands-v2/command-scheduler.rst similarity index 99% rename from source/docs/software/commandbased/command-scheduler.rst rename to source/docs/software/commandbased/commands-v2/command-scheduler.rst index 8810c96dce..f9e2e74d1c 100644 --- a/source/docs/software/commandbased/command-scheduler.rst +++ b/source/docs/software/commandbased/commands-v2/command-scheduler.rst @@ -19,7 +19,7 @@ To schedule a command, users call the ``schedule()`` method ([Java](https://gith This method walks through the following steps: #. Verifies that the command isn't in a composition. -#. :term:`No-op` if scheduler is disabled, command is already scheduled, or robot is disabled and command doesn't :ref:`docs/software/commandbased/commands:runsWhenDisabled`. +#. :term:`No-op` if scheduler is disabled, command is already scheduled, or robot is disabled and command doesn't :ref:`docs/software/commandbased/commands-v2/commands:runsWhenDisabled`. #. If requirements are in use: * If all conflicting commands are interruptible, cancel them. diff --git a/source/docs/software/commandbased/commands.rst b/source/docs/software/commandbased/commands-v2/commands.rst similarity index 97% rename from source/docs/software/commandbased/commands.rst rename to source/docs/software/commandbased/commands-v2/commands.rst index 9adea61d02..0368f56263 100644 --- a/source/docs/software/commandbased/commands.rst +++ b/source/docs/software/commandbased/commands-v2/commands.rst @@ -98,7 +98,7 @@ As a rule, command compositions are ``kCancelIncoming`` if all their components ## Included Command Types -The command-based library includes many pre-written command types. Through the use of :ref:`lambdas `, these commands can cover almost all use cases and teams should rarely need to write custom command classes. Many of these commands are provided via static factory functions in the ``Commands`` utility class (Java), in the ``frc2::cmd`` namespace defined in the ``Commands.h`` header (C++), or in the ``commands2.cmd`` namespace (Python). In Java and C++, classes inheriting from ``Subsystem`` also have instance methods that implicitly require ``this``. +The command-based library includes many pre-written command types. Through the use of :ref:`lambdas `, these commands can cover almost all use cases and teams should rarely need to write custom command classes. Many of these commands are provided via static factory functions in the ``Commands`` utility class (Java), in the ``frc2::cmd`` namespace defined in the ``Commands.h`` header (C++), or in the ``commands2.cmd`` namespace (Python). In Java and C++, classes inheriting from ``Subsystem`` also have instance methods that implicitly require ``this``. ### Running Actions @@ -306,7 +306,7 @@ To wait until a certain condition becomes ``true``, the library offers the ``Com There are commands for various control setups: -- ``TrapezoidProfile`` tracks a trapezoid motion profile. For more info, see :doc:`/docs/software/commandbased/profile-subsystems-commands`. +- ``TrapezoidProfile`` tracks a trapezoid motion profile. For more info, see :doc:`/docs/software/commandbased/commands-v2/profile-subsystems-commands`. - ``MecanumControllerCommand`` ([Java](https://github.wpilib.org/allwpilib/docs/release/java/edu/wpi/first/wpilibj2/command/MecanumControllerCommand.html), [C++](https://github.wpilib.org/allwpilib/docs/release/cpp/classfrc2_1_1_mecanum_controller_command.html)) is useful for controlling mecanum drivetrains. See API docs and the **MecanumControllerCommand** ([Java](https://github.com/wpilibsuite/allwpilib/tree/2027/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/mecanumcontrollercommand), [C++](https://github.com/wpilibsuite/allwpilib/tree/2027/wpilibcExamples/src/main/cpp/examples/MecanumControllerCommand)) example project for more info. diff --git a/source/docs/software/commandbased/cpp-command-discussion.rst b/source/docs/software/commandbased/commands-v2/cpp-command-discussion.rst similarity index 97% rename from source/docs/software/commandbased/cpp-command-discussion.rst rename to source/docs/software/commandbased/commands-v2/cpp-command-discussion.rst index ea6309a443..f39b85ca86 100644 --- a/source/docs/software/commandbased/cpp-command-discussion.rst +++ b/source/docs/software/commandbased/commands-v2/cpp-command-discussion.rst @@ -3,7 +3,7 @@ This article will help you understand the reasoning behind some of the decisions made in the 2020 command-based framework (such as the use of ``std::unique_ptr``, CRTP in the form of ``CommandHelper``, etc.). You do not need to understand the information within this article to use the command-based framework in your robot code. -.. note:: The model was further changed in 2023, as described :ref:`below `. +.. note:: The model was further changed in 2023, as described :ref:`below `. ## Ownership Model The old command-based framework employed the use of raw pointers, meaning that users had to use ``new`` (resulting in manual heap allocations) in their robot code. Since there was no clear indication on who owned the commands (the scheduler, the command groups, or the user themselves), it was not apparent who was supposed to take care of freeing the memory. @@ -167,7 +167,7 @@ After a few years in the new command-based framework, the recommended way to cre A significant root cause of most pain points was commands being passed by value in a non-polymorphic way. This made object slicing mistakes rather easy, and changes in composition structure could propagate type changes throughout the codebase: for example, if a ``ParallelRaceGroup`` were changed to a ``ParallelDeadlineGroup``, those type changes would propagate through the codebase. Passing around the object as a ``Command`` (as done in Java) would result in object slicing. -Additionally, various decorators weren't supported in C++ due to reasons described :ref:`above `. As long as decorators were rarely used and were mainly to reduce verbosity (where Java was more verbose than C++), this was less of a problem. Once heavy usage of decorators was recommended, this became more of an issue. +Additionally, various decorators weren't supported in C++ due to reasons described :ref:`above `. As long as decorators were rarely used and were mainly to reduce verbosity (where Java was more verbose than C++), this was less of a problem. Once heavy usage of decorators was recommended, this became more of an issue. ### ``CommandPtr`` diff --git a/source/docs/software/commandbased/diagrams/concurrent-commands.drawio.svg b/source/docs/software/commandbased/commands-v2/diagrams/concurrent-commands.drawio.svg similarity index 100% rename from source/docs/software/commandbased/diagrams/concurrent-commands.drawio.svg rename to source/docs/software/commandbased/commands-v2/diagrams/concurrent-commands.drawio.svg diff --git a/source/docs/software/commandbased/diagrams/scheduler-run-sequence.drawio.svg b/source/docs/software/commandbased/commands-v2/diagrams/scheduler-run-sequence.drawio.svg similarity index 100% rename from source/docs/software/commandbased/diagrams/scheduler-run-sequence.drawio.svg rename to source/docs/software/commandbased/commands-v2/diagrams/scheduler-run-sequence.drawio.svg diff --git a/source/docs/software/commandbased/diagrams/scheduler.drawio.svg b/source/docs/software/commandbased/commands-v2/diagrams/scheduler.drawio.svg similarity index 100% rename from source/docs/software/commandbased/diagrams/scheduler.drawio.svg rename to source/docs/software/commandbased/commands-v2/diagrams/scheduler.drawio.svg diff --git a/source/docs/software/commandbased/diagrams/subsystems-and-commands.drawio.svg b/source/docs/software/commandbased/commands-v2/diagrams/subsystems-and-commands.drawio.svg similarity index 100% rename from source/docs/software/commandbased/diagrams/subsystems-and-commands.drawio.svg rename to source/docs/software/commandbased/commands-v2/diagrams/subsystems-and-commands.drawio.svg diff --git a/source/docs/software/commandbased/commands-v2/index.rst b/source/docs/software/commandbased/commands-v2/index.rst new file mode 100644 index 0000000000..2722f86d71 --- /dev/null +++ b/source/docs/software/commandbased/commands-v2/index.rst @@ -0,0 +1,53 @@ +# Commands v2 Programming + +This sequence of articles serves as an introduction to and reference for the WPILib Commands v2 framework. + +Commands v2 is the stable, production-ready command-based framework that supports Java, C++, and Python. It uses a declarative programming style with method chaining and lambda expressions to compose robot behaviors. + +.. note:: Commands v2 will continue to be supported and maintained. Java teams may also consider :ref:`docs/software/commandbased/commands-v3/index:Commands v3 Programming`, which offers an imperative programming style with coroutines. + +For a collection of example projects using Commands v2, see :ref:`docs/software/examples-tutorials/wpilib-examples:Command-Based Examples`. + +.. toctree:: + :maxdepth: 1 + + what-is-command-based + commands + command-compositions + subsystems + binding-commands-to-triggers + structuring-command-based-project + organizing-command-based + command-scheduler + cpp-command-discussion + pid-subsystems-commands + profile-subsystems-commands + profilepid-subsystems-commands + +## Why Commands v2? + +Commands v2 is recommended for: + +- **Multi-language support**: Full support for Java, C++, and Python +- **Proven stability**: Battle-tested across thousands of FRC robots +- **Rich ecosystem**: Extensive examples, tutorials, and community resources +- **Team flexibility**: Works well for teams of all experience levels +- **Broad platform support**: Works on roboRIO, simulation, and coprocessors + +## Passing Functions As Parameters + +In order to provide a concise inline syntax, the command-based library often accepts functions as parameters of constructors, factories, and decorators. Fortunately, both Java and C++ offer users the ability to :ref:`pass functions as objects `: + +### Method References (Java) + +In Java, a reference to a function that can be passed as a parameter is called a method reference. The general syntax for a method reference is ``object::method`` or ``Class::staticMethod``. Note that no method parameters are included, since the method *itself* is passed. The method is not being called - it is being passed to another piece of code (in this case, a command) so that *that* code can call it when needed. For further information on method references, see :ref:`docs/software/basic-programming/functions-as-data:Method References`. + +### Lambda Expressions (Java) + +While method references work well for passing a function that has already been written, often it is inconvenient/wasteful to write a function solely for the purpose of sending as a method reference, if that function will never be used elsewhere. To avoid this, Java also supports a feature called "lambda expressions." A lambda expression is an inline method definition - it allows a function to be defined *inside of a parameter list*. For specifics on how to write Java lambda expressions, see :ref:`docs/software/basic-programming/functions-as-data:Lambda Expressions in Java`. + +### Lambda Expressions (C++) + +.. warning:: Due to complications in C++ semantics, capturing ``this`` in a C++ lambda can cause a null pointer exception if done from a component command of a command composition. Whenever possible, C++ users should capture relevant command members explicitly and by value. For more details, see [here](https://github.com/wpilibsuite/allwpilib/issues/3109). + +C++ lacks a close equivalent to Java method references - pointers to member functions are generally not directly usable as parameters due to the presence of the implicit ``this`` parameter. However, C++ does offer lambda expressions - in addition, the lambda expressions offered by C++ are in many ways more powerful than those in Java. For specifics on how to write C++ lambda expressions, see :ref:`docs/software/basic-programming/functions-as-data:Lambda Expressions in C++`. diff --git a/source/docs/software/commandbased/organizing-command-based.rst b/source/docs/software/commandbased/commands-v2/organizing-command-based.rst similarity index 99% rename from source/docs/software/commandbased/organizing-command-based.rst rename to source/docs/software/commandbased/commands-v2/organizing-command-based.rst index 6c4ca766b3..0111bb925f 100644 --- a/source/docs/software/commandbased/organizing-command-based.rst +++ b/source/docs/software/commandbased/commands-v2/organizing-command-based.rst @@ -68,7 +68,7 @@ Creating one ``StartEndCommand`` instance and putting it in a variable won't wor #### Instance Command Factory Methods -One way to solve this quandary is using the "factory method" design pattern: a function that returns a new object every invocation, according to some specification. Using :ref:`command composition `, a factory method can construct a complex command object with merely a few lines of code. +One way to solve this quandary is using the "factory method" design pattern: a function that returns a new object every invocation, according to some specification. Using :ref:`command composition `, a factory method can construct a complex command object with merely a few lines of code. For example, a command like the intake-running command is conceptually related to exactly one subsystem: the ``Intake``. As such, it makes sense to put a ``runIntakeCommand`` method as an instance method of the ``Intake`` class: diff --git a/source/docs/software/commandbased/pid-subsystems-commands.rst b/source/docs/software/commandbased/commands-v2/pid-subsystems-commands.rst similarity index 100% rename from source/docs/software/commandbased/pid-subsystems-commands.rst rename to source/docs/software/commandbased/commands-v2/pid-subsystems-commands.rst diff --git a/source/docs/software/commandbased/profile-subsystems-commands.rst b/source/docs/software/commandbased/commands-v2/profile-subsystems-commands.rst similarity index 100% rename from source/docs/software/commandbased/profile-subsystems-commands.rst rename to source/docs/software/commandbased/commands-v2/profile-subsystems-commands.rst diff --git a/source/docs/software/commandbased/profilepid-subsystems-commands.rst b/source/docs/software/commandbased/commands-v2/profilepid-subsystems-commands.rst similarity index 100% rename from source/docs/software/commandbased/profilepid-subsystems-commands.rst rename to source/docs/software/commandbased/commands-v2/profilepid-subsystems-commands.rst diff --git a/source/docs/software/commandbased/structuring-command-based-project.rst b/source/docs/software/commandbased/commands-v2/structuring-command-based-project.rst similarity index 100% rename from source/docs/software/commandbased/structuring-command-based-project.rst rename to source/docs/software/commandbased/commands-v2/structuring-command-based-project.rst diff --git a/source/docs/software/commandbased/subsystems.rst b/source/docs/software/commandbased/commands-v2/subsystems.rst similarity index 95% rename from source/docs/software/commandbased/subsystems.rst rename to source/docs/software/commandbased/commands-v2/subsystems.rst index c20ca97bc4..7ad089738c 100644 --- a/source/docs/software/commandbased/subsystems.rst +++ b/source/docs/software/commandbased/commands-v2/subsystems.rst @@ -2,7 +2,7 @@ Subsystems are the basic unit of robot organization in the command-based paradigm. A subsystem is an abstraction for a collection of robot hardware that *operates together as a unit*. Subsystems form an :term:`encapsulation` for this hardware, "hiding" it from the rest of the robot code and restricting access to it except through the subsystem’s public methods. Restricting the access in this way provides a single convenient place for code that might otherwise be duplicated in multiple places (such as scaling motor outputs or checking limit switches) if the subsystem internals were exposed. It also allows changes to the specific details of how the subsystem works (the "implementation") to be isolated from the rest of robot code, making it far easier to make substantial changes if/when the design constraints change. -Subsystems also serve as the backbone of the ``CommandScheduler``\ ’s resource management system. Commands may declare resource requirements by specifying which subsystems they interact with; the scheduler will never concurrently schedule more than one command that requires a given subsystem. An attempt to schedule a command that requires a subsystem that is already-in-use will either interrupt the currently-running command or be ignored, based on the running command's :ref:`Interruption Behavior `. +Subsystems also serve as the backbone of the ``CommandScheduler``\ 's resource management system. Commands may declare resource requirements by specifying which subsystems they interact with; the scheduler will never concurrently schedule more than one command that requires a given subsystem. An attempt to schedule a command that requires a subsystem that is already-in-use will either interrupt the currently-running command or be ignored, based on the running command's :ref:`Interruption Behavior `. Subsystems can be associated with "default commands" that will be automatically scheduled when no other command is currently using the subsystem. This is useful for "background" actions such as controlling the robot drive, keeping an arm held at a setpoint, or stopping motors when the subsystem isn't used. Similar functionality can be achieved in the subsystem’s ``periodic()`` method, which is run once per run of the scheduler; teams should try to be consistent within their codebase about which functionality is achieved through either of these methods. Subsystems are represented in the command-based library by the ``Subsystem`` interface ([Java](https://github.wpilib.org/allwpilib/docs/release/java/edu/wpi/first/wpilibj2/command/Subsystem.html), [C++](https://github.wpilib.org/allwpilib/docs/release/cpp/classfrc2_1_1_subsystem.html), :external:py:class:`Python `). @@ -144,7 +144,7 @@ Alternatively, instead of writing ``void`` public methods that are called from c Note the qualification of the ``RunOnce`` factory used here: this isn't the static factory in ``Commands``! Subsystems have similar instance factories that return commands requiring ``this`` (Java/C++) or ``self`` (Python) subsystem. Here, the ``Subsystem.runOnce(Runnable)`` factory ([Java](https://github.wpilib.org/allwpilib/docs/release/java/edu/wpi/first/wpilibj2/command/Subsystem.html#runOnce(java.lang.Runnable)), [C++](https://github.wpilib.org/allwpilib/docs/release/cpp/classfrc2_1_1_subsystem.html#a6b8b3b7dab6f54fb8635e335dad448fe), :external:py:meth:`Python `) is used. -For a comparison between these options, see :ref:`docs/software/commandbased/organizing-command-based:Instance Command Factory Methods`. +For a comparison between these options, see :ref:`docs/software/commandbased/commands-v2/organizing-command-based:Instance Command Factory Methods`. ## Periodic diff --git a/source/docs/software/commandbased/what-is-command-based.rst b/source/docs/software/commandbased/commands-v2/what-is-command-based.rst similarity index 96% rename from source/docs/software/commandbased/what-is-command-based.rst rename to source/docs/software/commandbased/commands-v2/what-is-command-based.rst index e7c4f6f151..65a87a1e2a 100644 --- a/source/docs/software/commandbased/what-is-command-based.rst +++ b/source/docs/software/commandbased/commands-v2/what-is-command-based.rst @@ -4,7 +4,7 @@ WPILib supports a robot programming methodology called "command-based" programmi "Command-based" programming is one possible :term:`design pattern` for robot software. It is not the only way to write a robot program, but it is a very effective one. Command-based robot code tends to be clean, extensible, and (with some tricks) easy to reuse from year to year. -The command-based paradigm is also an example of :term:`declarative programming`. The command-based library allow users to define desired robot behaviors while minimizing the amount of iteration-by-iteration robot logic that they must write. For example, in the command-based program, a user can specify that "the robot should perform an action when a condition is true" (note the use of a :ref:`lambda `): +The command-based paradigm is also an example of :term:`declarative programming`. The command-based library allow users to define desired robot behaviors while minimizing the amount of iteration-by-iteration robot logic that they must write. For example, in the command-based program, a user can specify that "the robot should perform an action when a condition is true" (note the use of a :ref:`lambda `): .. tab-set-code:: @@ -62,7 +62,7 @@ In contrast, without using command-based, the user would need to check the butto The command-based pattern is based around two core abstractions: **commands**, and **subsystems.** -**Commands** represent actions the robot can take. Commands run when scheduled, until they are interrupted or their end condition is met. Commands are very recursively composable: commands can be composed to accomplish more-complicated tasks. See :ref:`docs/software/commandbased/commands:Commands` for more info. +**Commands** represent actions the robot can take. Commands run when scheduled, until they are interrupted or their end condition is met. Commands are very recursively composable: commands can be composed to accomplish more-complicated tasks. See :ref:`docs/software/commandbased/commands-v2/commands:Commands` for more info. **Subsystems** represent independently-controlled collections of robot hardware (such as motor controllers, sensors, pneumatic actuators, etc.) that operate together. Subsystems back the resource-management system of command-based: only one command can use a given subsystem at the same time. Subsystems allow users to "hide" the internal complexity of their actual hardware from the rest of their code - this both simplifies the rest of the robot code, and allows changes to the internal details of a subsystem's hardware without also changing the rest of the robot code. diff --git a/source/docs/software/commandbased/commands-v3/advanced-topics.rst b/source/docs/software/commandbased/commands-v3/advanced-topics.rst new file mode 100644 index 0000000000..fc04c04ce4 --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/advanced-topics.rst @@ -0,0 +1,70 @@ +# Advanced Topics + +.. todo:: + This article covers advanced patterns, optimizations, and edge cases in Commands v3. This content is for experienced teams who have mastered the basics and want to push v3 to its limits or handle unusual requirements. + +## Custom Command Base Classes + +.. todo:: + Explain how and when to create custom base classes for commands. Cover: + - When custom base classes are useful vs. unnecessary abstraction + - Creating abstract command base classes with common functionality + - Decorator pattern for command functionality + - Wrapping commands to add cross-cutting concerns + - Best practices for base class design + - Examples of useful base class patterns (describe scenarios, not full implementations) + +## Dynamic Command Generation + +.. todo:: + Explain patterns for generating commands dynamically at runtime. Cover: + - When dynamic command generation is needed + - Creating commands from parameters/configuration + - Path planning and generated trajectories as commands + - Loading command sequences from files or network + - Command builders and fluent APIs + - Performance considerations for dynamic generation + - Memory management for dynamically created commands + - Examples of dynamic generation scenarios + +## Performance Optimization + +.. todo:: + Provide guidance on optimizing v3 command performance. Cover: + - Understanding scheduler overhead + - Minimizing allocations in command execution + - Efficient trigger condition evaluation + - Optimizing periodic operations + - Profiling v3 command code + - Trade-offs between readability and performance + - When optimization matters vs. premature optimization + - Benchmarking techniques + +## Advanced Async Patterns + +.. todo:: + Showcase advanced patterns using async/await and coroutines. Cover: + - Command pipelines and streaming patterns + - State machines implemented with async/await + - Error handling and recovery with async commands + - Cancellation and timeout patterns + - Resource pooling and management + - Coordinating multiple mechanisms with complex dependencies + - Real-time responsive commands with background processing + - Describe complex scenarios and how to implement them with v3 features + +## Edge Cases and Gotchas + +.. todo:: + Document edge cases, limitations, and common pitfalls. Cover: + - Commands that never yield (infinite loops without yield) + - Forked commands and lifecycle management + - Nested trigger scopes and cleanup + - Priority conflicts and circular dependencies + - Requirements conflicts with complex command compositions + - Thread safety considerations (if any) + - Limitations of the coroutine model + - Breaking scheduler assumptions + - Memory leaks and resource exhaustion + - Common mistakes and how to avoid them + - What NOT to do in v3 commands diff --git a/source/docs/software/commandbased/commands-v3/async-await-patterns.rst b/source/docs/software/commandbased/commands-v3/async-await-patterns.rst new file mode 100644 index 0000000000..af0d99b8dc --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/async-await-patterns.rst @@ -0,0 +1,76 @@ +# Async/Await Patterns + +.. todo:: + This article explains the async/await helper functions that enable advanced command orchestration in v3. These functions allow commands to launch other commands and wait for them to complete, enabling powerful composition patterns. Teams should understand basic command creation before reading this article. + +## Introduction to Async/Await + +.. todo:: + Provide an overview of async/await in Commands v3. Cover: + - What async/await means in the context of v3 (not OS-level async) + - Why async/await is useful for command orchestration + - How async/await differs from composition groups + - When to use async/await vs. other patterns + - High-level mental model for how it works with the scheduler + - Relationship to coroutines and yield() + +## await() + +.. todo:: + Explain the await() function in detail. Cover: + - What await(command) does: schedule a command and wait for it to complete + - How await() blocks the calling command until the child completes + - Requirements and priority handling with awaited commands + - What happens if the awaited command is interrupted + - What happens if the parent command is interrupted + - Return values and status from awaited commands + - Examples of await() patterns (describe what examples should show) + +## awaitAll() + +.. todo:: + Explain the awaitAll() function in detail. Cover: + - What awaitAll(commands) does: wait for multiple commands in parallel + - How awaitAll() differs from await() in a loop + - When all commands must complete vs. early termination scenarios + - Requirements management across multiple parallel commands + - Error and interruption handling + - Performance implications of parallel execution + - Examples of awaitAll() patterns (describe what examples should show) + +## awaitAny() + +.. todo:: + Explain the awaitAny() function in detail. Cover: + - What awaitAny(commands) does: wait until any command completes + - Race condition semantics: which command "wins" + - What happens to other commands when one completes + - Use cases for awaitAny() (timeouts, alternative paths, etc.) + - How interruption is handled + - Differences from race groups in composition + - Examples of awaitAny() patterns (describe what examples should show) + +## fork() + +.. todo:: + Explain the fork() function in detail. Cover: + - What fork(command) does: launch a command without waiting for it + - "Fire and forget" semantics + - When to use fork() vs. await() + - Lifecycle of forked commands relative to parent + - Requirements and priority considerations + - Common use cases (background operations, side effects, etc.) + - Potential pitfalls and how to avoid them + - Examples of fork() patterns (describe what examples should show) + +## Practical Patterns + +.. todo:: + Showcase common practical patterns combining async/await functions. Cover: + - Timeout patterns using awaitAny() with wait() + - Sequential operations with conditional logic + - Parallel operations with synchronization points + - Launching background tasks with fork() + - Complex state machines using async/await + - Error recovery and fallback patterns + - Describe several real-world scenarios and which async/await functions to combine diff --git a/source/docs/software/commandbased/commands-v3/binding-commands-to-triggers.rst b/source/docs/software/commandbased/commands-v3/binding-commands-to-triggers.rst new file mode 100644 index 0000000000..6b8df546c5 --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/binding-commands-to-triggers.rst @@ -0,0 +1,78 @@ +# Binding Commands to Triggers + +.. todo:: + This article explains how to connect commands to button inputs and other events using the trigger system. Triggers are how robot code responds to driver input and sensor events. This is essential knowledge for any team using Commands v3. + +## Triggers Overview + +.. todo:: + Provide an overview of the trigger system in v3. Cover: + - What triggers are and their role in the command framework + - How triggers differ from directly calling command.schedule() + - When trigger bindings are evaluated by the scheduler + - Available trigger sources (buttons, joysticks, sensors, custom) + - High-level syntax for creating and binding triggers + - How v3 triggers compare to v2 triggers + +## Button Bindings + +.. todo:: + Explain how to bind commands to physical buttons. Cover: + - Accessing button triggers from controllers/joysticks + - Available binding methods: onTrue(), onFalse(), whileTrue(), whileFalse(), toggleOnTrue(), etc. + - When each binding type activates and deactivates commands + - Multiple bindings on the same button + - Button composition (modifier keys, button combinations) + - Best practices for organizing button bindings in RobotContainer + - Examples of common button binding patterns (describe what examples should show) + +## Creating Custom Triggers + +.. todo:: + Explain how to create custom triggers beyond simple buttons. Cover: + - Creating triggers from boolean supplier functions + - Sensor-based triggers (limit switches, photoelectric sensors, etc.) + - State-based triggers (robot state, game piece detection, etc.) + - Time-based triggers + - Network table triggers + - Performance considerations for trigger condition functions + - Best practices for custom trigger implementation + - Examples of custom trigger patterns (describe what examples should show) + +## Trigger Composition + +.. todo:: + Explain how to compose triggers using logical operations. Cover: + - Available composition operations: and(), or(), negate() + - Creating complex trigger conditions from simple ones + - Debouncing triggers + - Edge detection (rising/falling edges) + - Trigger filtering and transformation + - When composition is evaluated + - Examples of trigger composition patterns (describe what examples should show) + +## Inner Trigger Scopes + +.. todo:: + Explain inner trigger scopes for command-local bindings. Cover: + - What inner trigger scopes are and when to use them + - How to create an inner scope within a command + - Lifecycle of inner scope bindings (when they're active) + - Use cases: responding to events during command execution + - How inner scopes interact with command interruption + - Cleanup of inner scope bindings + - Differences from global trigger bindings + - Examples of inner scope patterns (describe what examples should show) + +## Practical Patterns + +.. todo:: + Showcase common practical patterns for trigger usage. Cover: + - Organizing bindings in RobotContainer + - Driver control schemes (tank drive, arcade drive, split stick, etc.) + - Operator control panels and button boxes + - Mode switching and control profiles + - Cancellation buttons and emergency stops + - Trigger-based autonomous selection + - Testing and debugging trigger bindings + - Describe several real-world scenarios and recommended trigger patterns diff --git a/source/docs/software/commandbased/commands-v3/command-compositions.rst b/source/docs/software/commandbased/commands-v3/command-compositions.rst new file mode 100644 index 0000000000..78652335ce --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/command-compositions.rst @@ -0,0 +1,90 @@ +# Command Compositions + +.. todo:: + This article covers the traditional command composition groups that allow combining multiple commands into more complex behaviors. While v3 emphasizes async/await patterns, composition groups are still important and useful in many scenarios. This article should help teams understand when to use compositions vs. async/await. + +## Composition Overview + +.. todo:: + Provide an overview of command composition in v3. Cover: + - What command compositions are and why they exist + - How compositions differ from async/await patterns + - When to use compositions vs. async/await + - Available composition types in v3 + - How v3 compositions compare to v2 command groups + - General syntax and usage patterns + +## Sequence Groups + +.. todo:: + Explain sequence command groups in detail. Cover: + - What sequence groups do: run commands one after another + - How to create a sequence group + - When commands transition in the sequence + - What happens if a command in the sequence is interrupted + - Requirements aggregation across sequence members + - Common use cases for sequences + - Comparison to using await() in a coroutine + - Examples of sequence group patterns (describe what examples should show) + +## Parallel Groups + +.. todo:: + Explain parallel command groups in detail. Cover: + - What parallel groups do: run multiple commands simultaneously + - How to create a parallel group + - When the parallel group completes (all commands finish) + - Requirements handling with overlapping requirements + - What happens if one command is interrupted + - Common use cases for parallel groups + - Comparison to using awaitAll() in a coroutine + - Examples of parallel group patterns (describe what examples should show) + +## Race Groups + +.. todo:: + Explain race command groups in detail. Cover: + - What race groups do: run commands in parallel until one finishes + - How to create a race group + - When the race group completes (first command finishes) + - What happens to other commands when one finishes + - Common use cases for race groups (timeouts, alternatives) + - Comparison to using awaitAny() in a coroutine + - Examples of race group patterns (describe what examples should show) + +## Deadline Groups + +.. todo:: + Explain deadline command groups in detail. Cover: + - What deadline groups do: run commands with one as a "deadline" + - How to create a deadline group and specify the deadline command + - When the deadline group completes + - Differences between deadline command and other commands + - Common use cases for deadline groups + - How to achieve similar behavior with async/await + - Examples of deadline group patterns (describe what examples should show) + +## Repeating and Looping + +.. todo:: + Explain repeating and looping command patterns. Cover: + - Available repeat/loop composition functions + - Infinite repeats vs. counted repeats + - When the loop terminates + - How interruption affects repeated commands + - Performance implications of repeated compositions + - Common use cases for repeating commands + - Comparison to using yield() loops in coroutines + - Examples of repeat patterns (describe what examples should show) + +## Conditional Groups + +.. todo:: + Explain conditional command execution patterns. Cover: + - Available conditional composition functions (if/else-style branching) + - How conditions are evaluated + - When condition evaluation happens (command creation vs. execution) + - Proxy commands and deferred command selection + - Common use cases for conditional groups + - Comparison to using if/else in coroutines + - Examples of conditional patterns (describe what examples should show) diff --git a/source/docs/software/commandbased/commands-v3/commands-and-coroutines.rst b/source/docs/software/commandbased/commands-v3/commands-and-coroutines.rst new file mode 100644 index 0000000000..b0b5178c22 --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/commands-and-coroutines.rst @@ -0,0 +1,84 @@ +# Commands and Coroutines + +.. todo:: + This article covers the core of Commands v3: creating commands using the coroutine API. It explains the fundamental building blocks of command creation, the coroutine control flow primitives, and how command lifecycle works. This should be one of the first articles teams read when learning v3. + +## Command Creation Patterns + +.. todo:: + Describe the different ways to create commands in v3. Cover: + - Basic command creation using coroutine functions + - Inline vs. named command functions + - Commands as methods on Mechanism classes (factories) + - Commands as standalone functions in command files + - Lambda/anonymous command functions + - When to use each pattern + - Code examples showing syntax for each approach (structure only, not full implementations) + +## The Coroutine API + +.. todo:: + Provide an overview of what coroutines are and how v3 uses them. Cover: + - High-level explanation of coroutines for teams unfamiliar with the concept + - How coroutines enable sequential command logic without state machines + - The generator/yield paradigm + - How the scheduler executes coroutine commands + - Comparison to v2's initialize/execute/end/isFinished pattern + - Benefits of the coroutine approach + +## yield() + +.. todo:: + Explain the yield() primitive in detail. Cover: + - What yield() does: pause execution and resume next cycle + - When to use yield() vs. other control flow primitives + - How yield() relates to the scheduler loop timing + - Common patterns using yield() (e.g., running for multiple cycles) + - Performance implications + - Examples of yield() usage patterns (describe what examples should show) + +## park() + +.. todo:: + Explain the park() primitive in detail. Cover: + - What park() does: pause indefinitely until command is interrupted + - When to use park() (e.g., commands that should run until interrupted) + - How park() differs from yield() in a loop + - Interaction with command interruption and priorities + - Common use cases for park() + - Examples of park() usage patterns (describe what examples should show) + +## wait()/waitUntil() + +.. todo:: + Explain the wait() and waitUntil() primitives. Cover: + - wait(duration): pause for a specific time period + - waitUntil(condition): pause until a condition becomes true + - How these differ from yield() loops + - Timeout behavior and edge cases + - Best practices for conditions in waitUntil() + - Performance and timing accuracy considerations + - Examples of wait/waitUntil patterns (describe what examples should show) + +## Command Lifecycle + +.. todo:: + Describe the lifecycle of a command from creation to completion. Cover: + - When a command is created vs. when it starts executing + - The execution cycle: initialization, periodic execution, ending + - How coroutines map to the lifecycle phases + - What happens when a command completes normally + - What happens when a command is interrupted + - Cleanup and resource management + - How lifecycle differs from v2 commands + +## Command Properties + +.. todo:: + Explain the various properties that can be set on commands. Cover: + - How to set command properties (method chaining, decorators, etc.) + - Available properties: name, priority, interruptible, runsWhenDisabled, etc. + - When properties are evaluated vs. applied + - How properties affect scheduler behavior + - Best practices for setting properties + - Where properties should be set (factory vs. call site) diff --git a/source/docs/software/commandbased/commands-v3/getting-started.rst b/source/docs/software/commandbased/commands-v3/getting-started.rst new file mode 100644 index 0000000000..6c6371ae43 --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/getting-started.rst @@ -0,0 +1,135 @@ +# Getting Started with Commands v3 + +.. todo:: This article provides a hands-on tutorial for writing your first Commands v3 robot program. + +## Prerequisites + +.. todo:: + - Java 21+ requirement (for Continuation API support) + - WPILib 2027+ installation + - Basic Java knowledge (variables, methods, loops) + - No prior command-based experience required (but helpful) + +## Project Setup + +.. todo:: + **Creating a New Project:** + - Use WPILib VS Code project creator + - Select "Command Robot (v3)" template + - Project structure overview (Robot.java, RobotContainer.java, etc.) + + **Migrating Existing Project:** + - Point to migration guide for v2 → v3 + - Package imports change: ``org.wpilib.commands3`` not ``commands2`` + - Cannot mix v2 and v3 in same project + +## Setting Up the Scheduler + +.. todo:: + **Robot.java Configuration:** + - Import ``org.wpilib.commands3.Scheduler`` + - Call ``Scheduler.getDefault().run()`` in ``robotPeriodic()`` + - Why this must run every 20ms + - Single-threaded requirement warning + + **Example RLI:** + - Complete Robot.java from a wpilibjExamples project + - Show minimal setup with scheduler call + +## Creating Your First Mechanism + +.. todo:: + **What is a Mechanism:** + - Hardware grouping (motors, sensors, actuators that work together) + - Acts as exclusive resource for commands + - Replaces v2's Subsystem concept + + **Drivetrain Example:** + - Extend ``Mechanism`` base class + - Constructor: initialize hardware + - Private methods for hardware control (``tank()``, ``arcade()``, ``stop()``) + - Public methods for sensor reading (``getDistance()``, ``getHeading()``) + - Setting a default command for idle behavior + + **Example RLI:** + - Simple Drivetrain mechanism from wpilibjExamples + - Show hardware encapsulation pattern + - Default command for stopping motors when idle + +## Writing Your First Command + +.. todo:: + **Drive For Distance Example:** + - Use ``mechanism.run()`` factory method + - Command body receives ``Coroutine`` parameter + - Sequential steps: reset encoders → loop until target → stop + - **Critical:** ``coroutine.yield()`` inside the loop + - Naming the command with ``.named()`` + + **Understanding yield():** + - Pauses command execution + - Allows scheduler to run other commands + - Command resumes on next cycle + - What happens if you forget it (robot freeze) + + **Example RLI:** + - Drive for distance command + - Drive for time command + - Turn to angle command + +## Scheduling Commands + +.. todo:: + **Manual Scheduling:** + - ``Scheduler.schedule(command)`` + - When to use manual scheduling (autonomous, testing) + + **Button Bindings:** + - Quick preview (detailed in triggers article) + - ``CommandXboxController`` usage + - ``button.onTrue(command)`` pattern + + **Example RLI:** + - RobotContainer with button bindings + - Autonomous command scheduling + +## Testing Your First Command + +.. todo:: + **Using Driver Station:** + - Enable teleop mode + - Trigger command with button + - Observe robot behavior + - Check console output for command status + + **Dashboard Monitoring:** + - Glass/Shuffleboard command widgets + - Viewing running commands + - Command status indicators + +## Common Mistakes and Fixes + +.. todo:: + **Forgetting yield():** + - Symptom: robot freezes, becomes unresponsive + - Fix: add ``coroutine.yield()`` in every loop + + **Using v2 and v3 together:** + - Symptom: import errors, scheduler conflicts + - Fix: choose one framework per project + + **Calling yield() in synchronized blocks:** + - Symptom: exceptions, deadlocks + - Fix: restructure code to avoid locks or use different synchronization + + **Wrong package imports:** + - Symptom: cannot find Mechanism, Coroutine classes + - Fix: use ``org.wpilib.commands3`` not ``commands2`` + +## Next Steps + +.. todo:: + - Link to Mechanisms article for deeper dive + - Link to Commands and Coroutines for full API reference + - Link to Async/Await Patterns for advanced orchestration + - Link to Binding Commands to Triggers for full control setup diff --git a/source/docs/software/commandbased/commands-v3/index.rst b/source/docs/software/commandbased/commands-v3/index.rst new file mode 100644 index 0000000000..bf937afad4 --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/index.rst @@ -0,0 +1,110 @@ +# Commands v3 Programming + +.. note:: Commands v3 is currently in development for the 2027 season. This documentation is a work in progress. + +This section serves as an introduction to and reference for the WPILib Commands v3 framework. + +Commands v3 is the next-generation command-based framework for Java that introduces imperative-style command writing using coroutines. Instead of building complex chains of lambda expressions and decorators, you can write command logic as straightforward sequential code with loops, conditionals, and explicit control flow. + +**WPILib recommends Commands v3 for Java teams starting in 2027.** Commands v3 is actively being developed with new features including improved telemetry, enhanced trigger functionality, and priority-based interruption. + +.. warning:: + Commands v3 is **Java-only** and does not support C++ or Python. + +.. note:: + **Single-Threaded Requirement**: The Commands v3 scheduler must run on a single thread. Call ``Scheduler.getDefault().run()`` from ``robotPeriodic()`` as usual, but do not use the scheduler from virtual threads or other threads. + +## Should You Use Commands v3? + +**Use Commands v3 if:** + +- You're a Java team +- You want improved telemetry, enhanced triggers, and priority-based interruption +- You prefer imperative control flow (loops, if-statements) over declarative composition +- You're starting fresh or ready to migrate for the 2027 season + +**Stick with Commands v2 if:** + +- You need C++ or Python support +- Your team isn't ready to migrate yet +- You have significant existing v2 code that works well + +.. note:: + Commands v2 will continue to be maintained, but new features and improvements are focused on v3. + +See :ref:`docs/software/commandbased/commands-v2/index:Commands v2 Programming` for the v2 documentation. + +## Documentation Contents + +.. toctree:: + :maxdepth: 1 + + what-is-commands-v3 + getting-started + mechanisms + commands-and-coroutines + async-await-patterns + command-compositions + binding-commands-to-triggers + priorities-and-interrupts + structuring-v3-project + testing-and-simulation + telemetry-and-debugging + migration-from-v2 + advanced-topics + +## Quick Example + +Here's a simple "drive for distance" command written in Commands v3 style: + +.. code-block:: java + + Command driveTenFeet = drivetrain + .run(coroutine -> { + drivetrain.resetEncoders(); + while (drivetrain.getDistanceMeters() < 3.048) { + drivetrain.tank(0.5, 0.5); + coroutine.yield(); // Let scheduler run other commands + } + drivetrain.stop(); + }) + .named("Drive 10 ft"); + +Compare this to the equivalent v2 style which requires chaining multiple decorators and command groups to achieve the same sequential logic. + +## What's New in v3? + +- **Imperative command bodies**: Write commands as sequential code using ``Coroutine`` objects +- **Mechanisms replace Subsystems**: Similar concept with refined API and naming +- **Command priorities**: Fine-grained interrupt control beyond simple "interrupt or reject" +- **Async/await helpers**: ``await()``, ``awaitAll()``, ``awaitAny()``, ``fork()`` for orchestrating multiple commands +- **Explicit naming**: Commands require names for better debugging and dashboard visibility +- **Cooperative yielding**: Use ``coroutine.yield()`` to pause and let the scheduler run other commands +- **Enhanced telemetry**: Per-instance command tracking with performance metrics + +## Core Concepts + +### Mechanisms + +Mechanisms (like v2 Subsystems) represent robot hardware groupings and act as exclusive resources. Only one command can require a mechanism at a time. See :ref:`docs/software/commandbased/commands-v3/mechanisms:Mechanisms` for details. + +### Coroutines + +Coroutines enable cooperative multitasking. When you write a command body, you receive a ``Coroutine`` object that provides: + +- ``yield()``: Pause and let the scheduler run other commands +- ``await(command)``: Schedule another command and wait for it to finish +- ``wait(time)`` and ``waitUntil(condition)``: Delay or block on conditions +- ``park()``: Pause forever until canceled or interrupted + +See :ref:`docs/software/commandbased/commands-v3/commands-and-coroutines:Commands and Coroutines` for a deep dive. + +### Priorities + +Commands have priority levels. When a new command conflicts with a running command, it only starts if it has equal or higher priority. This provides more control than v2's simple "interrupt or reject" model. See :ref:`docs/software/commandbased/commands-v3/priorities-and-interrupts:Priorities and Interrupts`. + +## Getting Started + +Start with :ref:`docs/software/commandbased/commands-v3/getting-started:Getting Started with Commands v3` for a hands-on introduction. + +If you're migrating from Commands v2, see :ref:`docs/software/commandbased/commands-v3/migration-from-v2:Migrating from Commands v2 to v3`. diff --git a/source/docs/software/commandbased/commands-v3/mechanisms.rst b/source/docs/software/commandbased/commands-v3/mechanisms.rst new file mode 100644 index 0000000000..e3063004c8 --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/mechanisms.rst @@ -0,0 +1,70 @@ +# Mechanisms + +.. todo:: + This article provides a comprehensive guide to Mechanisms, the v3 replacement for Subsystems. It explains the philosophy behind Mechanisms, how to create them, best practices for encapsulation, and how they interact with the command system. The focus should be on teaching teams how to properly structure robot hardware abstractions in v3. + +## Creating Mechanisms + +.. todo:: + Describe how to create a Mechanism class. Cover: + - Basic Mechanism class structure and constructor + - How Mechanisms differ philosophically from v2 Subsystems + - When to create a Mechanism vs. other organizational patterns + - Naming conventions for Mechanism classes + - Where Mechanism classes should live in the project structure + - How to register Mechanisms with the command scheduler (if needed) + +## Encapsulation Best Practices + +.. todo:: + Explain encapsulation principles for Mechanisms. Cover: + - What hardware and state should be encapsulated within a Mechanism + - Public API design: what methods should be exposed vs. kept private + - How to avoid leaking implementation details + - Sensor data processing and filtering within Mechanisms + - State management and validation + - Examples of good vs. bad encapsulation patterns + +## Default Commands + +.. todo:: + Explain how default commands work with Mechanisms. Cover: + - What default commands are and when to use them + - How to set a default command for a Mechanism + - Lifecycle of default commands (when they start/stop) + - Common use cases (idle states, teleoperated control, etc.) + - How default commands interact with other commands requiring the same Mechanism + - Best practices for implementing default command behavior + +## Periodic Updates + +.. todo:: + Describe periodic update patterns in Mechanisms. Cover: + - Whether Mechanisms have a periodic() method like v2 Subsystems + - If not, how to handle periodic updates in v3 + - When to use periodic updates vs. command-based updates + - Performance considerations for periodic operations + - Common patterns like updating telemetry, processing sensor data, safety checks + +## Command Factories + +.. todo:: + Explain the command factory pattern for Mechanisms. Cover: + - What command factories are and why they're useful + - How to create factory methods on Mechanism classes + - Naming conventions for factory methods + - Benefits: encapsulation, reusability, readability + - How factories interact with requirements management + - Examples of simple and complex command factories + - When to use factories vs. standalone command classes + +## Requirements Management + +.. todo:: + Describe how Mechanisms interact with the requirements system. Cover: + - How commands declare they require a Mechanism + - What happens when multiple commands require the same Mechanism + - How the scheduler resolves requirement conflicts + - Relationship between requirements and the priority system + - Best practices for designing Mechanism APIs to work well with requirements + - Common pitfalls and how to avoid them diff --git a/source/docs/software/commandbased/commands-v3/migration-from-v2.rst b/source/docs/software/commandbased/commands-v3/migration-from-v2.rst new file mode 100644 index 0000000000..6ddfedf28b --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/migration-from-v2.rst @@ -0,0 +1,85 @@ +# Migrating from Commands v2 to v3 + +.. todo:: + This article guides teams through migrating an existing Commands v2 codebase to v3. Migration can be done incrementally, and this article should help teams plan their migration strategy, understand the key differences, and avoid common pitfalls. This is a critical resource for established teams. + +## Migration Strategy + +.. todo:: + Provide high-level guidance on planning a v2-to-v3 migration. Cover: + - Should teams migrate? (pros/cons, when to migrate vs. stay on v2) + - Migration approaches: full rewrite vs. incremental migration + - Incremental migration: v2 and v3 can coexist in the same project + - What to migrate first (start with simple mechanisms/commands) + - Testing strategy during migration + - Timeline considerations (offseason vs. competition season) + - Team training and learning curve + - Recommended migration phases + +## Package Changes + +.. todo:: + Document package and import changes between v2 and v3. Cover: + - New v3 package names and locations + - Renamed classes and methods + - Deprecated v2 APIs and their v3 equivalents + - How to add v3 dependencies to build.gradle/pom.xml + - Version compatibility and requirements + - Vendor library compatibility with v3 + +## Concept Mapping + +.. todo:: + Map v2 concepts to their v3 equivalents. Cover: + - Subsystem → Mechanism (concepts and naming) + - Command classes → Coroutine functions + - CommandBase methods (initialize, execute, end, isFinished) → Coroutine flow + - Command groups → Composition functions and async/await + - Sequential/Parallel/Race groups → v3 equivalents + - Trigger bindings (changes in API) + - Requirements → v3 requirements system + - Default commands → v3 default commands + - What's new in v3 that has no v2 equivalent (priorities, fork, etc.) + +## Common Migration Patterns + +.. todo:: + Provide concrete patterns for migrating common v2 code. Cover: + - Converting a simple Subsystem to a Mechanism + - Converting a simple Command to a coroutine command + - Converting a command group to a sequence/composition + - Converting a command group to async/await + - Converting trigger bindings + - Converting autonomous command groups + - Migrating default commands + - Handling periodic() methods from v2 Subsystems + - For each pattern, describe the v2 code structure and the equivalent v3 structure + +## API Differences Reference + +.. todo:: + Provide a quick reference of v2 vs. v3 API differences. Cover: + - Side-by-side comparison of common operations + - Method name changes + - Parameter changes + - Behavior changes (same API, different semantics) + - Removed v2 features and why + - Added v3 features not in v2 + - Present in table or comparison format for quick lookup + +## Migration Checklist + +.. todo:: + Provide a checklist for teams migrating to v3. Cover: + - Pre-migration: backup code, ensure v2 works, review v3 docs + - Update dependencies and build files + - Convert Subsystems to Mechanisms + - Convert Commands to coroutines + - Update trigger bindings + - Update autonomous routines + - Update RobotContainer + - Update Robot.java + - Test incrementally + - Update telemetry/logging + - Post-migration: cleanup, refactor to use v3 patterns, document changes + - Present as a sequential checklist teams can follow diff --git a/source/docs/software/commandbased/commands-v3/priorities-and-interrupts.rst b/source/docs/software/commandbased/commands-v3/priorities-and-interrupts.rst new file mode 100644 index 0000000000..ef20af9b34 --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/priorities-and-interrupts.rst @@ -0,0 +1,74 @@ +# Priorities and Interrupts + +.. todo:: + This article explains v3's priority system, one of the major new features compared to v2. The priority system provides fine-grained control over when commands can interrupt each other, enabling more sophisticated robot behaviors. Understanding priorities is crucial for teams using v3 effectively. + +## Priority Levels Explained + +.. todo:: + Introduce the concept of command priorities in v3. Cover: + - What priorities are and why they were added in v3 + - Available priority levels (numeric values, named constants) + - Default priority level for commands + - How priorities solve common v2 pain points + - High-level mental model: priorities as "importance" levels + - Relationship to requirements and the scheduler + +## How Priorities Work + +.. todo:: + Explain the mechanics of the priority system. Cover: + - How the scheduler uses priorities to resolve conflicts + - What happens when commands with different priorities require the same Mechanism + - Rules for when a higher-priority command can interrupt a lower-priority one + - What happens when priorities are equal + - The interruptible flag and its interaction with priorities + - How priorities propagate through command compositions and async/await + - Timing: when priority checks occur + +## Setting Command Priorities + +.. todo:: + Explain how to set priorities on commands. Cover: + - Syntax for setting command priority (method chaining, decorators, etc.) + - Where to set priorities: factory methods, binding sites, composition creation + - How to choose appropriate priority levels for different commands + - Making commands non-interruptible regardless of priority + - Dynamic priority adjustment (if supported) + - Best practices for consistent priority assignment across a codebase + +## Common Priority Patterns + +.. todo:: + Showcase common patterns for using priorities effectively. Cover: + - Default/teleoperated commands at low priority + - Autonomous routines at medium priority + - Safety/override commands at high priority + - Emergency stops at maximum priority + - Layered control systems with multiple priority tiers + - Mode-based priority schemes + - Describe several real-world scenarios and recommended priority levels + +## Interruption Behavior + +.. todo:: + Explain what happens when commands are interrupted. Cover: + - Command lifecycle during interruption + - Cleanup and resource release + - How coroutine commands handle interruption (exceptions, early exit) + - Interruption of composed commands (what happens to child commands) + - Interruption of awaited commands (how it propagates to parent) + - Forked commands and interruption + - Best practices for writing interruption-safe commands + +## Debugging Priority Issues + +.. todo:: + Provide guidance on troubleshooting priority-related problems. Cover: + - Common symptoms of priority misconfiguration + - How to diagnose why a command didn't interrupt another + - Tools and techniques for visualizing priority conflicts + - Dashboard/telemetry for monitoring command priorities + - Logging priority-related events + - Common mistakes and how to fix them + - Testing priority behavior diff --git a/source/docs/software/commandbased/commands-v3/structuring-v3-project.rst b/source/docs/software/commandbased/commands-v3/structuring-v3-project.rst new file mode 100644 index 0000000000..fe4f729232 --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/structuring-v3-project.rst @@ -0,0 +1,81 @@ +# Structuring a Commands v3 Project + +.. todo:: + This article provides guidance on how to organize a robot code project using Commands v3. Good project structure makes code easier to understand, maintain, and test. This article should help teams establish clean patterns early in their v3 adoption. + +## Project Structure Overview + +.. todo:: + Describe the recommended file and package organization for v3 projects. Cover: + - Top-level package structure + - Where Mechanisms should live + - Where command functions/classes should be organized + - Organization of constants and configuration + - Separation of concerns between different code areas + - How v3 structure differs from v2 structure + - Example directory tree showing recommended organization + +## RobotContainer Design + +.. todo:: + Explain the role and design of the RobotContainer class. Cover: + - What RobotContainer is responsible for in v3 + - How to structure RobotContainer for maintainability + - Mechanism instantiation and initialization + - Controller/joystick setup + - Button binding organization + - Autonomous routine selection + - Patterns for large RobotContainer classes (splitting into methods or subclasses) + - Example RobotContainer structure (describe sections, not full implementation) + +## Robot.java Setup + +.. todo:: + Explain the Robot.java class and v3-specific setup. Cover: + - Required v3 initialization in robotInit() + - Periodic methods and what should go in them + - How v3 uses the scheduler in periodic loops + - Autonomous vs. teleop initialization + - Test mode setup for v3 + - Simulation support hooks + - What should NOT go in Robot.java (antipatterns) + - Example Robot.java structure for v3 + +## Command Organization Strategies + +.. todo:: + Describe different approaches to organizing command code. Cover: + - Commands as factory methods on Mechanisms + - Commands as standalone functions in command files + - Commands organized by robot function (intake, shooter, etc.) + - Commands organized by autonomous routine + - Reusable command utilities and helpers + - Trade-offs of different organizational approaches + - Recommendations for small vs. large codebases + - Examples of each organizational strategy + +## Constants and Configuration + +.. todo:: + Explain how to organize constants, configuration, and tuning values. Cover: + - Where constants should live (Constants.java, separate config classes, etc.) + - Organizing constants by Mechanism vs. by type + - Physical constants vs. tuning parameters + - Using preferences/network tables for live tuning + - Version control and constants + - Robot-specific vs. shared constants (multiple robots) + - Type safety and units for constants + - Example constants organization patterns + +## Testing Structure + +.. todo:: + Describe how to structure test code for v3 projects. Cover: + - Where test files should live relative to main code + - Unit test organization (per-Mechanism, per-command, etc.) + - Integration test organization + - Test utilities and fixtures + - Mocking Mechanisms and hardware for command tests + - Simulation test setup + - CI/CD integration considerations + - Example test directory structure diff --git a/source/docs/software/commandbased/commands-v3/telemetry-and-debugging.rst b/source/docs/software/commandbased/commands-v3/telemetry-and-debugging.rst new file mode 100644 index 0000000000..e6cbaccd6f --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/telemetry-and-debugging.rst @@ -0,0 +1,59 @@ +# Telemetry and Debugging + +.. todo:: + This article covers using v3's enhanced telemetry features and debugging tools to understand and troubleshoot robot behavior. Good telemetry is essential for rapid iteration during competition, and v3 provides improved tools compared to v2. + +## v3 Telemetry Improvements + +.. todo:: + Overview of telemetry enhancements in v3. Cover: + - What telemetry improvements v3 provides over v2 + - Built-in command scheduler telemetry + - Mechanism state visibility + - Command lifecycle events + - Priority and interruption logging + - Performance metrics (cycle time, CPU usage) + - How telemetry integrates with the scheduler + +## Dashboard Integration + +.. todo:: + Explain how to integrate v3 telemetry with dashboards. Cover: + - Supported dashboard tools (Shuffleboard, Glass, etc.) + - Automatic command scheduler widget/visualization + - Publishing Mechanism state to Network Tables + - Publishing command properties and status + - Creating custom dashboard layouts for v3 projects + - Live tuning parameters through the dashboard + - Remote command triggering from dashboard + - Best practices for dashboard organization + +## Debugging Techniques + +.. todo:: + Provide techniques for debugging v3 command-based code. Cover: + - Using dashboard telemetry to diagnose issues + - Logging command lifecycle events + - Tracing command execution flow + - Debugging priority conflicts + - Debugging requirement conflicts + - Debugging trigger bindings that don't fire + - Debugging commands that don't end/interrupt properly + - Using simulation for debugging + - Breakpoint debugging in IDEs with v3 + - Common debugging patterns and workflows + +## Logging Best Practices + +.. todo:: + Explain best practices for logging in v3 projects. Cover: + - What to log and when to log it + - Logging levels and appropriate usage + - WPILib DataLog integration + - Logging command execution and state transitions + - Logging Mechanism state and sensor readings + - Logging errors and exceptions + - Performance impact of logging + - Log analysis tools and workflows + - Competition-ready logging strategies (what to enable/disable) + - Example logging patterns for commands and mechanisms diff --git a/source/docs/software/commandbased/commands-v3/testing-and-simulation.rst b/source/docs/software/commandbased/commands-v3/testing-and-simulation.rst new file mode 100644 index 0000000000..9cc5caccc6 --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/testing-and-simulation.rst @@ -0,0 +1,69 @@ +# Testing and Simulation + +.. todo:: + This article covers testing commands and mechanisms using both unit tests and simulation. Testing is crucial for reliable robot code, and v3's design makes testing easier than v2. This article should encourage teams to adopt testing practices and show them how. + +## Why Test Commands + +.. todo:: + Make the case for testing command-based code. Cover: + - Benefits of testing: catch bugs early, enable refactoring, document behavior + - Why v3 makes testing easier than v2 + - What aspects of command code can/should be tested + - Testing pyramid: unit tests, integration tests, simulation tests + - When to write tests (TDD, after implementation, before competition) + - Realistic expectations for FRC teams regarding testing + +## Unit Testing Commands + +.. todo:: + Explain how to write unit tests for individual commands. Cover: + - Setting up the test environment (scheduler, mocks, etc.) + - How to simulate scheduler cycles in tests + - Testing command initialization and execution logic + - Testing command completion conditions + - Testing interruption behavior + - Mocking Mechanisms and their methods + - Verifying command requirements + - Testing command properties (priority, interruptibility, etc.) + - Example test structure for a simple command (describe test cases, not full code) + +## Integration Testing + +.. todo:: + Explain how to write integration tests for command interactions. Cover: + - What integration tests cover that unit tests don't + - Testing command compositions + - Testing async/await patterns (await, awaitAll, fork, etc.) + - Testing trigger bindings + - Testing priority and interruption behavior between commands + - Testing Mechanism interactions with multiple commands + - Testing default commands + - Example integration test scenarios (describe test cases) + +## Simulation Integration + +.. todo:: + Explain how to use WPILib simulation tools with v3. Cover: + - Overview of WPILib simulation framework + - Setting up simulation for v3 projects + - Simulating Mechanisms and their hardware + - Running commands in simulation + - Using the simulation GUI to test robot behavior + - Physics simulation for mechanisms (drivetrains, arms, elevators, etc.) + - Advantages of simulation testing vs. pure unit tests + - Example simulation test workflow + +## Common Testing Patterns + +.. todo:: + Showcase common patterns and utilities for testing v3 code. Cover: + - Test fixture setup for commands and mechanisms + - Helper functions for advancing the scheduler + - Mock Mechanism base classes or utilities + - Testing commands with time-based logic + - Testing commands with sensor conditions + - Testing error handling and edge cases + - Snapshot testing for complex command sequences + - Performance testing (cycle time, memory usage) + - Describe useful testing utilities teams should build diff --git a/source/docs/software/commandbased/commands-v3/what-is-commands-v3.rst b/source/docs/software/commandbased/commands-v3/what-is-commands-v3.rst new file mode 100644 index 0000000000..c8af65450f --- /dev/null +++ b/source/docs/software/commandbased/commands-v3/what-is-commands-v3.rst @@ -0,0 +1,132 @@ +# What is Commands v3? + +.. todo:: This article introduces the conceptual foundation of Commands v3, explaining what problem it solves and its core concepts. + +## Introduction + +.. todo:: + - Recap the command-based pattern (commands + mechanisms for resource management) + - Explain what's fundamentally different in v3 vs v2 + - Why imperative style was chosen over declarative composition + - Brief history: evolution from v1 → v2 → v3 + +## The Problem v3 Solves + +.. todo:: + **Learning Curve Issues:** + - v2 requires understanding functional composition, decorators, and lambda chaining + - New programmers struggle with splitting logic across initialize/execute/isFinished + - Common mistake: writing blocking loops in execute() that stall the scheduler + + **Code Readability:** + - Complex behaviors require deeply nested decorator chains + - Hard to see the sequential flow of actions + - Difficult to add conditional logic mid-sequence + + **Example comparison:** Show a complex autonomous routine in v2 (decorator chains) vs v3 (sequential imperative code) to illustrate the readability difference. + +## Core Concepts + +### Commands as Imperative Functions + +.. todo:: + - Commands in v3 are written as normal sequential functions + - Use loops, if-statements, and control flow naturally + - The ``Coroutine`` object provides pause points via ``yield()`` + - Example: Simple command that reads like pseudocode + +### Coroutines and Cooperative Multitasking + +.. todo:: + - What are coroutines (functions that can pause and resume) + - How Java's ``Continuation`` API enables this (internal implementation detail) + - Cooperative vs preemptive multitasking + - Commands must voluntarily yield control + - The scheduler cannot forcibly suspend commands + +### Mechanisms as Exclusive Resources + +.. todo:: + - Mechanisms represent hardware groupings (like v2 Subsystems) + - Only one command can require a mechanism at a time + - Automatic resource conflict detection and resolution + - Comparison to v2 Subsystems with key differences + +### Command Priorities + +.. todo:: + - Priority levels replace v2's binary interrupt behavior + - Higher priority commands can interrupt lower priority ones + - Enables nuanced control (e.g., LED priority ladder for different robot states) + - Default priorities and when to override them + +## Key Improvements Over v2 + +### 1. Natural Sequential Syntax + +.. todo:: + - Write steps in order like a recipe + - No need to chain decorators for sequential actions + - Easy to add delays, loops, and conditions mid-command + - Example: Drive to position with adjustments + +### 2. Mandatory Command Naming + +.. todo:: + - All commands must have descriptive names + - Improves telemetry and debugging + - Eliminates vague "SequentialCommandGroup" labels + - Automatic naming for compositions (e.g., "Step 1 -> Step 2 -> Step 3") + +### 3. Eliminated Uncommanded Behavior + +.. todo:: + - v2 issue: nested commands finishing at different times leaves subsystems uncommanded + - v2 solution: proxy commands (boilerplate heavy) + - v3 solution: child commands use mechanisms without parent requiring them + - Child commands cannot interrupt parents + +### 4. Enhanced Telemetry + +.. todo:: + - Per-instance command tracking (each execution has unique ID) + - Clear command hierarchy visualization + - Performance metrics per command execution + - Better dashboard integration + +### 5. Inner Trigger Scopes + +.. todo:: + - Triggers defined inside command bodies are scoped to that command's lifetime + - No need for global trigger libraries with conditional checks + - Cleaner code organization + - Example: Temporary button binding during a specific command + +## What v3 Doesn't Do (Non-Goals) + +.. todo:: + - **Not preemptive multitasking**: Commands must yield voluntarily + - **Not multi-threaded**: Single-threaded execution only + - **No unrestricted coroutine usage**: Coroutines only work within command context + - **Cannot replace periodic loops**: Still need periodic methods for continuous updates + +## Comparison: v2 vs v3 + +.. todo:: + **When to use v2:** + - Need C++/Python support + - Team comfortable with functional programming + - Existing codebase works well + + **When to use v3:** + - Java-only team + - Prefer imperative style + - Want latest features + - Starting fresh for 2027 + +## Next Steps + +.. todo:: + - Link to Getting Started guide + - Link to Migration guide for v2 users + - Link to Mechanisms article for understanding hardware organization diff --git a/source/docs/software/commandbased/index.rst b/source/docs/software/commandbased/index.rst index 7769449950..62a5136f0b 100644 --- a/source/docs/software/commandbased/index.rst +++ b/source/docs/software/commandbased/index.rst @@ -1,39 +1,35 @@ # Command-Based Programming -This sequence of articles serves as an introduction to and reference for the WPILib command-based framework. +This section serves as an introduction to and reference for the WPILib command-based framework. -For a collection of example projects using the command-based framework, see :ref:`docs/software/examples-tutorials/wpilib-examples:Command-Based Examples`. - -.. toctree:: - :maxdepth: 1 +WPILib offers two command-based frameworks: - what-is-command-based - commands - command-compositions - subsystems - binding-commands-to-triggers - structuring-command-based-project - organizing-command-based - command-scheduler - cpp-command-discussion - pid-subsystems-commands - profile-subsystems-commands - profilepid-subsystems-commands +- **Commands v2**: The stable, production-ready framework supporting Java, C++, and Python. Uses a declarative programming style with method chaining and lambda expressions. +- **Commands v3**: A newer Java-only framework offering an imperative programming style with coroutines. Currently in development with enhanced features. -## Passing Functions As Parameters +.. note:: Most teams should use **Commands v2**, which is battle-tested and supports all WPILib languages. Java teams interested in coroutine-based imperative programming may explore Commands v3. -In order to provide a concise inline syntax, the command-based library often accepts functions as parameters of constructors, factories, and decorators. Fortunately, both Java and C++ offer users the ability to :ref:`pass functions as objects `: +For a collection of example projects using the command-based framework, see :ref:`docs/software/examples-tutorials/wpilib-examples:Command-Based Examples`. -### Method References (Java) +.. toctree:: + :maxdepth: 1 + :caption: Command-Based Frameworks -In Java, a reference to a function that can be passed as a parameter is called a method reference. The general syntax for a method reference is ``object::method`` or ``Class::staticMethod``. Note that no method parameters are included, since the method *itself* is passed. The method is not being called - it is being passed to another piece of code (in this case, a command) so that *that* code can call it when needed. For further information on method references, see :ref:`docs/software/basic-programming/functions-as-data:Method References`. + commands-v2/index + commands-v3/index -### Lambda Expressions (Java) +## Choosing Between v2 and v3 -While method references work well for passing a function that has already been written, often it is inconvenient/wasteful to write a function solely for the purpose of sending as a method reference, if that function will never be used elsewhere. To avoid this, Java also supports a feature called "lambda expressions." A lambda expression is an inline method definition - it allows a function to be defined *inside of a parameter list*. For specifics on how to write Java lambda expressions, see :ref:`docs/software/basic-programming/functions-as-data:Lambda Expressions in Java`. +### Use Commands v2 if -### Lambda Expressions (C++) +- You need C++ or Python support +- You want the most stable and widely-used framework +- Your team is comfortable with declarative/functional programming +- You're new to command-based programming -.. warning:: Due to complications in C++ semantics, capturing ``this`` in a C++ lambda can cause a null pointer exception if done from a component command of a command composition. Whenever possible, C++ users should capture relevant command members explicitly and by value. For more details, see [here](https://github.com/wpilibsuite/allwpilib/issues/3109). +### Use Commands v3 if -C++ lacks a close equivalent to Java method references - pointers to member functions are generally not directly usable as parameters due to the presence of the implicit ``this`` parameter. However, C++ does offer lambda expressions - in addition, the lambda expressions offered by C++ are in many ways more powerful than those in Java. For specifics on how to write C++ lambda expressions, see :ref:`docs/software/basic-programming/functions-as-data:Lambda Expressions in C++`. +- You're a Java team +- You prefer imperative control flow (loops, if-statements) over method chaining +- You want to use the actively developed framework with new features +- You're comfortable with more advanced programming concepts diff --git a/source/docs/software/convenience-features/event-based.rst b/source/docs/software/convenience-features/event-based.rst index e9b4c12cb6..d27d602b37 100644 --- a/source/docs/software/convenience-features/event-based.rst +++ b/source/docs/software/convenience-features/event-based.rst @@ -117,7 +117,7 @@ Often times it is desired to bind an action not to the *current* state of a cond ### Downcasting ``BooleanEvent`` Objects -To convert ``BooleanEvent`` objects to other types, most commonly the ``Trigger`` subclass used for :ref:`binding commands to conditions `, the generic ``castTo()``/``CastTo()`` decorator exists: +To convert ``BooleanEvent`` objects to other types, most commonly the ``Trigger`` subclass used for :ref:`binding commands to conditions `, the generic ``castTo()``/``CastTo()`` decorator exists: .. tab-set-code:: diff --git a/source/docs/software/dashboards/glass/command-based-widgets.rst b/source/docs/software/dashboards/glass/command-based-widgets.rst index 5ddafe382e..cddff22432 100644 --- a/source/docs/software/dashboards/glass/command-based-widgets.rst +++ b/source/docs/software/dashboards/glass/command-based-widgets.rst @@ -1,6 +1,6 @@ # Widgets for the Command-Based Framework -Glass also has several widgets that are specific to the :ref:`command-based framework `. These include widgets to schedule commands, view actively running commands on a specific subsystem, or view the state of the :ref:`command scheduler `. +Glass also has several widgets that are specific to the :ref:`command-based framework `. These include widgets to schedule commands, view actively running commands on a specific subsystem, or view the state of the :ref:`command scheduler `. ## Command Selector Widget diff --git a/source/docs/software/examples-tutorials/wpilib-examples.rst b/source/docs/software/examples-tutorials/wpilib-examples.rst index 624f24dfdb..dfc67bb7e9 100644 --- a/source/docs/software/examples-tutorials/wpilib-examples.rst +++ b/source/docs/software/examples-tutorials/wpilib-examples.rst @@ -55,7 +55,7 @@ These examples demonstrate sensor reading and data processing using WPILib. Mec ## Command-Based Examples -These examples demonstrate the use of the :ref:`Command-Based framework `. +These examples demonstrate the use of the :ref:`Command-Based framework `. * **DriveDistanceOffboard** ([Java](https://github.com/wpilibsuite/allwpilib/tree/2027/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/drivedistanceoffboard), [C++](https://github.com/wpilibsuite/allwpilib/tree/2027/wpilibcExamples/src/main/cpp/examples/DriveDistanceOffboard), [Python](https://github.com/robotpy/examples/tree/main/DriveDistanceOffboard)): Demonstrates the use of a ``TrapezoidProfileCommand`` in conjunction with a "smart motor controller" to drive forward by a set distance with a trapezoidal motion profile. * **Rapid React Command Bot** ([Java](https://github.com/wpilibsuite/allwpilib/tree/2027/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/rapidreactcommandbot), [C++](https://github.com/wpilibsuite/allwpilib/tree/2027/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot)): This project uses the latest command based best practices and the Epilogue logging system. It is capable of playing the FRC 2022 game Rapid React. diff --git a/source/docs/software/kinematics-and-odometry/differential-drive-odometry.rst b/source/docs/software/kinematics-and-odometry/differential-drive-odometry.rst index 85cef2b36f..ab3fe0b46c 100644 --- a/source/docs/software/kinematics-and-odometry/differential-drive-odometry.rst +++ b/source/docs/software/kinematics-and-odometry/differential-drive-odometry.rst @@ -50,7 +50,7 @@ The optional argument is the starting pose of your robot on the field (as a ``Po ``` ## Updating the Robot Pose -The ``update`` method can be used to update the robot's position on the field. This method must be called periodically, preferably in the ``periodic()`` method of a :ref:`Subsystem `. The ``update`` method returns the new updated pose of the robot. This method takes in the gyro angle of the robot, along with the left encoder distance and right encoder distance. +The ``update`` method can be used to update the robot's position on the field. This method must be called periodically, preferably in the ``periodic()`` method of a :ref:`Subsystem `. The ``update`` method returns the new updated pose of the robot. This method takes in the gyro angle of the robot, along with the left encoder distance and right encoder distance. .. note:: If the robot is moving forward in a straight line, **both** distances (left and right) must be increasing positively -- the rate of change must be positive. diff --git a/source/docs/software/kinematics-and-odometry/mecanum-drive-odometry.rst b/source/docs/software/kinematics-and-odometry/mecanum-drive-odometry.rst index fee6f8d777..217d7d41ba 100644 --- a/source/docs/software/kinematics-and-odometry/mecanum-drive-odometry.rst +++ b/source/docs/software/kinematics-and-odometry/mecanum-drive-odometry.rst @@ -99,7 +99,7 @@ The fourth optional argument is the starting pose of your robot on the field (as ``` ## Updating the robot pose -The ``update`` method of the odometry class updates the robot position on the field. The update method takes in the gyro angle of the robot, along with a ``MecanumDriveWheelPositions`` object representing the position of each of the 4 wheels on the robot. This ``update`` method must be called periodically, preferably in the ``periodic()`` method of a :ref:`Subsystem `. The ``update`` method returns the new updated pose of the robot. +The ``update`` method of the odometry class updates the robot position on the field. The update method takes in the gyro angle of the robot, along with a ``MecanumDriveWheelPositions`` object representing the position of each of the 4 wheels on the robot. This ``update`` method must be called periodically, preferably in the ``periodic()`` method of a :ref:`Subsystem `. The ``update`` method returns the new updated pose of the robot. .. tab-set-code:: diff --git a/source/docs/software/kinematics-and-odometry/swerve-drive-odometry.rst b/source/docs/software/kinematics-and-odometry/swerve-drive-odometry.rst index 4bbb8e0af0..9fc4b43b8c 100644 --- a/source/docs/software/kinematics-and-odometry/swerve-drive-odometry.rst +++ b/source/docs/software/kinematics-and-odometry/swerve-drive-odometry.rst @@ -97,7 +97,7 @@ The fourth optional argument is the starting pose of your robot on the field (as ## Updating the robot pose The ``update`` method of the odometry class updates the robot position on the field. The update method takes in the gyro angle of the robot, along with an array of ``SwerveModulePosition`` objects. It is important that the order in which you pass the ``SwerveModulePosition`` objects is the same as the order in which you created the kinematics object. -This ``update`` method must be called periodically, preferably in the ``periodic()`` method of a :ref:`Subsystem `. The ``update`` method returns the new updated pose of the robot. +This ``update`` method must be called periodically, preferably in the ``periodic()`` method of a :ref:`Subsystem `. The ``update`` method returns the new updated pose of the robot. .. tab-set-code:: diff --git a/source/docs/software/pathplanning/trajectory-tutorial/creating-drive-subsystem.rst b/source/docs/software/pathplanning/trajectory-tutorial/creating-drive-subsystem.rst index 92429c48dd..cd9c84c1c1 100644 --- a/source/docs/software/pathplanning/trajectory-tutorial/creating-drive-subsystem.rst +++ b/source/docs/software/pathplanning/trajectory-tutorial/creating-drive-subsystem.rst @@ -1,6 +1,6 @@ # Step 3: Creating a Drive Subsystem -Now that our drive is characterized, it is time to start writing our robot code *proper*. As mentioned before, we will use the :ref:`command-based ` framework for our robot code. Accordingly, our first step is to write a suitable drive :ref:`subsystem ` class. +Now that our drive is characterized, it is time to start writing our robot code *proper*. As mentioned before, we will use the :ref:`command-based ` framework for our robot code. Accordingly, our first step is to write a suitable drive :ref:`subsystem ` class. The full drive class from the RamseteCommand Example Project ([Java](https://github.com/wpilibsuite/allwpilib/tree/v2024.3.2/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/ramsetecommand), [C++](https://github.com/wpilibsuite/allwpilib/tree/v2024.3.2/wpilibcExamples/src/main/cpp/examples/RamseteCommand)) can be seen below. The rest of the article will describe the steps involved in writing this class. diff --git a/source/docs/software/pathplanning/trajectory-tutorial/creating-following-trajectory.rst b/source/docs/software/pathplanning/trajectory-tutorial/creating-following-trajectory.rst index 2ff150cbc0..722b01dd24 100644 --- a/source/docs/software/pathplanning/trajectory-tutorial/creating-following-trajectory.rst +++ b/source/docs/software/pathplanning/trajectory-tutorial/creating-following-trajectory.rst @@ -2,7 +2,7 @@ With our drive subsystem written, it is now time to generate a trajectory and write an autonomous command to follow it. -As per the :ref:`standard command-based project structure `, we will do this in the ``getAutonomousCommand`` method of the ``RobotContainer`` class. The full method from the RamseteCommand Example Project ([Java](https://github.com/wpilibsuite/allwpilib/tree/v2024.3.2/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/ramsetecommand), [C++](https://github.com/wpilibsuite/allwpilib/tree/v2024.3.2/wpilibcExamples/src/main/cpp/examples/RamseteCommand)) can be seen below. The rest of the article will break down the different parts of the method in more detail. +As per the :ref:`standard command-based project structure `, we will do this in the ``getAutonomousCommand`` method of the ``RobotContainer`` class. The full method from the RamseteCommand Example Project ([Java](https://github.com/wpilibsuite/allwpilib/tree/v2024.3.2/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/ramsetecommand), [C++](https://github.com/wpilibsuite/allwpilib/tree/v2024.3.2/wpilibcExamples/src/main/cpp/examples/RamseteCommand)) can be seen below. The rest of the article will break down the different parts of the method in more detail. .. tab-set:: diff --git a/source/docs/software/pathplanning/trajectory-tutorial/entering-constants.rst b/source/docs/software/pathplanning/trajectory-tutorial/entering-constants.rst index 27ec0d246e..163c7f6691 100644 --- a/source/docs/software/pathplanning/trajectory-tutorial/entering-constants.rst +++ b/source/docs/software/pathplanning/trajectory-tutorial/entering-constants.rst @@ -2,7 +2,7 @@ .. note:: In C++, it is important that the feedforward constants be entered as the correct unit type. For more information on C++ units, see :ref:`docs/software/basic-programming/cpp-units:The C++ Units Library`. -Now that we have our system constants, it is time to place them in our code. The recommended place for this is the ``Constants`` file of the :ref:`standard command-based project structure `. +Now that we have our system constants, it is time to place them in our code. The recommended place for this is the ``Constants`` file of the :ref:`standard command-based project structure `. The relevant parts of the constants file from the RamseteCommand Example Project ([Java](https://github.com/wpilibsuite/allwpilib/tree/v2024.3.2/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/ramsetecommand), [C++](https://github.com/wpilibsuite/allwpilib/tree/v2024.3.2/wpilibcExamples/src/main/cpp/examples/RamseteCommand)) can be seen below. diff --git a/source/docs/software/pathplanning/trajectory-tutorial/trajectory-tutorial-overview.rst b/source/docs/software/pathplanning/trajectory-tutorial/trajectory-tutorial-overview.rst index 0cc9468537..ed77951c8e 100644 --- a/source/docs/software/pathplanning/trajectory-tutorial/trajectory-tutorial-overview.rst +++ b/source/docs/software/pathplanning/trajectory-tutorial/trajectory-tutorial-overview.rst @@ -6,7 +6,7 @@ .. note:: Before following this tutorial, it is helpful (but not strictly necessary) to have a baseline familiarity with WPILib's :ref:`PID control `, :ref:`feedforward `, and :ref:`trajectory ` features. -.. note:: The robot code in this tutorial uses the :ref:`command-based ` framework. The command-based framework is strongly recommended for beginning and intermediate teams. +.. note:: The robot code in this tutorial uses the :ref:`command-based ` framework. The command-based framework is strongly recommended for beginning and intermediate teams. The goal of this tutorial is to provide "end-to-end" instruction on implementing a trajectory-following autonomous routine for a differential-drive robot. By following this tutorial, readers will learn how to: diff --git a/source/docs/software/vscode-overview/creating-robot-program.rst b/source/docs/software/vscode-overview/creating-robot-program.rst index e48e2580f3..5dd0845f76 100644 --- a/source/docs/software/vscode-overview/creating-robot-program.rst +++ b/source/docs/software/vscode-overview/creating-robot-program.rst @@ -119,7 +119,7 @@ This will bring up the "New Project Creator Window:" The elements of the New Project Creator Window are explained below: -1. **Project Type**: The kind of project we wish to create. This can be an example project, or one of the project templates provided by WPILib. Templates exist for each of the robot base classes. Additionally, a template exists for :ref:`Command-based ` projects, which are built on the :code:`TimedRobot` base class but include a number of additional features - this type of robot program is highly recommended for new teams. +1. **Project Type**: The kind of project we wish to create. This can be an example project, or one of the project templates provided by WPILib. Templates exist for each of the robot base classes. Additionally, a template exists for :ref:`Command-based ` projects, which are built on the :code:`TimedRobot` base class but include a number of additional features - this type of robot program is highly recommended for new teams. 2. **Language**: This is the language (C++ or Java) that will be used for this project. 3. **Base Folder**: If this is a template project, this specifies the type of template that will be used. 4. **Project Location**: This determines the folder in which the robot project will be located. diff --git a/source/docs/yearly-overview/yearly-changelog.rst b/source/docs/yearly-overview/yearly-changelog.rst index 95756cd2f6..2c2c95146c 100644 --- a/source/docs/yearly-overview/yearly-changelog.rst +++ b/source/docs/yearly-overview/yearly-changelog.rst @@ -60,7 +60,7 @@ Supported Operating Systems and Architectures: - Remove deprecated ``TrapzoidProfileCommand`` API - Breaking: Remove deprecated C++ method ``TransferOwnership`` - Deprecate ``PIDCommand``, ``PIDSubsystem``, ``ProfiledPIDCommand``, ``ProfiledPIDSubsystem``, ``TrapezoidProfileSubsystem`` -- Deprecate ``TrapezoidProfileCommand``. Use :doc:`TrapezoidProfile Directly ` +- Deprecate ``TrapezoidProfileCommand``. Use :doc:`TrapezoidProfile Directly ` - Cache controller ``BooleanEvents`` / ``Triggers`` and directly construct ``Triggers``, fixing issues if ``BooleanEvents`` / ``Triggers`` are created in loops - Add deadband trigger methods to ``CommandGenericHID`` - Make requirements private diff --git a/source/redirects.txt b/source/redirects.txt index b9675cb76b..f72db16c41 100644 --- a/source/redirects.txt +++ b/source/redirects.txt @@ -413,3 +413,15 @@ "docs/software/roborio-info/roborio-web-dashboard.rst" "docs/software/systemcore-info/roborio-web-dashboard.rst" "docs/software/roborio-info/index.rst" "docs/software/systemcore-info/index.rst" "docs/software/roborio-info/roborio-introduction.rst" "docs/software/systemcore-info/systemcore-introduction.rst" +"docs/software/commandbased/what-is-command-based.rst" "docs/software/commandbased/commands-v2/what-is-command-based.rst" +"docs/software/commandbased/commands.rst" "docs/software/commandbased/commands-v2/commands.rst" +"docs/software/commandbased/command-compositions.rst" "docs/software/commandbased/commands-v2/command-compositions.rst" +"docs/software/commandbased/subsystems.rst" "docs/software/commandbased/commands-v2/subsystems.rst" +"docs/software/commandbased/binding-commands-to-triggers.rst" "docs/software/commandbased/commands-v2/binding-commands-to-triggers.rst" +"docs/software/commandbased/structuring-command-based-project.rst" "docs/software/commandbased/commands-v2/structuring-command-based-project.rst" +"docs/software/commandbased/organizing-command-based.rst" "docs/software/commandbased/commands-v2/organizing-command-based.rst" +"docs/software/commandbased/command-scheduler.rst" "docs/software/commandbased/commands-v2/command-scheduler.rst" +"docs/software/commandbased/cpp-command-discussion.rst" "docs/software/commandbased/commands-v2/cpp-command-discussion.rst" +"docs/software/commandbased/pid-subsystems-commands.rst" "docs/software/commandbased/commands-v2/pid-subsystems-commands.rst" +"docs/software/commandbased/profile-subsystems-commands.rst" "docs/software/commandbased/commands-v2/profile-subsystems-commands.rst" +"docs/software/commandbased/profilepid-subsystems-commands.rst" "docs/software/commandbased/commands-v2/profilepid-subsystems-commands.rst"