/*----------------------------------------------------------------------------*/ /* Copyright (c) FIRST 2008-2016. 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. */ /*----------------------------------------------------------------------------*/ #pragma once #include #include #include #include #include "HAL/cpp/Semaphore.h" #include "HAL/cpp/priority_condition_variable.h" #include "HAL/cpp/priority_mutex.h" #include "RobotState.h" #include "SensorBase.h" #include "Task.h" struct HALControlWord; class AnalogInput; /** * Provide access to the network communication data to / from the Driver * Station. */ class DriverStation : public SensorBase, public RobotStateInterface { public: enum Alliance { kRed, kBlue, kInvalid }; virtual ~DriverStation(); static DriverStation& GetInstance(); static void ReportError(std::string error); static void ReportWarning(std::string error); static void ReportError(bool is_error, int code, const std::string& error, const std::string& location, const std::string& stack); static const int kJoystickPorts = 6; float GetStickAxis(int stick, int axis); int GetStickPOV(int stick, int pov); int GetStickButtons(int stick) const; bool GetStickButton(int stick, int button); int GetStickAxisCount(int stick) const; int GetStickPOVCount(int stick) const; int GetStickButtonCount(int stick) const; bool GetJoystickIsXbox(int stick) const; int GetJoystickType(int stick) const; std::string GetJoystickName(int stick) const; int GetJoystickAxisType(int stick, int axis) const; bool IsEnabled() const override; bool IsDisabled() const override; bool IsAutonomous() const override; bool IsOperatorControl() const override; bool IsTest() const override; bool IsDSAttached() const; bool IsNewControlData() const; bool IsFMSAttached() const; bool IsSysActive() const; bool IsBrownedOut() const; Alliance GetAlliance() const; int GetLocation() const; void WaitForData(); double GetMatchTime() const; float GetBatteryVoltage() const; /** Only to be used to tell the Driver Station what code you claim to be * executing for diagnostic purposes only * @param entering If true, starting disabled code; if false, leaving disabled * code */ void InDisabled(bool entering) { m_userInDisabled = entering; } /** Only to be used to tell the Driver Station what code you claim to be * executing for diagnostic purposes only * @param entering If true, starting autonomous code; if false, leaving * autonomous code */ void InAutonomous(bool entering) { m_userInAutonomous = entering; } /** Only to be used to tell the Driver Station what code you claim to be * executing for diagnostic purposes only * @param entering If true, starting teleop code; if false, leaving teleop * code */ void InOperatorControl(bool entering) { m_userInTeleop = entering; } /** Only to be used to tell the Driver Station what code you claim to be * executing for diagnostic purposes only * @param entering If true, starting test code; if false, leaving test code */ void InTest(bool entering) { m_userInTest = entering; } protected: void GetData(); private: DriverStation(); void ReportJoystickUnpluggedError(std::string message); void ReportJoystickUnpluggedWarning(std::string message); void Run(); void UpdateControlWord(bool force, HAL_ControlWord& controlWord) const; std::unique_ptr m_joystickAxes; std::unique_ptr m_joystickPOVs; std::unique_ptr m_joystickButtons; std::unique_ptr m_joystickDescriptor; // Cached Data std::unique_ptr m_joystickAxesCache; std::unique_ptr m_joystickPOVsCache; std::unique_ptr m_joystickButtonsCache; std::unique_ptr m_joystickDescriptorCache; Task m_task; std::atomic m_isRunning{false}; mutable Semaphore m_newControlData{Semaphore::kEmpty}; bool m_updatedControlLoopData = false; std::condition_variable_any m_waitForDataCond; priority_mutex m_waitForDataMutex; mutable priority_mutex m_joystickDataMutex; bool m_userInDisabled = false; bool m_userInAutonomous = false; bool m_userInTeleop = false; bool m_userInTest = false; mutable HAL_ControlWord m_controlWordCache; mutable std::chrono::steady_clock::time_point m_lastControlWordUpdate; mutable priority_mutex m_controlWordMutex; double m_nextMessageTime = 0; };