Now you can download a copy of these docs so you can use them offline! Download now
Encoder.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 "Encoder.h"
8 #include "DigitalInput.h"
9 #include "NetworkCommunication/UsageReporting.h"
10 #include "Resource.h"
11 #include "WPIErrors.h"
12 #include "LiveWindow/LiveWindow.h"
13 
14 static Resource *quadEncoders = NULL;
15 
26 void Encoder::InitEncoder(bool reverseDirection, EncodingType encodingType)
27 {
28  m_table = NULL;
29  m_encodingType = encodingType;
30  tRioStatusCode localStatus = NiFpga_Status_Success;
31  switch (encodingType)
32  {
33  case k4X:
34  {
35  Resource::CreateResourceObject(&quadEncoders, tEncoder::kNumSystems);
36  uint32_t index = quadEncoders->Allocate("4X Encoder");
37  if (index == ~0ul)
38  {
39  CloneError(quadEncoders);
40  return;
41  }
42  if (m_aSource->StatusIsFatal())
43  {
44  CloneError(m_aSource);
45  return;
46  }
47  if (m_bSource->StatusIsFatal())
48  {
49  CloneError(m_bSource);
50  return;
51  }
52  m_index = index;
53  m_encoder = tEncoder::create(m_index, &localStatus);
54  m_encoder->writeConfig_ASource_Module(m_aSource->GetModuleForRouting(), &localStatus);
55  m_encoder->writeConfig_ASource_Channel(m_aSource->GetChannelForRouting(), &localStatus);
56  m_encoder->writeConfig_ASource_AnalogTrigger(m_aSource->GetAnalogTriggerForRouting(), &localStatus);
57  m_encoder->writeConfig_BSource_Module(m_bSource->GetModuleForRouting(), &localStatus);
58  m_encoder->writeConfig_BSource_Channel(m_bSource->GetChannelForRouting(), &localStatus);
59  m_encoder->writeConfig_BSource_AnalogTrigger(m_bSource->GetAnalogTriggerForRouting(), &localStatus);
60  m_encoder->strobeReset(&localStatus);
61  m_encoder->writeConfig_Reverse(reverseDirection, &localStatus);
62  m_encoder->writeTimerConfig_AverageSize(4, &localStatus);
63  m_counter = NULL;
64  break;
65  }
66  case k1X:
67  case k2X:
68  {
69  m_counter = new Counter(m_encodingType, m_aSource, m_bSource, reverseDirection);
70  m_index = m_counter->GetIndex();
71  break;
72  }
73  }
74  m_distancePerPulse = 1.0;
75  m_pidSource = kDistance;
76  wpi_setError(localStatus);
77 
78  nUsageReporting::report(nUsageReporting::kResourceType_Encoder, m_index, encodingType);
79  LiveWindow::GetInstance()->AddSensor("Encoder", m_aSource->GetModuleForRouting(), m_aSource->GetChannelForRouting(), this);
80 }
81 
97 Encoder::Encoder(uint8_t aModuleNumber, uint32_t aChannel,
98  uint8_t bModuleNumber, uint32_t bChannel,
99  bool reverseDirection, EncodingType encodingType) :
100  m_encoder(NULL),
101  m_counter(NULL)
102 {
103  m_aSource = new DigitalInput(aModuleNumber, aChannel);
104  m_bSource = new DigitalInput(bModuleNumber, bChannel);
105  InitEncoder(reverseDirection, encodingType);
106  m_allocatedASource = true;
107  m_allocatedBSource = true;
108 }
109 
123 Encoder::Encoder(uint32_t aChannel, uint32_t bChannel, bool reverseDirection, EncodingType encodingType) :
124  m_encoder(NULL),
125  m_counter(NULL)
126 {
127  m_aSource = new DigitalInput(aChannel);
128  m_bSource = new DigitalInput(bChannel);
129  InitEncoder(reverseDirection, encodingType);
130  m_allocatedASource = true;
131  m_allocatedBSource = true;
132 }
133 
149 Encoder::Encoder(DigitalSource *aSource, DigitalSource *bSource, bool reverseDirection, EncodingType encodingType) :
150  m_encoder(NULL),
151  m_counter(NULL)
152 {
153  m_aSource = aSource;
154  m_bSource = bSource;
155  m_allocatedASource = false;
156  m_allocatedBSource = false;
157  if (m_aSource == NULL || m_bSource == NULL)
158  wpi_setWPIError(NullParameter);
159  else
160  InitEncoder(reverseDirection, encodingType);
161 }
162 
178 Encoder::Encoder(DigitalSource &aSource, DigitalSource &bSource, bool reverseDirection, EncodingType encodingType) :
179  m_encoder(NULL),
180  m_counter(NULL)
181 {
182  m_aSource = &aSource;
183  m_bSource = &bSource;
184  m_allocatedASource = false;
185  m_allocatedBSource = false;
186  InitEncoder(reverseDirection, encodingType);
187 }
188 
194 {
195  if (m_allocatedASource) delete m_aSource;
196  if (m_allocatedBSource) delete m_bSource;
197  if (m_counter)
198  {
199  delete m_counter;
200  }
201  else
202  {
203  quadEncoders->Free(m_index);
204  delete m_encoder;
205  }
206 }
207 
213 {
214  if (StatusIsFatal()) return;
215  if (m_counter)
216  m_counter->Start();
217  else
218  {
219  tRioStatusCode localStatus = NiFpga_Status_Success;
220  m_encoder->writeConfig_Enable(1, &localStatus);
221  wpi_setError(localStatus);
222  }
223 }
224 
229 {
230  if (StatusIsFatal()) return;
231  if (m_counter)
232  m_counter->Stop();
233  else
234  {
235  tRioStatusCode localStatus = NiFpga_Status_Success;
236  m_encoder->writeConfig_Enable(0, &localStatus);
237  wpi_setError(localStatus);
238  }
239 }
240 
248 {
249  if (StatusIsFatal()) return 0;
250  int32_t value;
251  if (m_counter)
252  value = m_counter->Get();
253  else
254  {
255  tRioStatusCode localStatus = NiFpga_Status_Success;
256  value = m_encoder->readOutput_Value(&localStatus);
257  wpi_setError(localStatus);
258  }
259  return value;
260 }
261 
269 int32_t Encoder::Get()
270 {
271  if (StatusIsFatal()) return 0;
272  return (int32_t) (GetRaw() * DecodingScaleFactor());
273 }
274 
280 {
281  if (StatusIsFatal()) return;
282  if (m_counter)
283  m_counter->Reset();
284  else
285  {
286  tRioStatusCode localStatus = NiFpga_Status_Success;
287  m_encoder->strobeReset(&localStatus);
288  wpi_setError(localStatus);
289  }
290 }
291 
302 {
303  if (StatusIsFatal()) return 0.0;
304  double measuredPeriod;
305  if (m_counter)
306  {
307  measuredPeriod = m_counter->GetPeriod();
308  }
309  else
310  {
311  tRioStatusCode localStatus = NiFpga_Status_Success;
312  tEncoder::tTimerOutput output = m_encoder->readTimerOutput(&localStatus);
313  double value;
314  if (output.Stalled)
315  {
316  // Return infinity
317  double zero = 0.0;
318  value = 1.0 / zero;
319  }
320  else
321  {
322  // output.Period is a fixed point number that counts by 2 (24 bits, 25 integer bits)
323  value = (double)(output.Period << 1) / (double)output.Count;
324  }
325  wpi_setError(localStatus);
326  measuredPeriod = value * 1.0e-6;
327  }
328  return measuredPeriod / DecodingScaleFactor();
329 }
330 
343 void Encoder::SetMaxPeriod(double maxPeriod)
344 {
345  if (StatusIsFatal()) return;
346  if (m_counter)
347  {
348  m_counter->SetMaxPeriod(maxPeriod * DecodingScaleFactor());
349  }
350  else
351  {
352  tRioStatusCode localStatus = NiFpga_Status_Success;
353  m_encoder->writeTimerConfig_StallPeriod((uint32_t)(maxPeriod * 1.0e6 * DecodingScaleFactor()), &localStatus);
354  wpi_setError(localStatus);
355  }
356 }
357 
366 {
367  if (StatusIsFatal()) return true;
368  if (m_counter)
369  {
370  return m_counter->GetStopped();
371  }
372  else
373  {
374  tRioStatusCode localStatus = NiFpga_Status_Success;
375  bool value = m_encoder->readTimerOutput_Stalled(&localStatus) != 0;
376  wpi_setError(localStatus);
377  return value;
378  }
379 }
380 
386 {
387  if (StatusIsFatal()) return false;
388  if (m_counter)
389  {
390  return m_counter->GetDirection();
391  }
392  else
393  {
394  tRioStatusCode localStatus = NiFpga_Status_Success;
395  bool value = m_encoder->readOutput_Direction(&localStatus);
396  wpi_setError(localStatus);
397  return value;
398  }
399 }
400 
404 double Encoder::DecodingScaleFactor()
405 {
406  if (StatusIsFatal()) return 0.0;
407  switch (m_encodingType)
408  {
409  case k1X:
410  return 1.0;
411  case k2X:
412  return 0.5;
413  case k4X:
414  return 0.25;
415  default:
416  return 0.0;
417  }
418 }
419 
426 {
427  if (StatusIsFatal()) return 0.0;
428  return GetRaw() * DecodingScaleFactor() * m_distancePerPulse;
429 }
430 
438 {
439  if (StatusIsFatal()) return 0.0;
440  return (m_distancePerPulse / GetPeriod());
441 }
442 
448 void Encoder::SetMinRate(double minRate)
449 {
450  if (StatusIsFatal()) return;
451  SetMaxPeriod(m_distancePerPulse / minRate);
452 }
453 
465 void Encoder::SetDistancePerPulse(double distancePerPulse)
466 {
467  if (StatusIsFatal()) return;
468  m_distancePerPulse = distancePerPulse;
469 }
470 
477 void Encoder::SetReverseDirection(bool reverseDirection)
478 {
479  if (StatusIsFatal()) return;
480  if (m_counter)
481  {
482  m_counter->SetReverseDirection(reverseDirection);
483  }
484  else
485  {
486  tRioStatusCode localStatus = NiFpga_Status_Success;
487  m_encoder->writeConfig_Reverse(reverseDirection, &localStatus);
488  wpi_setError(localStatus);
489  }
490 }
491 
492 
499 void Encoder::SetSamplesToAverage(int samplesToAverage)
500 {
501  tRioStatusCode localStatus = NiFpga_Status_Success;
502  if (samplesToAverage < 1 || samplesToAverage > 127)
503  {
504  wpi_setWPIErrorWithContext(ParameterOutOfRange, "Average counter values must be between 1 and 127");
505  }
506  switch (m_encodingType) {
507  case k4X:
508  m_encoder->writeTimerConfig_AverageSize(samplesToAverage, &localStatus);
509  break;
510  case k1X:
511  case k2X:
512  m_counter->SetSamplesToAverage(samplesToAverage);
513  break;
514  }
515  wpi_setError(localStatus);
516 }
517 
525 {
526  tRioStatusCode localStatus = NiFpga_Status_Success;
527  int result = 1;
528  switch (m_encodingType) {
529  case k4X:
530  result = m_encoder->readTimerConfig_AverageSize(&localStatus);
531  break;
532  case k1X:
533  case k2X:
534  result = m_counter->GetSamplesToAverage();
535  break;
536  }
537  wpi_setError(localStatus);
538  return result;
539 }
540 
541 
542 
548 void Encoder::SetPIDSourceParameter(PIDSourceParameter pidSource)
549 {
550  if (StatusIsFatal()) return;
551  m_pidSource = pidSource;
552 }
553 
560 {
561  if (StatusIsFatal()) return 0.0;
562  switch (m_pidSource)
563  {
564  case kDistance:
565  return GetDistance();
566  case kRate:
567  return GetRate();
568  default:
569  return 0.0;
570  }
571 }
572 
574  if (m_table != NULL) {
575  m_table->PutNumber("Speed", GetRate());
576  m_table->PutNumber("Distance", GetDistance());
577  m_table->PutNumber("Distance per Tick", m_distancePerPulse);
578  }
579 }
580 
582 
583 }
584 
586 
587 }
588 
590  if (m_encodingType == k4X)
591  return "Quadrature Encoder";
592  else
593  return "Encoder";
594 }
595 
596 void Encoder::InitTable(ITable *subTable) {
597  m_table = subTable;
598  UpdateTable();
599 }
600 
602  return m_table;
603 }
604 
void SetPIDSourceParameter(PIDSourceParameter pidSource)
Definition: Encoder.cpp:548
bool GetStopped()
Definition: Encoder.cpp:365
ITable * GetTable()
Definition: Encoder.cpp:601
void InitTable(ITable *subTable)
Definition: Encoder.cpp:596
void Start()
Definition: Counter.cpp:542
virtual void PutNumber(std::string key, double value)=0
void Reset()
Definition: Counter.cpp:569
void Stop()
Definition: Encoder.cpp:228
virtual ~Encoder()
Definition: Encoder.cpp:193
void Start()
Definition: Encoder.cpp:212
Definition: ITable.h:26
void StartLiveWindowMode()
Definition: Encoder.cpp:581
void Reset()
Definition: Encoder.cpp:279
int32_t GetRaw()
Definition: Encoder.cpp:247
void SetReverseDirection(bool reverseDirection)
Definition: Encoder.cpp:477
void StopLiveWindowMode()
Definition: Encoder.cpp:585
void AddSensor(const char *subsystem, const char *name, LiveWindowSendable *component)
Definition: LiveWindow.cpp:82
double PIDGet()
Definition: Encoder.cpp:559
void SetReverseDirection(bool reverseDirection)
Definition: Counter.cpp:686
double GetRate()
Definition: Encoder.cpp:437
void Free(uint32_t index)
Definition: Resource.cpp:105
void SetMinRate(double minRate)
Definition: Encoder.cpp:448
void SetDistancePerPulse(double distancePerPulse)
Definition: Encoder.cpp:465
uint32_t Allocate(const char *resourceDesc)
Definition: Resource.cpp:62
bool GetStopped()
Definition: Counter.cpp:659
static LiveWindow * GetInstance()
Definition: LiveWindow.cpp:13
void SetMaxPeriod(double maxPeriod)
Definition: Counter.cpp:623
int GetSamplesToAverage()
Definition: Encoder.cpp:524
void SetSamplesToAverage(int samplesToAverage)
Definition: Encoder.cpp:499
void SetMaxPeriod(double maxPeriod)
Definition: Encoder.cpp:343
bool GetDirection()
Definition: Counter.cpp:671
virtual bool StatusIsFatal() const
Check if the current error code represents a fatal error.
Definition: ErrorBase.cpp:178
void UpdateTable()
Definition: Encoder.cpp:573
void SetSamplesToAverage(int samplesToAverage)
Definition: Counter.cpp:527
int32_t Get()
Definition: Counter.cpp:555
static void CreateResourceObject(Resource **r, uint32_t elements)
Definition: Resource.cpp:39
std::string GetSmartDashboardType()
Definition: Encoder.cpp:589
bool GetDirection()
Definition: Encoder.cpp:385
void Stop()
Definition: Counter.cpp:581
double GetDistance()
Definition: Encoder.cpp:425
int GetSamplesToAverage()
Definition: Counter.cpp:514
double GetPeriod()
Definition: Encoder.cpp:301
int32_t Get()
Definition: Encoder.cpp:269

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