From 97381549e62705892dc33719bafdeadd1076ab12 Mon Sep 17 00:00:00 2001 From: Thad House Date: Thu, 11 Jun 2026 16:06:45 -0700 Subject: [PATCH] [wpilib,cmd] Add new generation for gamepads (#8957) SDL makes these schemas much simpler, so its easier to support more controllers. --- commandsv2/generate.bzl | 1 + commandsv2/generate_hids.py | 165 +++ .../main/java/first_ds_commandhid.java.jinja | 127 ++ .../button/first_ds_commandhid.cpp.jinja | 46 + .../button/first_ds_commandhid.hpp.jinja | 96 ++ .../main/python/first_ds_commandhid.py.jinja | 100 ++ .../button/CommandDualSenseController.java | 562 +++++++++ .../button/CommandXboxController.java | 518 +++++++++ .../button/CommandDualSenseController.cpp | 166 +++ .../button/CommandXboxController.cpp | 154 +++ .../button/CommandDualSenseController.hpp | 355 ++++++ .../button/CommandXboxController.hpp | 329 ++++++ .../main/python/commands2/button/__init__.py | 4 + .../button/commanddualsensecontroller.py | 384 ++++++ .../commands2/button/commandxboxcontroller.py | 356 ++++++ commandsv3/generate_files.py | 105 ++ .../main/java/first_ds_commandhid.java.jinja | 144 +++ .../button/CommandDualSenseController.java | 613 ++++++++++ .../button/CommandXboxController.java | 565 +++++++++ wpilibc/BUILD.bazel | 18 +- wpilibc/CMakeLists.txt | 2 + wpilibc/build.gradle | 14 + wpilibc/generate.bzl | 1 + wpilibc/generate_first_ds_hids.py | 237 ++++ wpilibc/generate_wpilibc.py | 18 + wpilibc/robotpy_pybind_build_info.bzl | 44 + .../cpp/driverstation/first_ds_hid.cpp.jinja | 128 ++ .../cpp/simulation/first_ds_hidsim.cpp.jinja | 38 + .../wpi/driverstation/first_ds_hid.hpp.jinja | 275 +++++ .../wpi/simulation/first_ds_hidsim.hpp.jinja | 53 + .../native/cpp/first_ds_hid_test.cpp.jinja | 31 + .../cpp/driverstation/DualSenseController.cpp | 411 +++++++ .../cpp/driverstation/XboxController.cpp | 369 ++++++ .../cpp/simulation/DualSenseControllerSim.cpp | 120 ++ .../cpp/simulation/XboxControllerSim.cpp | 112 ++ .../wpi/driverstation/DualSenseController.hpp | 825 +++++++++++++ .../wpi/driverstation/XboxController.hpp | 746 ++++++++++++ .../wpi/simulation/DualSenseControllerSim.hpp | 198 ++++ .../wpi/simulation/XboxControllerSim.hpp | 184 +++ .../native/cpp/DualSenseControllerTest.cpp | 50 + .../test/native/cpp/XboxControllerTest.cpp | 48 + wpilibc/src/main/python/pyproject.toml | 4 + .../python/semiwrap/DualSenseController.yml | 144 +++ .../main/python/semiwrap/XboxController.yml | 132 +++ .../simulation/DualSenseControllerSim.yml | 36 + .../semiwrap/simulation/XboxControllerSim.yml | 34 + wpilibc/src/main/python/wpilib/__init__.py | 4 + .../main/python/wpilib/simulation/__init__.py | 4 + .../{cpp => include}/JoystickTestMacros.hpp | 0 wpilibj/BUILD.bazel | 19 +- wpilibj/build.gradle | 1 + wpilibj/generate.bzl | 1 + wpilibj/generate_first_ds_hids.py | 196 ++++ wpilibj/generate_wpilibj.py | 15 + wpilibj/src/generate/first_ds_hids.json | 76 ++ .../src/generate/first_ds_hids.schema.json | 69 ++ .../main/java/first_ds_hid.java.jinja | 352 ++++++ .../main/java/first_ds_hidsim.java.jinja | 67 ++ .../test/java/first_ds_hid_test.java.jinja | 95 ++ .../driverstation/DualSenseController.java | 1034 +++++++++++++++++ .../wpilib/driverstation/XboxController.java | 931 +++++++++++++++ .../simulation/DualSenseControllerSim.java | 251 ++++ .../wpilib/simulation/XboxControllerSim.java | 233 ++++ .../DualSenseControllerTest.java | 95 ++ .../driverstation/XboxControllerTest.java | 95 ++ 65 files changed, 12597 insertions(+), 3 deletions(-) create mode 100644 commandsv2/src/generate/main/java/first_ds_commandhid.java.jinja create mode 100644 commandsv2/src/generate/main/native/cpp/wpi/commands2/button/first_ds_commandhid.cpp.jinja create mode 100644 commandsv2/src/generate/main/native/include/wpi/commands2/button/first_ds_commandhid.hpp.jinja create mode 100644 commandsv2/src/generate/main/python/first_ds_commandhid.py.jinja create mode 100644 commandsv2/src/generated/main/java/org/wpilib/command2/button/CommandDualSenseController.java create mode 100644 commandsv2/src/generated/main/java/org/wpilib/command2/button/CommandXboxController.java create mode 100644 commandsv2/src/generated/main/native/cpp/wpi/commands2/button/CommandDualSenseController.cpp create mode 100644 commandsv2/src/generated/main/native/cpp/wpi/commands2/button/CommandXboxController.cpp create mode 100644 commandsv2/src/generated/main/native/include/wpi/commands2/button/CommandDualSenseController.hpp create mode 100644 commandsv2/src/generated/main/native/include/wpi/commands2/button/CommandXboxController.hpp create mode 100644 commandsv2/src/main/python/commands2/button/commanddualsensecontroller.py create mode 100644 commandsv2/src/main/python/commands2/button/commandxboxcontroller.py create mode 100644 commandsv3/src/generate/main/java/first_ds_commandhid.java.jinja create mode 100644 commandsv3/src/generated/main/java/org/wpilib/command3/button/CommandDualSenseController.java create mode 100644 commandsv3/src/generated/main/java/org/wpilib/command3/button/CommandXboxController.java create mode 100644 wpilibc/generate_first_ds_hids.py create mode 100644 wpilibc/src/generate/main/native/cpp/driverstation/first_ds_hid.cpp.jinja create mode 100644 wpilibc/src/generate/main/native/cpp/simulation/first_ds_hidsim.cpp.jinja create mode 100644 wpilibc/src/generate/main/native/include/wpi/driverstation/first_ds_hid.hpp.jinja create mode 100644 wpilibc/src/generate/main/native/include/wpi/simulation/first_ds_hidsim.hpp.jinja create mode 100644 wpilibc/src/generate/test/native/cpp/first_ds_hid_test.cpp.jinja create mode 100644 wpilibc/src/generated/main/native/cpp/driverstation/DualSenseController.cpp create mode 100644 wpilibc/src/generated/main/native/cpp/driverstation/XboxController.cpp create mode 100644 wpilibc/src/generated/main/native/cpp/simulation/DualSenseControllerSim.cpp create mode 100644 wpilibc/src/generated/main/native/cpp/simulation/XboxControllerSim.cpp create mode 100644 wpilibc/src/generated/main/native/include/wpi/driverstation/DualSenseController.hpp create mode 100644 wpilibc/src/generated/main/native/include/wpi/driverstation/XboxController.hpp create mode 100644 wpilibc/src/generated/main/native/include/wpi/simulation/DualSenseControllerSim.hpp create mode 100644 wpilibc/src/generated/main/native/include/wpi/simulation/XboxControllerSim.hpp create mode 100644 wpilibc/src/generated/test/native/cpp/DualSenseControllerTest.cpp create mode 100644 wpilibc/src/generated/test/native/cpp/XboxControllerTest.cpp create mode 100644 wpilibc/src/main/python/semiwrap/DualSenseController.yml create mode 100644 wpilibc/src/main/python/semiwrap/XboxController.yml create mode 100644 wpilibc/src/main/python/semiwrap/simulation/DualSenseControllerSim.yml create mode 100644 wpilibc/src/main/python/semiwrap/simulation/XboxControllerSim.yml rename wpilibc/src/test/native/{cpp => include}/JoystickTestMacros.hpp (100%) create mode 100644 wpilibj/generate_first_ds_hids.py create mode 100644 wpilibj/src/generate/first_ds_hids.json create mode 100644 wpilibj/src/generate/first_ds_hids.schema.json create mode 100644 wpilibj/src/generate/main/java/first_ds_hid.java.jinja create mode 100644 wpilibj/src/generate/main/java/first_ds_hidsim.java.jinja create mode 100644 wpilibj/src/generate/test/java/first_ds_hid_test.java.jinja create mode 100644 wpilibj/src/generated/main/java/org/wpilib/driverstation/DualSenseController.java create mode 100644 wpilibj/src/generated/main/java/org/wpilib/driverstation/XboxController.java create mode 100644 wpilibj/src/generated/main/java/org/wpilib/simulation/DualSenseControllerSim.java create mode 100644 wpilibj/src/generated/main/java/org/wpilib/simulation/XboxControllerSim.java create mode 100644 wpilibj/src/generated/test/java/org/wpilib/driverstation/DualSenseControllerTest.java create mode 100644 wpilibj/src/generated/test/java/org/wpilib/driverstation/XboxControllerTest.java diff --git a/commandsv2/generate.bzl b/commandsv2/generate.bzl index 0265610ac3..02f595765f 100644 --- a/commandsv2/generate.bzl +++ b/commandsv2/generate.bzl @@ -7,6 +7,7 @@ def __generate_wpilib_new_commands_impl(ctx): args = ctx.actions.args() args.add("--output_directory", output_dir.path) args.add("--template_root", "commandsv2/src/generate") + args.add("--python_output_directory", "__none__") ctx.actions.run( inputs = ctx.attr._templates.files, diff --git a/commandsv2/generate_hids.py b/commandsv2/generate_hids.py index 80d30c8b64..ba503be0ab 100755 --- a/commandsv2/generate_hids.py +++ b/commandsv2/generate_hids.py @@ -6,6 +6,7 @@ import argparse import json +import re from pathlib import Path from jinja2 import Environment, FileSystemLoader @@ -63,6 +64,147 @@ def generate_hids(output_directory: Path, template_directory: Path, schema_file: write_controller_file(root_path, controllerName, output) +def _capitalize_first(name: str) -> str: + return name[0].upper() + name[1:] + + +def _display_name(name: str) -> str: + name = re.sub(r"([a-z0-9])([A-Z])", r"\1 \2", name) + name = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1 \2", name) + name = re.sub(r"([A-Za-z])([0-9])", r"\1 \2", name) + return name[0].upper() + name[1:] + + +def _constant_name(name: str) -> str: + name = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1_\2", name) + name = re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name) + name = re.sub(r"([a-z])([0-9])", r"\1_\2", name) + return name.upper() + + +def _is_trigger_axis(name: str) -> bool: + return name.endswith("Trigger") or name in { + "L2", + "R2", + "ZL", + "ZR", + } + + +def _normalize_command_mapping(mapping: dict[str, int]): + return [ + { + "Name": name, + "MethodName": _capitalize_first(name), + "ConstantName": _constant_name(name), + "DocName": _display_name(name), + "value": value, + } + for name, value in mapping.items() + ] + + +def _normalize_first_ds_command_controller(controller: dict): + buttons = _normalize_command_mapping(controller["buttons"]) + axes = _normalize_command_mapping(controller["axes"]) + button_names = {button["Name"] for button in buttons} + + trigger_axes = [] + for axis in axes: + if not _is_trigger_axis(axis["Name"]): + continue + + name = axis["Name"] + trigger_name = name + trigger_axes.append( + { + "Name": trigger_name, + "MethodName": _capitalize_first(trigger_name), + "DocName": _display_name(trigger_name), + "AxisName": axis["Name"], + "AxisMethodName": axis["MethodName"], + "AxisConstantName": axis["ConstantName"], + "AxisDocName": axis["DocName"], + "HasDefaultThresholdMethod": trigger_name not in button_names, + } + ) + + normalized = dict(controller) + normalized["buttons"] = buttons + normalized["axes"] = axes + normalized["triggerAxes"] = trigger_axes + return normalized + + +def generate_first_ds_hids( + output_directory: Path, + template_directory: Path, + schema_file: Path, + python_output_directory: Path | None = None, +): + with schema_file.open(encoding="utf-8") as f: + controllers = [ + _normalize_first_ds_command_controller(controller) + for controller in json.load(f) + ] + + # Java files + java_subdirectory = "main/java/org/wpilib/command2/button" + env = Environment( + loader=FileSystemLoader(template_directory / "main/java"), + autoescape=False, + keep_trailing_newline=True, + ) + root_path = output_directory / java_subdirectory + template = env.get_template("first_ds_commandhid.java.jinja") + for controller in controllers: + controller_name = f"Command{controller['ClassName']}Controller.java" + output = template.render(controller) + write_controller_file(root_path, controller_name, output) + + # C++ headers + hdr_subdirectory = "main/native/include/wpi/commands2/button" + env = Environment( + loader=FileSystemLoader(template_directory / hdr_subdirectory), + autoescape=False, + keep_trailing_newline=True, + ) + root_path = output_directory / hdr_subdirectory + template = env.get_template("first_ds_commandhid.hpp.jinja") + for controller in controllers: + controller_name = f"Command{controller['ClassName']}Controller.hpp" + output = template.render(controller) + write_controller_file(root_path, controller_name, output) + + # C++ files + cpp_subdirectory = "main/native/cpp/wpi/commands2/button" + env = Environment( + loader=FileSystemLoader(template_directory / cpp_subdirectory), + autoescape=False, + keep_trailing_newline=True, + ) + root_path = output_directory / cpp_subdirectory + template = env.get_template("first_ds_commandhid.cpp.jinja") + for controller in controllers: + controller_name = f"Command{controller['ClassName']}Controller.cpp" + output = template.render(controller) + write_controller_file(root_path, controller_name, output) + + if python_output_directory is not None: + python_subdirectory = "commands2/button" + env = Environment( + loader=FileSystemLoader(template_directory / "main/python"), + autoescape=False, + keep_trailing_newline=True, + ) + root_path = python_output_directory / python_subdirectory + template = env.get_template("first_ds_commandhid.py.jinja") + for controller in controllers: + controller_name = f"command{controller['ClassName'].lower()}controller.py" + output = template.render(controller) + write_controller_file(root_path, controller_name, output) + + def main(): script_path = Path(__file__).resolve() dirname = script_path.parent @@ -86,9 +228,32 @@ def main(): default="wpilibj/src/generate/hids.json", type=Path, ) + parser.add_argument( + "--first_ds_schema_file", + help="Optional. If set, will use this file for the FIRST Driver Station HID schema", + default="wpilibj/src/generate/first_ds_hids.json", + type=Path, + ) + parser.add_argument( + "--python_output_directory", + help="Optional. If set, will output generated Python files to this directory", + default=dirname / "src/main/python", + type=Path, + ) args = parser.parse_args() generate_hids(args.output_directory, args.template_root, args.schema_file) + python_output_directory = ( + None + if args.python_output_directory.name == "__none__" + else args.python_output_directory + ) + generate_first_ds_hids( + args.output_directory, + args.template_root, + args.first_ds_schema_file, + python_output_directory, + ) if __name__ == "__main__": diff --git a/commandsv2/src/generate/main/java/first_ds_commandhid.java.jinja b/commandsv2/src/generate/main/java/first_ds_commandhid.java.jinja new file mode 100644 index 0000000000..e9d09c2621 --- /dev/null +++ b/commandsv2/src/generate/main/java/first_ds_commandhid.java.jinja @@ -0,0 +1,127 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./commandsv2/generate_hids.py. DO NOT MODIFY + +package org.wpilib.command2.button; + +import org.wpilib.command2.CommandScheduler; +import org.wpilib.driverstation.{{ ClassName }}Controller; +import org.wpilib.event.EventLoop; + +/** + * A version of {@link {{ ClassName }}Controller} with {@link Trigger} factories for command-based. + * + * @see {{ ClassName }}Controller + */ +@SuppressWarnings("MethodName") +public class Command{{ ClassName }}Controller { + private final CommandGenericHID m_hid; + private final {{ ClassName }}Controller m_controller; + + /** + * Construct an instance of a controller. + * + * @param port The port index on the Driver Station that the controller is plugged into. + */ + public Command{{ ClassName }}Controller(int port) { + m_hid = CommandGenericHID.getCommandGenericHID(port); + m_controller = new {{ ClassName }}Controller(m_hid.getHID()); + } + + /** + * Get the underlying CommandGenericHID object. + * + * @return the wrapped CommandGenericHID object + */ + public CommandGenericHID getHID() { + return m_hid; + } + + /** + * Get the wrapped controller object. + * + * @return the wrapped controller object + */ + public {{ ClassName }}Controller getController() { + return m_controller; + } +{% for button in buttons %} + /** + * Constructs a Trigger instance around the {{ button.DocName }} button's digital signal. + * + * @return a Trigger instance representing the {{ button.DocName }} button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #{{ button.Name }}(EventLoop) + */ + public Trigger {{ button.Name }}() { + return {{ button.Name }}(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the {{ button.DocName }} button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the {{ button.DocName }} button's digital signal attached + * to the given loop. + */ + public Trigger {{ button.Name }}(EventLoop loop) { + return m_hid.button({{ ClassName }}Controller.Button.{{ button.ConstantName }}.value, loop); + } +{% endfor -%} +{% for trigger in triggerAxes %} + /** + * Constructs a Trigger instance around the axis value of the {{ trigger.DocName }}. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @param loop the event loop instance to attach the Trigger to. + * @return a Trigger instance that is true when the {{ trigger.DocName }} axis exceeds the provided + * threshold, attached to the given event loop + */ + public Trigger {{ trigger.Name }}(double threshold, EventLoop loop) { + return m_hid.axisGreaterThan( + {{ ClassName }}Controller.Axis.{{ trigger.AxisConstantName }}.value, threshold, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the {{ trigger.DocName }}. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @return a Trigger instance that is true when the {{ trigger.DocName }} axis exceeds the provided + * threshold, attached to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler + * button loop}. + */ + public Trigger {{ trigger.Name }}(double threshold) { + return {{ trigger.Name }}(threshold, CommandScheduler.getInstance().getDefaultButtonLoop()); + } +{% if trigger.HasDefaultThresholdMethod %} + + /** + * Constructs a Trigger instance around the axis value of the {{ trigger.DocName }}. The returned + * trigger will be true when the axis value is greater than 0.5. + * + * @return a Trigger instance that is true when the {{ trigger.DocName }} axis exceeds 0.5, + * attached to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button + * loop}. + */ + public Trigger {{ trigger.Name }}() { + return {{ trigger.Name }}(0.5); + } +{% endif -%} +{% endfor -%} +{% for axis in axes %} + /** + * Get the {{ axis.DocName }} value of the controller. + * + * @return The axis value. + */ + public double get{{ axis.MethodName }}() { + return m_controller.get{{ axis.MethodName }}(); + } +{% endfor -%} +} diff --git a/commandsv2/src/generate/main/native/cpp/wpi/commands2/button/first_ds_commandhid.cpp.jinja b/commandsv2/src/generate/main/native/cpp/wpi/commands2/button/first_ds_commandhid.cpp.jinja new file mode 100644 index 0000000000..3f91237113 --- /dev/null +++ b/commandsv2/src/generate/main/native/cpp/wpi/commands2/button/first_ds_commandhid.cpp.jinja @@ -0,0 +1,46 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./commandsv2/generate_hids.py. DO NOT MODIFY +#include "wpi/commands2/button/Command{{ ClassName }}Controller.hpp" + +using namespace wpi::cmd; + +Command{{ ClassName }}Controller::Command{{ ClassName }}Controller(int port) + : m_hid{&CommandGenericHID::GetCommandGenericHID(port)}, + m_controller{m_hid->GetHID()} {} + +CommandGenericHID& Command{{ ClassName }}Controller::GetHID() { + return *m_hid; +} + +wpi::{{ ClassName }}Controller& +Command{{ ClassName }}Controller::GetController() { + return m_controller; +} + +const wpi::{{ ClassName }}Controller& +Command{{ ClassName }}Controller::GetController() const { + return m_controller; +} +{% for button in buttons %} +Trigger Command{{ ClassName }}Controller::{{ button.MethodName }}( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::{{ ClassName }}Controller::Button::{{ button.ConstantName }}, + loop); +} +{% endfor -%} +{% for trigger in triggerAxes %} +Trigger Command{{ ClassName }}Controller::{{ trigger.MethodName }}( + double threshold, wpi::EventLoop* loop) const { + return m_hid->AxisGreaterThan( + wpi::{{ ClassName }}Controller::Axis::{{ trigger.AxisConstantName }}, + threshold, loop); +} +{% endfor -%} +{% for axis in axes %} +double Command{{ ClassName }}Controller::Get{{ axis.MethodName }}() const { + return m_controller.Get{{ axis.MethodName }}(); +} +{% endfor -%} diff --git a/commandsv2/src/generate/main/native/include/wpi/commands2/button/first_ds_commandhid.hpp.jinja b/commandsv2/src/generate/main/native/include/wpi/commands2/button/first_ds_commandhid.hpp.jinja new file mode 100644 index 0000000000..aebc4c2be0 --- /dev/null +++ b/commandsv2/src/generate/main/native/include/wpi/commands2/button/first_ds_commandhid.hpp.jinja @@ -0,0 +1,96 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./commandsv2/generate_hids.py. DO NOT MODIFY +#pragma once + +#include "wpi/driverstation/{{ ClassName }}Controller.hpp" + +#include "wpi/commands2/CommandScheduler.hpp" +#include "wpi/commands2/button/CommandGenericHID.hpp" +#include "wpi/commands2/button/Trigger.hpp" + +namespace wpi::cmd { +/** + * A version of {@link wpi::{{ ClassName }}Controller} with {@link Trigger} + * factories for command-based. + * + * @see wpi::{{ ClassName }}Controller + */ +class Command{{ ClassName }}Controller { + public: + /** + * Construct an instance of a controller. + * + * @param port The port index on the Driver Station that the controller is + * plugged into. + */ + explicit Command{{ ClassName }}Controller(int port); + + /** + * Get the underlying CommandGenericHID object. + * + * @return the wrapped CommandGenericHID object + */ + CommandGenericHID& GetHID(); + + /** + * Get the wrapped controller object. + * + * @return the wrapped controller object + */ + wpi::{{ ClassName }}Controller& GetController(); + + /** + * Get the wrapped controller object. + * + * @return the wrapped controller object + */ + const wpi::{{ ClassName }}Controller& GetController() const; +{% for button in buttons %} + /** + * Constructs a Trigger instance around the {{ button.DocName }} button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the {{ button.DocName }} button's + * digital signal attached to the given loop. + */ + Trigger {{ button.MethodName }}( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; +{% endfor -%} +{% for trigger in triggerAxes %} + /** + * Constructs a Trigger instance around the axis value of the + * {{ trigger.DocName }}. The returned Trigger will be true when the axis value + * is greater than threshold. + * + * @param threshold the minimum axis value for the returned Trigger to be + * true. This value should be in the range [0, 1] where 0 is the unpressed + * state of the axis.{% if trigger.HasDefaultThresholdMethod %} Defaults to 0.5.{% endif %} + * @param loop the event loop instance to attach the Trigger to. Defaults to + * the CommandScheduler's default loop. + * @return a Trigger instance that is true when the {{ trigger.DocName }} axis + * exceeds the provided threshold, attached to the given loop + */ + Trigger {{ trigger.MethodName }}( + double threshold{% if trigger.HasDefaultThresholdMethod %} = 0.5{% endif %}, + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; +{% endfor -%} +{% for axis in axes %} + /** + * Get the {{ axis.DocName }} value of the controller. + * + * @return the axis value. + */ + double Get{{ axis.MethodName }}() const; +{% endfor %} + private: + CommandGenericHID* m_hid; + wpi::{{ ClassName }}Controller m_controller; +}; +} // namespace wpi::cmd diff --git a/commandsv2/src/generate/main/python/first_ds_commandhid.py.jinja b/commandsv2/src/generate/main/python/first_ds_commandhid.py.jinja new file mode 100644 index 0000000000..68b674b393 --- /dev/null +++ b/commandsv2/src/generate/main/python/first_ds_commandhid.py.jinja @@ -0,0 +1,100 @@ +# THIS FILE WAS AUTO-GENERATED BY ./commandsv2/generate_hids.py. DO NOT MODIFY + +from typing import Optional + +from wpilib import EventLoop, {{ ClassName }}Controller + +from .commandgenerichid import CommandGenericHID +from .trigger import Trigger + + +def _enum_value(value) -> int: + try: + return int(value) + except TypeError: + return value.value + + +class Command{{ ClassName }}Controller: + """ + A version of :class:`wpilib.{{ ClassName }}Controller` with :class:`.Trigger` factories for command-based. + """ + + _hid: CommandGenericHID + _controller: {{ ClassName }}Controller + + def __init__(self, port: int): + """ + Construct an instance of a controller. + + :param port: The port index on the Driver Station that the controller is plugged into. + """ + self._hid = CommandGenericHID.getCommandGenericHID(port) + self._controller = {{ ClassName }}Controller(self._hid.getHID()) + + def __getattr__(self, name: str): + return getattr(self._hid, name) + + def getHID(self) -> CommandGenericHID: + """ + Get the underlying CommandGenericHID object. + + :returns: the wrapped CommandGenericHID object + """ + return self._hid + + def getController(self) -> {{ ClassName }}Controller: + """ + Get the wrapped controller object. + + :returns: the wrapped controller object + """ + return self._controller +{% for button in buttons %} + def {{ button.Name }}(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the {{ button.DocName }} button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the {{ button.DocName }} button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value({{ ClassName }}Controller.Button.{{ button.ConstantName }}), loop + ) +{% endfor -%} +{% for trigger in triggerAxes %} + def {{ trigger.Name }}( + self, + threshold: float{% if trigger.HasDefaultThresholdMethod %} = 0.5{% endif %}, + loop: Optional[EventLoop] = None, + ) -> Trigger: + """ + Constructs a Trigger instance around the {{ trigger.DocName }} axis value. The returned + Trigger will be true when the axis value is greater than ``threshold``. + + :param threshold: the minimum axis value for the returned Trigger to be true. This value + should be in the range [0, 1] where 0 is the unpressed state of the axis. + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance that is true when the {{ trigger.DocName }} axis exceeds the + provided threshold, attached to the given event loop. + """ + return self._hid.axisGreaterThan( + _enum_value({{ ClassName }}Controller.Axis.{{ trigger.AxisConstantName }}), + threshold, + loop, + ) +{% endfor -%} +{% for axis in axes %} + def get{{ axis.MethodName }}(self) -> float: + """ + Get the {{ axis.DocName }} value of the controller. + + :returns: the axis value. + """ + return self._controller.get{{ axis.MethodName }}() +{% endfor -%} diff --git a/commandsv2/src/generated/main/java/org/wpilib/command2/button/CommandDualSenseController.java b/commandsv2/src/generated/main/java/org/wpilib/command2/button/CommandDualSenseController.java new file mode 100644 index 0000000000..9d0a934f23 --- /dev/null +++ b/commandsv2/src/generated/main/java/org/wpilib/command2/button/CommandDualSenseController.java @@ -0,0 +1,562 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./commandsv2/generate_hids.py. DO NOT MODIFY + +package org.wpilib.command2.button; + +import org.wpilib.command2.CommandScheduler; +import org.wpilib.driverstation.DualSenseController; +import org.wpilib.event.EventLoop; + +/** + * A version of {@link DualSenseController} with {@link Trigger} factories for command-based. + * + * @see DualSenseController + */ +@SuppressWarnings("MethodName") +public class CommandDualSenseController { + private final CommandGenericHID m_hid; + private final DualSenseController m_controller; + + /** + * Construct an instance of a controller. + * + * @param port The port index on the Driver Station that the controller is plugged into. + */ + public CommandDualSenseController(int port) { + m_hid = CommandGenericHID.getCommandGenericHID(port); + m_controller = new DualSenseController(m_hid.getHID()); + } + + /** + * Get the underlying CommandGenericHID object. + * + * @return the wrapped CommandGenericHID object + */ + public CommandGenericHID getHID() { + return m_hid; + } + + /** + * Get the wrapped controller object. + * + * @return the wrapped controller object + */ + public DualSenseController getController() { + return m_controller; + } + + /** + * Constructs a Trigger instance around the Cross button's digital signal. + * + * @return a Trigger instance representing the Cross button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #cross(EventLoop) + */ + public Trigger cross() { + return cross(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Cross button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Cross button's digital signal attached + * to the given loop. + */ + public Trigger cross(EventLoop loop) { + return m_hid.button(DualSenseController.Button.CROSS.value, loop); + } + + /** + * Constructs a Trigger instance around the Circle button's digital signal. + * + * @return a Trigger instance representing the Circle button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #circle(EventLoop) + */ + public Trigger circle() { + return circle(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Circle button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Circle button's digital signal attached + * to the given loop. + */ + public Trigger circle(EventLoop loop) { + return m_hid.button(DualSenseController.Button.CIRCLE.value, loop); + } + + /** + * Constructs a Trigger instance around the Square button's digital signal. + * + * @return a Trigger instance representing the Square button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #square(EventLoop) + */ + public Trigger square() { + return square(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Square button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Square button's digital signal attached + * to the given loop. + */ + public Trigger square(EventLoop loop) { + return m_hid.button(DualSenseController.Button.SQUARE.value, loop); + } + + /** + * Constructs a Trigger instance around the Triangle button's digital signal. + * + * @return a Trigger instance representing the Triangle button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #triangle(EventLoop) + */ + public Trigger triangle() { + return triangle(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Triangle button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Triangle button's digital signal attached + * to the given loop. + */ + public Trigger triangle(EventLoop loop) { + return m_hid.button(DualSenseController.Button.TRIANGLE.value, loop); + } + + /** + * Constructs a Trigger instance around the Create button's digital signal. + * + * @return a Trigger instance representing the Create button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #create(EventLoop) + */ + public Trigger create() { + return create(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Create button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Create button's digital signal attached + * to the given loop. + */ + public Trigger create(EventLoop loop) { + return m_hid.button(DualSenseController.Button.CREATE.value, loop); + } + + /** + * Constructs a Trigger instance around the PS button's digital signal. + * + * @return a Trigger instance representing the PS button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #PS(EventLoop) + */ + public Trigger PS() { + return PS(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the PS button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the PS button's digital signal attached + * to the given loop. + */ + public Trigger PS(EventLoop loop) { + return m_hid.button(DualSenseController.Button.PS.value, loop); + } + + /** + * Constructs a Trigger instance around the Options button's digital signal. + * + * @return a Trigger instance representing the Options button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #options(EventLoop) + */ + public Trigger options() { + return options(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Options button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Options button's digital signal attached + * to the given loop. + */ + public Trigger options(EventLoop loop) { + return m_hid.button(DualSenseController.Button.OPTIONS.value, loop); + } + + /** + * Constructs a Trigger instance around the L 3 button's digital signal. + * + * @return a Trigger instance representing the L 3 button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #L3(EventLoop) + */ + public Trigger L3() { + return L3(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the L 3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the L 3 button's digital signal attached + * to the given loop. + */ + public Trigger L3(EventLoop loop) { + return m_hid.button(DualSenseController.Button.L3.value, loop); + } + + /** + * Constructs a Trigger instance around the R 3 button's digital signal. + * + * @return a Trigger instance representing the R 3 button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #R3(EventLoop) + */ + public Trigger R3() { + return R3(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the R 3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the R 3 button's digital signal attached + * to the given loop. + */ + public Trigger R3(EventLoop loop) { + return m_hid.button(DualSenseController.Button.R3.value, loop); + } + + /** + * Constructs a Trigger instance around the L 1 button's digital signal. + * + * @return a Trigger instance representing the L 1 button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #L1(EventLoop) + */ + public Trigger L1() { + return L1(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the L 1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the L 1 button's digital signal attached + * to the given loop. + */ + public Trigger L1(EventLoop loop) { + return m_hid.button(DualSenseController.Button.L1.value, loop); + } + + /** + * Constructs a Trigger instance around the R 1 button's digital signal. + * + * @return a Trigger instance representing the R 1 button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #R1(EventLoop) + */ + public Trigger R1() { + return R1(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the R 1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the R 1 button's digital signal attached + * to the given loop. + */ + public Trigger R1(EventLoop loop) { + return m_hid.button(DualSenseController.Button.R1.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Up button's digital signal. + * + * @return a Trigger instance representing the Dpad Up button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #dpadUp(EventLoop) + */ + public Trigger dpadUp() { + return dpadUp(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Up button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Up button's digital signal attached + * to the given loop. + */ + public Trigger dpadUp(EventLoop loop) { + return m_hid.button(DualSenseController.Button.DPAD_UP.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Down button's digital signal. + * + * @return a Trigger instance representing the Dpad Down button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #dpadDown(EventLoop) + */ + public Trigger dpadDown() { + return dpadDown(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Down button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Down button's digital signal attached + * to the given loop. + */ + public Trigger dpadDown(EventLoop loop) { + return m_hid.button(DualSenseController.Button.DPAD_DOWN.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Left button's digital signal. + * + * @return a Trigger instance representing the Dpad Left button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #dpadLeft(EventLoop) + */ + public Trigger dpadLeft() { + return dpadLeft(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Left button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Left button's digital signal attached + * to the given loop. + */ + public Trigger dpadLeft(EventLoop loop) { + return m_hid.button(DualSenseController.Button.DPAD_LEFT.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Right button's digital signal. + * + * @return a Trigger instance representing the Dpad Right button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #dpadRight(EventLoop) + */ + public Trigger dpadRight() { + return dpadRight(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Right button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Right button's digital signal attached + * to the given loop. + */ + public Trigger dpadRight(EventLoop loop) { + return m_hid.button(DualSenseController.Button.DPAD_RIGHT.value, loop); + } + + /** + * Constructs a Trigger instance around the Microphone button's digital signal. + * + * @return a Trigger instance representing the Microphone button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #microphone(EventLoop) + */ + public Trigger microphone() { + return microphone(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Microphone button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Microphone button's digital signal attached + * to the given loop. + */ + public Trigger microphone(EventLoop loop) { + return m_hid.button(DualSenseController.Button.MICROPHONE.value, loop); + } + + /** + * Constructs a Trigger instance around the Touchpad button's digital signal. + * + * @return a Trigger instance representing the Touchpad button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #touchpad(EventLoop) + */ + public Trigger touchpad() { + return touchpad(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Touchpad button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Touchpad button's digital signal attached + * to the given loop. + */ + public Trigger touchpad(EventLoop loop) { + return m_hid.button(DualSenseController.Button.TOUCHPAD.value, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the L 2. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @param loop the event loop instance to attach the Trigger to. + * @return a Trigger instance that is true when the L 2 axis exceeds the provided + * threshold, attached to the given event loop + */ + public Trigger L2(double threshold, EventLoop loop) { + return m_hid.axisGreaterThan( + DualSenseController.Axis.L2.value, threshold, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the L 2. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @return a Trigger instance that is true when the L 2 axis exceeds the provided + * threshold, attached to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler + * button loop}. + */ + public Trigger L2(double threshold) { + return L2(threshold, CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + + /** + * Constructs a Trigger instance around the axis value of the L 2. The returned + * trigger will be true when the axis value is greater than 0.5. + * + * @return a Trigger instance that is true when the L 2 axis exceeds 0.5, + * attached to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button + * loop}. + */ + public Trigger L2() { + return L2(0.5); + } + + /** + * Constructs a Trigger instance around the axis value of the R 2. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @param loop the event loop instance to attach the Trigger to. + * @return a Trigger instance that is true when the R 2 axis exceeds the provided + * threshold, attached to the given event loop + */ + public Trigger R2(double threshold, EventLoop loop) { + return m_hid.axisGreaterThan( + DualSenseController.Axis.R2.value, threshold, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the R 2. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @return a Trigger instance that is true when the R 2 axis exceeds the provided + * threshold, attached to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler + * button loop}. + */ + public Trigger R2(double threshold) { + return R2(threshold, CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + + /** + * Constructs a Trigger instance around the axis value of the R 2. The returned + * trigger will be true when the axis value is greater than 0.5. + * + * @return a Trigger instance that is true when the R 2 axis exceeds 0.5, + * attached to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button + * loop}. + */ + public Trigger R2() { + return R2(0.5); + } + + /** + * Get the Left X value of the controller. + * + * @return The axis value. + */ + public double getLeftX() { + return m_controller.getLeftX(); + } + + /** + * Get the Left Y value of the controller. + * + * @return The axis value. + */ + public double getLeftY() { + return m_controller.getLeftY(); + } + + /** + * Get the Right X value of the controller. + * + * @return The axis value. + */ + public double getRightX() { + return m_controller.getRightX(); + } + + /** + * Get the Right Y value of the controller. + * + * @return The axis value. + */ + public double getRightY() { + return m_controller.getRightY(); + } + + /** + * Get the L 2 value of the controller. + * + * @return The axis value. + */ + public double getL2() { + return m_controller.getL2(); + } + + /** + * Get the R 2 value of the controller. + * + * @return The axis value. + */ + public double getR2() { + return m_controller.getR2(); + } +} diff --git a/commandsv2/src/generated/main/java/org/wpilib/command2/button/CommandXboxController.java b/commandsv2/src/generated/main/java/org/wpilib/command2/button/CommandXboxController.java new file mode 100644 index 0000000000..4c5ec6a172 --- /dev/null +++ b/commandsv2/src/generated/main/java/org/wpilib/command2/button/CommandXboxController.java @@ -0,0 +1,518 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./commandsv2/generate_hids.py. DO NOT MODIFY + +package org.wpilib.command2.button; + +import org.wpilib.command2.CommandScheduler; +import org.wpilib.driverstation.XboxController; +import org.wpilib.event.EventLoop; + +/** + * A version of {@link XboxController} with {@link Trigger} factories for command-based. + * + * @see XboxController + */ +@SuppressWarnings("MethodName") +public class CommandXboxController { + private final CommandGenericHID m_hid; + private final XboxController m_controller; + + /** + * Construct an instance of a controller. + * + * @param port The port index on the Driver Station that the controller is plugged into. + */ + public CommandXboxController(int port) { + m_hid = CommandGenericHID.getCommandGenericHID(port); + m_controller = new XboxController(m_hid.getHID()); + } + + /** + * Get the underlying CommandGenericHID object. + * + * @return the wrapped CommandGenericHID object + */ + public CommandGenericHID getHID() { + return m_hid; + } + + /** + * Get the wrapped controller object. + * + * @return the wrapped controller object + */ + public XboxController getController() { + return m_controller; + } + + /** + * Constructs a Trigger instance around the A button's digital signal. + * + * @return a Trigger instance representing the A button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #a(EventLoop) + */ + public Trigger a() { + return a(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the A button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the A button's digital signal attached + * to the given loop. + */ + public Trigger a(EventLoop loop) { + return m_hid.button(XboxController.Button.A.value, loop); + } + + /** + * Constructs a Trigger instance around the B button's digital signal. + * + * @return a Trigger instance representing the B button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #b(EventLoop) + */ + public Trigger b() { + return b(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the B button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the B button's digital signal attached + * to the given loop. + */ + public Trigger b(EventLoop loop) { + return m_hid.button(XboxController.Button.B.value, loop); + } + + /** + * Constructs a Trigger instance around the X button's digital signal. + * + * @return a Trigger instance representing the X button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #x(EventLoop) + */ + public Trigger x() { + return x(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the X button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the X button's digital signal attached + * to the given loop. + */ + public Trigger x(EventLoop loop) { + return m_hid.button(XboxController.Button.X.value, loop); + } + + /** + * Constructs a Trigger instance around the Y button's digital signal. + * + * @return a Trigger instance representing the Y button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #y(EventLoop) + */ + public Trigger y() { + return y(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Y button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Y button's digital signal attached + * to the given loop. + */ + public Trigger y(EventLoop loop) { + return m_hid.button(XboxController.Button.Y.value, loop); + } + + /** + * Constructs a Trigger instance around the View button's digital signal. + * + * @return a Trigger instance representing the View button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #view(EventLoop) + */ + public Trigger view() { + return view(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the View button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the View button's digital signal attached + * to the given loop. + */ + public Trigger view(EventLoop loop) { + return m_hid.button(XboxController.Button.VIEW.value, loop); + } + + /** + * Constructs a Trigger instance around the Xbox button's digital signal. + * + * @return a Trigger instance representing the Xbox button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #xbox(EventLoop) + */ + public Trigger xbox() { + return xbox(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Xbox button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Xbox button's digital signal attached + * to the given loop. + */ + public Trigger xbox(EventLoop loop) { + return m_hid.button(XboxController.Button.XBOX.value, loop); + } + + /** + * Constructs a Trigger instance around the Menu button's digital signal. + * + * @return a Trigger instance representing the Menu button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #menu(EventLoop) + */ + public Trigger menu() { + return menu(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Menu button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Menu button's digital signal attached + * to the given loop. + */ + public Trigger menu(EventLoop loop) { + return m_hid.button(XboxController.Button.MENU.value, loop); + } + + /** + * Constructs a Trigger instance around the Left Stick button's digital signal. + * + * @return a Trigger instance representing the Left Stick button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #leftStick(EventLoop) + */ + public Trigger leftStick() { + return leftStick(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Left Stick button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Left Stick button's digital signal attached + * to the given loop. + */ + public Trigger leftStick(EventLoop loop) { + return m_hid.button(XboxController.Button.LEFT_STICK.value, loop); + } + + /** + * Constructs a Trigger instance around the Right Stick button's digital signal. + * + * @return a Trigger instance representing the Right Stick button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #rightStick(EventLoop) + */ + public Trigger rightStick() { + return rightStick(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Right Stick button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Right Stick button's digital signal attached + * to the given loop. + */ + public Trigger rightStick(EventLoop loop) { + return m_hid.button(XboxController.Button.RIGHT_STICK.value, loop); + } + + /** + * Constructs a Trigger instance around the Left Bumper button's digital signal. + * + * @return a Trigger instance representing the Left Bumper button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #leftBumper(EventLoop) + */ + public Trigger leftBumper() { + return leftBumper(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Left Bumper button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Left Bumper button's digital signal attached + * to the given loop. + */ + public Trigger leftBumper(EventLoop loop) { + return m_hid.button(XboxController.Button.LEFT_BUMPER.value, loop); + } + + /** + * Constructs a Trigger instance around the Right Bumper button's digital signal. + * + * @return a Trigger instance representing the Right Bumper button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #rightBumper(EventLoop) + */ + public Trigger rightBumper() { + return rightBumper(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Right Bumper button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Right Bumper button's digital signal attached + * to the given loop. + */ + public Trigger rightBumper(EventLoop loop) { + return m_hid.button(XboxController.Button.RIGHT_BUMPER.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Up button's digital signal. + * + * @return a Trigger instance representing the Dpad Up button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #dpadUp(EventLoop) + */ + public Trigger dpadUp() { + return dpadUp(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Up button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Up button's digital signal attached + * to the given loop. + */ + public Trigger dpadUp(EventLoop loop) { + return m_hid.button(XboxController.Button.DPAD_UP.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Down button's digital signal. + * + * @return a Trigger instance representing the Dpad Down button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #dpadDown(EventLoop) + */ + public Trigger dpadDown() { + return dpadDown(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Down button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Down button's digital signal attached + * to the given loop. + */ + public Trigger dpadDown(EventLoop loop) { + return m_hid.button(XboxController.Button.DPAD_DOWN.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Left button's digital signal. + * + * @return a Trigger instance representing the Dpad Left button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #dpadLeft(EventLoop) + */ + public Trigger dpadLeft() { + return dpadLeft(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Left button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Left button's digital signal attached + * to the given loop. + */ + public Trigger dpadLeft(EventLoop loop) { + return m_hid.button(XboxController.Button.DPAD_LEFT.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Right button's digital signal. + * + * @return a Trigger instance representing the Dpad Right button's digital signal attached + * to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}. + * @see #dpadRight(EventLoop) + */ + public Trigger dpadRight() { + return dpadRight(CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Right button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Right button's digital signal attached + * to the given loop. + */ + public Trigger dpadRight(EventLoop loop) { + return m_hid.button(XboxController.Button.DPAD_RIGHT.value, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the Left Trigger. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @param loop the event loop instance to attach the Trigger to. + * @return a Trigger instance that is true when the Left Trigger axis exceeds the provided + * threshold, attached to the given event loop + */ + public Trigger leftTrigger(double threshold, EventLoop loop) { + return m_hid.axisGreaterThan( + XboxController.Axis.LEFT_TRIGGER.value, threshold, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the Left Trigger. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @return a Trigger instance that is true when the Left Trigger axis exceeds the provided + * threshold, attached to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler + * button loop}. + */ + public Trigger leftTrigger(double threshold) { + return leftTrigger(threshold, CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + + /** + * Constructs a Trigger instance around the axis value of the Left Trigger. The returned + * trigger will be true when the axis value is greater than 0.5. + * + * @return a Trigger instance that is true when the Left Trigger axis exceeds 0.5, + * attached to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button + * loop}. + */ + public Trigger leftTrigger() { + return leftTrigger(0.5); + } + + /** + * Constructs a Trigger instance around the axis value of the Right Trigger. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @param loop the event loop instance to attach the Trigger to. + * @return a Trigger instance that is true when the Right Trigger axis exceeds the provided + * threshold, attached to the given event loop + */ + public Trigger rightTrigger(double threshold, EventLoop loop) { + return m_hid.axisGreaterThan( + XboxController.Axis.RIGHT_TRIGGER.value, threshold, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the Right Trigger. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @return a Trigger instance that is true when the Right Trigger axis exceeds the provided + * threshold, attached to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler + * button loop}. + */ + public Trigger rightTrigger(double threshold) { + return rightTrigger(threshold, CommandScheduler.getInstance().getDefaultButtonLoop()); + } + + + /** + * Constructs a Trigger instance around the axis value of the Right Trigger. The returned + * trigger will be true when the axis value is greater than 0.5. + * + * @return a Trigger instance that is true when the Right Trigger axis exceeds 0.5, + * attached to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button + * loop}. + */ + public Trigger rightTrigger() { + return rightTrigger(0.5); + } + + /** + * Get the Left X value of the controller. + * + * @return The axis value. + */ + public double getLeftX() { + return m_controller.getLeftX(); + } + + /** + * Get the Left Y value of the controller. + * + * @return The axis value. + */ + public double getLeftY() { + return m_controller.getLeftY(); + } + + /** + * Get the Right X value of the controller. + * + * @return The axis value. + */ + public double getRightX() { + return m_controller.getRightX(); + } + + /** + * Get the Right Y value of the controller. + * + * @return The axis value. + */ + public double getRightY() { + return m_controller.getRightY(); + } + + /** + * Get the Left Trigger value of the controller. + * + * @return The axis value. + */ + public double getLeftTrigger() { + return m_controller.getLeftTrigger(); + } + + /** + * Get the Right Trigger value of the controller. + * + * @return The axis value. + */ + public double getRightTrigger() { + return m_controller.getRightTrigger(); + } +} diff --git a/commandsv2/src/generated/main/native/cpp/wpi/commands2/button/CommandDualSenseController.cpp b/commandsv2/src/generated/main/native/cpp/wpi/commands2/button/CommandDualSenseController.cpp new file mode 100644 index 0000000000..3eeec0720c --- /dev/null +++ b/commandsv2/src/generated/main/native/cpp/wpi/commands2/button/CommandDualSenseController.cpp @@ -0,0 +1,166 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./commandsv2/generate_hids.py. DO NOT MODIFY +#include "wpi/commands2/button/CommandDualSenseController.hpp" + +using namespace wpi::cmd; + +CommandDualSenseController::CommandDualSenseController(int port) + : m_hid{&CommandGenericHID::GetCommandGenericHID(port)}, + m_controller{m_hid->GetHID()} {} + +CommandGenericHID& CommandDualSenseController::GetHID() { + return *m_hid; +} + +wpi::DualSenseController& +CommandDualSenseController::GetController() { + return m_controller; +} + +const wpi::DualSenseController& +CommandDualSenseController::GetController() const { + return m_controller; +} + +Trigger CommandDualSenseController::Cross( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::CROSS, + loop); +} + +Trigger CommandDualSenseController::Circle( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::CIRCLE, + loop); +} + +Trigger CommandDualSenseController::Square( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::SQUARE, + loop); +} + +Trigger CommandDualSenseController::Triangle( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::TRIANGLE, + loop); +} + +Trigger CommandDualSenseController::Create( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::CREATE, + loop); +} + +Trigger CommandDualSenseController::PS( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::PS, + loop); +} + +Trigger CommandDualSenseController::Options( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::OPTIONS, + loop); +} + +Trigger CommandDualSenseController::L3( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::L3, + loop); +} + +Trigger CommandDualSenseController::R3( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::R3, + loop); +} + +Trigger CommandDualSenseController::L1( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::L1, + loop); +} + +Trigger CommandDualSenseController::R1( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::R1, + loop); +} + +Trigger CommandDualSenseController::DpadUp( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::DPAD_UP, + loop); +} + +Trigger CommandDualSenseController::DpadDown( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::DPAD_DOWN, + loop); +} + +Trigger CommandDualSenseController::DpadLeft( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::DPAD_LEFT, + loop); +} + +Trigger CommandDualSenseController::DpadRight( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::DPAD_RIGHT, + loop); +} + +Trigger CommandDualSenseController::Microphone( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::MICROPHONE, + loop); +} + +Trigger CommandDualSenseController::Touchpad( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::DualSenseController::Button::TOUCHPAD, + loop); +} + +Trigger CommandDualSenseController::L2( + double threshold, wpi::EventLoop* loop) const { + return m_hid->AxisGreaterThan( + wpi::DualSenseController::Axis::L2, + threshold, loop); +} + +Trigger CommandDualSenseController::R2( + double threshold, wpi::EventLoop* loop) const { + return m_hid->AxisGreaterThan( + wpi::DualSenseController::Axis::R2, + threshold, loop); +} + +double CommandDualSenseController::GetLeftX() const { + return m_controller.GetLeftX(); +} + +double CommandDualSenseController::GetLeftY() const { + return m_controller.GetLeftY(); +} + +double CommandDualSenseController::GetRightX() const { + return m_controller.GetRightX(); +} + +double CommandDualSenseController::GetRightY() const { + return m_controller.GetRightY(); +} + +double CommandDualSenseController::GetL2() const { + return m_controller.GetL2(); +} + +double CommandDualSenseController::GetR2() const { + return m_controller.GetR2(); +} diff --git a/commandsv2/src/generated/main/native/cpp/wpi/commands2/button/CommandXboxController.cpp b/commandsv2/src/generated/main/native/cpp/wpi/commands2/button/CommandXboxController.cpp new file mode 100644 index 0000000000..3d9320036a --- /dev/null +++ b/commandsv2/src/generated/main/native/cpp/wpi/commands2/button/CommandXboxController.cpp @@ -0,0 +1,154 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./commandsv2/generate_hids.py. DO NOT MODIFY +#include "wpi/commands2/button/CommandXboxController.hpp" + +using namespace wpi::cmd; + +CommandXboxController::CommandXboxController(int port) + : m_hid{&CommandGenericHID::GetCommandGenericHID(port)}, + m_controller{m_hid->GetHID()} {} + +CommandGenericHID& CommandXboxController::GetHID() { + return *m_hid; +} + +wpi::XboxController& +CommandXboxController::GetController() { + return m_controller; +} + +const wpi::XboxController& +CommandXboxController::GetController() const { + return m_controller; +} + +Trigger CommandXboxController::A( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::A, + loop); +} + +Trigger CommandXboxController::B( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::B, + loop); +} + +Trigger CommandXboxController::X( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::X, + loop); +} + +Trigger CommandXboxController::Y( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::Y, + loop); +} + +Trigger CommandXboxController::View( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::VIEW, + loop); +} + +Trigger CommandXboxController::Xbox( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::XBOX, + loop); +} + +Trigger CommandXboxController::Menu( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::MENU, + loop); +} + +Trigger CommandXboxController::LeftStick( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::LEFT_STICK, + loop); +} + +Trigger CommandXboxController::RightStick( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::RIGHT_STICK, + loop); +} + +Trigger CommandXboxController::LeftBumper( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::LEFT_BUMPER, + loop); +} + +Trigger CommandXboxController::RightBumper( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::RIGHT_BUMPER, + loop); +} + +Trigger CommandXboxController::DpadUp( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::DPAD_UP, + loop); +} + +Trigger CommandXboxController::DpadDown( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::DPAD_DOWN, + loop); +} + +Trigger CommandXboxController::DpadLeft( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::DPAD_LEFT, + loop); +} + +Trigger CommandXboxController::DpadRight( + wpi::EventLoop* loop) const { + return m_hid->Button(wpi::XboxController::Button::DPAD_RIGHT, + loop); +} + +Trigger CommandXboxController::LeftTrigger( + double threshold, wpi::EventLoop* loop) const { + return m_hid->AxisGreaterThan( + wpi::XboxController::Axis::LEFT_TRIGGER, + threshold, loop); +} + +Trigger CommandXboxController::RightTrigger( + double threshold, wpi::EventLoop* loop) const { + return m_hid->AxisGreaterThan( + wpi::XboxController::Axis::RIGHT_TRIGGER, + threshold, loop); +} + +double CommandXboxController::GetLeftX() const { + return m_controller.GetLeftX(); +} + +double CommandXboxController::GetLeftY() const { + return m_controller.GetLeftY(); +} + +double CommandXboxController::GetRightX() const { + return m_controller.GetRightX(); +} + +double CommandXboxController::GetRightY() const { + return m_controller.GetRightY(); +} + +double CommandXboxController::GetLeftTrigger() const { + return m_controller.GetLeftTrigger(); +} + +double CommandXboxController::GetRightTrigger() const { + return m_controller.GetRightTrigger(); +} diff --git a/commandsv2/src/generated/main/native/include/wpi/commands2/button/CommandDualSenseController.hpp b/commandsv2/src/generated/main/native/include/wpi/commands2/button/CommandDualSenseController.hpp new file mode 100644 index 0000000000..298fc73597 --- /dev/null +++ b/commandsv2/src/generated/main/native/include/wpi/commands2/button/CommandDualSenseController.hpp @@ -0,0 +1,355 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./commandsv2/generate_hids.py. DO NOT MODIFY +#pragma once + +#include "wpi/driverstation/DualSenseController.hpp" + +#include "wpi/commands2/CommandScheduler.hpp" +#include "wpi/commands2/button/CommandGenericHID.hpp" +#include "wpi/commands2/button/Trigger.hpp" + +namespace wpi::cmd { +/** + * A version of {@link wpi::DualSenseController} with {@link Trigger} + * factories for command-based. + * + * @see wpi::DualSenseController + */ +class CommandDualSenseController { + public: + /** + * Construct an instance of a controller. + * + * @param port The port index on the Driver Station that the controller is + * plugged into. + */ + explicit CommandDualSenseController(int port); + + /** + * Get the underlying CommandGenericHID object. + * + * @return the wrapped CommandGenericHID object + */ + CommandGenericHID& GetHID(); + + /** + * Get the wrapped controller object. + * + * @return the wrapped controller object + */ + wpi::DualSenseController& GetController(); + + /** + * Get the wrapped controller object. + * + * @return the wrapped controller object + */ + const wpi::DualSenseController& GetController() const; + + /** + * Constructs a Trigger 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 a Trigger instance representing the Cross button's + * digital signal attached to the given loop. + */ + Trigger Cross( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger 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 a Trigger instance representing the Circle button's + * digital signal attached to the given loop. + */ + Trigger Circle( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger 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 a Trigger instance representing the Square button's + * digital signal attached to the given loop. + */ + Trigger Square( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger 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 a Trigger instance representing the Triangle button's + * digital signal attached to the given loop. + */ + Trigger Triangle( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Create button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Create button's + * digital signal attached to the given loop. + */ + Trigger Create( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger 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 a Trigger instance representing the PS button's + * digital signal attached to the given loop. + */ + Trigger PS( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger 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 a Trigger instance representing the Options button's + * digital signal attached to the given loop. + */ + Trigger Options( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the L 3 button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the L 3 button's + * digital signal attached to the given loop. + */ + Trigger L3( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the R 3 button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the R 3 button's + * digital signal attached to the given loop. + */ + Trigger R3( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the L 1 button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the L 1 button's + * digital signal attached to the given loop. + */ + Trigger L1( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the R 1 button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the R 1 button's + * digital signal attached to the given loop. + */ + Trigger R1( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Dpad Up button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Dpad Up button's + * digital signal attached to the given loop. + */ + Trigger DpadUp( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Dpad Down button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Dpad Down button's + * digital signal attached to the given loop. + */ + Trigger DpadDown( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Dpad Left button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Dpad Left button's + * digital signal attached to the given loop. + */ + Trigger DpadLeft( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Dpad Right button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Dpad Right button's + * digital signal attached to the given loop. + */ + Trigger DpadRight( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Microphone button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Microphone button's + * digital signal attached to the given loop. + */ + Trigger Microphone( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Touchpad button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Touchpad button's + * digital signal attached to the given loop. + */ + Trigger Touchpad( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the axis value of the + * L 2. The returned Trigger will be true when the axis value + * is greater than threshold. + * + * @param threshold the minimum axis value for the returned Trigger to be + * true. This value should be in the range [0, 1] where 0 is the unpressed + * state of the axis. Defaults to 0.5. + * @param loop the event loop instance to attach the Trigger to. Defaults to + * the CommandScheduler's default loop. + * @return a Trigger instance that is true when the L 2 axis + * exceeds the provided threshold, attached to the given loop + */ + Trigger L2( + double threshold = 0.5, + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the axis value of the + * R 2. The returned Trigger will be true when the axis value + * is greater than threshold. + * + * @param threshold the minimum axis value for the returned Trigger to be + * true. This value should be in the range [0, 1] where 0 is the unpressed + * state of the axis. Defaults to 0.5. + * @param loop the event loop instance to attach the Trigger to. Defaults to + * the CommandScheduler's default loop. + * @return a Trigger instance that is true when the R 2 axis + * exceeds the provided threshold, attached to the given loop + */ + Trigger R2( + double threshold = 0.5, + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Get the Left X value of the controller. + * + * @return the axis value. + */ + double GetLeftX() const; + + /** + * Get the Left Y value of the controller. + * + * @return the axis value. + */ + double GetLeftY() const; + + /** + * Get the Right X value of the controller. + * + * @return the axis value. + */ + double GetRightX() const; + + /** + * Get the Right Y value of the controller. + * + * @return the axis value. + */ + double GetRightY() const; + + /** + * Get the L 2 value of the controller. + * + * @return the axis value. + */ + double GetL2() const; + + /** + * Get the R 2 value of the controller. + * + * @return the axis value. + */ + double GetR2() const; + + private: + CommandGenericHID* m_hid; + wpi::DualSenseController m_controller; +}; +} // namespace wpi::cmd diff --git a/commandsv2/src/generated/main/native/include/wpi/commands2/button/CommandXboxController.hpp b/commandsv2/src/generated/main/native/include/wpi/commands2/button/CommandXboxController.hpp new file mode 100644 index 0000000000..9a3a6fc6cb --- /dev/null +++ b/commandsv2/src/generated/main/native/include/wpi/commands2/button/CommandXboxController.hpp @@ -0,0 +1,329 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./commandsv2/generate_hids.py. DO NOT MODIFY +#pragma once + +#include "wpi/driverstation/XboxController.hpp" + +#include "wpi/commands2/CommandScheduler.hpp" +#include "wpi/commands2/button/CommandGenericHID.hpp" +#include "wpi/commands2/button/Trigger.hpp" + +namespace wpi::cmd { +/** + * A version of {@link wpi::XboxController} with {@link Trigger} + * factories for command-based. + * + * @see wpi::XboxController + */ +class CommandXboxController { + public: + /** + * Construct an instance of a controller. + * + * @param port The port index on the Driver Station that the controller is + * plugged into. + */ + explicit CommandXboxController(int port); + + /** + * Get the underlying CommandGenericHID object. + * + * @return the wrapped CommandGenericHID object + */ + CommandGenericHID& GetHID(); + + /** + * Get the wrapped controller object. + * + * @return the wrapped controller object + */ + wpi::XboxController& GetController(); + + /** + * Get the wrapped controller object. + * + * @return the wrapped controller object + */ + const wpi::XboxController& GetController() const; + + /** + * Constructs a Trigger instance around the A button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the A button's + * digital signal attached to the given loop. + */ + Trigger A( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the B button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the B button's + * digital signal attached to the given loop. + */ + Trigger B( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the X button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the X button's + * digital signal attached to the given loop. + */ + Trigger X( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Y button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Y button's + * digital signal attached to the given loop. + */ + Trigger Y( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the View button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the View button's + * digital signal attached to the given loop. + */ + Trigger View( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Xbox button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Xbox button's + * digital signal attached to the given loop. + */ + Trigger Xbox( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Menu button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Menu button's + * digital signal attached to the given loop. + */ + Trigger Menu( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Left Stick button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Left Stick button's + * digital signal attached to the given loop. + */ + Trigger LeftStick( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Right Stick button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Right Stick button's + * digital signal attached to the given loop. + */ + Trigger RightStick( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Left Bumper button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Left Bumper button's + * digital signal attached to the given loop. + */ + Trigger LeftBumper( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Right Bumper button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Right Bumper button's + * digital signal attached to the given loop. + */ + Trigger RightBumper( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Dpad Up button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Dpad Up button's + * digital signal attached to the given loop. + */ + Trigger DpadUp( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Dpad Down button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Dpad Down button's + * digital signal attached to the given loop. + */ + Trigger DpadDown( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Dpad Left button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Dpad Left button's + * digital signal attached to the given loop. + */ + Trigger DpadLeft( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the Dpad Right button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. Defaults to the + * CommandScheduler's default loop. + * @return a Trigger instance representing the Dpad Right button's + * digital signal attached to the given loop. + */ + Trigger DpadRight( + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the axis value of the + * Left Trigger. The returned Trigger will be true when the axis value + * is greater than threshold. + * + * @param threshold the minimum axis value for the returned Trigger to be + * true. This value should be in the range [0, 1] where 0 is the unpressed + * state of the axis. Defaults to 0.5. + * @param loop the event loop instance to attach the Trigger to. Defaults to + * the CommandScheduler's default loop. + * @return a Trigger instance that is true when the Left Trigger axis + * exceeds the provided threshold, attached to the given loop + */ + Trigger LeftTrigger( + double threshold = 0.5, + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Constructs a Trigger instance around the axis value of the + * Right Trigger. The returned Trigger will be true when the axis value + * is greater than threshold. + * + * @param threshold the minimum axis value for the returned Trigger to be + * true. This value should be in the range [0, 1] where 0 is the unpressed + * state of the axis. Defaults to 0.5. + * @param loop the event loop instance to attach the Trigger to. Defaults to + * the CommandScheduler's default loop. + * @return a Trigger instance that is true when the Right Trigger axis + * exceeds the provided threshold, attached to the given loop + */ + Trigger RightTrigger( + double threshold = 0.5, + wpi::EventLoop* loop = + CommandScheduler::GetInstance().GetDefaultButtonLoop()) const; + + /** + * Get the Left X value of the controller. + * + * @return the axis value. + */ + double GetLeftX() const; + + /** + * Get the Left Y value of the controller. + * + * @return the axis value. + */ + double GetLeftY() const; + + /** + * Get the Right X value of the controller. + * + * @return the axis value. + */ + double GetRightX() const; + + /** + * Get the Right Y value of the controller. + * + * @return the axis value. + */ + double GetRightY() const; + + /** + * Get the Left Trigger value of the controller. + * + * @return the axis value. + */ + double GetLeftTrigger() const; + + /** + * Get the Right Trigger value of the controller. + * + * @return the axis value. + */ + double GetRightTrigger() const; + + private: + CommandGenericHID* m_hid; + wpi::XboxController m_controller; +}; +} // namespace wpi::cmd diff --git a/commandsv2/src/main/python/commands2/button/__init__.py b/commandsv2/src/main/python/commands2/button/__init__.py index 6958aba835..dd6d31a581 100644 --- a/commandsv2/src/main/python/commands2/button/__init__.py +++ b/commandsv2/src/main/python/commands2/button/__init__.py @@ -1,8 +1,10 @@ from .commandgenerichid import CommandGenericHID +from .commanddualsensecontroller import CommandDualSenseController from .commandgamepad import CommandGamepad from .commandjoystick import CommandJoystick from .commandnidsps4controller import CommandNiDsPS4Controller from .commandnidsxboxcontroller import CommandNiDsXboxController +from .commandxboxcontroller import CommandXboxController from .joystickbutton import JoystickButton from .networkbutton import NetworkButton from .povbutton import POVButton @@ -10,11 +12,13 @@ from .trigger import Trigger __all__ = [ "Trigger", + "CommandDualSenseController", "CommandGenericHID", "CommandGamepad", "CommandJoystick", "CommandNiDsPS4Controller", "CommandNiDsXboxController", + "CommandXboxController", "JoystickButton", "NetworkButton", "POVButton", diff --git a/commandsv2/src/main/python/commands2/button/commanddualsensecontroller.py b/commandsv2/src/main/python/commands2/button/commanddualsensecontroller.py new file mode 100644 index 0000000000..7957f71857 --- /dev/null +++ b/commandsv2/src/main/python/commands2/button/commanddualsensecontroller.py @@ -0,0 +1,384 @@ +# THIS FILE WAS AUTO-GENERATED BY ./commandsv2/generate_hids.py. DO NOT MODIFY + +from typing import Optional + +from wpilib import EventLoop, DualSenseController + +from .commandgenerichid import CommandGenericHID +from .trigger import Trigger + + +def _enum_value(value) -> int: + try: + return int(value) + except TypeError: + return value.value + + +class CommandDualSenseController: + """ + A version of :class:`wpilib.DualSenseController` with :class:`.Trigger` factories for command-based. + """ + + _hid: CommandGenericHID + _controller: DualSenseController + + def __init__(self, port: int): + """ + Construct an instance of a controller. + + :param port: The port index on the Driver Station that the controller is plugged into. + """ + self._hid = CommandGenericHID.getCommandGenericHID(port) + self._controller = DualSenseController(self._hid.getHID()) + + def __getattr__(self, name: str): + return getattr(self._hid, name) + + def getHID(self) -> CommandGenericHID: + """ + Get the underlying CommandGenericHID object. + + :returns: the wrapped CommandGenericHID object + """ + return self._hid + + def getController(self) -> DualSenseController: + """ + Get the wrapped controller object. + + :returns: the wrapped controller object + """ + return self._controller + + def cross(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Cross button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Cross button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.CROSS), loop + ) + + def circle(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Circle button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Circle button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.CIRCLE), loop + ) + + def square(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Square button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Square button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.SQUARE), loop + ) + + def triangle(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Triangle button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Triangle button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.TRIANGLE), loop + ) + + def create(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Create button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Create button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.CREATE), loop + ) + + def PS(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the PS button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the PS button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.PS), loop + ) + + def options(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Options button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Options button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.OPTIONS), loop + ) + + def L3(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the L 3 button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the L 3 button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.L3), loop + ) + + def R3(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the R 3 button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the R 3 button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.R3), loop + ) + + def L1(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the L 1 button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the L 1 button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.L1), loop + ) + + def R1(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the R 1 button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the R 1 button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.R1), loop + ) + + def dpadUp(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Dpad Up button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Dpad Up button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.DPAD_UP), loop + ) + + def dpadDown(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Dpad Down button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Dpad Down button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.DPAD_DOWN), loop + ) + + def dpadLeft(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Dpad Left button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Dpad Left button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.DPAD_LEFT), loop + ) + + def dpadRight(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Dpad Right button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Dpad Right button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.DPAD_RIGHT), loop + ) + + def microphone(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Microphone button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Microphone button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.MICROPHONE), loop + ) + + def touchpad(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Touchpad button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Touchpad button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(DualSenseController.Button.TOUCHPAD), loop + ) + + def L2( + self, + threshold: float = 0.5, + loop: Optional[EventLoop] = None, + ) -> Trigger: + """ + Constructs a Trigger instance around the L 2 axis value. The returned + Trigger will be true when the axis value is greater than ``threshold``. + + :param threshold: the minimum axis value for the returned Trigger to be true. This value + should be in the range [0, 1] where 0 is the unpressed state of the axis. + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance that is true when the L 2 axis exceeds the + provided threshold, attached to the given event loop. + """ + return self._hid.axisGreaterThan( + _enum_value(DualSenseController.Axis.L2), + threshold, + loop, + ) + + def R2( + self, + threshold: float = 0.5, + loop: Optional[EventLoop] = None, + ) -> Trigger: + """ + Constructs a Trigger instance around the R 2 axis value. The returned + Trigger will be true when the axis value is greater than ``threshold``. + + :param threshold: the minimum axis value for the returned Trigger to be true. This value + should be in the range [0, 1] where 0 is the unpressed state of the axis. + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance that is true when the R 2 axis exceeds the + provided threshold, attached to the given event loop. + """ + return self._hid.axisGreaterThan( + _enum_value(DualSenseController.Axis.R2), + threshold, + loop, + ) + + def getLeftX(self) -> float: + """ + Get the Left X value of the controller. + + :returns: the axis value. + """ + return self._controller.getLeftX() + + def getLeftY(self) -> float: + """ + Get the Left Y value of the controller. + + :returns: the axis value. + """ + return self._controller.getLeftY() + + def getRightX(self) -> float: + """ + Get the Right X value of the controller. + + :returns: the axis value. + """ + return self._controller.getRightX() + + def getRightY(self) -> float: + """ + Get the Right Y value of the controller. + + :returns: the axis value. + """ + return self._controller.getRightY() + + def getL2(self) -> float: + """ + Get the L 2 value of the controller. + + :returns: the axis value. + """ + return self._controller.getL2() + + def getR2(self) -> float: + """ + Get the R 2 value of the controller. + + :returns: the axis value. + """ + return self._controller.getR2() diff --git a/commandsv2/src/main/python/commands2/button/commandxboxcontroller.py b/commandsv2/src/main/python/commands2/button/commandxboxcontroller.py new file mode 100644 index 0000000000..35f694a4e6 --- /dev/null +++ b/commandsv2/src/main/python/commands2/button/commandxboxcontroller.py @@ -0,0 +1,356 @@ +# THIS FILE WAS AUTO-GENERATED BY ./commandsv2/generate_hids.py. DO NOT MODIFY + +from typing import Optional + +from wpilib import EventLoop, XboxController + +from .commandgenerichid import CommandGenericHID +from .trigger import Trigger + + +def _enum_value(value) -> int: + try: + return int(value) + except TypeError: + return value.value + + +class CommandXboxController: + """ + A version of :class:`wpilib.XboxController` with :class:`.Trigger` factories for command-based. + """ + + _hid: CommandGenericHID + _controller: XboxController + + def __init__(self, port: int): + """ + Construct an instance of a controller. + + :param port: The port index on the Driver Station that the controller is plugged into. + """ + self._hid = CommandGenericHID.getCommandGenericHID(port) + self._controller = XboxController(self._hid.getHID()) + + def __getattr__(self, name: str): + return getattr(self._hid, name) + + def getHID(self) -> CommandGenericHID: + """ + Get the underlying CommandGenericHID object. + + :returns: the wrapped CommandGenericHID object + """ + return self._hid + + def getController(self) -> XboxController: + """ + Get the wrapped controller object. + + :returns: the wrapped controller object + """ + return self._controller + + def a(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the A button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the A button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.A), loop + ) + + def b(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the B button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the B button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.B), loop + ) + + def x(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the X button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the X button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.X), loop + ) + + def y(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Y button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Y button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.Y), loop + ) + + def view(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the View button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the View button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.VIEW), loop + ) + + def xbox(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Xbox button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Xbox button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.XBOX), loop + ) + + def menu(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Menu button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Menu button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.MENU), loop + ) + + def leftStick(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Left Stick button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Left Stick button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.LEFT_STICK), loop + ) + + def rightStick(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Right Stick button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Right Stick button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.RIGHT_STICK), loop + ) + + def leftBumper(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Left Bumper button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Left Bumper button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.LEFT_BUMPER), loop + ) + + def rightBumper(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Right Bumper button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Right Bumper button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.RIGHT_BUMPER), loop + ) + + def dpadUp(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Dpad Up button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Dpad Up button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.DPAD_UP), loop + ) + + def dpadDown(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Dpad Down button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Dpad Down button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.DPAD_DOWN), loop + ) + + def dpadLeft(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Dpad Left button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Dpad Left button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.DPAD_LEFT), loop + ) + + def dpadRight(self, loop: Optional[EventLoop] = None) -> Trigger: + """ + Constructs a Trigger instance around the Dpad Right button's digital signal. + + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance representing the Dpad Right button's digital signal + attached to the given loop. + """ + return self._hid.button( + _enum_value(XboxController.Button.DPAD_RIGHT), loop + ) + + def leftTrigger( + self, + threshold: float = 0.5, + loop: Optional[EventLoop] = None, + ) -> Trigger: + """ + Constructs a Trigger instance around the Left Trigger axis value. The returned + Trigger will be true when the axis value is greater than ``threshold``. + + :param threshold: the minimum axis value for the returned Trigger to be true. This value + should be in the range [0, 1] where 0 is the unpressed state of the axis. + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance that is true when the Left Trigger axis exceeds the + provided threshold, attached to the given event loop. + """ + return self._hid.axisGreaterThan( + _enum_value(XboxController.Axis.LEFT_TRIGGER), + threshold, + loop, + ) + + def rightTrigger( + self, + threshold: float = 0.5, + loop: Optional[EventLoop] = None, + ) -> Trigger: + """ + Constructs a Trigger instance around the Right Trigger axis value. The returned + Trigger will be true when the axis value is greater than ``threshold``. + + :param threshold: the minimum axis value for the returned Trigger to be true. This value + should be in the range [0, 1] where 0 is the unpressed state of the axis. + :param loop: the event loop instance to attach the Trigger to, defaults + to :func:`commands2.CommandScheduler.getDefaultButtonLoop` + + :returns: a Trigger instance that is true when the Right Trigger axis exceeds the + provided threshold, attached to the given event loop. + """ + return self._hid.axisGreaterThan( + _enum_value(XboxController.Axis.RIGHT_TRIGGER), + threshold, + loop, + ) + + def getLeftX(self) -> float: + """ + Get the Left X value of the controller. + + :returns: the axis value. + """ + return self._controller.getLeftX() + + def getLeftY(self) -> float: + """ + Get the Left Y value of the controller. + + :returns: the axis value. + """ + return self._controller.getLeftY() + + def getRightX(self) -> float: + """ + Get the Right X value of the controller. + + :returns: the axis value. + """ + return self._controller.getRightX() + + def getRightY(self) -> float: + """ + Get the Right Y value of the controller. + + :returns: the axis value. + """ + return self._controller.getRightY() + + def getLeftTrigger(self) -> float: + """ + Get the Left Trigger value of the controller. + + :returns: the axis value. + """ + return self._controller.getLeftTrigger() + + def getRightTrigger(self) -> float: + """ + Get the Right Trigger value of the controller. + + :returns: the axis value. + """ + return self._controller.getRightTrigger() diff --git a/commandsv3/generate_files.py b/commandsv3/generate_files.py index 23ae3a8a67..54d83a0e27 100755 --- a/commandsv3/generate_files.py +++ b/commandsv3/generate_files.py @@ -6,6 +6,7 @@ import argparse import json +import re import subprocess from pathlib import Path @@ -38,6 +39,101 @@ def generate_hids(output_directory: Path, template_directory: Path, schema_file: write_controller_file(root_path, controllerName, output) +def _capitalize_first(name: str) -> str: + return name[0].upper() + name[1:] + + +def _display_name(name: str) -> str: + name = re.sub(r"([a-z0-9])([A-Z])", r"\1 \2", name) + name = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1 \2", name) + name = re.sub(r"([A-Za-z])([0-9])", r"\1 \2", name) + return name[0].upper() + name[1:] + + +def _constant_name(name: str) -> str: + name = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1_\2", name) + name = re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name) + name = re.sub(r"([a-z])([0-9])", r"\1_\2", name) + return name.upper() + + +def _is_trigger_axis(name: str) -> bool: + return name.endswith("Trigger") or name in { + "L2", + "R2", + "ZL", + "ZR", + } + + +def _normalize_command_mapping(mapping: dict[str, int]): + return [ + { + "Name": name, + "MethodName": _capitalize_first(name), + "ConstantName": _constant_name(name), + "DocName": _display_name(name), + "value": value, + } + for name, value in mapping.items() + ] + + +def _normalize_first_ds_command_controller(controller: dict): + buttons = _normalize_command_mapping(controller["buttons"]) + axes = _normalize_command_mapping(controller["axes"]) + button_names = {button["Name"] for button in buttons} + + trigger_axes = [] + for axis in axes: + if not _is_trigger_axis(axis["Name"]): + continue + + name = axis["Name"] + trigger_name = name + trigger_axes.append( + { + "Name": trigger_name, + "MethodName": _capitalize_first(trigger_name), + "DocName": _display_name(trigger_name), + "AxisName": axis["Name"], + "AxisMethodName": axis["MethodName"], + "AxisConstantName": axis["ConstantName"], + "AxisDocName": axis["DocName"], + "HasDefaultThresholdMethod": trigger_name not in button_names, + } + ) + + normalized = dict(controller) + normalized["buttons"] = buttons + normalized["axes"] = axes + normalized["triggerAxes"] = trigger_axes + return normalized + + +def generate_first_ds_hids( + output_directory: Path, template_directory: Path, schema_file: Path +): + with schema_file.open(encoding="utf-8") as f: + controllers = [ + _normalize_first_ds_command_controller(controller) + for controller in json.load(f) + ] + + java_subdirectory = "main/java/org/wpilib/command3/button" + env = Environment( + loader=FileSystemLoader(template_directory / "main/java"), + autoescape=False, + keep_trailing_newline=True, + ) + root_path = output_directory / java_subdirectory + template = env.get_template("first_ds_commandhid.java.jinja") + for controller in controllers: + controller_name = f"Command{controller['ClassName']}Controller.java" + output = template.render(controller) + write_controller_file(root_path, controller_name, output) + + def generate_quickbuf( protoc, quickbuf_plugin: Path, output_directory: Path, proto_dir: Path ): @@ -90,6 +186,12 @@ def main(): default="wpilibj/src/generate/hids.json", type=Path, ) + parser.add_argument( + "--first_ds_schema_file", + help="Optional. If set, will use this file for the FIRST Driver Station HID schema", + default="wpilibj/src/generate/first_ds_hids.json", + type=Path, + ) parser.add_argument( "--protoc", help="Protoc executable command", @@ -108,6 +210,9 @@ def main(): args = parser.parse_args() generate_hids(args.output_directory, args.template_root, args.schema_file) + generate_first_ds_hids( + args.output_directory, args.template_root, args.first_ds_schema_file + ) generate_quickbuf( args.protoc, args.quickbuf_plugin, diff --git a/commandsv3/src/generate/main/java/first_ds_commandhid.java.jinja b/commandsv3/src/generate/main/java/first_ds_commandhid.java.jinja new file mode 100644 index 0000000000..b9a1a2ee42 --- /dev/null +++ b/commandsv3/src/generate/main/java/first_ds_commandhid.java.jinja @@ -0,0 +1,144 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./commandsv3/generate_files.py. DO NOT MODIFY + +package org.wpilib.command3.button; + +import org.wpilib.command3.Scheduler; +import org.wpilib.command3.Trigger; +import org.wpilib.driverstation.{{ ClassName }}Controller; +import org.wpilib.event.EventLoop; + +/** + * A version of {@link {{ ClassName }}Controller} with {@link Trigger} factories for command-based. + * + * @see {{ ClassName }}Controller + */ +@SuppressWarnings("MethodName") +public class Command{{ ClassName }}Controller { + private final CommandGenericHID m_hid; + private final {{ ClassName }}Controller m_controller; + + /** + * Construct an instance of a controller. Commands bound to buttons on the controller will be + * scheduled on the {@link Scheduler#getDefault() default scheduler} using its default event loop. + * + * @param port The port index on the Driver Station that the controller is plugged into. + */ + public Command{{ ClassName }}Controller(int port) { + this(Scheduler.getDefault(), port); + } + + /** + * Construct an instance of a controller. Commands bound to buttons on the controller will be + * scheduled on the given scheduler using its default event loop. + * + * @param scheduler The scheduler that should execute the triggered commands. + * @param port The port index on the Driver Station that the controller is plugged into. + */ + public Command{{ ClassName }}Controller(Scheduler scheduler, int port) { + m_hid = CommandGenericHID.getCommandGenericHID(scheduler, port); + m_controller = new {{ ClassName }}Controller(m_hid.getHID()); + } + + /** + * Get the underlying CommandGenericHID object. + * + * @return the wrapped CommandGenericHID object + */ + public CommandGenericHID getHID() { + return m_hid; + } + + /** + * Get the wrapped controller object. + * + * @return the wrapped controller object + */ + public {{ ClassName }}Controller getController() { + return m_controller; + } +{% for button in buttons %} + /** + * Constructs a Trigger instance around the {{ button.DocName }} button's digital signal. + * + * @return a Trigger instance representing the {{ button.DocName }} button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #{{ button.Name }}(EventLoop) + */ + public Trigger {{ button.Name }}() { + return {{ button.Name }}(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the {{ button.DocName }} button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the {{ button.DocName }} button's digital signal attached + * to the given loop. + */ + public Trigger {{ button.Name }}(EventLoop loop) { + return m_hid.button({{ ClassName }}Controller.Button.{{ button.ConstantName }}.value, loop); + } +{% endfor -%} +{% for trigger in triggerAxes %} + /** + * Constructs a Trigger instance around the axis value of the {{ trigger.DocName }}. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @param loop the event loop instance to attach the Trigger to. + * @return a Trigger instance that is true when the {{ trigger.DocName }} axis exceeds the provided + * threshold, attached to the given event loop + */ + public Trigger {{ trigger.Name }}(double threshold, EventLoop loop) { + return m_hid.axisGreaterThan( + {{ ClassName }}Controller.Axis.{{ trigger.AxisConstantName }}.value, threshold, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the {{ trigger.DocName }}. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @return a Trigger instance that is true when the {{ trigger.DocName }} axis exceeds the provided + * threshold, attached to the {@link Scheduler#getDefaultEventLoop() default scheduler event + * loop} on the scheduler passed to the controller's constructor, or the {@link + * Scheduler#getDefault default scheduler} if a scheduler was not explicitly provided. + */ + public Trigger {{ trigger.Name }}(double threshold) { + return {{ trigger.Name }}(threshold, m_hid.getScheduler().getDefaultEventLoop()); + } +{% if trigger.HasDefaultThresholdMethod %} + + /** + * Constructs a Trigger instance around the axis value of the {{ trigger.DocName }}. The returned + * trigger will be true when the axis value is greater than 0.5. + * + * @return a Trigger instance that is true when the {{ trigger.DocName }} axis exceeds 0.5, attached to + * the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + */ + public Trigger {{ trigger.Name }}() { + return {{ trigger.Name }}(0.5); + } +{% endif -%} +{% endfor -%} +{% for axis in axes %} + /** + * Get the {{ axis.DocName }} value of the controller. + * + * @return The axis value. + */ + public double get{{ axis.MethodName }}() { + return m_controller.get{{ axis.MethodName }}(); + } +{% endfor -%} +} diff --git a/commandsv3/src/generated/main/java/org/wpilib/command3/button/CommandDualSenseController.java b/commandsv3/src/generated/main/java/org/wpilib/command3/button/CommandDualSenseController.java new file mode 100644 index 0000000000..d8eccd5aa0 --- /dev/null +++ b/commandsv3/src/generated/main/java/org/wpilib/command3/button/CommandDualSenseController.java @@ -0,0 +1,613 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./commandsv3/generate_files.py. DO NOT MODIFY + +package org.wpilib.command3.button; + +import org.wpilib.command3.Scheduler; +import org.wpilib.command3.Trigger; +import org.wpilib.driverstation.DualSenseController; +import org.wpilib.event.EventLoop; + +/** + * A version of {@link DualSenseController} with {@link Trigger} factories for command-based. + * + * @see DualSenseController + */ +@SuppressWarnings("MethodName") +public class CommandDualSenseController { + private final CommandGenericHID m_hid; + private final DualSenseController m_controller; + + /** + * Construct an instance of a controller. Commands bound to buttons on the controller will be + * scheduled on the {@link Scheduler#getDefault() default scheduler} using its default event loop. + * + * @param port The port index on the Driver Station that the controller is plugged into. + */ + public CommandDualSenseController(int port) { + this(Scheduler.getDefault(), port); + } + + /** + * Construct an instance of a controller. Commands bound to buttons on the controller will be + * scheduled on the given scheduler using its default event loop. + * + * @param scheduler The scheduler that should execute the triggered commands. + * @param port The port index on the Driver Station that the controller is plugged into. + */ + public CommandDualSenseController(Scheduler scheduler, int port) { + m_hid = CommandGenericHID.getCommandGenericHID(scheduler, port); + m_controller = new DualSenseController(m_hid.getHID()); + } + + /** + * Get the underlying CommandGenericHID object. + * + * @return the wrapped CommandGenericHID object + */ + public CommandGenericHID getHID() { + return m_hid; + } + + /** + * Get the wrapped controller object. + * + * @return the wrapped controller object + */ + public DualSenseController getController() { + return m_controller; + } + + /** + * Constructs a Trigger instance around the Cross button's digital signal. + * + * @return a Trigger instance representing the Cross button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #cross(EventLoop) + */ + public Trigger cross() { + return cross(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Cross button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Cross button's digital signal attached + * to the given loop. + */ + public Trigger cross(EventLoop loop) { + return m_hid.button(DualSenseController.Button.CROSS.value, loop); + } + + /** + * Constructs a Trigger instance around the Circle button's digital signal. + * + * @return a Trigger instance representing the Circle button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #circle(EventLoop) + */ + public Trigger circle() { + return circle(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Circle button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Circle button's digital signal attached + * to the given loop. + */ + public Trigger circle(EventLoop loop) { + return m_hid.button(DualSenseController.Button.CIRCLE.value, loop); + } + + /** + * Constructs a Trigger instance around the Square button's digital signal. + * + * @return a Trigger instance representing the Square button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #square(EventLoop) + */ + public Trigger square() { + return square(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Square button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Square button's digital signal attached + * to the given loop. + */ + public Trigger square(EventLoop loop) { + return m_hid.button(DualSenseController.Button.SQUARE.value, loop); + } + + /** + * Constructs a Trigger instance around the Triangle button's digital signal. + * + * @return a Trigger instance representing the Triangle button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #triangle(EventLoop) + */ + public Trigger triangle() { + return triangle(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Triangle button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Triangle button's digital signal attached + * to the given loop. + */ + public Trigger triangle(EventLoop loop) { + return m_hid.button(DualSenseController.Button.TRIANGLE.value, loop); + } + + /** + * Constructs a Trigger instance around the Create button's digital signal. + * + * @return a Trigger instance representing the Create button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #create(EventLoop) + */ + public Trigger create() { + return create(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Create button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Create button's digital signal attached + * to the given loop. + */ + public Trigger create(EventLoop loop) { + return m_hid.button(DualSenseController.Button.CREATE.value, loop); + } + + /** + * Constructs a Trigger instance around the PS button's digital signal. + * + * @return a Trigger instance representing the PS button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #PS(EventLoop) + */ + public Trigger PS() { + return PS(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the PS button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the PS button's digital signal attached + * to the given loop. + */ + public Trigger PS(EventLoop loop) { + return m_hid.button(DualSenseController.Button.PS.value, loop); + } + + /** + * Constructs a Trigger instance around the Options button's digital signal. + * + * @return a Trigger instance representing the Options button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #options(EventLoop) + */ + public Trigger options() { + return options(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Options button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Options button's digital signal attached + * to the given loop. + */ + public Trigger options(EventLoop loop) { + return m_hid.button(DualSenseController.Button.OPTIONS.value, loop); + } + + /** + * Constructs a Trigger instance around the L 3 button's digital signal. + * + * @return a Trigger instance representing the L 3 button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #L3(EventLoop) + */ + public Trigger L3() { + return L3(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the L 3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the L 3 button's digital signal attached + * to the given loop. + */ + public Trigger L3(EventLoop loop) { + return m_hid.button(DualSenseController.Button.L3.value, loop); + } + + /** + * Constructs a Trigger instance around the R 3 button's digital signal. + * + * @return a Trigger instance representing the R 3 button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #R3(EventLoop) + */ + public Trigger R3() { + return R3(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the R 3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the R 3 button's digital signal attached + * to the given loop. + */ + public Trigger R3(EventLoop loop) { + return m_hid.button(DualSenseController.Button.R3.value, loop); + } + + /** + * Constructs a Trigger instance around the L 1 button's digital signal. + * + * @return a Trigger instance representing the L 1 button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #L1(EventLoop) + */ + public Trigger L1() { + return L1(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the L 1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the L 1 button's digital signal attached + * to the given loop. + */ + public Trigger L1(EventLoop loop) { + return m_hid.button(DualSenseController.Button.L1.value, loop); + } + + /** + * Constructs a Trigger instance around the R 1 button's digital signal. + * + * @return a Trigger instance representing the R 1 button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #R1(EventLoop) + */ + public Trigger R1() { + return R1(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the R 1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the R 1 button's digital signal attached + * to the given loop. + */ + public Trigger R1(EventLoop loop) { + return m_hid.button(DualSenseController.Button.R1.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Up button's digital signal. + * + * @return a Trigger instance representing the Dpad Up button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #dpadUp(EventLoop) + */ + public Trigger dpadUp() { + return dpadUp(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Up button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Up button's digital signal attached + * to the given loop. + */ + public Trigger dpadUp(EventLoop loop) { + return m_hid.button(DualSenseController.Button.DPAD_UP.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Down button's digital signal. + * + * @return a Trigger instance representing the Dpad Down button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #dpadDown(EventLoop) + */ + public Trigger dpadDown() { + return dpadDown(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Down button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Down button's digital signal attached + * to the given loop. + */ + public Trigger dpadDown(EventLoop loop) { + return m_hid.button(DualSenseController.Button.DPAD_DOWN.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Left button's digital signal. + * + * @return a Trigger instance representing the Dpad Left button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #dpadLeft(EventLoop) + */ + public Trigger dpadLeft() { + return dpadLeft(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Left button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Left button's digital signal attached + * to the given loop. + */ + public Trigger dpadLeft(EventLoop loop) { + return m_hid.button(DualSenseController.Button.DPAD_LEFT.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Right button's digital signal. + * + * @return a Trigger instance representing the Dpad Right button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #dpadRight(EventLoop) + */ + public Trigger dpadRight() { + return dpadRight(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Right button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Right button's digital signal attached + * to the given loop. + */ + public Trigger dpadRight(EventLoop loop) { + return m_hid.button(DualSenseController.Button.DPAD_RIGHT.value, loop); + } + + /** + * Constructs a Trigger instance around the Microphone button's digital signal. + * + * @return a Trigger instance representing the Microphone button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #microphone(EventLoop) + */ + public Trigger microphone() { + return microphone(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Microphone button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Microphone button's digital signal attached + * to the given loop. + */ + public Trigger microphone(EventLoop loop) { + return m_hid.button(DualSenseController.Button.MICROPHONE.value, loop); + } + + /** + * Constructs a Trigger instance around the Touchpad button's digital signal. + * + * @return a Trigger instance representing the Touchpad button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #touchpad(EventLoop) + */ + public Trigger touchpad() { + return touchpad(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Touchpad button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Touchpad button's digital signal attached + * to the given loop. + */ + public Trigger touchpad(EventLoop loop) { + return m_hid.button(DualSenseController.Button.TOUCHPAD.value, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the L 2. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @param loop the event loop instance to attach the Trigger to. + * @return a Trigger instance that is true when the L 2 axis exceeds the provided + * threshold, attached to the given event loop + */ + public Trigger L2(double threshold, EventLoop loop) { + return m_hid.axisGreaterThan( + DualSenseController.Axis.L2.value, threshold, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the L 2. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @return a Trigger instance that is true when the L 2 axis exceeds the provided + * threshold, attached to the {@link Scheduler#getDefaultEventLoop() default scheduler event + * loop} on the scheduler passed to the controller's constructor, or the {@link + * Scheduler#getDefault default scheduler} if a scheduler was not explicitly provided. + */ + public Trigger L2(double threshold) { + return L2(threshold, m_hid.getScheduler().getDefaultEventLoop()); + } + + + /** + * Constructs a Trigger instance around the axis value of the L 2. The returned + * trigger will be true when the axis value is greater than 0.5. + * + * @return a Trigger instance that is true when the L 2 axis exceeds 0.5, attached to + * the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + */ + public Trigger L2() { + return L2(0.5); + } + + /** + * Constructs a Trigger instance around the axis value of the R 2. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @param loop the event loop instance to attach the Trigger to. + * @return a Trigger instance that is true when the R 2 axis exceeds the provided + * threshold, attached to the given event loop + */ + public Trigger R2(double threshold, EventLoop loop) { + return m_hid.axisGreaterThan( + DualSenseController.Axis.R2.value, threshold, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the R 2. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @return a Trigger instance that is true when the R 2 axis exceeds the provided + * threshold, attached to the {@link Scheduler#getDefaultEventLoop() default scheduler event + * loop} on the scheduler passed to the controller's constructor, or the {@link + * Scheduler#getDefault default scheduler} if a scheduler was not explicitly provided. + */ + public Trigger R2(double threshold) { + return R2(threshold, m_hid.getScheduler().getDefaultEventLoop()); + } + + + /** + * Constructs a Trigger instance around the axis value of the R 2. The returned + * trigger will be true when the axis value is greater than 0.5. + * + * @return a Trigger instance that is true when the R 2 axis exceeds 0.5, attached to + * the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + */ + public Trigger R2() { + return R2(0.5); + } + + /** + * Get the Left X value of the controller. + * + * @return The axis value. + */ + public double getLeftX() { + return m_controller.getLeftX(); + } + + /** + * Get the Left Y value of the controller. + * + * @return The axis value. + */ + public double getLeftY() { + return m_controller.getLeftY(); + } + + /** + * Get the Right X value of the controller. + * + * @return The axis value. + */ + public double getRightX() { + return m_controller.getRightX(); + } + + /** + * Get the Right Y value of the controller. + * + * @return The axis value. + */ + public double getRightY() { + return m_controller.getRightY(); + } + + /** + * Get the L 2 value of the controller. + * + * @return The axis value. + */ + public double getL2() { + return m_controller.getL2(); + } + + /** + * Get the R 2 value of the controller. + * + * @return The axis value. + */ + public double getR2() { + return m_controller.getR2(); + } +} diff --git a/commandsv3/src/generated/main/java/org/wpilib/command3/button/CommandXboxController.java b/commandsv3/src/generated/main/java/org/wpilib/command3/button/CommandXboxController.java new file mode 100644 index 0000000000..ebde4acad3 --- /dev/null +++ b/commandsv3/src/generated/main/java/org/wpilib/command3/button/CommandXboxController.java @@ -0,0 +1,565 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./commandsv3/generate_files.py. DO NOT MODIFY + +package org.wpilib.command3.button; + +import org.wpilib.command3.Scheduler; +import org.wpilib.command3.Trigger; +import org.wpilib.driverstation.XboxController; +import org.wpilib.event.EventLoop; + +/** + * A version of {@link XboxController} with {@link Trigger} factories for command-based. + * + * @see XboxController + */ +@SuppressWarnings("MethodName") +public class CommandXboxController { + private final CommandGenericHID m_hid; + private final XboxController m_controller; + + /** + * Construct an instance of a controller. Commands bound to buttons on the controller will be + * scheduled on the {@link Scheduler#getDefault() default scheduler} using its default event loop. + * + * @param port The port index on the Driver Station that the controller is plugged into. + */ + public CommandXboxController(int port) { + this(Scheduler.getDefault(), port); + } + + /** + * Construct an instance of a controller. Commands bound to buttons on the controller will be + * scheduled on the given scheduler using its default event loop. + * + * @param scheduler The scheduler that should execute the triggered commands. + * @param port The port index on the Driver Station that the controller is plugged into. + */ + public CommandXboxController(Scheduler scheduler, int port) { + m_hid = CommandGenericHID.getCommandGenericHID(scheduler, port); + m_controller = new XboxController(m_hid.getHID()); + } + + /** + * Get the underlying CommandGenericHID object. + * + * @return the wrapped CommandGenericHID object + */ + public CommandGenericHID getHID() { + return m_hid; + } + + /** + * Get the wrapped controller object. + * + * @return the wrapped controller object + */ + public XboxController getController() { + return m_controller; + } + + /** + * Constructs a Trigger instance around the A button's digital signal. + * + * @return a Trigger instance representing the A button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #a(EventLoop) + */ + public Trigger a() { + return a(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the A button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the A button's digital signal attached + * to the given loop. + */ + public Trigger a(EventLoop loop) { + return m_hid.button(XboxController.Button.A.value, loop); + } + + /** + * Constructs a Trigger instance around the B button's digital signal. + * + * @return a Trigger instance representing the B button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #b(EventLoop) + */ + public Trigger b() { + return b(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the B button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the B button's digital signal attached + * to the given loop. + */ + public Trigger b(EventLoop loop) { + return m_hid.button(XboxController.Button.B.value, loop); + } + + /** + * Constructs a Trigger instance around the X button's digital signal. + * + * @return a Trigger instance representing the X button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #x(EventLoop) + */ + public Trigger x() { + return x(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the X button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the X button's digital signal attached + * to the given loop. + */ + public Trigger x(EventLoop loop) { + return m_hid.button(XboxController.Button.X.value, loop); + } + + /** + * Constructs a Trigger instance around the Y button's digital signal. + * + * @return a Trigger instance representing the Y button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #y(EventLoop) + */ + public Trigger y() { + return y(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Y button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Y button's digital signal attached + * to the given loop. + */ + public Trigger y(EventLoop loop) { + return m_hid.button(XboxController.Button.Y.value, loop); + } + + /** + * Constructs a Trigger instance around the View button's digital signal. + * + * @return a Trigger instance representing the View button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #view(EventLoop) + */ + public Trigger view() { + return view(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the View button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the View button's digital signal attached + * to the given loop. + */ + public Trigger view(EventLoop loop) { + return m_hid.button(XboxController.Button.VIEW.value, loop); + } + + /** + * Constructs a Trigger instance around the Xbox button's digital signal. + * + * @return a Trigger instance representing the Xbox button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #xbox(EventLoop) + */ + public Trigger xbox() { + return xbox(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Xbox button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Xbox button's digital signal attached + * to the given loop. + */ + public Trigger xbox(EventLoop loop) { + return m_hid.button(XboxController.Button.XBOX.value, loop); + } + + /** + * Constructs a Trigger instance around the Menu button's digital signal. + * + * @return a Trigger instance representing the Menu button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #menu(EventLoop) + */ + public Trigger menu() { + return menu(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Menu button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Menu button's digital signal attached + * to the given loop. + */ + public Trigger menu(EventLoop loop) { + return m_hid.button(XboxController.Button.MENU.value, loop); + } + + /** + * Constructs a Trigger instance around the Left Stick button's digital signal. + * + * @return a Trigger instance representing the Left Stick button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #leftStick(EventLoop) + */ + public Trigger leftStick() { + return leftStick(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Left Stick button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Left Stick button's digital signal attached + * to the given loop. + */ + public Trigger leftStick(EventLoop loop) { + return m_hid.button(XboxController.Button.LEFT_STICK.value, loop); + } + + /** + * Constructs a Trigger instance around the Right Stick button's digital signal. + * + * @return a Trigger instance representing the Right Stick button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #rightStick(EventLoop) + */ + public Trigger rightStick() { + return rightStick(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Right Stick button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Right Stick button's digital signal attached + * to the given loop. + */ + public Trigger rightStick(EventLoop loop) { + return m_hid.button(XboxController.Button.RIGHT_STICK.value, loop); + } + + /** + * Constructs a Trigger instance around the Left Bumper button's digital signal. + * + * @return a Trigger instance representing the Left Bumper button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #leftBumper(EventLoop) + */ + public Trigger leftBumper() { + return leftBumper(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Left Bumper button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Left Bumper button's digital signal attached + * to the given loop. + */ + public Trigger leftBumper(EventLoop loop) { + return m_hid.button(XboxController.Button.LEFT_BUMPER.value, loop); + } + + /** + * Constructs a Trigger instance around the Right Bumper button's digital signal. + * + * @return a Trigger instance representing the Right Bumper button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #rightBumper(EventLoop) + */ + public Trigger rightBumper() { + return rightBumper(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Right Bumper button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Right Bumper button's digital signal attached + * to the given loop. + */ + public Trigger rightBumper(EventLoop loop) { + return m_hid.button(XboxController.Button.RIGHT_BUMPER.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Up button's digital signal. + * + * @return a Trigger instance representing the Dpad Up button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #dpadUp(EventLoop) + */ + public Trigger dpadUp() { + return dpadUp(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Up button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Up button's digital signal attached + * to the given loop. + */ + public Trigger dpadUp(EventLoop loop) { + return m_hid.button(XboxController.Button.DPAD_UP.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Down button's digital signal. + * + * @return a Trigger instance representing the Dpad Down button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #dpadDown(EventLoop) + */ + public Trigger dpadDown() { + return dpadDown(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Down button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Down button's digital signal attached + * to the given loop. + */ + public Trigger dpadDown(EventLoop loop) { + return m_hid.button(XboxController.Button.DPAD_DOWN.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Left button's digital signal. + * + * @return a Trigger instance representing the Dpad Left button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #dpadLeft(EventLoop) + */ + public Trigger dpadLeft() { + return dpadLeft(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Left button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Left button's digital signal attached + * to the given loop. + */ + public Trigger dpadLeft(EventLoop loop) { + return m_hid.button(XboxController.Button.DPAD_LEFT.value, loop); + } + + /** + * Constructs a Trigger instance around the Dpad Right button's digital signal. + * + * @return a Trigger instance representing the Dpad Right button's digital signal attached + * to the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + * @see #dpadRight(EventLoop) + */ + public Trigger dpadRight() { + return dpadRight(m_hid.getScheduler().getDefaultEventLoop()); + } + + /** + * Constructs a Trigger instance around the Dpad Right button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return a Trigger instance representing the Dpad Right button's digital signal attached + * to the given loop. + */ + public Trigger dpadRight(EventLoop loop) { + return m_hid.button(XboxController.Button.DPAD_RIGHT.value, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the Left Trigger. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @param loop the event loop instance to attach the Trigger to. + * @return a Trigger instance that is true when the Left Trigger axis exceeds the provided + * threshold, attached to the given event loop + */ + public Trigger leftTrigger(double threshold, EventLoop loop) { + return m_hid.axisGreaterThan( + XboxController.Axis.LEFT_TRIGGER.value, threshold, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the Left Trigger. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @return a Trigger instance that is true when the Left Trigger axis exceeds the provided + * threshold, attached to the {@link Scheduler#getDefaultEventLoop() default scheduler event + * loop} on the scheduler passed to the controller's constructor, or the {@link + * Scheduler#getDefault default scheduler} if a scheduler was not explicitly provided. + */ + public Trigger leftTrigger(double threshold) { + return leftTrigger(threshold, m_hid.getScheduler().getDefaultEventLoop()); + } + + + /** + * Constructs a Trigger instance around the axis value of the Left Trigger. The returned + * trigger will be true when the axis value is greater than 0.5. + * + * @return a Trigger instance that is true when the Left Trigger axis exceeds 0.5, attached to + * the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + */ + public Trigger leftTrigger() { + return leftTrigger(0.5); + } + + /** + * Constructs a Trigger instance around the axis value of the Right Trigger. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @param loop the event loop instance to attach the Trigger to. + * @return a Trigger instance that is true when the Right Trigger axis exceeds the provided + * threshold, attached to the given event loop + */ + public Trigger rightTrigger(double threshold, EventLoop loop) { + return m_hid.axisGreaterThan( + XboxController.Axis.RIGHT_TRIGGER.value, threshold, loop); + } + + /** + * Constructs a Trigger instance around the axis value of the Right Trigger. The returned + * trigger will be true when the axis value is greater than {@code threshold}. + * + * @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value + * should be in the range [0, 1] where 0 is the unpressed state of the axis. + * @return a Trigger instance that is true when the Right Trigger axis exceeds the provided + * threshold, attached to the {@link Scheduler#getDefaultEventLoop() default scheduler event + * loop} on the scheduler passed to the controller's constructor, or the {@link + * Scheduler#getDefault default scheduler} if a scheduler was not explicitly provided. + */ + public Trigger rightTrigger(double threshold) { + return rightTrigger(threshold, m_hid.getScheduler().getDefaultEventLoop()); + } + + + /** + * Constructs a Trigger instance around the axis value of the Right Trigger. The returned + * trigger will be true when the axis value is greater than 0.5. + * + * @return a Trigger instance that is true when the Right Trigger axis exceeds 0.5, attached to + * the {@link Scheduler#getDefaultEventLoop() default scheduler event loop} on the + * scheduler passed to the controller's constructor, or the {@link Scheduler#getDefault + * default scheduler} if a scheduler was not explicitly provided. + */ + public Trigger rightTrigger() { + return rightTrigger(0.5); + } + + /** + * Get the Left X value of the controller. + * + * @return The axis value. + */ + public double getLeftX() { + return m_controller.getLeftX(); + } + + /** + * Get the Left Y value of the controller. + * + * @return The axis value. + */ + public double getLeftY() { + return m_controller.getLeftY(); + } + + /** + * Get the Right X value of the controller. + * + * @return The axis value. + */ + public double getRightX() { + return m_controller.getRightX(); + } + + /** + * Get the Right Y value of the controller. + * + * @return The axis value. + */ + public double getRightY() { + return m_controller.getRightY(); + } + + /** + * Get the Left Trigger value of the controller. + * + * @return The axis value. + */ + public double getLeftTrigger() { + return m_controller.getLeftTrigger(); + } + + /** + * Get the Right Trigger value of the controller. + * + * @return The axis value. + */ + public double getRightTrigger() { + return m_controller.getRightTrigger(); + } +} diff --git a/wpilibc/BUILD.bazel b/wpilibc/BUILD.bazel index a7a536c807..a287de065b 100644 --- a/wpilibc/BUILD.bazel +++ b/wpilibc/BUILD.bazel @@ -31,6 +31,16 @@ py_binary( deps = [requirement("jinja2")], ) +py_binary( + name = "generate_first_ds_hids", + srcs = ["generate_first_ds_hids.py"], + target_compatible_with = select({ + "@rules_bzlmodrio_toolchains//constraints/is_systemcore:systemcore": ["@platforms//:incompatible"], + "//conditions:default": [], + }), + deps = [requirement("jinja2")], +) + py_binary( name = "generate_pwm_motor_controllers", srcs = ["generate_pwm_motor_controllers.py"], @@ -51,6 +61,7 @@ py_binary( "//conditions:default": [], }), deps = [ + ":generate_first_ds_hids", ":generate_hids", ":generate_pwm_motor_controllers", ], @@ -58,7 +69,7 @@ py_binary( filegroup( name = "templates", - srcs = glob(["src/generate/main/native/**"]) + [ + srcs = glob(["src/generate/main/native/**"]) + glob(["src/generate/test/native/**"]) + [ "//wpilibj:hid_schema", "//wpilibj:pwm_schema", ], @@ -178,7 +189,10 @@ cc_library( cc_test( name = "wpilibc-test", size = "small", - srcs = glob(["src/test/native/cpp/**"]), + srcs = glob([ + "src/generated/test/native/cpp/**", + "src/test/native/cpp/**", + ]), tags = [ "no-tsan", "no-ubsan", diff --git a/wpilibc/CMakeLists.txt b/wpilibc/CMakeLists.txt index 7f4907b296..0154e50588 100644 --- a/wpilibc/CMakeLists.txt +++ b/wpilibc/CMakeLists.txt @@ -50,6 +50,8 @@ install(EXPORT wpilibc DESTINATION share/wpilibc) if(WITH_TESTS) wpilib_add_test(wpilibc src/test/native/cpp) + file(GLOB_RECURSE wpilibc_generated_test_src src/generated/test/native/cpp/*.cpp) + target_sources(wpilibc_test PRIVATE ${wpilibc_generated_test_src}) target_include_directories(wpilibc_test PRIVATE src/test/native/include) target_link_libraries(wpilibc_test wpilibc googletest) if(NOT WITH_CSCORE) diff --git a/wpilibc/build.gradle b/wpilibc/build.gradle index f9086fa4fb..aa54c083f1 100644 --- a/wpilibc/build.gradle +++ b/wpilibc/build.gradle @@ -193,6 +193,15 @@ model { srcDirs 'src/test/native/include', 'src/main/native/cpp' } } + generatedCpp(CppSourceSet) { + source { + srcDirs 'src/generated/test/native/cpp' + include '**/*.cpp' + } + exportedHeaders { + srcDirs 'src/test/native/include' + } + } c { source { srcDirs 'src/test/native/c' @@ -203,6 +212,11 @@ model { } } } + it.sources.each { + it.exportedHeaders { + srcDirs 'src/test/native/include' + } + } } } binaries { diff --git a/wpilibc/generate.bzl b/wpilibc/generate.bzl index cc4249ce08..0922abddbd 100644 --- a/wpilibc/generate.bzl +++ b/wpilibc/generate.bzl @@ -8,6 +8,7 @@ def __generate_wpilibc_impl(ctx): args.add("--output_directory", output_dir.path) args.add("--schema_root", "wpilibj/src/generate") args.add("--template_root", "wpilibc/src/generate") + args.add("--test_output_directory", output_dir.path + "/test") ctx.actions.run( inputs = ctx.attr._templates.files, diff --git a/wpilibc/generate_first_ds_hids.py b/wpilibc/generate_first_ds_hids.py new file mode 100644 index 0000000000..b575cb365d --- /dev/null +++ b/wpilibc/generate_first_ds_hids.py @@ -0,0 +1,237 @@ +#!/usr/bin/env python3 + +# 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. + +import argparse +import json +import re +from pathlib import Path + +from jinja2 import Environment, FileSystemLoader + + +def write_controller_file(output_dir: Path, controller_name: str, contents: str): + output_dir.mkdir(parents=True, exist_ok=True) + output_file = output_dir / controller_name + output_file.write_text(contents, encoding="utf-8", newline="\n") + + +def _capitalize_first(name: str) -> str: + return name[0].upper() + name[1:] + + +def _display_name(name: str) -> str: + name = re.sub(r"([a-z0-9])([A-Z])", r"\1 \2", name) + name = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1 \2", name) + name = re.sub(r"([A-Za-z])([0-9])", r"\1 \2", name) + return name[0].upper() + name[1:] + + +def _constant_name(name: str) -> str: + name = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1_\2", name) + name = re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name) + name = re.sub(r"([a-z])([0-9])", r"\1_\2", name) + return name.upper() + + +def _normalize_mapping(mapping: dict[str, int]): + return [ + { + "Name": name, + "MethodName": _capitalize_first(name), + "ConstantName": _constant_name(name), + "DocName": _display_name(name), + "value": value, + } + for name, value in mapping.items() + ] + + +def _supported_outputs(controller: dict): + supports = controller["supports"] + outputs = [] + if supports["monoLed"]: + outputs.append("MONO_LED") + if supports["rgbLed"]: + outputs.append("RGB_LED") + if supports["rumble"]: + outputs.append("RUMBLE") + if supports["triggerRumble"]: + outputs.append("TRIGGER_RUMBLE") + return outputs + + +def _supported_outputs_value(outputs: list[str]): + values = { + "MONO_LED": 0x1, + "RGB_LED": 0x2, + "RUMBLE": 0x8, + "TRIGGER_RUMBLE": 0x10, + } + result = 0 + for output in outputs: + result |= values[output] + return result + + +def _availability_mask(mapping: list[dict]): + result = 0 + for entry in mapping: + result |= 1 << entry["value"] + return result + + +def _hex_literal(value: int): + return f"0x{value:X}" + + +def _normalize_controller(controller: dict): + normalized = dict(controller) + normalized["axes"] = _normalize_mapping(controller["axes"]) + normalized["buttons"] = _normalize_mapping(controller["buttons"]) + normalized["supportedOutputs"] = _supported_outputs(controller) + normalized["SupportedOutputsValue"] = _supported_outputs_value( + normalized["supportedOutputs"] + ) + normalized["AxesMaximumIndex"] = ( + max(axis["value"] for axis in normalized["axes"]) + 1 + if normalized["axes"] + else 0 + ) + normalized["ButtonsMaximumIndex"] = ( + max(button["value"] for button in normalized["buttons"]) + 1 + if normalized["buttons"] + else 0 + ) + normalized["AxesAvailableMask"] = _hex_literal( + _availability_mask(normalized["axes"]) + ) + normalized["ButtonsAvailableMask"] = _hex_literal( + _availability_mask(normalized["buttons"]) + ) + return normalized + + +def generate_first_ds_hids( + output_directory: Path, + template_directory: Path, + schema_file: Path, + test_output_directory: Path | None = None, +): + with schema_file.open(encoding="utf-8") as f: + controllers = [_normalize_controller(controller) for controller in json.load(f)] + + hdr_subdirectory = "main/native/include/wpi/driverstation" + env = Environment( + loader=FileSystemLoader(template_directory / hdr_subdirectory), + autoescape=False, + keep_trailing_newline=True, + ) + root_path = output_directory / hdr_subdirectory + template = env.get_template("first_ds_hid.hpp.jinja") + for controller in controllers: + controller_name = f"{controller['ClassName']}Controller.hpp" + output = template.render(controller) + write_controller_file(root_path, controller_name, output) + + cpp_subdirectory = "main/native/cpp/driverstation" + env = Environment( + loader=FileSystemLoader(template_directory / cpp_subdirectory), + autoescape=False, + keep_trailing_newline=True, + ) + root_path = output_directory / cpp_subdirectory + template = env.get_template("first_ds_hid.cpp.jinja") + for controller in controllers: + controller_name = f"{controller['ClassName']}Controller.cpp" + output = template.render(controller) + write_controller_file(root_path, controller_name, output) + + sim_hdr_subdirectory = "main/native/include/wpi/simulation" + env = Environment( + loader=FileSystemLoader(template_directory / sim_hdr_subdirectory), + autoescape=False, + keep_trailing_newline=True, + ) + root_path = output_directory / sim_hdr_subdirectory + template = env.get_template("first_ds_hidsim.hpp.jinja") + for controller in controllers: + controller_name = f"{controller['ClassName']}ControllerSim.hpp" + output = template.render(controller) + write_controller_file(root_path, controller_name, output) + + sim_cpp_subdirectory = "main/native/cpp/simulation" + env = Environment( + loader=FileSystemLoader(template_directory / sim_cpp_subdirectory), + autoescape=False, + keep_trailing_newline=True, + ) + root_path = output_directory / sim_cpp_subdirectory + template = env.get_template("first_ds_hidsim.cpp.jinja") + for controller in controllers: + controller_name = f"{controller['ClassName']}ControllerSim.cpp" + output = template.render(controller) + write_controller_file(root_path, controller_name, output) + + if test_output_directory is not None: + env = Environment( + loader=FileSystemLoader(template_directory / "test/native/cpp"), + autoescape=False, + keep_trailing_newline=True, + ) + root_path = test_output_directory / "native/cpp" + template = env.get_template("first_ds_hid_test.cpp.jinja") + for controller in controllers: + controller_name = f"{controller['ClassName']}ControllerTest.cpp" + output = template.render(controller) + write_controller_file(root_path, controller_name, output) + + +def main(): + script_path = Path(__file__).resolve() + dirname = script_path.parent + + parser = argparse.ArgumentParser() + parser.add_argument( + "--output_directory", + help="Optional. If set, will output the generated files to this directory, otherwise it will use a path relative to the script", + default=dirname / "src/generated", + type=Path, + ) + parser.add_argument( + "--template_root", + help="Optional. If set, will use this directory as the root for the jinja templates", + default=dirname / "src/generate", + type=Path, + ) + parser.add_argument( + "--schema_file", + help="Optional. If set, will use this file for the FIRST Driver Station HID schema", + default="wpilibj/src/generate/first_ds_hids.json", + type=Path, + ) + parser.add_argument( + "--test_output_directory", + help="Optional. If set, will output generated tests to this directory", + default=dirname / "src/generated/test", + type=Path, + ) + args = parser.parse_args() + + test_output_directory = ( + None + if args.test_output_directory.name == "__none__" + else args.test_output_directory + ) + generate_first_ds_hids( + args.output_directory, + args.template_root, + args.schema_file, + test_output_directory, + ) + + +if __name__ == "__main__": + main() diff --git a/wpilibc/generate_wpilibc.py b/wpilibc/generate_wpilibc.py index d46c48afed..377a763196 100644 --- a/wpilibc/generate_wpilibc.py +++ b/wpilibc/generate_wpilibc.py @@ -2,6 +2,7 @@ import argparse import os from pathlib import Path +from wpilibc.generate_first_ds_hids import generate_first_ds_hids from wpilibc.generate_hids import generate_hids from wpilibc.generate_pwm_motor_controllers import generate_pwm_motor_controllers @@ -28,11 +29,28 @@ def main(): default=os.path.join(dirname, "src/generate"), type=Path, ) + parser.add_argument( + "--test_output_directory", + help="Optional. If set, will output generated tests to this directory", + default=os.path.join(dirname, "src/generated/test"), + type=Path, + ) args = parser.parse_args() generate_hids( args.output_directory, args.template_root, args.schema_root / "hids.json" ) + test_output_directory = ( + None + if args.test_output_directory.name == "__none__" + else args.test_output_directory + ) + generate_first_ds_hids( + args.output_directory, + args.template_root, + args.schema_root / "first_ds_hids.json", + test_output_directory, + ) generate_pwm_motor_controllers( args.output_directory, args.template_root, args.schema_root ) diff --git a/wpilibc/robotpy_pybind_build_info.bzl b/wpilibc/robotpy_pybind_build_info.bzl index c80068e8a2..25b9ce5555 100644 --- a/wpilibc/robotpy_pybind_build_info.bzl +++ b/wpilibc/robotpy_pybind_build_info.bzl @@ -231,6 +231,30 @@ def wpilib_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includ ("wpi::Joystick", "wpi__Joystick.hpp"), ], ), + struct( + class_name = "DualSenseController", + yml_file = "semiwrap/DualSenseController.yml", + header_root = "$(execpath :robotpy-native-wpilib.copy_headers)", + header_file = "$(execpath :robotpy-native-wpilib.copy_headers)/wpi/driverstation/DualSenseController.hpp", + tmpl_class_names = [], + trampolines = [ + ("wpi::DualSenseController", "wpi__DualSenseController.hpp"), + ("wpi::DualSenseController::Button", "wpi__DualSenseController__Button.hpp"), + ("wpi::DualSenseController::Axis", "wpi__DualSenseController__Axis.hpp"), + ], + ), + struct( + class_name = "XboxController", + yml_file = "semiwrap/XboxController.yml", + header_root = "$(execpath :robotpy-native-wpilib.copy_headers)", + header_file = "$(execpath :robotpy-native-wpilib.copy_headers)/wpi/driverstation/XboxController.hpp", + tmpl_class_names = [], + trampolines = [ + ("wpi::XboxController", "wpi__XboxController.hpp"), + ("wpi::XboxController::Button", "wpi__XboxController__Button.hpp"), + ("wpi::XboxController::Axis", "wpi__XboxController__Axis.hpp"), + ], + ), struct( class_name = "NiDsPS4Controller", yml_file = "semiwrap/NiDsPS4Controller.yml", @@ -1442,6 +1466,26 @@ def wpilib_simulation_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = ("wpi::sim::LinearSystemSim", "wpi__sim__LinearSystemSim.hpp"), ], ), + struct( + class_name = "DualSenseControllerSim", + yml_file = "semiwrap/simulation/DualSenseControllerSim.yml", + header_root = "$(execpath :robotpy-native-wpilib.copy_headers)", + header_file = "$(execpath :robotpy-native-wpilib.copy_headers)/wpi/simulation/DualSenseControllerSim.hpp", + tmpl_class_names = [], + trampolines = [ + ("wpi::sim::DualSenseControllerSim", "wpi__sim__DualSenseControllerSim.hpp"), + ], + ), + struct( + class_name = "XboxControllerSim", + yml_file = "semiwrap/simulation/XboxControllerSim.yml", + header_root = "$(execpath :robotpy-native-wpilib.copy_headers)", + header_file = "$(execpath :robotpy-native-wpilib.copy_headers)/wpi/simulation/XboxControllerSim.hpp", + tmpl_class_names = [], + trampolines = [ + ("wpi::sim::XboxControllerSim", "wpi__sim__XboxControllerSim.hpp"), + ], + ), struct( class_name = "NiDsPS4ControllerSim", yml_file = "semiwrap/simulation/NiDsPS4ControllerSim.yml", diff --git a/wpilibc/src/generate/main/native/cpp/driverstation/first_ds_hid.cpp.jinja b/wpilibc/src/generate/main/native/cpp/driverstation/first_ds_hid.cpp.jinja new file mode 100644 index 0000000000..44b5a36c87 --- /dev/null +++ b/wpilibc/src/generate/main/native/cpp/driverstation/first_ds_hid.cpp.jinja @@ -0,0 +1,128 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#include "wpi/driverstation/{{ ClassName }}Controller.hpp" + +#include "wpi/driverstation/DriverStation.hpp" +#include "wpi/event/BooleanEvent.hpp" +#include "wpi/hal/UsageReporting.hpp" +#include "wpi/util/sendable/SendableBuilder.hpp" + +using namespace wpi; + +{{ ClassName }}Controller::{{ ClassName }}Controller(int port) + : {{ ClassName }}Controller{DriverStation::GetGenericHID(port)} {} + +{{ ClassName }}Controller::{{ ClassName }}Controller(GenericHID& hid) + : m_hid{&hid} { + HAL_ReportUsage("HID", hid.GetPort(), "{{ ClassName }}Controller"); +} + +GenericHID& {{ ClassName }}Controller::GetHID() { + return *m_hid; +} + +const GenericHID& {{ ClassName }}Controller::GetHID() const { + return *m_hid; +} + +int {{ ClassName }}Controller::GetPort() const { + return m_hid->GetPort(); +} + +bool {{ ClassName }}Controller::IsConnected() const { + return m_hid->IsConnected(); +} +{% for axis in axes %} +double {{ ClassName }}Controller::Get{{ axis.MethodName }}() const { + return GetAxis(Axis::{{ axis.ConstantName }}); +} +{% endfor %} +double {{ ClassName }}Controller::GetAxis(int axis) const { + return m_hid->GetRawAxis(axis); +} + +BooleanEvent {{ ClassName }}Controller::AxisLessThan(int axis, double threshold, + EventLoop* loop) const { + return m_hid->AxisLessThan(axis, threshold, loop); +} + +BooleanEvent {{ ClassName }}Controller::AxisGreaterThan( + int axis, double threshold, EventLoop* loop) const { + return m_hid->AxisGreaterThan(axis, threshold, loop); +} +{% for button in buttons %} +bool {{ ClassName }}Controller::Get{{ button.MethodName }}Button() const { + return GetButton(Button::{{ button.ConstantName }}); +} + +bool {{ ClassName }}Controller::Get{{ button.MethodName }}ButtonPressed() { + return GetButtonPressed(Button::{{ button.ConstantName }}); +} + +bool {{ ClassName }}Controller::Get{{ button.MethodName }}ButtonReleased() { + return GetButtonReleased(Button::{{ button.ConstantName }}); +} + +BooleanEvent {{ ClassName }}Controller::{{ button.MethodName }}(EventLoop* loop) const { + return ButtonEvent(Button::{{ button.ConstantName }}, loop); +} +{% endfor %} +bool {{ ClassName }}Controller::GetButton(int button) const { + return m_hid->GetRawButton(button); +} + +bool {{ ClassName }}Controller::GetButtonPressed(int button) { + return m_hid->GetRawButtonPressed(button); +} + +bool {{ ClassName }}Controller::GetButtonReleased(int button) { + return m_hid->GetRawButtonReleased(button); +} + +BooleanEvent {{ ClassName }}Controller::ButtonEvent(int button, + EventLoop* loop) const { + return m_hid->Button(button, loop); +} + +void {{ ClassName }}Controller::SetLeds(int r, int g, int b) { + m_hid->SetLeds(r, g, b); +} + +void {{ ClassName }}Controller::SetRumble(GenericHID::RumbleType type, + double value) { + m_hid->SetRumble(type, value); +} + +{% if touchpads == 1 %} +bool {{ ClassName }}Controller::GetTouchpadFingerAvailable(int finger) const { + return m_hid->GetTouchpadFingerAvailable(0, finger); +} + +TouchpadFinger {{ ClassName }}Controller::GetTouchpadFinger(int finger) const { + return m_hid->GetTouchpadFinger(0, finger); +} +{% elif touchpads > 1 %} +bool {{ ClassName }}Controller::GetTouchpadFingerAvailable(int touchpad, + int finger) const { + return m_hid->GetTouchpadFingerAvailable(touchpad, finger); +} + +TouchpadFinger {{ ClassName }}Controller::GetTouchpadFinger(int touchpad, + int finger) const { + return m_hid->GetTouchpadFinger(touchpad, finger); +} +{% endif %} + +void {{ ClassName }}Controller::InitSendable(wpi::util::SendableBuilder& builder) { + builder.SetSmartDashboardType("HID"); + builder.PublishConstString("ControllerType", "{{ ClassName }}"); +{%- for axis in axes %} + builder.AddDoubleProperty("{{ axis.MethodName }}", [this] { return Get{{ axis.MethodName }}(); }, nullptr); +{%- endfor -%} +{% for button in buttons %} + builder.AddBooleanProperty("{{ button.MethodName }}", [this] { return Get{{ button.MethodName }}Button(); }, nullptr); +{%- endfor %} +} diff --git a/wpilibc/src/generate/main/native/cpp/simulation/first_ds_hidsim.cpp.jinja b/wpilibc/src/generate/main/native/cpp/simulation/first_ds_hidsim.cpp.jinja new file mode 100644 index 0000000000..182a6eb448 --- /dev/null +++ b/wpilibc/src/generate/main/native/cpp/simulation/first_ds_hidsim.cpp.jinja @@ -0,0 +1,38 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#include "wpi/simulation/{{ ClassName }}ControllerSim.hpp" + +#include "wpi/driverstation/{{ ClassName }}Controller.hpp" + +using namespace wpi; +using namespace wpi::sim; + +{{ ClassName }}ControllerSim::{{ ClassName }}ControllerSim(const {{ ClassName }}Controller& joystick) + : GenericHIDSim{joystick.GetHID()} { + SetAxesAvailable({{ AxesAvailableMask }}); + SetButtonsAvailable({{ ButtonsAvailableMask }}ULL); + SetPOVsAvailable(0); + SetGamepadType(GenericHID::HIDType::{{ HIDType }}); + SetSupportedOutputs({{ ClassName }}Controller::SUPPORTED_OUTPUTS); +} + +{{ ClassName }}ControllerSim::{{ ClassName }}ControllerSim(int port) : GenericHIDSim{port} { + SetAxesAvailable({{ AxesAvailableMask }}); + SetButtonsAvailable({{ ButtonsAvailableMask }}ULL); + SetPOVsAvailable(0); + SetGamepadType(GenericHID::HIDType::{{ HIDType }}); + SetSupportedOutputs({{ ClassName }}Controller::SUPPORTED_OUTPUTS); +} +{% for axis in axes %} +void {{ ClassName }}ControllerSim::Set{{ axis.MethodName }}(double value) { + SetRawAxis({{ ClassName }}Controller::Axis::{{ axis.ConstantName }}, value); +} +{% endfor -%} +{% for button in buttons %} +void {{ ClassName }}ControllerSim::Set{{ button.MethodName }}Button(bool value) { + SetRawButton({{ ClassName }}Controller::Button::{{ button.ConstantName }}, value); +} +{% endfor -%} diff --git a/wpilibc/src/generate/main/native/include/wpi/driverstation/first_ds_hid.hpp.jinja b/wpilibc/src/generate/main/native/include/wpi/driverstation/first_ds_hid.hpp.jinja new file mode 100644 index 0000000000..9b1f28c823 --- /dev/null +++ b/wpilibc/src/generate/main/native/include/wpi/driverstation/first_ds_hid.hpp.jinja @@ -0,0 +1,275 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#pragma once + +#include "wpi/driverstation/GenericHID.hpp" +#include "wpi/driverstation/HIDDevice.hpp" +#include "wpi/driverstation/TouchpadFinger.hpp" +#include "wpi/util/sendable/Sendable.hpp" +#include "wpi/util/sendable/SendableHelper.hpp" + +namespace wpi { + +class BooleanEvent; +class EventLoop; + +/** + * Handle input from {{ ClassName }} controllers connected to the Driver Station. + * + * This class handles {{ ClassName }} input that comes from the Driver Station. + * Each time a value is requested the most recent value is returned. + */ +class {{ ClassName }}Controller + : public HIDDevice, + public wpi::util::Sendable, + public wpi::util::SendableHelper<{{ ClassName }}Controller> { + public: + /** The number of touchpads supported by this controller. */ + static constexpr int TOUCHPAD_COUNT = {{ touchpads }}; + + /** Whether this controller supports main rumble motors. */ + static constexpr bool SUPPORTS_RUMBLE = {{ "true" if supports.rumble else "false" }}; + + /** Whether this controller supports trigger rumble motors. */ + static constexpr bool SUPPORTS_TRIGGER_RUMBLE = {{ "true" if supports.triggerRumble else "false" }}; + + /** Whether this controller supports mono LED output. */ + static constexpr bool SUPPORTS_MONO_LED = {{ "true" if supports.monoLed else "false" }}; + + /** Whether this controller supports RGB LED output. */ + static constexpr bool SUPPORTS_RGB_LED = {{ "true" if supports.rgbLed else "false" }}; + + /** Supported outputs expected for this controller type. */ + static constexpr GenericHID::SupportedOutputs SUPPORTED_OUTPUTS = + static_cast({{ SupportedOutputsValue }}); + + /** + * Construct an instance of a 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. + */ + explicit {{ ClassName }}Controller(int port); + + /** + * Construct an instance of a controller with a GenericHID object. + * + * @param hid The GenericHID object to use for this controller. + */ + explicit {{ ClassName }}Controller(GenericHID& hid); + + ~{{ ClassName }}Controller() override = default; + + {{ ClassName }}Controller({{ ClassName }}Controller&&) = default; + {{ ClassName }}Controller& operator=({{ ClassName }}Controller&&) = default; + + /** + * Get the underlying GenericHID object. + * + * @return the wrapped GenericHID object + */ + GenericHID& GetHID() override; + + /** + * Get the underlying GenericHID object. + * + * @return the wrapped GenericHID object + */ + const GenericHID& GetHID() const override; + + /** + * Get the port number of the HID. + * + * @return The port number of the HID. + */ + int GetPort() const; + + /** + * Get if the HID is connected. + * + * @return true if the HID is connected + */ + bool IsConnected() const; +{% for axis in axes %} + /** + * Get the {{ axis.DocName }} value of the controller. + * + * @return the axis value. + */ + double Get{{ axis.MethodName }}() const; +{% endfor %} + /** + * Get the value of the axis. + * + * @param axis The axis to read + * @return the axis value. + */ + double GetAxis(int axis) const; + + /** + * Constructs an event instance that is true when the axis value is less than + * threshold. + * + * @param axis The axis to read. + * @param threshold The value below which this event should return true. + * @param loop the event loop instance to attach the event to. + * @return an event instance that is true when the axis value is less than the + * provided threshold. + */ + BooleanEvent AxisLessThan(int axis, double threshold, EventLoop* loop) const; + + /** + * Constructs an event instance that is true when the axis value is greater + * than threshold. + * + * @param axis The axis to read. + * @param threshold The value above which this event should return true. + * @param loop the event loop instance to attach the event to. + * @return an event instance that is true when the axis value is greater than + * the provided threshold. + */ + BooleanEvent AxisGreaterThan(int axis, double threshold, + EventLoop* loop) const; +{% for button in buttons %} + /** + * Read the value of the {{ button.DocName }} button on the controller. + * + * @return The state of the button. + */ + bool Get{{ button.MethodName }}Button() const; + + /** + * Whether the {{ button.DocName }} button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool Get{{ button.MethodName }}ButtonPressed(); + + /** + * Whether the {{ button.DocName }} button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool Get{{ button.MethodName }}ButtonReleased(); + + /** + * Constructs an event instance around the {{ button.DocName }} button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the {{ button.DocName }} button's + * digital signal attached to the given loop. + */ + BooleanEvent {{ button.MethodName }}(EventLoop* loop) const; +{% endfor %} + /** + * Get the button value. + * + * @param button The button to read + * @return The state of the button. + */ + bool GetButton(int button) const; + + /** + * Whether the button was pressed since the last check. + * + * @param button The button to read + * @return Whether the button was pressed since the last check. + */ + bool GetButtonPressed(int button); + + /** + * Whether the button was released since the last check. + * + * @param button The button to read + * @return Whether the button was released since the last check. + */ + bool GetButtonReleased(int button); + + /** + * Constructs an event instance around this button's digital signal. + * + * @param button the button + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the button's digital signal attached + * to the given loop. + */ + BooleanEvent ButtonEvent(int button, EventLoop* loop) const; + + /** + * Set leds on the controller. + * + * @param r Red value from 0-255 + * @param g Green value from 0-255 + * @param b Blue value from 0-255 + */ + void SetLeds(int r, int g, int b); + + /** + * Set the rumble output for the HID. + * + * @param type Which rumble value to set + * @param value The normalized value (0 to 1) to set the rumble to + */ + void SetRumble(GenericHID::RumbleType type, double value); + +{%- if touchpads == 1 %} + /** + * Check if a touchpad finger is available. + * @param finger The finger to check. + * @return true if the touchpad finger is available. + */ + bool GetTouchpadFingerAvailable(int finger) const; + + /** + * Get the touchpad finger data. + * @param finger The finger to read. + * @return The touchpad finger data. + */ + TouchpadFinger GetTouchpadFinger(int finger) const; +{%- elif touchpads > 1 %} + /** + * Check if a touchpad finger is available. + * @param touchpad The touchpad to check. + * @param finger The finger to check. + * @return true if the touchpad finger is available. + */ + bool GetTouchpadFingerAvailable(int touchpad, int finger) const; + + /** + * Get the touchpad finger data. + * @param touchpad The touchpad to read. + * @param finger The finger to read. + * @return The touchpad finger data. + */ + TouchpadFinger GetTouchpadFinger(int touchpad, int finger) const; +{%- endif %} + + /** Represents a digital button on a {{ ClassName }}Controller. */ + struct Button { +{%- for button in buttons %} + /// {{ button.DocName }} button. + static constexpr int {{ button.ConstantName }} = {{ button.value }}; +{%- endfor %} + }; + + /** Represents an axis on a {{ ClassName }}Controller. */ + struct Axis { +{%- for axis in axes %} + /// {{ axis.DocName }}. + static constexpr int {{ axis.ConstantName }} = {{ axis.value }}; +{%- endfor %} + }; + + void InitSendable(wpi::util::SendableBuilder& builder) override; + + private: + GenericHID* m_hid; +}; + +} // namespace wpi diff --git a/wpilibc/src/generate/main/native/include/wpi/simulation/first_ds_hidsim.hpp.jinja b/wpilibc/src/generate/main/native/include/wpi/simulation/first_ds_hidsim.hpp.jinja new file mode 100644 index 0000000000..167bf762ea --- /dev/null +++ b/wpilibc/src/generate/main/native/include/wpi/simulation/first_ds_hidsim.hpp.jinja @@ -0,0 +1,53 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#pragma once + +#include "wpi/simulation/GenericHIDSim.hpp" + +namespace wpi { + +class {{ ClassName }}Controller; + +namespace sim { + +/** + * Class to control a simulated {{ ClassName }} controller. + */ +class {{ ClassName }}ControllerSim : public GenericHIDSim { + public: + /** + * Constructs from a {{ ClassName }}Controller object. + * + * @param joystick controller to simulate + */ + explicit {{ ClassName }}ControllerSim(const {{ ClassName }}Controller& joystick); + + /** + * Constructs from a joystick port number. + * + * @param port port number + */ + explicit {{ ClassName }}ControllerSim(int port); +{% for axis in axes %} + /** + * Change the {{ axis.DocName }} value of the controller. + * + * @param value the new value + */ + void Set{{ axis.MethodName }}(double value); +{% endfor -%} +{% for button in buttons %} + /** + * Change the value of the {{ button.DocName }} button on the controller. + * + * @param value the new value + */ + void Set{{ button.MethodName }}Button(bool value); +{% endfor -%} +}; + +} // namespace sim +} // namespace wpi diff --git a/wpilibc/src/generate/test/native/cpp/first_ds_hid_test.cpp.jinja b/wpilibc/src/generate/test/native/cpp/first_ds_hid_test.cpp.jinja new file mode 100644 index 0000000000..7abf45e9dd --- /dev/null +++ b/wpilibc/src/generate/test/native/cpp/first_ds_hid_test.cpp.jinja @@ -0,0 +1,31 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#include "wpi/driverstation/{{ ClassName }}Controller.hpp" + +#include + +#include "JoystickTestMacros.hpp" +#include "wpi/simulation/{{ ClassName }}ControllerSim.hpp" + +using namespace wpi; + +TEST({{ ClassName }}ControllerTest, WrappedHID) { + {{ ClassName }}Controller controller{2}; + sim::{{ ClassName }}ControllerSim sim{controller}; + sim.NotifyNewData(); + + ASSERT_EQ(controller.GetPort(), 2); + ASSERT_EQ(controller.GetHID().GetPort(), 2); + ASSERT_EQ(controller.GetHID().GetAxesAvailable(), {{ AxesAvailableMask }}); + ASSERT_EQ(controller.GetHID().GetButtonsAvailable(), {{ ButtonsAvailableMask }}ULL); + ASSERT_EQ(controller.GetHID().GetPOVsAvailable(), 0); +} +{% for button in buttons %} +BUTTON_TEST({{ ClassName }}Controller, {{ button.MethodName }}Button) +{%- endfor %} +{% for axis in axes %} +AXIS_TEST({{ ClassName }}Controller, {{ axis.MethodName }}) +{%- endfor %} diff --git a/wpilibc/src/generated/main/native/cpp/driverstation/DualSenseController.cpp b/wpilibc/src/generated/main/native/cpp/driverstation/DualSenseController.cpp new file mode 100644 index 0000000000..f0d13f353c --- /dev/null +++ b/wpilibc/src/generated/main/native/cpp/driverstation/DualSenseController.cpp @@ -0,0 +1,411 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#include "wpi/driverstation/DualSenseController.hpp" + +#include "wpi/driverstation/DriverStation.hpp" +#include "wpi/event/BooleanEvent.hpp" +#include "wpi/hal/UsageReporting.hpp" +#include "wpi/util/sendable/SendableBuilder.hpp" + +using namespace wpi; + +DualSenseController::DualSenseController(int port) + : DualSenseController{DriverStation::GetGenericHID(port)} {} + +DualSenseController::DualSenseController(GenericHID& hid) + : m_hid{&hid} { + HAL_ReportUsage("HID", hid.GetPort(), "DualSenseController"); +} + +GenericHID& DualSenseController::GetHID() { + return *m_hid; +} + +const GenericHID& DualSenseController::GetHID() const { + return *m_hid; +} + +int DualSenseController::GetPort() const { + return m_hid->GetPort(); +} + +bool DualSenseController::IsConnected() const { + return m_hid->IsConnected(); +} + +double DualSenseController::GetLeftX() const { + return GetAxis(Axis::LEFT_X); +} + +double DualSenseController::GetLeftY() const { + return GetAxis(Axis::LEFT_Y); +} + +double DualSenseController::GetRightX() const { + return GetAxis(Axis::RIGHT_X); +} + +double DualSenseController::GetRightY() const { + return GetAxis(Axis::RIGHT_Y); +} + +double DualSenseController::GetL2() const { + return GetAxis(Axis::L2); +} + +double DualSenseController::GetR2() const { + return GetAxis(Axis::R2); +} + +double DualSenseController::GetAxis(int axis) const { + return m_hid->GetRawAxis(axis); +} + +BooleanEvent DualSenseController::AxisLessThan(int axis, double threshold, + EventLoop* loop) const { + return m_hid->AxisLessThan(axis, threshold, loop); +} + +BooleanEvent DualSenseController::AxisGreaterThan( + int axis, double threshold, EventLoop* loop) const { + return m_hid->AxisGreaterThan(axis, threshold, loop); +} + +bool DualSenseController::GetCrossButton() const { + return GetButton(Button::CROSS); +} + +bool DualSenseController::GetCrossButtonPressed() { + return GetButtonPressed(Button::CROSS); +} + +bool DualSenseController::GetCrossButtonReleased() { + return GetButtonReleased(Button::CROSS); +} + +BooleanEvent DualSenseController::Cross(EventLoop* loop) const { + return ButtonEvent(Button::CROSS, loop); +} + +bool DualSenseController::GetCircleButton() const { + return GetButton(Button::CIRCLE); +} + +bool DualSenseController::GetCircleButtonPressed() { + return GetButtonPressed(Button::CIRCLE); +} + +bool DualSenseController::GetCircleButtonReleased() { + return GetButtonReleased(Button::CIRCLE); +} + +BooleanEvent DualSenseController::Circle(EventLoop* loop) const { + return ButtonEvent(Button::CIRCLE, loop); +} + +bool DualSenseController::GetSquareButton() const { + return GetButton(Button::SQUARE); +} + +bool DualSenseController::GetSquareButtonPressed() { + return GetButtonPressed(Button::SQUARE); +} + +bool DualSenseController::GetSquareButtonReleased() { + return GetButtonReleased(Button::SQUARE); +} + +BooleanEvent DualSenseController::Square(EventLoop* loop) const { + return ButtonEvent(Button::SQUARE, loop); +} + +bool DualSenseController::GetTriangleButton() const { + return GetButton(Button::TRIANGLE); +} + +bool DualSenseController::GetTriangleButtonPressed() { + return GetButtonPressed(Button::TRIANGLE); +} + +bool DualSenseController::GetTriangleButtonReleased() { + return GetButtonReleased(Button::TRIANGLE); +} + +BooleanEvent DualSenseController::Triangle(EventLoop* loop) const { + return ButtonEvent(Button::TRIANGLE, loop); +} + +bool DualSenseController::GetCreateButton() const { + return GetButton(Button::CREATE); +} + +bool DualSenseController::GetCreateButtonPressed() { + return GetButtonPressed(Button::CREATE); +} + +bool DualSenseController::GetCreateButtonReleased() { + return GetButtonReleased(Button::CREATE); +} + +BooleanEvent DualSenseController::Create(EventLoop* loop) const { + return ButtonEvent(Button::CREATE, loop); +} + +bool DualSenseController::GetPSButton() const { + return GetButton(Button::PS); +} + +bool DualSenseController::GetPSButtonPressed() { + return GetButtonPressed(Button::PS); +} + +bool DualSenseController::GetPSButtonReleased() { + return GetButtonReleased(Button::PS); +} + +BooleanEvent DualSenseController::PS(EventLoop* loop) const { + return ButtonEvent(Button::PS, loop); +} + +bool DualSenseController::GetOptionsButton() const { + return GetButton(Button::OPTIONS); +} + +bool DualSenseController::GetOptionsButtonPressed() { + return GetButtonPressed(Button::OPTIONS); +} + +bool DualSenseController::GetOptionsButtonReleased() { + return GetButtonReleased(Button::OPTIONS); +} + +BooleanEvent DualSenseController::Options(EventLoop* loop) const { + return ButtonEvent(Button::OPTIONS, loop); +} + +bool DualSenseController::GetL3Button() const { + return GetButton(Button::L3); +} + +bool DualSenseController::GetL3ButtonPressed() { + return GetButtonPressed(Button::L3); +} + +bool DualSenseController::GetL3ButtonReleased() { + return GetButtonReleased(Button::L3); +} + +BooleanEvent DualSenseController::L3(EventLoop* loop) const { + return ButtonEvent(Button::L3, loop); +} + +bool DualSenseController::GetR3Button() const { + return GetButton(Button::R3); +} + +bool DualSenseController::GetR3ButtonPressed() { + return GetButtonPressed(Button::R3); +} + +bool DualSenseController::GetR3ButtonReleased() { + return GetButtonReleased(Button::R3); +} + +BooleanEvent DualSenseController::R3(EventLoop* loop) const { + return ButtonEvent(Button::R3, loop); +} + +bool DualSenseController::GetL1Button() const { + return GetButton(Button::L1); +} + +bool DualSenseController::GetL1ButtonPressed() { + return GetButtonPressed(Button::L1); +} + +bool DualSenseController::GetL1ButtonReleased() { + return GetButtonReleased(Button::L1); +} + +BooleanEvent DualSenseController::L1(EventLoop* loop) const { + return ButtonEvent(Button::L1, loop); +} + +bool DualSenseController::GetR1Button() const { + return GetButton(Button::R1); +} + +bool DualSenseController::GetR1ButtonPressed() { + return GetButtonPressed(Button::R1); +} + +bool DualSenseController::GetR1ButtonReleased() { + return GetButtonReleased(Button::R1); +} + +BooleanEvent DualSenseController::R1(EventLoop* loop) const { + return ButtonEvent(Button::R1, loop); +} + +bool DualSenseController::GetDpadUpButton() const { + return GetButton(Button::DPAD_UP); +} + +bool DualSenseController::GetDpadUpButtonPressed() { + return GetButtonPressed(Button::DPAD_UP); +} + +bool DualSenseController::GetDpadUpButtonReleased() { + return GetButtonReleased(Button::DPAD_UP); +} + +BooleanEvent DualSenseController::DpadUp(EventLoop* loop) const { + return ButtonEvent(Button::DPAD_UP, loop); +} + +bool DualSenseController::GetDpadDownButton() const { + return GetButton(Button::DPAD_DOWN); +} + +bool DualSenseController::GetDpadDownButtonPressed() { + return GetButtonPressed(Button::DPAD_DOWN); +} + +bool DualSenseController::GetDpadDownButtonReleased() { + return GetButtonReleased(Button::DPAD_DOWN); +} + +BooleanEvent DualSenseController::DpadDown(EventLoop* loop) const { + return ButtonEvent(Button::DPAD_DOWN, loop); +} + +bool DualSenseController::GetDpadLeftButton() const { + return GetButton(Button::DPAD_LEFT); +} + +bool DualSenseController::GetDpadLeftButtonPressed() { + return GetButtonPressed(Button::DPAD_LEFT); +} + +bool DualSenseController::GetDpadLeftButtonReleased() { + return GetButtonReleased(Button::DPAD_LEFT); +} + +BooleanEvent DualSenseController::DpadLeft(EventLoop* loop) const { + return ButtonEvent(Button::DPAD_LEFT, loop); +} + +bool DualSenseController::GetDpadRightButton() const { + return GetButton(Button::DPAD_RIGHT); +} + +bool DualSenseController::GetDpadRightButtonPressed() { + return GetButtonPressed(Button::DPAD_RIGHT); +} + +bool DualSenseController::GetDpadRightButtonReleased() { + return GetButtonReleased(Button::DPAD_RIGHT); +} + +BooleanEvent DualSenseController::DpadRight(EventLoop* loop) const { + return ButtonEvent(Button::DPAD_RIGHT, loop); +} + +bool DualSenseController::GetMicrophoneButton() const { + return GetButton(Button::MICROPHONE); +} + +bool DualSenseController::GetMicrophoneButtonPressed() { + return GetButtonPressed(Button::MICROPHONE); +} + +bool DualSenseController::GetMicrophoneButtonReleased() { + return GetButtonReleased(Button::MICROPHONE); +} + +BooleanEvent DualSenseController::Microphone(EventLoop* loop) const { + return ButtonEvent(Button::MICROPHONE, loop); +} + +bool DualSenseController::GetTouchpadButton() const { + return GetButton(Button::TOUCHPAD); +} + +bool DualSenseController::GetTouchpadButtonPressed() { + return GetButtonPressed(Button::TOUCHPAD); +} + +bool DualSenseController::GetTouchpadButtonReleased() { + return GetButtonReleased(Button::TOUCHPAD); +} + +BooleanEvent DualSenseController::Touchpad(EventLoop* loop) const { + return ButtonEvent(Button::TOUCHPAD, loop); +} + +bool DualSenseController::GetButton(int button) const { + return m_hid->GetRawButton(button); +} + +bool DualSenseController::GetButtonPressed(int button) { + return m_hid->GetRawButtonPressed(button); +} + +bool DualSenseController::GetButtonReleased(int button) { + return m_hid->GetRawButtonReleased(button); +} + +BooleanEvent DualSenseController::ButtonEvent(int button, + EventLoop* loop) const { + return m_hid->Button(button, loop); +} + +void DualSenseController::SetLeds(int r, int g, int b) { + m_hid->SetLeds(r, g, b); +} + +void DualSenseController::SetRumble(GenericHID::RumbleType type, + double value) { + m_hid->SetRumble(type, value); +} + + +bool DualSenseController::GetTouchpadFingerAvailable(int finger) const { + return m_hid->GetTouchpadFingerAvailable(0, finger); +} + +TouchpadFinger DualSenseController::GetTouchpadFinger(int finger) const { + return m_hid->GetTouchpadFinger(0, finger); +} + + +void DualSenseController::InitSendable(wpi::util::SendableBuilder& builder) { + builder.SetSmartDashboardType("HID"); + builder.PublishConstString("ControllerType", "DualSense"); + builder.AddDoubleProperty("LeftX", [this] { return GetLeftX(); }, nullptr); + builder.AddDoubleProperty("LeftY", [this] { return GetLeftY(); }, nullptr); + builder.AddDoubleProperty("RightX", [this] { return GetRightX(); }, nullptr); + builder.AddDoubleProperty("RightY", [this] { return GetRightY(); }, nullptr); + builder.AddDoubleProperty("L2", [this] { return GetL2(); }, nullptr); + builder.AddDoubleProperty("R2", [this] { return GetR2(); }, nullptr); + builder.AddBooleanProperty("Cross", [this] { return GetCrossButton(); }, nullptr); + builder.AddBooleanProperty("Circle", [this] { return GetCircleButton(); }, nullptr); + builder.AddBooleanProperty("Square", [this] { return GetSquareButton(); }, nullptr); + builder.AddBooleanProperty("Triangle", [this] { return GetTriangleButton(); }, nullptr); + builder.AddBooleanProperty("Create", [this] { return GetCreateButton(); }, nullptr); + builder.AddBooleanProperty("PS", [this] { return GetPSButton(); }, nullptr); + builder.AddBooleanProperty("Options", [this] { return GetOptionsButton(); }, nullptr); + builder.AddBooleanProperty("L3", [this] { return GetL3Button(); }, nullptr); + builder.AddBooleanProperty("R3", [this] { return GetR3Button(); }, nullptr); + builder.AddBooleanProperty("L1", [this] { return GetL1Button(); }, nullptr); + builder.AddBooleanProperty("R1", [this] { return GetR1Button(); }, nullptr); + builder.AddBooleanProperty("DpadUp", [this] { return GetDpadUpButton(); }, nullptr); + builder.AddBooleanProperty("DpadDown", [this] { return GetDpadDownButton(); }, nullptr); + builder.AddBooleanProperty("DpadLeft", [this] { return GetDpadLeftButton(); }, nullptr); + builder.AddBooleanProperty("DpadRight", [this] { return GetDpadRightButton(); }, nullptr); + builder.AddBooleanProperty("Microphone", [this] { return GetMicrophoneButton(); }, nullptr); + builder.AddBooleanProperty("Touchpad", [this] { return GetTouchpadButton(); }, nullptr); +} diff --git a/wpilibc/src/generated/main/native/cpp/driverstation/XboxController.cpp b/wpilibc/src/generated/main/native/cpp/driverstation/XboxController.cpp new file mode 100644 index 0000000000..45061e750d --- /dev/null +++ b/wpilibc/src/generated/main/native/cpp/driverstation/XboxController.cpp @@ -0,0 +1,369 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#include "wpi/driverstation/XboxController.hpp" + +#include "wpi/driverstation/DriverStation.hpp" +#include "wpi/event/BooleanEvent.hpp" +#include "wpi/hal/UsageReporting.hpp" +#include "wpi/util/sendable/SendableBuilder.hpp" + +using namespace wpi; + +XboxController::XboxController(int port) + : XboxController{DriverStation::GetGenericHID(port)} {} + +XboxController::XboxController(GenericHID& hid) + : m_hid{&hid} { + HAL_ReportUsage("HID", hid.GetPort(), "XboxController"); +} + +GenericHID& XboxController::GetHID() { + return *m_hid; +} + +const GenericHID& XboxController::GetHID() const { + return *m_hid; +} + +int XboxController::GetPort() const { + return m_hid->GetPort(); +} + +bool XboxController::IsConnected() const { + return m_hid->IsConnected(); +} + +double XboxController::GetLeftX() const { + return GetAxis(Axis::LEFT_X); +} + +double XboxController::GetLeftY() const { + return GetAxis(Axis::LEFT_Y); +} + +double XboxController::GetRightX() const { + return GetAxis(Axis::RIGHT_X); +} + +double XboxController::GetRightY() const { + return GetAxis(Axis::RIGHT_Y); +} + +double XboxController::GetLeftTrigger() const { + return GetAxis(Axis::LEFT_TRIGGER); +} + +double XboxController::GetRightTrigger() const { + return GetAxis(Axis::RIGHT_TRIGGER); +} + +double XboxController::GetAxis(int axis) const { + return m_hid->GetRawAxis(axis); +} + +BooleanEvent XboxController::AxisLessThan(int axis, double threshold, + EventLoop* loop) const { + return m_hid->AxisLessThan(axis, threshold, loop); +} + +BooleanEvent XboxController::AxisGreaterThan( + int axis, double threshold, EventLoop* loop) const { + return m_hid->AxisGreaterThan(axis, threshold, loop); +} + +bool XboxController::GetAButton() const { + return GetButton(Button::A); +} + +bool XboxController::GetAButtonPressed() { + return GetButtonPressed(Button::A); +} + +bool XboxController::GetAButtonReleased() { + return GetButtonReleased(Button::A); +} + +BooleanEvent XboxController::A(EventLoop* loop) const { + return ButtonEvent(Button::A, loop); +} + +bool XboxController::GetBButton() const { + return GetButton(Button::B); +} + +bool XboxController::GetBButtonPressed() { + return GetButtonPressed(Button::B); +} + +bool XboxController::GetBButtonReleased() { + return GetButtonReleased(Button::B); +} + +BooleanEvent XboxController::B(EventLoop* loop) const { + return ButtonEvent(Button::B, loop); +} + +bool XboxController::GetXButton() const { + return GetButton(Button::X); +} + +bool XboxController::GetXButtonPressed() { + return GetButtonPressed(Button::X); +} + +bool XboxController::GetXButtonReleased() { + return GetButtonReleased(Button::X); +} + +BooleanEvent XboxController::X(EventLoop* loop) const { + return ButtonEvent(Button::X, loop); +} + +bool XboxController::GetYButton() const { + return GetButton(Button::Y); +} + +bool XboxController::GetYButtonPressed() { + return GetButtonPressed(Button::Y); +} + +bool XboxController::GetYButtonReleased() { + return GetButtonReleased(Button::Y); +} + +BooleanEvent XboxController::Y(EventLoop* loop) const { + return ButtonEvent(Button::Y, loop); +} + +bool XboxController::GetViewButton() const { + return GetButton(Button::VIEW); +} + +bool XboxController::GetViewButtonPressed() { + return GetButtonPressed(Button::VIEW); +} + +bool XboxController::GetViewButtonReleased() { + return GetButtonReleased(Button::VIEW); +} + +BooleanEvent XboxController::View(EventLoop* loop) const { + return ButtonEvent(Button::VIEW, loop); +} + +bool XboxController::GetXboxButton() const { + return GetButton(Button::XBOX); +} + +bool XboxController::GetXboxButtonPressed() { + return GetButtonPressed(Button::XBOX); +} + +bool XboxController::GetXboxButtonReleased() { + return GetButtonReleased(Button::XBOX); +} + +BooleanEvent XboxController::Xbox(EventLoop* loop) const { + return ButtonEvent(Button::XBOX, loop); +} + +bool XboxController::GetMenuButton() const { + return GetButton(Button::MENU); +} + +bool XboxController::GetMenuButtonPressed() { + return GetButtonPressed(Button::MENU); +} + +bool XboxController::GetMenuButtonReleased() { + return GetButtonReleased(Button::MENU); +} + +BooleanEvent XboxController::Menu(EventLoop* loop) const { + return ButtonEvent(Button::MENU, loop); +} + +bool XboxController::GetLeftStickButton() const { + return GetButton(Button::LEFT_STICK); +} + +bool XboxController::GetLeftStickButtonPressed() { + return GetButtonPressed(Button::LEFT_STICK); +} + +bool XboxController::GetLeftStickButtonReleased() { + return GetButtonReleased(Button::LEFT_STICK); +} + +BooleanEvent XboxController::LeftStick(EventLoop* loop) const { + return ButtonEvent(Button::LEFT_STICK, loop); +} + +bool XboxController::GetRightStickButton() const { + return GetButton(Button::RIGHT_STICK); +} + +bool XboxController::GetRightStickButtonPressed() { + return GetButtonPressed(Button::RIGHT_STICK); +} + +bool XboxController::GetRightStickButtonReleased() { + return GetButtonReleased(Button::RIGHT_STICK); +} + +BooleanEvent XboxController::RightStick(EventLoop* loop) const { + return ButtonEvent(Button::RIGHT_STICK, loop); +} + +bool XboxController::GetLeftBumperButton() const { + return GetButton(Button::LEFT_BUMPER); +} + +bool XboxController::GetLeftBumperButtonPressed() { + return GetButtonPressed(Button::LEFT_BUMPER); +} + +bool XboxController::GetLeftBumperButtonReleased() { + return GetButtonReleased(Button::LEFT_BUMPER); +} + +BooleanEvent XboxController::LeftBumper(EventLoop* loop) const { + return ButtonEvent(Button::LEFT_BUMPER, loop); +} + +bool XboxController::GetRightBumperButton() const { + return GetButton(Button::RIGHT_BUMPER); +} + +bool XboxController::GetRightBumperButtonPressed() { + return GetButtonPressed(Button::RIGHT_BUMPER); +} + +bool XboxController::GetRightBumperButtonReleased() { + return GetButtonReleased(Button::RIGHT_BUMPER); +} + +BooleanEvent XboxController::RightBumper(EventLoop* loop) const { + return ButtonEvent(Button::RIGHT_BUMPER, loop); +} + +bool XboxController::GetDpadUpButton() const { + return GetButton(Button::DPAD_UP); +} + +bool XboxController::GetDpadUpButtonPressed() { + return GetButtonPressed(Button::DPAD_UP); +} + +bool XboxController::GetDpadUpButtonReleased() { + return GetButtonReleased(Button::DPAD_UP); +} + +BooleanEvent XboxController::DpadUp(EventLoop* loop) const { + return ButtonEvent(Button::DPAD_UP, loop); +} + +bool XboxController::GetDpadDownButton() const { + return GetButton(Button::DPAD_DOWN); +} + +bool XboxController::GetDpadDownButtonPressed() { + return GetButtonPressed(Button::DPAD_DOWN); +} + +bool XboxController::GetDpadDownButtonReleased() { + return GetButtonReleased(Button::DPAD_DOWN); +} + +BooleanEvent XboxController::DpadDown(EventLoop* loop) const { + return ButtonEvent(Button::DPAD_DOWN, loop); +} + +bool XboxController::GetDpadLeftButton() const { + return GetButton(Button::DPAD_LEFT); +} + +bool XboxController::GetDpadLeftButtonPressed() { + return GetButtonPressed(Button::DPAD_LEFT); +} + +bool XboxController::GetDpadLeftButtonReleased() { + return GetButtonReleased(Button::DPAD_LEFT); +} + +BooleanEvent XboxController::DpadLeft(EventLoop* loop) const { + return ButtonEvent(Button::DPAD_LEFT, loop); +} + +bool XboxController::GetDpadRightButton() const { + return GetButton(Button::DPAD_RIGHT); +} + +bool XboxController::GetDpadRightButtonPressed() { + return GetButtonPressed(Button::DPAD_RIGHT); +} + +bool XboxController::GetDpadRightButtonReleased() { + return GetButtonReleased(Button::DPAD_RIGHT); +} + +BooleanEvent XboxController::DpadRight(EventLoop* loop) const { + return ButtonEvent(Button::DPAD_RIGHT, loop); +} + +bool XboxController::GetButton(int button) const { + return m_hid->GetRawButton(button); +} + +bool XboxController::GetButtonPressed(int button) { + return m_hid->GetRawButtonPressed(button); +} + +bool XboxController::GetButtonReleased(int button) { + return m_hid->GetRawButtonReleased(button); +} + +BooleanEvent XboxController::ButtonEvent(int button, + EventLoop* loop) const { + return m_hid->Button(button, loop); +} + +void XboxController::SetLeds(int r, int g, int b) { + m_hid->SetLeds(r, g, b); +} + +void XboxController::SetRumble(GenericHID::RumbleType type, + double value) { + m_hid->SetRumble(type, value); +} + + + +void XboxController::InitSendable(wpi::util::SendableBuilder& builder) { + builder.SetSmartDashboardType("HID"); + builder.PublishConstString("ControllerType", "Xbox"); + builder.AddDoubleProperty("LeftX", [this] { return GetLeftX(); }, nullptr); + builder.AddDoubleProperty("LeftY", [this] { return GetLeftY(); }, nullptr); + builder.AddDoubleProperty("RightX", [this] { return GetRightX(); }, nullptr); + builder.AddDoubleProperty("RightY", [this] { return GetRightY(); }, nullptr); + builder.AddDoubleProperty("LeftTrigger", [this] { return GetLeftTrigger(); }, nullptr); + builder.AddDoubleProperty("RightTrigger", [this] { return GetRightTrigger(); }, nullptr); + builder.AddBooleanProperty("A", [this] { return GetAButton(); }, nullptr); + builder.AddBooleanProperty("B", [this] { return GetBButton(); }, nullptr); + builder.AddBooleanProperty("X", [this] { return GetXButton(); }, nullptr); + builder.AddBooleanProperty("Y", [this] { return GetYButton(); }, nullptr); + builder.AddBooleanProperty("View", [this] { return GetViewButton(); }, nullptr); + builder.AddBooleanProperty("Xbox", [this] { return GetXboxButton(); }, nullptr); + builder.AddBooleanProperty("Menu", [this] { return GetMenuButton(); }, nullptr); + builder.AddBooleanProperty("LeftStick", [this] { return GetLeftStickButton(); }, nullptr); + builder.AddBooleanProperty("RightStick", [this] { return GetRightStickButton(); }, nullptr); + builder.AddBooleanProperty("LeftBumper", [this] { return GetLeftBumperButton(); }, nullptr); + builder.AddBooleanProperty("RightBumper", [this] { return GetRightBumperButton(); }, nullptr); + builder.AddBooleanProperty("DpadUp", [this] { return GetDpadUpButton(); }, nullptr); + builder.AddBooleanProperty("DpadDown", [this] { return GetDpadDownButton(); }, nullptr); + builder.AddBooleanProperty("DpadLeft", [this] { return GetDpadLeftButton(); }, nullptr); + builder.AddBooleanProperty("DpadRight", [this] { return GetDpadRightButton(); }, nullptr); +} diff --git a/wpilibc/src/generated/main/native/cpp/simulation/DualSenseControllerSim.cpp b/wpilibc/src/generated/main/native/cpp/simulation/DualSenseControllerSim.cpp new file mode 100644 index 0000000000..32890b28e9 --- /dev/null +++ b/wpilibc/src/generated/main/native/cpp/simulation/DualSenseControllerSim.cpp @@ -0,0 +1,120 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#include "wpi/simulation/DualSenseControllerSim.hpp" + +#include "wpi/driverstation/DualSenseController.hpp" + +using namespace wpi; +using namespace wpi::sim; + +DualSenseControllerSim::DualSenseControllerSim(const DualSenseController& joystick) + : GenericHIDSim{joystick.GetHID()} { + SetAxesAvailable(0x3F); + SetButtonsAvailable(0x10FFFFULL); + SetPOVsAvailable(0); + SetGamepadType(GenericHID::HIDType::PS5); + SetSupportedOutputs(DualSenseController::SUPPORTED_OUTPUTS); +} + +DualSenseControllerSim::DualSenseControllerSim(int port) : GenericHIDSim{port} { + SetAxesAvailable(0x3F); + SetButtonsAvailable(0x10FFFFULL); + SetPOVsAvailable(0); + SetGamepadType(GenericHID::HIDType::PS5); + SetSupportedOutputs(DualSenseController::SUPPORTED_OUTPUTS); +} + +void DualSenseControllerSim::SetLeftX(double value) { + SetRawAxis(DualSenseController::Axis::LEFT_X, value); +} + +void DualSenseControllerSim::SetLeftY(double value) { + SetRawAxis(DualSenseController::Axis::LEFT_Y, value); +} + +void DualSenseControllerSim::SetRightX(double value) { + SetRawAxis(DualSenseController::Axis::RIGHT_X, value); +} + +void DualSenseControllerSim::SetRightY(double value) { + SetRawAxis(DualSenseController::Axis::RIGHT_Y, value); +} + +void DualSenseControllerSim::SetL2(double value) { + SetRawAxis(DualSenseController::Axis::L2, value); +} + +void DualSenseControllerSim::SetR2(double value) { + SetRawAxis(DualSenseController::Axis::R2, value); +} + +void DualSenseControllerSim::SetCrossButton(bool value) { + SetRawButton(DualSenseController::Button::CROSS, value); +} + +void DualSenseControllerSim::SetCircleButton(bool value) { + SetRawButton(DualSenseController::Button::CIRCLE, value); +} + +void DualSenseControllerSim::SetSquareButton(bool value) { + SetRawButton(DualSenseController::Button::SQUARE, value); +} + +void DualSenseControllerSim::SetTriangleButton(bool value) { + SetRawButton(DualSenseController::Button::TRIANGLE, value); +} + +void DualSenseControllerSim::SetCreateButton(bool value) { + SetRawButton(DualSenseController::Button::CREATE, value); +} + +void DualSenseControllerSim::SetPSButton(bool value) { + SetRawButton(DualSenseController::Button::PS, value); +} + +void DualSenseControllerSim::SetOptionsButton(bool value) { + SetRawButton(DualSenseController::Button::OPTIONS, value); +} + +void DualSenseControllerSim::SetL3Button(bool value) { + SetRawButton(DualSenseController::Button::L3, value); +} + +void DualSenseControllerSim::SetR3Button(bool value) { + SetRawButton(DualSenseController::Button::R3, value); +} + +void DualSenseControllerSim::SetL1Button(bool value) { + SetRawButton(DualSenseController::Button::L1, value); +} + +void DualSenseControllerSim::SetR1Button(bool value) { + SetRawButton(DualSenseController::Button::R1, value); +} + +void DualSenseControllerSim::SetDpadUpButton(bool value) { + SetRawButton(DualSenseController::Button::DPAD_UP, value); +} + +void DualSenseControllerSim::SetDpadDownButton(bool value) { + SetRawButton(DualSenseController::Button::DPAD_DOWN, value); +} + +void DualSenseControllerSim::SetDpadLeftButton(bool value) { + SetRawButton(DualSenseController::Button::DPAD_LEFT, value); +} + +void DualSenseControllerSim::SetDpadRightButton(bool value) { + SetRawButton(DualSenseController::Button::DPAD_RIGHT, value); +} + +void DualSenseControllerSim::SetMicrophoneButton(bool value) { + SetRawButton(DualSenseController::Button::MICROPHONE, value); +} + +void DualSenseControllerSim::SetTouchpadButton(bool value) { + SetRawButton(DualSenseController::Button::TOUCHPAD, value); +} diff --git a/wpilibc/src/generated/main/native/cpp/simulation/XboxControllerSim.cpp b/wpilibc/src/generated/main/native/cpp/simulation/XboxControllerSim.cpp new file mode 100644 index 0000000000..18d0b08ee6 --- /dev/null +++ b/wpilibc/src/generated/main/native/cpp/simulation/XboxControllerSim.cpp @@ -0,0 +1,112 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#include "wpi/simulation/XboxControllerSim.hpp" + +#include "wpi/driverstation/XboxController.hpp" + +using namespace wpi; +using namespace wpi::sim; + +XboxControllerSim::XboxControllerSim(const XboxController& joystick) + : GenericHIDSim{joystick.GetHID()} { + SetAxesAvailable(0x3F); + SetButtonsAvailable(0x7FFFULL); + SetPOVsAvailable(0); + SetGamepadType(GenericHID::HIDType::XBOX_ONE); + SetSupportedOutputs(XboxController::SUPPORTED_OUTPUTS); +} + +XboxControllerSim::XboxControllerSim(int port) : GenericHIDSim{port} { + SetAxesAvailable(0x3F); + SetButtonsAvailable(0x7FFFULL); + SetPOVsAvailable(0); + SetGamepadType(GenericHID::HIDType::XBOX_ONE); + SetSupportedOutputs(XboxController::SUPPORTED_OUTPUTS); +} + +void XboxControllerSim::SetLeftX(double value) { + SetRawAxis(XboxController::Axis::LEFT_X, value); +} + +void XboxControllerSim::SetLeftY(double value) { + SetRawAxis(XboxController::Axis::LEFT_Y, value); +} + +void XboxControllerSim::SetRightX(double value) { + SetRawAxis(XboxController::Axis::RIGHT_X, value); +} + +void XboxControllerSim::SetRightY(double value) { + SetRawAxis(XboxController::Axis::RIGHT_Y, value); +} + +void XboxControllerSim::SetLeftTrigger(double value) { + SetRawAxis(XboxController::Axis::LEFT_TRIGGER, value); +} + +void XboxControllerSim::SetRightTrigger(double value) { + SetRawAxis(XboxController::Axis::RIGHT_TRIGGER, value); +} + +void XboxControllerSim::SetAButton(bool value) { + SetRawButton(XboxController::Button::A, value); +} + +void XboxControllerSim::SetBButton(bool value) { + SetRawButton(XboxController::Button::B, value); +} + +void XboxControllerSim::SetXButton(bool value) { + SetRawButton(XboxController::Button::X, value); +} + +void XboxControllerSim::SetYButton(bool value) { + SetRawButton(XboxController::Button::Y, value); +} + +void XboxControllerSim::SetViewButton(bool value) { + SetRawButton(XboxController::Button::VIEW, value); +} + +void XboxControllerSim::SetXboxButton(bool value) { + SetRawButton(XboxController::Button::XBOX, value); +} + +void XboxControllerSim::SetMenuButton(bool value) { + SetRawButton(XboxController::Button::MENU, value); +} + +void XboxControllerSim::SetLeftStickButton(bool value) { + SetRawButton(XboxController::Button::LEFT_STICK, value); +} + +void XboxControllerSim::SetRightStickButton(bool value) { + SetRawButton(XboxController::Button::RIGHT_STICK, value); +} + +void XboxControllerSim::SetLeftBumperButton(bool value) { + SetRawButton(XboxController::Button::LEFT_BUMPER, value); +} + +void XboxControllerSim::SetRightBumperButton(bool value) { + SetRawButton(XboxController::Button::RIGHT_BUMPER, value); +} + +void XboxControllerSim::SetDpadUpButton(bool value) { + SetRawButton(XboxController::Button::DPAD_UP, value); +} + +void XboxControllerSim::SetDpadDownButton(bool value) { + SetRawButton(XboxController::Button::DPAD_DOWN, value); +} + +void XboxControllerSim::SetDpadLeftButton(bool value) { + SetRawButton(XboxController::Button::DPAD_LEFT, value); +} + +void XboxControllerSim::SetDpadRightButton(bool value) { + SetRawButton(XboxController::Button::DPAD_RIGHT, value); +} diff --git a/wpilibc/src/generated/main/native/include/wpi/driverstation/DualSenseController.hpp b/wpilibc/src/generated/main/native/include/wpi/driverstation/DualSenseController.hpp new file mode 100644 index 0000000000..c1368626c5 --- /dev/null +++ b/wpilibc/src/generated/main/native/include/wpi/driverstation/DualSenseController.hpp @@ -0,0 +1,825 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#pragma once + +#include "wpi/driverstation/GenericHID.hpp" +#include "wpi/driverstation/HIDDevice.hpp" +#include "wpi/driverstation/TouchpadFinger.hpp" +#include "wpi/util/sendable/Sendable.hpp" +#include "wpi/util/sendable/SendableHelper.hpp" + +namespace wpi { + +class BooleanEvent; +class EventLoop; + +/** + * Handle input from DualSense controllers connected to the Driver Station. + * + * This class handles DualSense input that comes from the Driver Station. + * Each time a value is requested the most recent value is returned. + */ +class DualSenseController + : public HIDDevice, + public wpi::util::Sendable, + public wpi::util::SendableHelper { + public: + /** The number of touchpads supported by this controller. */ + static constexpr int TOUCHPAD_COUNT = 1; + + /** Whether this controller supports main rumble motors. */ + static constexpr bool SUPPORTS_RUMBLE = true; + + /** Whether this controller supports trigger rumble motors. */ + static constexpr bool SUPPORTS_TRIGGER_RUMBLE = true; + + /** Whether this controller supports mono LED output. */ + static constexpr bool SUPPORTS_MONO_LED = false; + + /** Whether this controller supports RGB LED output. */ + static constexpr bool SUPPORTS_RGB_LED = true; + + /** Supported outputs expected for this controller type. */ + static constexpr GenericHID::SupportedOutputs SUPPORTED_OUTPUTS = + static_cast(26); + + /** + * Construct an instance of a 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. + */ + explicit DualSenseController(int port); + + /** + * Construct an instance of a controller with a GenericHID object. + * + * @param hid The GenericHID object to use for this controller. + */ + explicit DualSenseController(GenericHID& hid); + + ~DualSenseController() override = default; + + DualSenseController(DualSenseController&&) = default; + DualSenseController& operator=(DualSenseController&&) = default; + + /** + * Get the underlying GenericHID object. + * + * @return the wrapped GenericHID object + */ + GenericHID& GetHID() override; + + /** + * Get the underlying GenericHID object. + * + * @return the wrapped GenericHID object + */ + const GenericHID& GetHID() const override; + + /** + * Get the port number of the HID. + * + * @return The port number of the HID. + */ + int GetPort() const; + + /** + * Get if the HID is connected. + * + * @return true if the HID is connected + */ + bool IsConnected() const; + + /** + * Get the Left X value of the controller. + * + * @return the axis value. + */ + double GetLeftX() const; + + /** + * Get the Left Y value of the controller. + * + * @return the axis value. + */ + double GetLeftY() const; + + /** + * Get the Right X value of the controller. + * + * @return the axis value. + */ + double GetRightX() const; + + /** + * Get the Right Y value of the controller. + * + * @return the axis value. + */ + double GetRightY() const; + + /** + * Get the L 2 value of the controller. + * + * @return the axis value. + */ + double GetL2() const; + + /** + * Get the R 2 value of the controller. + * + * @return the axis value. + */ + double GetR2() const; + + /** + * Get the value of the axis. + * + * @param axis The axis to read + * @return the axis value. + */ + double GetAxis(int axis) const; + + /** + * Constructs an event instance that is true when the axis value is less than + * threshold. + * + * @param axis The axis to read. + * @param threshold The value below which this event should return true. + * @param loop the event loop instance to attach the event to. + * @return an event instance that is true when the axis value is less than the + * provided threshold. + */ + BooleanEvent AxisLessThan(int axis, double threshold, EventLoop* loop) const; + + /** + * Constructs an event instance that is true when the axis value is greater + * than threshold. + * + * @param axis The axis to read. + * @param threshold The value above which this event should return true. + * @param loop the event loop instance to attach the event to. + * @return an event instance that is true when the axis value is greater than + * the provided threshold. + */ + BooleanEvent AxisGreaterThan(int axis, double threshold, + 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 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 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 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 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 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 L 3 button on the controller. + * + * @return The state of the button. + */ + bool GetL3Button() const; + + /** + * Whether the L 3 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetL3ButtonPressed(); + + /** + * Whether the L 3 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 L 3 button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the L 3 button's + * digital signal attached to the given loop. + */ + BooleanEvent L3(EventLoop* loop) const; + + /** + * Read the value of the R 3 button on the controller. + * + * @return The state of the button. + */ + bool GetR3Button() const; + + /** + * Whether the R 3 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetR3ButtonPressed(); + + /** + * Whether the R 3 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 R 3 button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the R 3 button's + * digital signal attached to the given loop. + */ + BooleanEvent R3(EventLoop* loop) const; + + /** + * Read the value of the L 1 button on the controller. + * + * @return The state of the button. + */ + bool GetL1Button() const; + + /** + * Whether the L 1 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetL1ButtonPressed(); + + /** + * Whether the L 1 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 L 1 button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the L 1 button's + * digital signal attached to the given loop. + */ + BooleanEvent L1(EventLoop* loop) const; + + /** + * Read the value of the R 1 button on the controller. + * + * @return The state of the button. + */ + bool GetR1Button() const; + + /** + * Whether the R 1 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetR1ButtonPressed(); + + /** + * Whether the R 1 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 R 1 button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the R 1 button's + * digital signal attached to the given loop. + */ + BooleanEvent R1(EventLoop* loop) const; + + /** + * Read the value of the Dpad Up button on the controller. + * + * @return The state of the button. + */ + bool GetDpadUpButton() const; + + /** + * Whether the Dpad Up button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetDpadUpButtonPressed(); + + /** + * Whether the Dpad Up button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetDpadUpButtonReleased(); + + /** + * Constructs an event instance around the Dpad Up button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Up button's + * digital signal attached to the given loop. + */ + BooleanEvent DpadUp(EventLoop* loop) const; + + /** + * Read the value of the Dpad Down button on the controller. + * + * @return The state of the button. + */ + bool GetDpadDownButton() const; + + /** + * Whether the Dpad Down button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetDpadDownButtonPressed(); + + /** + * Whether the Dpad Down button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetDpadDownButtonReleased(); + + /** + * Constructs an event instance around the Dpad Down button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Down button's + * digital signal attached to the given loop. + */ + BooleanEvent DpadDown(EventLoop* loop) const; + + /** + * Read the value of the Dpad Left button on the controller. + * + * @return The state of the button. + */ + bool GetDpadLeftButton() const; + + /** + * Whether the Dpad Left button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetDpadLeftButtonPressed(); + + /** + * Whether the Dpad Left button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetDpadLeftButtonReleased(); + + /** + * Constructs an event instance around the Dpad Left button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Left button's + * digital signal attached to the given loop. + */ + BooleanEvent DpadLeft(EventLoop* loop) const; + + /** + * Read the value of the Dpad Right button on the controller. + * + * @return The state of the button. + */ + bool GetDpadRightButton() const; + + /** + * Whether the Dpad Right button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetDpadRightButtonPressed(); + + /** + * Whether the Dpad Right button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetDpadRightButtonReleased(); + + /** + * Constructs an event instance around the Dpad Right button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Right button's + * digital signal attached to the given loop. + */ + BooleanEvent DpadRight(EventLoop* loop) const; + + /** + * Read the value of the Microphone button on the controller. + * + * @return The state of the button. + */ + bool GetMicrophoneButton() const; + + /** + * Whether the Microphone button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetMicrophoneButtonPressed(); + + /** + * Whether the Microphone button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetMicrophoneButtonReleased(); + + /** + * Constructs an event instance around the Microphone button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Microphone button's + * digital signal attached to the given loop. + */ + BooleanEvent Microphone(EventLoop* loop) const; + + /** + * Read the value of the Touchpad button on the controller. + * + * @return The state of the button. + */ + bool GetTouchpadButton() const; + + /** + * Whether the Touchpad button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetTouchpadButtonPressed(); + + /** + * Whether the Touchpad button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetTouchpadButtonReleased(); + + /** + * Constructs an event instance around the Touchpad button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Touchpad button's + * digital signal attached to the given loop. + */ + BooleanEvent Touchpad(EventLoop* loop) const; + + /** + * Get the button value. + * + * @param button The button to read + * @return The state of the button. + */ + bool GetButton(int button) const; + + /** + * Whether the button was pressed since the last check. + * + * @param button The button to read + * @return Whether the button was pressed since the last check. + */ + bool GetButtonPressed(int button); + + /** + * Whether the button was released since the last check. + * + * @param button The button to read + * @return Whether the button was released since the last check. + */ + bool GetButtonReleased(int button); + + /** + * Constructs an event instance around this button's digital signal. + * + * @param button the button + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the button's digital signal attached + * to the given loop. + */ + BooleanEvent ButtonEvent(int button, EventLoop* loop) const; + + /** + * Set leds on the controller. + * + * @param r Red value from 0-255 + * @param g Green value from 0-255 + * @param b Blue value from 0-255 + */ + void SetLeds(int r, int g, int b); + + /** + * Set the rumble output for the HID. + * + * @param type Which rumble value to set + * @param value The normalized value (0 to 1) to set the rumble to + */ + void SetRumble(GenericHID::RumbleType type, double value); + /** + * Check if a touchpad finger is available. + * @param finger The finger to check. + * @return true if the touchpad finger is available. + */ + bool GetTouchpadFingerAvailable(int finger) const; + + /** + * Get the touchpad finger data. + * @param finger The finger to read. + * @return The touchpad finger data. + */ + TouchpadFinger GetTouchpadFinger(int finger) const; + + /** Represents a digital button on a DualSenseController. */ + struct Button { + /// Cross button. + static constexpr int CROSS = 0; + /// Circle button. + static constexpr int CIRCLE = 1; + /// Square button. + static constexpr int SQUARE = 2; + /// Triangle button. + static constexpr int TRIANGLE = 3; + /// Create button. + static constexpr int CREATE = 4; + /// PS button. + static constexpr int PS = 5; + /// Options button. + static constexpr int OPTIONS = 6; + /// L 3 button. + static constexpr int L3 = 7; + /// R 3 button. + static constexpr int R3 = 8; + /// L 1 button. + static constexpr int L1 = 9; + /// R 1 button. + static constexpr int R1 = 10; + /// Dpad Up button. + static constexpr int DPAD_UP = 11; + /// Dpad Down button. + static constexpr int DPAD_DOWN = 12; + /// Dpad Left button. + static constexpr int DPAD_LEFT = 13; + /// Dpad Right button. + static constexpr int DPAD_RIGHT = 14; + /// Microphone button. + static constexpr int MICROPHONE = 15; + /// Touchpad button. + static constexpr int TOUCHPAD = 20; + }; + + /** Represents an axis on a DualSenseController. */ + struct Axis { + /// Left X. + static constexpr int LEFT_X = 0; + /// Left Y. + static constexpr int LEFT_Y = 1; + /// Right X. + static constexpr int RIGHT_X = 2; + /// Right Y. + static constexpr int RIGHT_Y = 3; + /// L 2. + static constexpr int L2 = 4; + /// R 2. + static constexpr int R2 = 5; + }; + + void InitSendable(wpi::util::SendableBuilder& builder) override; + + private: + GenericHID* m_hid; +}; + +} // namespace wpi diff --git a/wpilibc/src/generated/main/native/include/wpi/driverstation/XboxController.hpp b/wpilibc/src/generated/main/native/include/wpi/driverstation/XboxController.hpp new file mode 100644 index 0000000000..14849dfc7f --- /dev/null +++ b/wpilibc/src/generated/main/native/include/wpi/driverstation/XboxController.hpp @@ -0,0 +1,746 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#pragma once + +#include "wpi/driverstation/GenericHID.hpp" +#include "wpi/driverstation/HIDDevice.hpp" +#include "wpi/driverstation/TouchpadFinger.hpp" +#include "wpi/util/sendable/Sendable.hpp" +#include "wpi/util/sendable/SendableHelper.hpp" + +namespace wpi { + +class BooleanEvent; +class EventLoop; + +/** + * Handle input from Xbox controllers connected to the Driver Station. + * + * This class handles Xbox input that comes from the Driver Station. + * Each time a value is requested the most recent value is returned. + */ +class XboxController + : public HIDDevice, + public wpi::util::Sendable, + public wpi::util::SendableHelper { + public: + /** The number of touchpads supported by this controller. */ + static constexpr int TOUCHPAD_COUNT = 0; + + /** Whether this controller supports main rumble motors. */ + static constexpr bool SUPPORTS_RUMBLE = true; + + /** Whether this controller supports trigger rumble motors. */ + static constexpr bool SUPPORTS_TRIGGER_RUMBLE = true; + + /** Whether this controller supports mono LED output. */ + static constexpr bool SUPPORTS_MONO_LED = false; + + /** Whether this controller supports RGB LED output. */ + static constexpr bool SUPPORTS_RGB_LED = false; + + /** Supported outputs expected for this controller type. */ + static constexpr GenericHID::SupportedOutputs SUPPORTED_OUTPUTS = + static_cast(24); + + /** + * Construct an instance of a 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. + */ + explicit XboxController(int port); + + /** + * Construct an instance of a controller with a GenericHID object. + * + * @param hid The GenericHID object to use for this controller. + */ + explicit XboxController(GenericHID& hid); + + ~XboxController() override = default; + + XboxController(XboxController&&) = default; + XboxController& operator=(XboxController&&) = default; + + /** + * Get the underlying GenericHID object. + * + * @return the wrapped GenericHID object + */ + GenericHID& GetHID() override; + + /** + * Get the underlying GenericHID object. + * + * @return the wrapped GenericHID object + */ + const GenericHID& GetHID() const override; + + /** + * Get the port number of the HID. + * + * @return The port number of the HID. + */ + int GetPort() const; + + /** + * Get if the HID is connected. + * + * @return true if the HID is connected + */ + bool IsConnected() const; + + /** + * Get the Left X value of the controller. + * + * @return the axis value. + */ + double GetLeftX() const; + + /** + * Get the Left Y value of the controller. + * + * @return the axis value. + */ + double GetLeftY() const; + + /** + * Get the Right X value of the controller. + * + * @return the axis value. + */ + double GetRightX() const; + + /** + * Get the Right Y value of the controller. + * + * @return the axis value. + */ + double GetRightY() const; + + /** + * Get the Left Trigger value of the controller. + * + * @return the axis value. + */ + double GetLeftTrigger() const; + + /** + * Get the Right Trigger value of the controller. + * + * @return the axis value. + */ + double GetRightTrigger() const; + + /** + * Get the value of the axis. + * + * @param axis The axis to read + * @return the axis value. + */ + double GetAxis(int axis) const; + + /** + * Constructs an event instance that is true when the axis value is less than + * threshold. + * + * @param axis The axis to read. + * @param threshold The value below which this event should return true. + * @param loop the event loop instance to attach the event to. + * @return an event instance that is true when the axis value is less than the + * provided threshold. + */ + BooleanEvent AxisLessThan(int axis, double threshold, EventLoop* loop) const; + + /** + * Constructs an event instance that is true when the axis value is greater + * than threshold. + * + * @param axis The axis to read. + * @param threshold The value above which this event should return true. + * @param loop the event loop instance to attach the event to. + * @return an event instance that is true when the axis value is greater than + * the provided threshold. + */ + BooleanEvent AxisGreaterThan(int axis, double threshold, + EventLoop* loop) const; + + /** + * Read the value of the A button on the controller. + * + * @return The state of the button. + */ + bool GetAButton() const; + + /** + * Whether the A button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetAButtonPressed(); + + /** + * Whether the A button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetAButtonReleased(); + + /** + * Constructs an event instance around the A button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the A button's + * digital signal attached to the given loop. + */ + BooleanEvent A(EventLoop* loop) const; + + /** + * Read the value of the B button on the controller. + * + * @return The state of the button. + */ + bool GetBButton() const; + + /** + * Whether the B button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetBButtonPressed(); + + /** + * Whether the B button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetBButtonReleased(); + + /** + * Constructs an event instance around the B button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the B button's + * digital signal attached to the given loop. + */ + BooleanEvent B(EventLoop* loop) const; + + /** + * Read the value of the X button on the controller. + * + * @return The state of the button. + */ + bool GetXButton() const; + + /** + * Whether the X button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetXButtonPressed(); + + /** + * Whether the X button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetXButtonReleased(); + + /** + * Constructs an event instance around the X button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the X button's + * digital signal attached to the given loop. + */ + BooleanEvent X(EventLoop* loop) const; + + /** + * Read the value of the Y button on the controller. + * + * @return The state of the button. + */ + bool GetYButton() const; + + /** + * Whether the Y button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetYButtonPressed(); + + /** + * Whether the Y button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetYButtonReleased(); + + /** + * Constructs an event instance around the Y button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Y button's + * digital signal attached to the given loop. + */ + BooleanEvent Y(EventLoop* loop) const; + + /** + * Read the value of the View button on the controller. + * + * @return The state of the button. + */ + bool GetViewButton() const; + + /** + * Whether the View button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetViewButtonPressed(); + + /** + * Whether the View button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetViewButtonReleased(); + + /** + * Constructs an event instance around the View button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the View button's + * digital signal attached to the given loop. + */ + BooleanEvent View(EventLoop* loop) const; + + /** + * Read the value of the Xbox button on the controller. + * + * @return The state of the button. + */ + bool GetXboxButton() const; + + /** + * Whether the Xbox button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetXboxButtonPressed(); + + /** + * Whether the Xbox button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetXboxButtonReleased(); + + /** + * Constructs an event instance around the Xbox button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Xbox button's + * digital signal attached to the given loop. + */ + BooleanEvent Xbox(EventLoop* loop) const; + + /** + * Read the value of the Menu button on the controller. + * + * @return The state of the button. + */ + bool GetMenuButton() const; + + /** + * Whether the Menu button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetMenuButtonPressed(); + + /** + * Whether the Menu button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetMenuButtonReleased(); + + /** + * Constructs an event instance around the Menu button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Menu button's + * digital signal attached to the given loop. + */ + BooleanEvent Menu(EventLoop* loop) const; + + /** + * Read the value of the Left Stick button on the controller. + * + * @return The state of the button. + */ + bool GetLeftStickButton() const; + + /** + * Whether the Left Stick button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetLeftStickButtonPressed(); + + /** + * Whether the Left Stick button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetLeftStickButtonReleased(); + + /** + * Constructs an event instance around the Left Stick button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Left Stick button's + * digital signal attached to the given loop. + */ + BooleanEvent LeftStick(EventLoop* loop) const; + + /** + * Read the value of the Right Stick button on the controller. + * + * @return The state of the button. + */ + bool GetRightStickButton() const; + + /** + * Whether the Right Stick button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetRightStickButtonPressed(); + + /** + * Whether the Right Stick button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetRightStickButtonReleased(); + + /** + * Constructs an event instance around the Right Stick button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Right Stick button's + * digital signal attached to the given loop. + */ + BooleanEvent RightStick(EventLoop* loop) const; + + /** + * Read the value of the Left Bumper button on the controller. + * + * @return The state of the button. + */ + bool GetLeftBumperButton() const; + + /** + * Whether the Left Bumper button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetLeftBumperButtonPressed(); + + /** + * Whether the Left Bumper button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetLeftBumperButtonReleased(); + + /** + * Constructs an event instance around the Left Bumper button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Left Bumper button's + * digital signal attached to the given loop. + */ + BooleanEvent LeftBumper(EventLoop* loop) const; + + /** + * Read the value of the Right Bumper button on the controller. + * + * @return The state of the button. + */ + bool GetRightBumperButton() const; + + /** + * Whether the Right Bumper button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetRightBumperButtonPressed(); + + /** + * Whether the Right Bumper button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetRightBumperButtonReleased(); + + /** + * Constructs an event instance around the Right Bumper button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Right Bumper button's + * digital signal attached to the given loop. + */ + BooleanEvent RightBumper(EventLoop* loop) const; + + /** + * Read the value of the Dpad Up button on the controller. + * + * @return The state of the button. + */ + bool GetDpadUpButton() const; + + /** + * Whether the Dpad Up button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetDpadUpButtonPressed(); + + /** + * Whether the Dpad Up button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetDpadUpButtonReleased(); + + /** + * Constructs an event instance around the Dpad Up button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Up button's + * digital signal attached to the given loop. + */ + BooleanEvent DpadUp(EventLoop* loop) const; + + /** + * Read the value of the Dpad Down button on the controller. + * + * @return The state of the button. + */ + bool GetDpadDownButton() const; + + /** + * Whether the Dpad Down button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetDpadDownButtonPressed(); + + /** + * Whether the Dpad Down button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetDpadDownButtonReleased(); + + /** + * Constructs an event instance around the Dpad Down button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Down button's + * digital signal attached to the given loop. + */ + BooleanEvent DpadDown(EventLoop* loop) const; + + /** + * Read the value of the Dpad Left button on the controller. + * + * @return The state of the button. + */ + bool GetDpadLeftButton() const; + + /** + * Whether the Dpad Left button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetDpadLeftButtonPressed(); + + /** + * Whether the Dpad Left button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetDpadLeftButtonReleased(); + + /** + * Constructs an event instance around the Dpad Left button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Left button's + * digital signal attached to the given loop. + */ + BooleanEvent DpadLeft(EventLoop* loop) const; + + /** + * Read the value of the Dpad Right button on the controller. + * + * @return The state of the button. + */ + bool GetDpadRightButton() const; + + /** + * Whether the Dpad Right button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + bool GetDpadRightButtonPressed(); + + /** + * Whether the Dpad Right button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + bool GetDpadRightButtonReleased(); + + /** + * Constructs an event instance around the Dpad Right button's + * digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Right button's + * digital signal attached to the given loop. + */ + BooleanEvent DpadRight(EventLoop* loop) const; + + /** + * Get the button value. + * + * @param button The button to read + * @return The state of the button. + */ + bool GetButton(int button) const; + + /** + * Whether the button was pressed since the last check. + * + * @param button The button to read + * @return Whether the button was pressed since the last check. + */ + bool GetButtonPressed(int button); + + /** + * Whether the button was released since the last check. + * + * @param button The button to read + * @return Whether the button was released since the last check. + */ + bool GetButtonReleased(int button); + + /** + * Constructs an event instance around this button's digital signal. + * + * @param button the button + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the button's digital signal attached + * to the given loop. + */ + BooleanEvent ButtonEvent(int button, EventLoop* loop) const; + + /** + * Set leds on the controller. + * + * @param r Red value from 0-255 + * @param g Green value from 0-255 + * @param b Blue value from 0-255 + */ + void SetLeds(int r, int g, int b); + + /** + * Set the rumble output for the HID. + * + * @param type Which rumble value to set + * @param value The normalized value (0 to 1) to set the rumble to + */ + void SetRumble(GenericHID::RumbleType type, double value); + + /** Represents a digital button on a XboxController. */ + struct Button { + /// A button. + static constexpr int A = 0; + /// B button. + static constexpr int B = 1; + /// X button. + static constexpr int X = 2; + /// Y button. + static constexpr int Y = 3; + /// View button. + static constexpr int VIEW = 4; + /// Xbox button. + static constexpr int XBOX = 5; + /// Menu button. + static constexpr int MENU = 6; + /// Left Stick button. + static constexpr int LEFT_STICK = 7; + /// Right Stick button. + static constexpr int RIGHT_STICK = 8; + /// Left Bumper button. + static constexpr int LEFT_BUMPER = 9; + /// Right Bumper button. + static constexpr int RIGHT_BUMPER = 10; + /// Dpad Up button. + static constexpr int DPAD_UP = 11; + /// Dpad Down button. + static constexpr int DPAD_DOWN = 12; + /// Dpad Left button. + static constexpr int DPAD_LEFT = 13; + /// Dpad Right button. + static constexpr int DPAD_RIGHT = 14; + }; + + /** Represents an axis on a XboxController. */ + struct Axis { + /// Left X. + static constexpr int LEFT_X = 0; + /// Left Y. + static constexpr int LEFT_Y = 1; + /// Right X. + static constexpr int RIGHT_X = 2; + /// Right Y. + static constexpr int RIGHT_Y = 3; + /// Left Trigger. + static constexpr int LEFT_TRIGGER = 4; + /// Right Trigger. + static constexpr int RIGHT_TRIGGER = 5; + }; + + void InitSendable(wpi::util::SendableBuilder& builder) override; + + private: + GenericHID* m_hid; +}; + +} // namespace wpi diff --git a/wpilibc/src/generated/main/native/include/wpi/simulation/DualSenseControllerSim.hpp b/wpilibc/src/generated/main/native/include/wpi/simulation/DualSenseControllerSim.hpp new file mode 100644 index 0000000000..1f32fc387e --- /dev/null +++ b/wpilibc/src/generated/main/native/include/wpi/simulation/DualSenseControllerSim.hpp @@ -0,0 +1,198 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#pragma once + +#include "wpi/simulation/GenericHIDSim.hpp" + +namespace wpi { + +class DualSenseController; + +namespace sim { + +/** + * Class to control a simulated DualSense controller. + */ +class DualSenseControllerSim : public GenericHIDSim { + public: + /** + * Constructs from a DualSenseController object. + * + * @param joystick controller to simulate + */ + explicit DualSenseControllerSim(const DualSenseController& joystick); + + /** + * Constructs from a joystick port number. + * + * @param port port number + */ + explicit DualSenseControllerSim(int port); + + /** + * Change the Left X value of the controller. + * + * @param value the new value + */ + void SetLeftX(double value); + + /** + * Change the Left Y value of the controller. + * + * @param value the new value + */ + void SetLeftY(double value); + + /** + * Change the Right X value of the controller. + * + * @param value the new value + */ + void SetRightX(double value); + + /** + * Change the Right Y value of the controller. + * + * @param value the new value + */ + void SetRightY(double value); + + /** + * Change the L 2 value of the controller. + * + * @param value the new value + */ + void SetL2(double value); + + /** + * Change the R 2 value of the controller. + * + * @param value the new value + */ + void SetR2(double 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 Square button on the controller. + * + * @param value the new value + */ + void SetSquareButton(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 Create button on the controller. + * + * @param value the new value + */ + void SetCreateButton(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 Options button on the controller. + * + * @param value the new value + */ + void SetOptionsButton(bool value); + + /** + * Change the value of the L 3 button on the controller. + * + * @param value the new value + */ + void SetL3Button(bool value); + + /** + * Change the value of the R 3 button on the controller. + * + * @param value the new value + */ + void SetR3Button(bool value); + + /** + * Change the value of the L 1 button on the controller. + * + * @param value the new value + */ + void SetL1Button(bool value); + + /** + * Change the value of the R 1 button on the controller. + * + * @param value the new value + */ + void SetR1Button(bool value); + + /** + * Change the value of the Dpad Up button on the controller. + * + * @param value the new value + */ + void SetDpadUpButton(bool value); + + /** + * Change the value of the Dpad Down button on the controller. + * + * @param value the new value + */ + void SetDpadDownButton(bool value); + + /** + * Change the value of the Dpad Left button on the controller. + * + * @param value the new value + */ + void SetDpadLeftButton(bool value); + + /** + * Change the value of the Dpad Right button on the controller. + * + * @param value the new value + */ + void SetDpadRightButton(bool value); + + /** + * Change the value of the Microphone button on the controller. + * + * @param value the new value + */ + void SetMicrophoneButton(bool value); + + /** + * Change the value of the Touchpad button on the controller. + * + * @param value the new value + */ + void SetTouchpadButton(bool value); +}; + +} // namespace sim +} // namespace wpi diff --git a/wpilibc/src/generated/main/native/include/wpi/simulation/XboxControllerSim.hpp b/wpilibc/src/generated/main/native/include/wpi/simulation/XboxControllerSim.hpp new file mode 100644 index 0000000000..2cace193dc --- /dev/null +++ b/wpilibc/src/generated/main/native/include/wpi/simulation/XboxControllerSim.hpp @@ -0,0 +1,184 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#pragma once + +#include "wpi/simulation/GenericHIDSim.hpp" + +namespace wpi { + +class XboxController; + +namespace sim { + +/** + * Class to control a simulated Xbox controller. + */ +class XboxControllerSim : public GenericHIDSim { + public: + /** + * Constructs from a XboxController object. + * + * @param joystick controller to simulate + */ + explicit XboxControllerSim(const XboxController& joystick); + + /** + * Constructs from a joystick port number. + * + * @param port port number + */ + explicit XboxControllerSim(int port); + + /** + * Change the Left X value of the controller. + * + * @param value the new value + */ + void SetLeftX(double value); + + /** + * Change the Left Y value of the controller. + * + * @param value the new value + */ + void SetLeftY(double value); + + /** + * Change the Right X value of the controller. + * + * @param value the new value + */ + void SetRightX(double value); + + /** + * Change the Right Y value of the controller. + * + * @param value the new value + */ + void SetRightY(double value); + + /** + * Change the Left Trigger value of the controller. + * + * @param value the new value + */ + void SetLeftTrigger(double value); + + /** + * Change the Right Trigger value of the controller. + * + * @param value the new value + */ + void SetRightTrigger(double value); + + /** + * Change the value of the A button on the controller. + * + * @param value the new value + */ + void SetAButton(bool value); + + /** + * Change the value of the B button on the controller. + * + * @param value the new value + */ + void SetBButton(bool value); + + /** + * Change the value of the X button on the controller. + * + * @param value the new value + */ + void SetXButton(bool value); + + /** + * Change the value of the Y button on the controller. + * + * @param value the new value + */ + void SetYButton(bool value); + + /** + * Change the value of the View button on the controller. + * + * @param value the new value + */ + void SetViewButton(bool value); + + /** + * Change the value of the Xbox button on the controller. + * + * @param value the new value + */ + void SetXboxButton(bool value); + + /** + * Change the value of the Menu button on the controller. + * + * @param value the new value + */ + void SetMenuButton(bool value); + + /** + * Change the value of the Left Stick button on the controller. + * + * @param value the new value + */ + void SetLeftStickButton(bool value); + + /** + * Change the value of the Right Stick button on the controller. + * + * @param value the new value + */ + void SetRightStickButton(bool value); + + /** + * Change the value of the Left Bumper button on the controller. + * + * @param value the new value + */ + void SetLeftBumperButton(bool value); + + /** + * Change the value of the Right Bumper button on the controller. + * + * @param value the new value + */ + void SetRightBumperButton(bool value); + + /** + * Change the value of the Dpad Up button on the controller. + * + * @param value the new value + */ + void SetDpadUpButton(bool value); + + /** + * Change the value of the Dpad Down button on the controller. + * + * @param value the new value + */ + void SetDpadDownButton(bool value); + + /** + * Change the value of the Dpad Left button on the controller. + * + * @param value the new value + */ + void SetDpadLeftButton(bool value); + + /** + * Change the value of the Dpad Right button on the controller. + * + * @param value the new value + */ + void SetDpadRightButton(bool value); +}; + +} // namespace sim +} // namespace wpi diff --git a/wpilibc/src/generated/test/native/cpp/DualSenseControllerTest.cpp b/wpilibc/src/generated/test/native/cpp/DualSenseControllerTest.cpp new file mode 100644 index 0000000000..ccea7a82d4 --- /dev/null +++ b/wpilibc/src/generated/test/native/cpp/DualSenseControllerTest.cpp @@ -0,0 +1,50 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#include "wpi/driverstation/DualSenseController.hpp" + +#include + +#include "JoystickTestMacros.hpp" +#include "wpi/simulation/DualSenseControllerSim.hpp" + +using namespace wpi; + +TEST(DualSenseControllerTest, WrappedHID) { + DualSenseController controller{2}; + sim::DualSenseControllerSim sim{controller}; + sim.NotifyNewData(); + + ASSERT_EQ(controller.GetPort(), 2); + ASSERT_EQ(controller.GetHID().GetPort(), 2); + ASSERT_EQ(controller.GetHID().GetAxesAvailable(), 0x3F); + ASSERT_EQ(controller.GetHID().GetButtonsAvailable(), 0x10FFFFULL); + ASSERT_EQ(controller.GetHID().GetPOVsAvailable(), 0); +} + +BUTTON_TEST(DualSenseController, CrossButton) +BUTTON_TEST(DualSenseController, CircleButton) +BUTTON_TEST(DualSenseController, SquareButton) +BUTTON_TEST(DualSenseController, TriangleButton) +BUTTON_TEST(DualSenseController, CreateButton) +BUTTON_TEST(DualSenseController, PSButton) +BUTTON_TEST(DualSenseController, OptionsButton) +BUTTON_TEST(DualSenseController, L3Button) +BUTTON_TEST(DualSenseController, R3Button) +BUTTON_TEST(DualSenseController, L1Button) +BUTTON_TEST(DualSenseController, R1Button) +BUTTON_TEST(DualSenseController, DpadUpButton) +BUTTON_TEST(DualSenseController, DpadDownButton) +BUTTON_TEST(DualSenseController, DpadLeftButton) +BUTTON_TEST(DualSenseController, DpadRightButton) +BUTTON_TEST(DualSenseController, MicrophoneButton) +BUTTON_TEST(DualSenseController, TouchpadButton) + +AXIS_TEST(DualSenseController, LeftX) +AXIS_TEST(DualSenseController, LeftY) +AXIS_TEST(DualSenseController, RightX) +AXIS_TEST(DualSenseController, RightY) +AXIS_TEST(DualSenseController, L2) +AXIS_TEST(DualSenseController, R2) diff --git a/wpilibc/src/generated/test/native/cpp/XboxControllerTest.cpp b/wpilibc/src/generated/test/native/cpp/XboxControllerTest.cpp new file mode 100644 index 0000000000..e044490f39 --- /dev/null +++ b/wpilibc/src/generated/test/native/cpp/XboxControllerTest.cpp @@ -0,0 +1,48 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibc/generate_first_ds_hids.py. DO NOT MODIFY +#include "wpi/driverstation/XboxController.hpp" + +#include + +#include "JoystickTestMacros.hpp" +#include "wpi/simulation/XboxControllerSim.hpp" + +using namespace wpi; + +TEST(XboxControllerTest, WrappedHID) { + XboxController controller{2}; + sim::XboxControllerSim sim{controller}; + sim.NotifyNewData(); + + ASSERT_EQ(controller.GetPort(), 2); + ASSERT_EQ(controller.GetHID().GetPort(), 2); + ASSERT_EQ(controller.GetHID().GetAxesAvailable(), 0x3F); + ASSERT_EQ(controller.GetHID().GetButtonsAvailable(), 0x7FFFULL); + ASSERT_EQ(controller.GetHID().GetPOVsAvailable(), 0); +} + +BUTTON_TEST(XboxController, AButton) +BUTTON_TEST(XboxController, BButton) +BUTTON_TEST(XboxController, XButton) +BUTTON_TEST(XboxController, YButton) +BUTTON_TEST(XboxController, ViewButton) +BUTTON_TEST(XboxController, XboxButton) +BUTTON_TEST(XboxController, MenuButton) +BUTTON_TEST(XboxController, LeftStickButton) +BUTTON_TEST(XboxController, RightStickButton) +BUTTON_TEST(XboxController, LeftBumperButton) +BUTTON_TEST(XboxController, RightBumperButton) +BUTTON_TEST(XboxController, DpadUpButton) +BUTTON_TEST(XboxController, DpadDownButton) +BUTTON_TEST(XboxController, DpadLeftButton) +BUTTON_TEST(XboxController, DpadRightButton) + +AXIS_TEST(XboxController, LeftX) +AXIS_TEST(XboxController, LeftY) +AXIS_TEST(XboxController, RightX) +AXIS_TEST(XboxController, RightY) +AXIS_TEST(XboxController, LeftTrigger) +AXIS_TEST(XboxController, RightTrigger) diff --git a/wpilibc/src/main/python/pyproject.toml b/wpilibc/src/main/python/pyproject.toml index 9f0bd068dc..25e328f705 100644 --- a/wpilibc/src/main/python/pyproject.toml +++ b/wpilibc/src/main/python/pyproject.toml @@ -121,6 +121,8 @@ Gamepad = "wpi/driverstation/Gamepad.hpp" GenericHID = "wpi/driverstation/GenericHID.hpp" HIDDevice = "wpi/driverstation/HIDDevice.hpp" Joystick = "wpi/driverstation/Joystick.hpp" +DualSenseController = "wpi/driverstation/DualSenseController.hpp" +XboxController = "wpi/driverstation/XboxController.hpp" NiDsPS4Controller = "wpi/driverstation/NiDsPS4Controller.hpp" NiDsPS5Controller = "wpi/driverstation/NiDsPS5Controller.hpp" NiDsStadiaController = "wpi/driverstation/NiDsStadiaController.hpp" @@ -278,6 +280,8 @@ GamepadSim = "wpi/simulation/GamepadSim.hpp" GenericHIDSim = "wpi/simulation/GenericHIDSim.hpp" JoystickSim = "wpi/simulation/JoystickSim.hpp" LinearSystemSim = "wpi/simulation/LinearSystemSim.hpp" +DualSenseControllerSim = "wpi/simulation/DualSenseControllerSim.hpp" +XboxControllerSim = "wpi/simulation/XboxControllerSim.hpp" NiDsPS4ControllerSim = "wpi/simulation/NiDsPS4ControllerSim.hpp" NiDsPS5ControllerSim = "wpi/simulation/NiDsPS5ControllerSim.hpp" OnboardIMUSim = "wpi/simulation/OnboardIMUSim.hpp" diff --git a/wpilibc/src/main/python/semiwrap/DualSenseController.yml b/wpilibc/src/main/python/semiwrap/DualSenseController.yml new file mode 100644 index 0000000000..cb74f4836e --- /dev/null +++ b/wpilibc/src/main/python/semiwrap/DualSenseController.yml @@ -0,0 +1,144 @@ +extra_includes: +- wpi/util/sendable/SendableBuilder.hpp +- wpi/driverstation/internal/DriverStationBackend.hpp +- wpi/event/BooleanEvent.hpp + +classes: + wpi::DualSenseController: + force_no_trampoline: true + ignored_bases: + - wpi::util::SendableHelper + attributes: + TOUCHPAD_COUNT: + SUPPORTS_RUMBLE: + SUPPORTS_TRIGGER_RUMBLE: + SUPPORTS_MONO_LED: + SUPPORTS_RGB_LED: + SUPPORTED_OUTPUTS: + methods: + DualSenseController: + overloads: + int: + GenericHID&: + GetHID: + overloads: + "": + return_value_policy: reference_internal + '[const]': + ignore: true + GetPort: + IsConnected: + GetLeftX: + GetLeftY: + GetRightX: + GetRightY: + GetAxis: + AxisLessThan: + AxisGreaterThan: + GetCrossButton: + GetCrossButtonPressed: + GetCrossButtonReleased: + Cross: + GetCircleButton: + GetCircleButtonPressed: + GetCircleButtonReleased: + Circle: + GetSquareButton: + GetSquareButtonPressed: + GetSquareButtonReleased: + Square: + GetTriangleButton: + GetTriangleButtonPressed: + GetTriangleButtonReleased: + Triangle: + GetCreateButton: + GetCreateButtonPressed: + GetCreateButtonReleased: + Create: + GetPSButton: + GetPSButtonPressed: + GetPSButtonReleased: + PS: + GetOptionsButton: + GetOptionsButtonPressed: + GetOptionsButtonReleased: + Options: + GetL3Button: + GetL3ButtonPressed: + GetL3ButtonReleased: + L3: + GetR3Button: + GetR3ButtonPressed: + GetR3ButtonReleased: + R3: + GetL1Button: + GetL1ButtonPressed: + GetL1ButtonReleased: + L1: + GetR1Button: + GetR1ButtonPressed: + GetR1ButtonReleased: + R1: + GetDpadUpButton: + GetDpadUpButtonPressed: + GetDpadUpButtonReleased: + DpadUp: + GetDpadDownButton: + GetDpadDownButtonPressed: + GetDpadDownButtonReleased: + DpadDown: + GetDpadLeftButton: + GetDpadLeftButtonPressed: + GetDpadLeftButtonReleased: + DpadLeft: + GetDpadRightButton: + GetDpadRightButtonPressed: + GetDpadRightButtonReleased: + DpadRight: + GetMicrophoneButton: + GetMicrophoneButtonPressed: + GetMicrophoneButtonReleased: + Microphone: + GetTouchpadButton: + GetTouchpadButtonPressed: + GetTouchpadButtonReleased: + Touchpad: + GetButton: + GetButtonPressed: + GetButtonReleased: + ButtonEvent: + rename: button + SetLeds: + SetRumble: + GetTouchpadFingerAvailable: + GetTouchpadFinger: + InitSendable: + GetL2: + GetR2: + wpi::DualSenseController::Button: + attributes: + CROSS: + CIRCLE: + SQUARE: + TRIANGLE: + CREATE: + PS: + OPTIONS: + L3: + R3: + L1: + R1: + DPAD_UP: + DPAD_DOWN: + DPAD_LEFT: + DPAD_RIGHT: + MICROPHONE: + TOUCHPAD: + wpi::DualSenseController::Axis: + attributes: + LEFT_X: + LEFT_Y: + RIGHT_X: + RIGHT_Y: + L2: + R2: diff --git a/wpilibc/src/main/python/semiwrap/XboxController.yml b/wpilibc/src/main/python/semiwrap/XboxController.yml new file mode 100644 index 0000000000..f1edba54d0 --- /dev/null +++ b/wpilibc/src/main/python/semiwrap/XboxController.yml @@ -0,0 +1,132 @@ +extra_includes: +- wpi/util/sendable/SendableBuilder.hpp +- wpi/driverstation/internal/DriverStationBackend.hpp +- wpi/event/BooleanEvent.hpp + +classes: + wpi::XboxController: + force_no_trampoline: true + ignored_bases: + - wpi::util::SendableHelper + attributes: + TOUCHPAD_COUNT: + SUPPORTS_RUMBLE: + SUPPORTS_TRIGGER_RUMBLE: + SUPPORTS_MONO_LED: + SUPPORTS_RGB_LED: + SUPPORTED_OUTPUTS: + methods: + XboxController: + overloads: + int: + GenericHID&: + GetHID: + overloads: + "": + return_value_policy: reference_internal + '[const]': + ignore: true + GetPort: + IsConnected: + GetLeftX: + GetLeftY: + GetRightX: + GetRightY: + GetAxis: + AxisLessThan: + AxisGreaterThan: + GetAButton: + GetAButtonPressed: + GetAButtonReleased: + A: + GetBButton: + GetBButtonPressed: + GetBButtonReleased: + B: + GetXButton: + GetXButtonPressed: + GetXButtonReleased: + X: + GetYButton: + GetYButtonPressed: + GetYButtonReleased: + Y: + GetViewButton: + GetViewButtonPressed: + GetViewButtonReleased: + View: + GetXboxButton: + GetXboxButtonPressed: + GetXboxButtonReleased: + Xbox: + GetMenuButton: + GetMenuButtonPressed: + GetMenuButtonReleased: + Menu: + GetLeftStickButton: + GetLeftStickButtonPressed: + GetLeftStickButtonReleased: + LeftStick: + GetRightStickButton: + GetRightStickButtonPressed: + GetRightStickButtonReleased: + RightStick: + GetLeftBumperButton: + GetLeftBumperButtonPressed: + GetLeftBumperButtonReleased: + LeftBumper: + GetRightBumperButton: + GetRightBumperButtonPressed: + GetRightBumperButtonReleased: + RightBumper: + GetDpadUpButton: + GetDpadUpButtonPressed: + GetDpadUpButtonReleased: + DpadUp: + GetDpadDownButton: + GetDpadDownButtonPressed: + GetDpadDownButtonReleased: + DpadDown: + GetDpadLeftButton: + GetDpadLeftButtonPressed: + GetDpadLeftButtonReleased: + DpadLeft: + GetDpadRightButton: + GetDpadRightButtonPressed: + GetDpadRightButtonReleased: + DpadRight: + GetButton: + GetButtonPressed: + GetButtonReleased: + ButtonEvent: + rename: button + SetLeds: + SetRumble: + InitSendable: + GetLeftTrigger: + GetRightTrigger: + wpi::XboxController::Button: + attributes: + A: + B: + X: + Y: + VIEW: + XBOX: + MENU: + LEFT_STICK: + RIGHT_STICK: + LEFT_BUMPER: + RIGHT_BUMPER: + DPAD_UP: + DPAD_DOWN: + DPAD_LEFT: + DPAD_RIGHT: + wpi::XboxController::Axis: + attributes: + LEFT_X: + LEFT_Y: + RIGHT_X: + RIGHT_Y: + LEFT_TRIGGER: + RIGHT_TRIGGER: diff --git a/wpilibc/src/main/python/semiwrap/simulation/DualSenseControllerSim.yml b/wpilibc/src/main/python/semiwrap/simulation/DualSenseControllerSim.yml new file mode 100644 index 0000000000..4c48bd1377 --- /dev/null +++ b/wpilibc/src/main/python/semiwrap/simulation/DualSenseControllerSim.yml @@ -0,0 +1,36 @@ +extra_includes: +- wpi/driverstation/DualSenseController.hpp + +classes: + wpi::sim::DualSenseControllerSim: + force_no_trampoline: true + typealias: + - wpi::DualSenseController + methods: + DualSenseControllerSim: + overloads: + const DualSenseController&: + int: + SetLeftX: + SetLeftY: + SetRightX: + SetRightY: + SetCrossButton: + SetCircleButton: + SetSquareButton: + SetTriangleButton: + SetCreateButton: + SetPSButton: + SetOptionsButton: + SetL3Button: + SetR3Button: + SetL1Button: + SetR1Button: + SetDpadUpButton: + SetDpadDownButton: + SetDpadLeftButton: + SetDpadRightButton: + SetMicrophoneButton: + SetTouchpadButton: + SetL2: + SetR2: diff --git a/wpilibc/src/main/python/semiwrap/simulation/XboxControllerSim.yml b/wpilibc/src/main/python/semiwrap/simulation/XboxControllerSim.yml new file mode 100644 index 0000000000..84d276685b --- /dev/null +++ b/wpilibc/src/main/python/semiwrap/simulation/XboxControllerSim.yml @@ -0,0 +1,34 @@ +extra_includes: +- wpi/driverstation/XboxController.hpp + +classes: + wpi::sim::XboxControllerSim: + force_no_trampoline: true + typealias: + - wpi::XboxController + methods: + XboxControllerSim: + overloads: + const XboxController&: + int: + SetLeftX: + SetLeftY: + SetRightX: + SetRightY: + SetAButton: + SetBButton: + SetXButton: + SetYButton: + SetViewButton: + SetXboxButton: + SetMenuButton: + SetLeftStickButton: + SetRightStickButton: + SetLeftBumperButton: + SetRightBumperButton: + SetDpadUpButton: + SetDpadDownButton: + SetDpadLeftButton: + SetDpadRightButton: + SetLeftTrigger: + SetRightTrigger: diff --git a/wpilibc/src/main/python/wpilib/__init__.py b/wpilibc/src/main/python/wpilib/__init__.py index d2d9e77420..9eea4d9da9 100644 --- a/wpilibc/src/main/python/wpilib/__init__.py +++ b/wpilibc/src/main/python/wpilib/__init__.py @@ -24,6 +24,7 @@ from ._wpilib import ( DoubleSolenoid, DriverStation, DriverStationBackend, + DualSenseController, DutyCycle, DutyCycleEncoder, EdgeConfiguration, @@ -105,6 +106,7 @@ from ._wpilib import ( UpDownCounter, VictorSP, Watchdog, + XboxController, getCurrentThreadPriority, getDeployDirectory, getErrorMessage, @@ -138,6 +140,7 @@ __all__ = [ "DoubleSolenoid", "DriverStation", "DriverStationBackend", + "DualSenseController", "DutyCycle", "DutyCycleEncoder", "EdgeConfiguration", @@ -219,6 +222,7 @@ __all__ = [ "UpDownCounter", "VictorSP", "Watchdog", + "XboxController", "getCurrentThreadPriority", "getDeployDirectory", "getErrorMessage", diff --git a/wpilibc/src/main/python/wpilib/simulation/__init__.py b/wpilibc/src/main/python/wpilib/simulation/__init__.py index 9341691a78..342056d28a 100644 --- a/wpilibc/src/main/python/wpilib/simulation/__init__.py +++ b/wpilibc/src/main/python/wpilib/simulation/__init__.py @@ -16,6 +16,7 @@ from ._simulation import ( DigitalPWMSim, DoubleSolenoidSim, DriverStationSim, + DualSenseControllerSim, DutyCycleEncoderSim, DutyCycleSim, ElevatorSim, @@ -47,6 +48,7 @@ from ._simulation import ( SimDeviceSim, SingleJointedArmSim, SolenoidSim, + XboxControllerSim, getProgramStarted, getProgramState, isTimingPaused, @@ -75,6 +77,7 @@ __all__ = [ "DigitalPWMSim", "DoubleSolenoidSim", "DriverStationSim", + "DualSenseControllerSim", "DutyCycleEncoderSim", "DutyCycleSim", "ElevatorSim", @@ -106,6 +109,7 @@ __all__ = [ "SimDeviceSim", "SingleJointedArmSim", "SolenoidSim", + "XboxControllerSim", "getProgramStarted", "getProgramState", "isTimingPaused", diff --git a/wpilibc/src/test/native/cpp/JoystickTestMacros.hpp b/wpilibc/src/test/native/include/JoystickTestMacros.hpp similarity index 100% rename from wpilibc/src/test/native/cpp/JoystickTestMacros.hpp rename to wpilibc/src/test/native/include/JoystickTestMacros.hpp diff --git a/wpilibj/BUILD.bazel b/wpilibj/BUILD.bazel index 69a6a8e9bf..3f908c7e77 100644 --- a/wpilibj/BUILD.bazel +++ b/wpilibj/BUILD.bazel @@ -19,6 +19,17 @@ py_binary( deps = [requirement("jinja2")], ) +py_binary( + name = "generate_first_ds_hids", + srcs = ["generate_first_ds_hids.py"], + target_compatible_with = select({ + "@rules_bzlmodrio_toolchains//constraints/is_roborio:roborio": ["@platforms//:incompatible"], + "@rules_bzlmodrio_toolchains//constraints/is_systemcore:systemcore": ["@platforms//:incompatible"], + "//conditions:default": [], + }), + deps = [requirement("jinja2")], +) + py_binary( name = "generate_pwm_motor_controllers", srcs = ["generate_pwm_motor_controllers.py"], @@ -40,6 +51,7 @@ py_binary( "//conditions:default": [], }), deps = [ + ":generate_first_ds_hids", ":generate_hids", ":generate_pwm_motor_controllers", ], @@ -106,7 +118,10 @@ pkg_files( wpilib_java_junit5_test( name = "wpilibj-java-test", - srcs = glob(["src/test/java/**/*.java"]), + srcs = glob([ + "src/generated/test/java/**/*.java", + "src/test/java/**/*.java", + ]), resource_strip_prefix = "wpilibj/src/test/resources", resources = glob(["src/test/resources/**"]), deps = [ @@ -141,6 +156,8 @@ java_binary( filegroup( name = "hid_schema", srcs = [ + "src/generate/first_ds_hids.json", + "src/generate/first_ds_hids.schema.json", "src/generate/hids.json", "src/generate/hids.schema.json", ], diff --git a/wpilibj/build.gradle b/wpilibj/build.gradle index f6de5baf34..3cc33ad210 100644 --- a/wpilibj/build.gradle +++ b/wpilibj/build.gradle @@ -51,6 +51,7 @@ gradle.taskGraph.addTaskExecutionGraphListener { graph -> sourceSets.main.java.srcDir "${buildDir}/generated/java/" sourceSets.main.java.srcDir "${projectDir}/src/generated/main/java" +sourceSets.test.java.srcDir "${projectDir}/src/generated/test/java" compileJava { dependsOn generateJavaVersion diff --git a/wpilibj/generate.bzl b/wpilibj/generate.bzl index 9fd6aaf2cd..7dd9c46c43 100644 --- a/wpilibj/generate.bzl +++ b/wpilibj/generate.bzl @@ -7,6 +7,7 @@ def __generate_wpilibj_impl(ctx): args = ctx.actions.args() args.add("--output_directory", output_dir.path) args.add("--template_root", "wpilibj/src/generate") + args.add("--test_output_directory", output_dir.path + "/test") ctx.actions.run( inputs = ctx.attr._templates.files, diff --git a/wpilibj/generate_first_ds_hids.py b/wpilibj/generate_first_ds_hids.py new file mode 100644 index 0000000000..02599f7cf3 --- /dev/null +++ b/wpilibj/generate_first_ds_hids.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python3 + +# 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. + +import argparse +import json +import re +from pathlib import Path + +from jinja2 import Environment, FileSystemLoader + + +def write_controller_file(output_dir: Path, controller_name: str, contents: str): + output_dir.mkdir(parents=True, exist_ok=True) + output_file = output_dir / controller_name + output_file.write_text(contents, encoding="utf-8", newline="\n") + + +def _capitalize_first(name: str) -> str: + return name[0].upper() + name[1:] + + +def _display_name(name: str) -> str: + name = re.sub(r"([a-z0-9])([A-Z])", r"\1 \2", name) + name = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1 \2", name) + name = re.sub(r"([A-Za-z])([0-9])", r"\1 \2", name) + return name[0].upper() + name[1:] + + +def _constant_name(name: str) -> str: + name = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1_\2", name) + name = re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name) + name = re.sub(r"([a-z])([0-9])", r"\1_\2", name) + return name.upper() + + +def _normalize_mapping(mapping: dict[str, int]): + return [ + { + "Name": name, + "MethodName": _capitalize_first(name), + "ConstantName": _constant_name(name), + "DocName": _display_name(name), + "value": value, + } + for name, value in mapping.items() + ] + + +def _supported_outputs(controller: dict): + supports = controller["supports"] + outputs = [] + if supports["monoLed"]: + outputs.append("MONO_LED") + if supports["rgbLed"]: + outputs.append("RGB_LED") + if supports["rumble"]: + outputs.append("RUMBLE") + if supports["triggerRumble"]: + outputs.append("TRIGGER_RUMBLE") + return outputs + + +def _supported_outputs_value(outputs: list[str]): + values = { + "MONO_LED": 0x1, + "RGB_LED": 0x2, + "RUMBLE": 0x8, + "TRIGGER_RUMBLE": 0x10, + } + result = 0 + for output in outputs: + result |= values[output] + return result + + +def _availability_mask(mapping: list[dict]): + result = 0 + for entry in mapping: + result |= 1 << entry["value"] + return result + + +def _hex_literal(value: int): + return f"0x{value:X}" + + +def _normalize_controller(controller: dict): + normalized = dict(controller) + normalized["axes"] = _normalize_mapping(controller["axes"]) + normalized["buttons"] = _normalize_mapping(controller["buttons"]) + normalized["supportedOutputs"] = _supported_outputs(controller) + normalized["SupportedOutputsValue"] = _supported_outputs_value( + normalized["supportedOutputs"] + ) + normalized["AxesMaximumIndex"] = ( + max(axis["value"] for axis in normalized["axes"]) + 1 + if normalized["axes"] + else 0 + ) + normalized["ButtonsMaximumIndex"] = ( + max(button["value"] for button in normalized["buttons"]) + 1 + if normalized["buttons"] + else 0 + ) + normalized["AxesAvailableMask"] = _hex_literal( + _availability_mask(normalized["axes"]) + ) + normalized["ButtonsAvailableMask"] = _hex_literal( + _availability_mask(normalized["buttons"]) + ) + return normalized + + +def generate_first_ds_hids( + output_directory: Path, + template_directory: Path, + test_output_directory: Path | None = None, +): + with (template_directory / "first_ds_hids.json").open(encoding="utf-8") as f: + controllers = [_normalize_controller(controller) for controller in json.load(f)] + + env = Environment( + loader=FileSystemLoader(template_directory / "main/java"), + autoescape=False, + keep_trailing_newline=True, + ) + + root_path = output_directory / "main/java/org/wpilib/driverstation" + template = env.get_template("first_ds_hid.java.jinja") + for controller in controllers: + controller_name = f"{controller['ClassName']}Controller.java" + output = template.render(controller) + write_controller_file(root_path, controller_name, output) + + root_path = output_directory / "main/java/org/wpilib/simulation" + template = env.get_template("first_ds_hidsim.java.jinja") + for controller in controllers: + controller_name = f"{controller['ClassName']}ControllerSim.java" + output = template.render(controller) + write_controller_file(root_path, controller_name, output) + + if test_output_directory is not None: + env = Environment( + loader=FileSystemLoader(template_directory / "test/java"), + autoescape=False, + keep_trailing_newline=True, + ) + + root_path = test_output_directory / "java/org/wpilib/driverstation" + template = env.get_template("first_ds_hid_test.java.jinja") + for controller in controllers: + controller_name = f"{controller['ClassName']}ControllerTest.java" + output = template.render(controller) + write_controller_file(root_path, controller_name, output) + + +def main(): + script_path = Path(__file__).resolve() + dirname = script_path.parent + + parser = argparse.ArgumentParser() + parser.add_argument( + "--output_directory", + help="Optional. If set, will output the generated files to this directory, otherwise it will use a path relative to the script", + default=dirname / "src/generated", + type=Path, + ) + parser.add_argument( + "--template_root", + help="Optional. If set, will use this directory as the root for the jinja templates", + default=dirname / "src/generate", + type=Path, + ) + parser.add_argument( + "--test_output_directory", + help="Optional. If set, will output generated tests to this directory", + default=dirname / "src/generated/test", + type=Path, + ) + args = parser.parse_args() + + test_output_directory = ( + None + if args.test_output_directory.name == "__none__" + else args.test_output_directory + ) + generate_first_ds_hids( + args.output_directory, args.template_root, test_output_directory + ) + + +if __name__ == "__main__": + main() diff --git a/wpilibj/generate_wpilibj.py b/wpilibj/generate_wpilibj.py index 1118714599..67042d25b9 100644 --- a/wpilibj/generate_wpilibj.py +++ b/wpilibj/generate_wpilibj.py @@ -2,6 +2,7 @@ import argparse import os from pathlib import Path +from wpilibj.generate_first_ds_hids import generate_first_ds_hids from wpilibj.generate_hids import generate_hids from wpilibj.generate_pwm_motor_controllers import generate_pwm_motor_controllers @@ -22,9 +23,23 @@ def main(): default=os.path.join(dirname, "src/generate"), type=Path, ) + parser.add_argument( + "--test_output_directory", + help="Optional. If set, will output generated tests to this directory", + default=os.path.join(dirname, "src/generated/test"), + type=Path, + ) args = parser.parse_args() generate_hids(args.output_directory, args.template_root) + test_output_directory = ( + None + if args.test_output_directory.name == "__none__" + else args.test_output_directory + ) + generate_first_ds_hids( + args.output_directory, args.template_root, test_output_directory + ) generate_pwm_motor_controllers(args.output_directory, args.template_root) diff --git a/wpilibj/src/generate/first_ds_hids.json b/wpilibj/src/generate/first_ds_hids.json new file mode 100644 index 0000000000..721662788a --- /dev/null +++ b/wpilibj/src/generate/first_ds_hids.json @@ -0,0 +1,76 @@ +[ + { + "ClassName": "Xbox", + "HIDType": "XBOX_ONE", + "axes": { + "leftX": 0, + "leftY": 1, + "rightX": 2, + "rightY": 3, + "leftTrigger": 4, + "rightTrigger": 5 + }, + "buttons": { + "a": 0, + "b": 1, + "x": 2, + "y": 3, + "view": 4, + "xbox": 5, + "menu": 6, + "leftStick": 7, + "rightStick": 8, + "leftBumper": 9, + "rightBumper": 10, + "dpadUp": 11, + "dpadDown": 12, + "dpadLeft": 13, + "dpadRight": 14 + }, + "touchpads": 0, + "supports": { + "rumble": true, + "triggerRumble": true, + "monoLed": false, + "rgbLed": false + } + }, + { + "ClassName": "DualSense", + "HIDType": "PS5", + "axes": { + "leftX": 0, + "leftY": 1, + "rightX": 2, + "rightY": 3, + "L2": 4, + "R2": 5 + }, + "buttons": { + "cross": 0, + "circle": 1, + "square": 2, + "triangle": 3, + "create": 4, + "PS": 5, + "options": 6, + "L3": 7, + "R3": 8, + "L1": 9, + "R1": 10, + "dpadUp": 11, + "dpadDown": 12, + "dpadLeft": 13, + "dpadRight": 14, + "microphone": 15, + "touchpad": 20 + }, + "touchpads": 1, + "supports": { + "rumble": true, + "triggerRumble": true, + "monoLed": false, + "rgbLed": true + } + } +] diff --git a/wpilibj/src/generate/first_ds_hids.schema.json b/wpilibj/src/generate/first_ds_hids.schema.json new file mode 100644 index 0000000000..8b68c9eab1 --- /dev/null +++ b/wpilibj/src/generate/first_ds_hids.schema.json @@ -0,0 +1,69 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://raw.githubusercontent.com/wpilibsuite/allwpilib/main/wpilibj/src/generate/first_ds_hids.schema.json", + "title": "A schema for defining FIRST Driver Station HIDs with JSON", + "type": "array", + "items": { + "type": "object", + "required": [ + "ClassName", + "HIDType", + "axes", + "buttons", + "touchpads", + "supports" + ], + "properties": { + "ClassName": { + "description": "The class name prefix before Controller", + "type": "string" + }, + "HIDType": { + "description": "The GenericHID HIDType enum value", + "type": "string" + }, + "axes": { + "description": "A map of axis method stems to DS axis indexes", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "buttons": { + "description": "A map of button method stems to DS button indexes", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "touchpads": { + "description": "The number of touchpads supported by the controller", + "type": "integer", + "minimum": 0 + }, + "supports": { + "type": "object", + "required": [ + "rumble", + "triggerRumble", + "monoLed", + "rgbLed" + ], + "properties": { + "rumble": { + "type": "boolean" + }, + "triggerRumble": { + "type": "boolean" + }, + "monoLed": { + "type": "boolean" + }, + "rgbLed": { + "type": "boolean" + } + } + } + } + } +} diff --git a/wpilibj/src/generate/main/java/first_ds_hid.java.jinja b/wpilibj/src/generate/main/java/first_ds_hid.java.jinja new file mode 100644 index 0000000000..da6f58a048 --- /dev/null +++ b/wpilibj/src/generate/main/java/first_ds_hid.java.jinja @@ -0,0 +1,352 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibj/generate_first_ds_hids.py. DO NOT MODIFY + +package org.wpilib.driverstation; + +import java.util.EnumSet; +import java.util.Objects; +import org.wpilib.event.BooleanEvent; +import org.wpilib.event.EventLoop; +import org.wpilib.hardware.hal.HAL; +import org.wpilib.util.sendable.Sendable; +import org.wpilib.util.sendable.SendableBuilder; + +/** + * Handle input from {{ ClassName }} controllers connected to the Driver Station. + * + *

This class handles {{ ClassName }} input that comes from the Driver Station. Each time a value + * is requested the most recent value is returned. + */ +public class {{ ClassName }}Controller implements HIDDevice, Sendable { + /** The number of touchpads supported by this controller. */ + public static final int TOUCHPAD_COUNT = {{ touchpads }}; + + /** Whether this controller supports main rumble motors. */ + public static final boolean SUPPORTS_RUMBLE = {{ supports.rumble|string|lower }}; + + /** Whether this controller supports trigger rumble motors. */ + public static final boolean SUPPORTS_TRIGGER_RUMBLE = {{ supports.triggerRumble|string|lower }}; + + /** Whether this controller supports mono LED output. */ + public static final boolean SUPPORTS_MONO_LED = {{ supports.monoLed|string|lower }}; + + /** Whether this controller supports RGB LED output. */ + public static final boolean SUPPORTS_RGB_LED = {{ supports.rgbLed|string|lower }}; + + /** Represents a digital button on a {{ ClassName }}Controller. */ + public enum Button { +{%- for button in buttons %} + /** {{ button.DocName }} button. */ + {{ button.ConstantName }}({{ button.value }}, "{{ button.MethodName }}Button"){{ ";" if loop.last else "," }} +{%- endfor %} + + /** Button value. */ + public final int value; + + private final String m_name; + + Button(int value, String name) { + this.value = value; + m_name = name; + } + + @Override + public String toString() { + return m_name; + } + } + + /** Represents an axis on a {{ ClassName }}Controller. */ + public enum Axis { +{%- for axis in axes %} + /** {{ axis.DocName }}. */ + {{ axis.ConstantName }}({{ axis.value }}, "{{ axis.MethodName }}"){{ ";" if loop.last else "," }} +{%- endfor %} + + /** Axis value. */ + public final int value; + + private final String m_name; + + Axis(int value, String name) { + this.value = value; + m_name = name; + } + + @Override + public String toString() { + return m_name; + } + } + + private final GenericHID m_hid; + + /** + * Construct an instance of a controller. + * + * @param port The port index on the Driver Station that the controller is plugged into. + */ + public {{ ClassName }}Controller(final int port) { + this(DriverStation.getGenericHID(port)); + } + + /** + * Construct an instance of a controller with a GenericHID object. + * + * @param hid The GenericHID object to use for this controller. + */ + public {{ ClassName }}Controller(final GenericHID hid) { + m_hid = Objects.requireNonNull(hid, "Provided HID object cannot be null"); + HAL.reportUsage("HID", hid.getPort(), "{{ ClassName }}Controller"); + } + + /** + * Get the underlying GenericHID object. + * + * @return the wrapped GenericHID object + */ + @Override + public GenericHID getHID() { + return m_hid; + } + + /** + * Get the supported outputs expected for this controller type. + * + * @return the expected supported outputs + */ + public static EnumSet getSupportedOutputCapabilities() { +{%- if supportedOutputs|length > 0 %} + return EnumSet.of( +{%- for output in supportedOutputs %} + GenericHID.SupportedOutput.{{ output }}{{ "," if not loop.last else "" }} +{%- endfor %} + ); +{%- else %} + return EnumSet.noneOf(GenericHID.SupportedOutput.class); +{%- endif %} + } + + /** + * Get the port number of the HID. + * + * @return The port number of the HID. + */ + public int getPort() { + return m_hid.getPort(); + } + + /** + * Get if the HID is connected. + * + * @return true if the HID is connected + */ + public boolean isConnected() { + return m_hid.isConnected(); + } +{% for axis in axes %} + /** + * Get the {{ axis.DocName }} value of the controller. + * + * @return The axis value. + */ + public double get{{ axis.MethodName }}() { + return getAxis(Axis.{{ axis.ConstantName }}); + } +{% endfor %} + /** + * Get the value of the axis. + * + * @param axis The axis to read + * @return The axis value. + */ + public double getAxis(Axis axis) { + return m_hid.getRawAxis(axis.value); + } + + /** + * Constructs an event instance that is true when the axis value is less than {@code threshold}. + * + * @param axis The axis to read. + * @param threshold The value below which this event should return true. + * @param loop the event loop instance to attach the event to. + * @return an event instance that is true when the axis value is less than the provided + * threshold. + */ + public BooleanEvent axisLessThan(Axis axis, double threshold, EventLoop loop) { + return m_hid.axisLessThan(axis.value, threshold, loop); + } + + /** + * Constructs an event instance that is true when the axis value is greater than {@code + * threshold}. + * + * @param axis The axis to read. + * @param threshold The value above which this event should return true. + * @param loop the event loop instance to attach the event to. + * @return an event instance that is true when the axis value is greater than the provided + * threshold. + */ + public BooleanEvent axisGreaterThan(Axis axis, double threshold, EventLoop loop) { + return m_hid.axisGreaterThan(axis.value, threshold, loop); + } +{% for button in buttons %} + /** + * Read the value of the {{ button.DocName }} button on the controller. + * + * @return The state of the button. + */ + public boolean get{{ button.MethodName }}Button() { + return getButton(Button.{{ button.ConstantName }}); + } + + /** + * Whether the {{ button.DocName }} button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean get{{ button.MethodName }}ButtonPressed() { + return getButtonPressed(Button.{{ button.ConstantName }}); + } + + /** + * Whether the {{ button.DocName }} button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean get{{ button.MethodName }}ButtonReleased() { + return getButtonReleased(Button.{{ button.ConstantName }}); + } + + /** + * Constructs an event instance around the {{ button.DocName }} button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the {{ button.DocName }} button's digital signal + * attached to the given loop. + */ + public BooleanEvent {{ button.Name }}(EventLoop loop) { + return button(Button.{{ button.ConstantName }}, loop); + } +{% endfor %} + /** + * Get the button value. + * + * @param button The button to read + * @return The state of the button. + */ + public boolean getButton(Button button) { + return m_hid.getRawButton(button.value); + } + + /** + * Whether the button was pressed since the last check. + * + * @param button The button to read + * @return Whether the button was pressed since the last check. + */ + public boolean getButtonPressed(Button button) { + return m_hid.getRawButtonPressed(button.value); + } + + /** + * Whether the button was released since the last check. + * + * @param button The button to read + * @return Whether the button was released since the last check. + */ + public boolean getButtonReleased(Button button) { + return m_hid.getRawButtonReleased(button.value); + } + + /** + * Constructs an event instance around this button's digital signal. + * + * @param button the button + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the button's digital signal attached to the given loop. + */ + public BooleanEvent button(Button button, EventLoop loop) { + return m_hid.button(button.value, loop); + } + + /** + * Set leds on the controller. + * + * @param r Red value from 0-255 + * @param g Green value from 0-255 + * @param b Blue value from 0-255 + */ + public void setLeds(int r, int g, int b) { + m_hid.setLeds(r, g, b); + } + + /** + * Set the rumble output for the HID. + * + * @param type Which rumble value to set + * @param value The normalized value (0 to 1) to set the rumble to + */ + public void setRumble(GenericHID.RumbleType type, double value) { + m_hid.setRumble(type, value); + } + +{% if touchpads == 1 %} + /** + * Check if a touchpad finger is available. + * + * @param finger The finger to check. + * @return true if the touchpad finger is available. + */ + public boolean getTouchpadFingerAvailable(int finger) { + return m_hid.getTouchpadFingerAvailable(0, finger); + } + + /** + * Get the touchpad finger data. + * + * @param finger The finger to read. + * @return The touchpad finger data. + */ + public TouchpadFinger getTouchpadFinger(int finger) { + return m_hid.getTouchpadFinger(0, finger); + } +{% elif touchpads > 1 %} + /** + * Check if a touchpad finger is available. + * + * @param touchpad The touchpad to check. + * @param finger The finger to check. + * @return true if the touchpad finger is available. + */ + public boolean getTouchpadFingerAvailable(int touchpad, int finger) { + return m_hid.getTouchpadFingerAvailable(touchpad, finger); + } + + /** + * Get the touchpad finger data. + * + * @param touchpad The touchpad to read. + * @param finger The finger to read. + * @return The touchpad finger data. + */ + public TouchpadFinger getTouchpadFinger(int touchpad, int finger) { + return m_hid.getTouchpadFinger(touchpad, finger); + } +{% endif %} + + @Override + public void initSendable(SendableBuilder builder) { + builder.setSmartDashboardType("HID"); + builder.publishConstString("ControllerType", "{{ ClassName }}"); +{%- for axis in axes %} + builder.addDoubleProperty("{{ axis.MethodName }}", this::get{{ axis.MethodName }}, null); +{%- endfor -%} +{% for button in buttons %} + builder.addBooleanProperty("{{ button.MethodName }}", this::get{{ button.MethodName }}Button, null); +{%- endfor %} + } +} diff --git a/wpilibj/src/generate/main/java/first_ds_hidsim.java.jinja b/wpilibj/src/generate/main/java/first_ds_hidsim.java.jinja new file mode 100644 index 0000000000..475a67ba4c --- /dev/null +++ b/wpilibj/src/generate/main/java/first_ds_hidsim.java.jinja @@ -0,0 +1,67 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibj/generate_first_ds_hids.py. DO NOT MODIFY + +package org.wpilib.simulation; +{% if ClassName < "GenericHID" %} +import org.wpilib.driverstation.{{ ClassName }}Controller; +import org.wpilib.driverstation.GenericHID; +{% else %} +import org.wpilib.driverstation.GenericHID; +import org.wpilib.driverstation.{{ ClassName }}Controller; +{% endif %} + +/** Class to control a simulated {{ ClassName }} controller. */ +public class {{ ClassName }}ControllerSim extends GenericHIDSim { + /** + * Constructs from a {{ ClassName }}Controller object. + * + * @param joystick controller to simulate + */ + @SuppressWarnings("this-escape") + public {{ ClassName }}ControllerSim({{ ClassName }}Controller joystick) { + super(joystick.getHID()); + configureDevice(); + } + + /** + * Constructs from a joystick port number. + * + * @param port port number + */ + @SuppressWarnings("this-escape") + public {{ ClassName }}ControllerSim(int port) { + super(port); + configureDevice(); + } + + private void configureDevice() { + setAxesAvailable({{ AxesAvailableMask }}); + setButtonsAvailable({{ ButtonsAvailableMask }}L); + setPOVsAvailable(0); + setGamepadType(GenericHID.HIDType.{{ HIDType }}); + setSupportedOutputs({{ ClassName }}Controller.getSupportedOutputCapabilities()); + } +{% for axis in axes %} + /** + * Change the {{ axis.DocName }} value of the controller. + * + * @param value the new value + */ + public void set{{ axis.MethodName }}(double value) { + setRawAxis({{ ClassName }}Controller.Axis.{{ axis.ConstantName }}.value, value); + } +{% endfor -%} +{% for button in buttons %} + /** + * Change the value of the {{ button.DocName }} button on the controller. + * + * @param value the new value + */ + public void set{{ button.MethodName }}Button(boolean value) { + setRawButton({{ ClassName }}Controller.Button.{{ button.ConstantName }}.value, value); + } +{% endfor -%} +} diff --git a/wpilibj/src/generate/test/java/first_ds_hid_test.java.jinja b/wpilibj/src/generate/test/java/first_ds_hid_test.java.jinja new file mode 100644 index 0000000000..595697c9e4 --- /dev/null +++ b/wpilibj/src/generate/test/java/first_ds_hid_test.java.jinja @@ -0,0 +1,95 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibj/generate_first_ds_hids.py. DO NOT MODIFY + +package org.wpilib.driverstation; + +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 java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.wpilib.hardware.hal.HAL; +import org.wpilib.simulation.{{ ClassName }}ControllerSim; + +class {{ ClassName }}ControllerTest { + @Test + void testWrappedHID() { + HAL.initialize(500, 0); + {{ ClassName }}Controller controller = new {{ ClassName }}Controller(2); + {{ ClassName }}ControllerSim sim = new {{ ClassName }}ControllerSim(controller); + sim.notifyNewData(); + + assertEquals(2, controller.getPort()); + assertEquals(2, controller.getHID().getPort()); + assertEquals({{ AxesAvailableMask }}, controller.getHID().getAxesAvailable()); + assertEquals({{ ButtonsAvailableMask }}L, controller.getHID().getButtonsAvailable()); + assertEquals(0, controller.getHID().getPOVsAvailable()); + } + + @ParameterizedTest + @EnumSource(value = {{ ClassName }}Controller.Button.class) + void testButtons({{ ClassName }}Controller.Button button) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + HAL.initialize(500, 0); + {{ ClassName }}Controller joy = new {{ ClassName }}Controller(2); + {{ ClassName }}ControllerSim joysim = new {{ ClassName }}ControllerSim(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)); + 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 = {{ ClassName }}Controller.Axis.class) + void testAxes({{ ClassName }}Controller.Axis axis) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + HAL.initialize(500, 0); + {{ ClassName }}Controller joy = new {{ ClassName }}Controller(2); + {{ ClassName }}ControllerSim joysim = new {{ ClassName }}ControllerSim(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); + } +} diff --git a/wpilibj/src/generated/main/java/org/wpilib/driverstation/DualSenseController.java b/wpilibj/src/generated/main/java/org/wpilib/driverstation/DualSenseController.java new file mode 100644 index 0000000000..99a24188e3 --- /dev/null +++ b/wpilibj/src/generated/main/java/org/wpilib/driverstation/DualSenseController.java @@ -0,0 +1,1034 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibj/generate_first_ds_hids.py. DO NOT MODIFY + +package org.wpilib.driverstation; + +import java.util.EnumSet; +import java.util.Objects; +import org.wpilib.event.BooleanEvent; +import org.wpilib.event.EventLoop; +import org.wpilib.hardware.hal.HAL; +import org.wpilib.util.sendable.Sendable; +import org.wpilib.util.sendable.SendableBuilder; + +/** + * Handle input from DualSense controllers connected to the Driver Station. + * + *

This class handles DualSense input that comes from the Driver Station. Each time a value + * is requested the most recent value is returned. + */ +public class DualSenseController implements HIDDevice, Sendable { + /** The number of touchpads supported by this controller. */ + public static final int TOUCHPAD_COUNT = 1; + + /** Whether this controller supports main rumble motors. */ + public static final boolean SUPPORTS_RUMBLE = true; + + /** Whether this controller supports trigger rumble motors. */ + public static final boolean SUPPORTS_TRIGGER_RUMBLE = true; + + /** Whether this controller supports mono LED output. */ + public static final boolean SUPPORTS_MONO_LED = false; + + /** Whether this controller supports RGB LED output. */ + public static final boolean SUPPORTS_RGB_LED = true; + + /** Represents a digital button on a DualSenseController. */ + public enum Button { + /** Cross button. */ + CROSS(0, "CrossButton"), + /** Circle button. */ + CIRCLE(1, "CircleButton"), + /** Square button. */ + SQUARE(2, "SquareButton"), + /** Triangle button. */ + TRIANGLE(3, "TriangleButton"), + /** Create button. */ + CREATE(4, "CreateButton"), + /** PS button. */ + PS(5, "PSButton"), + /** Options button. */ + OPTIONS(6, "OptionsButton"), + /** L 3 button. */ + L3(7, "L3Button"), + /** R 3 button. */ + R3(8, "R3Button"), + /** L 1 button. */ + L1(9, "L1Button"), + /** R 1 button. */ + R1(10, "R1Button"), + /** Dpad Up button. */ + DPAD_UP(11, "DpadUpButton"), + /** Dpad Down button. */ + DPAD_DOWN(12, "DpadDownButton"), + /** Dpad Left button. */ + DPAD_LEFT(13, "DpadLeftButton"), + /** Dpad Right button. */ + DPAD_RIGHT(14, "DpadRightButton"), + /** Microphone button. */ + MICROPHONE(15, "MicrophoneButton"), + /** Touchpad button. */ + TOUCHPAD(20, "TouchpadButton"); + + /** Button value. */ + public final int value; + + private final String m_name; + + Button(int value, String name) { + this.value = value; + m_name = name; + } + + @Override + public String toString() { + return m_name; + } + } + + /** Represents an axis on a DualSenseController. */ + public enum Axis { + /** Left X. */ + LEFT_X(0, "LeftX"), + /** Left Y. */ + LEFT_Y(1, "LeftY"), + /** Right X. */ + RIGHT_X(2, "RightX"), + /** Right Y. */ + RIGHT_Y(3, "RightY"), + /** L 2. */ + L2(4, "L2"), + /** R 2. */ + R2(5, "R2"); + + /** Axis value. */ + public final int value; + + private final String m_name; + + Axis(int value, String name) { + this.value = value; + m_name = name; + } + + @Override + public String toString() { + return m_name; + } + } + + private final GenericHID m_hid; + + /** + * Construct an instance of a controller. + * + * @param port The port index on the Driver Station that the controller is plugged into. + */ + public DualSenseController(final int port) { + this(DriverStation.getGenericHID(port)); + } + + /** + * Construct an instance of a controller with a GenericHID object. + * + * @param hid The GenericHID object to use for this controller. + */ + public DualSenseController(final GenericHID hid) { + m_hid = Objects.requireNonNull(hid, "Provided HID object cannot be null"); + HAL.reportUsage("HID", hid.getPort(), "DualSenseController"); + } + + /** + * Get the underlying GenericHID object. + * + * @return the wrapped GenericHID object + */ + @Override + public GenericHID getHID() { + return m_hid; + } + + /** + * Get the supported outputs expected for this controller type. + * + * @return the expected supported outputs + */ + public static EnumSet getSupportedOutputCapabilities() { + return EnumSet.of( + GenericHID.SupportedOutput.RGB_LED, + GenericHID.SupportedOutput.RUMBLE, + GenericHID.SupportedOutput.TRIGGER_RUMBLE + ); + } + + /** + * Get the port number of the HID. + * + * @return The port number of the HID. + */ + public int getPort() { + return m_hid.getPort(); + } + + /** + * Get if the HID is connected. + * + * @return true if the HID is connected + */ + public boolean isConnected() { + return m_hid.isConnected(); + } + + /** + * Get the Left X value of the controller. + * + * @return The axis value. + */ + public double getLeftX() { + return getAxis(Axis.LEFT_X); + } + + /** + * Get the Left Y value of the controller. + * + * @return The axis value. + */ + public double getLeftY() { + return getAxis(Axis.LEFT_Y); + } + + /** + * Get the Right X value of the controller. + * + * @return The axis value. + */ + public double getRightX() { + return getAxis(Axis.RIGHT_X); + } + + /** + * Get the Right Y value of the controller. + * + * @return The axis value. + */ + public double getRightY() { + return getAxis(Axis.RIGHT_Y); + } + + /** + * Get the L 2 value of the controller. + * + * @return The axis value. + */ + public double getL2() { + return getAxis(Axis.L2); + } + + /** + * Get the R 2 value of the controller. + * + * @return The axis value. + */ + public double getR2() { + return getAxis(Axis.R2); + } + + /** + * Get the value of the axis. + * + * @param axis The axis to read + * @return The axis value. + */ + public double getAxis(Axis axis) { + return m_hid.getRawAxis(axis.value); + } + + /** + * Constructs an event instance that is true when the axis value is less than {@code threshold}. + * + * @param axis The axis to read. + * @param threshold The value below which this event should return true. + * @param loop the event loop instance to attach the event to. + * @return an event instance that is true when the axis value is less than the provided + * threshold. + */ + public BooleanEvent axisLessThan(Axis axis, double threshold, EventLoop loop) { + return m_hid.axisLessThan(axis.value, threshold, loop); + } + + /** + * Constructs an event instance that is true when the axis value is greater than {@code + * threshold}. + * + * @param axis The axis to read. + * @param threshold The value above which this event should return true. + * @param loop the event loop instance to attach the event to. + * @return an event instance that is true when the axis value is greater than the provided + * threshold. + */ + public BooleanEvent axisGreaterThan(Axis axis, double threshold, EventLoop loop) { + return m_hid.axisGreaterThan(axis.value, threshold, loop); + } + + /** + * Read the value of the Cross button on the controller. + * + * @return The state of the button. + */ + public boolean getCrossButton() { + return getButton(Button.CROSS); + } + + /** + * Whether the Cross button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getCrossButtonPressed() { + return getButtonPressed(Button.CROSS); + } + + /** + * Whether the Cross button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getCrossButtonReleased() { + return getButtonReleased(Button.CROSS); + } + + /** + * 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 button(Button.CROSS, loop); + } + + /** + * Read the value of the Circle button on the controller. + * + * @return The state of the button. + */ + public boolean getCircleButton() { + return getButton(Button.CIRCLE); + } + + /** + * Whether the Circle button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getCircleButtonPressed() { + return getButtonPressed(Button.CIRCLE); + } + + /** + * Whether the Circle button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getCircleButtonReleased() { + return getButtonReleased(Button.CIRCLE); + } + + /** + * 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 button(Button.CIRCLE, loop); + } + + /** + * Read the value of the Square button on the controller. + * + * @return The state of the button. + */ + public boolean getSquareButton() { + return getButton(Button.SQUARE); + } + + /** + * Whether the Square button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getSquareButtonPressed() { + return getButtonPressed(Button.SQUARE); + } + + /** + * Whether the Square button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getSquareButtonReleased() { + return getButtonReleased(Button.SQUARE); + } + + /** + * 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 button(Button.SQUARE, loop); + } + + /** + * Read the value of the Triangle button on the controller. + * + * @return The state of the button. + */ + public boolean getTriangleButton() { + return getButton(Button.TRIANGLE); + } + + /** + * Whether the Triangle button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getTriangleButtonPressed() { + return getButtonPressed(Button.TRIANGLE); + } + + /** + * Whether the Triangle button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getTriangleButtonReleased() { + return getButtonReleased(Button.TRIANGLE); + } + + /** + * 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 button(Button.TRIANGLE, loop); + } + + /** + * Read the value of the Create button on the controller. + * + * @return The state of the button. + */ + public boolean getCreateButton() { + return getButton(Button.CREATE); + } + + /** + * Whether the Create button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getCreateButtonPressed() { + return getButtonPressed(Button.CREATE); + } + + /** + * Whether the Create button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getCreateButtonReleased() { + return getButtonReleased(Button.CREATE); + } + + /** + * 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 BooleanEvent create(EventLoop loop) { + return button(Button.CREATE, loop); + } + + /** + * Read the value of the PS button on the controller. + * + * @return The state of the button. + */ + public boolean getPSButton() { + return getButton(Button.PS); + } + + /** + * Whether the PS button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getPSButtonPressed() { + return getButtonPressed(Button.PS); + } + + /** + * Whether the PS button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getPSButtonReleased() { + return getButtonReleased(Button.PS); + } + + /** + * 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 BooleanEvent PS(EventLoop loop) { + return button(Button.PS, loop); + } + + /** + * Read the value of the Options button on the controller. + * + * @return The state of the button. + */ + public boolean getOptionsButton() { + return getButton(Button.OPTIONS); + } + + /** + * Whether the Options button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getOptionsButtonPressed() { + return getButtonPressed(Button.OPTIONS); + } + + /** + * Whether the Options button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getOptionsButtonReleased() { + return getButtonReleased(Button.OPTIONS); + } + + /** + * 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 button(Button.OPTIONS, loop); + } + + /** + * Read the value of the L 3 button on the controller. + * + * @return The state of the button. + */ + public boolean getL3Button() { + return getButton(Button.L3); + } + + /** + * Whether the L 3 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getL3ButtonPressed() { + return getButtonPressed(Button.L3); + } + + /** + * Whether the L 3 button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getL3ButtonReleased() { + return getButtonReleased(Button.L3); + } + + /** + * Constructs an event instance around the L 3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the L 3 button's digital signal + * attached to the given loop. + */ + public BooleanEvent L3(EventLoop loop) { + return button(Button.L3, loop); + } + + /** + * Read the value of the R 3 button on the controller. + * + * @return The state of the button. + */ + public boolean getR3Button() { + return getButton(Button.R3); + } + + /** + * Whether the R 3 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getR3ButtonPressed() { + return getButtonPressed(Button.R3); + } + + /** + * Whether the R 3 button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getR3ButtonReleased() { + return getButtonReleased(Button.R3); + } + + /** + * Constructs an event instance around the R 3 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the R 3 button's digital signal + * attached to the given loop. + */ + public BooleanEvent R3(EventLoop loop) { + return button(Button.R3, loop); + } + + /** + * Read the value of the L 1 button on the controller. + * + * @return The state of the button. + */ + public boolean getL1Button() { + return getButton(Button.L1); + } + + /** + * Whether the L 1 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getL1ButtonPressed() { + return getButtonPressed(Button.L1); + } + + /** + * Whether the L 1 button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getL1ButtonReleased() { + return getButtonReleased(Button.L1); + } + + /** + * Constructs an event instance around the L 1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the L 1 button's digital signal + * attached to the given loop. + */ + public BooleanEvent L1(EventLoop loop) { + return button(Button.L1, loop); + } + + /** + * Read the value of the R 1 button on the controller. + * + * @return The state of the button. + */ + public boolean getR1Button() { + return getButton(Button.R1); + } + + /** + * Whether the R 1 button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getR1ButtonPressed() { + return getButtonPressed(Button.R1); + } + + /** + * Whether the R 1 button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getR1ButtonReleased() { + return getButtonReleased(Button.R1); + } + + /** + * Constructs an event instance around the R 1 button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the R 1 button's digital signal + * attached to the given loop. + */ + public BooleanEvent R1(EventLoop loop) { + return button(Button.R1, loop); + } + + /** + * Read the value of the Dpad Up button on the controller. + * + * @return The state of the button. + */ + public boolean getDpadUpButton() { + return getButton(Button.DPAD_UP); + } + + /** + * Whether the Dpad Up button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getDpadUpButtonPressed() { + return getButtonPressed(Button.DPAD_UP); + } + + /** + * Whether the Dpad Up button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getDpadUpButtonReleased() { + return getButtonReleased(Button.DPAD_UP); + } + + /** + * Constructs an event instance around the Dpad Up button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Up button's digital signal + * attached to the given loop. + */ + public BooleanEvent dpadUp(EventLoop loop) { + return button(Button.DPAD_UP, loop); + } + + /** + * Read the value of the Dpad Down button on the controller. + * + * @return The state of the button. + */ + public boolean getDpadDownButton() { + return getButton(Button.DPAD_DOWN); + } + + /** + * Whether the Dpad Down button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getDpadDownButtonPressed() { + return getButtonPressed(Button.DPAD_DOWN); + } + + /** + * Whether the Dpad Down button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getDpadDownButtonReleased() { + return getButtonReleased(Button.DPAD_DOWN); + } + + /** + * Constructs an event instance around the Dpad Down button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Down button's digital signal + * attached to the given loop. + */ + public BooleanEvent dpadDown(EventLoop loop) { + return button(Button.DPAD_DOWN, loop); + } + + /** + * Read the value of the Dpad Left button on the controller. + * + * @return The state of the button. + */ + public boolean getDpadLeftButton() { + return getButton(Button.DPAD_LEFT); + } + + /** + * Whether the Dpad Left button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getDpadLeftButtonPressed() { + return getButtonPressed(Button.DPAD_LEFT); + } + + /** + * Whether the Dpad Left button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getDpadLeftButtonReleased() { + return getButtonReleased(Button.DPAD_LEFT); + } + + /** + * Constructs an event instance around the Dpad Left button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Left button's digital signal + * attached to the given loop. + */ + public BooleanEvent dpadLeft(EventLoop loop) { + return button(Button.DPAD_LEFT, loop); + } + + /** + * Read the value of the Dpad Right button on the controller. + * + * @return The state of the button. + */ + public boolean getDpadRightButton() { + return getButton(Button.DPAD_RIGHT); + } + + /** + * Whether the Dpad Right button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getDpadRightButtonPressed() { + return getButtonPressed(Button.DPAD_RIGHT); + } + + /** + * Whether the Dpad Right button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getDpadRightButtonReleased() { + return getButtonReleased(Button.DPAD_RIGHT); + } + + /** + * Constructs an event instance around the Dpad Right button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Right button's digital signal + * attached to the given loop. + */ + public BooleanEvent dpadRight(EventLoop loop) { + return button(Button.DPAD_RIGHT, loop); + } + + /** + * Read the value of the Microphone button on the controller. + * + * @return The state of the button. + */ + public boolean getMicrophoneButton() { + return getButton(Button.MICROPHONE); + } + + /** + * Whether the Microphone button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getMicrophoneButtonPressed() { + return getButtonPressed(Button.MICROPHONE); + } + + /** + * Whether the Microphone button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getMicrophoneButtonReleased() { + return getButtonReleased(Button.MICROPHONE); + } + + /** + * Constructs an event instance around the Microphone button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Microphone button's digital signal + * attached to the given loop. + */ + public BooleanEvent microphone(EventLoop loop) { + return button(Button.MICROPHONE, loop); + } + + /** + * Read the value of the Touchpad button on the controller. + * + * @return The state of the button. + */ + public boolean getTouchpadButton() { + return getButton(Button.TOUCHPAD); + } + + /** + * Whether the Touchpad button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getTouchpadButtonPressed() { + return getButtonPressed(Button.TOUCHPAD); + } + + /** + * Whether the Touchpad button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getTouchpadButtonReleased() { + return getButtonReleased(Button.TOUCHPAD); + } + + /** + * Constructs an event instance around the Touchpad button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Touchpad button's digital signal + * attached to the given loop. + */ + public BooleanEvent touchpad(EventLoop loop) { + return button(Button.TOUCHPAD, loop); + } + + /** + * Get the button value. + * + * @param button The button to read + * @return The state of the button. + */ + public boolean getButton(Button button) { + return m_hid.getRawButton(button.value); + } + + /** + * Whether the button was pressed since the last check. + * + * @param button The button to read + * @return Whether the button was pressed since the last check. + */ + public boolean getButtonPressed(Button button) { + return m_hid.getRawButtonPressed(button.value); + } + + /** + * Whether the button was released since the last check. + * + * @param button The button to read + * @return Whether the button was released since the last check. + */ + public boolean getButtonReleased(Button button) { + return m_hid.getRawButtonReleased(button.value); + } + + /** + * Constructs an event instance around this button's digital signal. + * + * @param button the button + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the button's digital signal attached to the given loop. + */ + public BooleanEvent button(Button button, EventLoop loop) { + return m_hid.button(button.value, loop); + } + + /** + * Set leds on the controller. + * + * @param r Red value from 0-255 + * @param g Green value from 0-255 + * @param b Blue value from 0-255 + */ + public void setLeds(int r, int g, int b) { + m_hid.setLeds(r, g, b); + } + + /** + * Set the rumble output for the HID. + * + * @param type Which rumble value to set + * @param value The normalized value (0 to 1) to set the rumble to + */ + public void setRumble(GenericHID.RumbleType type, double value) { + m_hid.setRumble(type, value); + } + + + /** + * Check if a touchpad finger is available. + * + * @param finger The finger to check. + * @return true if the touchpad finger is available. + */ + public boolean getTouchpadFingerAvailable(int finger) { + return m_hid.getTouchpadFingerAvailable(0, finger); + } + + /** + * Get the touchpad finger data. + * + * @param finger The finger to read. + * @return The touchpad finger data. + */ + public TouchpadFinger getTouchpadFinger(int finger) { + return m_hid.getTouchpadFinger(0, finger); + } + + + @Override + public void initSendable(SendableBuilder builder) { + builder.setSmartDashboardType("HID"); + builder.publishConstString("ControllerType", "DualSense"); + builder.addDoubleProperty("LeftX", this::getLeftX, null); + builder.addDoubleProperty("LeftY", this::getLeftY, null); + builder.addDoubleProperty("RightX", this::getRightX, null); + builder.addDoubleProperty("RightY", this::getRightY, null); + builder.addDoubleProperty("L2", this::getL2, null); + builder.addDoubleProperty("R2", this::getR2, null); + builder.addBooleanProperty("Cross", this::getCrossButton, null); + builder.addBooleanProperty("Circle", this::getCircleButton, null); + builder.addBooleanProperty("Square", this::getSquareButton, null); + builder.addBooleanProperty("Triangle", this::getTriangleButton, null); + builder.addBooleanProperty("Create", this::getCreateButton, null); + builder.addBooleanProperty("PS", this::getPSButton, null); + builder.addBooleanProperty("Options", this::getOptionsButton, null); + builder.addBooleanProperty("L3", this::getL3Button, null); + builder.addBooleanProperty("R3", this::getR3Button, null); + builder.addBooleanProperty("L1", this::getL1Button, null); + builder.addBooleanProperty("R1", this::getR1Button, null); + builder.addBooleanProperty("DpadUp", this::getDpadUpButton, null); + builder.addBooleanProperty("DpadDown", this::getDpadDownButton, null); + builder.addBooleanProperty("DpadLeft", this::getDpadLeftButton, null); + builder.addBooleanProperty("DpadRight", this::getDpadRightButton, null); + builder.addBooleanProperty("Microphone", this::getMicrophoneButton, null); + builder.addBooleanProperty("Touchpad", this::getTouchpadButton, null); + } +} diff --git a/wpilibj/src/generated/main/java/org/wpilib/driverstation/XboxController.java b/wpilibj/src/generated/main/java/org/wpilib/driverstation/XboxController.java new file mode 100644 index 0000000000..3ebdaf323f --- /dev/null +++ b/wpilibj/src/generated/main/java/org/wpilib/driverstation/XboxController.java @@ -0,0 +1,931 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibj/generate_first_ds_hids.py. DO NOT MODIFY + +package org.wpilib.driverstation; + +import java.util.EnumSet; +import java.util.Objects; +import org.wpilib.event.BooleanEvent; +import org.wpilib.event.EventLoop; +import org.wpilib.hardware.hal.HAL; +import org.wpilib.util.sendable.Sendable; +import org.wpilib.util.sendable.SendableBuilder; + +/** + * Handle input from Xbox controllers connected to the Driver Station. + * + *

This class handles Xbox input that comes from the Driver Station. Each time a value + * is requested the most recent value is returned. + */ +public class XboxController implements HIDDevice, Sendable { + /** The number of touchpads supported by this controller. */ + public static final int TOUCHPAD_COUNT = 0; + + /** Whether this controller supports main rumble motors. */ + public static final boolean SUPPORTS_RUMBLE = true; + + /** Whether this controller supports trigger rumble motors. */ + public static final boolean SUPPORTS_TRIGGER_RUMBLE = true; + + /** Whether this controller supports mono LED output. */ + public static final boolean SUPPORTS_MONO_LED = false; + + /** Whether this controller supports RGB LED output. */ + public static final boolean SUPPORTS_RGB_LED = false; + + /** Represents a digital button on a XboxController. */ + public enum Button { + /** A button. */ + A(0, "AButton"), + /** B button. */ + B(1, "BButton"), + /** X button. */ + X(2, "XButton"), + /** Y button. */ + Y(3, "YButton"), + /** View button. */ + VIEW(4, "ViewButton"), + /** Xbox button. */ + XBOX(5, "XboxButton"), + /** Menu button. */ + MENU(6, "MenuButton"), + /** Left Stick button. */ + LEFT_STICK(7, "LeftStickButton"), + /** Right Stick button. */ + RIGHT_STICK(8, "RightStickButton"), + /** Left Bumper button. */ + LEFT_BUMPER(9, "LeftBumperButton"), + /** Right Bumper button. */ + RIGHT_BUMPER(10, "RightBumperButton"), + /** Dpad Up button. */ + DPAD_UP(11, "DpadUpButton"), + /** Dpad Down button. */ + DPAD_DOWN(12, "DpadDownButton"), + /** Dpad Left button. */ + DPAD_LEFT(13, "DpadLeftButton"), + /** Dpad Right button. */ + DPAD_RIGHT(14, "DpadRightButton"); + + /** Button value. */ + public final int value; + + private final String m_name; + + Button(int value, String name) { + this.value = value; + m_name = name; + } + + @Override + public String toString() { + return m_name; + } + } + + /** Represents an axis on a XboxController. */ + public enum Axis { + /** Left X. */ + LEFT_X(0, "LeftX"), + /** Left Y. */ + LEFT_Y(1, "LeftY"), + /** Right X. */ + RIGHT_X(2, "RightX"), + /** Right Y. */ + RIGHT_Y(3, "RightY"), + /** Left Trigger. */ + LEFT_TRIGGER(4, "LeftTrigger"), + /** Right Trigger. */ + RIGHT_TRIGGER(5, "RightTrigger"); + + /** Axis value. */ + public final int value; + + private final String m_name; + + Axis(int value, String name) { + this.value = value; + m_name = name; + } + + @Override + public String toString() { + return m_name; + } + } + + private final GenericHID m_hid; + + /** + * Construct an instance of a controller. + * + * @param port The port index on the Driver Station that the controller is plugged into. + */ + public XboxController(final int port) { + this(DriverStation.getGenericHID(port)); + } + + /** + * Construct an instance of a controller with a GenericHID object. + * + * @param hid The GenericHID object to use for this controller. + */ + public XboxController(final GenericHID hid) { + m_hid = Objects.requireNonNull(hid, "Provided HID object cannot be null"); + HAL.reportUsage("HID", hid.getPort(), "XboxController"); + } + + /** + * Get the underlying GenericHID object. + * + * @return the wrapped GenericHID object + */ + @Override + public GenericHID getHID() { + return m_hid; + } + + /** + * Get the supported outputs expected for this controller type. + * + * @return the expected supported outputs + */ + public static EnumSet getSupportedOutputCapabilities() { + return EnumSet.of( + GenericHID.SupportedOutput.RUMBLE, + GenericHID.SupportedOutput.TRIGGER_RUMBLE + ); + } + + /** + * Get the port number of the HID. + * + * @return The port number of the HID. + */ + public int getPort() { + return m_hid.getPort(); + } + + /** + * Get if the HID is connected. + * + * @return true if the HID is connected + */ + public boolean isConnected() { + return m_hid.isConnected(); + } + + /** + * Get the Left X value of the controller. + * + * @return The axis value. + */ + public double getLeftX() { + return getAxis(Axis.LEFT_X); + } + + /** + * Get the Left Y value of the controller. + * + * @return The axis value. + */ + public double getLeftY() { + return getAxis(Axis.LEFT_Y); + } + + /** + * Get the Right X value of the controller. + * + * @return The axis value. + */ + public double getRightX() { + return getAxis(Axis.RIGHT_X); + } + + /** + * Get the Right Y value of the controller. + * + * @return The axis value. + */ + public double getRightY() { + return getAxis(Axis.RIGHT_Y); + } + + /** + * Get the Left Trigger value of the controller. + * + * @return The axis value. + */ + public double getLeftTrigger() { + return getAxis(Axis.LEFT_TRIGGER); + } + + /** + * Get the Right Trigger value of the controller. + * + * @return The axis value. + */ + public double getRightTrigger() { + return getAxis(Axis.RIGHT_TRIGGER); + } + + /** + * Get the value of the axis. + * + * @param axis The axis to read + * @return The axis value. + */ + public double getAxis(Axis axis) { + return m_hid.getRawAxis(axis.value); + } + + /** + * Constructs an event instance that is true when the axis value is less than {@code threshold}. + * + * @param axis The axis to read. + * @param threshold The value below which this event should return true. + * @param loop the event loop instance to attach the event to. + * @return an event instance that is true when the axis value is less than the provided + * threshold. + */ + public BooleanEvent axisLessThan(Axis axis, double threshold, EventLoop loop) { + return m_hid.axisLessThan(axis.value, threshold, loop); + } + + /** + * Constructs an event instance that is true when the axis value is greater than {@code + * threshold}. + * + * @param axis The axis to read. + * @param threshold The value above which this event should return true. + * @param loop the event loop instance to attach the event to. + * @return an event instance that is true when the axis value is greater than the provided + * threshold. + */ + public BooleanEvent axisGreaterThan(Axis axis, double threshold, EventLoop loop) { + return m_hid.axisGreaterThan(axis.value, threshold, loop); + } + + /** + * Read the value of the A button on the controller. + * + * @return The state of the button. + */ + public boolean getAButton() { + return getButton(Button.A); + } + + /** + * Whether the A button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getAButtonPressed() { + return getButtonPressed(Button.A); + } + + /** + * Whether the A button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getAButtonReleased() { + return getButtonReleased(Button.A); + } + + /** + * Constructs an event instance around the A button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the A button's digital signal + * attached to the given loop. + */ + public BooleanEvent a(EventLoop loop) { + return button(Button.A, loop); + } + + /** + * Read the value of the B button on the controller. + * + * @return The state of the button. + */ + public boolean getBButton() { + return getButton(Button.B); + } + + /** + * Whether the B button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getBButtonPressed() { + return getButtonPressed(Button.B); + } + + /** + * Whether the B button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getBButtonReleased() { + return getButtonReleased(Button.B); + } + + /** + * Constructs an event instance around the B button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the B button's digital signal + * attached to the given loop. + */ + public BooleanEvent b(EventLoop loop) { + return button(Button.B, loop); + } + + /** + * Read the value of the X button on the controller. + * + * @return The state of the button. + */ + public boolean getXButton() { + return getButton(Button.X); + } + + /** + * Whether the X button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getXButtonPressed() { + return getButtonPressed(Button.X); + } + + /** + * Whether the X button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getXButtonReleased() { + return getButtonReleased(Button.X); + } + + /** + * Constructs an event instance around the X button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the X button's digital signal + * attached to the given loop. + */ + public BooleanEvent x(EventLoop loop) { + return button(Button.X, loop); + } + + /** + * Read the value of the Y button on the controller. + * + * @return The state of the button. + */ + public boolean getYButton() { + return getButton(Button.Y); + } + + /** + * Whether the Y button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getYButtonPressed() { + return getButtonPressed(Button.Y); + } + + /** + * Whether the Y button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getYButtonReleased() { + return getButtonReleased(Button.Y); + } + + /** + * Constructs an event instance around the Y button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Y button's digital signal + * attached to the given loop. + */ + public BooleanEvent y(EventLoop loop) { + return button(Button.Y, loop); + } + + /** + * Read the value of the View button on the controller. + * + * @return The state of the button. + */ + public boolean getViewButton() { + return getButton(Button.VIEW); + } + + /** + * Whether the View button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getViewButtonPressed() { + return getButtonPressed(Button.VIEW); + } + + /** + * Whether the View button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getViewButtonReleased() { + return getButtonReleased(Button.VIEW); + } + + /** + * Constructs an event instance around the View button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the View button's digital signal + * attached to the given loop. + */ + public BooleanEvent view(EventLoop loop) { + return button(Button.VIEW, loop); + } + + /** + * Read the value of the Xbox button on the controller. + * + * @return The state of the button. + */ + public boolean getXboxButton() { + return getButton(Button.XBOX); + } + + /** + * Whether the Xbox button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getXboxButtonPressed() { + return getButtonPressed(Button.XBOX); + } + + /** + * Whether the Xbox button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getXboxButtonReleased() { + return getButtonReleased(Button.XBOX); + } + + /** + * Constructs an event instance around the Xbox button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Xbox button's digital signal + * attached to the given loop. + */ + public BooleanEvent xbox(EventLoop loop) { + return button(Button.XBOX, loop); + } + + /** + * Read the value of the Menu button on the controller. + * + * @return The state of the button. + */ + public boolean getMenuButton() { + return getButton(Button.MENU); + } + + /** + * Whether the Menu button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getMenuButtonPressed() { + return getButtonPressed(Button.MENU); + } + + /** + * Whether the Menu button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getMenuButtonReleased() { + return getButtonReleased(Button.MENU); + } + + /** + * Constructs an event instance around the Menu button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Menu button's digital signal + * attached to the given loop. + */ + public BooleanEvent menu(EventLoop loop) { + return button(Button.MENU, loop); + } + + /** + * Read the value of the Left Stick button on the controller. + * + * @return The state of the button. + */ + public boolean getLeftStickButton() { + return getButton(Button.LEFT_STICK); + } + + /** + * Whether the Left Stick button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getLeftStickButtonPressed() { + return getButtonPressed(Button.LEFT_STICK); + } + + /** + * Whether the Left Stick button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getLeftStickButtonReleased() { + return getButtonReleased(Button.LEFT_STICK); + } + + /** + * Constructs an event instance around the Left Stick button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Left Stick button's digital signal + * attached to the given loop. + */ + public BooleanEvent leftStick(EventLoop loop) { + return button(Button.LEFT_STICK, loop); + } + + /** + * Read the value of the Right Stick button on the controller. + * + * @return The state of the button. + */ + public boolean getRightStickButton() { + return getButton(Button.RIGHT_STICK); + } + + /** + * Whether the Right Stick button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getRightStickButtonPressed() { + return getButtonPressed(Button.RIGHT_STICK); + } + + /** + * Whether the Right Stick button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getRightStickButtonReleased() { + return getButtonReleased(Button.RIGHT_STICK); + } + + /** + * Constructs an event instance around the Right Stick button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Right Stick button's digital signal + * attached to the given loop. + */ + public BooleanEvent rightStick(EventLoop loop) { + return button(Button.RIGHT_STICK, loop); + } + + /** + * Read the value of the Left Bumper button on the controller. + * + * @return The state of the button. + */ + public boolean getLeftBumperButton() { + return getButton(Button.LEFT_BUMPER); + } + + /** + * Whether the Left Bumper button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getLeftBumperButtonPressed() { + return getButtonPressed(Button.LEFT_BUMPER); + } + + /** + * Whether the Left Bumper button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getLeftBumperButtonReleased() { + return getButtonReleased(Button.LEFT_BUMPER); + } + + /** + * Constructs an event instance around the Left Bumper button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Left Bumper button's digital signal + * attached to the given loop. + */ + public BooleanEvent leftBumper(EventLoop loop) { + return button(Button.LEFT_BUMPER, loop); + } + + /** + * Read the value of the Right Bumper button on the controller. + * + * @return The state of the button. + */ + public boolean getRightBumperButton() { + return getButton(Button.RIGHT_BUMPER); + } + + /** + * Whether the Right Bumper button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getRightBumperButtonPressed() { + return getButtonPressed(Button.RIGHT_BUMPER); + } + + /** + * Whether the Right Bumper button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getRightBumperButtonReleased() { + return getButtonReleased(Button.RIGHT_BUMPER); + } + + /** + * Constructs an event instance around the Right Bumper button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Right Bumper button's digital signal + * attached to the given loop. + */ + public BooleanEvent rightBumper(EventLoop loop) { + return button(Button.RIGHT_BUMPER, loop); + } + + /** + * Read the value of the Dpad Up button on the controller. + * + * @return The state of the button. + */ + public boolean getDpadUpButton() { + return getButton(Button.DPAD_UP); + } + + /** + * Whether the Dpad Up button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getDpadUpButtonPressed() { + return getButtonPressed(Button.DPAD_UP); + } + + /** + * Whether the Dpad Up button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getDpadUpButtonReleased() { + return getButtonReleased(Button.DPAD_UP); + } + + /** + * Constructs an event instance around the Dpad Up button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Up button's digital signal + * attached to the given loop. + */ + public BooleanEvent dpadUp(EventLoop loop) { + return button(Button.DPAD_UP, loop); + } + + /** + * Read the value of the Dpad Down button on the controller. + * + * @return The state of the button. + */ + public boolean getDpadDownButton() { + return getButton(Button.DPAD_DOWN); + } + + /** + * Whether the Dpad Down button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getDpadDownButtonPressed() { + return getButtonPressed(Button.DPAD_DOWN); + } + + /** + * Whether the Dpad Down button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getDpadDownButtonReleased() { + return getButtonReleased(Button.DPAD_DOWN); + } + + /** + * Constructs an event instance around the Dpad Down button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Down button's digital signal + * attached to the given loop. + */ + public BooleanEvent dpadDown(EventLoop loop) { + return button(Button.DPAD_DOWN, loop); + } + + /** + * Read the value of the Dpad Left button on the controller. + * + * @return The state of the button. + */ + public boolean getDpadLeftButton() { + return getButton(Button.DPAD_LEFT); + } + + /** + * Whether the Dpad Left button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getDpadLeftButtonPressed() { + return getButtonPressed(Button.DPAD_LEFT); + } + + /** + * Whether the Dpad Left button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getDpadLeftButtonReleased() { + return getButtonReleased(Button.DPAD_LEFT); + } + + /** + * Constructs an event instance around the Dpad Left button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Left button's digital signal + * attached to the given loop. + */ + public BooleanEvent dpadLeft(EventLoop loop) { + return button(Button.DPAD_LEFT, loop); + } + + /** + * Read the value of the Dpad Right button on the controller. + * + * @return The state of the button. + */ + public boolean getDpadRightButton() { + return getButton(Button.DPAD_RIGHT); + } + + /** + * Whether the Dpad Right button was pressed since the last check. + * + * @return Whether the button was pressed since the last check. + */ + public boolean getDpadRightButtonPressed() { + return getButtonPressed(Button.DPAD_RIGHT); + } + + /** + * Whether the Dpad Right button was released since the last check. + * + * @return Whether the button was released since the last check. + */ + public boolean getDpadRightButtonReleased() { + return getButtonReleased(Button.DPAD_RIGHT); + } + + /** + * Constructs an event instance around the Dpad Right button's digital signal. + * + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the Dpad Right button's digital signal + * attached to the given loop. + */ + public BooleanEvent dpadRight(EventLoop loop) { + return button(Button.DPAD_RIGHT, loop); + } + + /** + * Get the button value. + * + * @param button The button to read + * @return The state of the button. + */ + public boolean getButton(Button button) { + return m_hid.getRawButton(button.value); + } + + /** + * Whether the button was pressed since the last check. + * + * @param button The button to read + * @return Whether the button was pressed since the last check. + */ + public boolean getButtonPressed(Button button) { + return m_hid.getRawButtonPressed(button.value); + } + + /** + * Whether the button was released since the last check. + * + * @param button The button to read + * @return Whether the button was released since the last check. + */ + public boolean getButtonReleased(Button button) { + return m_hid.getRawButtonReleased(button.value); + } + + /** + * Constructs an event instance around this button's digital signal. + * + * @param button the button + * @param loop the event loop instance to attach the event to. + * @return an event instance representing the button's digital signal attached to the given loop. + */ + public BooleanEvent button(Button button, EventLoop loop) { + return m_hid.button(button.value, loop); + } + + /** + * Set leds on the controller. + * + * @param r Red value from 0-255 + * @param g Green value from 0-255 + * @param b Blue value from 0-255 + */ + public void setLeds(int r, int g, int b) { + m_hid.setLeds(r, g, b); + } + + /** + * Set the rumble output for the HID. + * + * @param type Which rumble value to set + * @param value The normalized value (0 to 1) to set the rumble to + */ + public void setRumble(GenericHID.RumbleType type, double value) { + m_hid.setRumble(type, value); + } + + + + @Override + public void initSendable(SendableBuilder builder) { + builder.setSmartDashboardType("HID"); + builder.publishConstString("ControllerType", "Xbox"); + builder.addDoubleProperty("LeftX", this::getLeftX, null); + builder.addDoubleProperty("LeftY", this::getLeftY, null); + builder.addDoubleProperty("RightX", this::getRightX, null); + builder.addDoubleProperty("RightY", this::getRightY, null); + builder.addDoubleProperty("LeftTrigger", this::getLeftTrigger, null); + builder.addDoubleProperty("RightTrigger", this::getRightTrigger, null); + builder.addBooleanProperty("A", this::getAButton, null); + builder.addBooleanProperty("B", this::getBButton, null); + builder.addBooleanProperty("X", this::getXButton, null); + builder.addBooleanProperty("Y", this::getYButton, null); + builder.addBooleanProperty("View", this::getViewButton, null); + builder.addBooleanProperty("Xbox", this::getXboxButton, null); + builder.addBooleanProperty("Menu", this::getMenuButton, null); + builder.addBooleanProperty("LeftStick", this::getLeftStickButton, null); + builder.addBooleanProperty("RightStick", this::getRightStickButton, null); + builder.addBooleanProperty("LeftBumper", this::getLeftBumperButton, null); + builder.addBooleanProperty("RightBumper", this::getRightBumperButton, null); + builder.addBooleanProperty("DpadUp", this::getDpadUpButton, null); + builder.addBooleanProperty("DpadDown", this::getDpadDownButton, null); + builder.addBooleanProperty("DpadLeft", this::getDpadLeftButton, null); + builder.addBooleanProperty("DpadRight", this::getDpadRightButton, null); + } +} diff --git a/wpilibj/src/generated/main/java/org/wpilib/simulation/DualSenseControllerSim.java b/wpilibj/src/generated/main/java/org/wpilib/simulation/DualSenseControllerSim.java new file mode 100644 index 0000000000..8b04f360da --- /dev/null +++ b/wpilibj/src/generated/main/java/org/wpilib/simulation/DualSenseControllerSim.java @@ -0,0 +1,251 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibj/generate_first_ds_hids.py. DO NOT MODIFY + +package org.wpilib.simulation; + +import org.wpilib.driverstation.DualSenseController; +import org.wpilib.driverstation.GenericHID; + + +/** Class to control a simulated DualSense controller. */ +public class DualSenseControllerSim extends GenericHIDSim { + /** + * Constructs from a DualSenseController object. + * + * @param joystick controller to simulate + */ + @SuppressWarnings("this-escape") + public DualSenseControllerSim(DualSenseController joystick) { + super(joystick.getHID()); + configureDevice(); + } + + /** + * Constructs from a joystick port number. + * + * @param port port number + */ + @SuppressWarnings("this-escape") + public DualSenseControllerSim(int port) { + super(port); + configureDevice(); + } + + private void configureDevice() { + setAxesAvailable(0x3F); + setButtonsAvailable(0x10FFFFL); + setPOVsAvailable(0); + setGamepadType(GenericHID.HIDType.PS5); + setSupportedOutputs(DualSenseController.getSupportedOutputCapabilities()); + } + + /** + * Change the Left X value of the controller. + * + * @param value the new value + */ + public void setLeftX(double value) { + setRawAxis(DualSenseController.Axis.LEFT_X.value, value); + } + + /** + * Change the Left Y value of the controller. + * + * @param value the new value + */ + public void setLeftY(double value) { + setRawAxis(DualSenseController.Axis.LEFT_Y.value, value); + } + + /** + * Change the Right X value of the controller. + * + * @param value the new value + */ + public void setRightX(double value) { + setRawAxis(DualSenseController.Axis.RIGHT_X.value, value); + } + + /** + * Change the Right Y value of the controller. + * + * @param value the new value + */ + public void setRightY(double value) { + setRawAxis(DualSenseController.Axis.RIGHT_Y.value, value); + } + + /** + * Change the L 2 value of the controller. + * + * @param value the new value + */ + public void setL2(double value) { + setRawAxis(DualSenseController.Axis.L2.value, value); + } + + /** + * Change the R 2 value of the controller. + * + * @param value the new value + */ + public void setR2(double value) { + setRawAxis(DualSenseController.Axis.R2.value, value); + } + + /** + * Change the value of the Cross button on the controller. + * + * @param value the new value + */ + public void setCrossButton(boolean value) { + setRawButton(DualSenseController.Button.CROSS.value, value); + } + + /** + * Change the value of the Circle button on the controller. + * + * @param value the new value + */ + public void setCircleButton(boolean value) { + setRawButton(DualSenseController.Button.CIRCLE.value, value); + } + + /** + * Change the value of the Square button on the controller. + * + * @param value the new value + */ + public void setSquareButton(boolean value) { + setRawButton(DualSenseController.Button.SQUARE.value, value); + } + + /** + * Change the value of the Triangle button on the controller. + * + * @param value the new value + */ + public void setTriangleButton(boolean value) { + setRawButton(DualSenseController.Button.TRIANGLE.value, value); + } + + /** + * Change the value of the Create button on the controller. + * + * @param value the new value + */ + public void setCreateButton(boolean value) { + setRawButton(DualSenseController.Button.CREATE.value, value); + } + + /** + * Change the value of the PS button on the controller. + * + * @param value the new value + */ + public void setPSButton(boolean value) { + setRawButton(DualSenseController.Button.PS.value, value); + } + + /** + * Change the value of the Options button on the controller. + * + * @param value the new value + */ + public void setOptionsButton(boolean value) { + setRawButton(DualSenseController.Button.OPTIONS.value, value); + } + + /** + * Change the value of the L 3 button on the controller. + * + * @param value the new value + */ + public void setL3Button(boolean value) { + setRawButton(DualSenseController.Button.L3.value, value); + } + + /** + * Change the value of the R 3 button on the controller. + * + * @param value the new value + */ + public void setR3Button(boolean value) { + setRawButton(DualSenseController.Button.R3.value, value); + } + + /** + * Change the value of the L 1 button on the controller. + * + * @param value the new value + */ + public void setL1Button(boolean value) { + setRawButton(DualSenseController.Button.L1.value, value); + } + + /** + * Change the value of the R 1 button on the controller. + * + * @param value the new value + */ + public void setR1Button(boolean value) { + setRawButton(DualSenseController.Button.R1.value, value); + } + + /** + * Change the value of the Dpad Up button on the controller. + * + * @param value the new value + */ + public void setDpadUpButton(boolean value) { + setRawButton(DualSenseController.Button.DPAD_UP.value, value); + } + + /** + * Change the value of the Dpad Down button on the controller. + * + * @param value the new value + */ + public void setDpadDownButton(boolean value) { + setRawButton(DualSenseController.Button.DPAD_DOWN.value, value); + } + + /** + * Change the value of the Dpad Left button on the controller. + * + * @param value the new value + */ + public void setDpadLeftButton(boolean value) { + setRawButton(DualSenseController.Button.DPAD_LEFT.value, value); + } + + /** + * Change the value of the Dpad Right button on the controller. + * + * @param value the new value + */ + public void setDpadRightButton(boolean value) { + setRawButton(DualSenseController.Button.DPAD_RIGHT.value, value); + } + + /** + * Change the value of the Microphone button on the controller. + * + * @param value the new value + */ + public void setMicrophoneButton(boolean value) { + setRawButton(DualSenseController.Button.MICROPHONE.value, value); + } + + /** + * Change the value of the Touchpad button on the controller. + * + * @param value the new value + */ + public void setTouchpadButton(boolean value) { + setRawButton(DualSenseController.Button.TOUCHPAD.value, value); + } +} diff --git a/wpilibj/src/generated/main/java/org/wpilib/simulation/XboxControllerSim.java b/wpilibj/src/generated/main/java/org/wpilib/simulation/XboxControllerSim.java new file mode 100644 index 0000000000..242ae745d5 --- /dev/null +++ b/wpilibj/src/generated/main/java/org/wpilib/simulation/XboxControllerSim.java @@ -0,0 +1,233 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibj/generate_first_ds_hids.py. DO NOT MODIFY + +package org.wpilib.simulation; + +import org.wpilib.driverstation.GenericHID; +import org.wpilib.driverstation.XboxController; + + +/** Class to control a simulated Xbox controller. */ +public class XboxControllerSim extends GenericHIDSim { + /** + * Constructs from a XboxController object. + * + * @param joystick controller to simulate + */ + @SuppressWarnings("this-escape") + public XboxControllerSim(XboxController joystick) { + super(joystick.getHID()); + configureDevice(); + } + + /** + * Constructs from a joystick port number. + * + * @param port port number + */ + @SuppressWarnings("this-escape") + public XboxControllerSim(int port) { + super(port); + configureDevice(); + } + + private void configureDevice() { + setAxesAvailable(0x3F); + setButtonsAvailable(0x7FFFL); + setPOVsAvailable(0); + setGamepadType(GenericHID.HIDType.XBOX_ONE); + setSupportedOutputs(XboxController.getSupportedOutputCapabilities()); + } + + /** + * Change the Left X value of the controller. + * + * @param value the new value + */ + public void setLeftX(double value) { + setRawAxis(XboxController.Axis.LEFT_X.value, value); + } + + /** + * Change the Left Y value of the controller. + * + * @param value the new value + */ + public void setLeftY(double value) { + setRawAxis(XboxController.Axis.LEFT_Y.value, value); + } + + /** + * Change the Right X value of the controller. + * + * @param value the new value + */ + public void setRightX(double value) { + setRawAxis(XboxController.Axis.RIGHT_X.value, value); + } + + /** + * Change the Right Y value of the controller. + * + * @param value the new value + */ + public void setRightY(double value) { + setRawAxis(XboxController.Axis.RIGHT_Y.value, value); + } + + /** + * Change the Left Trigger value of the controller. + * + * @param value the new value + */ + public void setLeftTrigger(double value) { + setRawAxis(XboxController.Axis.LEFT_TRIGGER.value, value); + } + + /** + * Change the Right Trigger value of the controller. + * + * @param value the new value + */ + public void setRightTrigger(double value) { + setRawAxis(XboxController.Axis.RIGHT_TRIGGER.value, value); + } + + /** + * Change the value of the A button on the controller. + * + * @param value the new value + */ + public void setAButton(boolean value) { + setRawButton(XboxController.Button.A.value, value); + } + + /** + * Change the value of the B button on the controller. + * + * @param value the new value + */ + public void setBButton(boolean value) { + setRawButton(XboxController.Button.B.value, value); + } + + /** + * Change the value of the X button on the controller. + * + * @param value the new value + */ + public void setXButton(boolean value) { + setRawButton(XboxController.Button.X.value, value); + } + + /** + * Change the value of the Y button on the controller. + * + * @param value the new value + */ + public void setYButton(boolean value) { + setRawButton(XboxController.Button.Y.value, value); + } + + /** + * Change the value of the View button on the controller. + * + * @param value the new value + */ + public void setViewButton(boolean value) { + setRawButton(XboxController.Button.VIEW.value, value); + } + + /** + * Change the value of the Xbox button on the controller. + * + * @param value the new value + */ + public void setXboxButton(boolean value) { + setRawButton(XboxController.Button.XBOX.value, value); + } + + /** + * Change the value of the Menu button on the controller. + * + * @param value the new value + */ + public void setMenuButton(boolean value) { + setRawButton(XboxController.Button.MENU.value, value); + } + + /** + * Change the value of the Left Stick button on the controller. + * + * @param value the new value + */ + public void setLeftStickButton(boolean value) { + setRawButton(XboxController.Button.LEFT_STICK.value, value); + } + + /** + * Change the value of the Right Stick button on the controller. + * + * @param value the new value + */ + public void setRightStickButton(boolean value) { + setRawButton(XboxController.Button.RIGHT_STICK.value, value); + } + + /** + * Change the value of the Left Bumper button on the controller. + * + * @param value the new value + */ + public void setLeftBumperButton(boolean value) { + setRawButton(XboxController.Button.LEFT_BUMPER.value, value); + } + + /** + * Change the value of the Right Bumper button on the controller. + * + * @param value the new value + */ + public void setRightBumperButton(boolean value) { + setRawButton(XboxController.Button.RIGHT_BUMPER.value, value); + } + + /** + * Change the value of the Dpad Up button on the controller. + * + * @param value the new value + */ + public void setDpadUpButton(boolean value) { + setRawButton(XboxController.Button.DPAD_UP.value, value); + } + + /** + * Change the value of the Dpad Down button on the controller. + * + * @param value the new value + */ + public void setDpadDownButton(boolean value) { + setRawButton(XboxController.Button.DPAD_DOWN.value, value); + } + + /** + * Change the value of the Dpad Left button on the controller. + * + * @param value the new value + */ + public void setDpadLeftButton(boolean value) { + setRawButton(XboxController.Button.DPAD_LEFT.value, value); + } + + /** + * Change the value of the Dpad Right button on the controller. + * + * @param value the new value + */ + public void setDpadRightButton(boolean value) { + setRawButton(XboxController.Button.DPAD_RIGHT.value, value); + } +} diff --git a/wpilibj/src/generated/test/java/org/wpilib/driverstation/DualSenseControllerTest.java b/wpilibj/src/generated/test/java/org/wpilib/driverstation/DualSenseControllerTest.java new file mode 100644 index 0000000000..eafc451d36 --- /dev/null +++ b/wpilibj/src/generated/test/java/org/wpilib/driverstation/DualSenseControllerTest.java @@ -0,0 +1,95 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibj/generate_first_ds_hids.py. DO NOT MODIFY + +package org.wpilib.driverstation; + +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 java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.wpilib.hardware.hal.HAL; +import org.wpilib.simulation.DualSenseControllerSim; + +class DualSenseControllerTest { + @Test + void testWrappedHID() { + HAL.initialize(500, 0); + DualSenseController controller = new DualSenseController(2); + DualSenseControllerSim sim = new DualSenseControllerSim(controller); + sim.notifyNewData(); + + assertEquals(2, controller.getPort()); + assertEquals(2, controller.getHID().getPort()); + assertEquals(0x3F, controller.getHID().getAxesAvailable()); + assertEquals(0x10FFFFL, controller.getHID().getButtonsAvailable()); + assertEquals(0, controller.getHID().getPOVsAvailable()); + } + + @ParameterizedTest + @EnumSource(value = DualSenseController.Button.class) + void testButtons(DualSenseController.Button button) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + HAL.initialize(500, 0); + DualSenseController joy = new DualSenseController(2); + DualSenseControllerSim joysim = new DualSenseControllerSim(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)); + 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 = DualSenseController.Axis.class) + void testAxes(DualSenseController.Axis axis) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + HAL.initialize(500, 0); + DualSenseController joy = new DualSenseController(2); + DualSenseControllerSim joysim = new DualSenseControllerSim(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); + } +} diff --git a/wpilibj/src/generated/test/java/org/wpilib/driverstation/XboxControllerTest.java b/wpilibj/src/generated/test/java/org/wpilib/driverstation/XboxControllerTest.java new file mode 100644 index 0000000000..381f665b07 --- /dev/null +++ b/wpilibj/src/generated/test/java/org/wpilib/driverstation/XboxControllerTest.java @@ -0,0 +1,95 @@ +// 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. + +// THIS FILE WAS AUTO-GENERATED BY ./wpilibj/generate_first_ds_hids.py. DO NOT MODIFY + +package org.wpilib.driverstation; + +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 java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.wpilib.hardware.hal.HAL; +import org.wpilib.simulation.XboxControllerSim; + +class XboxControllerTest { + @Test + void testWrappedHID() { + HAL.initialize(500, 0); + XboxController controller = new XboxController(2); + XboxControllerSim sim = new XboxControllerSim(controller); + sim.notifyNewData(); + + assertEquals(2, controller.getPort()); + assertEquals(2, controller.getHID().getPort()); + assertEquals(0x3F, controller.getHID().getAxesAvailable()); + assertEquals(0x7FFFL, controller.getHID().getButtonsAvailable()); + assertEquals(0, controller.getHID().getPOVsAvailable()); + } + + @ParameterizedTest + @EnumSource(value = XboxController.Button.class) + void testButtons(XboxController.Button button) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + HAL.initialize(500, 0); + XboxController joy = new XboxController(2); + XboxControllerSim joysim = new XboxControllerSim(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)); + 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 = XboxController.Axis.class) + void testAxes(XboxController.Axis axis) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + HAL.initialize(500, 0); + XboxController joy = new XboxController(2); + XboxControllerSim joysim = new XboxControllerSim(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); + } +}