Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
243 lines (198 sloc) 6.72 KB
package plugins;
import gnu.io.*;
import javax.comm.*;
import java.io.*;
import java.util.*;
import logger.Logger;
import config.Config;
import coordinates.area.Area;
import coordinates.Cartesian;
import pdf.GaussDistribution;
import services.Service;
import services.GPSService;
import pdf.PDF;
import coordinates.WGS84;
import java.lang.Math;
import java.lang.Thread;
/**
* a concrete plugin implementation.
* Gets NMEA sentences from a GPS sensor.
* Only GPGGA sentences are evalutated.
* This implementation uses the rxtx library to access the serial port, where the GPS sensor is expected.
* See http://www.rxtx.org/ for details
*
* $GPGGA
*
* Global Positioning System Fix Data
*
* eg1. $GPGGA,170834,4124.8963,N,08151.6838,W,1,05,1.5,280.2,M,-34.0,M,,,*75
*
* Name Example Data Description
* Sentence Identifier $GPGGA Global Positioning System Fix Data
* Time 170834 17:08:34 UTC
* Latitude 4124.8963, N 41d 24.8963' N or 41d 24' 54" N
* Longitude 08151.6838, W 81d 51.6838' W or 81d 51' 41" W
* Fix Quality:
* - 0 = Invalid
* - 1 = GPS fix
* - 2 = DGPS fix 1 Data is from a GPS fix
* Number of Satellites 05 5 Satellites are in view
* Horizontal Dilution
* of Precision (HDOP) 1.5 Relative accuracy of horizontal position
* Altitude 280.2, M 280.2 meters above mean sea level
* Height of geoid above
* WGS84 ellipsoid -34.0, M -34.0 meters
* Time since last
* DGPS update blank No last update
* DGPS reference
* station id blank No station id
* Checksum *75 Used by program to check for transmission errors
*
*/
public class GPSPlugin extends AbstractPlugin {
private BufferedInputStream stream;
private SerialPort port;
public GPSPlugin()
{
calcParams();
CommPortIdentifier portID;
Enumeration list;
list = CommPortIdentifier.getPortIdentifiers();
while (list.hasMoreElements()) {
portID = (CommPortIdentifier) list.nextElement();
if (portID.getName().equals(Config.plugin.GPSPlugin.getDevice())) {
try {
port = (SerialPort) portID.open("compass", 2000);
} catch (PortInUseException e) {
Logger.fatal("GPSPlugin", "GPSPlugin", "Port in use");
return;
}
try {
port.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
Logger.fatal("GPSPlugin", "GPSPlugin", "Unsupported Comm Operation");
return;
}
try {
stream = new BufferedInputStream(port.getInputStream());
} catch (IOException e) {
Logger.fatal("GPSPlugin", "GPSPlugin", "IOException");
return;
}
return;
}
}
Logger.fatal("GPSPlugin", "GPSPlugin", Config.plugin.GPSPlugin.getDevice() + " not found");
return;
}
/****** Plugin ******/
public Vector getRequiredServices()
{
return null;
}
protected boolean needMoreServices()
{
return false;
}
protected PDF createPdf(long timeout)
{
WGS84 position;
PDF newPDF;
position = scanForPosition(timeout);
if (position == null) {
return null;
}
newPDF = calcPDF(position);
return newPDF;
}
protected void freeRessources()
{
port.close();
}
/***** private *****/
private WGS84 scanForPosition(long timeout)
{
String sentence;
String[] elements;
float latitude, longitude, altitude;
while (System.currentTimeMillis() < timeout) {
sentence = get_GPS_Sentence();
if (sentence == null) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
;
}
continue;
}
elements = sentence.split(",");
if (elements[4].equals("0")) { // quality == invalid
try {
Thread.sleep(100);
} catch (InterruptedException e) {
;
}
continue;
}
latitude = Float.parseFloat(elements[2]);
longitude = Float.parseFloat(elements[3]);
altitude = Float.parseFloat(elements[7]);
/* TODO: calculate and compare checksum */
return new WGS84(latitude, longitude, altitude);
}
return null;
}
private PDF calcPDF(WGS84 position)
{
Area area = Area.newArea(position, params);
return new GaussDistribution(area, Config.plugin.GPSPlugin.getVariance());
}
// returns the newest GPGGA sentence
private String get_GPS_Sentence()
{
byte b[] = new byte[30];
StringBuffer buffer = new StringBuffer(200);
int start, end, skip, n;
start = -1;
end = -1;
skip = 0;
while (true) {
try {
n = stream.read(b);
} catch (IOException e) {
Logger.error("GPSPlugin", "get_GPS_Sentence", "IOException");
return null;
}
if (n == -1) {
Logger.fatal("GPSPlugin", "get_GPS_Sentence", "Stream closed");
return null;
}
buffer.append(new String(b));
if (start == -1) {
start = buffer.indexOf("$GPGGA", skip);
skip += n;
}
if (start != -1) {
end = buffer.indexOf("$", start + 1);
}
if (end != -1) {
return buffer.substring(start, end);
}
}
}
private void calcParams()
{
int deviation = Config.plugin.GPSPlugin.getDeviation();
int resolution = Config.coordinates.Cartesian.getResolution();
int l = (int) Math.sqrt(2 * deviation * 100 / resolution);
Cartesian lowerLeftFront = new Cartesian(-l, -l, -l);
Cartesian upperRightBack = new Cartesian(l, l, l);
params = new Vector();
params.add(lowerLeftFront);
params.add(upperRightBack);
}
private Vector params;
}