vrpn  07.33
Virtual Reality Peripheral Network
vrpn_Flock.C
Go to the documentation of this file.
1 // The structure of this code came from vrpn_3Space.[Ch]
2 // Most of the flock specific code comes from snippets in:
3 // ~hmd/src/libs/tracker/apps/ascension/FLOCK232/C
4 // That directory includes a program called cbird which allows you
5 // to send almost any command to the flock.
6 // If you are having trouble with the flock, compile and run that program.
7 // Things to remember:
8 // Drain or flush i/o buffers as appropriate
9 // If the flock is in stream mode ('@'), put it into point mode ('B')
10 // before trying to send other commands
11 // Even if you are running in group mode, you need to preface data
12 // specification commands with the RS232TOFBB command.
13 // (weberh 1/11/98)
14 
15 #include <stdio.h> // for fprintf, stderr, perror, etc
16 #include <time.h> // for ctime, time, time_t
17 
18 #include "quat.h" // for q_invert
19 #include "vrpn_Flock.h"
20 #include "vrpn_Serial.h" // for vrpn_drain_output_buffer, etc
21 #include "vrpn_Tracker.h" // for vrpn_TRACKER_FAIL, etc
22 #include "vrpn_Types.h" // for vrpn_float64
23 
25 
26 // output a status msg every status_msg_secs
27 #define STATUS_MSG
28 #define STATUS_MSG_SECS 600
29 
30 void vrpn_Tracker_Flock::printError( unsigned char uchErrCode,
31  unsigned char uchExpandedErrCode ) {
32 
33  fprintf(stderr,"\n\rError Code is %u (decimal) ", uchErrCode);
34  /*
35  Display a message describing the Error
36  */
37  switch (uchErrCode) {
38  case 0:
39  fprintf(stderr,"...No Errors Have Occurred");
40  break;
41  case 1:
42  fprintf(stderr,"...System RAM Test Error");
43  break;
44  case 2:
45  fprintf(stderr,"...Non-Volatile Storage Write Failure");
46  break;
47  case 3:
48  fprintf(stderr,"...System EEPROM Configuration Corrupt");
49  break;
50  case 4:
51  fprintf(stderr,"...Transmitter EEPROM Configuration Corrupt");
52  break;
53  case 5:
54  fprintf(stderr,"...Receiver EEPROM Configuration Corrupt");
55  break;
56  case 6:
57  fprintf(stderr,"...Invalid RS232 Command");
58  break;
59  case 7:
60  fprintf(stderr,"...Not an FBB Master");
61  break;
62  case 8:
63  fprintf(stderr,"...No 6DFOBs are Active");
64  break;
65  case 9:
66  fprintf(stderr,"...6DFOB has not been Initialized");
67  break;
68  case 10:
69  fprintf(stderr,"...FBB Receive Error - Intra Bird Bus");
70  break;
71  case 11:
72  fprintf(stderr,"...RS232 Overrun and/or Framing Error");
73  break;
74  case 12:
75  fprintf(stderr,"...FBB Receive Error - FBB Host Bus");
76  break;
77  case 13:
78  fprintf(stderr,
79  "...No FBB Command Response from Device at address %d (decimal)",
80  uchExpandedErrCode & 0x0f);
81  break;
82  case 14:
83  fprintf(stderr,"...Invalid FBB Host Command");
84  break;
85  case 15:
86  fprintf(stderr,"...FBB Run Time Error");
87  break;
88  case 16:
89  fprintf(stderr,"...Invalid CPU Speed");
90  break;
91  case 17:
92  fprintf(stderr,"...Slave No Data Error");
93  break;
94  case 18:
95  fprintf(stderr,"...Illegal Baud Rate");
96  break;
97  case 19:
98  fprintf(stderr,"...Slave Acknowledge Error");
99  break;
100  case 20:
101  fprintf(stderr,"...CPU Overflow Error - call factory");
102  break;
103  case 21:
104  fprintf(stderr,"...Array Bounds Error - call factory");
105  break;
106  case 22:
107  fprintf(stderr,"...Unused Opcode Error - call factory");
108  break;
109  case 23:
110  fprintf(stderr,"...Escape Opcode Error - call factory");
111  break;
112  case 24:
113  fprintf(stderr,"...Reserved Int 9 - call factory");
114  break;
115  case 25:
116  fprintf(stderr,"...Reserved Int 10 - call factory");
117  break;
118  case 26:
119  fprintf(stderr,"...Reserved Int 11 - call factory");
120  break;
121  case 27:
122  fprintf(stderr,"...Numeric CPU Error - call factory");
123  break;
124  case 28:
125  fprintf(stderr,"...CRT Synchronization Error");
126  break;
127  case 29:
128  fprintf(stderr,"...Transmitter Not Active Error");
129  break;
130  case 30:
131  fprintf(stderr,"...ERC Extended Range Transmitter Not Attached Error");
132  break;
133  case 31:
134  fprintf(stderr,"...CPU Time Overflow Error");
135  break;
136  case 32:
137  fprintf(stderr,"...Receiver Saturated Error");
138  break;
139  case 33:
140  fprintf(stderr,"...Slave Configuration Error");
141  break;
142  case 34:
143  fprintf(stderr,"...ERC Watchdog Error");
144  break;
145  case 35:
146  fprintf(stderr,"...ERC Overtemp Error");
147  break;
148  default:
149  fprintf(stderr,"...UNKNOWN ERROR... check user manual");
150  break;
151  }
152 }
153 
154 // check for flock error, return err number if there is an error
155 // zero if no error
157 
158  // Some compilers (CenterLine CC on sunos!?) still don't support
159  // automatic aggregate initialization
160 
161  //unsigned char rguch[4]={'B','G','O',10};
162 
163  int cLen=0;
164  unsigned char rguch[2];
165  rguch[cLen++] = 'B';
166  rguch[cLen++] = 'G';
167 
168  // put the flock to sleep (B to get out of stream mode, G to sleep)
169 
170  if (vrpn_write_characters(serial_fd, (const unsigned char *) &rguch, cLen )!=cLen) {
171  perror("\nvrpn_Tracker_Flock: failed writing cmds to tracker");
172  return -1;
173  }
174 
175  // make sure the command is sent out
177 
178  vrpn_SleepMsecs(500);
179 
180  // clear in buffer
182 
183  // now get error code and clear error status
184  // we want error code 16, not 10 -- we want the expanded error code
185  // prepare error status query (expanded error codes)
186  cLen=0;
187  rguch[cLen++] = 'O';
188  rguch[cLen++] = 16;
189  if (vrpn_write_characters(serial_fd, (const unsigned char *)rguch, cLen )!=cLen) {
190  perror("\nvrpn_Tracker_Flock: failed writing cmds to tracker");
191  return -1;
192  }
193 
194  // make sure the command is sent out
196 
197  vrpn_SleepMsecs(500);
198 
199  // read response (2 char response to error query 16),
200  // 1 char response to 10
201  int cRet;
202  if ((cRet=vrpn_read_available_characters(serial_fd, rguch, 2))!=2) {
203  fprintf(stderr,
204  "\nvrpn_Tracker_Flock: received only %d of 2 chars for err code",
205  cRet);
206  return -1;
207  }
208 
209  // if first byte is 0, there is no error
210  // if (rguch[0]) {
211  printError( rguch[0], rguch[1] );
212  // }
213  return rguch[0];
214 }
215 
217  int cSensors, const char *port, long baud,
218  int fStreamMode, int useERT, bool invertQuaternion, int active_hemisphere) :
219  vrpn_Tracker_Serial(name,c,port,baud), cSensors(cSensors), cResets(0),
220  fStream(fStreamMode), fGroupMode(1), cSyncs(0), fFirstStatusReport(1), d_useERT(useERT),
221  activeHemisphere(active_hemisphere),
222  d_invertQuaternion(invertQuaternion) {
224  fprintf(stderr, "\nvrpn_Tracker_Flock: too many sensors requested ... only %d allowed (%d specified)", VRPN_FLOCK_MAX_SENSORS, cSensors );
226  }
227  fprintf(stderr, "\nvrpn_Tracker_Flock: starting up (FOBHack)...");
228 }
229 
230 
232  // the cbird code shows how to read these
233  int resetLen = 0;
234  unsigned char reset[5];
235  unsigned char response[5];
236 
237  // get crystal freq and measurement rate
238  reset[resetLen++]='O';
239  reset[resetLen++]=2;
240  reset[resetLen++]='O';
241  reset[resetLen++]=6;
242 
243  if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
244  perror("\nvrpn_Tracker_Flock: failed writing set mode cmds to tracker");
246  return 1;
247  }
248 
249  // make sure the commands are sent out
251 
252  // let the tracker respond
253  vrpn_SleepMsecs(500);
254 
255  int cRetF;
256  if ((cRetF=vrpn_read_available_characters(serial_fd, response, 4))!=4) {
257  fprintf(stderr,
258  "\nvrpn_Tracker_Flock: received only %d of 4 chars as freq",
259  cRetF);
261  return 1;
262  }
263 
264  fprintf(stderr, "\nvrpn_Tracker_Flock: crystal freq is %d Mhz",
265  (unsigned int)response[0]);
266  unsigned int iCount = response[2] + (((unsigned int)response[3]) << 8);
267  return (1000.0/((4*(iCount*(8.0/response[0])/1000.0)) + 0.3));
268 }
269 
271 
272  // Some compilers (CenterLine CC on sunos!?) still don't support
273  // automatic aggregate initialization
274 
275  int cLen=0;
276  //unsigned char rgch[2]={'B','G'};
277  unsigned char rgch [2];
278  rgch[cLen++] = 'B';
279  rgch[cLen++] = 'G';
280 
281  fprintf(stderr,"\nvrpn_Tracker_Flock: shutting down ...");
282  // clear output buffer
284 
285  // put the flock to sleep (B to get out of stream mode, G to sleep)
286  if (vrpn_write_characters(serial_fd, (const unsigned char *) rgch, cLen )!=cLen) {
287  perror("\nvrpn_Tracker_Flock: failed writing sleep cmd to tracker");
289  return;
290  }
291  // make sure the command is sent out
293  fprintf(stderr, " done.\n");
294 }
295 
297 {
298  int i;
299  int resetLen;
300  unsigned char reset[6*(VRPN_FLOCK_MAX_SENSORS+1)+10];
301 
302  // If the RTS/CTS pins are in the cable that connects the Flock
303  // to the computer, we need to raise and drop the RTS/CTS line
304  // to make the communications on the Flock reset. We need to give
305  // it time to reset. If these wires are not installed (ie, if only
306  // send, receive and ground are connected) then we don't need this.
307  // To be more general, we put it in. The following code snippet
308  // comes from Kyle at Ascension.
310  vrpn_SleepMsecs(1000);
312  vrpn_SleepMsecs(2000);
313 
314  // set vars for error handling
315  // set them right away so they are set properly in the
316  // event that we fail during the reset.
317  cResets++;
318  cSyncs=0;
320 
321  // Get rid of the characters left over from before the reset
322  // (make sure they are processed)
324 
325  // put back into polled mode (need to stop stream mode
326  // before doing an auto-config)
327  resetLen=0;
328  reset[resetLen++]='B';
329 
330  // send the poll mode command (cmd and cmd_size are args)
331  fprintf(stderr," vrpn_Flock: Sending POLL mode command...\n");
332  if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
333  perror("\nvrpn_Tracker_Flock: failed writing poll cmd to tracker");
335  return;
336  }
337  // make sure the command is sent out
339 
340  // wait for tracker to respond and flush buffers
341  vrpn_SleepMsecs(5000);
342 
343  // Send the tracker a string that should reset it.
344 
345  // we will try to do an auto-reconfigure of all units of the flock
346  // then set the flock into pos/quat stream mode (this requires group
347  // mode, so we set that as well).
348 
349  resetLen=0;
350 
351  // "change value" cmd
352  reset[resetLen++]='P';
353 
354  // flock of birds auto-configure code
355  reset[resetLen++]=50;
356 
357  // number of units (xmitter + receivers)
358  reset[resetLen++]= (unsigned char)(cSensors+d_useERT);
359 
360  // as per pg 59 of the jan 31, 1995 FOB manual, we need to pause at
361  // least 300 ms before and after sending the autoconfig (paused above)
362 
363  // send the reset command (cmd and cmd_size are args)
364  fprintf(stderr," vrpn_Flock: Sending RESET command...\n");
365  if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
366  perror("\nvrpn_Tracker_Flock: failed writing auto-config to tracker");
368  return;
369  }
370  // make sure the command is sent out
372 
373  // wait for auto reconfig
374  vrpn_SleepMsecs(10000);
375 
376  // now set modes: pos/quat, group, stream
377  resetLen=0;
378 
379  // group mode
380  reset[resetLen++] = 'P';
381  reset[resetLen++] = 35;
382  reset[resetLen++] = 1;
383  // pos/quat mode sent to each receiver (transmitter is unit 1)
384  // 0xf0 + addr is the cmd to tell the master to forward a cmd
385  for (i=1;i<=cSensors;i++) {
386  reset[resetLen++] = (unsigned char)(0xf0 + i + d_useERT);
387  reset[resetLen++] = ']';
388  }
389 
390  //
391  // Set the active hemisphere based on what's in the config file.
392 
393  unsigned char hem, sign;
394  switch (activeHemisphere)
395  {
396  case HEMI_PLUSX : hem = 0x00; sign = 0x00; break;
397  case HEMI_MINUSX: hem = 0x00; sign = 0x01; break;
398  case HEMI_PLUSY : hem = 0x06; sign = 0x00; break;
399  case HEMI_MINUSY: hem = 0x06; sign = 0x01; break;
400  case HEMI_PLUSZ : hem = 0x0c; sign = 0x00; break;
401  case HEMI_MINUSZ: hem = 0x0c; sign = 0x01; break;
402  }
403  // prepare the command
404  for (i=1;i<=cSensors;i++) {
405  reset[resetLen++] = (unsigned char)(0xf0 + i + d_useERT);
406  reset[resetLen++] = 'L';
407  reset[resetLen++] = hem;
408  reset[resetLen++] = sign;
409  }
410 
411  // write it all out
412  fprintf(stderr," vrpn_Flock: Setting parameters...\n");
413  if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
414  perror("\nvrpn_Tracker_Flock: failed writing set mode cmds to tracker");
416  return;
417  }
418 
419  // make sure the commands are sent out
421 
422  // clear the input buffer (it will contain a single point
423  // record from the poll command above and garbage from before reset)
425 
426  resetLen=0;
427  // get the system status to check that it opened correctly
428  // examine value cmd is 'O'
429  reset[resetLen++]='O';
430 
431  // flock system status is 36
432  reset[resetLen++]=36;
433 
434  // write the cmd and get response
435  if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
436  perror("\nvrpn_Tracker_Flock: failed writing get sys config to tracker");
438  return;
439  }
440 
441  // make sure the command is sent out
443 
444  // let the tracker respond
445  vrpn_SleepMsecs(500);
446 
447  fprintf(stderr," vrpn_Flock: Checking for response...\n");
448  unsigned char response[14];
449  int cRet;
450  if ((cRet=vrpn_read_available_characters(serial_fd, response, 14))!=14) {
451  fprintf(stderr,
452  "\nvrpn_Tracker_Flock: received only %d of 14 chars as status",
453  cRet);
455  return;
456  }
457 
458  // check the configuration ...
459  int fOk=1;
460  for (i=0;i<=cSensors-1+d_useERT;i++) {
461  fprintf(stderr, "\nvrpn_Tracker_Flock: unit %d", i);
462  if (response[i] & 0x20) {
463  fprintf(stderr," (a receiver)");
464  } else {
465  fprintf(stderr," (a transmitter)");
466 // now we allow non transmitters at fisrt address !!!!
467 // if (i != 0) {
468 // fprintf(stderr,"\nError: VRPN Flock driver can only accept transmitter as first unit\n");
469 // status = vrpn_TRACKER_FAIL;
470 // fOk=0;
471 // return;
472 // }
473  }
474  if (response[i] & 0x80) {
475  fprintf(stderr," is accessible");
476  } else {
477  fprintf(stderr," is not accessible");
478  fOk=0;
479  }
480  if (response[i] & 0x40) {
481  fprintf(stderr," and is running");
482  } else {
483  fprintf(stderr," and is not running");
484  fOk=0;
485  }
486  }
487 
488  fprintf(stderr, "\n");
489 
490  if (!fOk) {
491  perror("\nvrpn_Tracker_Flock: problems resetting tracker.");
493  return;
494  }
495 
496 #define GET_FREQ
497 #ifdef GET_FREQ
498  fprintf(stderr, "\nvrpn_Tracker_Flock: sensor measurement rate is %lf hz.",
500 #endif
501 
502  // now start it running
503  resetLen = 0;
504 
505  if (fStream==1) {
506  // stream mode
507  reset[resetLen++] = '@';
508  if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
509  perror("\nvrpn_Tracker_Flock: failed writing set mode cmds to tracker");
511  return;
512  }
513 
514  // make sure the commands are sent out
516  }
517 
518  fprintf(stderr,"\nvrpn_Tracker_Flock: done with reset ... running.\n");
519 
520  vrpn_gettimeofday(&timestamp, NULL); // Set watchdog now
521  status = vrpn_TRACKER_SYNCING; // We're trying for a new reading
522 }
523 
524 
526 {
527  int ret;
528  unsigned RECORD_SIZE = 15;
529 
530  // The reports are 15 bytes long each (Pos/Quat format plus
531  // group address), with a phasing bit set in the first byte
532  // of each sensor.
533  // If not in group mode, then reports are just 14 bytes
534  // VRPN sends every tracker report for every sensor.
535 
536  if (!fGroupMode) {
537  RECORD_SIZE = 14;
538  }
539 
540  // We need to search for the phasing bit because if the input
541  // buffer overflows then it will be emptied and overwritten.
542 
543  // If we're synching, read a byte at a time until we find
544  // one with the high bit set.
545 
546  if (status == vrpn_TRACKER_SYNCING) {
547  // Try to get a character. If none, just return.
549  return 0;
550  }
551 
552  // If the high bit isn't set, we don't want it we
553  // need to look at the next one, so just return
554  if ( (buffer[0] & 0x80) == 0) {
555  fprintf(stderr,"\nvrpn_Tracker_Flock: Syncing (high bit not set)");
556  cSyncs++;
557  if (cSyncs>RECORD_SIZE) {
558  // reset the tracker if more than a few syncs occur
560  }
561  return 0;
562  }
563  cSyncs=0;
564 
565  // Got the first character of a report -- go into PARTIAL mode
566  // and say that we got one character at this time.
567  bufcount = 1;
570  }
571 
572  // Read as many bytes of this record as we can, storing them
573  // in the buffer. We keep track of how many have been read so far
574  // and only try to read the rest. The routine that calls this one
575  // makes sure we get a full reading often enough (ie, it is responsible
576  // for doing the watchdog timing to make sure the tracker hasn't simply
577  // stopped sending characters).
579  RECORD_SIZE-bufcount);
580  if (ret == -1) {
581  fprintf(stderr,"\nvrpn_Tracker_Flock: Error reading");
583  return 0;
584  }
585  bufcount += ret;
586  if (bufcount < RECORD_SIZE) { // Not done -- go back for more
587  return 0;
588  }
589 
590  // confirm that we are still synched ...
591  if ( (buffer[0] & 0x80) == 0) {
592  fprintf(stderr,"\nvrpn_Tracker_Flock: lost sync, resyncing.");
594  return 0;
595  }
596 
597  // Now decode the report
598 
599  // from the flock manual (page 28) and ascension's code ...
600 
601  // they use 14 bit ints
602  short *rgs= (short *)buffer;
603  short cs = (short)(RECORD_SIZE/2);
604 
605  // Go though the flock data and make into two's complemented
606  // 16 bit integers by:
607  // 1) getting rid of the lsb phasing bit
608  // 2) shifting the lsbyte left one bit
609  // 3) recombining msb/lsb into words
610  // 4) shifting each word left one more bit
611  // These are then scaled appropriately.
612 
613  unsigned char uchLsb;
614  unsigned char uchMsb;
615 
616  for (int irgs=0;irgs<cs;irgs++) {
617  // The data is dealt with as bytes so that the host byte ordering
618  // will not affect the operation
619  uchLsb = (unsigned char)(buffer[irgs*2] & 0x7F);
620  uchLsb <<= 1;
621  uchMsb = buffer[irgs*2+1];
622  rgs[irgs] = (short)( ((unsigned short) uchLsb) + (((unsigned short) uchMsb) << 8) );
623  rgs[irgs] <<= 1;
624  }
625 
626  // scale factor for position.
627  // According to Jo Skermo, this depends on whether we're using the
628  // extended-range transmitter or not.
629  double int_to_inches;
630  if (d_useERT) {
631  int_to_inches = 144.0/32768.0;
632  } else {
633  int_to_inches = 36.0/32768.0;
634  }
635 
636  int i;
637  for (i=0;i<3;i++) {
638  // scale and convert to meters
639  pos[i] = (double)(rgs[i] * int_to_inches * 0.0254);
640  }
641 
642  // they code quats as w,x,y,z, we need to give out x,y,z,w
643  // The quats are already normalized
644 #define WTF (float)(1.0/32768.0) /* float to word integer */
645  for (i=4;i<7;i++) {
646  // quat[i-4] = (double)(((short *)buffer)[i] * WTF);
647  d_quat[i-4] = (double)(rgs[i] * WTF);
648  }
649  d_quat[3] = (double)(rgs[3] * WTF);
650 
651  // Because the Flock was used at UNC by having the transmitter
652  // above the user, we were always operating in the wrong hemisphere.
653  // According to the Flock manual, the Flock should report things
654  // in the same way other trackers do. The original code inverted
655  // the Quaternion value before returning it, probably because of this
656  // hemisphere problem. Sebastien Maraux pointed out the confusion.
657  // To Enable either mode to work, the code now has an optional parameter
658  // that will invert the quaternion, but it is not the default anymore.
659  // Others must have been using the Flock in the same manner, because
660  // they didn't see a problem with this code.
661 
662  if (d_invertQuaternion) { q_invert(d_quat, d_quat); }
663 
664  if (fGroupMode) {
665  // sensor addr are 0 indexed in vrpn, but start at 2 in the flock
666  // (1 is the transmitter)
667 // d_sensor = buffer[RECORD_SIZE-1]-2;
668  d_sensor = buffer[RECORD_SIZE-1]-1-d_useERT;
669  }
670 
671  // all set for this sensor, so cycle
673  bufcount = 0;
674 
675 #ifdef VERBOSE
677 #endif
678  return 1;
679 }
680 
681 #define poll() { \
682 char chPoint = 'B';\
683 fprintf(stderr,"."); \
684 if (vrpn_write_characters(serial_fd, (const unsigned char *) &chPoint, 1 )!=1) {\
685  perror("\nvrpn_Tracker_Flock: failed writing set mode cmds to tracker");\
686  status = vrpn_TRACKER_FAIL;\
687  return;\
688 } \
689 vrpn_gettimeofday(&timestamp, NULL);\
690 }
691 
694 
695  // NOTE: the flock behavior is very finicky -- if you try to poll
696  // again before most of the last response has been read, then
697  // it will complain. You need to wait and issue the next
698  // group poll only once you have read out the previous one entirely
699  // As a result, polling is very slow with multiple sensors.
700  if (fStream==0) {
701  if (d_sensor==(cSensors-1)) {
702  poll();
703  }
704  }
705 
706  // successful read, so reset the reset count
707  cResets = 0;
708 
709 #ifdef STATUS_MSG
710  // data to calc report rate
711  struct timeval tvNow;
712 
713  // get curr time
714  vrpn_gettimeofday(&tvNow, NULL);
715 
716  if (fFirstStatusReport) {
717  // print a status message in cStatusInterval seconds
718  cStatusInterval=3;
719  tvLastStatusReport=tvNow;
720  cReports=0;
722  fprintf(stderr, "\nFlock: status will be printed every %d seconds.",
724  }
725 
726  cReports++;
727 
729  cStatusInterval*1000){
730 
731  double dRate = cReports /
733  tvLastStatusReport))/1000.0);
734  time_t tNow = time(NULL);
735  char *pch = ctime(&tNow);
736  pch[24]='\0';
737  fprintf(stderr, "\nFlock: reports being sent at %6.2lf hz "
738  "(%d sensors, so ~%6.2lf hz per sensor) ( %s )",
739  dRate, cSensors, dRate/cSensors, pch);
740  tvLastStatusReport = tvNow;
741  cReports=0;
742  // display the rate every STATUS_MSG_SECS seconds
744  }
745 #endif
746 }
STATUS_MSG_SECS
#define STATUS_MSG_SECS
Definition: vrpn_Flock.C:28
vrpn_Tracker.h
vrpn_Tracker_Flock::cSensors
int cSensors
Definition: vrpn_Flock.h:57
vrpn_Tracker_Flock::printError
void printError(unsigned char uchErrCode, unsigned char uchExpandedErrCode)
Definition: vrpn_Flock.C:30
vrpn_Tracker_Flock::cReports
int cReports
Definition: vrpn_Flock.h:71
vrpn_Tracker::d_sensor
vrpn_int32 d_sensor
Definition: vrpn_Tracker.h:94
vrpn_Types.h
vrpn_Tracker_Flock::fGroupMode
int fGroupMode
Definition: vrpn_Flock.h:59
vrpn_Tracker_Serial::buffer
unsigned char buffer[VRPN_TRACKER_BUF_SIZE]
Definition: vrpn_Tracker.h:155
vrpn_set_rts
int vrpn_set_rts(int comm)
Definition: vrpn_Serial.C:365
vrpn_drain_output_buffer
int vrpn_drain_output_buffer(int comm)
Wait until all of the characters in the output buffer are sent, then return.
Definition: vrpn_Serial.C:485
vrpn_Tracker_Serial::serial_fd
int serial_fd
Definition: vrpn_Tracker.h:153
vrpn_Tracker_Flock::vrpn_Tracker_Flock
vrpn_Tracker_Flock(char *name, vrpn_Connection *c, int cSensors=1, const char *port="/dev/ttyd3", long baud=38400, int fStreamMode=1, int useERT=1, bool invertQuaternion=false, int active_hemisphere=HEMI_PLUSZ)
Definition: vrpn_Flock.C:216
vrpn_Tracker::d_quat
vrpn_float64 d_quat[4]
Definition: vrpn_Tracker.h:95
vrpn_Tracker_Flock::HEMI_MINUSY
Definition: vrpn_Flock.h:46
vrpn_Tracker::timestamp
struct timeval timestamp
Definition: vrpn_Tracker.h:100
vrpn_Tracker_Flock::HEMI_PLUSX
Definition: vrpn_Flock.h:46
vrpn_Tracker_Flock::getMeasurementRate
double getMeasurementRate()
Definition: vrpn_Flock.C:231
vrpn_Serial.h
vrpn_Serial: Pulls all the serial port routines into one file to make porting to new operating system...
vrpn_Tracker_Flock::HEMI_MINUSZ
Definition: vrpn_Flock.h:46
VRPN_FLOCK_MAX_SENSORS
#define VRPN_FLOCK_MAX_SENSORS
Definition: vrpn_Flock.h:11
vrpn_Tracker_Flock::~vrpn_Tracker_Flock
virtual ~vrpn_Tracker_Flock()
Definition: vrpn_Flock.C:270
vrpn_Tracker_Flock::d_invertQuaternion
bool d_invertQuaternion
Definition: vrpn_Flock.h:62
vrpn_flush_input_buffer
int vrpn_flush_input_buffer(int comm)
Throw out any characters within the input buffer.
Definition: vrpn_Serial.C:435
vrpn_TimevalDiff
timeval vrpn_TimevalDiff(const timeval &tv1, const timeval &tv2)
Definition: vrpn_Shared.C:92
vrpn_SleepMsecs
void vrpn_SleepMsecs(double dMsecs)
Definition: vrpn_Shared.C:157
vrpn_TRACKER_PARTIAL
const int vrpn_TRACKER_PARTIAL
Definition: vrpn_Tracker.h:38
vrpn_Tracker_Serial::send_report
virtual void send_report(void)
Definition: vrpn_Tracker.C:885
vrpn_Tracker_Flock::fFirstStatusReport
int fFirstStatusReport
Definition: vrpn_Flock.h:69
vrpn_Tracker_Flock::tvLastStatusReport
struct timeval tvLastStatusReport
Definition: vrpn_Flock.h:70
vrpn_Tracker_Flock::get_report
virtual int get_report(void)
Gets a report if one is available, returns 0 if not, 1 if complete report.
Definition: vrpn_Flock.C:525
vrpn_Connection
Generic connection class not specific to the transport mechanism.
Definition: vrpn_Connection.h:510
vrpn_TRACKER_FAIL
const int vrpn_TRACKER_FAIL
Definition: vrpn_Tracker.h:40
vrpn_Tracker_Flock::cSyncs
unsigned cSyncs
Definition: vrpn_Flock.h:66
vrpn_TRACKER_RESETTING
const int vrpn_TRACKER_RESETTING
Definition: vrpn_Tracker.h:39
vrpn_Tracker_Flock::d_useERT
int d_useERT
Definition: vrpn_Flock.h:61
vrpn_Tracker_Flock::activeHemisphere
int activeHemisphere
Definition: vrpn_Flock.h:50
vrpn_Tracker_Flock::HEMI_PLUSZ
Definition: vrpn_Flock.h:46
vrpn_gettimeofday
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:89
vrpn_Tracker::status
int status
Definition: vrpn_Tracker.h:129
vrpn_Tracker_Flock::fStream
int fStream
Definition: vrpn_Flock.h:58
vrpn_Tracker_Serial
Definition: vrpn_Tracker.h:144
vrpn_read_available_characters
int vrpn_read_available_characters(int comm, unsigned char *buffer, size_t bytes)
Definition: vrpn_Serial.C:512
WTF
#define WTF
vrpn_Tracker_Flock::cResets
unsigned cResets
Definition: vrpn_Flock.h:65
vrpn_TRACKER_SYNCING
const int vrpn_TRACKER_SYNCING
Definition: vrpn_Tracker.h:35
vrpn_Tracker_Serial::bufcount
vrpn_uint32 bufcount
Definition: vrpn_Tracker.h:157
vrpn_Tracker_Flock::checkError
int checkError()
Definition: vrpn_Flock.C:156
vrpn_Tracker_Flock::reset
virtual void reset()
Reset the tracker.
Definition: vrpn_Flock.C:296
vrpn_Flock.h
vrpn_write_characters
int vrpn_write_characters(int comm, const unsigned char *buffer, size_t bytes)
Write the buffer to the serial port.
Definition: vrpn_Serial.C:643
vrpn_TimevalMsecs
double vrpn_TimevalMsecs(const timeval &tv)
Definition: vrpn_Shared.C:141
vrpn_Tracker::pos
vrpn_float64 pos[3]
Definition: vrpn_Tracker.h:95
vrpn_Tracker::print_latest_report
void print_latest_report(void)
Definition: vrpn_Tracker.C:306
vrpn_flush_output_buffer
int vrpn_flush_output_buffer(int comm)
Throw out any characters (do not send) within the output buffer.
Definition: vrpn_Serial.C:462
vrpn_Tracker_Flock::HEMI_PLUSY
Definition: vrpn_Flock.h:46
vrpn_Tracker_Flock::HEMI_MINUSX
Definition: vrpn_Flock.h:46
vrpn_Tracker_Flock::cStatusInterval
int cStatusInterval
Definition: vrpn_Flock.h:72
VRPN_API
#define VRPN_API
Definition: vrpn_Configure.h:646
vrpn_Tracker_Flock::send_report
virtual void send_report(void)
Definition: vrpn_Flock.C:692
poll
#define poll()
Definition: vrpn_Flock.C:681
vrpn_clear_rts
int vrpn_clear_rts(int comm)
Definition: vrpn_Serial.C:399