diff --git a/wpilibc/src/main/native/cpp/DriverStation.cpp b/wpilibc/src/main/native/cpp/DriverStation.cpp index 758eef7688..c770331f03 100644 --- a/wpilibc/src/main/native/cpp/DriverStation.cpp +++ b/wpilibc/src/main/native/cpp/DriverStation.cpp @@ -331,6 +331,11 @@ int DriverStation::GetJoystickAxisType(int stick, int axis) const { return static_cast(descriptor.axisTypes); } +bool DriverStation::IsJoystickConnected(int stick) const { + return GetStickAxisCount(stick) > 0 || GetStickButtonCount(stick) > 0 || + GetStickPOVCount(stick) > 0; +} + bool DriverStation::IsEnabled() const { HAL_ControlWord controlWord; HAL_GetControlWord(&controlWord); diff --git a/wpilibc/src/main/native/cpp/GenericHID.cpp b/wpilibc/src/main/native/cpp/GenericHID.cpp index 8b28849a20..4a264c800a 100644 --- a/wpilibc/src/main/native/cpp/GenericHID.cpp +++ b/wpilibc/src/main/native/cpp/GenericHID.cpp @@ -47,6 +47,10 @@ int GenericHID::GetButtonCount() const { return m_ds->GetStickButtonCount(m_port); } +bool GenericHID::IsConnected() const { + return m_ds->IsJoystickConnected(m_port); +} + GenericHID::HIDType GenericHID::GetType() const { return static_cast(m_ds->GetJoystickType(m_port)); } diff --git a/wpilibc/src/main/native/include/frc/DriverStation.h b/wpilibc/src/main/native/include/frc/DriverStation.h index 85b067cb62..342073ecdf 100644 --- a/wpilibc/src/main/native/include/frc/DriverStation.h +++ b/wpilibc/src/main/native/include/frc/DriverStation.h @@ -181,6 +181,17 @@ class DriverStation : public ErrorBase { */ int GetJoystickAxisType(int stick, int axis) const; + /** + * Returns if a joystick is connected to the Driver Station. + * + * This makes a best effort guess by looking at the reported number of axis, + * buttons, and POVs attached. + * + * @param stick The joystick port number + * @return true if a joystick is connected + */ + bool IsJoystickConnected(int stick) const; + /** * Check if the DS has enabled the robot. * diff --git a/wpilibc/src/main/native/include/frc/GenericHID.h b/wpilibc/src/main/native/include/frc/GenericHID.h index f1ac24ae62..001b984f45 100644 --- a/wpilibc/src/main/native/include/frc/GenericHID.h +++ b/wpilibc/src/main/native/include/frc/GenericHID.h @@ -136,6 +136,13 @@ class GenericHID : public ErrorBase { */ int GetButtonCount() const; + /** + * Get if the HID is connected. + * + * @return true if the HID is connected + */ + bool IsConnected() const; + /** * Get the type of the HID. * diff --git a/wpilibc/src/test/native/cpp/DriverStationTest.cpp b/wpilibc/src/test/native/cpp/DriverStationTest.cpp new file mode 100644 index 0000000000..6c5b262fc5 --- /dev/null +++ b/wpilibc/src/test/native/cpp/DriverStationTest.cpp @@ -0,0 +1,34 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2020 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#include + +#include "frc/DriverStation.h" +#include "frc/simulation/DriverStationSim.h" +#include "gtest/gtest.h" + +class IsJoystickConnectedParametersTests + : public ::testing::TestWithParam> {}; + +TEST_P(IsJoystickConnectedParametersTests, IsJoystickConnected) { + frc::sim::DriverStationSim::SetJoystickAxisCount(1, std::get<0>(GetParam())); + frc::sim::DriverStationSim::SetJoystickButtonCount(1, + std::get<1>(GetParam())); + frc::sim::DriverStationSim::SetJoystickPOVCount(1, std::get<2>(GetParam())); + frc::sim::DriverStationSim::NotifyNewData(); + + ASSERT_EQ(std::get<3>(GetParam()), + frc::DriverStation::GetInstance().IsJoystickConnected(1)); +} + +INSTANTIATE_TEST_SUITE_P(IsConnectedTests, IsJoystickConnectedParametersTests, + ::testing::Values(std::make_tuple(0, 0, 0, false), + std::make_tuple(1, 0, 0, true), + std::make_tuple(0, 1, 0, true), + std::make_tuple(0, 0, 1, true), + std::make_tuple(1, 1, 1, true), + std::make_tuple(4, 10, 1, true))); diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DriverStation.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DriverStation.java index 80693a425c..1e2567e49f 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DriverStation.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DriverStation.java @@ -594,6 +594,21 @@ public class DriverStation { return HAL.getJoystickAxisType((byte) stick, (byte) axis); } + /** + * Returns if a joystick is connected to the Driver Station. + * + *

This makes a best effort guess by looking at the reported number of axis, + * buttons, and POVs attached. + * + * @param stick The joystick port number + * @return true if a joystick is connected + */ + public boolean isJoystickConnected(int stick) { + return getStickAxisCount(stick) > 0 + || getStickButtonCount(stick) > 0 + || getStickPOVCount(stick) > 0; + } + /** * Gets a value indicating whether the Driver Station requires the robot to be enabled. * diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/GenericHID.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/GenericHID.java index 5f00bfd41b..f573cb2744 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/GenericHID.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/GenericHID.java @@ -217,6 +217,15 @@ public abstract class GenericHID { return m_ds.getStickButtonCount(m_port); } + /** + * Get if the HID is connected. + * + * @return true if the HID is connected + */ + public boolean isConnected() { + return m_ds.isJoystickConnected(m_port); + } + /** * Get the type of the HID. * diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/DriverStationTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/DriverStationTest.java new file mode 100644 index 0000000000..7970f52132 --- /dev/null +++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/DriverStationTest.java @@ -0,0 +1,44 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2020 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +package edu.wpi.first.wpilibj; + +import java.util.stream.Stream; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import edu.wpi.first.wpilibj.simulation.DriverStationSim; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +class DriverStationTest { + @ParameterizedTest + @MethodSource("isConnectedProvider") + void testIsConnected(int axisCount, int buttonCount, int povCount, boolean expected) { + DriverStationSim.setJoystickAxisCount(1, axisCount); + DriverStationSim.setJoystickButtonCount(1, buttonCount); + DriverStationSim.setJoystickPOVCount(1, povCount); + + DriverStationSim.notifyNewData(); + + assertEquals(expected, DriverStation.getInstance().isJoystickConnected(1)); + } + + static Stream isConnectedProvider() { + return Stream.of( + arguments(0, 0, 0, false), + arguments(1, 0, 0, true), + arguments(0, 1, 0, true), + arguments(0, 0, 1, true), + arguments(1, 1, 1, true), + arguments(4, 10, 1, true) + ); + } +}