Code Search for Developers
 
 
  

NmeaService.java from GridBlocks at Krugle


Show NmeaService.java syntax highlighted

/*
 * Copyright (c) 2005 
 * Helsinki Institute of Physics
 * see LICENSE file for details
 * 
 * Nmea.java 
 * Created on Dec 15, 2004
 */
package fi.hip.gb.bluetooth;

import java.io.DataInputStream;
import java.io.EOFException;
import java.util.Calendar;

import javax.bluetooth.ServiceRecord;

import fi.hip.gb.bluetooth.coordconv.LatitudeLongitude;
import fi.hip.gb.bluetooth.util.Properties;
import fi.hip.gb.bluetooth.util.StringTokenizer;
import fi.hip.gb.midlet.util.Float;

/**
 * Socket handler for reading NMEA messages from bluetooth GPS. Runs in a
 * new thread until {@link fi.hip.gb.bluetooth.Service#closeConnection()} 
 * method is called. Received sentences are sent to 
 * {@link fi.hip.gb.bluetooth.BTListener#handleAction(String, EndPoint, Object)}
 * implementation. Storage contains a result with GPS data in the property field. 
 * <p>
 * Currently supports following NMEA sentences:
 * $GPRMC<br>
 * $GPGGA
 * 
 * @author Juho Karppinen
 */
public class NmeaService extends Service {	
	public final static String SENTENCE = "sentence";
	public final static String DATETIME = "date";
	//public final static String LATITUDE = "latitude";
	public final static String LATITUDE_DEG = "latitude_deg";
	public final static String LATITUDE_MIN = "latitude_min";
	public final static String LATITUDE_SEC = "latitude_sec";
	public final static String LATITUDE_NS = "latitude_ns";
	//public final static String LONGITUDE = "longitude";
	public final static String LONGITUDE_DEG = "longitude_deg";
	public final static String LONGITUDE_MIN = "longitude_min";
	public final static String LONGITUDE_SEC = "longitude_sec";
	public final static String LONGITUDE_EW = "longitude_ew";
	public final static String FIX = "fix";
	public final static String SATELLITES = "satellites";
	public final static String HORIZONTAL_ACC = "horizontal_accuracy";
	public final static String ALTITUDE = "altitude";
	public final static String SPEED = "speed";
	public final static String HEADING = "heading";
	
	/**
	 * Constructs a NMEA reader
	 * @param endpt the endpoint where data is downloaded
	 * @param url connection string to the bluetooth GPS
	 */
	public NmeaService(EndPoint endpt, String url) {
		super(endpt, url);
		this.reader = new Reader();
	}

	/**
	 * Constructs a NMEA reader
	 * @param endpt the endpoint where data is downloaded
	 * @param svcRec record of the service
	 */
	public NmeaService(EndPoint endpt, ServiceRecord svcRec) {
		super(endpt, svcRec);
		this.reader = new Reader();
	}
	
