/** * Title: iSIM * Copyright: Copyright (c) 2002 * Company: University of Oregon Computer Science Dept. * * @author Jason Prideaux * @version 1.0 * */ package gps_monitor.gps; import gps_monitor.util.*; import gps_monitor.gui.*; import javax.comm.*; import java.util.*; import java.io.IOException; /** * This class is a GPS widget that wraps a serial port reader. The reader is designed * to collect sentences produced on the port which are generated by * a GPS receiver. The reader this class uses is the NmeaSerialReader class * found in this package. This software was originally developed to be used * with Anind Dey's contextual toolkit, however it has been slightly revised * so that it can be used in any Java application * * @see NmeaSerialReader * @see GpsGenerator * @author Richard Caudle * @version 1.0.4 */ public class NmeaSerialGps implements GpsGenerator{ /** * Development version number */ public String VERSION_NUMBER = "1.0.4"; /** * Create a pointer to our port reader (NmeaSerialReader) */ private NmeaSerialReader reader; /** * A string to describe one of the states a receiver could be in. */ public static final String ACTIVE = "active"; /** * A string to describe one of the states a receiver could be in. */ public static final String INACTIVE = "inactive"; /** * A string to describe one of the states a receiver could be in. */ public static final String OUT_OF_RANGE = "out_of_range"; /** * A string to describe one of the states a receiver could be in. */ public static final String RECEPTION_WARNING = "reception_warning"; GpsMonitorUI ui; String currStatus = INACTIVE; double currHeading = -1.0; GlobalCoordinate position = new GlobalCoordinate(null,null,-9999999.9999999); double currSpeed = -1.0; long lastUpdate = -1; double presentAccuracy = -1.0; double worstCaseAccuracy = -1.0; /** * These variables are needed to implement the accuracy methods */ double longVar, latVar; double totalLat = 0.0; double totalLong = 0.0; double longSquaredTotal = 0.0; double latSquaredTotal = 0.0; int accuracyUpdates = 0; double hdop; double pseudorangeError = -1.0; /** * Constructor that creates the Gps widget which will monitor * input on the given port. It does this by in turn creating an * NmeaSerialReader object on that port. * * Exceptions thrown are actually thrown by creating the NmeaSerialReader object. * * @param inputPort The port which the reads listens to * @param baud The baud rate to connect to the serial port * @param location Location the widget is "monitoring" */ public NmeaSerialGps (String inputPort, int baud, GpsMonitorUI ui) throws PortInUseException, IOException, TooManyListenersException, UnsupportedCommOperationException { reader = new NmeaSerialReader(inputPort, baud, this, ui); } /** * Constructor that creates the Gps widget which will monitor * input on the given port. It does this by in turn creating an * NmeaSerialReader object on that port. The widget is also * given an initial position according to the final argument. * * Exceptions thrown are actually thrown by creating the NmeaSerialReader object. * * @param inputPort The port which the reads listens to * @param location Location the widget is "monitoring" * @param pos The initial position */ public NmeaSerialGps (String inputPort, int baud, GlobalCoordinate pos, GpsMonitorUI ui) throws PortInUseException, IOException, TooManyListenersException, UnsupportedCommOperationException { reader = new NmeaSerialReader(inputPort, baud, this, ui); position = pos; } /** * This method sets the status of the reciever * * @param status The new status of the reciever */ public void setStatus(String status) { if (!(status.equals(currStatus))) { currStatus = status; } } /** * This method gets the status of the reciever and implements the required * method in GpsGenerator interface * * @return the current status of the receiver */ public String getStatus() throws NullPointerException { if (currStatus != null) return currStatus; else throw new NullPointerException("The status has not been set yet."); } /** * This method sets the latitude of the reciever. * * @param lat The new latitude of the object */ public void setLatitude(LatOrLongitude lat) { if ((position.getLatitude() == null) || (!(position.getLatitude().equals(lat)))) { position.setLatitude(lat); } } /** * This method gets the latitude of the reciever and implements the required * method in GpsGenerator interface * * @return the latitude of the receiver */ public LatOrLongitude getLatitude() throws NullPointerException { if (position.getLatitude() != null) return position.getLatitude(); else throw new NullPointerException("The latitude has not been set yet."); } /** * This method sets the longitude of the reciever. * * @param lon The new longitude of the object */ public void setLongitude(LatOrLongitude lon) { if ((position != null ) && (position.getLatitude() != null) && (position.getAltitude() != -9999999.9999999)) { setUpPseudorangeError(position.getLatitude(), lon); } if ((position.getLongitude() == null) || (!(position.getLongitude().equals(lon)))) { position.setLongitude(lon); } } /** * This method gets the longitude of the reciever and implements the required * method in GpsGenerator interface * * @return the longitude of the receiver */ public LatOrLongitude getLongitude() throws NullPointerException { if (position.getLongitude() != null) return position.getLongitude(); else throw new NullPointerException("The longitude has not been set yet."); } /** * This method sets the altitude of the reciever * * @param altitude The altitude of the reciever */ public void setAltitude(double altitude) { if ((position.getAltitude() == -9999999.9999999) || (position.getAltitude() != altitude)) { position.setAltitude(altitude); } } /** * This method gets the altitude of the reciever and implements the required * method in GpsGenerator interface * * @return The altitude of the reciever */ public double getAltitude() throws NullPointerException { if (position.getAltitude() != -9999999.9999999) return position.getAltitude(); else throw new NullPointerException("The altitude has not been set yet."); } /** * This method sets the heading which the reciever is on * * @param heading The heading of the reciever */ public void setTrueHeading(double heading) { if (currHeading != heading) { currHeading = heading; } } /** * This method returns the true heading of the receiver and implements the required * method in GpsGenerator interface * * @return The true heading of the receiver */ public double getTrueHeading() throws NullPointerException { if (currHeading != -1.0) return currHeading; else throw new NullPointerException("The heading has not been set yet."); } /** * This method sets the time of the last update * * @param time The time at which the reciever last updated the location */ public void setTimeLastLocationUpdate(int year, int month, int date, int hours, int mins, int secs) { /* * This is not the best way to specify the year. Needs to be the * number of years since 1900, and we only recieve a 2 digit year * from the receiver. It will work for one hundred years though!! * Note the month's run from 0, ie January = 0. */ year += 2000; GregorianCalendar temp = new GregorianCalendar(year, (month - 1), date, (hours + 1), mins, secs); long time = temp.getTime().getTime(); //System.out.println(time); if (lastUpdate != time) { lastUpdate = time; } } /** * This method gets the time of the last update and implements the required * method in GpsGenerator interface * * @return lastUpdate The time at which the reciever last updated the location */ public long getTimeLastLocationUpdate() throws NullPointerException { if (lastUpdate != -1) return lastUpdate; else throw new NullPointerException("The last time update has not been set yet."); } /** * This method sets the speed of the reciever * * @param speed The present speed of the receiver */ public void setSpeed(double speed) { if (currSpeed != speed) { currSpeed = speed; } } /** * This method returns the current speed of the receiver and implements the required * method in GpsGenerator interface * * @return The current/present speed */ public double getSpeed() throws NullPointerException { if (currSpeed != -1.0) return currSpeed; else throw new NullPointerException("The speed has not been set yet."); } /** * This method gets the present horizontal accuracy of the receiver * * @return The present accuracy of the receiver */ public double getPresentHorizontalAccuracy() throws NullPointerException { if ((pseudorangeError != -1.0) && (hdop != -1.0)) { presentAccuracy = hdop * pseudorangeError; } if (presentAccuracy != -1.0) return presentAccuracy; else throw new NullPointerException("The present accuracy has not been set yet."); } /** * This method gets the mean average horizontal accuracy of the receiver and implements the required * method in GpsGenerator interface * * @return The mean accuracy of the receiver */ public double getMeanHorizontalAccuracy() throws NullPointerException { return -1.0; } /** * This method gets the worst case horizontal accuracy of the receiver and implements the required * method in GpsGenerator interface * * @return The worst case accuracy of the receiver */ public double getWorstCaseHorizontalAccuracy() throws NullPointerException { if (worstCaseAccuracy != -1.0) return worstCaseAccuracy; else throw new NullPointerException("The worst-case accuracy has not been set yet."); } /** * This method sets the worst case horizontal accuracy of the receiver * * @param The worst case accuracy of the receiver */ public void setHorizontalDOP(double dop) { hdop = dop; } /** * This method allows us to obtain the 3D position of the gps receiver. * It returns this data as a GlobalCoordinate. * * @return The location of the gps receiver */ public GlobalCoordinate getLocation() { return position; } /** * This method helps in establishing a receivers accuracy. Using this method * one can find the variance of horizontal coordinates and hence establish * a mean accuracy. * * @param lati A received latitude value * @param longi A received longitude value */ public void setUpPseudorangeError(LatOrLongitude lati, LatOrLongitude longi) { if (accuracyUpdates < 120) { accuracyUpdates++; double[] latLong = LocationConverter.geospatialToCOORDS(lati, longi); double lat = latLong[1]; double lon = latLong[1]; totalLat += lat; totalLong += lon; latSquaredTotal += lat * lat; longSquaredTotal += lon* lon; if (accuracyUpdates == 120) { double latVariance = (latSquaredTotal - (totalLat * totalLat)/accuracyUpdates) / (accuracyUpdates - 1); double longVariance = (longSquaredTotal - (totalLong * totalLong)/accuracyUpdates) / (accuracyUpdates - 1); pseudorangeError = Math.sqrt(latVariance + longVariance); System.out.println("Pseudorange error set to: " + pseudorangeError); } } } public void setUI(GpsMonitorUI ui){ this.ui = ui; } }