/**
* 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;
}
}