Now you can download a copy of these docs so you can use them offline! Download now
Encoder.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 "Encoder.h" 00008 #include "DigitalInput.h" 00009 #include "Resource.h" 00010 #include "WPIErrors.h" 00011 00012 static Resource *quadEncoders = NULL; 00013 00024 void Encoder::InitEncoder(bool reverseDirection, EncodingType encodingType) 00025 { 00026 m_encodingType = encodingType; 00027 tRioStatusCode localStatus = NiFpga_Status_Success; 00028 switch (encodingType) 00029 { 00030 case k4X: 00031 Resource::CreateResourceObject(&quadEncoders, tEncoder::kNumSystems); 00032 UINT32 index = quadEncoders->Allocate("4X Encoder"); 00033 if (index == ~0ul) 00034 { 00035 CloneError(quadEncoders); 00036 return; 00037 } 00038 if (m_aSource->StatusIsFatal()) 00039 { 00040 CloneError(m_aSource); 00041 return; 00042 } 00043 if (m_bSource->StatusIsFatal()) 00044 { 00045 CloneError(m_bSource); 00046 return; 00047 } 00048 m_index = index; 00049 m_encoder = tEncoder::create(m_index, &localStatus); 00050 m_encoder->writeConfig_ASource_Module(m_aSource->GetModuleForRouting(), &localStatus); 00051 m_encoder->writeConfig_ASource_Channel(m_aSource->GetChannelForRouting(), &localStatus); 00052 m_encoder->writeConfig_ASource_AnalogTrigger(m_aSource->GetAnalogTriggerForRouting(), &localStatus); 00053 m_encoder->writeConfig_BSource_Module(m_bSource->GetModuleForRouting(), &localStatus); 00054 m_encoder->writeConfig_BSource_Channel(m_bSource->GetChannelForRouting(), &localStatus); 00055 m_encoder->writeConfig_BSource_AnalogTrigger(m_bSource->GetAnalogTriggerForRouting(), &localStatus); 00056 m_encoder->strobeReset(&localStatus); 00057 m_encoder->writeConfig_Reverse(reverseDirection, &localStatus); 00058 m_encoder->writeTimerConfig_AverageSize(4, &localStatus); 00059 m_counter = NULL; 00060 break; 00061 case k1X: 00062 case k2X: 00063 m_counter = new Counter(m_encodingType, m_aSource, m_bSource, reverseDirection); 00064 break; 00065 } 00066 m_distancePerPulse = 1.0; 00067 m_pidSource = kDistance; 00068 wpi_setError(localStatus); 00069 } 00070 00086 Encoder::Encoder(UINT8 aModuleNumber, UINT32 aChannel, 00087 UINT8 bModuleNumber, UINT32 bChannel, 00088 bool reverseDirection, EncodingType encodingType) : 00089 m_encoder(NULL), 00090 m_counter(NULL) 00091 { 00092 m_aSource = new DigitalInput(aModuleNumber, aChannel); 00093 m_bSource = new DigitalInput(bModuleNumber, bChannel); 00094 InitEncoder(reverseDirection, encodingType); 00095 m_allocatedASource = true; 00096 m_allocatedBSource = true; 00097 } 00098 00112 Encoder::Encoder(UINT32 aChannel, UINT32 bChannel, bool reverseDirection, EncodingType encodingType) : 00113 m_encoder(NULL), 00114 m_counter(NULL) 00115 { 00116 m_aSource = new DigitalInput(aChannel); 00117 m_bSource = new DigitalInput(bChannel); 00118 InitEncoder(reverseDirection, encodingType); 00119 m_allocatedASource = true; 00120 m_allocatedBSource = true; 00121 } 00122 00138 Encoder::Encoder(DigitalSource *aSource, DigitalSource *bSource, bool reverseDirection, EncodingType encodingType) : 00139 m_encoder(NULL), 00140 m_counter(NULL) 00141 { 00142 m_aSource = aSource; 00143 m_bSource = bSource; 00144 m_allocatedASource = false; 00145 m_allocatedBSource = false; 00146 if (m_aSource == NULL || m_bSource == NULL) 00147 wpi_setWPIError(NullParameter); 00148 else 00149 InitEncoder(reverseDirection, encodingType); 00150 } 00151 00167 Encoder::Encoder(DigitalSource &aSource, DigitalSource &bSource, bool reverseDirection, EncodingType encodingType) : 00168 m_encoder(NULL), 00169 m_counter(NULL) 00170 { 00171 m_aSource = &aSource; 00172 m_bSource = &bSource; 00173 m_allocatedASource = false; 00174 m_allocatedBSource = false; 00175 InitEncoder(reverseDirection, encodingType); 00176 } 00177 00182 Encoder::~Encoder() 00183 { 00184 if (m_allocatedASource) delete m_aSource; 00185 if (m_allocatedBSource) delete m_bSource; 00186 if (m_counter) 00187 { 00188 delete m_counter; 00189 } 00190 else 00191 { 00192 quadEncoders->Free(m_index); 00193 delete m_encoder; 00194 } 00195 } 00196 00201 void Encoder::Start() 00202 { 00203 if (StatusIsFatal()) return; 00204 if (m_counter) 00205 m_counter->Start(); 00206 else 00207 { 00208 tRioStatusCode localStatus = NiFpga_Status_Success; 00209 m_encoder->writeConfig_Enable(1, &localStatus); 00210 wpi_setError(localStatus); 00211 } 00212 } 00213 00217 void Encoder::Stop() 00218 { 00219 if (StatusIsFatal()) return; 00220 if (m_counter) 00221 m_counter->Stop(); 00222 else 00223 { 00224 tRioStatusCode localStatus = NiFpga_Status_Success; 00225 m_encoder->writeConfig_Enable(0, &localStatus); 00226 wpi_setError(localStatus); 00227 } 00228 } 00229 00236 INT32 Encoder::GetRaw() 00237 { 00238 if (StatusIsFatal()) return 0; 00239 INT32 value; 00240 if (m_counter) 00241 value = m_counter->Get(); 00242 else 00243 { 00244 tRioStatusCode localStatus = NiFpga_Status_Success; 00245 value = m_encoder->readOutput_Value(&localStatus); 00246 wpi_setError(localStatus); 00247 } 00248 return value; 00249 } 00250 00258 INT32 Encoder::Get() 00259 { 00260 if (StatusIsFatal()) return 0; 00261 return (INT32) (GetRaw() * DecodingScaleFactor()); 00262 } 00263 00268 void Encoder::Reset() 00269 { 00270 if (StatusIsFatal()) return; 00271 if (m_counter) 00272 m_counter->Reset(); 00273 else 00274 { 00275 tRioStatusCode localStatus = NiFpga_Status_Success; 00276 m_encoder->strobeReset(&localStatus); 00277 wpi_setError(localStatus); 00278 } 00279 } 00280 00290 double Encoder::GetPeriod() 00291 { 00292 if (StatusIsFatal()) return 0.0; 00293 double measuredPeriod; 00294 if (m_counter) 00295 { 00296 measuredPeriod = m_counter->GetPeriod(); 00297 } 00298 else 00299 { 00300 tRioStatusCode localStatus = NiFpga_Status_Success; 00301 tEncoder::tTimerOutput output = m_encoder->readTimerOutput(&localStatus); 00302 double value; 00303 if (output.Stalled) 00304 { 00305 // Return infinity 00306 double zero = 0.0; 00307 value = 1.0 / zero; 00308 } 00309 else 00310 { 00311 // output.Period is a fixed point number that counts by 2 (24 bits, 25 integer bits) 00312 value = (double)(output.Period << 1) / (double)output.Count; 00313 } 00314 wpi_setError(localStatus); 00315 measuredPeriod = value * 1.0e-6; 00316 } 00317 return measuredPeriod / DecodingScaleFactor(); 00318 } 00319 00332 void Encoder::SetMaxPeriod(double maxPeriod) 00333 { 00334 if (StatusIsFatal()) return; 00335 if (m_counter) 00336 { 00337 m_counter->SetMaxPeriod(maxPeriod * DecodingScaleFactor()); 00338 } 00339 else 00340 { 00341 tRioStatusCode localStatus = NiFpga_Status_Success; 00342 m_encoder->writeTimerConfig_StallPeriod((UINT32)(maxPeriod * 1.0e6 * DecodingScaleFactor()), &localStatus); 00343 wpi_setError(localStatus); 00344 } 00345 } 00346 00354 bool Encoder::GetStopped() 00355 { 00356 if (StatusIsFatal()) return true; 00357 if (m_counter) 00358 { 00359 return m_counter->GetStopped(); 00360 } 00361 else 00362 { 00363 tRioStatusCode localStatus = NiFpga_Status_Success; 00364 bool value = m_encoder->readTimerOutput_Stalled(&localStatus) != 0; 00365 wpi_setError(localStatus); 00366 return value; 00367 } 00368 } 00369 00374 bool Encoder::GetDirection() 00375 { 00376 if (StatusIsFatal()) return false; 00377 if (m_counter) 00378 { 00379 return m_counter->GetDirection(); 00380 } 00381 else 00382 { 00383 tRioStatusCode localStatus = NiFpga_Status_Success; 00384 bool value = m_encoder->readOutput_Direction(&localStatus); 00385 wpi_setError(localStatus); 00386 return value; 00387 } 00388 } 00389 00393 double Encoder::DecodingScaleFactor() 00394 { 00395 if (StatusIsFatal()) return 0.0; 00396 switch (m_encodingType) 00397 { 00398 case k1X: 00399 return 1.0; 00400 case k2X: 00401 return 0.5; 00402 case k4X: 00403 return 0.25; 00404 default: 00405 return 0.0; 00406 } 00407 } 00408 00414 double Encoder::GetDistance() 00415 { 00416 if (StatusIsFatal()) return 0.0; 00417 return GetRaw() * DecodingScaleFactor() * m_distancePerPulse; 00418 } 00419 00426 double Encoder::GetRate() 00427 { 00428 if (StatusIsFatal()) return 0.0; 00429 return (m_distancePerPulse / GetPeriod()); 00430 } 00431 00437 void Encoder::SetMinRate(double minRate) 00438 { 00439 if (StatusIsFatal()) return; 00440 SetMaxPeriod(m_distancePerPulse / minRate); 00441 } 00442 00454 void Encoder::SetDistancePerPulse(double distancePerPulse) 00455 { 00456 if (StatusIsFatal()) return; 00457 m_distancePerPulse = distancePerPulse; 00458 } 00459 00466 void Encoder::SetReverseDirection(bool reverseDirection) 00467 { 00468 if (StatusIsFatal()) return; 00469 if (m_counter) 00470 { 00471 m_counter->SetReverseDirection(reverseDirection); 00472 } 00473 else 00474 { 00475 tRioStatusCode localStatus = NiFpga_Status_Success; 00476 m_encoder->writeConfig_Reverse(reverseDirection, &localStatus); 00477 wpi_setError(localStatus); 00478 } 00479 } 00480 00486 void Encoder::SetPIDSourceParameter(PIDSourceParameter pidSource) 00487 { 00488 if (StatusIsFatal()) return; 00489 m_pidSource = pidSource; 00490 } 00491 00497 double Encoder::PIDGet() 00498 { 00499 if (StatusIsFatal()) return 0.0; 00500 switch (m_pidSource) 00501 { 00502 case kDistance: 00503 return GetDistance(); 00504 case kRate: 00505 return GetRate(); 00506 default: 00507 return 0.0; 00508 } 00509 }
Generated on Thu Jan 12 2012 22:35:20 for WPILibC++ by
1.7.1