	private void parse(String sentence) {
	    BTService.getInstance().log("parsing "  + new String(sentence));
	    StringTokenizer st = new StringTokenizer(sentence, ",");
	    if(!st.hasMoreTokens())
	        return;
	    String op = st.nextToken();
	    
	    Properties prop = new Properties();
	    prop.setProperty(SENTENCE, op);
	    if(op.equals("$GPGGA")) {
	        // $GPGGA,104856.324,4614.1920,N,00602.3681,E,1,04,4.6,542.2,M,48.2,M,0.0,0000*75
	        // $GPGGA,170834,4124.8963,N,08151.6838,W,1,05,1.5,280.2,M,-34.0,M,,,*75
	        
	        // Global Positioning System Fix Data
	        // 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
	        
	        String time = st.nextToken();
	        
	        LatitudeLongitude ll = getLatLon(st.nextToken(), st.nextToken(), st.nextToken(), st.nextToken());
	        //prop.setProperty(LATITUDE, ll.getLatitude().toString());
	        //prop.setProperty(LATITUDE_NS, ll.getLatitudeNS());
	        //prop.setProperty(LONGITUDE, ll.getLongitude().toString());
	        //prop.setProperty(LONGITUDE_EW, ll.getLongitudeEW());
	        
	        prop.setProperty(FIX, st.nextToken());
	        prop.setProperty(SATELLITES, st.nextToken());
	        prop.setProperty(HORIZONTAL_ACC, st.nextToken());
	        prop.setProperty(ALTITUDE, st.nextToken());
	        
	        this.sendData(prop);
	    } else if(op.equals("$GPRMC")) {
	        // eg1. $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62
	        // eg2. $GPRMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68

	        // Recommended Minimum Specific GPS/TRANSIT Data
	        // 225446       Time of fix 22:54:46 UTC
	        // A            Navigation receiver warning A = Valid position, V = Warning
	        // 4916.45,N    Latitude 49 deg. 16.45 min. North
	        // 12311.12,W   Longitude 123 deg. 11.12 min. West
	        // 000.5        Speed over ground, Knots
	        // 054.7        Course Made Good, degrees true
	        // 191194       UTC Date of fix, 19 November 1994
	        // 020.3,E      Magnetic variation, 20.3 deg. East
	        // *68          mandatory checksum
	        
            BTService.getInstance().log("start");
	        String time = st.nextToken();
            BTService.getInstance().log("time");
	        String validity = st.nextToken();
            BTService.getInstance().log("valid");
	        int status = 0;
	        if(validity.toUpperCase().equals("A"))
	            status = 1;
	        prop.setProperty(FIX, Integer.toString(status));
            BTService.getInstance().log("latlong");
	        LatitudeLongitude ll = getLatLon(st.nextToken(), st.nextToken(), st.nextToken(), st.nextToken());
	        String[] arr = ll.getLatitude();
            BTService.getInstance().log("lat " + arr.length);
	        prop.setProperty(LATITUDE_DEG, arr[0]);
	        prop.setProperty(LATITUDE_MIN, arr[1]);
	        prop.setProperty(LATITUDE_SEC, arr[2]);
	        prop.setProperty(LATITUDE_NS, ll.getLatitudeNS());
            
	        arr = ll.getLongitude();
            BTService.getInstance().log("lng " + arr.length);
	        prop.setProperty(LONGITUDE_DEG, arr[0]);
	        prop.setProperty(LONGITUDE_MIN, arr[1]);
	        prop.setProperty(LONGITUDE_SEC, arr[2]);
	        prop.setProperty(LONGITUDE_EW, ll.getLongitudeEW());

            BTService.getInstance().log("speed");
	        Float kmh = new Float(Float.parse(st.nextToken()).Div(Float.parse("0.01852")).toLong()).Div(100);
            prop.setProperty(SPEED, kmh.toString());
	        //int kmh = (int)(Float.parseFloat(st.nextToken()) / Float.parseFloat("0.01852"));
	        //prop.setProperty(SPEED, Float.toString(((float)kmh) / 100));
            
            BTService.getInstance().log("heading");
	        prop.setProperty(HEADING, st.nextToken());
	        
            BTService.getInstance().log("date");
	        String date = st.nextToken();
	        long datetime = getDateTime(date, time);
	        prop.setProperty(DATETIME, Long.toString(datetime));
	        
            BTService.getInstance().log("send");
	        this.sendData(prop);
	    }
	}
	
	private void sendData(Properties prop) {
	    // pass the message to the GUI
		GPSResult res = new GPSResult();
		res.setName("GPS data from " + this.endpt.getName());
		res.setType(GPSResult.GPS_TYPE);
		res.setFlags(prop);
		
		BTService.getInstance().fireEvent(BTListener.EVENT_RECEIVED,
					this.endpt, 
					res);
	}

