package lejos.addon.gps; import java.util.*; /** * This class has been designed to manage a GGA Sentence * * GGA - essential fix data which provide 3D location and accuracy data. * * $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47 * * Where: * GGA Global Positioning System Fix Data * 123519 Fix taken at 12:35:19 UTC * 4807.038,N Latitude 48 deg 07.038' N * 01131.000,E Longitude 11 deg 31.000' E * 1 Fix quality: 0 = invalid * 1 = GPS fix (SPS) * 2 = DGPS fix * 3 = PPS fix * 4 = Real Time Kinematic * 5 = Float RTK * 6 = estimated (dead reckoning) (2.3 feature) * 7 = Manual input mode * 8 = Simulation mode * 08 Number of satellites being tracked * 0.9 Horizontal dilution of position * 545.4,M Altitude, Meters, above mean sea level * 46.9,M Height of geoid (mean sea level) above WGS84 * ellipsoid * (empty field) time in seconds since last DGPS update * (empty field) DGPS station ID number * *47 the checksum data, always begins with * * * @author BB */ public class GGASentence extends NMEASentence{ //GGA // TODO: Convert all/most of Juan's floats to int. // TODO: Initialize values with -1 or perhaps NaN private float dateTimeOfFix = -1; private double latitude = 0; private char latitudeDirection; // TODO: Delete me? Maybe used briefly in calc. private double longitude = 0; private char longitudeDirection; // ToDO: Delete me? private float quality; private float satellitesTracked = 0; private float hdop = 0; private float altitude = 0; private String altitudeUnits; private float geoidalSeparation; private String geoidalSeparationUnit; //Header public static final String HEADER = "$GPGGA"; /* * GETTERS & SETTERS */ /** * Returns the NMEA header for this sentence. */ public String getHeader() { return HEADER; } /** * Get Latitude * */ public double getLatitude() { checkRefresh(); return latitude; } /** * Get Latitude Direction * * @return the latitude direction */ // TODO: I think this is a useless method because we just use + or - in coordinates. public char getLatitudeDirection(){ checkRefresh(); return latitudeDirection; } /** * Get Longitude * */ public double getLongitude() { checkRefresh(); return longitude; } /** * Get Longitude Direction * @return the longitude direction */ // TODO: I think this is a useless method because we just use + or - in coordinates. public char getLongitudeDirection(){ checkRefresh(); return longitudeDirection; } /** * Get Altitude * * @return the altitude */ public float getAltitude(){ checkRefresh(); return altitude; } /** * Returns the last time stamp retrieved from a satellite * * @return The time as a UTC integer. 123519 = 12:35:19 UTC */ public int getTime(){ checkRefresh(); // TODO: Why is he using Math.round? return Math.round(dateTimeOfFix); } /** * Returns the number of satellites being tracked to * determine the coordinates. * * @return Number of satellites e.g. 8 */ public int getSatellitesTracked() { checkRefresh(); // TODO: Why is he using Math.round? return Math.round(satellitesTracked); } /** * Get GPS Quality Data * * @return the fix quality */ public int getFixQuality(){ checkRefresh(); // TODO: Why is he using Math.round? return Math.round(quality); } /** * Method used to parse a GGA Sentence */ protected void parse(String sentence){ //StringTokenizer st = new StringTokenizer(nmeaSentence,","); st = new StringTokenizer(sentence,","); // TODO: What's with all these Strings defined as ""? String q = ""; String h = ""; // TODO: Should this really be in a try-catch block? Didn't do anything until I added System.err output. try{ st.nextToken(); // skip $GPGGA header // TODO: I attempted Integer.parseInt and it threw a NumberFormatException because // UTC looks like 175958.000. Is it wrong to discard decimals? Always seem to be 000. dateTimeOfFix = Float.parseFloat(st.nextToken());//UTC Time latitude = degreesMinToDegrees(st.nextToken()); latitudeDirection = st.nextToken().charAt(0);//N longitude = degreesMinToDegrees(st.nextToken()); longitudeDirection = st.nextToken().charAt(0);//E q = st.nextToken(); if(q.length() == 0){ quality = 0; }else{ quality = Float.parseFloat(q);//Fix quality } //quality = Float.parseFloat(st.nextToken());//Fix quality satellitesTracked = Float.parseFloat(st.nextToken());//Number of satellites being tracked h = st.nextToken(); if(h.length() == 0){ hdop = 0; }else{ hdop = Float.parseFloat(h);//Horizontal dilution of position } altitude = Float.parseFloat(st.nextToken()); // Geoidal separation is 0 with Holux-1200. If decide to use in future check for 0 length before parse. //this.geoidalSeparation = Float.parseFloat(st.nextToken()); //Improve quality data if (longitudeDirection != 'E') { longitude = -longitude; } if (latitudeDirection != 'N') { latitude = -latitude; } }catch(NoSuchElementException e){ //Empty System.err.println("GGASentence.parse() NoSuchElementException thrown: " + e.getMessage()); }catch(NumberFormatException e){ //Empty System.err.println("GGASentence.parse() NumberFormatException thrown: " + e.getMessage()); } }//End parse }//End class