X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=altoslib%2FAltosGPS.java;h=a730957b2566bc5c0b872820d69fa682b38994cc;hp=399e95b1376369de24c5ebaf491fe6da62f08938;hb=fd738d47bbc46d36698350d5450abe1125d990a3;hpb=7ec1b97d278c7aec3199fb7270f0dcf9484c879f diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index 399e95b1..a730957b 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -3,7 +3,8 @@ * * 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; version 2 of the License. + * 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 @@ -15,13 +16,16 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_11; import java.text.*; +import java.util.concurrent.*; +import java.io.*; +import java.time.*; public class AltosGPS implements Cloneable { - public final static int MISSING = AltosRecord.MISSING; + public final static int MISSING = AltosLib.MISSING; public int nsat; public boolean locked; @@ -39,10 +43,11 @@ public class AltosGPS implements Cloneable { public double ground_speed; /* m/s */ public int course; /* degrees */ public double climb_rate; /* m/s */ + public double pdop; /* unitless */ public double hdop; /* unitless */ public double vdop; /* unitless */ - public int h_error; /* m */ - public int v_error; /* m */ + public double h_error; /* m */ + public double v_error; /* m */ public AltosGPSSat[] cc_gps_sat; /* tracking data */ @@ -65,8 +70,26 @@ public class AltosGPS implements Cloneable { } public void ClearGPSTime() { - year = month = day = 0; - hour = minute = second = 0; + year = month = day = AltosLib.MISSING; + hour = minute = second = AltosLib.MISSING; + } + + /* Return time since epoc in seconds */ + public long seconds() { + if (year == AltosLib.MISSING) + return AltosLib.MISSING; + if (month == AltosLib.MISSING) + return AltosLib.MISSING; + if (day == AltosLib.MISSING) + return AltosLib.MISSING; + if (hour == AltosLib.MISSING) + return AltosLib.MISSING; + if (minute == AltosLib.MISSING) + return AltosLib.MISSING; + if (second == AltosLib.MISSING) + return AltosLib.MISSING; + OffsetDateTime odt = OffsetDateTime.of(year, month, day, hour, minute, second, 0, ZoneOffset.UTC); + return odt.toEpochSecond(); } public AltosGPS(AltosTelemetryMap map) throws ParseException { @@ -91,9 +114,10 @@ public class AltosGPS implements Cloneable { second = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_SECOND, 0); ground_speed = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_HORIZONTAL_SPEED, - AltosRecord.MISSING, 1/100.0); + AltosLib.MISSING, 1/100.0); course = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_COURSE, - AltosRecord.MISSING); + AltosLib.MISSING); + pdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_PDOP, MISSING, 1.0); hdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_HDOP, MISSING, 1.0); vdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_VDOP, MISSING, 1.0); h_error = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_HERROR, MISSING); @@ -107,6 +131,62 @@ public class AltosGPS implements Cloneable { } } + public boolean parse_string (String line, boolean says_done) { + String[] bits = line.split("\\s+"); + if (bits.length == 0) + return false; + if (line.startsWith("Date:")) { + if (bits.length < 2) + return false; + String[] d = bits[1].split("/"); + if (d.length < 3) + return false; + year = Integer.parseInt(d[0]) + 2000; + month = Integer.parseInt(d[1]); + day = Integer.parseInt(d[2]); + } else if (line.startsWith("Time:")) { + if (bits.length < 2) + return false; + String[] d = bits[1].split(":"); + if (d.length < 3) + return false; + hour = Integer.parseInt(d[0]); + minute = Integer.parseInt(d[1]); + second = Integer.parseInt(d[2]); + } else if (line.startsWith("Lat/Lon:")) { + if (bits.length < 3) + return false; + lat = Integer.parseInt(bits[1]) * 1.0e-7; + lon = Integer.parseInt(bits[2]) * 1.0e-7; + } else if (line.startsWith("Alt:")) { + if (bits.length < 2) + return false; + alt = Integer.parseInt(bits[1]); + } else if (line.startsWith("Flags:")) { + if (bits.length < 2) + return false; + int status = Integer.decode(bits[1]); + connected = (status & AltosLib.AO_GPS_RUNNING) != 0; + locked = (status & AltosLib.AO_GPS_VALID) != 0; + if (!says_done) + return false; + } else if (line.startsWith("Sats:")) { + if (bits.length < 2) + return false; + nsat = Integer.parseInt(bits[1]); + cc_gps_sat = new AltosGPSSat[nsat]; + for (int i = 0; i < nsat; i++) { + int svid = Integer.parseInt(bits[2+i*2]); + int cc_n0 = Integer.parseInt(bits[3+i*2]); + cc_gps_sat[i] = new AltosGPSSat(svid, cc_n0); + } + } else if (line.startsWith("done")) { + return false; + } else + return false; + return true; + } + public AltosGPS(String[] words, int i, int version) throws ParseException { AltosParse.word(words[i++], "GPS"); nsat = AltosParse.parse_int(words[i++]); @@ -135,10 +215,10 @@ public class AltosGPS implements Cloneable { lon = AltosParse.parse_coord(words[i++]); alt = AltosParse.parse_int(words[i++]); if (version > 1 || (i < words.length && !words[i].equals("SAT"))) { - ground_speed = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(H)")); + ground_speed = AltosParse.parse_double_net(AltosParse.strip_suffix(words[i++], "m/s(H)")); course = AltosParse.parse_int(words[i++]); - climb_rate = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(V)")); - hdop = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "(hdop)")); + climb_rate = AltosParse.parse_double_net(AltosParse.strip_suffix(words[i++], "m/s(V)")); + hdop = AltosParse.parse_double_net(AltosParse.strip_suffix(words[i++], "(hdop)")); h_error = AltosParse.parse_int(words[i++]); v_error = AltosParse.parse_int(words[i++]); } @@ -211,11 +291,26 @@ public class AltosGPS implements Cloneable { cc_gps_sat[cc_gps_sat.length - 1] = sat; } - public AltosGPS() { + private void init() { + lat = AltosLib.MISSING; + lon = AltosLib.MISSING; + alt = AltosLib.MISSING; + ground_speed = AltosLib.MISSING; + course = AltosLib.MISSING; + climb_rate = AltosLib.MISSING; + pdop = AltosLib.MISSING; + hdop = AltosLib.MISSING; + vdop = AltosLib.MISSING; + h_error = AltosLib.MISSING; + v_error = AltosLib.MISSING; ClearGPSTime(); cc_gps_sat = null; } + public AltosGPS() { + init(); + } + public AltosGPS clone() { AltosGPS g = new AltosGPS(); @@ -235,7 +330,9 @@ public class AltosGPS implements Cloneable { g.ground_speed = ground_speed; /* m/s */ g.course = course; /* degrees */ g.climb_rate = climb_rate; /* m/s */ - g.hdop = hdop; /* unitless? */ + g.pdop = pdop; /* unitless */ + g.hdop = hdop; /* unitless */ + g.vdop = vdop; /* unitless */ g.h_error = h_error; /* m */ g.v_error = v_error; /* m */ @@ -267,9 +364,11 @@ public class AltosGPS implements Cloneable { ground_speed = old.ground_speed; /* m/s */ course = old.course; /* degrees */ climb_rate = old.climb_rate; /* m/s */ + pdop = old.pdop; /* unitless? */ hdop = old.hdop; /* unitless? */ - h_error = old.h_error; /* m */ - v_error = old.v_error; /* m */ + vdop = old.vdop; /* unitless? */ + h_error = old.h_error; /* m */ + v_error = old.v_error; /* m */ if (old.cc_gps_sat != null) { cc_gps_sat = new AltosGPSSat[old.cc_gps_sat.length]; @@ -280,8 +379,29 @@ public class AltosGPS implements Cloneable { } } } else { - ClearGPSTime(); - cc_gps_sat = null; + init(); + } + } + + static public void provide_data(AltosDataListener listener, AltosLink link, AltosCalData cal_data) throws InterruptedException { + try { + AltosGPS gps = new AltosGPS(link, link.config_data()); + if (gps != null) + listener.set_gps(gps); + } catch (TimeoutException te) { + } + } + + public AltosGPS (AltosLink link, AltosConfigData config_data) throws TimeoutException, InterruptedException { + boolean says_done = config_data.compare_version("1.0") >= 0; + init(); + link.printf("g\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) + throw new TimeoutException(); + if (!parse_string(line, says_done)) + break; } } }