2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
33 int iglasses_headset_installed=0;
35 void iglasses_close_tracking();
42 #define FILTER_LENGTH 6
43 typedef struct filter {
44 fix history[FILTER_LENGTH];
45 fix weights[FILTER_LENGTH];
47 fix * hCurrent,* hEnd,* hRestart;
50 void initFIR(filter * f);
51 fix filterFIR(filter * f,fix newval);
52 static filter X_filter, Y_filter, Z_filter;
55 void iglasses_init_tracking(int serial_port)
60 if (iglasses_headset_installed) return;
62 if ( (serial_port < 1) || (serial_port > 4) ) {
63 Error( TXT_IGLASSES_ERROR_1 );
66 printf( TXT_IGLASSES_INIT, serial_port );
67 printf( "\n%s\n", TXT_IGLASSES_ON);
68 printf( "Looking for glasses - %s", TXT_PRESS_ESC_TO_ABORT);
69 Iport = PortOpenGreenleafFast(serial_port-1, 9600, 'N', 8, 1 );
71 printf( "%s\n", TXT_SERIAL_FAILURE, Iport->status );
77 UseRtsCts( Iport, 0 );
79 t2 = timer_get_fixed_seconds() + i2f(20);
81 while(timer_get_fixed_seconds() < t2) {
83 t1 = timer_get_fixed_seconds() + F1_0;
86 WriteBuffer( Iport, "!\r", 2 );
87 while ( timer_get_fixed_seconds() < t1 ) {
88 if ( key_inkey() == KEY_ESC ) goto NotOK;
89 c = ReadChar( Iport );
97 printf( "\n\nWarning: Cannot find i-glasses! on port %d\n"
98 " Press Esc to abort D2, any other key to continue without i-glasses support.\n"
99 " Use SETUP to disable i-glasses support.\n",serial_port);
100 if ( key_getch() == KEY_ESC )
109 t1 = timer_get_fixed_seconds() + F1_0;
110 ClearRXBuffer(Iport);
111 ClearTXBuffer(Iport);
114 WriteBuffer( Iport, "!M1,P,B\r", 8 );
115 while ( timer_get_fixed_seconds() < t1 ) {
116 if ( key_inkey() == KEY_ESC ) return;
117 c = ReadChar( Iport );
127 ClearRXBuffer(Iport);
128 ClearTXBuffer(Iport);
130 WriteChar( Iport, 'S' );
132 iglasses_headset_installed = 1;
133 atexit( iglasses_close_tracking );
136 initFIR( &X_filter );
137 initFIR( &Y_filter );
138 initFIR( &Z_filter );
144 // iglasses_read_headset( &y, &p, &r);
145 // //printf( "%d\t%d\t%d\n", y, p, r );
146 // printf( "%8.2f\n", f2fl(y) );
147 // if (key_inkey()==KEY_ESC) break;
153 void iglasses_close_tracking() {
154 if ( iglasses_headset_installed ) {
155 iglasses_headset_installed = 0;
161 //UNUSED int iglasses_read_headset1( fix *yaw, fix *pitch, fix *roll )
164 //UNUSED static unsigned char buff[8];
165 //UNUSED unsigned char checksum;
166 //UNUSED int i,count;
168 //UNUSED ReadBufferTimed(Iport, buff, 8, 1000);
169 //UNUSED checksum = 0;
170 //UNUSED count = Iport->count;
171 //UNUSED for (i=0; i < 7; i++) checksum += buff[i];
172 //UNUSED if ( (count < 8) || (checksum != buff[7]) ) {
173 //UNUSED ClearRXBuffer(Iport);
174 //UNUSED WriteChar( Iport, 'S' );
175 //UNUSED *yaw = *pitch = *roll = 0;
178 //UNUSED WriteChar( Iport, 'S' );
180 //UNUSED y = (short)(buff[1] << 8) | buff[2];
181 //UNUSED p = (short)(buff[3] << 8) | buff[4];
182 //UNUSED r = (short)(buff[5] << 8) | buff[6];
191 #define M_PI 3.14159265358979323846264338327950288
193 #define TO_RADIANS (M_PI/FBITS)
194 #define TO_DEGREES (180./M_PI)
195 #define TO_FIX (0.5/M_PI)
201 int Num_readings = 0;
202 fix BasisYaw, BasisPitch, BasisBank;
204 int iglasses_read_headset( fix *yaw, fix *pitch, fix *roll )
206 static unsigned char buff[16];
207 float radPitch,radRoll,sinPitch,sinRoll,cosPitch,cosRoll;
208 float rotx,roty,rotz;
211 unsigned char checksum;
214 ReadBufferTimed(Iport, buff, 12, 10 ); // Wait 1/100 second for timeout.
216 count = Iport->count;
217 ClearRXBuffer(Iport);
218 WriteChar( Iport, 'S' );
219 for (i=0; i < 11; i++) checksum += buff[i];
220 if ( (count < 12) || (checksum != buff[11]) ) {
227 x = (short)(buff[1] << 8) | buff[2];
228 y = (short)(buff[3] << 8) | buff[4];
229 z = (short)(buff[5] << 8) | buff[6];
230 p = (short)(buff[7] << 8) | buff[8];
231 r = (short)(buff[9] << 8) | buff[10];
236 radPitch = (float)p*TO_RADIANS;
237 radRoll = (float)r*TO_RADIANS;
238 sinPitch = sin(radPitch);
239 cosPitch = cos(radPitch);
240 sinRoll = sin(radRoll);
241 cosRoll = cos(radRoll);
243 roty = cosPitch*fy - sinPitch*fz;
244 rotz = sinPitch*fy + cosPitch*fz;
245 rotx = cosRoll*fx - sinRoll*roty;
248 *yaw = filterFIR( &X_filter,fl2f(-atan2(rotz,rotx)*M_PI/2.0));
249 *pitch = filterFIR( &Y_filter,fl2f(-radPitch*M_PI/2.0));
250 *roll = filterFIR( &Z_filter,fl2f(radRoll*M_PI/2.0));
251 if ( Num_readings < 30 ) {
258 *pitch -= BasisPitch;
261 *yaw = fl2f(-atan2(rotz,rotx)*M_PI/2.0);
262 *pitch = fl2f(-radPitch*M_PI/2.0);
263 *roll = fl2f(radRoll*M_PI/2.0);
275 void initWeights(filter * f)
282 for (i=0; i < f->len; i++) {
283 //f->weights[i] = i; // Linear ramp
284 //f->weights[i] = i*i; // Exp ramp
285 f->weights[i] = F1_0; // Average
290 for (i=0; i < f->len; i++) {
291 sum += f->weights[i];
294 // Normalize and convert to fixed point.
295 for (i=0; i < f->len; i++) {
296 f->weights[i] = fixdiv(f->weights[i],sum);
300 void initHistory(filter * f)
303 for (i=0; i < f->len; i++) {
304 f->history[i] = F1_0;
306 f->hCurrent = f->history;
307 f->hEnd = &f->history[f->len-1];
308 f->hRestart = &f->history[-1];
311 void initFIR(filter * f)
313 f->len = FILTER_LENGTH;
318 fix filterFIR(filter * f,fix newval)
326 weightp = f->weights;
328 *(f->hCurrent)++ = newval;
329 if (f->hCurrent == &f->history[f->len]) f->hCurrent = f->history;
331 // Compute FIR filter
334 sum += fixmul( (*currp--), (*weightp++) );
335 if (currp == f->hRestart) currp = f->hEnd;
336 if (currp == last) break;