Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

GPS/GPS.cpp

Go to the documentation of this file.
00001 #include <iostream>
00002 #include "GPS.h"
00003 
00004 #include <sys/types.h>
00005 #include <sys/stat.h>
00006 #include <fcntl.h>
00007 //#include <stdio.h>
00008 #include <stdlib.h>
00009 #include <termios.h>
00010 #include <unistd.h>
00011 #include <errno.h>
00012 #include <sys/ioctl.h>
00013 #include <math.h>
00014 #include <fcntl.h>
00015 
00016 using std::cerr;
00017 using std::cout;
00018 using std::endl;
00019 
00020 
00021 double GPS::invalid;
00022 
00033 GPS::GPS(void) {
00034   initVars();
00035 }
00036 
00047 GPS::GPS(const char* serial_dev, int nowait) 
00048 {
00049   initVars();
00050 
00051   if (nowait) {
00052         gps_fd = open(serial_dev, O_RDWR | O_NOCTTY | O_NONBLOCK);   
00053   } else {
00054         gps_fd = open(serial_dev, O_RDWR | O_NOCTTY);   
00055   }
00056 
00057   if (gps_fd < 0)
00058   {     
00059     std::cerr << "opening serial port '" << serial_dev << "' failed : " << strerror(errno) << std::endl;    
00060                 exit(EXIT_FAILURE);
00061   }
00062 
00063   // set new port settings for 9600 baud, no parity, use hardware flow control
00064   struct termios newtio;
00065   bzero(&newtio, sizeof(newtio));
00066   newtio.c_cflag = CS8 | B9600 | CRTSCTS | CLOCAL | CREAD;
00067   newtio.c_iflag = IGNPAR; //ignore framing and parity errors, or cariage returns
00068   newtio.c_oflag = 0;    //no output processing
00069   newtio.c_lflag = ICANON;
00070   newtio.c_cc[VINTR]    = 0;     /* Ctrl-c */ 
00071   newtio.c_cc[VQUIT]    = 0;     /* Ctrl-\ */
00072   newtio.c_cc[VERASE]   = 0;     /* del */
00073   newtio.c_cc[VKILL]    = 0;     /* @ */
00074   newtio.c_cc[VEOF]     = 0;     /* Ctrl-d */
00075   newtio.c_cc[VTIME]    = 0;     /* inter-character timer unused */
00076   newtio.c_cc[VMIN]     = 1;     /* blocking read until 1 character arrives */
00077   newtio.c_cc[VSWTC]    = 0;     /* '\0' */
00078   newtio.c_cc[VSTART]   = 0;     /* Ctrl-q */ 
00079   newtio.c_cc[VSTOP]    = 0;     /* Ctrl-s */
00080   newtio.c_cc[VSUSP]    = 0;     /* Ctrl-z */
00081   newtio.c_cc[VEOL]     = 0;     /* '\0' */
00082   newtio.c_cc[VREPRINT] = 0;     /* Ctrl-r */
00083   newtio.c_cc[VDISCARD] = 0;     /* Ctrl-u */
00084   newtio.c_cc[VWERASE]  = 0;     /* Ctrl-w */
00085   newtio.c_cc[VLNEXT]   = 0;     /* Ctrl-v */
00086   newtio.c_cc[VEOL2]    = 0;     /* '\0' */
00087 
00088   //flush both the input and output, before changing serial port attibutes
00089   tcflush(gps_fd, TCIOFLUSH); 
00090 
00091   int result = tcsetattr(gps_fd,TCSANOW,&newtio);
00092   if (result == -1) {
00093     perror("GPS::GPS : tcsetattr failed");
00094     exit(EXIT_FAILURE);
00095   }
00096 }
00097 
00108 int 
00109 GPS::init(float period, int dynamicMode) {
00110     //even though GPS may be in blocking mode, 
00111     //initialization should be in non-blocking mode
00112     int flags;
00113     int result = fcntl(gps_fd, F_GETFL, &flags);
00114         if (result == -1) {
00115             perror("GPS::init() error with fcntl F_GETFL");
00116             return -1;
00117         }
00118         result = fcntl(gps_fd, F_SETFL, flags | O_NONBLOCK);    
00119         if (result == -1) {
00120             perror("GPS::init() error with fcntl F_SETFL");
00121             return -1;
00122     }
00123 
00124         //clear out any crap in the serial port buffer before starting
00125         do {    
00126             result = read(gps_fd, msgbuf, sizeof(msgbuf)-1);
00127             if (result == 0) {
00128                     if (errno == EAGAIN) {
00129                           break;
00130                     } else {
00131                           perror ("GPS::init() error with read");
00132                           return -1;
00133                         }                   
00134                 }
00135     } while (result > 0);
00136 
00137         //reset settings on serial port 
00138         writeLine("$PASHS,RST\r\n");     
00139         if (checkAck()) {
00140                 cerr << "GPS::init() error - could not reset GPS - trying once more" << endl;
00141                 sleep(3);
00142                 writeLine("$PASHS,RST\r\n");    
00143                 if (checkAck()) {
00144                   cerr << "GPS::init() error - could not reset GPS failing" << endl;
00145                   return -1;
00146                 }
00147         }       
00148 
00149         // set initial altitude - based on what we have seen before
00150         writeLine("$PASHS,ALT,219.60\r\n");
00151         if (checkAck()) {
00152                 cerr << "GPS::init() error - could not run set initial altitude on GPS" << endl;
00153                 return -1;
00154         }
00155 
00156         char msgtmp[40];
00157         
00158         // set dynamic mode for GPS unit
00159         snprintf(msgtmp, sizeof(msgtmp),"$PASHS,DYN,%d\r\n",dynamicMode);
00160         writeLine(msgtmp);
00161         if (checkAck()) {
00162                 cerr << "GPS::init() error - could set dynamic mode on GPS" << endl;
00163                 cerr << "GPS::init() - with command : " << msgtmp;
00164                 return -1;
00165         }       
00166         
00167         // have GPS unit provide data every <period> seconds
00168         snprintf(msgtmp, sizeof(msgtmp),"$PASHS,NME,POS,A,ON,%f\r\n",period);
00169         writeLine(msgtmp);
00170         if (checkAck()) {
00171                 cerr << "GPS::init() error - could not run NME,POS on GPS" << endl;
00172                 cerr << "GPS::init() - with command : " << msgtmp;
00173                 return -1;
00174         }
00175 
00176         // TODO
00177         // change BAUD rate?
00178         
00179         // have GPS unit provide data UTM coordinates instead of latitude/longitude
00180         // need to use parseUTM instead of parsePOS
00181         //writeLine("$PASHS,NME,UTM,A,ON,5\r\n");
00182         //checkAck();
00183 
00184         // put serial port back into whatever mode it was in before
00185         result = fcntl(gps_fd, F_SETFL, flags); 
00186         if (result == -1) {
00187             perror("GPS::init() error with fcntl F_SETFL (2)");
00188             return -1;
00189     }
00190         
00191         //cout << "GPS initialization done" << endl;
00192         return 0;
00193 }
00194 
00205 void 
00206 GPS::initVars(void) 
00207 {
00208         // initialize class variables
00209         invalid = nan("");
00210         msgbuf[0] = '\0';
00211         //reading = 0;  
00212         using_file = 0;
00213         gps_fd = -1;
00214         msglen = 0;
00215         has_positions = has_velocities = 0;
00216         latitude = longitude = altitude = invalid;
00217         x = y = z = invalid;
00218         xvel = yvel = zvel = invalid;
00219         hVelocity = vVelocity = direction = invalid;
00220         pdop = hdop = vdop = tdop = invalid;
00221 }
00222 
00223 
00234 GPS::~GPS(void)
00235 {
00236   if (gps_fd != -1) 
00237     close(gps_fd);
00238 }
00239 
00240 
00241 
00243 // Will read and buffer entire line of input.  It will allow about 10 seconds
00244 // for a complete line of input to be read.  The fuction will return 1 if there
00245 // was a complete line of input that was read, otherwise it will return 0;
00247 
00257 int 
00258 GPS::readLine(void) 
00259 {
00260   int result;
00261 
00262   for(int i=1; i<10; ++i) {
00263     // read from serial port
00264     result = read(gps_fd, msgbuf, sizeof(msgbuf)-1);
00265     if (result == 0) {
00266       std::cerr << "GPS::readLine : serial port closed?" << std::endl;
00267       //exit(EXIT_FAILURE);
00268                         return -1;
00269     } 
00270     else if ((result == -1) && (errno != EAGAIN)) {
00271       std::cerr << "GPS::readLine error - " << strerror(errno) << std::endl;
00272       //exit(EXIT_FAILURE);
00273                         return -1;
00274     } 
00275     else if (result > 0) {
00276       msglen = result;
00277       std::cout << "GPS responded in " << i << " seconds\n";
00278       if (msgbuf[msglen-1] != '\n') {
00279                                 std::cerr << "GPS::Readline read didn't return a complete line" << std::endl;
00280                                 //exit(EXIT_FAILURE);
00281                                 return -1;
00282       }
00283       msgbuf[msglen] = '\0';      
00284       return 0;
00285     }   
00286 
00287     // wait for a little bit before trying again
00288     sleep(1);
00289 
00290   }
00291 
00292   return -1;
00293 }
00294 
00295 
00296 
00298 // Writes msg to serial port, makes sure complete message is put on serial port
00299 // Before returning
00301 
00311 int 
00312 GPS::writeLine(const char* msg) 
00313 {
00314   int len = strlen(msg);
00315   
00316   //std::cout << "GPS::writeLine, writing len= " << len 
00317         //    << " msg='" << msg << "' to serial fd=" << gps_fd << std::endl;
00318 
00319   int result = write(gps_fd,msg,len);
00320   if (result == -1) {
00321     std::cerr << "GPS::writeLine error writing to gps serial port : " << strerror(errno) << std::endl;
00322                 return -1;
00323     //exit(EXIT_FAILURE);
00324   } 
00325   else if (result != len) {
00326     std::cerr << "GPS::writeLine error, only wrote " << result << " bytes of " << len << std::endl;
00327                 return -1;
00328     //exit(EXIT_FAILURE);
00329   }
00330 
00331   return 0;
00332 }
00333 
00334 
00335 
00336 
00338 // Will check to see if the next responce message from the GPS unit is an 
00339 // acknowledgement message 
00341 
00351 int 
00352 GPS::checkAck(void) {
00353   if ( readLine() ) {
00354     std::cerr << "GPS::checkAck : No repsonse from GPS unit" << std::endl;
00355                 return -1;
00356   }
00357 
00358   if (strcmp(msgbuf, "$PASHR,ACK*3D\r\n") == 0) {
00359     return 0;
00360   }
00361   else if (strcmp(msgbuf, "$PASHR,NAK*30\r\n") == 0) {
00362     std::cerr << "GPS::checkAck : recieved NAK message '" << msgbuf << ",\n";
00363                 return -1;
00364     //exit(EXIT_FAILURE);
00365   }
00366   else {
00367     std::cerr << "GPS::checkAck : recieved unknown message '" << msgbuf << ",\n";
00368                 return -1;
00369     //exit(EXIT_FAILURE);
00370   } 
00371 
00372   return -1;
00373 }
00374 
00375 
00377 // This function won't block waiting for data from the serial port.  
00378 // This function will buffer the GPS serial data until it has a complete record 
00379 //  that it can parse.  
00380 // This function will return a 1 when it has new, data or a 0 otherwise
00382 
00392 int 
00393 GPS::Read(void) {
00394         int result;
00395 
00396         // read any new data from GPS system into buffer
00397         result = read(gps_fd, msgbuf, sizeof(msgbuf));  
00398         if (result == 0) {
00399                 std::cerr << "GPS::Read : serial port closed?" << std::endl;
00400                 //exit(EXIT_FAILURE);
00401                 return -1;
00402         } 
00403         else if (result == -1) {
00404                 if (errno == EAGAIN) {
00405                         return 0;
00406                 }
00407                 else {
00408                         std::cerr << "GPS::Read error - " << strerror(errno) << std::endl;
00409                         return -1;
00410                         //exit(EXIT_FAILURE);
00411                 }
00412         }       
00413   
00414         if (result >= (int) sizeof(msgbuf)) {
00415                 std::cerr << "GPS::ReadNoWait : message is longer than buffer" << std::endl;
00416                 exit(EXIT_FAILURE);
00417         }
00418 
00419         msglen = result;
00420         msgbuf[msglen] = '\0';
00421         //std::cout << "POS = '" << msgbuf << "'\n";  
00422 
00423         //make sure the message is complete
00424         if ( (msgbuf[msglen-2] != '\r') ||
00425                  (msgbuf[msglen-1] != '\n') ) {
00426                 std::cerr << "GPS::ReadNoWait : missing EOL chars in '" << msgbuf << "'\n";
00427                 //exit(EXIT_FAILURE);
00428                 return -1;
00429         }
00430 
00431         if (dispatchMsg(msgbuf) < 0) {
00432                 cerr << "GPS::Read error parsing message '" << msgbuf << "'\n";
00433                 return -1;
00434         }
00435         else
00436                 return 1;
00437 }
00438 
00439 
00441 // dispatchMsg()
00442 // Determine what message type GPS is using and calls correct parsing
00443 // fucntion based on the type (parsePOS/parseUTM)
00445 
00455 int
00456 GPS::dispatchMsg(const char* msg) {
00457         if (memcmp(msg,"$PASHR,POS",10) == 0) {         
00458                 return parsePOS(msg);
00459         }
00460         else if (memcmp(msgbuf,"$PASHR,UTM",10) == 0) {
00461                 return parseUTM(msg);
00462         }
00463         else {
00464                 cerr << "GPS::dispatchMsg - Unknown message '" << msg << '\'' << endl;
00465                 return -1;
00466         }
00467 }
00468 
00469 
00470 
00472 // Parse POS GPS string into values.  
00473 // Returns 0 if successfull or negative value otherwise
00475 // pashr : response header = '$PASHR'
00476 // pos   : response type = 'POS'     
00477 // d1    : rtsc   - 1 if using RTSC differential correction, 0 if not
00478 // d2    : numsat - number of satellites used in computing position
00479 // m1    : time   - UTC time hhmmss.tt (00 to 235959.50)
00480 // m2    : latitude   - ddmm.mmmmm
00481 // c1    : latsector  - 'N' or 'S' (north or south)
00482 // m3    : longitude  - dddmm.mmmmm 
00483 // c2    : longsector - 'E' or 'W'
00484 // f1    : altitude   - +aaaaa.aa  (in meters)
00485 // f2    : siteid     = '????'  not used (what is it supposed to be?)
00486 // f3    : direction  - ttt.tt referenced from true north (0.00 - 359.99)
00487 // f4    : horz veloc - 000.00 to 999.99 (in knots)
00488 // f5    : vert veloc - -999.99 to +999.99 (in meters/second)
00489 // f6    : pdop       - 0.00 to 99.0
00490 // f7    : hdop       - 
00491 // f8    : vdop       -
00492 // f9    : tdop       - 
00493 // s1    : version    - 4 character ascii
00494 // hh    : checksum   - 2 character hex
00496 
00506 int 
00507 GPS::parsePOS(const char* msg) 
00508 {  
00509   // enumerate the different fields in the array
00510   enum {pashr=0, pos, d1, d2, m1, m2, c1, m3, c2, f1, f2, f3, f4, f5, f6, f7, f8, f9, s1, hh};
00511 
00512   // find different fields of message by looking for ','
00513   const char *fieldarr[20], *field=msg, *lastfield=msg; 
00514   fieldarr[0] = msg;
00515   for(int i=1; i<=18; ++i) {
00516     field = strchr(field, ','); 
00517     if (field == NULL) {
00518       std::cerr << "GPS::read missing field from '" << lastfield << " iter=" << i << std::endl
00519                 << "  in '" << msg << "'\n"; 
00520       return -1;
00521     }
00522     ++field; // move past ',' 
00523     fieldarr[i] = field;
00524     lastfield = field;
00525   }      
00526 
00527   field = strchr(field, '*'); 
00528   if (*field != '*') {
00529     std::cerr << "GPS::parsePOS missing checksum in '" << field << "'\n"
00530               << "  in '" << msg << ",\n"; 
00531     return -1;
00532   }
00533   fieldarr[19] = field+1;    
00534     
00535   // TODO : make sure checksum is correct
00536  
00537   // make sure response header matches
00538   if ( memcmp(fieldarr[pashr], "$PASHR,POS", 10) != 0 ) {
00539     //if ( ( memcmp(fieldarr[pashr], "$PASHR", 6) != 0 ) || 
00540     //   ( memcmp(fieldarr[pos], "POS", 3) != 0 ) ) {
00541     std::cerr << "GPS::parsePOS incorrect message header '" << fieldarr[pashr] << ',' << fieldarr[pos] << "'\n";
00542     return -1;
00543   }
00544 
00545   // make sure firmware version makes sense 
00546   if ( memcmp(fieldarr[s1],"DC00",4) != 0 ) {
00547     std::cerr << "GPS::parsePOS incorrect firmware version '" << fieldarr[s1] << "'\n";
00548     return -1;
00549   }
00550 
00551   errno = 0;
00552   is_corrected = strtol(fieldarr[d1],NULL,10);
00553   numsat = strtol(fieldarr[d2],NULL,10);           
00554   if (errno != 0) {
00555     std::cerr << "GPS::parsePOS - error converting decimal values : " << strerror(errno) << std::endl;
00556     return -1;
00557   }          
00558 
00559   // convert longitude latitude and altitude into x,y,z position WRT and zero-reference
00560   if ( (*fieldarr[m2] != ',') &&
00561        (*fieldarr[m3] != ',') &&
00562        (*fieldarr[c1] != ',') &&
00563        (*fieldarr[c2] != ',') &&
00564        (*fieldarr[f1] != ',') ) {
00565     has_positions = 1;
00566 
00567     NorS = *fieldarr[c1];
00568     EorW = *fieldarr[c2];
00569      
00570     if ( ((NorS != 'N') && (NorS != 'S'))  ||
00571          ((EorW != 'E') && (EorW != 'W')) ) {
00572       std::cerr << "GPS::parsePOS - bad GPS region (N S E W) : in " 
00573                 << *fieldarr[c1] << *fieldarr[c2] << std::endl;
00574       return -1;
00575     }                   
00576 
00577 
00578     errno=0;
00579     //convert latitude into radians
00580     {
00581       char numbuf[3] = {*fieldarr[m2], *(fieldarr[m2]+1), '\0'};
00582       latitude = minutes2radians * strtod(fieldarr[m2]+2,NULL);
00583       latitude += degrees2radians * strtod(numbuf,NULL);    
00584     }
00585     //convert longitude into radians
00586     {
00587       char numbuf[4] = {*fieldarr[m3], *(fieldarr[m3]+1), *(fieldarr[m3]+2), '\0'};
00588       longitude = minutes2radians * strtod(fieldarr[m3]+3,NULL);      
00589       longitude += degrees2radians * strtod(numbuf,NULL);
00590     }
00591 
00592     z = altitude = strtod(fieldarr[m1],NULL);
00593 
00594     if (errno != 0) {
00595       std::cerr << "GPS::parsePOS - error converting longitude/latitude values : " << strerror(errno) << std::endl;
00596       return -1;
00597     }          
00598 
00599 
00600     x = (latitude-zeroLatitude) * earthRadius;
00601     y = (longitude-zeroLongitude) * cos(latitude) * earthRadius;
00602     
00603   } 
00604   else {
00605     // no positions availible
00606     has_positions = 0;
00607     latitude=longitude=invalid;
00608     x=y=z=invalid;
00609   }
00610 
00611   // convert direction and speeds 
00612   if ( (*fieldarr[f3] != ',') && 
00613        (*fieldarr[f4] != ',') && 
00614        (*fieldarr[f5] != ',') ) {
00615     has_velocities = 1;
00616     errno = 0;
00617 
00618     direction = degrees2radians * strtod(fieldarr[f3],NULL);
00619     hVelocity = knots2mps * strtod(fieldarr[f4],NULL);
00620     vVelocity = strtod(fieldarr[f5],NULL);
00621     if (errno != 0) {
00622       std::cerr << "GPS::parsePOS - error converting velocity values to floats : " << strerror(errno) << std::endl;
00623       return -1;
00624     }      
00625         xvel = cos(direction) * hVelocity;
00626         yvel = sin(direction) * hVelocity;
00627   } else {
00628     has_velocities = 0;
00629     direction = invalid;
00630     hVelocity = invalid;
00631     vVelocity = invalid;
00632         xvel = invalid;
00633         yvel = invalid;
00634   }
00635 
00636 
00637   // get *dop values
00638   errno = 0;
00639   pdop = strtod(fieldarr[f6],NULL);
00640   hdop = strtod(fieldarr[f7],NULL);
00641   vdop = strtod(fieldarr[f8],NULL);
00642   tdop = strtod(fieldarr[f9],NULL);
00643   if (errno != 0) {
00644     std::cerr << "GPS::parsePOS - error converting *dop values to floats : " << strerror(errno) << std::endl;
00645     return -1;
00646   }
00647 
00648   return 0;
00649 }
00650 
00651 
00652 
00654 // Parse UTM GPS string into values.  
00655 // Returns 0 if successfull or negative value otherwise
00657 //  THIS FUNCTION NEEDS TO BE DONE
00658 //
00660 
00670 int 
00671 GPS::parseUTM(const char* msg) 
00672 {  
00673   // enumerate the different fields in the array
00674   enum {pashr=0, pos, d1, d2, m1, m2, c1, m3, c2, f1, f2, f3, f4, f5, f6, f7, f8, f9, s1, hh};
00675 
00676   // find different fields of message by looking for ','
00677   const char *fieldarr[20], *field=msg, *lastfield=msg; 
00678   fieldarr[0] = msg;
00679   for(int i=1; i<=18; ++i) {
00680     field = strchr(field, ','); 
00681     if (field == NULL) {
00682       std::cerr << "GPS::read missing field from '" << lastfield << " iter=" << i << std::endl
00683                 << "  in '" << msg << "'\n"; 
00684       return -1;
00685     }
00686     ++field; // move past ',' 
00687     fieldarr[i] = field;
00688     lastfield = field;
00689   }      
00690 
00691   field = strchr(field, '*'); 
00692   if (*field != '*') {
00693     std::cerr << "GPS::parsePOS missing checksum in '" << field << "'\n"
00694               << "  in '" << msg << ",\n"; 
00695     return -1;
00696   }
00697   fieldarr[19] = field+1;    
00698     
00699   // TODO : make sure checksum is correct
00700  
00701   // make sure response header matches
00702   if ( memcmp(fieldarr[pashr], "$PASHR,POS", 10) != 0 ) {
00703     //if ( ( memcmp(fieldarr[pashr], "$PASHR", 6) != 0 ) || 
00704     //   ( memcmp(fieldarr[pos], "POS", 3) != 0 ) ) {
00705     std::cerr << "GPS::parsePOS incorrect message header '" << fieldarr[pashr] << ',' << fieldarr[pos] << "'\n";
00706     return -1;
00707   }
00708 
00709   // make sure firmware version makes sense 
00710   if ( memcmp(fieldarr[s1],"DC00",4) != 0 ) {
00711     std::cerr << "GPS::parsePOS incorrect firmware version '" << fieldarr[s1] << "'\n";
00712     return -1;
00713   }
00714 
00715   errno = 0;
00716   is_corrected = strtol(fieldarr[d1],NULL,10);
00717   numsat = strtol(fieldarr[d2],NULL,10);           
00718   if (errno != 0) {
00719     std::cerr << "GPS::parsePOS - error converting decimal values : " << strerror(errno) << std::endl;
00720     return -1;
00721   }          
00722 
00723   // convert longitude latitude and altitude into x,y,z position WRT and zero-reference
00724   if ( (*fieldarr[m2] != ',') &&
00725        (*fieldarr[m3] != ',') &&
00726        (*fieldarr[c1] != ',') &&
00727        (*fieldarr[c2] != ',') &&
00728        (*fieldarr[f1] != ',') ) {
00729     has_positions = 1;
00730 
00731     NorS = *fieldarr[c1];
00732     EorW = *fieldarr[c2];
00733      
00734     if ( ((NorS != 'N') && (NorS != 'S'))  ||
00735          ((EorW != 'E') && (EorW != 'W')) ) {
00736       std::cerr << "GPS::parsePOS - bad GPS region (N S E W) : in " 
00737                 << *fieldarr[c1] << *fieldarr[c2] << std::endl;
00738       return -1;
00739     }                   
00740 
00741 
00742     errno=0;
00743     //convert latitude into radians
00744     {
00745       char numbuf[3] = {*fieldarr[m2], *(fieldarr[m2]+1), '\0'};
00746       latitude = minutes2radians * strtod(fieldarr[m2]+2,NULL);
00747       latitude += degrees2radians * strtod(numbuf,NULL);    
00748     }
00749     //convert longitude into radians
00750     {
00751       char numbuf[4] = {*fieldarr[m3], *(fieldarr[m3]+1), *(fieldarr[m3]+2), '\0'};
00752       longitude = minutes2radians * strtod(fieldarr[m3]+3,NULL);      
00753       longitude += degrees2radians * strtod(numbuf,NULL);
00754     }
00755 
00756     z = altitude = strtod(fieldarr[m1],NULL);
00757 
00758     if (errno != 0) {
00759       std::cerr << "GPS::parsePOS - error converting longitude/latitude values : " << strerror(errno) << std::endl;
00760       return -1;
00761     }          
00762 
00763 
00764     x = (latitude-zeroLatitude) * earthRadius;
00765     y = (longitude-zeroLongitude) * cos(latitude) * earthRadius;
00766     
00767   } 
00768   else {
00769     // no positions availible
00770     has_positions = 0;
00771     latitude=longitude=invalid;
00772     x=y=z=invalid;
00773   }
00774 
00775   // convert direction and speeds 
00776   if ( (*fieldarr[f3] != ',') && 
00777        (*fieldarr[f4] != ',') && 
00778        (*fieldarr[f5] != ',') ) {
00779     has_velocities = 1;
00780     errno = 0;
00781 
00782     direction = degrees2radians * strtod(fieldarr[f3],NULL);
00783     hVelocity = knots2mps * strtod(fieldarr[f4],NULL);
00784     vVelocity = strtod(fieldarr[f5],NULL);
00785     if (errno != 0) {
00786       std::cerr << "GPS::parsePOS - error converting velocity values to floats : " << strerror(errno) << std::endl;
00787       return -1;
00788     }      
00789   } else {
00790     has_velocities = 0;
00791     direction = invalid;
00792     hVelocity = invalid;
00793     vVelocity = invalid;
00794   }
00795 
00796 
00797   // get *dop values
00798   errno = 0;
00799   pdop = strtod(fieldarr[f6],NULL);
00800   hdop = strtod(fieldarr[f7],NULL);
00801   vdop = strtod(fieldarr[f8],NULL);
00802   tdop = strtod(fieldarr[f9],NULL);
00803   if (errno != 0) {
00804     std::cerr << "GPS::parsePOS - error converting *dop values to floats : " << strerror(errno) << std::endl;
00805     return -1;
00806   }
00807 
00808   return 0;
00809 }
00810 
00811 
00812 
00814 // Prints out GPS position and velocity data contained in class
00816 
00826 void
00827 GPS::printData(void) {
00828   std::cout 
00829     << numsat << " Satellites, " << std::endl;
00830 
00831   if (has_positions) 
00832     std::cout 
00833       << "lat = " << latitude << " rads, long = " << longitude << " rads, " << NorS << EorW << std::endl
00834       << " [x,y,z] pos = [" << x << ',' << y << ',' << z << ']' << std::endl; 
00835   
00836   if (has_velocities) 
00837     std::cout 
00838       << "dir = " << direction << ", hVel = " << hVelocity << ", vVel = " << vVelocity << std::endl
00839       << " [x,y,z] vel = [" << xvel << ',' << yvel << ',' << zvel << ']' << std::endl; 
00840 
00841   std::cout << "DOP : P=" << pdop << " H=" << hdop << " V=" << vdop << " T=" << tdop << std::endl;
00842 
00843 }

Generated on Fri Sep 1 14:25:44 2006 for Raptor by  doxygen 1.4.4