From 87a34af367aa784ccce24cec8e88296e393763e1 Mon Sep 17 00:00:00 2001 From: Starlight220 <53231611+Starlight220@users.noreply.github.com> Date: Mon, 26 Dec 2022 21:28:06 +0200 Subject: [PATCH] [templates] Add bindings to command-based template (#4838) --- .../commandbased/cpp/RobotContainer.cpp | 14 +++++++- .../cpp/subsystems/ExampleSubsystem.cpp | 5 +++ .../commandbased/include/Constants.h | 6 ++++ .../commandbased/include/RobotContainer.h | 8 ++++- .../include/subsystems/ExampleSubsystem.h | 8 +++++ .../templates/commandbased/Constants.java | 6 +++- .../commandbased/RobotContainer.java | 35 ++++++++++++++----- .../subsystems/ExampleSubsystem.java | 10 ++++++ 8 files changed, 80 insertions(+), 12 deletions(-) diff --git a/wpilibcExamples/src/main/cpp/templates/commandbased/cpp/RobotContainer.cpp b/wpilibcExamples/src/main/cpp/templates/commandbased/cpp/RobotContainer.cpp index d56b84eeee..43005010e2 100644 --- a/wpilibcExamples/src/main/cpp/templates/commandbased/cpp/RobotContainer.cpp +++ b/wpilibcExamples/src/main/cpp/templates/commandbased/cpp/RobotContainer.cpp @@ -4,7 +4,10 @@ #include "RobotContainer.h" +#include + #include "commands/Autos.h" +#include "commands/ExampleCommand.h" RobotContainer::RobotContainer() { // Initialize all of your commands and subsystems here @@ -14,7 +17,16 @@ RobotContainer::RobotContainer() { } void RobotContainer::ConfigureBindings() { - // Configure your button bindings here + // Configure your trigger bindings here + + // Schedule `ExampleCommand` when `exampleCondition` changes to `true` + frc2::Trigger([this] { + return m_subsystem.ExampleCondition(); + }).OnTrue(ExampleCommand(&m_subsystem).ToPtr()); + + // Schedule `ExampleMethodCommand` when the Xbox controller's B button is + // pressed, cancelling on release. + m_driverController.B().WhileTrue(m_subsystem.ExampleMethodCommand()); } frc2::CommandPtr RobotContainer::GetAutonomousCommand() { diff --git a/wpilibcExamples/src/main/cpp/templates/commandbased/cpp/subsystems/ExampleSubsystem.cpp b/wpilibcExamples/src/main/cpp/templates/commandbased/cpp/subsystems/ExampleSubsystem.cpp index 4f428f833b..1660de7bfa 100644 --- a/wpilibcExamples/src/main/cpp/templates/commandbased/cpp/subsystems/ExampleSubsystem.cpp +++ b/wpilibcExamples/src/main/cpp/templates/commandbased/cpp/subsystems/ExampleSubsystem.cpp @@ -14,6 +14,11 @@ frc2::CommandPtr ExampleSubsystem::ExampleMethodCommand() { return RunOnce([/* this */] { /* one-time action goes here */ }); } +bool ExampleSubsystem::ExampleCondition() { + // Query some boolean state, such as a digital sensor. + return false; +} + void ExampleSubsystem::Periodic() { // Implementation of subsystem periodic method goes here. } diff --git a/wpilibcExamples/src/main/cpp/templates/commandbased/include/Constants.h b/wpilibcExamples/src/main/cpp/templates/commandbased/include/Constants.h index 20cc88acd6..963b31c6b5 100644 --- a/wpilibcExamples/src/main/cpp/templates/commandbased/include/Constants.h +++ b/wpilibcExamples/src/main/cpp/templates/commandbased/include/Constants.h @@ -13,3 +13,9 @@ * command-specific namespaces within this header, which can then be used where * they are needed. */ + +namespace OperatorConstants { + +constexpr int kDriverControllerPort = 0; + +} // namespace OperatorConstants diff --git a/wpilibcExamples/src/main/cpp/templates/commandbased/include/RobotContainer.h b/wpilibcExamples/src/main/cpp/templates/commandbased/include/RobotContainer.h index 9d51c8fbd6..697b9a2f5e 100644 --- a/wpilibcExamples/src/main/cpp/templates/commandbased/include/RobotContainer.h +++ b/wpilibcExamples/src/main/cpp/templates/commandbased/include/RobotContainer.h @@ -5,7 +5,9 @@ #pragma once #include +#include +#include "Constants.h" #include "subsystems/ExampleSubsystem.h" /** @@ -13,7 +15,7 @@ * Command-based is a "declarative" paradigm, very little robot logic should * actually be handled in the {@link Robot} periodic methods (other than the * scheduler calls). Instead, the structure of the robot (including subsystems, - * commands, and button mappings) should be declared here. + * commands, and trigger mappings) should be declared here. */ class RobotContainer { public: @@ -22,6 +24,10 @@ class RobotContainer { frc2::CommandPtr GetAutonomousCommand(); private: + // Replace with CommandPS4Controller or CommandJoystick if needed + frc2::CommandXboxController m_driverController{ + OperatorConstants::kDriverControllerPort}; + // The robot's subsystems are defined here... ExampleSubsystem m_subsystem; diff --git a/wpilibcExamples/src/main/cpp/templates/commandbased/include/subsystems/ExampleSubsystem.h b/wpilibcExamples/src/main/cpp/templates/commandbased/include/subsystems/ExampleSubsystem.h index 0649f88df8..669f2eda06 100644 --- a/wpilibcExamples/src/main/cpp/templates/commandbased/include/subsystems/ExampleSubsystem.h +++ b/wpilibcExamples/src/main/cpp/templates/commandbased/include/subsystems/ExampleSubsystem.h @@ -16,6 +16,14 @@ class ExampleSubsystem : public frc2::SubsystemBase { */ frc2::CommandPtr ExampleMethodCommand(); + /** + * An example method querying a boolean state of the subsystem (for example, a + * digital sensor). + * + * @return value of some boolean subsystem state, such as a digital sensor. + */ + bool ExampleCondition(); + /** * Will be called periodically whenever the CommandScheduler runs. */ diff --git a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/commandbased/Constants.java b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/commandbased/Constants.java index ecfe201607..0c958be1b0 100644 --- a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/commandbased/Constants.java +++ b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/commandbased/Constants.java @@ -12,4 +12,8 @@ package edu.wpi.first.wpilibj.templates.commandbased; *

It is advised to statically import this class (or one of its inner classes) wherever the * constants are needed, to reduce verbosity. */ -public final class Constants {} +public final class Constants { + public static class OperatorConstants { + public static final int kDriverControllerPort = 0; + } +} diff --git a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/commandbased/RobotContainer.java b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/commandbased/RobotContainer.java index b5721a754e..c29ad382cd 100644 --- a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/commandbased/RobotContainer.java +++ b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/commandbased/RobotContainer.java @@ -4,35 +4,52 @@ package edu.wpi.first.wpilibj.templates.commandbased; -import edu.wpi.first.wpilibj.GenericHID; -import edu.wpi.first.wpilibj.XboxController; +import edu.wpi.first.wpilibj.templates.commandbased.Constants.OperatorConstants; import edu.wpi.first.wpilibj.templates.commandbased.commands.Autos; +import edu.wpi.first.wpilibj.templates.commandbased.commands.ExampleCommand; import edu.wpi.first.wpilibj.templates.commandbased.subsystems.ExampleSubsystem; import edu.wpi.first.wpilibj2.command.Command; +import edu.wpi.first.wpilibj2.command.button.CommandXboxController; +import edu.wpi.first.wpilibj2.command.button.Trigger; /** * This class is where the bulk of the robot should be declared. Since Command-based is a * "declarative" paradigm, very little robot logic should actually be handled in the {@link Robot} * periodic methods (other than the scheduler calls). Instead, the structure of the robot (including - * subsystems, commands, and button mappings) should be declared here. + * subsystems, commands, and trigger mappings) should be declared here. */ public class RobotContainer { // The robot's subsystems and commands are defined here... private final ExampleSubsystem m_exampleSubsystem = new ExampleSubsystem(); + // Replace with CommandPS4Controller or CommandJoystick if needed + private final CommandXboxController m_driverController = + new CommandXboxController(OperatorConstants.kDriverControllerPort); + /** The container for the robot. Contains subsystems, OI devices, and commands. */ public RobotContainer() { - // Configure the button bindings + // Configure the trigger bindings configureBindings(); } /** - * Use this method to define your button->command mappings. Buttons can be created by - * instantiating a {@link GenericHID} or one of its subclasses ({@link - * edu.wpi.first.wpilibj.Joystick} or {@link XboxController}), and then passing it to a {@link - * edu.wpi.first.wpilibj2.command.button.JoystickButton}. + * Use this method to define your trigger->command mappings. Triggers can be created via the + * {@link Trigger#Trigger(java.util.function.BooleanSupplier)} constructor with an arbitrary + * predicate, or via the named factories in {@link + * edu.wpi.first.wpilibj2.command.button.CommandGenericHID}'s subclasses for {@link + * CommandXboxController Xbox}/{@link edu.wpi.first.wpilibj2.command.button.CommandPS4Controller + * PS4} controllers or {@link edu.wpi.first.wpilibj2.command.button.CommandJoystick Flight + * joysticks}. */ - private void configureBindings() {} + private void configureBindings() { + // Schedule `ExampleCommand` when `exampleCondition` changes to `true` + new Trigger(m_exampleSubsystem::exampleCondition) + .onTrue(new ExampleCommand(m_exampleSubsystem)); + + // Schedule `exampleMethodCommand` when the Xbox controller's B button is pressed, + // cancelling on release. + m_driverController.b().whileTrue(m_exampleSubsystem.exampleMethodCommand()); + } /** * Use this to pass the autonomous command to the main {@link Robot} class. diff --git a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/commandbased/subsystems/ExampleSubsystem.java b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/commandbased/subsystems/ExampleSubsystem.java index 91719b2752..57d86cc1c7 100644 --- a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/commandbased/subsystems/ExampleSubsystem.java +++ b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/templates/commandbased/subsystems/ExampleSubsystem.java @@ -25,6 +25,16 @@ public class ExampleSubsystem extends SubsystemBase { }); } + /** + * An example method querying a boolean state of the subsystem (for example, a digital sensor). + * + * @return value of some boolean subsystem state, such as a digital sensor. + */ + public boolean exampleCondition() { + // Query some boolean state, such as a digital sensor. + return false; + } + @Override public void periodic() { // This method will be called once per scheduler run