vrpn 07.35
Virtual Reality Peripheral Network
 
Loading...
Searching...
No Matches
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
30void 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)
220 , activeHemisphere(active_hemisphere)
222 , fStream(fStreamMode)
223 , fGroupMode(1)
224 , d_useERT(useERT)
225 , d_invertQuaternion(invertQuaternion)
226 , cResets(0)
227 , cSyncs(0)
229{
231 fprintf(stderr, "\nvrpn_Tracker_Flock: too many sensors requested ... only %d allowed (%d specified)", VRPN_FLOCK_MAX_SENSORS, cSensors );
233 }
234 fprintf(stderr, "\nvrpn_Tracker_Flock: starting up (FOBHack)...");
235}
236
237
239 // the cbird code shows how to read these
240 int resetLen = 0;
241 unsigned char reset[5];
242 unsigned char response[5];
243
244 // get crystal freq and measurement rate
245 reset[resetLen++]='O';
246 reset[resetLen++]=2;
247 reset[resetLen++]='O';
248 reset[resetLen++]=6;
249
250 if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
251 perror("\nvrpn_Tracker_Flock: failed writing set mode cmds to tracker");
253 return 1;
254 }
255
256 // make sure the commands are sent out
258
259 // let the tracker respond
260 vrpn_SleepMsecs(500);
261
262 int cRetF;
263 if ((cRetF=vrpn_read_available_characters(serial_fd, response, 4))!=4) {
264 fprintf(stderr,
265 "\nvrpn_Tracker_Flock: received only %d of 4 chars as freq",
266 cRetF);
268 return 1;
269 }
270
271 fprintf(stderr, "\nvrpn_Tracker_Flock: crystal freq is %d Mhz",
272 (unsigned int)response[0]);
273 unsigned int iCount = response[2] + (((unsigned int)response[3]) << 8);
274 return (1000.0/((4*(iCount*(8.0/response[0])/1000.0)) + 0.3));
275}
276
278
279 // Some compilers (CenterLine CC on sunos!?) still don't support
280 // automatic aggregate initialization
281
282 int cLen=0;
283 //unsigned char rgch[2]={'B','G'};
284 unsigned char rgch [2];
285 rgch[cLen++] = 'B';
286 rgch[cLen++] = 'G';
287
288 fprintf(stderr,"\nvrpn_Tracker_Flock: shutting down ...");
289 // clear output buffer
291
292 // put the flock to sleep (B to get out of stream mode, G to sleep)
293 if (vrpn_write_characters(serial_fd, (const unsigned char *) rgch, cLen )!=cLen) {
294 perror("\nvrpn_Tracker_Flock: failed writing sleep cmd to tracker");
296 return;
297 }
298 // make sure the command is sent out
300 fprintf(stderr, " done.\n");
301}
302
304{
305 int i;
306 int resetLen;
307 unsigned char reset[6*(VRPN_FLOCK_MAX_SENSORS+1)+10];
308
309 // If the RTS/CTS pins are in the cable that connects the Flock
310 // to the computer, we need to raise and drop the RTS/CTS line
311 // to make the communications on the Flock reset. We need to give
312 // it time to reset. If these wires are not installed (ie, if only
313 // send, receive and ground are connected) then we don't need this.
314 // To be more general, we put it in. The following code snippet
315 // comes from Kyle at Ascension.
317 vrpn_SleepMsecs(1000);
319 vrpn_SleepMsecs(2000);
320
321 // set vars for error handling
322 // set them right away so they are set properly in the
323 // event that we fail during the reset.
324 cResets++;
325 cSyncs=0;
327
328 // Get rid of the characters left over from before the reset
329 // (make sure they are processed)
331
332 // put back into polled mode (need to stop stream mode
333 // before doing an auto-config)
334 resetLen=0;
335 reset[resetLen++]='B';
336
337 // send the poll mode command (cmd and cmd_size are args)
338 fprintf(stderr," vrpn_Flock: Sending POLL mode command...\n");
339 if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
340 perror("\nvrpn_Tracker_Flock: failed writing poll cmd to tracker");
342 return;
343 }
344 // make sure the command is sent out
346
347 // wait for tracker to respond and flush buffers
348 vrpn_SleepMsecs(5000);
349
350 // Send the tracker a string that should reset it.
351
352 // we will try to do an auto-reconfigure of all units of the flock
353 // then set the flock into pos/quat stream mode (this requires group
354 // mode, so we set that as well).
355
356 resetLen=0;
357
358 // "change value" cmd
359 reset[resetLen++]='P';
360
361 // flock of birds auto-configure code
362 reset[resetLen++]=50;
363
364 // number of units (xmitter + receivers)
365 reset[resetLen++]= (unsigned char)(cSensors+d_useERT);
366
367 // as per pg 59 of the jan 31, 1995 FOB manual, we need to pause at
368 // least 300 ms before and after sending the autoconfig (paused above)
369
370 // send the reset command (cmd and cmd_size are args)
371 fprintf(stderr," vrpn_Flock: Sending RESET command...\n");
372 if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
373 perror("\nvrpn_Tracker_Flock: failed writing auto-config to tracker");
375 return;
376 }
377 // make sure the command is sent out
379
380 // wait for auto reconfig
381 vrpn_SleepMsecs(10000);
382
383 // now set modes: pos/quat, group, stream
384 resetLen=0;
385
386 // group mode
387 reset[resetLen++] = 'P';
388 reset[resetLen++] = 35;
389 reset[resetLen++] = 1;
390 // pos/quat mode sent to each receiver (transmitter is unit 1)
391 // 0xf0 + addr is the cmd to tell the master to forward a cmd
392 for (i=1;i<=cSensors;i++) {
393 reset[resetLen++] = (unsigned char)(0xf0 + i + d_useERT);
394 reset[resetLen++] = ']';
395 }
396
397 //
398 // Set the active hemisphere based on what's in the config file.
399
400 unsigned char hem, sign;
401 switch (activeHemisphere)
402 {
403 case HEMI_PLUSX : hem = 0x00; sign = 0x00; break;
404 case HEMI_MINUSX: hem = 0x00; sign = 0x01; break;
405 case HEMI_PLUSY : hem = 0x06; sign = 0x00; break;
406 case HEMI_MINUSY: hem = 0x06; sign = 0x01; break;
407 case HEMI_PLUSZ : hem = 0x0c; sign = 0x00; break;
408 case HEMI_MINUSZ: hem = 0x0c; sign = 0x01; break;
409 }
410 // prepare the command
411 for (i=1;i<=cSensors;i++) {
412 reset[resetLen++] = (unsigned char)(0xf0 + i + d_useERT);
413 reset[resetLen++] = 'L';
414 reset[resetLen++] = hem;
415 reset[resetLen++] = sign;
416 }
417
418 // write it all out
419 fprintf(stderr," vrpn_Flock: Setting parameters...\n");
420 if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
421 perror("\nvrpn_Tracker_Flock: failed writing set mode cmds to tracker");
423 return;
424 }
425
426 // make sure the commands are sent out
428
429 // clear the input buffer (it will contain a single point
430 // record from the poll command above and garbage from before reset)
432
433 resetLen=0;
434 // get the system status to check that it opened correctly
435 // examine value cmd is 'O'
436 reset[resetLen++]='O';
437
438 // flock system status is 36
439 reset[resetLen++]=36;
440
441 // write the cmd and get response
442 if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
443 perror("\nvrpn_Tracker_Flock: failed writing get sys config to tracker");
445 return;
446 }
447
448 // make sure the command is sent out
450
451 // let the tracker respond
452 vrpn_SleepMsecs(500);
453
454 fprintf(stderr," vrpn_Flock: Checking for response...\n");
455 unsigned char response[14];
456 int cRet;
457 if ((cRet=vrpn_read_available_characters(serial_fd, response, 14))!=14) {
458 fprintf(stderr,
459 "\nvrpn_Tracker_Flock: received only %d of 14 chars as status",
460 cRet);
462 return;
463 }
464
465 // check the configuration ...
466 int fOk=1;
467 for (i=0;i<=cSensors-1+d_useERT;i++) {
468 fprintf(stderr, "\nvrpn_Tracker_Flock: unit %d", i);
469 if (response[i] & 0x20) {
470 fprintf(stderr," (a receiver)");
471 } else {
472 fprintf(stderr," (a transmitter)");
473// now we allow non transmitters at fisrt address !!!!
474// if (i != 0) {
475// fprintf(stderr,"\nError: VRPN Flock driver can only accept transmitter as first unit\n");
476// status = vrpn_TRACKER_FAIL;
477// fOk=0;
478// return;
479// }
480 }
481 if (response[i] & 0x80) {
482 fprintf(stderr," is accessible");
483 } else {
484 fprintf(stderr," is not accessible");
485 fOk=0;
486 }
487 if (response[i] & 0x40) {
488 fprintf(stderr," and is running");
489 } else {
490 fprintf(stderr," and is not running");
491 fOk=0;
492 }
493 }
494
495 fprintf(stderr, "\n");
496
497 if (!fOk) {
498 perror("\nvrpn_Tracker_Flock: problems resetting tracker.");
500 return;
501 }
502
503#define GET_FREQ
504#ifdef GET_FREQ
505 fprintf(stderr, "\nvrpn_Tracker_Flock: sensor measurement rate is %lf hz.",
507#endif
508
509 // now start it running
510 resetLen = 0;
511
512 if (fStream==1) {
513 // stream mode
514 reset[resetLen++] = '@';
515 if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
516 perror("\nvrpn_Tracker_Flock: failed writing set mode cmds to tracker");
518 return;
519 }
520
521 // make sure the commands are sent out
523 }
524
525 fprintf(stderr,"\nvrpn_Tracker_Flock: done with reset ... running.\n");
526
527 vrpn_gettimeofday(&timestamp, NULL); // Set watchdog now
528 status = vrpn_TRACKER_SYNCING; // We're trying for a new reading
529}
530
531
533{
534 int ret;
535 unsigned RECORD_SIZE = 15;
536
537 // The reports are 15 bytes long each (Pos/Quat format plus
538 // group address), with a phasing bit set in the first byte
539 // of each sensor.
540 // If not in group mode, then reports are just 14 bytes
541 // VRPN sends every tracker report for every sensor.
542
543 if (!fGroupMode) {
544 RECORD_SIZE = 14;
545 }
546
547 // We need to search for the phasing bit because if the input
548 // buffer overflows then it will be emptied and overwritten.
549
550 // If we're synching, read a byte at a time until we find
551 // one with the high bit set.
552
554 // Try to get a character. If none, just return.
556 return 0;
557 }
558
559 // If the high bit isn't set, we don't want it we
560 // need to look at the next one, so just return
561 if ( (buffer[0] & 0x80) == 0) {
562 fprintf(stderr,"\nvrpn_Tracker_Flock: Syncing (high bit not set)");
563 cSyncs++;
564 if (cSyncs>RECORD_SIZE) {
565 // reset the tracker if more than a few syncs occur
567 }
568 return 0;
569 }
570 cSyncs=0;
571
572 // Got the first character of a report -- go into PARTIAL mode
573 // and say that we got one character at this time.
574 bufcount = 1;
577 }
578
579 // Read as many bytes of this record as we can, storing them
580 // in the buffer. We keep track of how many have been read so far
581 // and only try to read the rest. The routine that calls this one
582 // makes sure we get a full reading often enough (ie, it is responsible
583 // for doing the watchdog timing to make sure the tracker hasn't simply
584 // stopped sending characters).
586 RECORD_SIZE-bufcount);
587 if (ret == -1) {
588 fprintf(stderr,"\nvrpn_Tracker_Flock: Error reading");
590 return 0;
591 }
592 bufcount += ret;
593 if (bufcount < RECORD_SIZE) { // Not done -- go back for more
594 return 0;
595 }
596
597 // confirm that we are still synched ...
598 if ( (buffer[0] & 0x80) == 0) {
599 fprintf(stderr,"\nvrpn_Tracker_Flock: lost sync, resyncing.");
601 return 0;
602 }
603
604 // Now decode the report
605
606 // from the flock manual (page 28) and ascension's code ...
607
608 // they use 14 bit ints
609 short *rgs= (short *)buffer;
610 short cs = (short)(RECORD_SIZE/2);
611
612 // Go though the flock data and make into two's complemented
613 // 16 bit integers by:
614 // 1) getting rid of the lsb phasing bit
615 // 2) shifting the lsbyte left one bit
616 // 3) recombining msb/lsb into words
617 // 4) shifting each word left one more bit
618 // These are then scaled appropriately.
619
620 unsigned char uchLsb;
621 unsigned char uchMsb;
622
623 for (int irgs=0;irgs<cs;irgs++) {
624 // The data is dealt with as bytes so that the host byte ordering
625 // will not affect the operation
626 uchLsb = (unsigned char)(buffer[irgs*2] & 0x7F);
627 uchLsb <<= 1;
628 uchMsb = buffer[irgs*2+1];
629 rgs[irgs] = (short)( ((unsigned short) uchLsb) + (((unsigned short) uchMsb) << 8) );
630 rgs[irgs] <<= 1;
631 }
632
633 // scale factor for position.
634 // According to Jo Skermo, this depends on whether we're using the
635 // extended-range transmitter or not.
636 double int_to_inches;
637 if (d_useERT) {
638 int_to_inches = 144.0/32768.0;
639 } else {
640 int_to_inches = 36.0/32768.0;
641 }
642
643 int i;
644 for (i=0;i<3;i++) {
645 // scale and convert to meters
646 pos[i] = (double)(rgs[i] * int_to_inches * 0.0254);
647 }
648
649 // they code quats as w,x,y,z, we need to give out x,y,z,w
650 // The quats are already normalized
651#define WTF (float)(1.0/32768.0) /* float to word integer */
652 for (i=4;i<7;i++) {
653 // quat[i-4] = (double)(((short *)buffer)[i] * WTF);
654 d_quat[i-4] = (double)(rgs[i] * WTF);
655 }
656 d_quat[3] = (double)(rgs[3] * WTF);
657
658 // Because the Flock was used at UNC by having the transmitter
659 // above the user, we were always operating in the wrong hemisphere.
660 // According to the Flock manual, the Flock should report things
661 // in the same way other trackers do. The original code inverted
662 // the Quaternion value before returning it, probably because of this
663 // hemisphere problem. Sebastien Maraux pointed out the confusion.
664 // To Enable either mode to work, the code now has an optional parameter
665 // that will invert the quaternion, but it is not the default anymore.
666 // Others must have been using the Flock in the same manner, because
667 // they didn't see a problem with this code.
668
669 if (d_invertQuaternion) { q_invert(d_quat, d_quat); }
670
671 if (fGroupMode) {
672 // sensor addr are 0 indexed in vrpn, but start at 2 in the flock
673 // (1 is the transmitter)
674// d_sensor = buffer[RECORD_SIZE-1]-2;
675 d_sensor = buffer[RECORD_SIZE-1]-1-d_useERT;
676 }
677
678 // all set for this sensor, so cycle
680 bufcount = 0;
681
682#ifdef VERBOSE
684#endif
685 return 1;
686}
687
688#define poll() { \
689char chPoint = 'B';\
690fprintf(stderr,"."); \
691if (vrpn_write_characters(serial_fd, (const unsigned char *) &chPoint, 1 )!=1) {\
692 perror("\nvrpn_Tracker_Flock: failed writing set mode cmds to tracker");\
693 status = vrpn_TRACKER_FAIL;\
694 return;\
695} \
696vrpn_gettimeofday(&timestamp, NULL);\
697}
698
699static const char* vrpn_ctime_r(time_t* cur_time, char* buffer, size_t bufsize)
700{
701#if _WIN32
702 if (0 != ctime_s(buffer, bufsize, cur_time)) {
703 return NULL;
704 }
705 return buffer;
706#else
707 return ctime_r(cur_time, buffer);
708#endif
709}
710
713
714 // NOTE: the flock behavior is very finicky -- if you try to poll
715 // again before most of the last response has been read, then
716 // it will complain. You need to wait and issue the next
717 // group poll only once you have read out the previous one entirely
718 // As a result, polling is very slow with multiple sensors.
719 if (fStream==0) {
720 if (d_sensor==(cSensors-1)) {
721 poll();
722 }
723 }
724
725 // successful read, so reset the reset count
726 cResets = 0;
727
728#ifdef STATUS_MSG
729 // data to calc report rate
730 struct timeval tvNow;
731
732 // get curr time
733 vrpn_gettimeofday(&tvNow, NULL);
734
735 if (fFirstStatusReport) {
736 // print a status message in cStatusInterval seconds
738 tvLastStatusReport=tvNow;
739 cReports=0;
741 fprintf(stderr, "\nFlock: status will be printed every %d seconds.",
743 }
744
745 cReports++;
746
748 cStatusInterval*1000){
749
750 double dRate = cReports /
752 tvLastStatusReport))/1000.0);
753 time_t tNow = time(NULL);
754 char pch[28];
755 memset(pch, 0, sizeof(pch));
756 vrpn_ctime_r(&tNow, pch, sizeof(pch));
757 fprintf(stderr, "\nFlock: reports being sent at %6.2lf hz "
758 "(%d sensors, so ~%6.2lf hz per sensor) ( %s )",
759 dRate, cSensors, dRate/cSensors, pch);
760 tvLastStatusReport = tvNow;
761 cReports=0;
762 // display the rate every STATUS_MSG_SECS seconds
764 }
765#endif
766}
Generic connection class not specific to the transport mechanism.
virtual ~vrpn_Tracker_Flock()
Definition vrpn_Flock.C:277
double getMeasurementRate()
Definition vrpn_Flock.C:238
virtual void reset()
Reset the tracker.
Definition vrpn_Flock.C:303
virtual int get_report(void)
Gets a report if one is available, returns 0 if not, 1 if complete report.
Definition vrpn_Flock.C:532
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
void printError(unsigned char uchErrCode, unsigned char uchExpandedErrCode)
Definition vrpn_Flock.C:30
virtual void send_report(void)
Definition vrpn_Flock.C:711
struct timeval tvLastStatusReport
Definition vrpn_Flock.h:70
unsigned char buffer[VRPN_TRACKER_BUF_SIZE]
virtual void send_report(void)
vrpn_Tracker_Serial(const char *name, vrpn_Connection *c, const char *port="/dev/ttyS1", long baud=38400)
vrpn_float64 d_quat[4]
vrpn_int32 d_sensor
vrpn_float64 pos[3]
void print_latest_report(void)
struct timeval timestamp
#define VRPN_API
#define STATUS_MSG_SECS
Definition vrpn_Flock.C:28
#define poll()
Definition vrpn_Flock.C:688
#define WTF
#define VRPN_FLOCK_MAX_SENSORS
Definition vrpn_Flock.h:11
class VRPN_API vrpn_Connection
Definition vrpn_Flock.h:8
int vrpn_write_characters(int comm, const unsigned char *buffer, size_t bytes)
Write the buffer to the serial port.
int vrpn_set_rts(int comm)
int vrpn_flush_input_buffer(int comm)
Throw out any characters within the input buffer.
int vrpn_drain_output_buffer(int comm)
Wait until all of the characters in the output buffer are sent, then return.
int vrpn_read_available_characters(int comm, unsigned char *buffer, size_t bytes)
int vrpn_flush_output_buffer(int comm)
Throw out any characters (do not send) within the output buffer.
int vrpn_clear_rts(int comm)
vrpn_Serial: Pulls all the serial port routines into one file to make porting to new operating system...
double vrpn_TimevalMsecs(const timeval &tv)
timeval vrpn_TimevalDiff(const timeval &tv1, const timeval &tv2)
void vrpn_SleepMsecs(double dMilliSecs)
#define vrpn_gettimeofday
Definition vrpn_Shared.h:99
const int vrpn_TRACKER_FAIL
const int vrpn_TRACKER_RESETTING
const int vrpn_TRACKER_SYNCING
const int vrpn_TRACKER_PARTIAL