00001 /************************************************************************************************/ 00002 /*! \file AshtechG12_GPS_PhysicalDevice.h 00003 * \brief Get the Satellite Position 00004 * \author $Author: jayhawk_hokie $ 00005 * \version $Revision: 1.1 $ 00006 * \date $Date: 2007/08/31 16:10:54 $ 00007 ************************************************************************************************/ 00008 /*! 00009 * 00010 ************************************************************************************************/ 00011 00012 00013 #ifndef ASHTECHG12_GPS_PHYSICAL_DEVICE_H 00014 #define ASHTECHG12_GPS_PHYSICAL_DEVICE_H 00015 00016 #include <string> 00017 #include <iostream> 00018 00019 #include <stdio.h> 00020 #include <sys/socket.h> 00021 #include <arpa/inet.h> 00022 #include <stdlib.h> 00023 #include <unistd.h> 00024 #include <netinet/in.h> 00025 00026 #include <math.h> 00027 #include <sstream> 00028 00029 #include "Comm/ClientSocket.h" 00030 #include "Comm/SocketException.h" 00031 00032 using namespace std; 00033 00034 /** 00035 * This class encapsulates the serial interface to Ashtech's G12 series 00036 * of GPS receivers. The intention is to send all commands synchronously over 00037 * PortA. Asynchonous (periodic) messages are intended to be received 00038 * from Port B. If no asynchonous operation is desired, Port B may be omitted 00039 * at initialization. 00040 * TODO: 00041 * 1) If we need to use port B for control instead of A for some reason, 00042 * supply interface to specify which port is for control and which 00043 * (if any) is for asynch. 00044 * 2) If necessary, make RecvAckNak() search for leading $PASH instead of just 00045 * leading '$'. This would only be needed if there is "garbage" on the line 00046 * that includes '$' characters. 00047 * 3) As time permits and need dictates, find some way to handle synchronous 00048 * and asynchronous messaging on the same port. Likely with a reader 00049 * thread and ACE_Conditional or counting semaphore arrangement. The G12 00050 * signifigantly complicates this because messages are not always a single 00051 * line with a $PASH header. 00052 */ 00053 class AshtechG12_GPS_PhysicalDevice 00054 { 00055 public: 00056 /** 00057 * This structure holds all the data sent by a G12 in response to a 00058 * position request. 00059 */ 00060 struct Position 00061 { 00062 /** 00063 * Default Constructor. Initializes all fields to zero 00064 * or the lowest sane value for fields where zero is not allowed. 00065 */ 00066 Position(); 00067 00068 /** 00069 * Copy constructor. All fields are copied such that the equality 00070 * operator would return true for the constructed object and the 00071 * other. 00072 * @param other The Position object to be constructed 00073 */ 00074 Position(const Position & other); 00075 00076 /** 00077 * Constructs a Position object from a G12 <code>$PASHR,POS</code> 00078 * message. If the supplied message is improperly formatted or has 00079 * a bad checksum, the position object is returned as if from the 00080 * default constructor. To check for success of message parsing, the 00081 * default constructor should be called followed by a call to 00082 * <code>SetFromPOS_Message(const char *)</code>. 00083 * @param message The G12 $PASHR,POS message 00084 * @see SetFromPOS_Message(const char *) 00085 */ 00086 explicit Position(const char *message); 00087 00088 /** 00089 * Populates the Position object with the contents of a G12 <code> 00090 * $PASHR,POS</code> message. 00091 * @param message The G12 $PASHR,POS message 00092 * @return 0=success, -1=invalid message structure, -2=bad or unreadable checksum 00093 */ 00094 int SetFromPOS_Message(const char *message); 00095 00096 /** 00097 * Converts a Position message to a human-readable string. 00098 * Generates a string that can be read from a display -- it is not 00099 * intended for re-parsing or interprocess communication. 00100 * @param str The string object to be populated with the Position object's contents 00101 */ 00102 void toString(std::string &str) const; 00103 00104 /** 00105 * Converts a Position message to a human-readable string. 00106 * Generates a string that can be read from a display -- it is not 00107 * intended for re-parsing or interprocess communication. 00108 * @return The position data as a human-readable string 00109 */ 00110 std::string toString() const; 00111 00112 /** 00113 * Assigns all fields in this Position object to those from another. 00114 * Fields are assigned such that the equality operator would return 00115 * true when comparing the two objects. 00116 * @param The Position object to be assigned to this one 00117 * @return A reference to <code>this</code> object 00118 */ 00119 Position &operator = (const Position &other); 00120 00121 /** 00122 * The equality operator. Compares all fields in this object 00123 * to those in another Position object. 00124 * @return <code>true</code> if all fields are equal, <code>false</code> otherwise 00125 */ 00126 bool operator == (const Position &other) const; 00127 00128 00129 /** 00130 * Indicates whether the position is a result of normal or RTCM 00131 * operation. 0 means normal, 1 means RTCM (differential). 00132 */ 00133 unsigned char m_RTCM; // 0=no RTCM, 1=RTCM 00134 /** 00135 * The number of satellites that contributed to this reading. 00136 * Valid Range: 0 to 12 00137 */ 00138 //unsigned char m_numSatellites; // 0-12 00139 int m_numSatellites; // 0-12 00140 /** 00141 * The UTC time of the reading 00142 * Valid Range: 0 to 235959.50 seconds 00143 */ 00144 float m_UTC_Timetag; // 00-235959.50 00145 /** 00146 * The latitude in degrees at the time of the reading. 00147 * Valid Range: 0 to 90 degrees, 0.00001 minute resolution 00148 */ 00149 float m_latitude; // 0-90 degrees, 0.00001 minute resolution 00150 /** 00151 * The sector in which the latitude measurement resides. 00152 * Valid Range: 'N' for north or 'S' for south 00153 */ 00154 char m_latitudeSector; // 'N' or 'S' 00155 /** 00156 * The longitude in degrees at the time of the reading. 00157 * Valid Range: 0 to 90 degrees, 0.00001 minute resolution 00158 */ 00159 float m_longitude; // 0-90 degrees, 0.00001 minute resolution 00160 /** 00161 * The sector in which the longitude measurement resides. 00162 * Valid Range: 'W' for west or 'E' for east 00163 */ 00164 char m_longitudeSector; // 'W' or 'E' 00165 /** 00166 * The ellipsoidal height in meters at the time of the reading. 00167 * Valid Range: -3000.00 to +3000.00 meters (ellipsoidal) 00168 */ 00169 float m_altitude; // -3000.00 to +3000.00 meters (ellipsoidal) 00170 /** 00171 * The ground track in degrees from true north at the time of the reading. 00172 * Valid Range: 0.00 to 359.99 degrees true north reference 00173 */ 00174 float m_groundTrack; // 0.00 to 359.99 degrees true north reference 00175 /** 00176 * The ground speed in knots at the time of the reading. 00177 * Valid Range: 0 to 999.99 knots 00178 */ 00179 float m_groundSpeed; // 000.00-999.99 knots 00180 /** 00181 * The vertical velocity in meters per second at the time of the reading. 00182 * Valid Range: -999.9 to +999.9 meters/second 00183 */ 00184 float m_verticalVelocity; // -999.9 to +999.9 meters/second 00185 /** 00186 * The Position Dilution of Precision (PDOP) at the time of the reading. 00187 * PDOP = sqrt(HDOP^2 + VDOP^2) 00188 * Valid Range: 0 to 99.9 (higher=worse, <6 is nominal) 00189 */ 00190 float m_PDOP; // 0.00 to 99.9 (higher=worse, <6 is nominal) 00191 /** 00192 * The Height Dilution of Precision (HDOP) at the time of the reading. 00193 * Valid Range: 0 to 99.9 (higher=worse, <4 is nominal) 00194 */ 00195 float m_HDOP; // 0.00 to 99.9 (higher=worse, <4 is nominal) 00196 /** 00197 * The Vertical Dilution of Precision (VDOP) at the time of the reading. 00198 * Valid Range: 0 to 99.9 (higher=worse, <4 is nominal) 00199 */ 00200 float m_VDOP; // 0.00 to 99.9 (higher=worse, <4 is nominal) 00201 /** 00202 * The Time Dilution of Precision (TDOP) at the time of the reading. 00203 * Valid Range: 0 to 99.9 (higher=worse, <4 is nominal) 00204 */ 00205 float m_TDOP; // 0.00 to 99.9 (seconds) 00206 }; 00207 00208 enum { DEFAULT_PORT = 5002 }; 00209 00210 AshtechG12_GPS_PhysicalDevice( ); 00211 00212 AshtechG12_GPS_PhysicalDevice( const char* serverName ); 00213 00214 AshtechG12_GPS_PhysicalDevice( const char* serverName, int port ); 00215 00216 ~AshtechG12_GPS_PhysicalDevice( ); 00217 00218 int Connect( const char * serverName ); 00219 00220 int Connect( const char * serverName, int portNumber ); 00221 00222 int Send_i( const char *buf ); 00223 00224 int Send_i( const char *buf, unsigned int len ); 00225 00226 int Recv_i( char *buf, unsigned int bufsize ); 00227 00228 int GetCurrentPosition(Position &pos ); 00229 00230 static int ValidateChecksum(const char *message); 00231 00232 /* 00233 int SendInfo(int sock, char *buf); 00234 00235 int RecvInfo(int sock, char *buf, int bufsize); 00236 00237 int GetCurrentPosition(Position &pos, int sock); 00238 */ 00239 00240 00241 protected: 00242 00243 00244 private: 00245 00246 /* The connection to SimGEN */ 00247 ClientSocket *m_clientSocket; 00248 00249 }; 00250 00251 #endif 00252 00253 // Do not change the comments below - they will be added automatically by CVS 00254 /***************************************************************************** 00255 * $Log: AshtechG12_GPS_PhysicalDevice.h,v $ 00256 * Revision 1.1 2007/08/31 16:10:54 jayhawk_hokie 00257 * Initial Submission. 00258 * 00259 * 00260 * 00261 * 00262 * 00263 ******************************************************************************/ 00264