1 /*************** <auto-copyright.pl BEGIN do not edit this line> **************
2  *
3  * VR Juggler is (C) Copyright 1998, 1999, 2000 by Iowa State University
4  *
5  * Original Authors:
6  *   Allen Bierbaum, Christopher Just,
7  *   Patrick Hartling, Kevin Meinert,
8  *   Carolina Cruz-Neira, Albert Baker
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the
22  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23  * Boston, MA 02111-1307, USA.
24  *
25  * -----------------------------------------------------------------
26  * File:          aFlock.h,v
27  * Date modified: 2000/10/30 16:06:01
28  * Version:       1.21
29  * -----------------------------------------------------------------
30  *
31  *************** <auto-copyright.pl END do not edit this line> ***************/
32 
33 #pragma once
34 
35 //===============================================================
36 // Aflock
37 //
38 // Purpose:
39 //      Ascention Flock of birds tracking class
40 //
41 // Author:
42 //      Kevin Meinert
43 //      modified for white_dune by J. "MUFTI" Scheurich
44 //      using things from HeadTracker/I3Stick API by J. Dean Brederson
45 //
46 //      the streaming mode of the orginal VRjuggler Ascention Flock of birds
47 //      tracking class seams to be not a good idea for white_dune...
48 //
49 //      TODO: maybe you should not trust calfile/initCorrectionTable....
50 //
51 // Last Modified: Oct 11 2002
52 
53 // white_dune assumes the following configuration:
54 
55 // FOBs with single RS232 Interface to Host Computer
56 // (see "The flock of Birds, Installation and Operation Guide, Standalone
57 //  and Multiple Transmitter/Multiple Sensors Configurations", Page 3
58 //  (Capture "Introduction"), Figure 2)
59 
60 // +-------------+
61 // | Users Host  |
62 // | Computer    |
63 // |             |
64 // |  RS232      |
65 // +----+--------+
66 //      |           +----------------+----------------+------------
67 //      |           |                |                |
68 //      |           |                |                |
69 //  +---+-----------+------+   +-----+-----+    +-----+-----+
70 //  | RS232        FBB     |   |    FBB    |    |    FBB    |
71 //  |                      |   |           |    |           |
72 //  | Master (transmitter) |   |  Slave 1  |    |  Slave 2  |
73 //  |                      |   |           |    |           |
74 //  | 1. unit (fobadress)  |   |  2. unit  |    |  3. unit  |
75 //  +----------------------+   +-----------+    +-----------+
76 
77 //===============================================================
78 
79 //do not use
80 //#define USE_AFLOCK_QUATERNION 1
81 
82 // standard range transmitter: 36 or 72 INCH (1 INCH = 0.0254 meter)
83 // #define POSITION_RANGE 36.0*0.0254
84 // #define POSITION_RANGE 72.0*0.0254
85 
86 // extended range transmitter: 144 INCH (1 INCH = 0.0254 meter)
87 #define POSITION_RANGE 144.0*0.0254
88 
89 #define ANGLE_RANGE 180.0f
90 #define MAX_SENSORS 128
91 
92 // number of accectable READ (no data) errors
93 #define MAX_READ_ERRORS 100
94 
95 // error timeout to wait between drain and flush (in usleep units)
96 #define ERROR_TIMEOUT 1000
97 
98 /*  #ifndef _BOOL */
99 /*  typedef bool int; */
100 /*  #define true 1 */
101 /*  #define false 0 */
102 /*  #endif */
103 
104 typedef struct {
105         float xmin, ymin, zmin;
106         float xmax, ymax, zmax;
107         float xloc[15][10][15],yloc[15][10][15],zloc[15][10][15];
108 } CalStruct;
109 
110 enum BIRD_HEMI  {FRONT_HEM, AFT_HEM, UPPER_HEM, LOWER_HEM, LEFT_HEM, RIGHT_HEM};
111 typedef int BIRD_FILT;
112 #define AC_NARROW 4
113 #define AC_WIDE 2
114 #define DC_FILTER 1
115 #define FILTER_DEFAULT 0
116 
117 //: class for running a Flock of Birds.
118 //  Aflock is a positional device driver for the Flock of Birds <br>
119 //!PUBLIC_API
120 class Aflock
121 {
122 public:
123         //: Configure Constructor
124         //! ARGS: port - such as "/dev/ttyd3"                         <BR>
125         //! ARGS: baud - such as 38400, 19200, 9600, 14400, etc...    <BR>
126         //! ARGS: sync - sync type.                                   <BR>
127         //! ARGS: block - blocking                                    <BR>
128         //! ARGS: numBrds - number of birds in flock                  <BR>
129         //                  (without transmitter !)                   <BR>
130         //! ARGS: transmit - transmitter unit number,                 <BR>
131         //! ARGS: hemi - hemisphere to track from,                    <BR>
132         //! ARGS: filt - filtering type,                              <BR>
133         //! ARGS: report - flock report rate.                         <BR>
134         //! ARGS: calfile - a calibration file, if "", then use none. <BR>
135         //                                                       <BR>
136         //! POST: configures internal data members,
137         //+         doesn't actually talk to the FOB yet.
138         Aflock(const char* const port = SERIAL_DEVICE,
139                 const int& baud = 38400,
140                 const int& sync = 0,
141                 const int& block = 0,
142                 const int& numBrds = 3,
143                 const int& transmit = 1,
144                 const BIRD_HEMI& hemi = RIGHT_HEM,
145                 const BIRD_FILT& filt = FILTER_DEFAULT,
146                 const bool& sudden_lock = true,
147                 const char& report = 'R',
148                 const char* const calfile = "");
149 
150 
151         //: Destructor
152         ~Aflock();
153 
154 
155         //: call this to connect to the flock device.
156         //  NOTE: flock.isActive() must be false to use this function
157         int start();
158 
159         //: stop the flock
160         int stop();
161 
162         //: call this repeatedly to request data from the birds
163         //  get the data later with flock.sample()
164         //  NOTE: flock.isActive() must be true to use this function
165         int prepareSample();
166 
167         //: call this repeatedly to read the data from the birds.
168         //  NOTE: flock.isActive() must be true to use this function
169         int sample();
170 
171         //: destroy remaining dirt on the port to recover from errors
172         void destroyDirt();
173 
174         //: see if the flock is active or not
175         const bool& isActive() const;
176 
177         //: set the port to use
178         //  this will be a string in the form of the native OS descriptor <BR>
179         //  ex: unix - "/dev/ttyd3", win32 - "COM3" <BR>
180         //  NOTE: flock.isActive() must be false to use this function
181         void setPort( const char* const serialPort );
182 
183         //: get the port used
184         //  this will be a string in the form of the native OS descriptor <BR>
185         //  ex: unix - "/dev/ttyd3", win32 - "COM3"
186         const char* getPort() const;
187 
188 
189         //: set the baud rate
190         //  this is generally 38400, consult flock manual for other rates. <BR>
191         //  NOTE: flock.isActive() must be false to use this function
192         void setBaudRate( const int& baud );
193 
194         //: get the baud rate
195         //  this is generally 38400, consult flock manual for other rates. <BR>
getBaudRate()196         inline const int&  getBaudRate()  const { return m_baud;}
197 
198         //: Set the unit number of the transmitter
199         //  give - an integer that is the same as the dip switch
200         //         setting on the transmitter box (for the unit number) <BR>
201         //  NOTE: flock.isActive() must be false to use this function
202         void setTransmitter( const int& Transmit );
203 
204         //: Get the unit number of the transmitter
205         //  returns - an integer that is the same as the dip switch
206         //         setting on the transmitter box (for the unit number) <BR>
getTransmitter()207         inline const int&  getTransmitter() const { return m_xmitterUnitNumber; }
208 
209 
210         //: Set the number of birds to use in the flock.
211         //  give - an integer number not more than the number of
212         //         birds attached to the system <BR>
213         //  NOTE: flock.isActive() must be false to use this function
214         void setNumBirds( const int& n );
215 
216         //: Get the number of birds to use in the flock.
217         //  returns - an integer number not more than the number of
218         //         birds attached to the system <BR>
getNumBirds()219         inline const int&  getNumBirds() const { return m_numBirds; }
220 
221 
222         //: set the video sync type
223         //  this option allows the Flock to syncronize its pulses with
224         //  your video display.  This will eliminate most flicker caused
225         //  by the magnetic distortion. <BR>
226         //  - Refer to your flock manual for what number to use.
227         //  NOTE: flock.isActive() must be false to use this function
228         void setSync( const int& sync );
229 
230         //: Get the video sync type
231         //  this option allows the Flock to syncronize its pulses with
232         //  your video display.  This will eliminate most flicker caused
233         //  by the magnetic distortion. <BR>
234         //  - Refer to your flock manual for what the return number means
getSync()235         inline const int&  getSync() const {return m_syncStyle; }
236 
237 
238         //: Set blocking of flock
239         //  see flock manual for details.
240         //  NOTE: flock.isActive() must be false to use this function
241         void setBlocking( const int& blVal );
242 
243         //: Get blocking flock's blocking type
244         //  see flock manual for details.
getBlocking()245         inline const int&  getBlocking() const { return m_blocking; }
246 
247 
248         //: Set the type of filtering that the flock uses
249         //  NOTE: flock.isActive() must be false to use this function
250         void setFilterType( const BIRD_FILT& f );
251 
252         //: Set the type of filtering that the flock uses
getFilterType()253         inline const BIRD_FILT&  getFilterType() const { return m_filter; }
254 
255         //: Set if sudden output changes of a bird are locked
256         //  NOTE: flock.isActive() must be false to use this function
257         void setSuddenOutputChangeLock( const bool& b );
258 
259         //: Set the type of filtering that the flock uses
getSuddenOutputChangeLock()260         inline const bool&  getSuddenOutputChangeLock() const
261                     { return m_sudden_output_change_lock; }
262 
263 
264         //: Set the hemisphere that the transmitter transmits from.
265         //  NOTE: flock.isActive() must be false to use this function
266         void setHemisphere( const BIRD_HEMI& h );
267 
268         //: Set the hemisphere that the transmitter transmits from.
getHemisphere()269         inline const BIRD_HEMI&  getHemisphere() const {return m_hemisphere; }
270 
271 
272         //: Set the report rate that the flock uses
273         //  NOTE: flock.isActive() must be false to use this function
274         void setReportRate( const char& rRate );
275 
276         //: Set the report rate that the flock uses
getReportRate()277         inline const char& getReportRate() const {return m_reportRate; }
278 
279 
280         //: get the x position of the i'th bird
281         float& xPos( const int& i );
282 
283         //: get the y position of the i'th bird
284         float& yPos( const int& i );
285 
286         //: get the z position of the i'th bird
287         float& zPos( const int& i );
288 
289 #ifdef USE_AFLOCK_QUATERNION
290         //: get the rotation of the i'th bird as quaternion
291         float& xQuat( const int& i );
292         float& yQuat( const int& i );
293         float& zQuat( const int& i );
294         float& wQuat( const int& i );
295 #else
296         //: get the z rotation of the i'th bird
297         float& zRot( const int& i );
298 
299         //: get the y rotation of the i'th bird
300         float& yRot( const int& i );
301 
302         //: get the x rotation of the i'th bird
303         float& xRot( const int& i );
304 #endif
305 
306 // public methods
307 public:
308         //: with the calibration table info, correct a given position
309         //  give - a position in x, y, z euclidian coordinates
310         //  returns - a corrected position in x, y, z euclidian coordinates
311         void positionCorrect( float& x, float& y, float& z );
312 
313         //: init the correction table from a file
314         //  give - a file name of the calibration file.
315         //  result - initializes the correction table with the file's info
316         void initCorrectionTable( const char* const );
317 
318         //: get number of devices
319         //  (including master, if master is use a receiver)
320         int getNumberDevices(void) const;
321 
322         //: set that the master ("transmitter") deliver data
setMasterUseReceiver(void)323         void        setMasterUseReceiver(void) { m_masterUseReceiver=true; }
324 
325         bool        deliverData(int birdaddr);
326 
327 // Private data members
328 private:
329         CalStruct   caltable;
330         char        m_reportRate;
331         BIRD_HEMI   m_hemisphere;
332         BIRD_FILT   m_filter;
333         bool        m_sudden_output_change_lock;
334 
335         static const int   MAXCHARSTRINGSIZE;
336         char m_port[256];
337         char m_calibrationFileName[256];
338 
339         int m_portId;
340         int m_baud;
341         int m_syncStyle;
342         int m_blocking;
343         int m_numBirds;
344         int m_xmitterUnitNumber;
345         bool m_usingCorrectionTable;
346 
347         unsigned char* m_groupbuffer;
348         int m_grouplength;
349 
350         bool        m_samplePrepared;
351 
352         // do the master ("transmitter") deliver data ?
353         // a ERC as master do not deliver data
354         // a "normal Bird unit" as master do deliver data
355         bool        m_masterUseReceiver;
356 
357         // x,y,z
358         float m_position[MAX_SENSORS][3];
359 #ifdef USE_AFLOCK_QUATERNION
360         // x,y,z,w
361         float m_orientation[MAX_SENSORS][4];
362 #else
363         // r,y,p
364         float m_orientation[MAX_SENSORS][3];
365 #endif
366 
367         bool m_active;
368 
369 // bird functions.
370 private:
371         float rawToFloat(float factor, unsigned char& r1, unsigned char& r2);
372         float rawToQuat(unsigned char& r1, unsigned char& r2);
373         void  pickBird(const int& sensor, const int& port_id);
374         int   open_port(const char* const serialPort, const int& baud, int& port_id );
375         void  set_blocking(const int& port, const int& blocking);
376         void  set_sync(const int& port, const int& sync);
377         void  set_hemisphere(const int& port, const BIRD_HEMI& hem, const int& transmitter);
378         void  set_rep_and_stream(const int& port, const char& repRate);
379         void  set_pos_angles(const int& port, const int& transmitter);
380         void  set_pos_quat(const int& port, const int& transmitter);
381         void  set_filter(const int& port, const BIRD_FILT& filter);
382         void  set_transmitter(const int& port, const int& transmitter);
383         void  set_autoconfig(const int& port);
384         void  set_group(const int& port);
385         void  set_sudden_output_change_lock(const int& port,bool lock);
386         static const int mSleepFactor;
387 };
388 
389 #ifdef HAVE_AFLOCK_DEBUG
390 #define AFLOCK_PRINT(message) fprintf(stderr,message)
391 #else
392 #define AFLOCK_PRINT(message)
393 #endif
394