7 #include "DriverStation.h"
8 #include "AnalogChannel.h"
9 #include "Synchronized.h"
11 #include "NetworkCommunication/FRCComm.h"
12 #include "NetworkCommunication/UsageReporting.h"
13 #include "MotorSafetyHelper.h"
15 #include "WPIErrors.h"
18 const uint32_t DriverStation::kBatteryModuleNumber;
19 const uint32_t DriverStation::kBatteryChannel;
20 const uint32_t DriverStation::kJoystickPorts;
21 const uint32_t DriverStation::kJoystickAxes;
22 constexpr
float DriverStation::kUpdatePeriod;
24 uint8_t DriverStation::m_updateNumber = 0;
32 : m_controlData (NULL)
34 , m_batteryChannel (NULL)
35 , m_statusDataSemaphore (semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE))
37 , m_dashboardHigh(m_statusDataSemaphore)
38 , m_dashboardLow(m_statusDataSemaphore)
39 , m_dashboardInUseHigh(&m_dashboardHigh)
40 , m_dashboardInUseLow(&m_dashboardLow)
42 , m_packetDataAvailableSem (0)
45 , m_approxMatchTimeOffset(-1.0)
46 , m_userInDisabled(false)
47 , m_userInAutonomous(false)
48 , m_userInTeleop(false)
52 m_packetDataAvailableSem = semBCreate (SEM_Q_PRIORITY, SEM_EMPTY);
53 m_newControlData = semBCreate (SEM_Q_FIFO, SEM_EMPTY);
57 setNewDataSem(m_packetDataAvailableSem);
59 m_waitForDataSem = semBCreate (SEM_Q_PRIORITY, SEM_EMPTY);
61 m_controlData =
new FRCCommonControlData;
64 m_controlData->packetIndex = 0;
65 m_controlData->control = 0;
68 m_controlData->stick0Axis1 = m_controlData->stick0Axis2 = m_controlData->stick0Axis3 = 0;
69 m_controlData->stick1Axis1 = m_controlData->stick1Axis2 = m_controlData->stick1Axis3 = 0;
70 m_controlData->stick2Axis1 = m_controlData->stick2Axis2 = m_controlData->stick2Axis3 = 0;
71 m_controlData->stick3Axis1 = m_controlData->stick3Axis2 = m_controlData->stick3Axis3 = 0;
72 m_controlData->stick0Axis4 = m_controlData->stick0Axis5 = m_controlData->stick0Axis6 = 0;
73 m_controlData->stick1Axis4 = m_controlData->stick1Axis5 = m_controlData->stick1Axis6 = 0;
74 m_controlData->stick2Axis4 = m_controlData->stick2Axis5 = m_controlData->stick2Axis6 = 0;
75 m_controlData->stick3Axis4 = m_controlData->stick3Axis5 = m_controlData->stick3Axis6 = 0;
76 m_controlData->stick0Buttons = 0;
77 m_controlData->stick1Buttons = 0;
78 m_controlData->stick2Buttons = 0;
79 m_controlData->stick3Buttons = 0;
82 m_controlData->analog1 = 0;
83 m_controlData->analog2 = 0;
84 m_controlData->analog3 = 0;
85 m_controlData->analog4 = 0;
86 m_controlData->dsDigitalIn = 0;
88 m_batteryChannel =
new AnalogChannel(kBatteryModuleNumber, kBatteryChannel);
92 if (!m_task.
Start((int32_t)
this))
94 wpi_setWPIError(DriverStationTaskError);
98 DriverStation::~DriverStation()
101 semDelete(m_statusDataSemaphore);
102 delete m_batteryChannel;
103 delete m_controlData;
105 semDelete(m_waitForDataSem);
108 semDelete(m_packetDataAvailableSem);
116 void DriverStation::Run()
121 semTake(m_packetDataAvailableSem, WAIT_FOREVER);
123 m_enhancedIO.UpdateData();
125 semFlush(m_waitForDataSem);
131 if (m_userInDisabled)
132 FRC_NetworkCommunication_observeUserProgramDisabled();
133 if (m_userInAutonomous)
134 FRC_NetworkCommunication_observeUserProgramAutonomous();
136 FRC_NetworkCommunication_observeUserProgramTeleop();
138 FRC_NetworkCommunication_observeUserProgramTest();
147 if (m_instance == NULL)
161 static bool lastEnabled =
false;
162 getCommonControlData(m_controlData, WAIT_FOREVER);
163 if (!lastEnabled && IsEnabled())
167 m_approxMatchTimeOffset = Timer::GetFPGATimestamp();
169 m_approxMatchTimeOffset = Timer::GetFPGATimestamp() - 15.0;
171 else if (lastEnabled && !IsEnabled())
173 m_approxMatchTimeOffset = -1.0;
175 lastEnabled = IsEnabled();
176 semGive(m_newControlData);
184 char *userStatusDataHigh;
185 int32_t userStatusDataHighSize;
186 char *userStatusDataLow;
187 int32_t userStatusDataLowSize;
191 m_dashboardInUseHigh->GetStatusBuffer(&userStatusDataHigh, &userStatusDataHighSize);
192 m_dashboardInUseLow->GetStatusBuffer(&userStatusDataLow, &userStatusDataLowSize);
194 userStatusDataHigh, userStatusDataHighSize, userStatusDataLow, userStatusDataLowSize, WAIT_FOREVER);
196 m_dashboardInUseHigh->Flush();
197 m_dashboardInUseLow->Flush();
210 if (m_batteryChannel == NULL)
211 wpi_setWPIError(NullParameter);
229 if (axis < 1 || axis > kJoystickAxes)
231 wpi_setWPIError(BadJoystickAxis);
239 value = m_controlData->stick0Axes[axis-1];
242 value = m_controlData->stick1Axes[axis-1];
245 value = m_controlData->stick2Axes[axis-1];
248 value = m_controlData->stick3Axes[axis-1];
251 wpi_setWPIError(BadJoystickIndex);
257 result = ((float) value) / 128.0;
259 result = ((float) value) / 127.0;
260 wpi_assert(result <= 1.0 && result >= -1.0);
263 else if (result < -1.0)
277 if (stick < 1 || stick > 4)
278 wpi_setWPIErrorWithContext(ParameterOutOfRange,
"stick must be between 1 and 4");
283 return m_controlData->stick0Buttons;
285 return m_controlData->stick1Buttons;
287 return m_controlData->stick2Buttons;
289 return m_controlData->stick3Buttons;
295 #define kDSAnalogInScaling ((float)(5.0 / 1023.0))
308 if (channel < 1 || channel > 4)
309 wpi_setWPIErrorWithContext(ParameterOutOfRange,
"channel must be between 1 and 4");
311 static uint8_t reported_mask = 0;
312 if (!(reported_mask & (1 >> channel)))
314 nUsageReporting::report(nUsageReporting::kResourceType_DriverStationCIO, channel, nUsageReporting::kDriverStationCIO_Analog);
315 reported_mask |= (1 >> channel);
321 return kDSAnalogInScaling * m_controlData->analog1;
323 return kDSAnalogInScaling * m_controlData->analog2;
325 return kDSAnalogInScaling * m_controlData->analog3;
327 return kDSAnalogInScaling * m_controlData->analog4;
340 if (channel < 1 || channel > 8)
341 wpi_setWPIErrorWithContext(ParameterOutOfRange,
"channel must be between 1 and 8");
343 static uint8_t reported_mask = 0;
344 if (!(reported_mask & (1 >> channel)))
346 nUsageReporting::report(nUsageReporting::kResourceType_DriverStationCIO, channel, nUsageReporting::kDriverStationCIO_DigitalIn);
347 reported_mask |= (1 >> channel);
350 return ((m_controlData->dsDigitalIn >> (channel-1)) & 0x1) ?
true :
false;
364 if (channel < 1 || channel > 8)
365 wpi_setWPIErrorWithContext(ParameterOutOfRange,
"channel must be between 1 and 8");
367 static uint8_t reported_mask = 0;
368 if (!(reported_mask & (1 >> channel)))
370 nUsageReporting::report(nUsageReporting::kResourceType_DriverStationCIO, channel, nUsageReporting::kDriverStationCIO_DigitalOut);
371 reported_mask |= (1 >> channel);
374 m_digitalOut &= ~(0x1 << (channel-1));
375 m_digitalOut |= ((uint8_t)value << (channel-1));
385 if (channel < 1 || channel > 8)
386 wpi_setWPIErrorWithContext(ParameterOutOfRange,
"channel must be between 1 and 8");
388 return ((m_digitalOut >> (channel-1)) & 0x1) ?
true :
false;;
391 bool DriverStation::IsEnabled()
393 return m_controlData->enabled;
396 bool DriverStation::IsDisabled()
398 return !m_controlData->enabled;
401 bool DriverStation::IsAutonomous()
403 return m_controlData->autonomous;
406 bool DriverStation::IsOperatorControl()
408 return !(m_controlData->autonomous || m_controlData->test);
411 bool DriverStation::IsTest()
413 return m_controlData->test;
424 return semTake(m_newControlData, NO_WAIT) == 0;
434 return m_controlData->fmsAttached;
445 return m_controlData->packetIndex;
455 if (m_controlData->dsID_Alliance ==
'R')
return kRed;
456 if (m_controlData->dsID_Alliance ==
'B')
return kBlue;
468 wpi_assert ((m_controlData->dsID_Position >=
'1') && (m_controlData->dsID_Position <=
'3'));
469 return m_controlData->dsID_Position -
'0';
479 semTake(m_waitForDataSem, WAIT_FOREVER);
494 if (m_approxMatchTimeOffset < 0.0)
496 return Timer::GetFPGATimestamp() - m_approxMatchTimeOffset;
505 return m_controlData->teamID;
bool Start(uint32_t arg0=0, uint32_t arg1=0, uint32_t arg2=0, uint32_t arg3=0, uint32_t arg4=0, uint32_t arg5=0, uint32_t arg6=0, uint32_t arg7=0, uint32_t arg8=0, uint32_t arg9=0)
float GetAnalogIn(uint32_t channel)
bool GetDigitalIn(uint32_t channel)
uint32_t GetPacketNumber()
float GetAverageVoltage()
bool GetDigitalOut(uint32_t channel)
void SetDigitalOut(uint32_t channel, bool value)
static DriverStation * GetInstance()
static void CheckMotors()
void AddToSingletonList()
short GetStickButtons(uint32_t stick)
float GetBatteryVoltage()
float GetStickAxis(uint32_t stick, uint32_t axis)