Now you can download a copy of these docs so you can use them offline! Download now
DriverStation.cpp
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) FIRST 2008. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
5 /*----------------------------------------------------------------------------*/
6 
7 #include "DriverStation.h"
8 #include "AnalogChannel.h"
9 #include "Synchronized.h"
10 #include "Timer.h"
11 #include "NetworkCommunication/FRCComm.h"
12 #include "NetworkCommunication/UsageReporting.h"
13 #include "MotorSafetyHelper.h"
14 #include "Utility.h"
15 #include "WPIErrors.h"
16 #include <strLib.h>
17 
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;
23 DriverStation* DriverStation::m_instance = NULL;
24 uint8_t DriverStation::m_updateNumber = 0;
25 
32  : m_controlData (NULL)
33  , m_digitalOut (0)
34  , m_batteryChannel (NULL)
35  , m_statusDataSemaphore (semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE))
36  , m_task ("DriverStation", (FUNCPTR)DriverStation::InitTask)
37  , m_dashboardHigh(m_statusDataSemaphore)
38  , m_dashboardLow(m_statusDataSemaphore)
39  , m_dashboardInUseHigh(&m_dashboardHigh)
40  , m_dashboardInUseLow(&m_dashboardLow)
41  , m_newControlData(0)
42  , m_packetDataAvailableSem (0)
43  , m_enhancedIO()
44  , m_waitForDataSem(0)
45  , m_approxMatchTimeOffset(-1.0)
46  , m_userInDisabled(false)
47  , m_userInAutonomous(false)
48  , m_userInTeleop(false)
49  , m_userInTest(false)
50 {
51  // Create a new semaphore
52  m_packetDataAvailableSem = semBCreate (SEM_Q_PRIORITY, SEM_EMPTY);
53  m_newControlData = semBCreate (SEM_Q_FIFO, SEM_EMPTY);
54 
55  // Register that semaphore with the network communications task.
56  // It will signal when new packet data is available.
57  setNewDataSem(m_packetDataAvailableSem);
58 
59  m_waitForDataSem = semBCreate (SEM_Q_PRIORITY, SEM_EMPTY);
60 
61  m_controlData = new FRCCommonControlData;
62 
63  // initialize packet number and control words to zero;
64  m_controlData->packetIndex = 0;
65  m_controlData->control = 0;
66 
67  // set all joystick axis values to neutral; buttons to OFF
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;
80 
81  // initialize the analog and digital data.
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;
87 
88  m_batteryChannel = new AnalogChannel(kBatteryModuleNumber, kBatteryChannel);
89 
91 
92  if (!m_task.Start((int32_t)this))
93  {
94  wpi_setWPIError(DriverStationTaskError);
95  }
96 }
97 
98 DriverStation::~DriverStation()
99 {
100  m_task.Stop();
101  semDelete(m_statusDataSemaphore);
102  delete m_batteryChannel;
103  delete m_controlData;
104  m_instance = NULL;
105  semDelete(m_waitForDataSem);
106  // Unregister our semaphore.
107  setNewDataSem(0);
108  semDelete(m_packetDataAvailableSem);
109 }
110 
111 void DriverStation::InitTask(DriverStation *ds)
112 {
113  ds->Run();
114 }
115 
116 void DriverStation::Run()
117 {
118  int period = 0;
119  while (true)
120  {
121  semTake(m_packetDataAvailableSem, WAIT_FOREVER);
122  SetData();
123  m_enhancedIO.UpdateData();
124  GetData();
125  semFlush(m_waitForDataSem);
126  if (++period >= 4)
127  {
129  period = 0;
130  }
131  if (m_userInDisabled)
132  FRC_NetworkCommunication_observeUserProgramDisabled();
133  if (m_userInAutonomous)
134  FRC_NetworkCommunication_observeUserProgramAutonomous();
135  if (m_userInTeleop)
136  FRC_NetworkCommunication_observeUserProgramTeleop();
137  if (m_userInTest)
138  FRC_NetworkCommunication_observeUserProgramTest();
139  }
140 }
141 
146 {
147  if (m_instance == NULL)
148  {
149  m_instance = new DriverStation();
150  }
151  return m_instance;
152 }
153 
160 {
161  static bool lastEnabled = false;
162  getCommonControlData(m_controlData, WAIT_FOREVER);
163  if (!lastEnabled && IsEnabled())
164  {
165  // If starting teleop, assume that autonomous just took up 15 seconds
166  if (IsAutonomous())
167  m_approxMatchTimeOffset = Timer::GetFPGATimestamp();
168  else
169  m_approxMatchTimeOffset = Timer::GetFPGATimestamp() - 15.0;
170  }
171  else if (lastEnabled && !IsEnabled())
172  {
173  m_approxMatchTimeOffset = -1.0;
174  }
175  lastEnabled = IsEnabled();
176  semGive(m_newControlData);
177 }
178 
183 {
184  char *userStatusDataHigh;
185  int32_t userStatusDataHighSize;
186  char *userStatusDataLow;
187  int32_t userStatusDataLowSize;
188 
189  Synchronized sync(m_statusDataSemaphore);
190 
191  m_dashboardInUseHigh->GetStatusBuffer(&userStatusDataHigh, &userStatusDataHighSize);
192  m_dashboardInUseLow->GetStatusBuffer(&userStatusDataLow, &userStatusDataLowSize);
193  setStatusData(GetBatteryVoltage(), m_digitalOut, m_updateNumber,
194  userStatusDataHigh, userStatusDataHighSize, userStatusDataLow, userStatusDataLowSize, WAIT_FOREVER);
195 
196  m_dashboardInUseHigh->Flush();
197  m_dashboardInUseLow->Flush();
198 }
199 
209 {
210  if (m_batteryChannel == NULL)
211  wpi_setWPIError(NullParameter);
212 
213  // The Analog bumper has a voltage divider on the battery source.
214  // Vbatt *--/\/\/\--* Vsample *--/\/\/\--* Gnd
215  // 680 Ohms 1000 Ohms
216  return m_batteryChannel->GetAverageVoltage() * (1680.0 / 1000.0);
217 }
218 
227 float DriverStation::GetStickAxis(uint32_t stick, uint32_t axis)
228 {
229  if (axis < 1 || axis > kJoystickAxes)
230  {
231  wpi_setWPIError(BadJoystickAxis);
232  return 0.0;
233  }
234 
235  int8_t value;
236  switch (stick)
237  {
238  case 1:
239  value = m_controlData->stick0Axes[axis-1];
240  break;
241  case 2:
242  value = m_controlData->stick1Axes[axis-1];
243  break;
244  case 3:
245  value = m_controlData->stick2Axes[axis-1];
246  break;
247  case 4:
248  value = m_controlData->stick3Axes[axis-1];
249  break;
250  default:
251  wpi_setWPIError(BadJoystickIndex);
252  return 0.0;
253  }
254 
255  float result;
256  if (value < 0)
257  result = ((float) value) / 128.0;
258  else
259  result = ((float) value) / 127.0;
260  wpi_assert(result <= 1.0 && result >= -1.0);
261  if (result > 1.0)
262  result = 1.0;
263  else if (result < -1.0)
264  result = -1.0;
265  return result;
266 }
267 
275 short DriverStation::GetStickButtons(uint32_t stick)
276 {
277  if (stick < 1 || stick > 4)
278  wpi_setWPIErrorWithContext(ParameterOutOfRange, "stick must be between 1 and 4");
279 
280  switch (stick)
281  {
282  case 1:
283  return m_controlData->stick0Buttons;
284  case 2:
285  return m_controlData->stick1Buttons;
286  case 3:
287  return m_controlData->stick2Buttons;
288  case 4:
289  return m_controlData->stick3Buttons;
290  }
291  return 0;
292 }
293 
294 // 5V divided by 10 bits
295 #define kDSAnalogInScaling ((float)(5.0 / 1023.0))
296 
306 float DriverStation::GetAnalogIn(uint32_t channel)
307 {
308  if (channel < 1 || channel > 4)
309  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 4");
310 
311  static uint8_t reported_mask = 0;
312  if (!(reported_mask & (1 >> channel)))
313  {
314  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationCIO, channel, nUsageReporting::kDriverStationCIO_Analog);
315  reported_mask |= (1 >> channel);
316  }
317 
318  switch (channel)
319  {
320  case 1:
321  return kDSAnalogInScaling * m_controlData->analog1;
322  case 2:
323  return kDSAnalogInScaling * m_controlData->analog2;
324  case 3:
325  return kDSAnalogInScaling * m_controlData->analog3;
326  case 4:
327  return kDSAnalogInScaling * m_controlData->analog4;
328  }
329  return 0.0;
330 }
331 
338 bool DriverStation::GetDigitalIn(uint32_t channel)
339 {
340  if (channel < 1 || channel > 8)
341  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 8");
342 
343  static uint8_t reported_mask = 0;
344  if (!(reported_mask & (1 >> channel)))
345  {
346  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationCIO, channel, nUsageReporting::kDriverStationCIO_DigitalIn);
347  reported_mask |= (1 >> channel);
348  }
349 
350  return ((m_controlData->dsDigitalIn >> (channel-1)) & 0x1) ? true : false;
351 }
352 
362 void DriverStation::SetDigitalOut(uint32_t channel, bool value)
363 {
364  if (channel < 1 || channel > 8)
365  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 8");
366 
367  static uint8_t reported_mask = 0;
368  if (!(reported_mask & (1 >> channel)))
369  {
370  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationCIO, channel, nUsageReporting::kDriverStationCIO_DigitalOut);
371  reported_mask |= (1 >> channel);
372  }
373 
374  m_digitalOut &= ~(0x1 << (channel-1));
375  m_digitalOut |= ((uint8_t)value << (channel-1));
376 }
377 
383 bool DriverStation::GetDigitalOut(uint32_t channel)
384 {
385  if (channel < 1 || channel > 8)
386  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 8");
387 
388  return ((m_digitalOut >> (channel-1)) & 0x1) ? true : false;;
389 }
390 
391 bool DriverStation::IsEnabled()
392 {
393  return m_controlData->enabled;
394 }
395 
396 bool DriverStation::IsDisabled()
397 {
398  return !m_controlData->enabled;
399 }
400 
401 bool DriverStation::IsAutonomous()
402 {
403  return m_controlData->autonomous;
404 }
405 
406 bool DriverStation::IsOperatorControl()
407 {
408  return !(m_controlData->autonomous || m_controlData->test);
409 }
410 
411 bool DriverStation::IsTest()
412 {
413  return m_controlData->test;
414 }
415 
423 {
424  return semTake(m_newControlData, NO_WAIT) == 0;
425 }
426 
433 {
434  return m_controlData->fmsAttached;
435 }
436 
444 {
445  return m_controlData->packetIndex;
446 }
447 
453 DriverStation::Alliance DriverStation::GetAlliance()
454 {
455  if (m_controlData->dsID_Alliance == 'R') return kRed;
456  if (m_controlData->dsID_Alliance == 'B') return kBlue;
457  wpi_assert(false);
458  return kInvalid;
459 }
460 
467 {
468  wpi_assert ((m_controlData->dsID_Position >= '1') && (m_controlData->dsID_Position <= '3'));
469  return m_controlData->dsID_Position - '0';
470 }
471 
478 {
479  semTake(m_waitForDataSem, WAIT_FOREVER);
480 }
481 
493 {
494  if (m_approxMatchTimeOffset < 0.0)
495  return 0.0;
496  return Timer::GetFPGATimestamp() - m_approxMatchTimeOffset;
497 }
498 
504 {
505  return m_controlData->teamID;
506 }
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)
Definition: Task.cpp:52
bool IsNewControlData()
float GetAnalogIn(uint32_t channel)
bool GetDigitalIn(uint32_t channel)
uint32_t GetPacketNumber()
Alliance GetAlliance()
float GetAverageVoltage()
uint16_t GetTeamNumber()
bool GetDigitalOut(uint32_t channel)
void SetDigitalOut(uint32_t channel, bool value)
bool Stop()
Definition: Task.cpp:81
static DriverStation * GetInstance()
double GetMatchTime()
static void CheckMotors()
void AddToSingletonList()
Definition: SensorBase.cpp:47
uint32_t GetLocation()
short GetStickButtons(uint32_t stick)
float GetBatteryVoltage()
float GetStickAxis(uint32_t stick, uint32_t axis)

Generated on Sat Apr 26 2014 12:26:45 for WPILibC++ by doxygen 1.8.6