/Users/craigcornelius/Projects/SPRING Mac Release 0.2/bird.cpp

Go to the documentation of this file.
00001 // $Id: bird.cpp,v 1.30 2006/05/24 16:52:40 sean Exp $
00002 //
00003 // Upgraded to now also use the new Ascension beta library
00004 //
00005 #define USE_NEW_LIBRARY
00006 
00007 
00008 #if defined(_WIN32) && defined(USE_NEW_LIBRARY)
00009 
00010 
00011 // stdafx.h : include file for standard system include files,
00012 //  or project specific include files that are used frequently, but
00013 //      are changed infrequently
00014 //
00015 
00016 // #define VC_EXTRALEAN         // Exclude rarely-used stuff from Windows headers
00017 
00018 #include <afxwin.h>         // MFC core and standard components
00019 #include <afxext.h>         // MFC extensions
00020 #ifndef _AFX_NO_AFXCMN_SUPPORT
00021 #include <afxcmn.h>                     // MFC support for Windows 95 Common Controls
00022 #endif // _AFX_NO_AFXCMN_SUPPORT
00023 
00024 
00025 #include "pcBird.h"
00026 
00027 
00028 // Group ID #
00029 #define GROUP_ID                                0
00030 
00031 // ISA connection info
00032 #define ISA_BASE_ADDRESS                0x304
00033 
00034 #define DeviceNum  1    // which receiver
00035 
00036 #include "bird.h"
00037 const char* Bird::rcsid = "@(#) $Id: bird.cpp,v 1.30 2006/05/24 16:52:40 sean Exp $ $Copyright: (c)2001 National Biocomputation Center, Stanford University $";
00038 
00039 int Bird::debug = 0;
00040 
00041 
00042 Bird::Bird(char* port_name_in, int baud, int num_birds_if_master, 
00043         return_values_enum return_values_in)
00044         : Sensor(Sensor::bird_sensor), SerialDevice(port_name_in, baud)
00045 {
00046         if (debug)
00047           cerr << "Bird::Bird(\"" << port_name_in << "\", " << baud << ", "
00048                    << num_birds_if_master << ", " << int(return_values_in) << ")\n";
00049 
00050         // locals
00051         int m_bStandAlone = 0;
00052         int m_nNumDevices = 1;
00053         WORD m_pwAddress[10]; m_pwAddress[1] = ISA_BASE_ADDRESS;
00054         int m_dwReadTimeout = 1000;
00055         int m_dwWriteTimeout = 1000;
00056 
00057         // Enable displaying of error dialogs.
00058         birdDisplayErrorDialogs(TRUE);
00059 
00060         // Wake up the birds in ISA mode.
00061         if (!birdISAWakeUp(GROUP_ID, FALSE, m_nNumDevices, m_pwAddress,
00062                 m_dwReadTimeout, m_dwWriteTimeout)) {
00063                 cerr << "Bird- can't wakeup\n";
00064                 return;
00065         }
00066 
00067         // Get the old system configuration.
00068         BIRDSYSTEMCONFIG syscfg;
00069         if (!birdGetSystemConfig(GROUP_ID, &syscfg)) {
00070                 cerr << "Bird- can't get system config\n";
00071                 return;
00072         }
00073 
00074         // Display the old system configuration.
00075         if (debug) {
00076         fprintf(stderr,"\n\
00077 SYSTEM CONFIGURATION:\n\
00078 System Status: 0x%02X\n\
00079 Error: %d\n\
00080 # Devices: %d\n\
00081 # Servers: %d\n\
00082 Transmitter #: 0x%02X\n\
00083 Measurement Rate: %f\n\
00084 Chassis #: %d\n\
00085 # Chassis Devices: %d\n\
00086 First Device #: %d\n\
00087 Software Revision: 0x%04X\n",
00088                         syscfg.bySystemStatus,
00089                         syscfg.byError,
00090                         syscfg.byNumDevices,
00091                         syscfg.byNumServers,
00092                         syscfg.byXmtrNum,
00093                         syscfg.dMeasurementRate,
00094                         syscfg.byChassisNum,
00095                         syscfg.byNumChassisDevices,
00096                         syscfg.byFirstDeviceNum,
00097                         syscfg.wSoftwareRev);
00098         }
00099 
00100 
00101         { // Change the configuration of each device.
00102                 // Get the old device configuration.
00103                 BIRDDEVICECONFIG devcfg;
00104                 if (!birdGetDeviceConfig(GROUP_ID, DeviceNum, &devcfg)) {
00105                         cerr << "Bird-can't get device config #1\n";
00106                         return;
00107                 }
00108 
00109                 // Change the device configuration so that the data format
00110                 //  is position/quaternion.
00111                 devcfg.byDataFormat = BDF_POSITIONMATRIX;
00112                 devcfg.byHemisphere = BHC_REAR;
00113 
00114 #ifdef DO_FILTERING
00115                 // if to setup for filtering
00116                 devcfg.bySetup = BDS_ACWIDENOTCHFILTER | BDS_DCFILTER;
00117                 for (int i = 0; i < 7; i++)
00118                 {
00119                         devcfg.wAlphaMin[i] = 655;
00120                         devcfg.wAlphaMax[i] = 983;
00121                         devcfg.wVM[i] = 32767;
00122                 }
00123 #endif
00124 
00125                 if (!birdSetDeviceConfig(GROUP_ID, DeviceNum, &devcfg)) {
00126                         cerr << "Bird- can't set device config\n";
00127                         return;
00128                 }
00129 
00130                 // Get the new device configuration.
00131                 if (!birdGetDeviceConfig(GROUP_ID, DeviceNum, &devcfg)) {
00132                         cerr << "Bird-can't get device config #2\n";
00133                         return;
00134                 }
00135 
00136                 // Display the new device configuration.
00137                 if (debug) {
00138                 fprintf(stderr, "\n\
00139 DEVICE %d CONFIGURATION:\n\
00140 Status: 0x%02X\n\
00141 ID: %d\n\
00142 Software Revision: 0x%04X\n\
00143 Error: %d\n\
00144 Setup: 0x%02X\n\
00145 Data Format: %d\n\
00146 Report Rate: %d\n\
00147 Scaling: %d\n\
00148 Hemisphere: %d\n\
00149 Device #: %d\n\
00150 Transmitter Type: 0x%02X\n",
00151                                 DeviceNum,
00152                                 devcfg.byStatus,
00153                                 devcfg.byID,
00154                                 devcfg.wSoftwareRev,
00155                                 devcfg.byError,
00156                                 devcfg.bySetup,
00157                                 devcfg.byDataFormat,
00158                                 devcfg.byReportRate,
00159                                 devcfg.wScaling,
00160                                 devcfg.byHemisphere,
00161                                 devcfg.byDeviceNum,
00162                                 devcfg.byXmtrType);
00163                 }
00164         }  // end device config set
00165 
00166         { // Get a single test reading from each bird.  NOTE: Do NOT use this command in
00167           //  TCP/IP mode - there is no way to get single bird readings.
00168         BIRDREADING reading;
00169         if (!birdStartReading(GROUP_ID, DeviceNum)) {
00170                 cerr << "Bird- can't start reading\n";
00171                 return;
00172         }
00173         if (!birdGetReading(GROUP_ID, DeviceNum, &reading)) {
00174                 cerr << "Bird- can't get reading\n";
00175                 return;
00176         }
00177         }
00178 
00179 }
00180         
00181 
00182 void Bird::Update()
00183 {
00184         BIRDREADING reading;
00185         if (!birdStartReading(GROUP_ID, DeviceNum))
00186                 return;
00187         
00188         if (!birdGetReading(GROUP_ID, DeviceNum, &reading)) {
00189                 if (birdGetErrorCode() == BE_PHASEERROR)
00190                         cerr << "Bird::Update()- Phase Error\n";
00191                 else
00192                         return;
00193         }
00194         
00195         // map the x,y,z (z up) of the transmitter to x,y,z (z out) of the screen
00196         // Note: this already gives us the position in mm, so no need to convert
00197         // Looks like this is wrong: it seems to be in 1/1000 of an inch
00198     pos.x =  reading.position.nY;
00199     pos.y =  -reading.position.nZ;
00200     pos.z =  -reading.position.nX;
00201 
00202         // Convert from 1/1000 of an inch to 1 mm
00203         pos *= 25.4/1000;
00204 
00205         // center off the initial position
00206         pos -= init_pos;
00207 
00208         // scale it based on the scale factor
00209         pos *= scalefactor;
00210 
00211         // convert to standard graphics format and 
00212         // transpose it to make them rotations relative to object
00213         m.m[0][0] = reading.matrix.n[1][1];
00214     m.m[1][0] = -reading.matrix.n[1][2];
00215     m.m[2][0] = -reading.matrix.n[1][0];
00216     m.m[0][1] = -reading.matrix.n[2][1];
00217     m.m[1][1] = reading.matrix.n[2][2];
00218     m.m[2][1] = reading.matrix.n[2][0];
00219     m.m[0][2] = -reading.matrix.n[0][1];
00220     m.m[1][2] = reading.matrix.n[0][2];
00221     m.m[2][2] = reading.matrix.n[0][0];
00222         m.m[0][3] = m.m[1][3] = m.m[2][3] = 0;
00223         m.m[3][0] = m.m[3][1] = m.m[3][2] = 0; 
00224         m.m[3][3] = 1.0;
00225 
00226         { // decode  matrix values
00227                 for (int i=0;i<3; i++) for (int j=0;j<3; j++)
00228                         m.m[i][j] /= 32767.0;
00229         }
00230 
00231 }
00232 
00233 
00234 Bird::~Bird()
00235 {
00236         // Shut down the birds.
00237         birdShutDown(GROUP_ID);
00238 }
00239 
00240 
00241 #else
00242 
00243 #include "bird.h"
00244 const char* Bird::rcsid = "@(#) $Id: bird.cpp,v 1.30 2006/05/24 16:52:40 sean Exp $ $Copyright: (c)2001 National Biocomputation Center, Stanford University $";
00245 
00246 // Streaming versus Polled
00247 //#define STREAMING
00248 
00249 #ifdef _WIN32
00250 #include "pcBird.h"
00251 
00252 #else
00253 #include <strings.h>
00254 #include <unistd.h>
00255 #ifndef __APPLE__
00256 #include <termio.h>
00257 #endif // __APPLE__
00258 #include <fcntl.h>
00259 #include <sys/time.h>
00260 
00261 #ifdef SGI_4D
00262 #include <sys/types.h>
00263 #include <bstring.h>
00264 #elif defined(SUN4)
00265 #include <string.h>
00266 #endif
00267 #endif
00268 
00269 #include <stdio.h>
00270 
00271 // Command set for bird 
00272 #define BIRD_EXAMINE_VALUE      0x4F
00273 #define BIRD_CHANGE_VALUE       0x50
00274 #define BIRD_POSITION           0x56
00275 #define BIRD_ANGLES             0x57
00276 #define BIRD_MATRIX             0x58
00277 #define BIRD_POSITION_ANGLES    0x59
00278 #define BIRD_POSITION_MATRIX    0x5A
00279 #define BIRD_POINT              0x42
00280 #define BIRD_STREAM             0x40
00281 #define BIRD_RUN                0x46
00282 #define BIRD_SLEEP              0x47
00283 #define BIRD_SYNC_CMD           0x41
00284 #define BIRD_CRT_SYNC_LOW       0x01
00285 #define BIRD_CRT_SYNC_HIGH      0x02
00286 #define BIRD_HOST_SYNC          0x80
00287 #define BIRD_RATE1              0x51
00288 #define BIRD_RATE2              0x52
00289 #define BIRD_RATE8              0x53
00290 #define BIRD_RATE32             0x54
00291 #define BIRD_BUTTON_ON          0x01
00292 #define BIRD_BUTTON_OFF         0x00
00293 #define BIRD_SET_BUTTON         0x4d
00294 // set hemisphere stuff (0x06,0x01) are left hemisphere params)
00295 #define BIRD_HEMISPHERE         0x4c
00296 #define BIRD_HEMI_AXIS          0x00    // aft
00297 #define BIRD_HEMI_SIGN          0x01    // aft
00298 #define BIRD_ANGLE_ALIGN2       0x71
00299 // examine values parameters
00300 #define BIRD_CRYSTAL_SPEED      0x02
00301 
00302 #define POSMAX     (36.0 / 32767.0)          /* Position scalling, in inch */
00303 #define ANGMAX     (180.0 / 32767.0)         /* Max angle value */
00304 #define MATMAX     (1.0 / 32767.0)           /* Max matrix value */
00305 
00306 #define BIRD_TIME_OUT 800000                 /* after .8 second we abort */
00307 
00308 // handy macros for converting their representation to/from a short
00309 #define DECODE(b,i) ((short)( ( ((b)[i+1] << 7 ) | ((b)[i] & 0x7f) ) << 2 ))
00310 #define ENCODE_LSB(x)   (short(x) & 0x00ff)
00311 #define ENCODE_MSB(x)   ((short(x) & 0xff00) >> 8)
00312 
00313 int Bird::debug = 0;
00314 
00315 // send bird a request for stream data, initialise bird_buffer, and time outs
00316 void Bird::bird_start_stream()
00317 {
00318         if (!is_master) return;
00319 
00320         if (debug) cerr << "Bird[" << port_name << "]-starting bird stream ...\n";
00321         write_bird(BIRD_RUN);
00322 #ifdef STREAMING
00323     write_bird(BIRD_STREAM);
00324 
00325     /* testing bird connection and phasing bit position */
00326     while ( GetByte() & 0x80 ) {
00327             /* we have located the phasing bit */
00328             break;
00329         }
00330 #endif
00331 
00332         if (debug) cerr << "bird stream started...\n";
00333 }
00334 
00335 void Bird::Sleep()
00336 {
00337         if (debug) cerr << "Bird[" << port_name << "]::Sleep()\n";
00338         write_bird(BIRD_SLEEP);
00339         first_update = 1;       // set flag so we'll restart stream 
00340 }
00341 
00342 /* write to bird one byte of command, return the actual number of 
00343    bytes that have been written */
00344 void Bird::write_bird(unsigned char command)
00345 {
00346     if (debug)
00347 #ifdef LINUX
00348        cerr << "Bird[" << port_name << "]-WRITE_BIRD: 0x" << command << endl;
00349 #else
00350        cerr << "Bird[" << port_name << "]-WRITE_BIRD: 0x" << hex << command
00351                         << dec << endl;
00352 #endif
00353     
00354     SendByte(command);
00355 }
00356 
00357 /* Initialize Flock of Birds */
00358 void Bird::initialize_flock(int num_birds_in_flock)
00359 {
00360     write_bird(BIRD_CHANGE_VALUE);   /* change value */
00361     write_bird(0x32);           /* autoconfiguration */
00362     write_bird(num_birds_in_flock);
00363 }
00364 
00365 
00366 /* Bird():
00367  *      Initialise bird to these conditions:
00368  *      1. open a port
00369  *      2. use left hemisphere
00370  *      3. combine position/angle/button into one packet of 13 bytes
00371  *      4. use stream mode
00372  *      5. use proper bird sync function
00373  *      6. properly locate the phasing bit
00374  *      7. set filters.
00375  * Bird( char *, int );
00376  */
00377 
00378 Bird::Bird(char* port_name_in, int baud, int num_birds_if_master, 
00379         return_values_enum return_values_in)
00380         : Sensor(Sensor::bird_sensor), SerialDevice(port_name_in, baud)
00381 {
00382         if (debug)
00383           cerr << "Bird::Bird(\"" << port_name_in << "\", " << baud << ", "
00384                    << num_birds_if_master << ", " << int(return_values_in) << ")\n";
00385 
00386     // initialization of class variables
00387         is_master = 0;          // assume not
00388     first_update = 1;   // never been updated before
00389     return_values = return_values_in;
00390     for (int i=0; i<3; i++) for (int j=0; j<3; j++) m.m[i][j] = 0.0;
00391         strncpy(port_name, port_name_in, 80);
00392 
00393     // if it is the master, initialize and tell the number of birds in flock
00394     if (num_birds_if_master > 0) {
00395                 is_master = 1;  // hey- we are!
00396         initialize_flock(num_birds_if_master);
00397         }
00398 
00399     switch (return_values) {
00400     case POSITION:              write_bird(BIRD_POSITION); break; // position data only
00401     case ANGLES:                write_bird(BIRD_ANGLES); break; // angles data only
00402     case MATRIX:                write_bird(BIRD_MATRIX); break; // matrix data only
00403     case POSITION_ANGLES:       write_bird(BIRD_POSITION_ANGLES); break; // position/angles data 
00404     case POSITION_MATRIX:       write_bird(BIRD_POSITION_MATRIX); break; // position/matrix data
00405     }
00406 
00407     // set other params
00408     write_bird(BIRD_RATE1);               /* using highest report rate */
00409         write_bird(BIRD_SET_BUTTON);          /* instruct the button...*/
00410     write_bird(BIRD_BUTTON_OFF);           /* to be off, to save xmit time */
00411 
00412     /* Use choosen hemispere */
00413     write_bird(BIRD_HEMISPHERE);              
00414     write_bird(BIRD_HEMI_AXIS);       
00415     write_bird(BIRD_HEMI_SIGN);   
00416 
00417     /* rotate coord system */
00418     //angle_align(0.0, 0.0, 0.0);
00419 
00420     // learn some things about the bird
00421     //write_bird(BIRD_EXAMINE_VALUE);
00422 
00423 /*    turn_off_filters(); */
00424 }
00425 
00426 Bird::~Bird()
00427 {
00428           if (debug) cerr << "Bird[" << port_name << "]::~Bird()\n";
00429 
00430           if (is_master)
00431         Sleep();        // put the bird to bed
00432 }
00433 
00434 void Bird::setCRTsync(sync_enum sync_mode)
00435 {
00436         if (!is_master) return;
00437         if (debug) 
00438                 cerr << "Bird[" << port_name << "]::setCRTsync(" << int(sync_mode) 
00439                          << ")\n";
00440 
00441     /* use the proper sync function */
00442     switch ( sync_mode )
00443     {
00444       case NO_SYNC: break;
00445       case SYNC_CRT_LOW: sync_bird_crt_low(); break;
00446       case SYNC_HOST: sync_bird_host(); break;
00447       case SYNC_CRT_HIGH: sync_bird_crt_low(); break;
00448       default:
00449         fprintf(stderr, "Unknown bird sync mode\n");
00450         break;
00451     }
00452 }
00453 
00454 /* read_bird_stream()
00455  *      Read in bird position/angle/button status, and put in the structure
00456  *      Return 1 if data is properly read-in, 0 if no useful data present
00457  */
00458 char* Bird::read_bird_stream ()
00459 {
00460         if (debug) cerr << "Bird:[" << port_name << "]- read_bird_stream()\n";
00461 
00462 #ifndef STREAMING
00463         write_bird(BIRD_POINT);
00464 #endif
00465 
00466     // determine size of packet
00467     int packet_length = 6;
00468     switch (return_values) {
00469     case POSITION:              packet_length = 6; break;
00470     case ANGLES:                packet_length = 6; break;
00471     case MATRIX:                packet_length = 18; break;
00472     case POSITION_ANGLES:       packet_length = 12; break;
00473     case POSITION_MATRIX:       packet_length = 24; break;
00474     }
00475     //packet_length++;  // for the button value
00476 
00477 
00478     // first, flush leftovers so we have the most up-to-date data (no lag)
00479         // NOTE!!!:  THIS WOULD BE GOOD, EXCEPT IT MEANS THAT WE MUST BE ABLE
00480         // TO BUFFER THE ENTIRE PACKET IN THE UART, WHICH IS NOT TRUE FOR THE
00481         // 16550 (16 byte buffer) WHEN READING IN POSITION_MATRIX MODE. SO, WE
00482         // MOVE THE FLUSH UNTIL AFTER THE READ TO TRY TO KEEP THINGS RELATIVELY
00483         // UP-TO-DATE, BUT THIS IS A HAIRY SITUATION- WE'RE ALMOST GUARANTEED TO
00484         // HAVE OLD DATA THE WAY THIS IS SETUP NOW!!!!
00485         const int uart_buffer_length = 32;  // bytes
00486         if (packet_length < uart_buffer_length)
00487       FlushInputQueue();
00488 
00489     { // read characters, building up the bird buffer
00490       int counter = 0;
00491       do {
00492         int c = GetByte();
00493                 if (c == -1) continue;
00494 
00495         // if found phasing bit, restart packet
00496         if (c & 0x80) counter = 0; 
00497 
00498         // save the char
00499         bird_buffer[counter] = char(c & 0x7f);
00500 
00501         // increment counter with bounds checking
00502         if (counter < BIRD_BUF_SIZE) counter++;
00503       } while (counter < packet_length);
00504     }
00505 
00506         // flush the rest right here
00507         if (packet_length >= uart_buffer_length)
00508           FlushInputQueue();
00509 
00510     // return the buffer
00511     return bird_buffer;
00512 }
00513 
00514 // decode position packet (6 bytes long) into easy-to-use Bird structure
00515 int Bird::decode_position(char* b_b)
00516 {
00517     // decode the output of the bird unit
00518     Point3D decoded_pos;
00519     decoded_pos.x = POSMAX * DECODE(b_b, 0);
00520     decoded_pos.y = POSMAX * DECODE(b_b, 2);
00521     decoded_pos.z = POSMAX * DECODE(b_b, 4);
00522     if (debug)
00523        cerr << "decode_position::decoded_pos = " << decoded_pos << endl;
00524 
00525     // map the x,y,z (z up) of the transmitter to x,y,z (z out) of the screen
00526     pos.x =  decoded_pos.y;
00527     pos.y =  -decoded_pos.z;
00528     pos.z =  -decoded_pos.x;
00529 
00530         // convert to mm from inches
00531         pos *= 25.4;
00532 
00533         // make it relative to the user-chosen origin
00534         pos -= init_pos;
00535 
00536         // scale it based on the scale factor
00537         pos *= scalefactor;
00538 
00539     // return number of chars eaten
00540     return(6);
00541 }
00542 
00543 // decode angle packet (6 bytes long) into easy-to-use Bird structure
00544 int Bird::decode_angles(char* b_b)
00545 {
00546     // decode the output of the bird unit
00547     Point3D decoded_ang;
00548     decoded_ang.x = ANGMAX * DECODE(b_b, 0);
00549     decoded_ang.y = ANGMAX * DECODE(b_b, 2);
00550     decoded_ang.z = ANGMAX * DECODE(b_b, 4);
00551 
00552     // map the x,y,z (z up) of the transmitter to x,y,z (z out) of the screen
00553     //rot.x =  decoded_ang.y;
00554     //rot.y =  decoded_ang.x;
00555     //rot.z =  decoded_ang.z;
00556 
00557     // return number of chars eaten
00558     return(6);
00559 }
00560 
00561 // decode matrix packet (18 bytes long) into easy-to-use Bird structure
00562 int Bird::decode_matrix(char* b_b)
00563 {
00564     // decode the matrix
00565         double decoded_m[3][3];
00566     decoded_m[0][0] = MATMAX * DECODE(b_b, 0);
00567     decoded_m[0][1] = MATMAX * DECODE(b_b, 2);
00568     decoded_m[0][2] = MATMAX * DECODE(b_b, 4);
00569     decoded_m[1][0] = MATMAX * DECODE(b_b, 6);
00570     decoded_m[1][1] = MATMAX * DECODE(b_b, 8);
00571     decoded_m[1][2] = MATMAX * DECODE(b_b, 10);
00572     decoded_m[2][0] = MATMAX * DECODE(b_b, 12);
00573     decoded_m[2][1] = MATMAX * DECODE(b_b, 14);
00574     decoded_m[2][2] = MATMAX * DECODE(b_b, 16);
00575 
00576         // convert to standard graphics format and 
00577         // transpose it to make them rotations relative to object
00578         m.m[0][0] = decoded_m[1][1];
00579     m.m[1][0] = -decoded_m[1][2];
00580     m.m[2][0] = -decoded_m[1][0];
00581     m.m[0][1] = -decoded_m[2][1];
00582     m.m[1][1] = decoded_m[2][2];
00583     m.m[2][1] = decoded_m[2][0];
00584     m.m[0][2] = -decoded_m[0][1];
00585     m.m[1][2] = decoded_m[0][2];
00586     m.m[2][2] = decoded_m[0][0];
00587 
00588     if (debug)
00589           m.Print();
00590 
00591     // return number of chars eaten
00592     return(18);
00593 }
00594 
00595 // decode button packet (1 byte long) into easy-to-use Bird structure
00596 int Bird::decode_button(char* b_b)
00597 {
00598     // the button's just the guy at the end of the stream
00599     active[0] = (b_b[0] & 0x70) ? 1:0;
00600 
00601     // return number of chars eaten
00602     return(1);
00603 }
00604 
00605 // decode position/angle packet (13 bytes long) into easy-to-use Bird structure
00606 int Bird::decode_pos_ang(char* b_b)
00607 {
00608   int num_used = 0;
00609   num_used += decode_position(b_b + num_used);
00610   num_used += decode_angles(b_b + num_used);
00611   return(num_used);
00612 }
00613 
00614 // decode position/angle packet (13 bytes long) into easy-to-use Bird structure
00615 int Bird::decode_pos_mat(char* b_b)
00616 {
00617   int num_used = 0;
00618   num_used += decode_position(b_b + num_used);
00619   num_used += decode_matrix(b_b + num_used); 
00620   return(num_used);
00621 }
00622 
00623 /* bird_button_status():
00624  *      Return > 0 if the button is down, < 0 if up (not been pressed)
00625  *      Refer to birdlib.h for exact meaning of these:
00626  *              BIRD_BUTTON_IS_DOWN 1
00627  *              BIRD_BUTTON_PRESSED 2
00628  *              BIRD_BUTTON_IS_UP -1
00629  *              BIRD_BUTTON_RELEASED -2
00630  */
00631 Bird::button_enum Bird::bird_button_status()
00632 {
00633     static Bird::button_enum last_button_status = Bird::UP;
00634     Bird::button_enum retval = Bird::UP;
00635 
00636     if (active[0])
00637         retval = Bird::DOWN;
00638     else
00639         retval = Bird::UP;
00640 
00641     if ( last_button_status != retval )
00642     {
00643         last_button_status = retval;
00644         //retval += retval;
00645     }
00646     return retval;
00647 }
00648 
00649 /* some trivial routines */
00650 
00651 #ifdef OLD_CODE
00652 /* return current time, in the residule of micro-second */
00653 int Bird::get_mic_time()
00654 {
00655     gettimeofday( &timeval, &timez);
00656     return timeval.tv_usec;
00657 }
00658 
00659 /* return duration since the give value, in microsecond */
00660 int Bird::get_mic_duration(int last)
00661 // int last;                                 /* micro second */
00662 {
00663     int duration;
00664     gettimeofday( &timeval, &timez);
00665     duration = timeval.tv_usec - last;
00666     return ( (duration <0 ) ? (duration + 1000000):duration );
00667 }
00668 #endif
00669 
00670 /* set the bird to use CRT sync */
00671 void Bird::sync_bird_crt_low()
00672 {
00673         write_bird(BIRD_SYNC_CMD);
00674         write_bird(BIRD_CRT_SYNC_LOW);
00675 }
00676 
00677 /* set the bird to use CRT sync */
00678 void Bird::sync_bird_crt_high()
00679 {
00680         write_bird(BIRD_SYNC_CMD);
00681         write_bird(BIRD_CRT_SYNC_HIGH);
00682 }
00683 
00684 /* set the bird to use HOST sync */
00685 void Bird::sync_bird_host()
00686 {
00687         write_bird(BIRD_SYNC_CMD);
00688         write_bird(BIRD_HOST_SYNC);
00689 }
00690 
00691 
00692 void Bird::Update()
00693 {
00694     if (debug) cerr << "Bird[" << port_name << "]::Update()\n";
00695 
00696     // if it's the first time, go into stream mode
00697     if (first_update) {
00698        bird_start_stream();     /* start bird data stream */
00699        first_update = 0;
00700     }
00701 
00702     // do the read
00703     char* packet = read_bird_stream();
00704 
00705     /* decode the packet into usable data structure */
00706     if (packet != NULL) {
00707        int num_used = 0;
00708        switch (return_values) {
00709        case POSITION: num_used += decode_position(packet); break;
00710        case ANGLES: num_used += decode_angles(packet); break;
00711        case MATRIX: num_used += decode_matrix(packet); break;
00712        case POSITION_ANGLES: num_used += decode_pos_ang(packet); break;
00713        case POSITION_MATRIX: num_used += decode_pos_mat(packet); break;
00714        }
00715        packet += num_used;
00716        //num_used += decode_button(packet);
00717     }
00718 }
00719 
00720 
00721 void Bird::turn_off_filters()
00722 {
00723     write_bird(BIRD_CHANGE_VALUE);      /* change command, check page 23 of Bird manual*/
00724     write_bird(0x04);           /* PARAMETERnumber 4, filters, check page24 */     
00725     write_bird(0x05);           /* PARAMETERdata, check page28, 00000101 to turn AC Wide  filter off*/
00726 }
00727 
00728 // allows you to rotate the bird coordinate system
00729 // angles are +-180 degrees
00730 void Bird::angle_align(double x_rot, double y_rot, double z_rot)
00731 {
00732     double factor = 32767.0/180.0;
00733     write_bird(BIRD_ANGLE_ALIGN2);      // command
00734     write_bird(ENCODE_LSB(z_rot * factor));             // Z rotation LSB
00735     write_bird(ENCODE_MSB(z_rot * factor));             // Z rotation MSB
00736     write_bird(ENCODE_LSB(y_rot * factor));             // Y rotation LSB
00737     write_bird(ENCODE_MSB(y_rot * factor));             // Y rotation MSB
00738     write_bird(ENCODE_LSB(x_rot * factor));             // X rotation LSB
00739     write_bird(ENCODE_MSB(x_rot * factor));             // X rotation MSB
00740 }
00741 
00742 void Bird::CRTVoltageTest(double* voltage_p, double* scanrate_p)
00743 {
00744     write_bird(BIRD_SYNC_CMD);  // command
00745     write_bird(255);    // sync pickup command
00746 
00747     // read in the 4-byte voltage/scan_rate values
00748     //int counter=0;
00749     const int packet_size = 4;  // bytes
00750     char local_buffer[80];
00751     
00752         GetBuffer(local_buffer, packet_size);
00753 
00754     // debugging
00755     printf("local buffer = %d %d %d %d\n", local_buffer[0], local_buffer[1],
00756         local_buffer[2], local_buffer[3]);
00757 
00758     // decode voltage
00759 #define DECODE_UNPHASED(b,i) ((short)( ((b)[i+1] << 8 ) | (b)[i]))
00760     const double voltage_factor = (5.0/32767.0);
00761     *voltage_p = (voltage_factor * DECODE_UNPHASED(local_buffer, 0));
00762 
00763     // decode scan rate
00764     const double scanrate_factor = (500000.0);
00765     const double clock_rate = 8.0/40.0; // 40 MHz internal flock crystal speed
00766     unsigned short counts = DECODE_UNPHASED(local_buffer, 2);
00767     *scanrate_p = scanrate_factor / (clock_rate*counts);
00768 }
00769 
00770 #endif

Generated on Thu Aug 30 11:03:13 2007 for SPRING Mac by  doxygen 1.5.3