From 2ef67f20a7a66b971fcb688fba9330d4e46c9d56 Mon Sep 17 00:00:00 2001 From: Prateek Machiraju Date: Sat, 14 Nov 2020 15:00:56 -0500 Subject: [PATCH] [wpilib] Add way to silence joystick connection warnings (#2845) Warnings cannot be silenced when connected to FMS. --- wpilibc/src/main/native/cpp/DriverStation.cpp | 18 +++++++-- .../main/native/include/frc/DriverStation.h | 19 +++++++++ .../src/test/native/cpp/DriverStationTest.cpp | 40 +++++++++++++++++++ .../edu/wpi/first/wpilibj/DriverStation.java | 33 +++++++++++++-- .../wpi/first/wpilibj/DriverStationTest.java | 19 +++++++++ 5 files changed, 121 insertions(+), 8 deletions(-) diff --git a/wpilibc/src/main/native/cpp/DriverStation.cpp b/wpilibc/src/main/native/cpp/DriverStation.cpp index c770331f03..dbb99f9b57 100644 --- a/wpilibc/src/main/native/cpp/DriverStation.cpp +++ b/wpilibc/src/main/native/cpp/DriverStation.cpp @@ -543,6 +543,14 @@ void DriverStation::GetData() { SendMatchData(); } +void DriverStation::SilenceJoystickConnectionWarning(bool silence) { + m_silenceJoystickWarning = silence; +} + +bool DriverStation::IsJoystickConnectionWarningSilenced() const { + return !IsFMSAttached() && m_silenceJoystickWarning; +} + DriverStation::DriverStation() { HAL_Initialize(500, 0); m_waitForDataCounter = 0; @@ -570,10 +578,12 @@ void DriverStation::ReportJoystickUnpluggedError(const wpi::Twine& message) { } void DriverStation::ReportJoystickUnpluggedWarning(const wpi::Twine& message) { - double currentTime = Timer::GetFPGATimestamp(); - if (currentTime > m_nextMessageTime) { - ReportWarning(message); - m_nextMessageTime = currentTime + kJoystickUnpluggedMessageInterval; + if (IsFMSAttached() || !m_silenceJoystickWarning) { + double currentTime = Timer::GetFPGATimestamp(); + if (currentTime > m_nextMessageTime) { + ReportWarning(message); + m_nextMessageTime = currentTime + kJoystickUnpluggedMessageInterval; + } } } diff --git a/wpilibc/src/main/native/include/frc/DriverStation.h b/wpilibc/src/main/native/include/frc/DriverStation.h index 342073ecdf..a6c40d666a 100644 --- a/wpilibc/src/main/native/include/frc/DriverStation.h +++ b/wpilibc/src/main/native/include/frc/DriverStation.h @@ -431,6 +431,23 @@ class DriverStation : public ErrorBase { */ void WakeupWaitForData(); + /** + * Allows the user to specify whether they want joystick connection warnings + * to be printed to the console. This setting is ignored when the FMS is + * connected -- warnings will always be on in that scenario. + * + * @param silence Whether warning messages should be silenced. + */ + void SilenceJoystickConnectionWarning(bool silence); + + /** + * Returns whether joystick connection warnings are silenced. This will + * always return false when connected to the FMS. + * + * @return Whether joystick connection warnings are silenced. + */ + bool IsJoystickConnectionWarningSilenced() const; + protected: /** * Copy data from the DS task for the user. @@ -482,6 +499,8 @@ class DriverStation : public ErrorBase { wpi::condition_variable m_waitForDataCond; int m_waitForDataCounter; + bool m_silenceJoystickWarning = false; + // Robot state status variables bool m_userInDisabled = false; bool m_userInAutonomous = false; diff --git a/wpilibc/src/test/native/cpp/DriverStationTest.cpp b/wpilibc/src/test/native/cpp/DriverStationTest.cpp index 6c5b262fc5..3b8272fc8f 100644 --- a/wpilibc/src/test/native/cpp/DriverStationTest.cpp +++ b/wpilibc/src/test/native/cpp/DriverStationTest.cpp @@ -5,10 +5,13 @@ /* the project. */ /*----------------------------------------------------------------------------*/ +#include #include #include "frc/DriverStation.h" +#include "frc/Joystick.h" #include "frc/simulation/DriverStationSim.h" +#include "frc/simulation/SimHooks.h" #include "gtest/gtest.h" class IsJoystickConnectedParametersTests @@ -32,3 +35,40 @@ INSTANTIATE_TEST_SUITE_P(IsConnectedTests, IsJoystickConnectedParametersTests, std::make_tuple(0, 0, 1, true), std::make_tuple(1, 1, 1, true), std::make_tuple(4, 10, 1, true))); +class JoystickConnectionWarningTests + : public ::testing::TestWithParam< + std::tuple> {}; + +TEST_P(JoystickConnectionWarningTests, JoystickConnectionWarnings) { + // Capture all output to stderr. + ::testing::internal::CaptureStderr(); + + // Set FMS and Silence settings + frc::sim::DriverStationSim::SetFmsAttached(std::get<0>(GetParam())); + frc::sim::DriverStationSim::NotifyNewData(); + frc::DriverStation::GetInstance().SilenceJoystickConnectionWarning( + std::get<1>(GetParam())); + + // Create joystick and attempt to retrieve button. + frc::Joystick joystick(0); + joystick.GetRawButton(1); + + frc::sim::StepTiming(1_s); + EXPECT_EQ( + frc::DriverStation::GetInstance().IsJoystickConnectionWarningSilenced(), + std::get<2>(GetParam())); + EXPECT_EQ(::testing::internal::GetCapturedStderr(), std::get<3>(GetParam())); +} + +INSTANTIATE_TEST_SUITE_P( + DriverStation, JoystickConnectionWarningTests, + ::testing::Values(std::make_tuple(false, true, true, ""), + std::make_tuple(false, false, false, + "Joystick Button missing, check if all " + "controllers are plugged in\n"), + std::make_tuple(true, true, false, + "Joystick Button missing, check if all " + "controllers are plugged in\n"), + std::make_tuple(true, false, false, + "Joystick Button missing, check if all " + "controllers are plugged in\n"))); 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 1e2567e49f..fe3ca50bab 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DriverStation.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DriverStation.java @@ -165,6 +165,8 @@ public class DriverStation { private int m_waitForDataCount; private final ThreadLocal m_lastCount = ThreadLocal.withInitial(() -> 0); + private boolean m_silenceJoystickWarning; + // Robot state status variables private boolean m_userInDisabled; private boolean m_userInAutonomous; @@ -1067,6 +1069,27 @@ public class DriverStation { m_waitForDataMutex.unlock(); } + /** + * Allows the user to specify whether they want joystick connection warnings + * to be printed to the console. This setting is ignored when the FMS is + * connected -- warnings will always be on in that scenario. + * + * @param silence Whether warning messages should be silenced. + */ + public void silenceJoystickConnectionWarning(boolean silence) { + m_silenceJoystickWarning = silence; + } + + /** + * Returns whether joystick connection warnings are silenced. This will + * always return false when connected to the FMS. + * + * @return Whether joystick connection warnings are silenced. + */ + public boolean isJoystickConnectionWarningSilenced() { + return !isFMSAttached() && m_silenceJoystickWarning; + } + /** * Copy data from the DS task for the user. If no new data exists, it will just be returned, * otherwise the data will be copied from the DS polling loop. @@ -1141,10 +1164,12 @@ public class DriverStation { * the DS. */ private void reportJoystickUnpluggedWarning(String message) { - double currentTime = Timer.getFPGATimestamp(); - if (currentTime > m_nextMessageTime) { - reportWarning(message, false); - m_nextMessageTime = currentTime + JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL; + if (isFMSAttached() || !m_silenceJoystickWarning) { + double currentTime = Timer.getFPGATimestamp(); + if (currentTime > m_nextMessageTime) { + reportWarning(message, false); + m_nextMessageTime = currentTime + JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL; + } } } diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/DriverStationTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/DriverStationTest.java index 7970f52132..50e16c8b74 100644 --- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/DriverStationTest.java +++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/DriverStationTest.java @@ -41,4 +41,23 @@ class DriverStationTest { arguments(4, 10, 1, true) ); } + + @MethodSource("connectionWarningProvider") + void testConnectionWarnings(boolean fms, boolean silence, boolean expected) { + DriverStationSim.setFmsAttached(fms); + DriverStationSim.notifyNewData(); + + DriverStation.getInstance().silenceJoystickConnectionWarning(silence); + assertEquals(expected, + DriverStation.getInstance().isJoystickConnectionWarningSilenced()); + } + + static Stream connectionWarningProvider() { + return Stream.of( + arguments(false, true, true), + arguments(false, false, false), + arguments(true, true, false), + arguments(true, false, false) + ); + } }