/**
* 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 transport.protocol.*;
import transport.*;
import javax.comm.*;
import java.util.*;
import java.io.IOException;
import java.net.*;
import java.io.*;
public class NmeaSocketGps implements GpsGenerator, SocketReceiverListener{
/**
* Development version number
*/
public String VERSION_NUMBER = "1.0.4";
/**
* 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";
private 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;
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;
/* ====================================================================== */
/** This simple Constructor starts the transport connection to the iSIM
* simulator.
*
* @param ui The parent to pass data up to.
* @param port The port to have transport package use.
*
*/
public NmeaSocketGps (GpsMonitorUI ui, int port) throws PortInUseException, IOException, TooManyListenersException, UnsupportedCommOperationException{
SocketReceiver server = new SocketReceiver(this, port);
server.start();
} //Constructor
/* ====================================================================== */
/** This method receives incoming messages from the transport class. As
* required by being a SocketReceiverListener.
*
* @param msg The incoming message.
*
*/
public void incomingMessage(Message msg){
System.out.println("NmeaSocketGps got incoming message...");
if( msg instanceof NMEAMessage ){
setLatitude( new LatOrLongitude(""+((NMEAMessage)msg).getLatitude()) );
setLongitude( new LatOrLongitude(""+((NMEAMessage)msg).getLongitude()) );
setTrueHeading( ((NMEAMessage)msg).getHeading() );
}
} //method: incomingMessage
/**
* 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;
}
} //class