Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages | Examples

vos/metaobjects/property/gps_position.cc

Go to the documentation of this file.
00001 /* $Id: gps_position.cc,v 1.19 2003/07/23 00:17:32 reed Exp $ */
00002 
00003 /** @file gps_position.cc   Define specialized LocalProperty that gets its data from gpsd.
00004 
00005     Copyright (C) 2001, 2002 Reed Hedges <reed@zerohour.net>
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00020 
00021 */
00022 
00023 
00024 #include <sys/types.h>
00025 #include <unistd.h>
00026 #include <errno.h>
00027 #include <math.h>
00028 
00029 #include <vos/corelibs/vos/vos.hh>
00030 
00031 #include "gps_position.hh"
00032 
00033 // initialize static members
00034 char* GPSPosition::gpsd_host = "127.0.0.1";
00035 int GPSPosition::gpsd_port = GPSD_DEFAULT_PORT;
00036 
00037 
00038 /* Constructor */
00039 GPSPosition::GPSPosition(MetaObject *super) throw(ServerCommError)
00040         : LocalProperty(super), Property(super), MetaObject(super), lat_scale(1), lon_scale(1), alt_scale(1), lat_off(0), lon_off(0), alt_off(0), fix_alt(false), last_lat(0), last_lon(0), last_alt(0), threshold(GPSPROP_DEFAULT_THRESHOLD)
00041 {
00042    struct sockaddr_in address;
00043     LOG("GPSPosition", 3, "Opening connection to GPSD server at " << gpsd_host << ":" << gpsd_port);
00044     if( (socket_fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
00045         throw ServerCommError(string("Error creating socket: ") + sys_errlist[errno]);
00046     }
00047     struct hostent* he;
00048     if(!(he = gethostbyname(gpsd_host))) {
00049         throw ServerCommError(string("Invalid address: ") + gpsd_host);
00050     }
00051     memset(&address, 0, sizeof(address));
00052     address.sin_port=htons(gpsd_port);
00053     address.sin_family=AF_INET;
00054     address.sin_addr=*((struct in_addr *)he->h_addr);
00055     if( connect(socket_fd, (struct sockaddr *)&address, sizeof(address)) == -1) {
00056         char port_s[16];
00057         sprintf(port_s, "%d", gpsd_port);
00058         throw ServerCommError(string("Error connecting to server ") + gpsd_host + ":" + port_s + ". " + sys_errlist[errno]);
00059     }
00060     setPrecision(GPSPROP_DEFAULT_PRECISION);
00061 }
00062 
00063 /* Destructor */
00064 GPSPosition::~GPSPosition() {
00065     if ( shutdown(socket_fd, 2) < 0 ) {
00066         LOG("GPSPosition", 0, "Warning: error closing socket. " << sys_errlist[errno]);
00067     }
00068 }
00069 
00070 
00071 
00072 /* gpsd commands are:
00073 
00074     Command  Reply             Meaning
00075 
00076     P/p      GPSD,P=%f %f      position, where %f %f are latitude and longitude values
00077     D/d      GPSD,D=%s         time?? ('utc')
00078     A/a      GPSD,A=%f         altitude (%f is value)
00079     V/v      GPSD,V=%f         velocity (%f is value-- m/sec??)
00080     R/r      GPSD,R=%d         reset?? (where %i is 0 for ok and 1 for error??)
00081     S/s      GPSD,S=%d         status (0 = ok? 1 = error?)
00082     M/m      GPSD,M=%d         mode??
00083 
00084 */
00085 
00086 
00087 /* get position */
00088 void GPSPosition::update() throw(ServerCommError) {
00089     double lat, lon, alt;
00090     char msg[128];
00091     int nrecvd;
00092 
00093     if(send(socket_fd, "P\n", 2, 0) != 2)
00094         throw ServerCommError("Error sending command to gpsd!");
00095     nrecvd = recv(socket_fd, msg, 128, 0);
00096     sscanf(msg, "GPSD,P=%lf %lf", &lat, &lon);
00097 
00098     if(fix_alt) {
00099         alt = fixed_alt_val;
00100     } else {
00101         if(send(socket_fd, "A\n", 2, 0) != 2)
00102             throw ServerCommError("Error sending command to gpsd!");
00103         nrecvd = recv(socket_fd, msg, 128, 0);
00104         sscanf(msg, "GPSD,A=%lf", &alt);
00105     }
00106 
00107 
00108     if( (fabs(last_lat - lat) > threshold) || (fabs(last_lon - lon) > threshold) || (fabs(last_alt - alt) > threshold) ) {
00109         last_lat = lat;
00110         last_lon = lon;
00111         last_alt = alt;
00112         char str[128];
00113         sprintf(str, position_format, ((lon + lon_off) * lon_scale),
00114                 ((alt + alt_off) * alt_scale), ((lat + lat_off) * lat_scale));
00115         LOG("GPS Position Property", 4, str);
00116         this->replace(string(str));
00117     }
00118 }
00119 
00120 /* set precision */
00121 void GPSPosition::setPrecision(int precision) throw(range_error) {
00122     if(precision > 15 || precision < 0)
00123         throw range_error("GPS Property: Illegal precision range.");
00124     sprintf(position_format, "%%.%df %%.%df %%.%df", precision, precision, precision);
00125 }
00126 
00127 /* get status */
00128 int GPSPosition::getStatus() throw(ServerCommError){
00129     int status;
00130     char msg[128];
00131     if(send(socket_fd, "S\n", 2, 0) != 2) {
00132         throw ServerCommError("Error sending command to gpsd!");
00133         return -1;
00134     }
00135     recv(socket_fd, msg, 128, 0);
00136     sscanf(msg, "GPSD,S=%d", &status);
00137     return status;
00138 }
00139 
00140 
00141 /* set scaling  */
00142 void GPSPosition::setScaling(double lat, double lon, double alt) {
00143     lat_scale = lat;
00144     lon_scale = lon;
00145     alt_scale = alt;
00146 }
00147 
00148 /* set offsets */
00149 void GPSPosition::setOffsets(double lat, double lon, double alt) {
00150     lat_off = lat;
00151     lon_off = lon;
00152     alt_off = alt;
00153 }

Generated on Tue Aug 12 03:55:45 2003 for Interreality Project - VOS by doxygen 1.3.2