X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=ao-tools%2Faltosui%2FAltosEepromReader.java;h=86bbaee0cde2a9640b768aca0f17a428032cc941;hp=7a8ff5b036a2f3dc4811bcf607fa2adb81739794;hb=6c653a4cba5fef8d49261cf1c024f3e86e9058c6;hpb=0e917f3ff822616adb147517ac961422e5fedbfd diff --git a/ao-tools/altosui/AltosEepromReader.java b/ao-tools/altosui/AltosEepromReader.java index 7a8ff5b0..86bbaee0 100644 --- a/ao-tools/altosui/AltosEepromReader.java +++ b/ao-tools/altosui/AltosEepromReader.java @@ -36,9 +36,13 @@ import altosui.AltosLog; import altosui.AltosVoice; import altosui.AltosEepromMonitor; +/* + * AltosRecords with an index field so they can be sorted by tick while preserving + * the original ordering for elements with matching ticks + */ class AltosOrderedRecord extends AltosEepromRecord implements Comparable { - int index; + public int index; public AltosOrderedRecord(String line, int in_index, int prev_tick) throws ParseException { @@ -52,6 +56,11 @@ class AltosOrderedRecord extends AltosEepromRecord implements Comparable> 8); state.gps.second = (record.b & 0xff); @@ -182,7 +203,7 @@ public class AltosEepromReader { } break; case Altos.AO_LOG_GPS_DATE: - state.gps.year = record.a & 0xff; + state.gps.year = (record.a & 0xff) + 2000; state.gps.month = record.a >> 8; state.gps.day = record.b & 0xff; break; @@ -209,6 +230,7 @@ public class AltosEepromReader { case Altos.AO_LOG_PRODUCT: break; case Altos.AO_LOG_SERIAL_NUMBER: + state.serial = record.a; break; case Altos.AO_LOG_SOFTWARE_VERSION: break; @@ -217,18 +239,99 @@ public class AltosEepromReader { } } - public AltosEepromReader (FileInputStream in_input) { + public void write_comments(PrintStream out) { + Iterator iterator = records.iterator(); + out.printf("# Comments\n"); + while (iterator.hasNext()) { + AltosOrderedRecord record = iterator.next(); + switch (record.cmd) { + case Altos.AO_LOG_CONFIG_VERSION: + out.printf("# Config version: %s\n", record.data); + break; + case Altos.AO_LOG_MAIN_DEPLOY: + out.printf("# Main deploy: %s\n", record.a); + break; + case Altos.AO_LOG_APOGEE_DELAY: + out.printf("# Apogee delay: %s\n", record.a); + break; + case Altos.AO_LOG_RADIO_CHANNEL: + out.printf("# Radio channel: %s\n", record.a); + break; + case Altos.AO_LOG_CALLSIGN: + out.printf("# Callsign: %s\n", record.data); + break; + case Altos.AO_LOG_ACCEL_CAL: + out.printf ("# Accel cal: %d %d\n", record.a, record.b); + break; + case Altos.AO_LOG_RADIO_CAL: + out.printf ("# Radio cal: %d\n", record.a); + break; + case Altos.AO_LOG_MANUFACTURER: + out.printf ("# Manufacturer: %s\n", record.data); + break; + case Altos.AO_LOG_PRODUCT: + out.printf ("# Product: %s\n", record.data); + break; + case Altos.AO_LOG_SERIAL_NUMBER: + out.printf ("# Serial number: %d\n", record.a); + break; + case Altos.AO_LOG_SOFTWARE_VERSION: + out.printf ("# Software version: %s\n", record.data); + break; + } + } + } + + /* + * Given an AO_LOG_GPS_TIME record with correct time, and one + * missing time, rewrite the missing time values with the good + * ones, assuming that the difference between them is 'diff' seconds + */ + void update_time(AltosOrderedRecord good, AltosOrderedRecord bad) { + + int diff = (bad.tick - good.tick + 50) / 100; + + int hour = (good.a & 0xff); + int minute = (good.a >> 8); + int second = (good.b & 0xff); + int flags = (good.b >> 8); + int seconds = hour * 3600 + minute * 60 + second; + + int new_seconds = seconds + diff; + if (new_seconds < 0) + new_seconds += 24 * 3600; + int new_second = (new_seconds % 60); + int new_minutes = (new_seconds / 60); + int new_minute = (new_minutes % 60); + int new_hours = (new_minutes / 60); + int new_hour = (new_hours % 24); + + bad.a = new_hour + (new_minute << 8); + bad.b = new_second + (flags << 8); + } + + /* + * Read the whole file, dumping records into a RB tree so + * we can enumerate them in time order -- the eeprom data + * are sometimes out of order with GPS data getting timestamps + * matching the first packet out of the GPS unit but not + * written until the final GPS packet has been received. + */ + public AltosEepromReader (FileInputStream input) { state = new AltosRecord(); state.state = Altos.ao_flight_pad; state.accel_plus_g = 15758; state.accel_minus_g = 16294; - input = in_input; seen = 0; records = new TreeSet(); + AltosOrderedRecord last_gps_time = null; + int index = 0; int tick = 0; + boolean missing_time = false; + try { for (;;) { String line = AltosRecord.gets(input); @@ -237,12 +340,70 @@ public class AltosEepromReader { AltosOrderedRecord record = new AltosOrderedRecord(line, index++, tick); if (record == null) break; + if (record.cmd == Altos.AO_LOG_INVALID) + continue; tick = record.tick; + if (!saw_boost && record.cmd == Altos.AO_LOG_STATE && + record.a >= Altos.ao_flight_boost) + { + saw_boost = true; + boost_tick = tick; + } + if (record.cmd == Altos.AO_LOG_FLIGHT) { + state.ground_accel = record.a; + state.flight = record.b; + seen |= seen_flight; + } + + /* Two firmware bugs caused the loss of some GPS data. + * The flight date would never be recorded, and often + * the flight time would get overwritten by another + * record. Detect the loss of the GPS date and fix up the + * missing time records + */ + if (record.cmd == Altos.AO_LOG_GPS_DATE) + saw_gps_date = true; + + /* go back and fix up any missing time values */ + if (record.cmd == Altos.AO_LOG_GPS_TIME) { + last_gps_time = record; + if (missing_time) { + Iterator iterator = records.iterator(); + while (iterator.hasNext()) { + AltosOrderedRecord old = iterator.next(); + if (old.cmd == Altos.AO_LOG_GPS_TIME && + old.a == -1 && old.b == -1) + { + update_time(record, old); + } + } + missing_time = false; + } + } + + if (record.cmd == Altos.AO_LOG_GPS_LAT) { + if (last_gps_time == null || last_gps_time.tick != record.tick) { + AltosOrderedRecord add_gps_time = new AltosOrderedRecord(Altos.AO_LOG_GPS_TIME, + record.tick, + -1, -1, index-1); + if (last_gps_time != null) + update_time(last_gps_time, add_gps_time); + else + missing_time = true; + + records.add(add_gps_time); + record.index = index++; + } + } records.add(record); } } catch (IOException io) { } catch (ParseException pe) { } record_iterator = records.iterator(); + try { + input.close(); + } catch (IOException ie) { + } } }