00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00034 char* GPSPosition::gpsd_host = "127.0.0.1";
00035 int GPSPosition::gpsd_port = GPSD_DEFAULT_PORT;
00036
00037
00038
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
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
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
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
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
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
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
00149 void GPSPosition::setOffsets(double lat, double lon, double alt) {
00150 lat_off = lat;
00151 lon_off = lon;
00152 alt_off = alt;
00153 }