From aa40d98ff3479bee57baeea43729cb77674ee2ea Mon Sep 17 00:00:00 2001 From: David Baucum Date: Fri, 7 Apr 2023 14:38:15 -0400 Subject: [PATCH 1/6] Add support for the PS5 DualSense controller --- hal/src/generate/ResourceType.txt | 1 + shared/examplecheck.gradle | 2 +- .../command/button/CommandPS5Controller.java | 389 ++++++++++ .../command/button/CommandPS5Controller.cpp | 63 ++ .../command/button/CommandPS5Controller.h | 178 +++++ wpilibc/src/main/native/cpp/PS5Controller.cpp | 263 +++++++ .../cpp/simulation/PS5ControllerSim.cpp | 103 +++ .../main/native/include/frc/PS5Controller.h | 529 +++++++++++++ .../include/frc/simulation/PS5ControllerSim.h | 176 +++++ .../src/test/native/cpp/PS5ControllerTest.cpp | 37 + .../edu/wpi/first/wpilibj/PS5Controller.java | 699 ++++++++++++++++++ .../wpilibj/simulation/PS5ControllerSim.java | 214 ++++++ .../wpi/first/wpilibj/PS5ControllerTest.java | 79 ++ 13 files changed, 2732 insertions(+), 1 deletion(-) create mode 100644 wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/button/CommandPS5Controller.java create mode 100644 wpilibNewCommands/src/main/native/cpp/frc2/command/button/CommandPS5Controller.cpp create mode 100644 wpilibNewCommands/src/main/native/include/frc2/command/button/CommandPS5Controller.h create mode 100644 wpilibc/src/main/native/cpp/PS5Controller.cpp create mode 100644 wpilibc/src/main/native/cpp/simulation/PS5ControllerSim.cpp create mode 100644 wpilibc/src/main/native/include/frc/PS5Controller.h create mode 100644 wpilibc/src/main/native/include/frc/simulation/PS5ControllerSim.h create mode 100644 wpilibc/src/test/native/cpp/PS5ControllerTest.cpp create mode 100644 wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java create mode 100644 wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PS5ControllerSim.java create mode 100644 wpilibj/src/test/java/edu/wpi/first/wpilibj/PS5ControllerTest.java diff --git a/hal/src/generate/ResourceType.txt b/hal/src/generate/ResourceType.txt index f48cb596d06..9089b3c235e 100644 --- a/hal/src/generate/ResourceType.txt +++ b/hal/src/generate/ResourceType.txt @@ -93,3 +93,4 @@ kResourceType_DutyCycle = 91 kResourceType_AddressableLEDs = 92 kResourceType_FusionVenom = 93 kResourceType_PS4Controller = 94 +kResourceType_PS5Controller = 95 diff --git a/shared/examplecheck.gradle b/shared/examplecheck.gradle index 4635d050570..7f8c157626f 100644 --- a/shared/examplecheck.gradle +++ b/shared/examplecheck.gradle @@ -77,7 +77,7 @@ def tagList = [ "Digital Output", /* --- HID --- */ - "XboxController", "PS4Controller", "Joystick", + "XboxController", "PS4Controller", "PS5Controller", "Joystick", /* --- Misc --- */ /* (try to keep this section minimal) */ diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/button/CommandPS5Controller.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/button/CommandPS5Controller.java new file mode 100644 index 00000000000..6b149d62b4b --- /dev/null +++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/button/CommandPS5Controller.java @@ -0,0 +1,389 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +package edu.wpi.first.wpilibj2.command.button; + +import edu.wpi.first.wpilibj.PS5Controller; +import edu.wpi.first.wpilibj.event.EventLoop; +import edu.wpi.first.wpilibj2.command.CommandScheduler; + +/** + * A version of {@link PS5Controller} with {@link Trigger} factories for command-based. + * + * @see PS5Controller + */ +@SuppressWarnings("MethodName") +public class CommandPS5Controller extends CommandGenericHID { + private final PS5Controller m_hid; + + /** + * Construct an instance of a device. + * + * @param port The port index on the Driver Station that the device is plugged into. + */ + public CommandPS5Controller(int port) { + super(port); + m_hid = new PS5Controller(port); + } + + /** + * Get the underlying GenericHID object. + * + * @return the wrapped GenericHID object + */ + @Override + public PS5Controller getHID() { + return m_hid; + } + + /** + * Constructs an event instance around the L2 button's digital signal. + * + * @return an event instance representing the L2 button's digital signal attached to the {@link + * CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger L2() { + return L2(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the L2 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the L2 button's digital signal attached to the given + * loop. + */ + public Trigger L2(EventLoop loop) { + return m_hid.L2(loop).castTo(Trigger::new); + } + + /** + * Constructs an event instance around the R2 button's digital signal. + * + * @return an event instance representing the R2 button's digital signal attached to the {@link + * CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger R2() { + return R2(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the R2 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the R2 button's digital signal attached to the given + * loop. + */ + public Trigger R2(EventLoop loop) { + return m_hid.R2(loop).castTo(Trigger::new); + } + + /** + * Constructs an event instance around the L1 button's digital signal. + * + * @return an event instance representing the L1 button's digital signal attached to the {@link + * CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger L1() { + return L1(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the L1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the L1 button's digital signal attached to the given + * loop. + */ + public Trigger L1(EventLoop loop) { + return m_hid.L1(loop).castTo(Trigger::new); + } + + /** + * Constructs an event instance around the R1 button's digital signal. + * + * @return an event instance representing the R1 button's digital signal attached to the {@link + * CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger R1() { + return R1(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the R1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the R1 button's digital signal attached to the given + * loop. + */ + public Trigger R1(EventLoop loop) { + return m_hid.R1(loop).castTo(Trigger::new); + } + + /** + * Constructs an event instance around the L3 button's digital signal. + * + * @return an event instance representing the L3 button's digital signal attached to the {@link + * CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger L3() { + return L3(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the L3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the L3 button's digital signal attached to the given + * loop. + */ + public Trigger L3(EventLoop loop) { + return m_hid.L3(loop).castTo(Trigger::new); + } + + /** + * Constructs an event instance around the R3 button's digital signal. + * + * @return an event instance representing the R3 button's digital signal attached to the {@link + * CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger R3() { + return R3(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the R3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the R3 button's digital signal attached to the given + * loop. + */ + public Trigger R3(EventLoop loop) { + return m_hid.R3(loop).castTo(Trigger::new); + } + + /** + * Constructs an event instance around the square button's digital signal. + * + * @return an event instance representing the square button's digital signal attached to the + * {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger square() { + return square(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the square button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the square button's digital signal attached to the given + * loop. + */ + public Trigger square(EventLoop loop) { + return m_hid.square(loop).castTo(Trigger::new); + } + + /** + * Constructs an event instance around the cross button's digital signal. + * + * @return an event instance representing the cross button's digital signal attached to the {@link + * CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger cross() { + return cross(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the cross button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the cross button's digital signal attached to the given + * loop. + */ + public Trigger cross(EventLoop loop) { + return m_hid.cross(loop).castTo(Trigger::new); + } + + /** + * Constructs an event instance around the triangle button's digital signal. + * + * @return an event instance representing the triangle button's digital signal attached to the + * {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger triangle() { + return triangle(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the triangle button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the triangle button's digital signal attached to the + * given loop. + */ + public Trigger triangle(EventLoop loop) { + return m_hid.triangle(loop).castTo(Trigger::new); + } + + /** + * Constructs an event instance around the circle button's digital signal. + * + * @return an event instance representing the circle button's digital signal attached to the + * {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger circle() { + return circle(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the circle button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the circle button's digital signal attached to the given + * loop. + */ + public Trigger circle(EventLoop loop) { + return m_hid.circle(loop).castTo(Trigger::new); + } + + /** + * Constructs an event instance around the create button's digital signal. + * + * @return an event instance representing the create button's digital signal attached to the + * {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger create() { + return create(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the create button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the create button's digital signal attached to the given + * loop. + */ + public Trigger create(EventLoop loop) { + return m_hid.create(loop).castTo(Trigger::new); + } + + /** + * Constructs an event instance around the PS button's digital signal. + * + * @return an event instance representing the PS button's digital signal attached to the {@link + * CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger PS() { + return PS(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the PS button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the PS button's digital signal attached to the given + * loop. + */ + public Trigger PS(EventLoop loop) { + return m_hid.PS(loop).castTo(Trigger::new); + } + + /** + * Constructs an event instance around the options button's digital signal. + * + * @return an event instance representing the options button's digital signal attached to the + * {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger options() { + return options(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the options button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the options button's digital signal attached to the + * given loop. + */ + public Trigger options(EventLoop loop) { + return m_hid.options(loop).castTo(Trigger::new); + } + + /** + * Constructs an event instance around the touchpad's digital signal. + * + * @return an event instance representing the touchpad's digital signal attached to the {@link + * CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + */ + public Trigger touchpad() { + return touchpad(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs an event instance around the touchpad's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the touchpad's digital signal attached to the given + * loop. + */ + public Trigger touchpad(EventLoop loop) { + return m_hid.touchpad(loop).castTo(Trigger::new); + } + + /** + * Get the X axis value of left side of the controller. + * + * @return the axis value. + */ + public double getLeftX() { + return m_hid.getLeftX(); + } + + /** + * Get the X axis value of right side of the controller. + * + * @return the axis value. + */ + public double getRightX() { + return m_hid.getRightX(); + } + + /** + * Get the Y axis value of left side of the controller. + * + * @return the axis value. + */ + public double getLeftY() { + return m_hid.getLeftY(); + } + + /** + * Get the Y axis value of right side of the controller. + * + * @return the axis value. + */ + public double getRightY() { + return m_hid.getRightY(); + } + + /** + * Get the L2 axis value of the controller. Note that this axis is bound to the range of [0, 1] as + * opposed to the usual [-1, 1]. + * + * @return the axis value. + */ + public double getL2Axis() { + return m_hid.getL2Axis(); + } + + /** + * Get the R2 axis value of the controller. Note that this axis is bound to the range of [0, 1] as + * opposed to the usual [-1, 1]. + * + * @return the axis value. + */ + public double getR2Axis() { + return m_hid.getR2Axis(); + } +} diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/button/CommandPS5Controller.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/button/CommandPS5Controller.cpp new file mode 100644 index 00000000000..399a771ddcd --- /dev/null +++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/button/CommandPS5Controller.cpp @@ -0,0 +1,63 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#include "frc2/command/button/CommandPS5Controller.h" + +using namespace frc2; + +Trigger CommandPS5Controller::Button(int button, frc::EventLoop* loop) const { + return GenericHID::Button(button, loop).CastTo(); +} + +Trigger CommandPS5Controller::Square(frc::EventLoop* loop) const { + return PS5Controller::Square(loop).CastTo(); +} + +Trigger CommandPS5Controller::Cross(frc::EventLoop* loop) const { + return PS5Controller::Cross(loop).CastTo(); +} + +Trigger CommandPS5Controller::Circle(frc::EventLoop* loop) const { + return PS5Controller::Circle(loop).CastTo(); +} + +Trigger CommandPS5Controller::Triangle(frc::EventLoop* loop) const { + return PS5Controller::Triangle(loop).CastTo(); +} + +Trigger CommandPS5Controller::L1(frc::EventLoop* loop) const { + return PS5Controller::L1(loop).CastTo(); +} + +Trigger CommandPS5Controller::R1(frc::EventLoop* loop) const { + return PS5Controller::R1(loop).CastTo(); +} + +Trigger CommandPS5Controller::L2(frc::EventLoop* loop) const { + return PS5Controller::L2(loop).CastTo(); +} + +Trigger CommandPS5Controller::R2(frc::EventLoop* loop) const { + return PS5Controller::R2(loop).CastTo(); +} + +Trigger CommandPS5Controller::Options(frc::EventLoop* loop) const { + return PS5Controller::Options(loop).CastTo(); +} + +Trigger CommandPS5Controller::L3(frc::EventLoop* loop) const { + return PS5Controller::L3(loop).CastTo(); +} + +Trigger CommandPS5Controller::R3(frc::EventLoop* loop) const { + return PS5Controller::R3(loop).CastTo(); +} + +Trigger CommandPS5Controller::PS(frc::EventLoop* loop) const { + return PS5Controller::PS(loop).CastTo(); +} + +Trigger CommandPS5Controller::Touchpad(frc::EventLoop* loop) const { + return PS5Controller::Touchpad(loop).CastTo(); +} diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/button/CommandPS5Controller.h b/wpilibNewCommands/src/main/native/include/frc2/command/button/CommandPS5Controller.h new file mode 100644 index 00000000000..d86d38388b5 --- /dev/null +++ b/wpilibNewCommands/src/main/native/include/frc2/command/button/CommandPS5Controller.h @@ -0,0 +1,178 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#pragma once +#include + +#include "Trigger.h" +#include "frc2/command/CommandScheduler.h" + +namespace frc2 { +/** + * A version of {@link PS5Controller} with {@link Trigger} factories for + * command-based. + * + * @see PS5Controller + */ +class CommandPS5Controller : public frc::PS5Controller { + public: + using PS5Controller::PS5Controller; + + /** + * Constructs an event instance around this button's digital signal. + * + * @param button the button index + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the button's digital signal attached + * to the given loop. + */ + Trigger Button(int button, + frc::EventLoop* loop = CommandScheduler::GetInstance() + .GetDefaultButtonLoop()) const; + + /** + * Constructs an event instance around the square button's digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the square button's digital signal + * attached to the given loop. + */ + Trigger Square(frc::EventLoop* loop = CommandScheduler::GetInstance() + .GetDefaultButtonLoop()) const; + + /** + * Constructs an event instance around the cross button's digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the cross button's digital signal + * attached to the given loop. + */ + Trigger Cross(frc::EventLoop* loop = CommandScheduler::GetInstance() + .GetDefaultButtonLoop()) const; + + /** + * Constructs an event instance around the circle button's digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the circle button's digital signal + * attached to the given loop. + */ + Trigger Circle(frc::EventLoop* loop = CommandScheduler::GetInstance() + .GetDefaultButtonLoop()) const; + + /** + * Constructs an event instance around the triangle button's digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the triangle button's digital signal + * attached to the given loop. + */ + Trigger Triangle(frc::EventLoop* loop = CommandScheduler::GetInstance() + .GetDefaultButtonLoop()) const; + + /** + * Constructs an event instance around the L1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the L1 button's digital signal + * attached to the given loop. + */ + Trigger L1(frc::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs an event instance around the R1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the R1 button's digital signal + * attached to the given loop. + */ + Trigger R1(frc::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs an event instance around the L2 button's digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the L2 button's digital signal + * attached to the given loop. + */ + Trigger L2(frc::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs an event instance around the R2 button's digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the R2 button's digital signal + * attached to the given loop. + */ + Trigger R2(frc::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs an event instance around the options button's digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the options button's digital signal + * attached to the given loop. + */ + Trigger Options(frc::EventLoop* loop = CommandScheduler::GetInstance() + .GetDefaultButtonLoop()) const; + + /** + * Constructs an event instance around the L3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the L3 button's digital signal + * attached to the given loop. + */ + Trigger L3(frc::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs an event instance around the R3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the R3 button's digital signal + * attached to the given loop. + */ + Trigger R3(frc::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs an event instance around the PS button's digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the PS button's digital signal + * attached to the given loop. + */ + Trigger PS(frc::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs an event instance around the touchpad's digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return an event instance representing the touchpad's digital signal + * attached to the given loop. + */ + Trigger Touchpad(frc::EventLoop* loop = CommandScheduler::GetInstance() + .GetDefaultButtonLoop()) const; +}; +} // namespace frc2 diff --git a/wpilibc/src/main/native/cpp/PS5Controller.cpp b/wpilibc/src/main/native/cpp/PS5Controller.cpp new file mode 100644 index 00000000000..16da518a6d8 --- /dev/null +++ b/wpilibc/src/main/native/cpp/PS5Controller.cpp @@ -0,0 +1,263 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#include "frc/PS5Controller.h" + +#include + +#include "frc/event/BooleanEvent.h" + +using namespace frc; + +PS5Controller::PS5Controller(int port) : GenericHID(port) { + HAL_Report(HALUsageReporting::kResourceType_PS5Controller, port + 1); +} + +double PS5Controller::GetLeftX() const { + return GetRawAxis(Axis::kLeftX); +} + +double PS5Controller::GetRightX() const { + return GetRawAxis(Axis::kRightX); +} + +double PS5Controller::GetLeftY() const { + return GetRawAxis(Axis::kLeftY); +} + +double PS5Controller::GetRightY() const { + return GetRawAxis(Axis::kRightY); +} + +double PS5Controller::GetL2Axis() const { + return GetRawAxis(Axis::kL2); +} + +double PS5Controller::GetR2Axis() const { + return GetRawAxis(Axis::kR2); +} + +bool PS5Controller::GetSquareButton() const { + return GetRawButton(Button::kSquare); +} + +bool PS5Controller::GetSquareButtonPressed() { + return GetRawButtonPressed(Button::kSquare); +} + +bool PS5Controller::GetSquareButtonReleased() { + return GetRawButtonReleased(Button::kSquare); +} + +BooleanEvent PS5Controller::Square(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetSquareButton(); }); +} + +bool PS5Controller::GetCrossButton() const { + return GetRawButton(Button::kCross); +} + +bool PS5Controller::GetCrossButtonPressed() { + return GetRawButtonPressed(Button::kCross); +} + +bool PS5Controller::GetCrossButtonReleased() { + return GetRawButtonReleased(Button::kCross); +} + +BooleanEvent PS5Controller::Cross(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetCrossButton(); }); +} + +bool PS5Controller::GetCircleButton() const { + return GetRawButton(Button::kCircle); +} + +bool PS5Controller::GetCircleButtonPressed() { + return GetRawButtonPressed(Button::kCircle); +} + +bool PS5Controller::GetCircleButtonReleased() { + return GetRawButtonReleased(Button::kCircle); +} + +BooleanEvent PS5Controller::Circle(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetCircleButton(); }); +} + +bool PS5Controller::GetTriangleButton() const { + return GetRawButton(Button::kTriangle); +} + +bool PS5Controller::GetTriangleButtonPressed() { + return GetRawButtonPressed(Button::kTriangle); +} + +bool PS5Controller::GetTriangleButtonReleased() { + return GetRawButtonReleased(Button::kTriangle); +} + +BooleanEvent PS5Controller::Triangle(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetTriangleButton(); }); +} + +bool PS5Controller::GetL1Button() const { + return GetRawButton(Button::kL1); +} + +bool PS5Controller::GetL1ButtonPressed() { + return GetRawButtonPressed(Button::kL1); +} + +bool PS5Controller::GetL1ButtonReleased() { + return GetRawButtonReleased(Button::kL1); +} + +BooleanEvent PS5Controller::L1(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetL1Button(); }); +} + +bool PS5Controller::GetR1Button() const { + return GetRawButton(Button::kR1); +} + +bool PS5Controller::GetR1ButtonPressed() { + return GetRawButtonPressed(Button::kR1); +} + +bool PS5Controller::GetR1ButtonReleased() { + return GetRawButtonReleased(Button::kR1); +} + +BooleanEvent PS5Controller::R1(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetR1Button(); }); +} + +bool PS5Controller::GetL2Button() const { + return GetRawButton(Button::kL2); +} + +bool PS5Controller::GetL2ButtonPressed() { + return GetRawButtonPressed(Button::kL2); +} + +bool PS5Controller::GetL2ButtonReleased() { + return GetRawButtonReleased(Button::kL2); +} + +BooleanEvent PS5Controller::L2(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetL2Button(); }); +} + +bool PS5Controller::GetR2Button() const { + return GetRawButton(Button::kR2); +} + +bool PS5Controller::GetR2ButtonPressed() { + return GetRawButtonPressed(Button::kR2); +} + +bool PS5Controller::GetR2ButtonReleased() { + return GetRawButtonReleased(Button::kR2); +} + +BooleanEvent PS5Controller::R2(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetR2Button(); }); +} + +bool PS5Controller::GetCreateButton() const { + return GetRawButton(Button::kCreate); +} + +bool PS5Controller::GetCreateButtonPressed() { + return GetRawButtonPressed(Button::kCreate); +} + +bool PS5Controller::GetCreateButtonReleased() { + return GetRawButtonReleased(Button::kCreate); +} + +BooleanEvent PS5Controller::Create(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetCreateButton(); }); +} + +bool PS5Controller::GetOptionsButton() const { + return GetRawButton(Button::kOptions); +} + +bool PS5Controller::GetOptionsButtonPressed() { + return GetRawButtonPressed(Button::kOptions); +} + +bool PS5Controller::GetOptionsButtonReleased() { + return GetRawButtonReleased(Button::kOptions); +} + +BooleanEvent PS5Controller::Options(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetOptionsButton(); }); +} + +bool PS5Controller::GetL3Button() const { + return GetRawButton(Button::kL3); +} + +bool PS5Controller::GetL3ButtonPressed() { + return GetRawButtonPressed(Button::kL3); +} + +bool PS5Controller::GetL3ButtonReleased() { + return GetRawButtonReleased(Button::kL3); +} + +BooleanEvent PS5Controller::L3(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetL3Button(); }); +} + +bool PS5Controller::GetR3Button() const { + return GetRawButton(Button::kR3); +} + +bool PS5Controller::GetR3ButtonPressed() { + return GetRawButtonPressed(Button::kR3); +} + +bool PS5Controller::GetR3ButtonReleased() { + return GetRawButtonReleased(Button::kR3); +} + +BooleanEvent PS5Controller::R3(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetR3Button(); }); +} + +bool PS5Controller::GetPSButton() const { + return GetRawButton(Button::kPS); +} + +bool PS5Controller::GetPSButtonPressed() { + return GetRawButtonPressed(Button::kPS); +} + +bool PS5Controller::GetPSButtonReleased() { + return GetRawButtonReleased(Button::kPS); +} + +BooleanEvent PS5Controller::PS(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetPSButton(); }); +} + +bool PS5Controller::GetTouchpad() const { + return GetRawButton(Button::kTouchpad); +} + +bool PS5Controller::GetTouchpadPressed() { + return GetRawButtonPressed(Button::kTouchpad); +} + +bool PS5Controller::GetTouchpadReleased() { + return GetRawButtonReleased(Button::kTouchpad); +} + +BooleanEvent PS5Controller::Touchpad(EventLoop* loop) const { + return BooleanEvent(loop, [this]() { return this->GetTouchpad(); }); +} diff --git a/wpilibc/src/main/native/cpp/simulation/PS5ControllerSim.cpp b/wpilibc/src/main/native/cpp/simulation/PS5ControllerSim.cpp new file mode 100644 index 00000000000..e20105c4b3d --- /dev/null +++ b/wpilibc/src/main/native/cpp/simulation/PS5ControllerSim.cpp @@ -0,0 +1,103 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#include "frc/simulation/PS5ControllerSim.h" + +#include "frc/PS5Controller.h" + +using namespace frc; +using namespace frc::sim; + +PS5ControllerSim::PS5ControllerSim(const PS5Controller& joystick) + : GenericHIDSim{joystick} { + SetAxisCount(6); + SetButtonCount(14); + SetPOVCount(1); +} + +PS5ControllerSim::PS5ControllerSim(int port) : GenericHIDSim{port} { + SetAxisCount(6); + SetButtonCount(14); + SetPOVCount(1); +} + +void PS5ControllerSim::SetLeftX(double value) { + SetRawAxis(PS5Controller::Axis::kLeftX, value); +} + +void PS5ControllerSim::SetRightX(double value) { + SetRawAxis(PS5Controller::Axis::kRightX, value); +} + +void PS5ControllerSim::SetLeftY(double value) { + SetRawAxis(PS5Controller::Axis::kLeftY, value); +} + +void PS5ControllerSim::SetRightY(double value) { + SetRawAxis(PS5Controller::Axis::kRightY, value); +} + +void PS5ControllerSim::SetL2Axis(double value) { + SetRawAxis(PS5Controller::Axis::kL2, value); +} + +void PS5ControllerSim::SetR2Axis(double value) { + SetRawAxis(PS5Controller::Axis::kR2, value); +} + +void PS5ControllerSim::SetSquareButton(bool value) { + SetRawButton(PS5Controller::Button::kSquare, value); +} + +void PS5ControllerSim::SetCrossButton(bool value) { + SetRawButton(PS5Controller::Button::kCross, value); +} + +void PS5ControllerSim::SetCircleButton(bool value) { + SetRawButton(PS5Controller::Button::kCircle, value); +} + +void PS5ControllerSim::SetTriangleButton(bool value) { + SetRawButton(PS5Controller::Button::kTriangle, value); +} + +void PS5ControllerSim::SetL1Button(bool value) { + SetRawButton(PS5Controller::Button::kL1, value); +} + +void PS5ControllerSim::SetR1Button(bool value) { + SetRawButton(PS5Controller::Button::kR1, value); +} + +void PS5ControllerSim::SetL2Button(bool value) { + SetRawButton(PS5Controller::Button::kL2, value); +} + +void PS5ControllerSim::SetR2Button(bool value) { + SetRawButton(PS5Controller::Button::kR2, value); +} + +void PS5ControllerSim::SetCreateButton(bool value) { + SetRawButton(PS5Controller::Button::kCreate, value); +} + +void PS5ControllerSim::SetOptionsButton(bool value) { + SetRawButton(PS5Controller::Button::kOptions, value); +} + +void PS5ControllerSim::SetL3Button(bool value) { + SetRawButton(PS5Controller::Button::kL3, value); +} + +void PS5ControllerSim::SetR3Button(bool value) { + SetRawButton(PS5Controller::Button::kR3, value); +} + +void PS5ControllerSim::SetPSButton(bool value) { + SetRawButton(PS5Controller::Button::kPS, value); +} + +void PS5ControllerSim::SetTouchpad(bool value) { + SetRawButton(PS5Controller::Button::kTouchpad, value); +} diff --git a/wpilibc/src/main/native/include/frc/PS5Controller.h b/wpilibc/src/main/native/include/frc/PS5Controller.h new file mode 100644 index 00000000000..2a24f5e3612 --- /dev/null +++ b/wpilibc/src/main/native/include/frc/PS5Controller.h @@ -0,0 +1,529 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#pragma once + +#include "frc/GenericHID.h" + +namespace frc { + +/** + * Handle input from PS5 controllers connected to the Driver Station. + * + *

This class handles PS5 input that comes from the Driver Station. Each time + * a value is requested the most recent value is returned. There is a single + * class instance for each controller and the mapping of ports to hardware + * buttons depends on the code in the Driver Station. + */ +class PS5Controller : public GenericHID { + public: + /** + * Construct an instance of an PS5 controller. + * + * The controller index is the USB port on the Driver Station. + * + * @param port The port on the Driver Station that the controller is plugged + * into (0-5). + */ + explicit PS5Controller(int port); + + ~PS5Controller() override = default; + + PS5Controller(PS5Controller&&) = default; + PS5Controller& operator=(PS5Controller&&) = default; + + /** + * Get the X axis value of left side of the controller. + * + * @return the axis value. + */ + double GetLeftX() const; + + /** + * Get the X axis value of right side of the controller. + * + * @return the axis value. + */ + double GetRightX() const; + + /** + * Get the Y axis value of left side of the controller. + * + * @return the axis value. + */ + double GetLeftY() const; + + /** + * Get the Y axis value of right side of the controller. + * + * @return the axis value. + */ + double GetRightY() const; + + /** + * Get the L2 axis value of the controller. Note that this axis is bound to + * the range of [0, 1] as opposed to the usual [-1, 1]. + * + * @return the axis value. + */ + double GetL2Axis() const; + + /** + * Get the R2 axis value of the controller. Note that this axis is bound to + * the range of [0, 1] as opposed to the usual [-1, 1]. + * + * @return the axis value. + */ + double GetR2Axis() const; + + /** + * Read the value of the Square button on the controller. + * + * @return The state of the button. + */ + bool GetSquareButton() const; + + /** + * Whether the Square button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetSquareButtonPressed(); + + /** + * Whether the Square button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetSquareButtonReleased(); + + /** + * Constructs an event instance around the square button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the square button's digital signal + * attached to the given loop. + */ + BooleanEvent Square(EventLoop* loop) const; + + /** + * Read the value of the Cross button on the controller. + * + * @return The state of the button. + */ + bool GetCrossButton() const; + + /** + * Whether the Cross button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetCrossButtonPressed(); + + /** + * Whether the Cross button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetCrossButtonReleased(); + + /** + * Constructs an event instance around the cross button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the cross button's digital signal + * attached to the given loop. + */ + BooleanEvent Cross(EventLoop* loop) const; + + /** + * Read the value of the Circle button on the controller. + * + * @return The state of the button. + */ + bool GetCircleButton() const; + + /** + * Whether the Circle button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetCircleButtonPressed(); + + /** + * Whether the Circle button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetCircleButtonReleased(); + + /** + * Constructs an event instance around the circle button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the circle button's digital signal + * attached to the given loop. + */ + BooleanEvent Circle(EventLoop* loop) const; + + /** + * Read the value of the Triangle button on the controller. + * + * @return The state of the button. + */ + bool GetTriangleButton() const; + + /** + * Whether the Triangle button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetTriangleButtonPressed(); + + /** + * Whether the Triangle button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetTriangleButtonReleased(); + + /** + * Constructs an event instance around the triangle button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the triangle button's digital signal + * attached to the given loop. + */ + BooleanEvent Triangle(EventLoop* loop) const; + + /** + * Read the value of the L1 button on the controller. + * + * @return The state of the button. + */ + bool GetL1Button() const; + + /** + * Whether the L1 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetL1ButtonPressed(); + + /** + * Whether the L1 button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetL1ButtonReleased(); + + /** + * Constructs an event instance around the L1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the L1 button's digital signal + * attached to the given loop. + */ + BooleanEvent L1(EventLoop* loop) const; + + /** + * Read the value of the R1 button on the controller. + * + * @return The state of the button. + */ + bool GetR1Button() const; + + /** + * Whether the R1 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetR1ButtonPressed(); + + /** + * Whether the R1 button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetR1ButtonReleased(); + + /** + * Constructs an event instance around the R1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the R1 button's digital signal + * attached to the given loop. + */ + BooleanEvent R1(EventLoop* loop) const; + + /** + * Read the value of the L2 button on the controller. + * + * @return The state of the button. + */ + bool GetL2Button() const; + + /** + * Whether the L2 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetL2ButtonPressed(); + + /** + * Whether the L2 button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetL2ButtonReleased(); + + /** + * Constructs an event instance around the L2 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the L2 button's digital signal + * attached to the given loop. + */ + BooleanEvent L2(EventLoop* loop) const; + + /** + * Read the value of the R2 button on the controller. + * + * @return The state of the button. + */ + bool GetR2Button() const; + + /** + * Whether the R2 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetR2ButtonPressed(); + + /** + * Whether the R2 button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetR2ButtonReleased(); + + /** + * Constructs an event instance around the R2 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the R2 button's digital signal + * attached to the given loop. + */ + BooleanEvent R2(EventLoop* loop) const; + + /** + * Read the value of the Create button on the controller. + * + * @return The state of the button. + */ + bool GetCreateButton() const; + + /** + * Whether the Create button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetCreateButtonPressed(); + + /** + * Whether the Create button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetCreateButtonReleased(); + + /** + * Constructs an event instance around the Create button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Create button's digital signal + * attached to the given loop. + */ + BooleanEvent Create(EventLoop* loop) const; + + /** + * Read the value of the Options button on the controller. + * + * @return The state of the button. + */ + bool GetOptionsButton() const; + + /** + * Whether the Options button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetOptionsButtonPressed(); + + /** + * Whether the Options button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetOptionsButtonReleased(); + + /** + * Constructs an event instance around the options button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the options button's digital signal + * attached to the given loop. + */ + BooleanEvent Options(EventLoop* loop) const; + + /** + * Read the value of the L3 button (pressing the left analog stick) on the + * controller. + * + * @return The state of the button. + */ + bool GetL3Button() const; + + /** + * Whether the L3 (left stick) button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetL3ButtonPressed(); + + /** + * Whether the L3 (left stick) button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetL3ButtonReleased(); + + /** + * Constructs an event instance around the L3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the L3 button's digital signal + * attached to the given loop. + */ + BooleanEvent L3(EventLoop* loop) const; + + /** + * Read the value of the R3 button (pressing the right analog stick) on the + * controller. + * + * @return The state of the button. + */ + bool GetR3Button() const; + + /** + * Whether the R3 (right stick) button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetR3ButtonPressed(); + + /** + * Whether the R3 (right stick) button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetR3ButtonReleased(); + + /** + * Constructs an event instance around the R3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the R3 button's digital signal + * attached to the given loop. + */ + BooleanEvent R3(EventLoop* loop) const; + + /** + * Read the value of the PS button on the controller. + * + * @return The state of the button. + */ + bool GetPSButton() const; + + /** + * Whether the PS button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetPSButtonPressed(); + + /** + * Whether the PS button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetPSButtonReleased(); + + /** + * Constructs an event instance around the PS button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the PS button's digital signal + * attached to the given loop. + */ + BooleanEvent PS(EventLoop* loop) const; + + /** + * Read the value of the touchpad button on the controller. + * + * @return The state of the button. + */ + bool GetTouchpad() const; + + /** + * Whether the touchpad was pressed since the last check. + * + * @return Whether the touchpad was pressed since the last check. + */ + bool GetTouchpadPressed(); + + /** + * Whether the touchpad was released since the last check. + * + * @return Whether the touchpad was released since the last check. + */ + bool GetTouchpadReleased(); + + /** + * Constructs an event instance around the touchpad's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the touchpad's digital signal + * attached to the given loop. + */ + BooleanEvent Touchpad(EventLoop* loop) const; + + struct Button { + static constexpr int kSquare = 3; + static constexpr int kCross = 1; + static constexpr int kCircle = 2; + static constexpr int kTriangle = 4; + static constexpr int kL1 = 5; + static constexpr int kR1 = 6; + static constexpr int kL2 = 7; + static constexpr int kR2 = 8; + static constexpr int kCreate = 9; + static constexpr int kOptions = 10; + static constexpr int kL3 = 12; + static constexpr int kR3 = 13; + static constexpr int kPS = 11; + static constexpr int kTouchpad = 14; + }; + + struct Axis { + static constexpr int kLeftX = 0; + static constexpr int kLeftY = 1; + static constexpr int kRightX = 3; + static constexpr int kRightY = 4; + static constexpr int kL2 = 2; + static constexpr int kR2 = 5; + }; +}; + +} // namespace frc diff --git a/wpilibc/src/main/native/include/frc/simulation/PS5ControllerSim.h b/wpilibc/src/main/native/include/frc/simulation/PS5ControllerSim.h new file mode 100644 index 00000000000..6b9e2c7b2b3 --- /dev/null +++ b/wpilibc/src/main/native/include/frc/simulation/PS5ControllerSim.h @@ -0,0 +1,176 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#pragma once + +#include "frc/simulation/GenericHIDSim.h" + +namespace frc { + +class PS5Controller; + +namespace sim { + +/** + * Class to control a simulated PS5 controller. + */ +class PS5ControllerSim : public GenericHIDSim { + public: + /** + * Constructs from a PS5Controller object. + * + * @param joystick controller to simulate + */ + explicit PS5ControllerSim(const PS5Controller& joystick); + + /** + * Constructs from a joystick port number. + * + * @param port port number + */ + explicit PS5ControllerSim(int port); + + /** + * Change the X axis value of the controller's left stick. + * + * @param value the new value + */ + void SetLeftX(double value); + + /** + * Change the X axis value of the controller's right stick. + * + * @param value the new value + */ + void SetRightX(double value); + + /** + * Change the Y axis value of the controller's left stick. + * + * @param value the new value + */ + void SetLeftY(double value); + + /** + * Change the Y axis value of the controller's right stick. + * + * @param value the new value + */ + void SetRightY(double value); + + /** + * Change the L2 axis axis value of the controller. + * + * @param value the new value + */ + void SetL2Axis(double value); + + /** + * Change the R2 axis value of the controller. + * + * @param value the new value + */ + void SetR2Axis(double value); + + /** + * Change the value of the Square button on the controller. + * + * @param value the new value + */ + void SetSquareButton(bool value); + + /** + * Change the value of the Cross button on the controller. + * + * @param value the new value + */ + void SetCrossButton(bool value); + + /** + * Change the value of the Circle button on the controller. + * + * @param value the new value + */ + void SetCircleButton(bool value); + + /** + * Change the value of the Triangle button on the controller. + * + * @param value the new value + */ + void SetTriangleButton(bool value); + + /** + * Change the value of the L1 button on the controller. + * + * @param value the new value + */ + void SetL1Button(bool value); + + /** + * Change the value of the R1 button on the controller. + * + * @param value the new value + */ + void SetR1Button(bool value); + + /** + * Change the value of the L2 button on the controller. + * + * @param value the new value + */ + void SetL2Button(bool value); + + /** + * Change the value of the R2 button on the controller. + * + * @param value the new value + */ + void SetR2Button(bool value); + + /** + * Change the value of the Create button on the controller. + * + * @param value the new value + */ + void SetCreateButton(bool value); + + /** + * Change the value of the Options button on the controller. + * + * @param value the new value + */ + void SetOptionsButton(bool value); + + /** + * Change the value of the L3 (left stick) button on the controller. + * + * @param value the new value + */ + void SetL3Button(bool value); + + /** + * Change the value of the R3 (right stick) button on the controller. + * + * @param value the new value + */ + void SetR3Button(bool value); + + /** + * Change the value of the PS button on the controller. + * + * @param value the new value + */ + void SetPSButton(bool value); + + /** + * Change the value of the touchpad button on the controller. + * + * @param value the new value + */ + void SetTouchpad(bool value); +}; + +} // namespace sim +} // namespace frc diff --git a/wpilibc/src/test/native/cpp/PS5ControllerTest.cpp b/wpilibc/src/test/native/cpp/PS5ControllerTest.cpp new file mode 100644 index 00000000000..1d3b150bc1a --- /dev/null +++ b/wpilibc/src/test/native/cpp/PS5ControllerTest.cpp @@ -0,0 +1,37 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#include "frc/PS5Controller.h" // NOLINT(build/include_order) + +#include "JoystickTestMacros.h" +#include "frc/simulation/PS5ControllerSim.h" +#include "gtest/gtest.h" + +using namespace frc; + +BUTTON_TEST(PS5Controller, SquareButton) +BUTTON_TEST(PS5Controller, CrossButton) +BUTTON_TEST(PS5Controller, CircleButton) +BUTTON_TEST(PS5Controller, TriangleButton) + +BUTTON_TEST(PS5Controller, L1Button) +BUTTON_TEST(PS5Controller, R1Button) +BUTTON_TEST(PS5Controller, L2Button) +BUTTON_TEST(PS5Controller, R2Button) + +BUTTON_TEST(PS5Controller, CreateButton) +BUTTON_TEST(PS5Controller, OptionsButton) + +BUTTON_TEST(PS5Controller, L3Button) +BUTTON_TEST(PS5Controller, R3Button) + +BUTTON_TEST(PS5Controller, PSButton) +BUTTON_TEST(PS5Controller, Touchpad) + +AXIS_TEST(PS5Controller, LeftX) +AXIS_TEST(PS5Controller, RightX) +AXIS_TEST(PS5Controller, LeftY) +AXIS_TEST(PS5Controller, RightY) +AXIS_TEST(PS5Controller, L2Axis) +AXIS_TEST(PS5Controller, R2Axis) diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java new file mode 100644 index 00000000000..b210581bf16 --- /dev/null +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java @@ -0,0 +1,699 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +package edu.wpi.first.wpilibj; + +import edu.wpi.first.hal.FRCNetComm.tResourceType; +import edu.wpi.first.hal.HAL; +import edu.wpi.first.wpilibj.event.BooleanEvent; +import edu.wpi.first.wpilibj.event.EventLoop; + +/** + * Handle input from PS5 controllers connected to the Driver Station. + * + *

This class handles PS5 input that comes from the Driver Station. Each time a value is + * requested the most recent value is returned. There is a single class instance for each controller + * and the mapping of ports to hardware buttons depends on the code in the Driver Station. + */ +public class PS5Controller extends GenericHID { + /** + * Construct an instance of a device. + * + * @param port The port index on the Driver Station that the device is plugged into. + */ + public PS5Controller(int port) { + super(port); + HAL.report(tResourceType.kResourceType_PS5Controller, port + 1); + } + + /** Represents a digital button on a PS5Controller. */ + public enum Button { + kCross(1), + kCircle(2), + kSquare(3), + kTriangle(4), + kL1(5), + kR1(6), + kL2(7), + kR2(8), + kCreate(9), + kOptions(10), + kPS(11), + kL3(12), + kR3(13), + kTouchpad(14); + + public final int value; + + Button(int index) { + this.value = index; + } + + /** + * Get the human-friendly name of the button, matching the relevant methods. This is done by + * stripping the leading `k`, and if not the touchpad append `Button`. + * + *

Primarily used for automated unit tests. + * + * @return the human-friendly name of the button. + */ + @Override + public String toString() { + var name = this.name().substring(1); // Remove leading `k` + if (this == kTouchpad) { + return name; + } + return name + "Button"; + } + } + + /** Represents an axis on a PS5Controller. */ + public enum Axis { + kLeftX(0), + kLeftY(1), + kL2(2), + kRightX(3), + kRightY(4), + kR2(5); + + public final int value; + + Axis(int index) { + value = index; + } + + /** + * Get the human-friendly name of the axis, matching the relevant methods. This is done by + * stripping the leading `k`, and if one of L2/R2 append `Axis`. + * + *

Primarily used for automated unit tests. + * + * @return the human-friendly name of the axis. + */ + @Override + public String toString() { + var name = this.name().substring(1); // Remove leading `k` + if (name.endsWith("2")) { + return name + "Axis"; + } + return name; + } + } + + /** + * Get the X axis value of left side of the controller. + * + * @return the axis value. + */ + public double getLeftX() { + return getRawAxis(Axis.kLeftX.value); + } + + /** + * Get the X axis value of right side of the controller. + * + * @return the axis value. + */ + public double getRightX() { + return getRawAxis(Axis.kRightX.value); + } + + /** + * Get the Y axis value of left side of the controller. + * + * @return the axis value. + */ + public double getLeftY() { + return getRawAxis(Axis.kLeftY.value); + } + + /** + * Get the Y axis value of right side of the controller. + * + * @return the axis value. + */ + public double getRightY() { + return getRawAxis(Axis.kRightY.value); + } + + /** + * Get the L2 axis value of the controller. Note that this axis is bound to the range of [0, 1] as + * opposed to the usual [-1, 1]. + * + * @return the axis value. + */ + public double getL2Axis() { + return getRawAxis(Axis.kL2.value); + } + + /** + * Get the R2 axis value of the controller. Note that this axis is bound to the range of [0, 1] as + * opposed to the usual [-1, 1]. + * + * @return the axis value. + */ + public double getR2Axis() { + return getRawAxis(Axis.kR2.value); + } + + /** + * Read the value of the left trigger button on the controller. + * + * @return The state of the button. + */ + public boolean getL2Button() { + return getRawButton(Button.kL2.value); + } + + /** + * Read the value of the right trigger button on the controller. + * + * @return The state of the button. + */ + public boolean getR2Button() { + return getRawButton(Button.kR2.value); + } + + /** + * Whether the L2 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getL2ButtonPressed() { + return getRawButtonPressed(Button.kL2.value); + } + + /** + * Whether the R2 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getR2ButtonPressed() { + return getRawButtonPressed(Button.kR2.value); + } + + /** + * Whether the L2 button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getL2ButtonReleased() { + return getRawButtonReleased(Button.kL2.value); + } + + /** + * Whether the R2 button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getR2ButtonReleased() { + return getRawButtonReleased(Button.kR2.value); + } + + /** + * Constructs an event instance around the L2 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the L2 button's digital signal attached to the given + * loop. + */ + @SuppressWarnings("MethodName") + public BooleanEvent L2(EventLoop loop) { + return new BooleanEvent(loop, this::getL2Button); + } + + /** + * Constructs an event instance around the R2 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the R2 button's digital signal attached to the given + * loop. + */ + @SuppressWarnings("MethodName") + public BooleanEvent R2(EventLoop loop) { + return new BooleanEvent(loop, this::getR2Button); + } + + /** + * Read the value of the L1 button on the controller. + * + * @return The state of the button. + */ + public boolean getL1Button() { + return getRawButton(Button.kL1.value); + } + + /** + * Read the value of the R1 button on the controller. + * + * @return The state of the button. + */ + public boolean getR1Button() { + return getRawButton(Button.kR1.value); + } + + /** + * Whether the L1 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getL1ButtonPressed() { + return getRawButtonPressed(Button.kL1.value); + } + + /** + * Whether the R1 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getR1ButtonPressed() { + return getRawButtonPressed(Button.kR1.value); + } + + /** + * Whether the L1 button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getL1ButtonReleased() { + return getRawButtonReleased(Button.kL1.value); + } + + /** + * Whether the R1 button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getR1ButtonReleased() { + return getRawButtonReleased(Button.kR1.value); + } + + /** + * Constructs an event instance around the L1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the L1 button's digital signal attached to the given + * loop. + */ + @SuppressWarnings("MethodName") + public BooleanEvent L1(EventLoop loop) { + return new BooleanEvent(loop, this::getL1Button); + } + + /** + * Constructs an event instance around the R1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the R1 button's digital signal attached to the given + * loop. + */ + @SuppressWarnings("MethodName") + public BooleanEvent R1(EventLoop loop) { + return new BooleanEvent(loop, this::getR1Button); + } + + /** + * Read the value of the L3 button (pressing the left analog stick) on the controller. + * + * @return The state of the button. + */ + public boolean getL3Button() { + return getRawButton(Button.kL3.value); + } + + /** + * Read the value of the R3 button (pressing the right analog stick) on the controller. + * + * @return The state of the button. + */ + public boolean getR3Button() { + return getRawButton(Button.kR3.value); + } + + /** + * Whether the L3 (left stick) button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getL3ButtonPressed() { + return getRawButtonPressed(Button.kL3.value); + } + + /** + * Whether the R3 (right stick) button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getR3ButtonPressed() { + return getRawButtonPressed(Button.kR3.value); + } + + /** + * Whether the L3 (left stick) button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getL3ButtonReleased() { + return getRawButtonReleased(Button.kL3.value); + } + + /** + * Whether the R3 (right stick) button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getR3ButtonReleased() { + return getRawButtonReleased(Button.kR3.value); + } + + /** + * Constructs an event instance around the L3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the L3 button's digital signal attached to the given + * loop. + */ + @SuppressWarnings("MethodName") + public BooleanEvent L3(EventLoop loop) { + return new BooleanEvent(loop, this::getL3Button); + } + + /** + * Constructs an event instance around the R3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the R3 button's digital signal attached to the given + * loop. + */ + @SuppressWarnings("MethodName") + public BooleanEvent R3(EventLoop loop) { + return new BooleanEvent(loop, this::getR3Button); + } + + /** + * Read the value of the Square button on the controller. + * + * @return The state of the button. + */ + public boolean getSquareButton() { + return getRawButton(Button.kSquare.value); + } + + /** + * Whether the Square button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getSquareButtonPressed() { + return getRawButtonPressed(Button.kSquare.value); + } + + /** + * Whether the Square button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getSquareButtonReleased() { + return getRawButtonReleased(Button.kSquare.value); + } + + /** + * Constructs an event instance around the square button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the square button's digital signal attached to the given + * loop. + */ + public BooleanEvent square(EventLoop loop) { + return new BooleanEvent(loop, this::getSquareButton); + } + + /** + * Read the value of the Cross button on the controller. + * + * @return The state of the button. + */ + public boolean getCrossButton() { + return getRawButton(Button.kCross.value); + } + + /** + * Whether the Cross button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getCrossButtonPressed() { + return getRawButtonPressed(Button.kCross.value); + } + + /** + * Whether the Cross button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getCrossButtonReleased() { + return getRawButtonReleased(Button.kCross.value); + } + + /** + * Constructs an event instance around the cross button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the cross button's digital signal attached to the given + * loop. + */ + public BooleanEvent cross(EventLoop loop) { + return new BooleanEvent(loop, this::getCrossButton); + } + + /** + * Read the value of the Triangle button on the controller. + * + * @return The state of the button. + */ + public boolean getTriangleButton() { + return getRawButton(Button.kTriangle.value); + } + + /** + * Whether the Triangle button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getTriangleButtonPressed() { + return getRawButtonPressed(Button.kTriangle.value); + } + + /** + * Whether the Triangle button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getTriangleButtonReleased() { + return getRawButtonReleased(Button.kTriangle.value); + } + + /** + * Constructs an event instance around the triangle button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the triangle button's digital signal attached to the + * given loop. + */ + public BooleanEvent triangle(EventLoop loop) { + return new BooleanEvent(loop, this::getTriangleButton); + } + + /** + * Read the value of the Circle button on the controller. + * + * @return The state of the button. + */ + public boolean getCircleButton() { + return getRawButton(Button.kCircle.value); + } + + /** + * Whether the Circle button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getCircleButtonPressed() { + return getRawButtonPressed(Button.kCircle.value); + } + + /** + * Whether the Circle button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getCircleButtonReleased() { + return getRawButtonReleased(Button.kCircle.value); + } + + /** + * Constructs an event instance around the circle button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the circle button's digital signal attached to the given + * loop. + */ + public BooleanEvent circle(EventLoop loop) { + return new BooleanEvent(loop, this::getCircleButton); + } + + /** + * Read the value of the share button on the controller. + * + * @return The state of the button. + */ + public boolean getCreateButton() { + return getRawButton(Button.kCreate.value); + } + + /** + * Whether the share button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getCreateButtonPressed() { + return getRawButtonPressed(Button.kCreate.value); + } + + /** + * Whether the share button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getCreateButtonReleased() { + return getRawButtonReleased(Button.kCreate.value); + } + + /** + * Constructs an event instance around the share button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the share button's digital signal attached to the given + * loop. + */ + @SuppressWarnings("MethodName") + public BooleanEvent create(EventLoop loop) { + return new BooleanEvent(loop, this::getCreateButton); + } + + /** + * Read the value of the PS button on the controller. + * + * @return The state of the button. + */ + public boolean getPSButton() { + return getRawButton(Button.kPS.value); + } + + /** + * Whether the PS button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getPSButtonPressed() { + return getRawButtonPressed(Button.kPS.value); + } + + /** + * Whether the PS button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getPSButtonReleased() { + return getRawButtonReleased(Button.kPS.value); + } + + /** + * Constructs an event instance around the PS button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the PS button's digital signal attached to the given + * loop. + */ + @SuppressWarnings("MethodName") + public BooleanEvent PS(EventLoop loop) { + return new BooleanEvent(loop, this::getPSButton); + } + + /** + * Read the value of the options button on the controller. + * + * @return The state of the button. + */ + public boolean getOptionsButton() { + return getRawButton(Button.kOptions.value); + } + + /** + * Whether the options button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getOptionsButtonPressed() { + return getRawButtonPressed(Button.kOptions.value); + } + + /** + * Whether the options button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getOptionsButtonReleased() { + return getRawButtonReleased(Button.kOptions.value); + } + + /** + * Constructs an event instance around the options button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the options button's digital signal attached to the + * given loop. + */ + public BooleanEvent options(EventLoop loop) { + return new BooleanEvent(loop, this::getOptionsButton); + } + + /** + * Read the value of the touchpad on the controller. + * + * @return The state of the touchpad. + */ + public boolean getTouchpad() { + return getRawButton(Button.kTouchpad.value); + } + + /** + * Whether the touchpad was pressed since the last check. + * + * @return Whether the touchpad was pressed since the last check. + */ + public boolean getTouchpadPressed() { + return getRawButtonPressed(Button.kTouchpad.value); + } + + /** + * Whether the touchpad was released since the last check. + * + * @return Whether the touchpad was released since the last check. + */ + public boolean getTouchpadReleased() { + return getRawButtonReleased(Button.kTouchpad.value); + } + + /** + * Constructs an event instance around the touchpad's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the touchpad's digital signal attached to the given + * loop. + */ + public BooleanEvent touchpad(EventLoop loop) { + return new BooleanEvent(loop, this::getTouchpad); + } +} diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PS5ControllerSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PS5ControllerSim.java new file mode 100644 index 00000000000..d886bd6e71b --- /dev/null +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PS5ControllerSim.java @@ -0,0 +1,214 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +package edu.wpi.first.wpilibj.simulation; + +import edu.wpi.first.wpilibj.PS5Controller; + +/** Class to control a simulated PS5 controller. */ +public class PS5ControllerSim extends GenericHIDSim { + /** + * Constructs from a PS5Controller object. + * + * @param joystick controller to simulate + */ + public PS5ControllerSim(PS5Controller joystick) { + super(joystick); + setAxisCount(6); + setButtonCount(14); + setPOVCount(1); + } + + /** + * Constructs from a joystick port number. + * + * @param port port number + */ + public PS5ControllerSim(int port) { + super(port); + setAxisCount(6); + setButtonCount(14); + setPOVCount(1); + } + + /** + * Change the X axis value of the controller's left stick. + * + * @param value the new value + */ + public void setLeftX(double value) { + setRawAxis(PS5Controller.Axis.kLeftX.value, value); + } + + /** + * Change the X axis value of the controller's right stick. + * + * @param value the new value + */ + public void setRightX(double value) { + setRawAxis(PS5Controller.Axis.kRightX.value, value); + } + + /** + * Change the Y axis value of the controller's left stick. + * + * @param value the new value + */ + public void setLeftY(double value) { + setRawAxis(PS5Controller.Axis.kLeftY.value, value); + } + + /** + * Change the Y axis value of the controller's right stick. + * + * @param value the new value + */ + public void setRightY(double value) { + setRawAxis(PS5Controller.Axis.kRightY.value, value); + } + + /** + * Change the L2 axis value of the controller. + * + * @param value the new value + */ + public void setL2Axis(double value) { + setRawAxis(PS5Controller.Axis.kL2.value, value); + } + + /** + * Change the R2 axis value of the controller. + * + * @param value the new value + */ + public void setR2Axis(double value) { + setRawAxis(PS5Controller.Axis.kR2.value, value); + } + + /** + * Change the value of the Square button on the controller. + * + * @param value the new value + */ + public void setSquareButton(boolean value) { + setRawButton(PS5Controller.Button.kSquare.value, value); + } + + /** + * Change the value of the Cross button on the controller. + * + * @param value the new value + */ + public void setCrossButton(boolean value) { + setRawButton(PS5Controller.Button.kCross.value, value); + } + + /** + * Change the value of the Circle button on the controller. + * + * @param value the new value + */ + public void setCircleButton(boolean value) { + setRawButton(PS5Controller.Button.kCircle.value, value); + } + + /** + * Change the value of the Triangle button on the controller. + * + * @param value the new value + */ + public void setTriangleButton(boolean value) { + setRawButton(PS5Controller.Button.kTriangle.value, value); + } + + /** + * Change the value of the L1 button on the controller. + * + * @param value the new value + */ + public void setL1Button(boolean value) { + setRawButton(PS5Controller.Button.kL1.value, value); + } + + /** + * Change the value of the R1 button on the controller. + * + * @param value the new value + */ + public void setR1Button(boolean value) { + setRawButton(PS5Controller.Button.kR1.value, value); + } + + /** + * Change the value of the L2 button on the controller. + * + * @param value the new value + */ + public void setL2Button(boolean value) { + setRawButton(PS5Controller.Button.kL2.value, value); + } + + /** + * Change the value of the R2 button on the controller. + * + * @param value the new value + */ + public void setR2Button(boolean value) { + setRawButton(PS5Controller.Button.kR2.value, value); + } + + /** + * Change the value of the Create button on the controller. + * + * @param value the new value + */ + public void setCreateButton(boolean value) { + setRawButton(PS5Controller.Button.kCreate.value, value); + } + + /** + * Change the value of the Options button on the controller. + * + * @param value the new value + */ + public void setOptionsButton(boolean value) { + setRawButton(PS5Controller.Button.kOptions.value, value); + } + + /** + * Change the value of the L3 (left stick) button on the controller. + * + * @param value the new value + */ + public void setL3Button(boolean value) { + setRawButton(PS5Controller.Button.kL3.value, value); + } + + /** + * Change the value of the R3 (right stick) button on the controller. + * + * @param value the new value + */ + public void setR3Button(boolean value) { + setRawButton(PS5Controller.Button.kR3.value, value); + } + + /** + * Change the value of the PS button on the controller. + * + * @param value the new value + */ + public void setPSButton(boolean value) { + setRawButton(PS5Controller.Button.kPS.value, value); + } + + /** + * Change the value of the touchpad button on the controller. + * + * @param value the new value + */ + public void setTouchpad(boolean value) { + setRawButton(PS5Controller.Button.kTouchpad.value, value); + } +} diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/PS5ControllerTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/PS5ControllerTest.java new file mode 100644 index 00000000000..cb24fbf74ed --- /dev/null +++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/PS5ControllerTest.java @@ -0,0 +1,79 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +package edu.wpi.first.wpilibj; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import edu.wpi.first.hal.HAL; +import edu.wpi.first.wpilibj.simulation.PS5ControllerSim; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +class PS5ControllerTest { + @ParameterizedTest + @EnumSource(value = PS5Controller.Button.class) + void testButtons(PS5Controller.Button button) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + HAL.initialize(500, 0); + PS5Controller joy = new PS5Controller(2); + PS5ControllerSim joysim = new PS5ControllerSim(joy); + + var buttonName = button.toString(); + + String simSetMethodName = "set" + buttonName; + String joyGetMethodName = "get" + buttonName; + String joyPressedMethodName = "get" + buttonName + "Pressed"; + String joyReleasedMethodName = "get" + buttonName + "Released"; + + final Method simSetMethod = joysim.getClass().getMethod(simSetMethodName, boolean.class); + final Method joyGetMethod = joy.getClass().getMethod(joyGetMethodName); + final Method joyPressedMethod = joy.getClass().getMethod(joyPressedMethodName); + final Method joyReleasedMethod = joy.getClass().getMethod(joyReleasedMethodName); + + simSetMethod.invoke(joysim, false); + joysim.notifyNewData(); + assertFalse((Boolean) joyGetMethod.invoke(joy)); + // need to call pressed and released to clear flags + joyPressedMethod.invoke(joy); + joyReleasedMethod.invoke(joy); + + simSetMethod.invoke(joysim, true); + joysim.notifyNewData(); + assertTrue((Boolean) joyGetMethod.invoke(joy)); + assertTrue((Boolean) joyPressedMethod.invoke(joy)); + assertFalse((Boolean) joyReleasedMethod.invoke(joy)); + + simSetMethod.invoke(joysim, false); + joysim.notifyNewData(); + assertFalse((Boolean) joyGetMethod.invoke(joy)); + assertFalse((Boolean) joyPressedMethod.invoke(joy)); + assertTrue((Boolean) joyReleasedMethod.invoke(joy)); + } + + @ParameterizedTest + @EnumSource(value = PS5Controller.Axis.class) + void testAxes(PS5Controller.Axis axis) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + HAL.initialize(500, 0); + PS5Controller joy = new PS5Controller(2); + PS5ControllerSim joysim = new PS5ControllerSim(joy); + + var axisName = axis.toString(); + + String simSetMethodName = "set" + axisName; + String joyGetMethodName = "get" + axisName; + + Method simSetMethod = joysim.getClass().getMethod(simSetMethodName, double.class); + Method joyGetMethod = joy.getClass().getMethod(joyGetMethodName); + + simSetMethod.invoke(joysim, 0.35); + joysim.notifyNewData(); + assertEquals(0.35, (Double) joyGetMethod.invoke(joy), 0.001); + } +} From daf9b01175006bbf51c009d2bce69252abeb5d0d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 06:25:26 +0000 Subject: [PATCH 2/6] Formatting fixes --- wpilibc/src/test/native/cpp/PS5ControllerTest.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wpilibc/src/test/native/cpp/PS5ControllerTest.cpp b/wpilibc/src/test/native/cpp/PS5ControllerTest.cpp index 1d3b150bc1a..67dd0caa98e 100644 --- a/wpilibc/src/test/native/cpp/PS5ControllerTest.cpp +++ b/wpilibc/src/test/native/cpp/PS5ControllerTest.cpp @@ -4,9 +4,10 @@ #include "frc/PS5Controller.h" // NOLINT(build/include_order) +#include + #include "JoystickTestMacros.h" #include "frc/simulation/PS5ControllerSim.h" -#include "gtest/gtest.h" using namespace frc; From 024a0ccf9356d1b20abc45e035de54237cbc07b0 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Thu, 26 Oct 2023 19:12:40 -0700 Subject: [PATCH 3/6] Remove PS5 resource type --- hal/src/generate/ResourceType.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/hal/src/generate/ResourceType.txt b/hal/src/generate/ResourceType.txt index 9089b3c235e..f48cb596d06 100644 --- a/hal/src/generate/ResourceType.txt +++ b/hal/src/generate/ResourceType.txt @@ -93,4 +93,3 @@ kResourceType_DutyCycle = 91 kResourceType_AddressableLEDs = 92 kResourceType_FusionVenom = 93 kResourceType_PS4Controller = 94 -kResourceType_PS5Controller = 95 From 13460a7ace2ec4bdbd527ed769539ab69ff0b206 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Thu, 26 Oct 2023 19:19:07 -0700 Subject: [PATCH 4/6] Comment out PS5 HAL report call --- wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java index b210581bf16..233c67dd381 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java @@ -24,7 +24,7 @@ public class PS5Controller extends GenericHID { */ public PS5Controller(int port) { super(port); - HAL.report(tResourceType.kResourceType_PS5Controller, port + 1); + // HAL.report(tResourceType.kResourceType_PS5Controller, port + 1); } /** Represents a digital button on a PS5Controller. */ From 2a2f0b8a713e26dadff05b311c5355ec6ea1a525 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Thu, 26 Oct 2023 19:29:55 -0700 Subject: [PATCH 5/6] Run javaFormat --- wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java index 233c67dd381..8af98a52295 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java @@ -4,8 +4,6 @@ package edu.wpi.first.wpilibj; -import edu.wpi.first.hal.FRCNetComm.tResourceType; -import edu.wpi.first.hal.HAL; import edu.wpi.first.wpilibj.event.BooleanEvent; import edu.wpi.first.wpilibj.event.EventLoop; From a0b3167c0565a4775f216802a3464e05f972b3cf Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Thu, 26 Oct 2023 19:30:07 -0700 Subject: [PATCH 6/6] Comment out C++ PS5 HAL report call --- wpilibc/src/main/native/cpp/PS5Controller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wpilibc/src/main/native/cpp/PS5Controller.cpp b/wpilibc/src/main/native/cpp/PS5Controller.cpp index 16da518a6d8..95685d677b8 100644 --- a/wpilibc/src/main/native/cpp/PS5Controller.cpp +++ b/wpilibc/src/main/native/cpp/PS5Controller.cpp @@ -11,7 +11,7 @@ using namespace frc; PS5Controller::PS5Controller(int port) : GenericHID(port) { - HAL_Report(HALUsageReporting::kResourceType_PS5Controller, port + 1); + // HAL_Report(HALUsageReporting::kResourceType_PS5Controller, port + 1); } double PS5Controller::GetLeftX() const {