	/**
	 * Gets the date and time from satellite.
	 * @return
	 */
	public long getDateTime(String date, String time) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(date.substring(0,2)));
        cal.set(Calendar.MONTH, Integer.parseInt(date.substring(2,4)));
        cal.set(Calendar.YEAR, Integer.parseInt(date.substring(4,6)));
        cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time.substring(0,2)));
        cal.set(Calendar.MINUTE, Integer.parseInt(time.substring(2,4)));
        cal.set(Calendar.SECOND, Integer.parseInt(time.substring(4,6)));
        
        //return cal.getTimeInMillis();
        return cal.getTime().getTime();
	}
	
	/**
	 * Gets the latitude and longitude in normal decimal system
	 * @param lat latitude in format 1234.5678, means 12deg 34min 0.5678sec
	 * @param lat_ns S for south, and N for north
	 * @param lng longitude in format 1234.5678, means 12deg 34min 0.5678sec
	 * @param lng_ew W for west, and E for east 
	 * @return
	 */
	private LatitudeLongitude getLatLon(String lat, String lat_ns, String lng, String lng_ew) {
	    try {
	        int degreesN = Integer.parseInt(lat.substring(0, 2));
	        if(lat_ns.toUpperCase().equals("S"))
                degreesN *= -1;
	        int minutesN = Integer.parseInt(lat.substring(2, 4));
            Float secondsN = Float.parse("0." + lat.substring(5)).Mul(60);
	        //Float secondsN = new Float(Float.parseFloat("0." + lat.substring(5)) * 60);
	        //double secondsN = 60.d * Double.parseDouble("0." + lat.substring(5));
	        
	        int degreesE = Integer.parseInt(lng.substring(0, 3));
	        if(lng_ew.toUpperCase().equals("W"))
	            degreesE *= -1;
	        int minutesE = Integer.parseInt(lng.substring(3, 5));
	        
            Float secondsE = Float.parse("0." + lat.substring(6)).Mul(60);
	        //Float secondsE = new Float( Float.parseFloat("0." + lng.substring(6)) * 60);
	        
            //return new LatitudeLongitude(degreesN, degreesE);
            
	        return new LatitudeLongitude(degreesN, minutesN, secondsN, 
                    degreesE, minutesE, secondsE);
	    } catch(Exception e) {
	        System.out.println(lat + " " + lng);
	        e.printStackTrace();
	        return null;
	    }
	}

	/**
	 * Gets the status of GPS.
	 * @return
	 *
	public String getStatus() {
        if(this.status == 1) {
            return "fix";
        } else if(this.status == 2) {
            return "DGPS fix";
        } else {
            return "Invalid";
        }
	}*/
	
	class Reader implements Runnable {
		public void run() {
			try {
			    BTService.getInstance().log("opening input from GPS");
				DataInputStream datain = 
				    NmeaService.this.getConnection().openDataInputStream();
				
				int i = 0;
				// maximum length of NMEA sentence is 82 characters
				byte[] sentence = new byte[182];
				while(! NmeaService.this.done) {
					byte c = datain.readByte();
					if(c == '$' || i >= sentence.length) {
					    i = 0;
					}
					
					sentence[i] = c;
					if(c == '\n' && sentence[0] == '$') {
					    parse(new String(sentence, 0, i));
					} 
					i++;
				}
				datain.close();
			} catch(EOFException eofe) {
			    BTService.getInstance().log("stream closed from " + endpt);
			} catch (Exception e) {
			    BTService.getInstance().log("failed to read from " + endpt 
				        	+ ": " + e.getClass().toString() + " " + e.getMessage());
			    e.printStackTrace();
				//MIDui.showException("cannot read over bluetooth from " + endPoint.remoteName, e, null);
			}
			
			// remove the endpoint
			BTService.getInstance().fireEvent(BTListener.EVENT_LEAVE,
			        NmeaService.this.endpt, 
			        null);
			//endPoint.btnet.cleanupRemoteEndPoint(endPoint);
			BTService.getInstance().log("Reader thread exit for " + endpt.getName());
		}
	}
}



See more files for this project here

GridBlocks

GridBlocks builds a grid application framework via easy-to-use building blocks in distributed environment. The framework offers components for Grid security, distributed storage, computing, and Portlet web interfaces.

Project homepage: http://sourceforge.net/projects/gridblocks
Programming language(s): Java,JSP,XML
License: other

  coordconv/
    LatitudeLongitude.java
  util/
    Properties.java
    StringTokenizer.java
  AgentService.java
  BTListener.java
  BTService.java
  EndPoint.java
  GPSResult.java
  NmeaService.java
  Service.java
  Util.java