lejos.hardware.gps.SimpleGPS Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lejos-ev3-api Show documentation
Show all versions of lejos-ev3-api Show documentation
leJOS (pronounced like the Spanish word "lejos" for "far") is a tiny Java Virtual Machine. In 2013 it was ported to the LEGO EV3 brick.
The newest version!
package lejos.hardware.gps;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.NoSuchElementException;
/**
* This class manages data received from a GPS Device.
* SimpleGPS Class manages the following NMEA Sentences
* which supply location, heading, and speed data:
*
* GPGGA (location data)
* GPVTG (heading and speed data)
* GPGSA (accuracy information)
*
* This class is primarily for use by the javax.microedition.location package. The preferred
* class to use for obtaining GPS data is the GPS class.
*
* @author BB
* @author Juan Antonio Breña Moral
*
*/
public class SimpleGPS extends Thread {
private InputStream in;
//Classes which manages GGA, VTG, GSA Sentences
protected GGASentence ggaSentence;
protected VTGSentence vtgSentence;
protected GSASentence gsaSentence;
// Security
private boolean close = false;
// Listener-notifier
static private ArrayList listeners = new ArrayList();
/**
* The constructor. It needs an InputStream
*
* @param in An input stream from the GPS receiver
*/
public SimpleGPS(InputStream in) {
this.in = new BufferedInputStream(in, 128);
ggaSentence = new GGASentence();
vtgSentence = new VTGSentence();
gsaSentence = new GSASentence();
this.setDaemon(true); // Must be set before thread starts
this.start();
}
/**
* Get Latitude
*
* @return the latitude
*/
public double getLatitude() {
return ggaSentence.getLatitude();
}
/**
* Get Latitude Direction
*
* @return the latitude direction
*/
public char getLatitudeDirection(){
return ggaSentence.getLatitudeDirection();
}
/**
* Get Longitude
*
* @return the longitude
*/
public double getLongitude() {
return ggaSentence.getLongitude();
}
/**
* Get Longitude Direction
*
* @return the longitude direction
*/
public char getLongitudeDirection(){
return ggaSentence.getLongitudeDirection();
}
/**
* The altitude above mean sea level
*
* @return Meters above sea level e.g. 545.4
*/
public float getAltitude(){
return ggaSentence.getAltitude();
}
/**
* Returns the number of satellites being tracked to
* determine the coordinates.
* @return Number of satellites e.g. 8
*/
public int getSatellitesTracked(){
return ggaSentence.getSatellitesTracked();
}
/**
* 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
*
* @return the fix quality
*/
public int getFixMode(){
return ggaSentence.getFixQuality();
}
/**
* Get the last time stamp from the satellite for GGA sentence.
*
* @return Time as a UTC integer. 123459 = 12:34:59 UTC
*/
public int getTimeStamp() {
return ggaSentence.getTime();
}
/**
* Get speed in kilometers per hour
*
* @return the speed in kilometers per hour
*/
public float getSpeed() {
return vtgSentence.getSpeed();
}
/**
* Get the course heading of the GPS unit.
* @return course (0.0 to 360.0)
*/
public float getCourse() {
return vtgSentence.getTrueCourse();
}
/**
* Selection type of 2D or 3D fix
* 'M' = manual
* 'A' = automatic
* @return selection type - either 'A' or 'M'
*/
public String getSelectionType(){
return gsaSentence.getMode();
}
/**
* 3D fix - values include:
* 1 = no fix
* 2 = 2D fix
* 3 = 3D fix
*
* @return fix type (1 to 3)
*/
public int getFixType(){
return gsaSentence.getModeValue();
}
/**
* Get an Array of Pseudo-Random Noise codes (PRN). You can look up a list of GPS satellites by
* this number at: http://en.wikipedia.org/wiki/List_of_GPS_satellite_launches
* Note: This number might be similar or identical to SVN.
*
* @return array of PRNs
*/
public int[] getPRN(){
return gsaSentence.getPRN();
}
/**
* Get the 3D Position Dilution of Precision (PDOP). When visible GPS satellites are close
* together in the sky, the geometry is said to be weak and the DOP value is high; when far
* apart, the geometry is strong and the DOP value is low. Thus a low DOP value represents
* a better GPS positional accuracy due to the wider angular separation between the
* satellites used to calculate a GPS unit's position. Other factors that can increase
* the effective DOP are obstructions such as nearby mountains or buildings.
*
* @return The PDOP (PDOP * 6 meters = the error to expect in meters) -1 means PDOP is unavailable from the GPS.
*/
public float getPDOP(){
return gsaSentence.getPDOP();
}
/**
* Get the Horizontal Dilution of Precision (HDOP). When visible GPS satellites are close
* together in the sky, the geometry is said to be weak and the DOP value is high; when far
* apart, the geometry is strong and the DOP value is low. Thus a low DOP value represents
* a better GPS positional accuracy due to the wider angular separation between the
* satellites used to calculate a GPS unit's position. Other factors that can increase
* the effective DOP are obstructions such as nearby mountains or buildings.
*
* @return the HDOP (HDOP * 6 meters = the error to expect in meters) -1 means HDOP is unavailable from the GPS.
*/
public float getHDOP(){
return gsaSentence.getHDOP();
}
/**
* Get the Vertical Dilution of Precision (VDOP). When visible GPS satellites are close
* together in the sky, the geometry is said to be weak and the DOP value is high; when far
* apart, the geometry is strong and the DOP value is low. Thus a low DOP value represents
* a better GPS positional accuracy due to the wider angular separation between the
* satellites used to calculate a GPS unit's position. Other factors that can increase
* the effective DOP are obstructions such as nearby mountains or buildings.
*
* @return the VDOP (VDOP * 6 meters = the error to expect in meters) -1 means VDOP is unavailable from the GPS.
*/
public float getVDOP(){
return gsaSentence.getVDOP();
}
/**
* Method used to close connection. There is no real need to call this method.
* Included in case programmer wants absolutely clean exit.
*/
public void close() throws IOException {
this.close = true;
in.close();
}
/*
* EVENTS SECTION
*
*/
protected static synchronized void notifyListeners(NMEASentence sen){
/* TODO: Problem is ggaSentence is a reused object in this API.
* Should really pass a copy of the NMEASentence to notify (and the copy
* must have all the appropriate GGA data, not just NMEA). However, check
* if there are any listeners before making unnecessary copy. */
for(int i=0; i= 0) {
currentSentence.append((char)c);
c = in.read();
// trailing CR/LF marks EOL
if (c == '\n' || c == '\r')
break;
}
} catch (IOException e) {
//TODO handle errors
}
return currentSentence.toString();
}
/**
* Internal helper method to aid in the subclass architecture. Overwritten by subclass.
* @param header
* @param s
*/
protected void sentenceChooser(String header, String s) {
if (header.equals(GGASentence.HEADER)){
this.ggaSentence.parse(s);
notifyListeners(this.ggaSentence);
}else if (header.equals(VTGSentence.HEADER)){
this.vtgSentence.parse(s);
notifyListeners(this.vtgSentence);
}else if (header.equals(GSASentence.HEADER)){
gsaSentence.parse(s);
notifyListeners(this.gsaSentence);
}
}
}