00001
00002
00003
00004
00005 #define USE_NEW_LIBRARY
00006
00007
00008 #if defined(_WIN32) && defined(USE_NEW_LIBRARY)
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <afxwin.h>
00019 #include <afxext.h>
00020 #ifndef _AFX_NO_AFXCMN_SUPPORT
00021 #include <afxcmn.h>
00022 #endif // _AFX_NO_AFXCMN_SUPPORT
00023
00024
00025 #include "pcBird.h"
00026
00027
00028
00029 #define GROUP_ID 0
00030
00031
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
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
00058 birdDisplayErrorDialogs(TRUE);
00059
00060
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
00068 BIRDSYSTEMCONFIG syscfg;
00069 if (!birdGetSystemConfig(GROUP_ID, &syscfg)) {
00070 cerr << "Bird- can't get system config\n";
00071 return;
00072 }
00073
00074
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 {
00102
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
00110
00111 devcfg.byDataFormat = BDF_POSITIONMATRIX;
00112 devcfg.byHemisphere = BHC_REAR;
00113
00114 #ifdef DO_FILTERING
00115
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
00131 if (!birdGetDeviceConfig(GROUP_ID, DeviceNum, &devcfg)) {
00132 cerr << "Bird-can't get device config #2\n";
00133 return;
00134 }
00135
00136
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 }
00165
00166 {
00167
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
00196
00197
00198 pos.x = reading.position.nY;
00199 pos.y = -reading.position.nZ;
00200 pos.z = -reading.position.nX;
00201
00202
00203 pos *= 25.4/1000;
00204
00205
00206 pos -= init_pos;
00207
00208
00209 pos *= scalefactor;
00210
00211
00212
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 {
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
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
00247
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
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
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
00300 #define BIRD_CRYSTAL_SPEED 0x02
00301
00302 #define POSMAX (36.0 / 32767.0)
00303 #define ANGMAX (180.0 / 32767.0)
00304 #define MATMAX (1.0 / 32767.0)
00305
00306 #define BIRD_TIME_OUT 800000
00307
00308
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
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
00326 while ( GetByte() & 0x80 ) {
00327
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;
00340 }
00341
00342
00343
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
00358 void Bird::initialize_flock(int num_birds_in_flock)
00359 {
00360 write_bird(BIRD_CHANGE_VALUE);
00361 write_bird(0x32);
00362 write_bird(num_birds_in_flock);
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
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
00387 is_master = 0;
00388 first_update = 1;
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
00394 if (num_birds_if_master > 0) {
00395 is_master = 1;
00396 initialize_flock(num_birds_if_master);
00397 }
00398
00399 switch (return_values) {
00400 case POSITION: write_bird(BIRD_POSITION); break;
00401 case ANGLES: write_bird(BIRD_ANGLES); break;
00402 case MATRIX: write_bird(BIRD_MATRIX); break;
00403 case POSITION_ANGLES: write_bird(BIRD_POSITION_ANGLES); break;
00404 case POSITION_MATRIX: write_bird(BIRD_POSITION_MATRIX); break;
00405 }
00406
00407
00408 write_bird(BIRD_RATE1);
00409 write_bird(BIRD_SET_BUTTON);
00410 write_bird(BIRD_BUTTON_OFF);
00411
00412
00413 write_bird(BIRD_HEMISPHERE);
00414 write_bird(BIRD_HEMI_AXIS);
00415 write_bird(BIRD_HEMI_SIGN);
00416
00417
00418
00419
00420
00421
00422
00423
00424 }
00425
00426 Bird::~Bird()
00427 {
00428 if (debug) cerr << "Bird[" << port_name << "]::~Bird()\n";
00429
00430 if (is_master)
00431 Sleep();
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
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
00455
00456
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
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
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 const int uart_buffer_length = 32;
00486 if (packet_length < uart_buffer_length)
00487 FlushInputQueue();
00488
00489 {
00490 int counter = 0;
00491 do {
00492 int c = GetByte();
00493 if (c == -1) continue;
00494
00495
00496 if (c & 0x80) counter = 0;
00497
00498
00499 bird_buffer[counter] = char(c & 0x7f);
00500
00501
00502 if (counter < BIRD_BUF_SIZE) counter++;
00503 } while (counter < packet_length);
00504 }
00505
00506
00507 if (packet_length >= uart_buffer_length)
00508 FlushInputQueue();
00509
00510
00511 return bird_buffer;
00512 }
00513
00514
00515 int Bird::decode_position(char* b_b)
00516 {
00517
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
00526 pos.x = decoded_pos.y;
00527 pos.y = -decoded_pos.z;
00528 pos.z = -decoded_pos.x;
00529
00530
00531 pos *= 25.4;
00532
00533
00534 pos -= init_pos;
00535
00536
00537 pos *= scalefactor;
00538
00539
00540 return(6);
00541 }
00542
00543
00544 int Bird::decode_angles(char* b_b)
00545 {
00546
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
00553
00554
00555
00556
00557
00558 return(6);
00559 }
00560
00561
00562 int Bird::decode_matrix(char* b_b)
00563 {
00564
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
00577
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
00592 return(18);
00593 }
00594
00595
00596 int Bird::decode_button(char* b_b)
00597 {
00598
00599 active[0] = (b_b[0] & 0x70) ? 1:0;
00600
00601
00602 return(1);
00603 }
00604
00605
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
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
00624
00625
00626
00627
00628
00629
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
00645 }
00646 return retval;
00647 }
00648
00649
00650
00651 #ifdef OLD_CODE
00652
00653 int Bird::get_mic_time()
00654 {
00655 gettimeofday( &timeval, &timez);
00656 return timeval.tv_usec;
00657 }
00658
00659
00660 int Bird::get_mic_duration(int last)
00661
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
00671 void Bird::sync_bird_crt_low()
00672 {
00673 write_bird(BIRD_SYNC_CMD);
00674 write_bird(BIRD_CRT_SYNC_LOW);
00675 }
00676
00677
00678 void Bird::sync_bird_crt_high()
00679 {
00680 write_bird(BIRD_SYNC_CMD);
00681 write_bird(BIRD_CRT_SYNC_HIGH);
00682 }
00683
00684
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
00697 if (first_update) {
00698 bird_start_stream();
00699 first_update = 0;
00700 }
00701
00702
00703 char* packet = read_bird_stream();
00704
00705
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
00717 }
00718 }
00719
00720
00721 void Bird::turn_off_filters()
00722 {
00723 write_bird(BIRD_CHANGE_VALUE);
00724 write_bird(0x04);
00725 write_bird(0x05);
00726 }
00727
00728
00729
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);
00734 write_bird(ENCODE_LSB(z_rot * factor));
00735 write_bird(ENCODE_MSB(z_rot * factor));
00736 write_bird(ENCODE_LSB(y_rot * factor));
00737 write_bird(ENCODE_MSB(y_rot * factor));
00738 write_bird(ENCODE_LSB(x_rot * factor));
00739 write_bird(ENCODE_MSB(x_rot * factor));
00740 }
00741
00742 void Bird::CRTVoltageTest(double* voltage_p, double* scanrate_p)
00743 {
00744 write_bird(BIRD_SYNC_CMD);
00745 write_bird(255);
00746
00747
00748
00749 const int packet_size = 4;
00750 char local_buffer[80];
00751
00752 GetBuffer(local_buffer, packet_size);
00753
00754
00755 printf("local buffer = %d %d %d %d\n", local_buffer[0], local_buffer[1],
00756 local_buffer[2], local_buffer[3]);
00757
00758
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
00764 const double scanrate_factor = (500000.0);
00765 const double clock_rate = 8.0/40.0;
00766 unsigned short counts = DECODE_UNPHASED(local_buffer, 2);
00767 *scanrate_p = scanrate_factor / (clock_rate*counts);
00768 }
00769
00770 #endif