vrpn  07.33
Virtual Reality Peripheral Network
vrpn_Tracker_NDI_Polaris.h
Go to the documentation of this file.
1 
2 //TODO
3 
4 //---Do I really need a reset? If we add one, we'll need to either store
5 //the filenames of each .rom file, or store the contents of
6 //the files themselves. The NDI Polaris needs theses files to be uploaded
7 //to the tracker, over the serial port, each time we connect to it.
8 
9 //---do update_rate affect only the rate at which tracker reports are
10 //generated, or also the rate at which they are sent?
11 
12 //---read frame # from tracker and avoid sending duplicate reports
13 //(if this runs at faster than 60Hz)
14 
15 //---test on other platforms (only tested on WinXP so far)
16 
17 //---add support for
18 
19 
20 
21 // This server works with the NDI Polaris Spectra and Polaris Vectra
22 // trackers. It doesn't work with the Optitrak or Aurora. It only
23 // handles rigid bodies made from passive sphere markers, and does
24 // not yet support active led markers nor single "stray" passive
25 // spheres.
26 
27 // Each vrpn "sensor" is a single rigid body (or "tool" in NDI
28 // terminology), which consists of 3 or more passive spheres in a
29 // particular geometric arrangement. In order to define a custom
30 // rigid body (one that didn't come from NDI), you must use the NDI
31 // Architect software. That software produces .rom files for each
32 // rigid body. This vrpn tracker class will load those files during
33 // initialization.
34 
35 // Before configuring the vrpn server here, you should first run
36 // the NDI software to track the rigid bodies using the NDI's
37 // interactive GUI. Only after you have configured and tested the
38 // tracker and rigid bodies to your satisfaction, should you try
39 // this vrpn server.
40 
41 // This currently only handles an IR strobe rate of 60Hz, not
42 // 20Hz or 30Hz.
43 
44 
45 // The NDI Polaris Vectra and Spectra communicates with the host over
46 // the serial port, but this VRPN Tracker isn't a sub-class of
47 // vrpn_Tracker_Serial. Perhaps a future version of this class should
48 // be. Here are some potential differences between this Tracker class
49 // and the other serial port trackers:
50 //
51 // 1) The host must connect at a fixed 9600 baud rate at first, but
52 // then switches to a faster rate. This should happen each time the
53 // tracker server initializes, and after each reset. And the com port
54 // isn't really a com port - it's a virtual com port that runs over
55 // NDI's own USB device. When we tell the host to connect at 19200 baud
56 // (on Windows), it really runs at 1.2Mbps.
57 //
58 // 2) While other trackers consciously send tracker report to the
59 // host, the NDI Polaris trackers do not. Instead, they wait for
60 // a command from the host, then immediately (< 17 ms later) send a
61 // single reply back. The host asks for a single trackerport at a
62 // time (using the "TX" command). Because of the 1.2Mbps connection
63 // speed, it seems reasonable (to me) to simply block and wait for the
64 // response, rather than return control back to the caller and then
65 // processing the response later.
66 
67 #ifndef VRPN_TRACKER_NDI_POLARIS_H
68 #define VRPN_TRACKER_NDI_POLARIS_H
69 
70 #include <stddef.h> // for NULL
71 
72 #include "vrpn_Configure.h" // for VRPN_API
73 #include "vrpn_Tracker.h" // for vrpn_Tracker
74 
76 
78 
79 public:
86 
87  vrpn_Tracker_NDI_Polaris(const char *name,
88  vrpn_Connection *c,
89  const char *port,
90  int numOfRigidBodies,
91  const char** rigidBodyNDIRomFileNames);
92 
94 
95  virtual void mainloop();
96 
97 protected:
98 
99  // constants, that are enums instead of const ints, to allow VC6 compatibility
100  // Other vrpn objects appear to put the globals in the global scope?
101  enum { NDI_ROMFILE_CHUNK_SIZE=64};
102  enum { MAX_NDI_ROM_FILE_SIZE_IN_BYTES=1024};
103  enum { MAX_NDI_RESPONSE_LENGTH=300} ; //FIXME look up what the longest response the NDI tracker will send back
104  enum { VRPN_MSGBUFSIZE=1024};
105 
106 
107 int serialFd; //the fid for the serial port
109 unsigned char* latestResponseStr;
110 
111 
112 protected:
113  // FIXME - do I need a reset() method?
114  virtual int get_report(void);
115  virtual void send_report(void);
116 
117 // Send a command to the NDI tracker over the serial port.
118 // This assumes the serial port has already been opened.
119 // Some NDI commands require a white-space char at the end of the command, the
120 // call must be sure to add it.
121 // NDI commands end with a Carriage-return (\r) char. This function automatically adds it, and
122 // flushes the output buffer.
123 // commandString MUST be terminated with \0, since we don't know the string
124 // length otherwise.
125 // The NDI trackers have two different command syntaxes - this only supports the syntax
126 // WITHOUT CRC checksums
127 
128  void sendCommand(const char* commandString );
129 
130 // Read a fully formed responses from the NDI tracker, (including the 4-byte CRC at the end)
131 // and copies it to latestResponseString.
132 // Returns the number of characters in the response (not including the CR),
133 // or -1 in case of an error
134 // NDI responses are all terminated with a CR, which this function replace with a end-of-string char.
135 //
136 // This function blocks until the CR has been received.
137 // FIXME: add a timeout parameter, and timeout if it's been too long
138  int readResponse();
139 
140 // Given a filename of a binary .rom file, this reads the file and returns
141 // a string with the contents of the file as ascii encoded hex: For each byte of
142 // the file, this returns two ascii characters, each of which are ascii representation
143 // of a HEX digit (0-9 & a-f). Hex letters are returned as lower case.
144 // The string is padded with zeros to make it's length a multiple of 128
145 // characters( which is 64 bytes of the original binary file).
146 // asciiEncodedHexStr must be allocated before calling, be
147 // MAX_NDI_FROM_FILE_SIZE_IN_BYTES * 2 characters long.
148 //
149 // RETURNS the number of bytes represented in the string (which is half the number of ASCII characters)
150 // , or -1 on failure
151  int convertBinaryFileToAsciiEncodedHex(const char* filename, char *asciiEncodedHexStr);
152 
153 // NDI response strings often encode ints as a two ascii's WITHOUT any separator behind it
154 // this returns the value as an int.
155 // The caller passes in the string, and a pointer to an (int) index into that string (which will be advanced
156 // to the end of the value we just parsed.
157 // The caller must make sure the string is at least two characters long
158  unsigned int parse2CharIntFromNDIResponse(unsigned char* str, int* strIndexPtr=NULL);
159 
160 // NDI TX response strings often encode floats as a size ascii's WITHOUT any separator behind it
161 // this returns the value as an float. The last 4 digits are implicitly to the right of the decimal point
162 // (the decimal point itself is not in the string)
163 // The caller passes in the string, and a pointer to an (int) index into that string (which will be advanced
164 // to the end of the value we just parsed.
165 // The caller must make sure the string is at least six characters long
166  float parse6CharFloatFromNDIResponse(unsigned char* str, int* strIndexPtr);
167 
168 // NDI TX response strings often encode floats as a size ascii's WITHOUT any separator behind it
169 // this returns the value as an float. The last 2 digits are implicitly to the right of the decimal point
170 // (the decimal point itself is not in the string)
171 // The caller passes in the string, and a pointer to an (int) index into that string (which will be advanced
172 // to the end of the value we just parsed.
173 // The caller must make sure the string is at least seven characters long
174  float parse7CharFloatFromNDIResponse(unsigned char* str, int* strIndexPtr);
175 
176  int setupOneTool(const char* NDIToolRomFilename);
177 
178  void switchToHigherBaudRate(const char* port);
179 
180 };
181 
182 #endif
vrpn_Tracker.h
vrpn_Tracker
Definition: vrpn_Tracker.h:49
vrpn_Tracker_NDI_Polaris::numOfRigidBodies
int numOfRigidBodies
Definition: vrpn_Tracker_NDI_Polaris.h:108
vrpn_BaseClass::mainloop
virtual void mainloop()=0
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
vrpn_Connection
Generic connection class not specific to the transport mechanism.
Definition: vrpn_Connection.h:510
vrpn_Tracker_NDI_Polaris::serialFd
int serialFd
Definition: vrpn_Tracker_NDI_Polaris.h:107
vrpn_Tracker_NDI_Polaris
Definition: vrpn_Tracker_NDI_Polaris.h:77
vrpn_Tracker_NDI_Polaris::latestResponseStr
unsigned char * latestResponseStr
Definition: vrpn_Tracker_NDI_Polaris.h:109
vrpn_Configure.h
VRPN_API
#define VRPN_API
Definition: vrpn_Configure.h:646