00001 /* $Id: gps_position.hh,v 1.16 2003/07/24 23:08:35 reed Exp $ */ 00002 00003 /* Copyright (C) 2001, 2002 Reed Hedges <reed@zerohour.net> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 */ 00020 00021 #ifndef _GPS_POSITION_H_ 00022 #define _GPS_POSITION_H_ 00023 00024 #include <stdio.h> 00025 #include <vos/corelibs/vos/vos.hh> 00026 #include <vos/metaobjects/property/property.hh> 00027 00028 /* This specialization of LocalProperty is meant to get its data from gpsd, the Global 00029 Positioning System daemon by Remco Treffkorn: <http://russnelson.com/gpsd/>. 00030 00031 @deprecated libtracking now provides an interface to GPSD, so you should 00032 use that, perhaps running a little background process to update a 00033 property. Sorry, but this class isn't being used by anyone (as far 00034 as we know) at the 00035 moment and it's a bit esoteric to be a standard member of the property 00036 classes. 00037 00038 gpsd listens on a TCP port and responds to simple commands with data from a GPS 00039 hooked up to the computer by serial cable. (I have noted most of the commands 00040 in the source, gps_position.cc). The latutude (LAT), longitude (LON) and altitutde 00041 (ALT) of the GPS are stored in the property in this format (the format conforms to 00042 that of a3dl object3d position property, with "room" as an arbitrary sector name): 00043 00044 "LAT ALT LON room" 00045 00046 That is, latitutde is interpreted as X, longitude as Z, and altitude as Y. 00047 00048 If we decide to split up 3D object position, this class might be modified to 00049 represent only one component (X, Y, or Z) rather than have all three together 00050 as object3d currently does. I think the default will be to have all three, though, 00051 to remain backwards compatible. 00052 00053 00054 @author Reed Hedges <reed@zerohour.net> 2/25/02 00055 00056 */ 00057 00058 /** The default gpsd 1.06 TCP port. */ 00059 #define GPSD_DEFAULT_PORT 2947 00060 00061 /** Default position precision for values in printf() format string */ 00062 #define GPSPROP_DEFAULT_PRECISION 15 00063 00064 /** Default threshold before new property is set (and update messages sent). */ 00065 #define GPSPROP_DEFAULT_THRESHOLD 0 00066 00067 class GPSPosition : public LocalProperty { 00068 00069 public: 00070 00071 /** An exception that indicates a general error communicating to server through network socket. (use ServerCommError::what() to get a descriptive string) */ 00072 class ServerCommError : public runtime_error { 00073 public: 00074 ServerCommError(const string& s) : runtime_error(s) {} 00075 }; 00076 00077 protected: 00078 00079 int socket_fd; 00080 static char* gpsd_host; 00081 static int gpsd_port; 00082 00083 /* scale factors (multipliers) */ 00084 double lat_scale; 00085 double lon_scale; 00086 double alt_scale; 00087 00088 /* offsets */ 00089 double lat_off; 00090 double lon_off; 00091 double alt_off; 00092 00093 /* fixed altitude? */ 00094 bool fix_alt; 00095 double fixed_alt_val; 00096 00097 /* Store values from last update */ 00098 double last_lat; 00099 double last_lon; 00100 double last_alt; 00101 00102 /* Threshold difference from last value before the new values are written (and 00103 * update messages are sent). Use setThreshold to change. */ 00104 double threshold; 00105 00106 /* Format string for creating position property. Use setPrecision to change. */ 00107 char position_format[64]; 00108 00109 00110 public: 00111 00112 /** Constructor: initializes values and oens socket to gpsd */ 00113 GPSPosition(MetaObject *super) throw (ServerCommError); 00114 00115 /** Destructor: closes socket. */ 00116 ~GPSPosition(); 00117 00118 /** Register GPSPosition with MetaFactory by typeid(GPSPosition).name, as a local object extension. You must also call Property::registerExtenders()! */ 00119 static void registerExtenders() { 00120 LocalSite::addLocalObjectExtension(typeid(GPSPosition).name(), &GPSPosition::new_GPSPosition); 00121 } 00122 00123 /** This method is used by MetaFactory to create a new instance of this class. */ 00124 static MetaObject* new_GPSPosition(MetaObject* super, const string& type) { 00125 return new GPSPosition(super); 00126 } 00127 00128 /** Set precision of values. The default value is 15 decimal places. Must 00129 * be an integer value >= 0 and <= 15. 00130 * @precision new precision value 00131 * @throws range_error if requested precision value is > 15 or < 0.*/ 00132 void setPrecision(int precision) throw (range_error); 00133 00134 /** Set threshold of change before property value is replaced on update() 00135 * (and therefore update messages sent to listeners) */ 00136 void setThreshold(double t) { 00137 threshold = t; 00138 } 00139 00140 /** Update value from gpsd after which you can use read() to get the new value. Call at intervals, or right before a read. Only changes the property value (with a call to replace()) if the difference from the last update is greater than the threshold. 00141 * @see setThreshold() 00142 * @see setPrecision() 00143 */ 00144 void update() throw (ServerCommError); 00145 00146 /** Send status command to gpsd and return response. -1 is returned on connection/communicaiton error. */ 00147 int getStatus() throw(ServerCommError); 00148 00149 /** Set default gpsd server for future GPSPosition objects 00150 @param host Numerical host address. Default is "127.0.0.1" 00151 @param port Port number. Default is GPSD_DEFAULT_PORT (2947). */ 00152 static void setServer(char* host = "127.0.0.1", int port = GPSD_DEFAULT_PORT) { 00153 gpsd_host = host; 00154 gpsd_port = port; 00155 } 00156 00157 /** Set scaling multipliers. ( (Final value) = (Original value + Offset) * Scaling ). */ 00158 void setScaling(double latitude, double longitude, double altitude); 00159 00160 /** Set offsets. ( (Final value) = (Original value + Offset) * Scaling ). */ 00161 void setOffsets(double latitude, double longitude, double altitude); 00162 00163 /** Fix altitude (Y position) to some value. */ 00164 void fixAltitude(double val) { 00165 fix_alt = true; 00166 fixed_alt_val = val; 00167 } 00168 }; 00169 00170 00171 00172 00173 00174 #endif