Now you can download a copy of these docs so you can use them offline! Download now
DriverStation.cpp
00001 /*----------------------------------------------------------------------------*/ 00002 /* Copyright (c) FIRST 2008. All Rights Reserved. */ 00003 /* Open Source Software - may be modified and shared by FRC teams. The code */ 00004 /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */ 00005 /*----------------------------------------------------------------------------*/ 00006 00007 #include "DriverStation.h" 00008 #include "AnalogChannel.h" 00009 #include "Synchronized.h" 00010 #include "Timer.h" 00011 #include "NetworkCommunication/FRCComm.h" 00012 #include "MotorSafetyHelper.h" 00013 #include "Utility.h" 00014 #include "WPIErrors.h" 00015 #include <strLib.h> 00016 00017 const UINT32 DriverStation::kBatteryModuleNumber; 00018 const UINT32 DriverStation::kBatteryChannel; 00019 const UINT32 DriverStation::kJoystickPorts; 00020 const UINT32 DriverStation::kJoystickAxes; 00021 const float DriverStation::kUpdatePeriod; 00022 DriverStation* DriverStation::m_instance = NULL; 00023 UINT8 DriverStation::m_updateNumber = 0; 00024 00030 DriverStation::DriverStation() 00031 : m_controlData (NULL) 00032 , m_digitalOut (0) 00033 , m_batteryChannel (NULL) 00034 , m_statusDataSemaphore (semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE)) 00035 , m_task ("DriverStation", (FUNCPTR)DriverStation::InitTask) 00036 , m_dashboardHigh(m_statusDataSemaphore) 00037 , m_dashboardLow(m_statusDataSemaphore) 00038 , m_dashboardInUseHigh(&m_dashboardHigh) 00039 , m_dashboardInUseLow(&m_dashboardLow) 00040 , m_newControlData (false) 00041 , m_packetDataAvailableSem (0) 00042 , m_enhancedIO() 00043 , m_waitForDataSem(0) 00044 , m_approxMatchTimeOffset(-1.0) 00045 , m_userInDisabled(false) 00046 , m_userInAutonomous(false) 00047 , m_userInTeleop(false) 00048 { 00049 // Create a new semaphore 00050 m_packetDataAvailableSem = semBCreate (SEM_Q_PRIORITY, SEM_EMPTY); 00051 00052 // Register that semaphore with the network communications task. 00053 // It will signal when new packet data is available. 00054 setNewDataSem(m_packetDataAvailableSem); 00055 00056 m_waitForDataSem = semBCreate (SEM_Q_PRIORITY, SEM_EMPTY); 00057 00058 m_controlData = new FRCCommonControlData; 00059 00060 // initialize packet number and control words to zero; 00061 m_controlData->packetIndex = 0; 00062 m_controlData->control = 0; 00063 00064 // set all joystick axis values to neutral; buttons to OFF 00065 m_controlData->stick0Axis1 = m_controlData->stick0Axis2 = m_controlData->stick0Axis3 = 0; 00066 m_controlData->stick1Axis1 = m_controlData->stick1Axis2 = m_controlData->stick1Axis3 = 0; 00067 m_controlData->stick2Axis1 = m_controlData->stick2Axis2 = m_controlData->stick2Axis3 = 0; 00068 m_controlData->stick3Axis1 = m_controlData->stick3Axis2 = m_controlData->stick3Axis3 = 0; 00069 m_controlData->stick0Axis4 = m_controlData->stick0Axis5 = m_controlData->stick0Axis6 = 0; 00070 m_controlData->stick1Axis4 = m_controlData->stick1Axis5 = m_controlData->stick1Axis6 = 0; 00071 m_controlData->stick2Axis4 = m_controlData->stick2Axis5 = m_controlData->stick2Axis6 = 0; 00072 m_controlData->stick3Axis4 = m_controlData->stick3Axis5 = m_controlData->stick3Axis6 = 0; 00073 m_controlData->stick0Buttons = 0; 00074 m_controlData->stick1Buttons = 0; 00075 m_controlData->stick2Buttons = 0; 00076 m_controlData->stick3Buttons = 0; 00077 00078 // initialize the analog and digital data. 00079 m_controlData->analog1 = 0; 00080 m_controlData->analog2 = 0; 00081 m_controlData->analog3 = 0; 00082 m_controlData->analog4 = 0; 00083 m_controlData->dsDigitalIn = 0; 00084 00085 m_batteryChannel = new AnalogChannel(kBatteryModuleNumber, kBatteryChannel); 00086 00087 AddToSingletonList(); 00088 00089 if (!m_task.Start((INT32)this)) 00090 { 00091 wpi_setWPIError(DriverStationTaskError); 00092 } 00093 } 00094 00095 DriverStation::~DriverStation() 00096 { 00097 m_task.Stop(); 00098 semDelete(m_statusDataSemaphore); 00099 delete m_batteryChannel; 00100 delete m_controlData; 00101 m_instance = NULL; 00102 semDelete(m_waitForDataSem); 00103 // Unregister our semaphore. 00104 setNewDataSem(0); 00105 semDelete(m_packetDataAvailableSem); 00106 } 00107 00108 void DriverStation::InitTask(DriverStation *ds) 00109 { 00110 ds->Run(); 00111 } 00112 00113 void DriverStation::Run() 00114 { 00115 int period = 0; 00116 while (true) 00117 { 00118 semTake(m_packetDataAvailableSem, WAIT_FOREVER); 00119 SetData(); 00120 m_enhancedIO.UpdateData(); 00121 GetData(); 00122 semFlush(m_waitForDataSem); 00123 if (++period >= 4) 00124 { 00125 MotorSafetyHelper::CheckMotors(); 00126 period = 0; 00127 } 00128 if (m_userInDisabled) 00129 FRC_NetworkCommunication_observeUserProgramDisabled(); 00130 if (m_userInAutonomous) 00131 FRC_NetworkCommunication_observeUserProgramAutonomous(); 00132 if (m_userInTeleop) 00133 FRC_NetworkCommunication_observeUserProgramTeleop(); 00134 } 00135 } 00136 00140 DriverStation* DriverStation::GetInstance() 00141 { 00142 if (m_instance == NULL) 00143 { 00144 m_instance = new DriverStation(); 00145 } 00146 return m_instance; 00147 } 00148 00154 void DriverStation::GetData() 00155 { 00156 static bool lastEnabled = false; 00157 getCommonControlData(m_controlData, WAIT_FOREVER); 00158 if (!lastEnabled && IsEnabled()) 00159 { 00160 // If starting teleop, assume that autonomous just took up 15 seconds 00161 if (IsAutonomous()) 00162 m_approxMatchTimeOffset = Timer::GetFPGATimestamp(); 00163 else 00164 m_approxMatchTimeOffset = Timer::GetFPGATimestamp() - 15.0; 00165 } 00166 else if (lastEnabled && !IsEnabled()) 00167 { 00168 m_approxMatchTimeOffset = -1.0; 00169 } 00170 lastEnabled = IsEnabled(); 00171 m_newControlData = true; 00172 } 00173 00177 void DriverStation::SetData() 00178 { 00179 char *userStatusDataHigh; 00180 INT32 userStatusDataHighSize; 00181 char *userStatusDataLow; 00182 INT32 userStatusDataLowSize; 00183 00184 Synchronized sync(m_statusDataSemaphore); 00185 00186 m_dashboardInUseHigh->GetStatusBuffer(&userStatusDataHigh, &userStatusDataHighSize); 00187 m_dashboardInUseLow->GetStatusBuffer(&userStatusDataLow, &userStatusDataLowSize); 00188 setStatusData(GetBatteryVoltage(), m_digitalOut, m_updateNumber, 00189 userStatusDataHigh, userStatusDataHighSize, userStatusDataLow, userStatusDataLowSize, WAIT_FOREVER); 00190 00191 m_dashboardInUseHigh->Flush(); 00192 m_dashboardInUseLow->Flush(); 00193 } 00194 00203 float DriverStation::GetBatteryVoltage() 00204 { 00205 if (m_batteryChannel == NULL) 00206 wpi_setWPIError(NullParameter); 00207 00208 // The Analog bumper has a voltage divider on the battery source. 00209 // Vbatt *--/\/\/\--* Vsample *--/\/\/\--* Gnd 00210 // 680 Ohms 1000 Ohms 00211 return m_batteryChannel->GetAverageVoltage() * (1680.0 / 1000.0); 00212 } 00213 00222 float DriverStation::GetStickAxis(UINT32 stick, UINT32 axis) 00223 { 00224 if (axis < 1 || axis > kJoystickAxes) 00225 { 00226 wpi_setWPIError(BadJoystickAxis); 00227 return 0.0; 00228 } 00229 00230 INT8 value; 00231 switch (stick) 00232 { 00233 case 1: 00234 value = m_controlData->stick0Axes[axis-1]; 00235 break; 00236 case 2: 00237 value = m_controlData->stick1Axes[axis-1]; 00238 break; 00239 case 3: 00240 value = m_controlData->stick2Axes[axis-1]; 00241 break; 00242 case 4: 00243 value = m_controlData->stick3Axes[axis-1]; 00244 break; 00245 default: 00246 wpi_setWPIError(BadJoystickIndex); 00247 return 0.0; 00248 } 00249 00250 float result; 00251 if (value < 0) 00252 result = ((float) value) / 128.0; 00253 else 00254 result = ((float) value) / 127.0; 00255 wpi_assert(result <= 1.0 && result >= -1.0); 00256 if (result > 1.0) 00257 result = 1.0; 00258 else if (result < -1.0) 00259 result = -1.0; 00260 return result; 00261 } 00262 00270 short DriverStation::GetStickButtons(UINT32 stick) 00271 { 00272 if (stick < 1 || stick > 4) 00273 wpi_setWPIErrorWithContext(ParameterOutOfRange, "stick must be between 1 and 4"); 00274 00275 switch (stick) 00276 { 00277 case 1: 00278 return m_controlData->stick0Buttons; 00279 case 2: 00280 return m_controlData->stick1Buttons; 00281 case 3: 00282 return m_controlData->stick2Buttons; 00283 case 4: 00284 return m_controlData->stick3Buttons; 00285 } 00286 return 0; 00287 } 00288 00289 // 5V divided by 10 bits 00290 #define kDSAnalogInScaling ((float)(5.0 / 1023.0)) 00291 00301 float DriverStation::GetAnalogIn(UINT32 channel) 00302 { 00303 if (channel < 1 || channel > 4) 00304 wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 4"); 00305 00306 switch (channel) 00307 { 00308 case 1: 00309 return kDSAnalogInScaling * m_controlData->analog1; 00310 case 2: 00311 return kDSAnalogInScaling * m_controlData->analog2; 00312 case 3: 00313 return kDSAnalogInScaling * m_controlData->analog3; 00314 case 4: 00315 return kDSAnalogInScaling * m_controlData->analog4; 00316 } 00317 return 0.0; 00318 } 00319 00326 bool DriverStation::GetDigitalIn(UINT32 channel) 00327 { 00328 if (channel < 1 || channel > 8) 00329 wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 8"); 00330 00331 return ((m_controlData->dsDigitalIn >> (channel-1)) & 0x1) ? true : false; 00332 } 00333 00343 void DriverStation::SetDigitalOut(UINT32 channel, bool value) 00344 { 00345 if (channel < 1 || channel > 8) 00346 wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 8"); 00347 00348 m_digitalOut &= ~(0x1 << (channel-1)); 00349 m_digitalOut |= ((UINT8)value << (channel-1)); 00350 } 00351 00357 bool DriverStation::GetDigitalOut(UINT32 channel) 00358 { 00359 if (channel < 1 || channel > 8) 00360 wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 8"); 00361 00362 return ((m_digitalOut >> (channel-1)) & 0x1) ? true : false;; 00363 } 00364 00365 bool DriverStation::IsEnabled() 00366 { 00367 return m_controlData->enabled; 00368 } 00369 00370 bool DriverStation::IsDisabled() 00371 { 00372 return !m_controlData->enabled; 00373 } 00374 00375 bool DriverStation::IsAutonomous() 00376 { 00377 return m_controlData->autonomous; 00378 } 00379 00380 bool DriverStation::IsOperatorControl() 00381 { 00382 return !m_controlData->autonomous; 00383 } 00384 00391 bool DriverStation::IsNewControlData() 00392 { 00393 bool newData = m_newControlData; 00394 m_newControlData = false; 00395 return newData; 00396 } 00397 00403 bool DriverStation::IsFMSAttached() 00404 { 00405 return m_controlData->fmsAttached; 00406 } 00407 00414 UINT32 DriverStation::GetPacketNumber() 00415 { 00416 return m_controlData->packetIndex; 00417 } 00418 00424 DriverStation::Alliance DriverStation::GetAlliance() 00425 { 00426 if (m_controlData->dsID_Alliance == 'R') return kRed; 00427 if (m_controlData->dsID_Alliance == 'B') return kBlue; 00428 wpi_assert(false); 00429 return kInvalid; 00430 } 00431 00437 UINT32 DriverStation::GetLocation() 00438 { 00439 wpi_assert ((m_controlData->dsID_Position >= '1') && (m_controlData->dsID_Position <= '3')); 00440 return m_controlData->dsID_Position - '0'; 00441 } 00442 00448 void DriverStation::WaitForData() 00449 { 00450 semTake(m_waitForDataSem, WAIT_FOREVER); 00451 } 00452 00463 double DriverStation::GetMatchTime() 00464 { 00465 if (m_approxMatchTimeOffset < 0.0) 00466 return 0.0; 00467 return Timer::GetFPGATimestamp() - m_approxMatchTimeOffset; 00468 } 00469 00474 UINT16 DriverStation::GetTeamNumber() 00475 { 00476 return m_controlData->teamID; 00477 }
Generated on Thu Jan 12 2012 22:35:19 for WPILibC++ by
1.7.1