// EPS: Elgaard Positioning System: GPS navigation software. // Copyright (C) 1997 Niels Elgaard Larsen // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Niels Elgaard Larsen, // // Garmin communication code is based on Gpstrans by Carsten Tschach // (tschach@zedat.fu-berlin.de) import java.util.Date; import java.awt.*; import java.util.Calendar; class Getgpsinfo implements Runnable { int gtype; List waypointList, routeWPList, routeList; EPSCanvas ic; static Route currentRoute=null; /* define global variables */ static short records; static int AlmanacSat = 0; String GPSVersionStr; /****************************************************************************/ /* Query GPS for its model and software version. */ /****************************************************************************/ Getgpsinfo (int t, List wl, List rl, List rwl, EPSCanvas tic) { waypointList = wl; routeWPList = rwl; routeList = rl; gtype =t; ic = tic; } String getGPSVersion() { String temp; int err; int last=10, i; /* First check it GPS responds to the "are-you-ready" package */ if (Garmincomm.CheckGPS()) { /* send request and receive version package */ Garmincomm.sendGPSMessage(Gpsmessage.gid4, 2); Garmincomm.getGPSMessage(); Garmincomm.sendGPSMessage(Gpsmessage.gid5, 4); Garmincomm.getGPSMessage(); Garmincomm.serialClose(); /* extract model name and software version */ GPSVersionStr= "Garmin "+ (new String(Garmincomm.gGarminMessage,0, 7)).trim(); for (i = 0; i <= GPSVersionStr.length(); i++) { if (GPSVersionStr.charAt(i) == ' ') { last = i; } } GPSVersionStr = " - V"+ GPSVersionStr.substring(0,last); ic.FullPaint=true; ic.repaint(); return (GPSVersionStr); } else { GPSVersionStr= ""; return (GPSVersionStr); } } /****************************************************************************/ /* Query GPS for current GPS time (in GMT/UTC). */ /****************************************************************************/ Date getGPSTime(){ int err; Calendar tcal = Calendar.getInstance(); /* Check if GPS responds to the "are-you-ready" package */ if (!Garmincomm.CheckGPS()) { CAux.perr("GPS is not responding - make sure it is on and set to GRMN/GRMN protocol.",4); } /* open serial device */ // if ((err = Garmincomm.serialOpen(Garmincomm.GRM_comm)) != 0) { // CAux.perr("GT The port initialization of %s has failed.", 5); // return(null); // } /* send command and receive package */ Garmincomm.sendGPSMessage(Gpsmessage.tim1, 4); Garmincomm.getGPSMessage(); /* this is the ACK-package */ Garmincomm. getGPSMessage(); /* close serial device */ Garmincomm.serialClose(); /* exit if not a valid time package */ if (Garmincomm.gGarminMessage[1] != 0x0e) { return (null); } tcal.set(Garmincomm.gGarminMessage[5], Garmincomm.gGarminMessage [ 3], (Garmincomm.gGarminMessage [ 4]), (Garmincomm.gGarminMessage [ 7]), (Garmincomm.gGarminMessage [ 9]), (Garmincomm.gGarminMessage [ 10]) ); return (tcal.getTime()); } /****************************************************************************/ /* Get multiple line packages from GPS (route, waypoint, track) */ /****************************************************************************/ public void run() { int total; boolean done = false; byte init[], req[]; byte n; byte p[]; int err; String rType; currentRoute =null; /* First check it GPS responds to the "are-you-ready" package */ Thread thisThread = Thread.currentThread(); if (!Garmincomm.CheckGPS()) { CAux.perr("GPS is not responding - make sure it is on and set to GRMN/GRMN protocol.",4); } /* open serial device */ if ((err = Garmincomm.serialOpen(Garmincomm.GRM_comm)) != 0) { CAux.perr( "GGInfo:The port initialization of %s has failed.", 4); // Continue. Netscape/IE problem } records = 0; /* process different requests */ if (gtype == Gpsmessage.ALMANAC){ init = Gpsmessage.alm1; req = Gpsmessage.alm2; rType = "almanac"; } else if (gtype == Gpsmessage.ROUTE){ init = Gpsmessage.rte1; req = Gpsmessage.rte2; rType = "routes"; } else if (gtype == Gpsmessage.TRACK){ init = Gpsmessage.trk1; req = Gpsmessage.trk2; rType = "track"; } else if (gtype == Gpsmessage.WAYPOINT){ init = Gpsmessage.wpt1; req = Gpsmessage.wpt2; rType = "waypoint"; } else { init = Gpsmessage.alm1; req = Gpsmessage.alm2; rType = "almanac"; } AlmanacSat = 0; /* send init package */ Garmincomm.sendGPSMessage(init, 4); /* exit if no package received from GPS */ if (Garmincomm.getGPSMessage()==0) { return; } /* get number of records to transfer */ total = 0x100*Garmincomm.gGarminMessage[4]+ /* MSB of number of records to transfer */ Garmincomm.gGarminMessage[3]; /* LSB */ CAux.perr( " total rd = " + total, 4); /* repeat until all packages received */ while (!done && GPS.GMThread==thisThread) { Garmincomm.sendGPSMessage(req, 4); if (Garmincomm.getGPSMessage() == 0) { break; } done = (Garmincomm.gGarminMessage[1] == 0x0c); if (!done) { parseGPS(); records ++; //SetBarGraph((double)(++records)/(double)total); } } /* close BarGraph and serial device */ //CloseBarGraph(); Garmincomm.serialClose(); ic.FullPaint=true; ic.repaint(); CAux.perr((records - 1)+" "+ rType +" packets were transfered from the GPS receiver.", 0); Garmincomm.serialClose(); if (gtype == Gpsmessage.ROUTE){ RouteC.flushList(routeList); aWP.theWP.flushList(waypointList, false); // if (routeWPList != null) { // RouteC.routes[activeRT].wpts.flushList(routeWPList,true); // } } else if (gtype == Gpsmessage.WAYPOINT) { aWP.theWP.flushList(waypointList, false); } return; } /****************************************************************************/ /* Parse messages received from GPS. */ /****************************************************************************/ static void parseGPS() { byte gm = Garmincomm.gGarminMessage[1]; if (gm == Gpsmessage.RTE_NAM) { /* Route name record */ doRouteName(); } else if (gm == Gpsmessage.RTE_WPT) { /* Route waypoint record */ doWaypoint(true); } else if (gm == Gpsmessage.ALM) { /* Almanac record */ doAlmanac(); } else if (gm == Gpsmessage.TRK) { /* Track record */ doTrack(); } else if (gm == Gpsmessage.WPT) { /* Waypoint record */ doWaypoint(false); } } /****************************************************************************/ /* Process RouteName package and write to output device. */ /****************************************************************************/ static void doRouteName() { String name; int rno; rno = ubyte(Garmincomm.gGarminMessage[3]); name = new String(Garmincomm.gGarminMessage,4,20).trim(); if (name.equals("________________")) { name = "route "+ rno; } currentRoute = new Route(name); // RouteC.insertRoute(null, routeList, currentRoute); RouteC.insertRoute(null, null, currentRoute); System.out.println( " new route: " + currentRoute); } /****************************************************************************/ /* Process Track package and write to output device. */ /****************************************************************************/ static void doTrack() { Pos tPos; Date tstamp; double latitude, longitude, x, y; if ((Garmincomm.gGarminMessage[15]) == 0x01){ // New track, create blank record if (records != 0) { TrackC.insertTrack(null); } } /* convert bytes to latitude / longitude */ latitude = Gpsmessage.int2deg(gnumber(Garmincomm.gGarminMessage,3)); longitude = Gpsmessage.int2deg(gnumber(Garmincomm.gGarminMessage,7)); tstamp = CAux.usecs2td(gnumber(Garmincomm.gGarminMessage,11)*1000L); /* translate to selected datum */ tPos = new Pos(longitude,latitude,Pos.WGS84); TrackC.insertTrack(new TRPos(tPos,tstamp)); /* Write track time to file */ } /****************************************************************************/ /* Process Waypoint package and write to output device. */ /****************************************************************************/ static void doWaypoint(boolean isRt) { double latitude, longitude, x, y; String comment,name; Pos tPos; Date tstamp; long latn,longn; System.out.println( " gm="+ Garmincomm.gGarminMessage); /* convert bytes to latitude/longitude */ latn = gnumber(Garmincomm.gGarminMessage,9); latitude = Gpsmessage.int2deg(latn); //System.out.println( " lat="+latitude); longn = gnumber(Garmincomm.gGarminMessage,13); longitude = Gpsmessage.int2deg(longn); tPos = new Pos(longitude,latitude,Pos.WGS84); System.out.println( " WP: pos="+ tPos + " longn = "+longn + " latn=" + latn ); if (Gpsmessage.DEBUG ){ } /* translate to selected datum */ /* write waypoint name */ name = new String(Garmincomm.gGarminMessage,3,6).trim(); System.out.println( " name="+name); /* write comment - up to 40 characters */ comment = new String(Garmincomm.gGarminMessage,21,40).trim(); System.out.println( " comm="+ comment); /* write date/time */ tstamp = CAux.usecs2td(gnumber(Garmincomm.gGarminMessage,17)*1000L); System.out.println( " ts="+ tstamp); if (isRt) { WayPoint thisWP; thisWP = aWP.theWP.findWP(name); if (thisWP == null) { thisWP = new WayPoint(name, tPos, comment, tstamp); aWP.theWP.insertWP(null, null, thisWP, false); } currentRoute.wpts.insertWP(null, null, thisWP, true); } else { aWP.theWP.insertWP(null, null, new WayPoint(name, tPos, comment, tstamp), false); } } /****************************************************************************/ /* Process Almanac package and write to output device. */ /****************************************************************************/ static void doAlmanac() { } static int ubyte(byte by){ if (by >= 0) { return ((int) by); } else { return (256+(int) by); } } /****************************************************************************/ /* Convert bytes to long number. */ /****************************************************************************/ static long gnumber(byte p[], int st) { long nr; nr = 0x1000000L*ubyte(p[3+st]) + 0x10000L*ubyte(p[2+st]) + 0x100L*ubyte(p[1+st]) + ubyte(p[st]); if (nr>= 0x80000000L) { nr = nr - 0x100000000L; } return(nr); } /****************************************************************************/ /* Convert bytes to short number. */ /****************************************************************************/ static short toshort(byte p[],int st) { return (short)(ubyte(p[st]) + 0x100*ubyte(p[st+1])); } }