From fcea12ac416b1eab11e9e8aae801358574308f73 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Jun 2014 11:46:32 -0700 Subject: altoslib: Add TeleGPS log parsing code Signed-off-by: Keith Packard --- altoslib/AltosEepromGPS.java | 159 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 altoslib/AltosEepromGPS.java (limited to 'altoslib/AltosEepromGPS.java') diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java new file mode 100644 index 00000000..33172eed --- /dev/null +++ b/altoslib/AltosEepromGPS.java @@ -0,0 +1,159 @@ +/* + * Copyright © 2014 Keith Packard + * + * 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. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_4; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromGPS extends AltosEeprom { + public static final int record_length = 32; + + public static final int max_sat = 12; + + public int record_length() { return record_length; } + + /* AO_LOG_FLIGHT elements */ + public int flight() { return data16(0); } + public int start_altitude() { return data16(2); } + public int start_latitude() { return data32(4); } + public int start_longitude() { return data32(8); } + + /* AO_LOG_GPS_TIME elements */ + public int latitude() { return data32(0); } + public int longitude() { return data32(4); } + public int altitude() { return data16(8); } + public int hour() { return data8(10); } + public int minute() { return data8(11); } + public int second() { return data8(12); } + public int flags() { return data8(13); } + public int year() { return data8(14); } + public int month() { return data8(15); } + public int day() { return data8(16); } + public int course() { return data8(17); } + public int ground_speed() { return data16(18); } + public int climb_rate() { return data16(20); } + public int pdop() { return data8(22); } + public int hdop() { return data8(23); } + public int vdop() { return data8(24); } + public int mode() { return data8(25); } + public int state() { return data8(26); } + + /* AO_LOG_GPS_SAT elements */ + public int nsat() { return data16(0); } + public int svid(int n) { return data8(2 + n * 2); } + public int c_n(int n) { return data8(2 + n * 2 + 1); } + + public AltosEepromGPS (AltosEepromChunk chunk, int start) throws ParseException { + parse_chunk(chunk, start); + } + + public void update_state(AltosState state) { + super.update_state(state); + + AltosGPS gps; + + /* Flush any pending GPS changes */ + if (state.gps_pending) { + switch (cmd) { + case AltosLib.AO_LOG_GPS_LAT: + case AltosLib.AO_LOG_GPS_LON: + case AltosLib.AO_LOG_GPS_ALT: + case AltosLib.AO_LOG_GPS_SAT: + case AltosLib.AO_LOG_GPS_DATE: + break; + default: + state.set_temp_gps(); + break; + } + } + + switch (cmd) { + case AltosLib.AO_LOG_FLIGHT: + state.set_boost_tick(tick); + state.set_flight(flight()); + /* no place to log start lat/lon yet */ + break; + case AltosLib.AO_LOG_GPS_TIME: + state.set_tick(tick); + state.set_state(state()); + gps = state.make_temp_gps(false); + gps.lat = latitude() / 1e7; + gps.lon = longitude() / 1e7; + gps.alt = altitude(); + + gps.hour = hour(); + gps.minute = minute(); + gps.second = second(); + + int flags = flags(); + + gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; + gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; + gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> + AltosLib.AO_GPS_NUM_SAT_SHIFT; + + gps.year = 2000 + year(); + gps.month = month(); + gps.day = day(); + gps.ground_speed = ground_speed() * 1.0e-2; + gps.course = course() * 2; + gps.climb_rate = climb_rate() * 1.0e-2; + gps.hdop = hdop(); + gps.vdop = vdop(); + break; + case AltosLib.AO_LOG_GPS_SAT: + state.set_tick(tick); + gps = state.make_temp_gps(true); + + int n = nsat(); + if (n > max_sat) + n = max_sat; + for (int i = 0; i < n; i++) + gps.add_sat(svid(i), c_n(i)); + break; + } + } + + public AltosEepromGPS (String line) { + parse_string(line); + } + + static public LinkedList read(FileInputStream input) { + LinkedList tgpss = new LinkedList(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + try { + AltosEepromGPS tgps = new AltosEepromGPS(line); + if (tgps.cmd != AltosLib.AO_LOG_INVALID) + tgpss.add(tgps); + } catch (Exception e) { + System.out.printf ("exception\n"); + } + } catch (IOException ie) { + break; + } + } + + return tgpss; + } +} -- cgit v1.2.3 From 871fb4753a3b54cc2e22309e80e24dfe9cc54511 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 10 Jun 2014 10:15:47 -0700 Subject: altoslib: TeleGPS no longer logs satellite information This doubles the amount of space available to log position information Signed-off-by: Keith Packard --- altoslib/AltosEepromGPS.java | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'altoslib/AltosEepromGPS.java') diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java index 33172eed..1820cd61 100644 --- a/altoslib/AltosEepromGPS.java +++ b/altoslib/AltosEepromGPS.java @@ -52,12 +52,6 @@ public class AltosEepromGPS extends AltosEeprom { public int hdop() { return data8(23); } public int vdop() { return data8(24); } public int mode() { return data8(25); } - public int state() { return data8(26); } - - /* AO_LOG_GPS_SAT elements */ - public int nsat() { return data16(0); } - public int svid(int n) { return data8(2 + n * 2); } - public int c_n(int n) { return data8(2 + n * 2 + 1); } public AltosEepromGPS (AltosEepromChunk chunk, int start) throws ParseException { parse_chunk(chunk, start); @@ -91,7 +85,6 @@ public class AltosEepromGPS extends AltosEeprom { break; case AltosLib.AO_LOG_GPS_TIME: state.set_tick(tick); - state.set_state(state()); gps = state.make_temp_gps(false); gps.lat = latitude() / 1e7; gps.lon = longitude() / 1e7; @@ -117,16 +110,6 @@ public class AltosEepromGPS extends AltosEeprom { gps.hdop = hdop(); gps.vdop = vdop(); break; - case AltosLib.AO_LOG_GPS_SAT: - state.set_tick(tick); - gps = state.make_temp_gps(true); - - int n = nsat(); - if (n > max_sat) - n = max_sat; - for (int i = 0; i < n; i++) - gps.add_sat(svid(i), c_n(i)); - break; } } -- cgit v1.2.3 From a8325483adb8d9ffda62d3f4900cf52bde70ff62 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 11 Jun 2014 18:48:11 -0700 Subject: altoslib: Use GPS seconds as an additional sort key for TeleGPS eeprom Long idle periods with TeleGPS can easily overflow 16 bits of tick count. Using the GPS seconds provides an additional sort which will span the tick wrap-around. Signed-off-by: Keith Packard --- altoslib/AltosEeprom.java | 4 ++++ altoslib/AltosEepromGPS.java | 11 +++++++++++ altoslib/AltosEepromIterable.java | 9 ++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) (limited to 'altoslib/AltosEepromGPS.java') diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java index be18ba24..020590eb 100644 --- a/altoslib/AltosEeprom.java +++ b/altoslib/AltosEeprom.java @@ -43,6 +43,10 @@ public abstract class AltosEeprom implements AltosStateUpdate { return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); } + public boolean has_seconds() { return false; } + + public int seconds() { return 0; } + public final static int header_length = 4; public abstract int record_length(); diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java index 1820cd61..3c1852c0 100644 --- a/altoslib/AltosEepromGPS.java +++ b/altoslib/AltosEepromGPS.java @@ -53,6 +53,17 @@ public class AltosEepromGPS extends AltosEeprom { public int vdop() { return data8(24); } public int mode() { return data8(25); } + public boolean has_seconds() { return cmd == AltosLib.AO_LOG_GPS_TIME; } + + public int seconds() { + switch (cmd) { + case AltosLib.AO_LOG_GPS_TIME: + return second() + 60 * (minute() + 60 * (hour() + 24 * (day() + 31 * month()))); + default: + return 0; + } + } + public AltosEepromGPS (AltosEepromChunk chunk, int start) throws ParseException { parse_chunk(chunk, start); } diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java index 415c5b62..d6832c1b 100644 --- a/altoslib/AltosEepromIterable.java +++ b/altoslib/AltosEepromIterable.java @@ -38,6 +38,13 @@ class AltosEepromOrdered implements Comparable { if (cmd_diff != 0) return cmd_diff; + if (eeprom.has_seconds() && o.eeprom.has_seconds()) { + int seconds_diff = eeprom.seconds() - o.eeprom.seconds(); + + if (seconds_diff != 0) + return seconds_diff; + } + int tick_diff = tick - o.tick; if (tick_diff != 0) @@ -116,4 +123,4 @@ public class AltosEepromIterable implements Iterable { eeproms = new LinkedList(); return new AltosEepromOrderedIterator(eeproms); } -} \ No newline at end of file +} -- cgit v1.2.3