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..75d45741cd --- /dev/null +++ b/source/docs/software/commandbased/commands-v2/index.rst @@ -0,0 +1,51 @@ +# 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. + +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/index.rst b/source/docs/software/commandbased/index.rst index 7769449950..97aa5a5ea2 100644 --- a/source/docs/software/commandbased/index.rst +++ b/source/docs/software/commandbased/index.rst @@ -1,39 +1,10 @@ # 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 - 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 - -## 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++`. + commands-v2/index 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"