From de8d9c5630ae46378c50faf97f7d2e97fe139e30 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 29 Aug 2013 19:24:51 -0500 Subject: [PATCH] altoslib, altosui: Restructured state management now does TM eeprom files Removed uses of AltosRecord from AltosState, now just need to rewrite the other AltosState changing code to match Signed-off-by: Keith Packard --- altoslib/AltosConvert.java | 6 + altoslib/AltosEepromFile.java | 64 +++- altoslib/AltosEepromHeader.java | 13 +- altoslib/AltosEepromHeaderIterable.java | 2 +- altoslib/AltosEepromIterable.java | 72 +++- altoslib/AltosEepromMini.java | 17 + altoslib/AltosEepromMiniIterable.java | 2 +- altoslib/AltosEepromTM.java | 249 ++++++-------- altoslib/AltosFlightReader.java | 2 +- altoslib/AltosGPS.java | 10 +- altoslib/AltosIMU.java | 1 + altoslib/AltosLib.java | 4 +- altoslib/AltosRecord.java | 8 + altoslib/AltosReplayReader.java | 6 +- altoslib/AltosState.java | 425 +++++++++++++++--------- altoslib/AltosStateIterable.java | 29 ++ altoslib/AltosTelemetryReader.java | 6 +- altoslib/Makefile.am | 3 +- altosui/AltosAscent.java | 17 +- altosui/AltosCSV.java | 113 ++++--- altosui/AltosCSVUI.java | 8 +- altosui/AltosCompanionInfo.java | 4 +- altosui/AltosDataChooser.java | 12 +- altosui/AltosDescent.java | 17 +- altosui/AltosDisplayThread.java | 12 +- altosui/AltosEepromDownload.java | 5 +- altosui/AltosFlightStats.java | 99 +++--- altosui/AltosFlightStatsTable.java | 8 +- altosui/AltosFlightStatus.java | 14 +- altosui/AltosFlightUI.java | 2 +- altosui/AltosGraphDataPoint.java | 17 +- altosui/AltosGraphDataSet.java | 31 +- altosui/AltosGraphUI.java | 13 +- altosui/AltosInfoTable.java | 20 +- altosui/AltosKML.java | 56 ++-- altosui/AltosLanded.java | 14 +- altosui/AltosPad.java | 28 +- altosui/AltosScanUI.java | 12 +- altosui/AltosSiteMap.java | 21 +- altosui/AltosUI.java | 106 +++--- altosui/AltosWriter.java | 4 +- 41 files changed, 907 insertions(+), 645 deletions(-) create mode 100644 altoslib/AltosStateIterable.java diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index 8cd478e2..a1e2cdca 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -190,6 +190,12 @@ public class AltosConvert { return ignite / 32767 * 15.0; } + public static double + barometer_to_pressure(double count) + { + return ((count / 16.0) / 2047.0 + 0.095) / 0.009 * 1000.0; + } + public static double radio_to_frequency(int freq, int setting, int cal, int channel) { double f; diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index 48d2543c..bcc7171e 100644 --- a/altoslib/AltosEepromFile.java +++ b/altoslib/AltosEepromFile.java @@ -21,11 +21,47 @@ import java.io.*; import java.util.*; import java.text.*; -public class AltosEepromFile { +class AltosEepromIterator implements Iterator { + AltosState state; + Iterator body; + AltosEeprom next; + boolean seen; + + public boolean hasNext() { + return !seen || body.hasNext(); + } + + public AltosState next() { + if (seen) { + AltosState n = state.clone(); + AltosEeprom e = body.next(); + + e.update_state(n); + state = n; + } + seen = true; + return state; + } + + public void remove () { + } + + public AltosEepromIterator(AltosState start, Iterator body) { + this.state = start; + this.body = body; + this.seen = false; + } +} + +public class AltosEepromFile extends AltosStateIterable { AltosEepromIterable headers; AltosEepromIterable body; + public void write_comments(PrintStream out) { + headers.write(out); + } + public void write(PrintStream out) { headers.write(out); body.write(out); @@ -38,14 +74,38 @@ public class AltosEepromFile { switch (state.log_format) { case AltosLib.AO_LOG_FORMAT_FULL: + body = new AltosEepromIterable(AltosEepromTM.read(input)); + break; case AltosLib.AO_LOG_FORMAT_TINY: case AltosLib.AO_LOG_FORMAT_TELEMETRY: case AltosLib.AO_LOG_FORMAT_TELESCIENCE: case AltosLib.AO_LOG_FORMAT_TELEMEGA: break; - case AltosLib.AO_LOG_FORMAT_MINI: + case AltosLib.AO_LOG_FORMAT_TELEMINI: + case AltosLib.AO_LOG_FORMAT_EASYMINI: body = new AltosEepromIterable(AltosEepromMini.read(input)); break; } } + + int boost_tick (AltosState start) { + AltosState state = start.clone(); + for (AltosEeprom eeprom : body) { + eeprom.update_state(state); + if (state.state >= AltosLib.ao_flight_boost) + return state.tick; + } + return 0; + } + + public Iterator iterator() { + + AltosState state = headers.state(); + Iterator i = body.iterator(); + + while (i.hasNext() && !state.valid()) + i.next().update_state(state); + state.set_boost_tick(boost_tick(state)); + return new AltosEepromIterator(state, i); + } } \ No newline at end of file diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java index b2343dc6..a06f05ed 100644 --- a/altoslib/AltosEepromHeader.java +++ b/altoslib/AltosEepromHeader.java @@ -43,8 +43,7 @@ public class AltosEepromHeader extends AltosEeprom { state.callsign = data; break; case AltosLib.AO_LOG_ACCEL_CAL: - state.accel_plus_g = config_a; - state.accel_minus_g = config_b; + state.set_accel_g(config_a, config_b); break; case AltosLib.AO_LOG_RADIO_CAL: break; @@ -56,30 +55,38 @@ public class AltosEepromHeader extends AltosEeprom { state.log_format = config_a; break; case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = config_a; + state.set_serial(config_a); break; case AltosLib.AO_LOG_BARO_RESERVED: + state.make_baro(); state.baro.reserved = config_a; break; case AltosLib.AO_LOG_BARO_SENS: + state.make_baro(); state.baro.sens = config_a; break; case AltosLib.AO_LOG_BARO_OFF: + state.make_baro(); state.baro.off = config_a; break; case AltosLib.AO_LOG_BARO_TCS: + state.make_baro(); state.baro.tcs = config_a; break; case AltosLib.AO_LOG_BARO_TCO: + state.make_baro(); state.baro.tco = config_a; break; case AltosLib.AO_LOG_BARO_TREF: + state.make_baro(); state.baro.tref = config_a; break; case AltosLib.AO_LOG_BARO_TEMPSENS: + state.make_baro(); state.baro.tempsens = config_a; break; case AltosLib.AO_LOG_BARO_CRC: + state.make_baro(); state.baro.crc = config_a; break; case AltosLib.AO_LOG_SOFTWARE_VERSION: diff --git a/altoslib/AltosEepromHeaderIterable.java b/altoslib/AltosEepromHeaderIterable.java index fe9e05d9..01953f0e 100644 --- a/altoslib/AltosEepromHeaderIterable.java +++ b/altoslib/AltosEepromHeaderIterable.java @@ -29,7 +29,7 @@ public class AltosEepromHeaderIterable implements Iterable { } public AltosState state() { - AltosState state = new AltosState(null); + AltosState state = new AltosState(); for (AltosEepromHeader header : headers) header.update_state(state); diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java index 470a7a8a..8e6a2313 100644 --- a/altoslib/AltosEepromIterable.java +++ b/altoslib/AltosEepromIterable.java @@ -21,6 +21,74 @@ import java.io.*; import java.util.*; import java.text.*; +class AltosEepromOrdered implements Comparable { + AltosEeprom eeprom; + int index; + int tick; + + int cmdi() { + if (eeprom.cmd == AltosLib.AO_LOG_FLIGHT) + return 0; + return 1; + } + + public int compareTo(AltosEepromOrdered o) { + int cmd_diff = cmdi() - o.cmdi(); + + if (cmd_diff != 0) + return cmd_diff; + + int tick_diff = tick - o.tick; + + if (tick_diff != 0) + return tick_diff; + return index - o.index; + } + + AltosEepromOrdered (AltosEeprom eeprom, int index, int tick) { + this.eeprom = eeprom; + this.index = index; + this.tick = tick; + } +} + +class AltosEepromOrderedIterator implements Iterator { + TreeSet olist; + Iterator oiterator; + + public AltosEepromOrderedIterator(Iterable eeproms) { + olist = new TreeSet(); + + int tick = 0; + int index = 0; + boolean first = true; + + for (AltosEeprom e : eeproms) { + int t = e.tick; + if (first) + tick = t; + else { + while (t < tick - 32767) + t += 65536; + tick = t; + } + olist.add(new AltosEepromOrdered(e, index++, tick)); + } + oiterator = olist.iterator(); + } + + public boolean hasNext() { + return oiterator.hasNext(); + } + + public AltosEeprom next() { + return oiterator.next().eeprom; + } + + public void remove () { + } +} + public class AltosEepromIterable implements Iterable { public LinkedList eeproms; @@ -30,7 +98,7 @@ public class AltosEepromIterable implements Iterable { } public AltosState state() { - AltosState state = new AltosState(null); + AltosState state = new AltosState(); for (AltosEeprom header : eeproms) header.update_state(state); @@ -44,6 +112,6 @@ public class AltosEepromIterable implements Iterable { public Iterator iterator() { if (eeproms == null) eeproms = new LinkedList(); - return eeproms.iterator(); + return new AltosEepromOrderedIterator(eeproms); } } \ No newline at end of file diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index ced87680..1e0ff1b9 100644 --- a/altoslib/AltosEepromMini.java +++ b/altoslib/AltosEepromMini.java @@ -55,13 +55,30 @@ public class AltosEepromMini extends AltosEeprom { public int sense_m() { return data16(8); } public int v_batt() { return data16(10); } + double voltage(AltosState state, int sensor) { + double supply; + + if (state.log_format == AltosLib.AO_LOG_FORMAT_EASYMINI) + supply = 3.0; + else + supply = 3.3; + return sensor / 32767.0 * supply * 127/27; + } + public void update_state(AltosState state) { switch (cmd) { case AltosLib.AO_LOG_FLIGHT: + state.set_flight(flight()); + state.set_ground_pressure(ground_pres()); break; case AltosLib.AO_LOG_STATE: + state.set_state(state()); break; case AltosLib.AO_LOG_SENSOR: + state.set_ms5607(pres(), temp()); + state.set_apogee_voltage(voltage(state, sense_a())); + state.set_main_voltage(voltage(state, sense_m())); + state.set_battery_voltage(voltage(state, v_batt())); break; } } diff --git a/altoslib/AltosEepromMiniIterable.java b/altoslib/AltosEepromMiniIterable.java index 1f221187..495495eb 100644 --- a/altoslib/AltosEepromMiniIterable.java +++ b/altoslib/AltosEepromMiniIterable.java @@ -21,7 +21,7 @@ import java.io.*; import java.util.*; import java.text.*; -public class AltosEepromMiniIterable extends AltosRecordIterable { +public class AltosEepromMiniIterable implements Iterable { static final int seen_flight = 1; static final int seen_sensor = 2; diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index fc7ec321..6945468b 100644 --- a/altoslib/AltosEepromTM.java +++ b/altoslib/AltosEepromTM.java @@ -17,134 +17,119 @@ package org.altusmetrum.altoslib_1; +import java.io.*; +import java.util.*; import java.text.*; -public class AltosEepromTM implements AltosStateUpdate { +public class AltosEepromTM extends AltosEeprom { public int cmd; public int tick; public int a; public int b; - public String data; public boolean tick_valid; public static final int record_length = 8; + static double + thermometer_to_temperature(double thermo) + { + return (thermo - 19791.268) / 32728.0 * 1.25 / 0.00247; + } + + public void write(PrintStream out) { + out.printf("%c %4x %4x %4x\n", cmd, tick, a, b); + } + public void update_state(AltosState state) { - state.set_tick(tick); + 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.ground_accel = a; - state.flight = b; + state.set_state(AltosLib.ao_flight_pad); + state.set_ground_accel(a); + state.set_flight(b); state.set_boost_tick(tick); - state.time = 0; break; case AltosLib.AO_LOG_SENSOR: - state.set_telemetrum(a, b); + state.set_tick(tick); + state.set_accel(a); + double pressure = AltosConvert.barometer_to_pressure(b); + state.set_pressure(pressure); break; case AltosLib.AO_LOG_PRESSURE: - state.set_telemetrum(AltosState.MISSING, b); + state.set_tick(tick); + state.set_pressure(AltosConvert.barometer_to_pressure(b)); break; case AltosLib.AO_LOG_TEMP_VOLT: -/* - - record.temp = a; - record.batt = b; - eeprom_state.seen |= AltosRecord.seen_temp_volt; -*/ + state.set_tick(tick); + state.set_temperature(thermometer_to_temperature(a)); + state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(b)); break; case AltosLib.AO_LOG_DEPLOY: -/* - record.drogue = a; - record.main = b; - eeprom_state.seen |= AltosRecord.seen_deploy; - has_ignite = true; -*/ + state.set_tick(tick); + state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(a)); + state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(b)); break; case AltosLib.AO_LOG_STATE: - state.state = a; - break; -// case AltosLib.AO_LOG_GPS_TIME: -// eeprom_state.gps_tick = record.tick; -// eeprom_state.seen |= AltosRecord.seen_gps_time; -// AltosGPS old = state.gps; -// AltosGPS gps = new AltosGPS(); -// -// /* GPS date doesn't get repeated through the file */ -// if (old != null) { -// gps.year = old.year; -// gps.month = old.month; -// gps.day = old.day; -// } -// gps.hour = (a & 0xff); -// gps.minute = (a >> 8); -// gps.second = (b & 0xff); -// -// int flags = (b >> 8); -// 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; -// state.temp_gps = gps; -// break; -// case AltosLib.AO_LOG_GPS_LAT: -// int lat32 = a | (b << 16); -// if (state.temp_gps == null) -// state.temp_gps = new AltosGPS(); -// state.temp_gps.lat = (double) lat32 / 1e7; -// break; -// case AltosLib.AO_LOG_GPS_LON: -// int lon32 = a | (b << 16); -// if (state.temp_gps == null) -// state.temp_gps = new AltosGPS(); -// state.temp_gps.lon = (double) lon32 / 1e7; -// break; -// case AltosLib.AO_LOG_GPS_ALT: -// if (state.temp_gps == null) -// state.temp_gps = new AltosGPS(); -// state.temp_gps.alt = a; -// break; -// case AltosLib.AO_LOG_GPS_SAT: -// if (record.tick == eeprom_state.gps_tick) { -// int svid = a; -// int c_n0 = b >> 8; -// if (record.gps == null) -// record.gps = new AltosGPS(); -// record.gps.add_sat(svid, c_n0); -// } -// break; -// case AltosLib.AO_LOG_GPS_DATE: -// if (record.gps == null) -// record.gps = new AltosGPS(); -// record.gps.year = (a & 0xff) + 2000; -// record.gps.month = a >> 8; -// record.gps.day = b & 0xff; -// break; - - case AltosLib.AO_LOG_CONFIG_VERSION: - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - break; - case AltosLib.AO_LOG_CALLSIGN: - state.callsign = data; + state.set_tick(tick); + state.set_state(a); break; - case AltosLib.AO_LOG_ACCEL_CAL: - state.accel_plus_g = a; - state.accel_minus_g = b; + case AltosLib.AO_LOG_GPS_TIME: + gps = state.make_temp_gps(); + + gps.hour = (a & 0xff); + gps.minute = (a >> 8); + gps.second = (b & 0xff); + + int flags = (b >> 8); + + 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; break; - case AltosLib.AO_LOG_RADIO_CAL: + case AltosLib.AO_LOG_GPS_LAT: + gps = state.make_temp_gps(); + + int lat32 = a | (b << 16); + gps.lat = (double) lat32 / 1e7; break; - case AltosLib.AO_LOG_MANUFACTURER: + case AltosLib.AO_LOG_GPS_LON: + gps = state.make_temp_gps(); + + int lon32 = a | (b << 16); + gps.lon = (double) lon32 / 1e7; break; - case AltosLib.AO_LOG_PRODUCT: + case AltosLib.AO_LOG_GPS_ALT: + gps = state.make_temp_gps(); + gps.alt = a; break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = a; + case AltosLib.AO_LOG_GPS_SAT: + gps = state.make_temp_gps(); + int svid = a; + int c_n0 = b >> 8; + gps.add_sat(svid, c_n0); break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: + case AltosLib.AO_LOG_GPS_DATE: + gps = state.make_temp_gps(); + gps.year = (a & 0xff) + 2000; + gps.month = a >> 8; + gps.day = b & 0xff; break; } } @@ -166,8 +151,6 @@ public class AltosEepromTM implements AltosStateUpdate { tick = chunk.data16(start + 2); a = chunk.data16(start + 4); b = chunk.data16(start + 6); - - data = null; } public AltosEepromTM (String line) { @@ -175,10 +158,8 @@ public class AltosEepromTM implements AltosStateUpdate { tick = 0; a = 0; b = 0; - data = null; if (line == null) { cmd = AltosLib.AO_LOG_INVALID; - data = ""; } else { try { String[] tokens = line.split("\\s+"); @@ -186,7 +167,6 @@ public class AltosEepromTM implements AltosStateUpdate { if (tokens[0].length() == 1) { if (tokens.length != 4) { cmd = AltosLib.AO_LOG_INVALID; - data = line; } else { cmd = tokens[0].codePointAt(0); tick = Integer.parseInt(tokens[1],16); @@ -194,53 +174,11 @@ public class AltosEepromTM implements AltosStateUpdate { a = Integer.parseInt(tokens[2],16); b = Integer.parseInt(tokens[3],16); } - } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { - cmd = AltosLib.AO_LOG_CONFIG_VERSION; - data = tokens[2]; - } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { - cmd = AltosLib.AO_LOG_MAIN_DEPLOY; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { - cmd = AltosLib.AO_LOG_APOGEE_DELAY; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { - cmd = AltosLib.AO_LOG_RADIO_CHANNEL; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Callsign:")) { - cmd = AltosLib.AO_LOG_CALLSIGN; - data = tokens[1].replaceAll("\"",""); - } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { - cmd = AltosLib.AO_LOG_ACCEL_CAL; - a = Integer.parseInt(tokens[3]); - b = Integer.parseInt(tokens[5]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { - cmd = AltosLib.AO_LOG_RADIO_CAL; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { - cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; - a = Integer.parseInt(tokens[3]); - } else if (tokens[0].equals("manufacturer")) { - cmd = AltosLib.AO_LOG_MANUFACTURER; - data = tokens[1]; - } else if (tokens[0].equals("product")) { - cmd = AltosLib.AO_LOG_PRODUCT; - data = tokens[1]; - } else if (tokens[0].equals("serial-number")) { - cmd = AltosLib.AO_LOG_SERIAL_NUMBER; - a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("log-format")) { - cmd = AltosLib.AO_LOG_LOG_FORMAT; - a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("software-version")) { - cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; - data = tokens[1]; } else { cmd = AltosLib.AO_LOG_INVALID; - data = line; } } catch (NumberFormatException ne) { -v cmd = AltosLib.AO_LOG_INVALID; - data = line; + cmd = AltosLib.AO_LOG_INVALID; } } } @@ -252,4 +190,23 @@ v cmd = AltosLib.AO_LOG_INVALID; a = in_a; b = in_b; } + + static public LinkedList read(FileInputStream input) { + LinkedList tms = new LinkedList(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + AltosEepromTM tm = new AltosEepromTM(line); + tms.add(tm); + } catch (IOException ie) { + break; + } + } + + return tms; + } + } diff --git a/altoslib/AltosFlightReader.java b/altoslib/AltosFlightReader.java index 34526658..5a415274 100644 --- a/altoslib/AltosFlightReader.java +++ b/altoslib/AltosFlightReader.java @@ -28,7 +28,7 @@ public class AltosFlightReader { public void init() { } - public AltosRecord read() throws InterruptedException, ParseException, AltosCRCException, IOException { return null; } + public AltosState read() throws InterruptedException, ParseException, AltosCRCException, IOException { return null; } public void close(boolean interrupted) { } diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index f7929a4c..eb384e4d 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -28,7 +28,7 @@ public class AltosGPS implements Cloneable { public boolean connected; public double lat; /* degrees (+N -S) */ public double lon; /* degrees (+E -W) */ - public int alt; /* m */ + public double alt; /* m */ public int year; public int month; public int day; @@ -222,7 +222,7 @@ public class AltosGPS implements Cloneable { g.nsat = nsat; g.locked = locked; g.connected = connected; - g.lat = lat; g./* degrees (+N -S) */ + g.lat = lat; /* degrees (+N -S) */ g.lon = lon; /* degrees (+E -W) */ g.alt = alt; /* m */ g.year = year; @@ -242,11 +242,11 @@ public class AltosGPS implements Cloneable { if (cc_gps_sat != null) { g.cc_gps_sat = new AltosGPSSat[cc_gps_sat.length]; for (int i = 0; i < cc_gps_sat.length; i++) { - g.cc_gps_sat[i] = new AltosGPSSat(); - g.cc_gps_sat[i].svid = cc_gps_sat[i].svid; - g.cc_gps_sat[i].c_n0 = cc_gps_sat[i].c_n0; + g.cc_gps_sat[i] = new AltosGPSSat(cc_gps_sat[i].svid, + cc_gps_sat[i].c_n0); } } + return g; } public AltosGPS(AltosGPS old) { diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java index 46df35bf..c5ebbb16 100644 --- a/altoslib/AltosIMU.java +++ b/altoslib/AltosIMU.java @@ -37,5 +37,6 @@ public class AltosIMU implements Cloneable { n.gyro_y = gyro_y; n.gyro_z = gyro_z; return n; + } } \ No newline at end of file diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index d60ef492..4ca8ad9d 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -218,7 +218,9 @@ public class AltosLib { public static final int AO_LOG_FORMAT_TELEMETRY = 3; public static final int AO_LOG_FORMAT_TELESCIENCE = 4; public static final int AO_LOG_FORMAT_TELEMEGA = 5; - public static final int AO_LOG_FORMAT_MINI = 6; + public static final int AO_LOG_FORMAT_EASYMINI = 6; + public static final int AO_LOG_FORMAT_TELEMETRUM = 7; + public static final int AO_LOG_FORMAT_TELEMINI = 8; public static final int AO_LOG_FORMAT_NONE = 127; public static boolean isspace(int c) { diff --git a/altoslib/AltosRecord.java b/altoslib/AltosRecord.java index 5e4ed927..0c8e1db9 100644 --- a/altoslib/AltosRecord.java +++ b/altoslib/AltosRecord.java @@ -56,6 +56,10 @@ public class AltosRecord implements Comparable , Cloneable { public int flight_log_max; public String firmware_version; + public double accel_plus_g, accel_minus_g; + public double ground_accel; + public double accel; + public AltosRecordCompanion companion; /* Telemetry sources have these values recorded from the flight computer */ @@ -167,5 +171,9 @@ public class AltosRecord implements Comparable , Cloneable { kalman_acceleration = MISSING; kalman_speed = MISSING; kalman_height = MISSING; + + accel_plus_g = MISSING; + accel_minus_g = MISSING; + } } diff --git a/altoslib/AltosReplayReader.java b/altoslib/AltosReplayReader.java index a7e30370..0c14dee4 100644 --- a/altoslib/AltosReplayReader.java +++ b/altoslib/AltosReplayReader.java @@ -25,10 +25,10 @@ import java.util.*; */ public class AltosReplayReader extends AltosFlightReader { - Iterator iterator; + Iterator iterator; File file; - public AltosRecord read() { + public AltosState read() { if (iterator.hasNext()) return iterator.next(); return null; @@ -45,7 +45,7 @@ public class AltosReplayReader extends AltosFlightReader { public File backing_file() { return file; } - public AltosReplayReader(Iterator in_iterator, File in_file) { + public AltosReplayReader(Iterator in_iterator, File in_file) { iterator = in_iterator; file = in_file; name = file.getName(); diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index b40b744f..daf06c19 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -22,22 +22,35 @@ package org.altusmetrum.altoslib_1; public class AltosState implements Cloneable { - public AltosRecord data; + public AltosRecord record; + + public static final int set_position = 1; + public static final int set_gps = 2; + public static final int set_data = 4; + + public int set; /* derived data */ public long report_time; public double time; + public double prev_time; public double time_change; public int tick; + public int boost_tick; public int state; + public int flight; + public int serial; public boolean landed; public boolean ascent; /* going up? */ public boolean boost; /* under power */ + public int rssi; + public int status; public double ground_altitude; + public double ground_pressure; public double altitude; public double height; public double pressure; @@ -60,6 +73,8 @@ public class AltosState implements Cloneable { public double kalman_height, kalman_speed, kalman_acceleration; public AltosGPS gps; + public AltosGPS temp_gps; + public boolean gps_pending; public int gps_sequence; public AltosIMU imu; @@ -91,10 +106,11 @@ public class AltosState implements Cloneable { public double ground_accel; public int log_format; - public int serial; public AltosMs5607 baro; + public AltosRecordCompanion companion; + public double speed() { return speed; } @@ -112,17 +128,25 @@ public class AltosState implements Cloneable { } public void init() { - data = new AltosRecord(); + record = null; + + set = 0; report_time = System.currentTimeMillis(); time = AltosRecord.MISSING; time_change = AltosRecord.MISSING; + prev_time = AltosRecord.MISSING; tick = AltosRecord.MISSING; + boost_tick = AltosRecord.MISSING; state = AltosLib.ao_flight_invalid; + flight = AltosRecord.MISSING; landed = false; boost = false; + rssi = AltosRecord.MISSING; + status = 0; ground_altitude = AltosRecord.MISSING; + ground_pressure = AltosRecord.MISSING; altitude = AltosRecord.MISSING; height = AltosRecord.MISSING; pressure = AltosRecord.MISSING; @@ -138,21 +162,20 @@ public class AltosState implements Cloneable { apogee_voltage = AltosRecord.MISSING; main_voltage = AltosRecord.MISSING; - - accel_speed = AltosRecord.MISSING; - baro_speed = AltosRecord.MISSING; + speed = AltosRecord.MISSING; kalman_height = AltosRecord.MISSING; kalman_speed = AltosRecord.MISSING; kalman_acceleration = AltosRecord.MISSING; - max_baro_speed = 0; - max_accel_speed = 0; + max_speed = 0; max_height = 0; max_acceleration = 0; gps = null; + temp_gps = null; gps_sequence = 0; + gps_pending = false; imu = null; mag = null; @@ -165,7 +188,7 @@ public class AltosState implements Cloneable { range = AltosRecord.MISSING; gps_height = AltosRecord.MISSING; - pat_lat = AltosRecord.MISSING; + pad_lat = AltosRecord.MISSING; pad_lon = AltosRecord.MISSING; pad_alt = AltosRecord.MISSING; @@ -176,15 +199,18 @@ public class AltosState implements Cloneable { accel_plus_g = AltosRecord.MISSING; accel_minus_g = AltosRecord.MISSING; + accel = AltosRecord.MISSING; + ground_accel = AltosRecord.MISSING; log_format = AltosRecord.MISSING; serial = AltosRecord.MISSING; baro = null; + companion = null; } void copy(AltosState old) { - data = null; + record = null; if (old == null) { init(); @@ -193,13 +219,19 @@ public class AltosState implements Cloneable { report_time = old.report_time; time = old.time; - time_change = old.time_change; + time_change = 0; tick = old.tick; + boost_tick = old.boost_tick; state = old.state; + flight = old.flight; landed = old.landed; ascent = old.ascent; boost = old.boost; + rssi = old.rssi; + status = old.status; + + set = 0; ground_altitude = old.ground_altitude; altitude = old.altitude; @@ -211,17 +243,16 @@ public class AltosState implements Cloneable { temperature = old.temperature; apogee_voltage = old.apogee_voltage; main_voltage = old.main_voltage; - accel_speed = old.accel_speed; - baro_speed = old.baro_speed; + speed = old.speed; prev_height = old.height; prev_speed = old.speed; prev_acceleration = old.acceleration; + prev_time = old.time; max_height = old.max_height; max_acceleration = old.max_acceleration; - max_accel_speed = old.max_accel_speed; - max_baro_speed = old.max_baro_speed; + max_speed = old.max_speed; kalman_height = old.kalman_height; kalman_speed = old.kalman_speed; @@ -231,7 +262,12 @@ public class AltosState implements Cloneable { gps = old.gps.clone(); else gps = null; + if (old.temp_gps != null) + temp_gps = old.temp_gps.clone(); + else + temp_gps = null; gps_sequence = old.gps_sequence; + gps_pending = old.gps_pending; if (old.imu != null) imu = old.imu.clone(); @@ -268,14 +304,14 @@ public class AltosState implements Cloneable { accel_plus_g = old.accel_plus_g; accel_minus_g = old.accel_minus_g; + accel = old.accel; + ground_accel = old.ground_accel; + log_format = old.log_format; serial = old.serial; baro = old.baro; - } - - double ground_altitude() { - + companion = old.companion; } double altitude() { @@ -289,8 +325,12 @@ public class AltosState implements Cloneable { void update_vertical_pos() { double alt = altitude(); - if (state == AltosLib.ao_flight_pad) { - + + if (state == AltosLib.ao_flight_pad && alt != AltosRecord.MISSING && ground_pressure == AltosRecord.MISSING) { + if (ground_altitude == AltosRecord.MISSING) + ground_altitude = alt; + else + ground_altitude = (ground_altitude * 7 + alt) / 8; } if (kalman_height != AltosRecord.MISSING) @@ -300,6 +340,9 @@ public class AltosState implements Cloneable { else height = AltosRecord.MISSING; + if (height != AltosRecord.MISSING && height > max_height) + max_height = height; + update_speed(); } @@ -348,12 +391,14 @@ public class AltosState implements Cloneable { } } } + if (boost && speed != AltosRecord.MISSING && speed > max_speed) + max_speed = speed; } void update_accel() { if (accel == AltosRecord.MISSING) return; - if (ground_Accel == AltosRecord.MISSING) + if (ground_accel == AltosRecord.MISSING) return; if (accel_plus_g == AltosRecord.MISSING) return; @@ -364,9 +409,60 @@ public class AltosState implements Cloneable { double counts_per_mss = counts_per_g / 9.80665; acceleration = (ground_accel - accel) / counts_per_mss; + + /* Only look at accelerometer data under boost */ + if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration)) + max_acceleration = acceleration; update_speed(); } + void update_time() { + if (tick != AltosRecord.MISSING) { + time = tick / 100.0; + if (prev_time != AltosRecord.MISSING) + time_change = time - prev_time; + } + } + + void update_gps() { + elevation = 0; + range = -1; + gps_height = 0; + + if (gps == null) + return; + + if (gps.locked && gps.nsat >= 4) { + /* Track consecutive 'good' gps reports, waiting for 10 of them */ + if (state == AltosLib.ao_flight_pad) { + set_npad(npad+1); + if (pad_lat != AltosRecord.MISSING) { + pad_lat = (pad_lat * 31 + gps.lat) / 32; + pad_lon = (pad_lon * 31 + gps.lon) / 32; + pad_alt = (pad_alt * 31 + gps.alt) / 32; + } + } + if (pad_lat == AltosRecord.MISSING) { + pad_lat = gps.lat; + pad_lon = gps.lon; + pad_alt = gps.alt; + } + } + if (gps.lat != 0 && gps.lon != 0 && + pad_lat != AltosRecord.MISSING && + pad_lon != AltosRecord.MISSING) + { + double h = height; + + if (h == AltosRecord.MISSING) + h = 0; + from_pad = new AltosGreatCircle(pad_lat, pad_lon, 0, gps.lat, gps.lon, h); + elevation = from_pad.elevation; + range = from_pad.range; + gps_height = gps.alt - pad_alt; + } + } + public void set_tick(int tick) { if (tick != AltosRecord.MISSING) { if (this.tick != AltosRecord.MISSING) { @@ -380,6 +476,15 @@ public class AltosState implements Cloneable { } } + public void set_boost_tick(int boost_tick) { + if (boost_tick != AltosRecord.MISSING) + this.boost_tick = boost_tick; + } + + public String state_name() { + return AltosLib.state_name(state); + } + public void set_state(int state) { if (state != AltosLib.ao_flight_invalid) { this.state = state; @@ -390,10 +495,47 @@ public class AltosState implements Cloneable { } + public void set_flight(int flight) { + + /* When the flight changes, reset the state */ + if (flight != AltosRecord.MISSING) { + if (this.flight != AltosRecord.MISSING && + this.flight != flight) { + init(); + } + this.flight = flight; + } + } + + public void set_serial(int serial) { + /* When the serial changes, reset the state */ + if (serial != AltosRecord.MISSING) { + if (this.serial != AltosRecord.MISSING && + this.serial != serial) { + init(); + } + this.serial = serial; + } + } + + public int rssi() { + if (rssi == AltosRecord.MISSING) + return 0; + return rssi; + } + + public void set_rssi(int rssi, int status) { + if (rssi != AltosRecord.MISSING) { + this.rssi = rssi; + this.status = status; + } + } + public void set_altitude(double altitude) { if (altitude != AltosRecord.MISSING) { this.altitude = altitude; update_vertical_pos(); + set |= set_position; } } @@ -404,11 +546,24 @@ public class AltosState implements Cloneable { } } + public void set_ground_pressure (double pressure) { + if (pressure != AltosRecord.MISSING) { + this.ground_pressure = pressure; + set_ground_altitude(AltosConvert.pressure_to_altitude(pressure)); + update_vertical_pos(); + } + } + public void set_gps(AltosGPS gps, int sequence) { if (gps != null) { + System.out.printf ("gps date: %d-%d-%d time %d:%d:%d\n", + gps.year, gps.month, gps.day, + gps.hour, gps.minute, gps.second); this.gps = gps.clone(); gps_sequence = sequence; + update_gps(); update_vertical_pos(); + set |= set_gps; } } @@ -417,7 +572,6 @@ public class AltosState implements Cloneable { kalman_height = height; kalman_speed = speed; kalman_acceleration = acceleration; - baro_speed = accel_speed = speed; update_vertical_pos(); } } @@ -429,6 +583,29 @@ public class AltosState implements Cloneable { } } + public void make_baro() { + if (baro == null) + baro = new AltosMs5607(); + } + + public void set_ms5607(int pres, int temp) { + if (baro != null) { + baro.set(pres, temp); + + set_pressure(baro.pa); + set_temperature(baro.cc / 100.0); + } + } + + public void make_companion (int nchannels) { + if (companion == null) + companion = new AltosRecordCompanion(nchannels); + } + + public void set_companion(AltosRecordCompanion companion) { + this.companion = companion; + } + public void set_accel_g(double accel_plus_g, double accel_minus_g) { if (accel_plus_g != AltosRecord.MISSING) { this.accel_plus_g = accel_plus_g; @@ -451,36 +628,77 @@ public class AltosState implements Cloneable { } public void set_temperature(double temperature) { - if (temperature != AltosRecord.MISSING) + if (temperature != AltosRecord.MISSING) { this.temperature = temperature; + set |= set_data; + } } public void set_battery_voltage(double battery_voltage) { - if (battery_voltage != AltosRecord.MISSING) + if (battery_voltage != AltosRecord.MISSING) { this.battery_voltage = battery_voltage; + set |= set_data; + } } public void set_pyro_voltage(double pyro_voltage) { - if (pyro_voltage != AltosRecord.MISSING) + if (pyro_voltage != AltosRecord.MISSING) { this.pyro_voltage = pyro_voltage; + set |= set_data; + } } public void set_apogee_voltage(double apogee_voltage) { - if (apogee_voltage != AltosRecord.MISSING) + if (apogee_voltage != AltosRecord.MISSING) { this.apogee_voltage = apogee_voltage; + set |= set_data; + } } public void set_main_voltage(double main_voltage) { - if (main_voltage != AltosRecord.MISSING) + if (main_voltage != AltosRecord.MISSING) { this.main_voltage = main_voltage; + set |= set_data; + } + } + + + public double time_since_boost() { + if (tick == AltosRecord.MISSING) + return 0.0; + + if (boost_tick != AltosRecord.MISSING) { + return (tick - boost_tick) / 100.0; + } + return tick / 100.0; + } + + public boolean valid() { + return tick != AltosRecord.MISSING && serial != AltosRecord.MISSING; + } + + public AltosGPS make_temp_gps() { + if (temp_gps == null) { + temp_gps = new AltosGPS(gps); + temp_gps.cc_gps_sat = null; + } + gps_pending = true; + return temp_gps; + } + + public void set_temp_gps() { + set_gps(temp_gps, gps_sequence + 1); + gps_pending = false; + temp_gps = null; } public void init (AltosRecord cur, AltosState prev_state) { + System.out.printf ("init\n"); if (cur == null) cur = new AltosRecord(); - data = cur; + record = cur; /* Discard previous state if it was for a different board */ if (prev_state != null && prev_state.serial != cur.serial) @@ -488,146 +706,35 @@ public class AltosState implements Cloneable { copy(prev_state); - set_ground_altitude(data.ground_altitude()); - set_altitude(data.altitude()); + set_ground_altitude(cur.ground_altitude()); + set_altitude(cur.altitude()); - set_kalman(data.kalman_height, data.kalman_speed, data.kalman_acceleration); + set_kalman(cur.kalman_height, cur.kalman_speed, cur.kalman_acceleration); report_time = System.currentTimeMillis(); - set_temperature(data.temperature()); - set_apogee_voltage(data.drogue_voltage()); - set_main_voltage(data.main_voltage()); - set_battery_voltage(data.battery_voltage()); - - set_pressure(data.pressure()); - - set_tick(data.tick); - set_state(data.state); + set_temperature(cur.temperature()); + set_apogee_voltage(cur.drogue_voltage()); + set_main_voltage(cur.main_voltage()); + set_battery_voltage(cur.battery_voltage()); - set_accel_g (data.accel_minus_g, data.accel_plus_g); - set_ground_accel(data.ground_accel); - set_accel (data.accel); + set_pressure(cur.pressure()); - set_gps(data.gps, data.gps_sequence); + set_tick(cur.tick); + set_state(cur.state); - if (prev_state != null) { + set_accel_g (cur.accel_minus_g, cur.accel_plus_g); + set_ground_accel(cur.ground_accel); + set_accel (cur.accel); - if (data.kalman_speed != AltosRecord.MISSING) { - baro_speed = accel_speed = data.kalman_speed; - } else { - /* compute barometric speed */ - - double height_change = height - prev_state.height; - - double prev_baro_speed = prev_state.baro_speed; - if (prev_baro_speed == AltosRecord.MISSING) - prev_baro_speed = 0; - - if (time_change > 0) - baro_speed = (prev_baro_speed * 3 + (height_change / time_change)) / 4.0; - else - baro_speed = prev_state.baro_speed; + if (cur.gps_sequence != gps_sequence) + set_gps(cur.gps, cur.gps_sequence); - double prev_accel_speed = prev_state.accel_speed; - - if (prev_accel_speed == AltosRecord.MISSING) - prev_accel_speed = 0; - - if (acceleration == AltosRecord.MISSING) { - /* Fill in mising acceleration value */ - accel_speed = baro_speed; - - if (time_change > 0 && accel_speed != AltosRecord.MISSING) - acceleration = (accel_speed - prev_accel_speed) / time_change; - else - acceleration = prev_state.acceleration; - } else { - /* compute accelerometer speed */ - accel_speed = prev_accel_speed + acceleration * time_change; - } - } - } else { - npad = 0; - ngps = 0; - gps = null; - gps_sequence = 0; - baro_speed = AltosRecord.MISSING; - accel_speed = AltosRecord.MISSING; - pad_alt = AltosRecord.MISSING; - max_baro_speed = 0; - max_accel_speed = 0; - max_height = 0; - max_acceleration = 0; - time_change = 0; - baro = new AltosMs5607(); - callsign = ""; - accel_plus_g = AltosRecord.MISSING; - accel_minus_g = AltosRecord.MISSING; - log_format = AltosRecord.MISSING; - serial = AltosRecord.MISSING; - } - - time = tick / 100.0; - - if (data.gps != null && data.gps_sequence != gps_sequence && (state < AltosLib.ao_flight_boost)) { - - /* Track consecutive 'good' gps reports, waiting for 10 of them */ - if (data.gps != null && data.gps.locked && data.gps.nsat >= 4) - set_npad(npad+1); - else - set_npad(0); - - /* Average GPS data while on the pad */ - if (data.gps != null && data.gps.locked && data.gps.nsat >= 4) { - if (ngps > 1 && state == AltosLib.ao_flight_pad) { - /* filter pad position */ - pad_lat = (pad_lat * 31.0 + data.gps.lat) / 32.0; - pad_lon = (pad_lon * 31.0 + data.gps.lon) / 32.0; - pad_alt = (pad_alt * 31.0 + data.gps.alt) / 32.0; - } else { - pad_lat = data.gps.lat; - pad_lon = data.gps.lon; - pad_alt = data.gps.alt; - } - ngps++; - } - } else { - if (ngps == 0 && ground_altitude != AltosRecord.MISSING) - pad_alt = ground_altitude; - } - - gps_sequence = data.gps_sequence; - - /* Only look at accelerometer data under boost */ - if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration)) - max_acceleration = acceleration; - if (boost && accel_speed != AltosRecord.MISSING && accel_speed > max_accel_speed) - max_accel_speed = accel_speed; - if (boost && baro_speed != AltosRecord.MISSING && baro_speed > max_baro_speed) - max_baro_speed = baro_speed; - - if (height != AltosRecord.MISSING && height > max_height) - max_height = height; - elevation = 0; - range = -1; - gps_height = 0; - if (data.gps != null) { - gps = data.gps; - if (ngps > 0 && gps.locked) { - double h = height; - - if (h == AltosRecord.MISSING) h = 0; - from_pad = new AltosGreatCircle(pad_lat, pad_lon, 0, gps.lat, gps.lon, h); - elevation = from_pad.elevation; - range = from_pad.range; - gps_height = gps.alt - pad_alt; - } - } } public AltosState clone() { - AltosState s = new AltosState(data, this); + AltosState s = new AltosState(); + s.copy(this); return s; } @@ -638,4 +745,8 @@ public class AltosState implements Cloneable { public AltosState (AltosRecord cur, AltosState prev) { init(cur, prev); } + + public AltosState () { + init(); + } } diff --git a/altoslib/AltosStateIterable.java b/altoslib/AltosStateIterable.java new file mode 100644 index 00000000..db4a2568 --- /dev/null +++ b/altoslib/AltosStateIterable.java @@ -0,0 +1,29 @@ +/* + * Copyright © 2013 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_1; + +import java.io.*; +import java.util.*; + +public abstract class AltosStateIterable implements Iterable { + + public void write_comments (PrintStream out) { + } + + public abstract void write(PrintStream out); +} diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index b4293c73..3915927c 100644 --- a/altoslib/AltosTelemetryReader.java +++ b/altoslib/AltosTelemetryReader.java @@ -27,16 +27,18 @@ public class AltosTelemetryReader extends AltosFlightReader { AltosRecord previous; double frequency; int telemetry; + AltosState state = null; LinkedBlockingQueue telem; - public AltosRecord read() throws InterruptedException, ParseException, AltosCRCException, IOException { + public AltosState read() throws InterruptedException, ParseException, AltosCRCException, IOException { AltosLine l = telem.take(); if (l.line == null) throw new IOException("IO error"); AltosRecord next = AltosTelemetry.parse(l.line, previous); previous = next; - return next; + state = new AltosState (next, state); + return state; } public void flush() { diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 8a41b90c..bbcca906 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -20,6 +20,7 @@ altoslib_JAVA = \ AltosEeprom.java \ AltosEepromChunk.java \ AltosEepromFile.java \ + AltosEepromTM.java \ AltosEepromHeader.java \ AltosEepromIterable.java \ AltosEepromLog.java \ @@ -28,7 +29,6 @@ altoslib_JAVA = \ AltosEepromRecord.java \ AltosEepromTeleScience.java \ AltosEepromMini.java \ - AltosEepromMiniIterable.java \ AltosEepromOldIterable.java \ AltosFile.java \ AltosFlash.java \ @@ -69,6 +69,7 @@ altoslib_JAVA = \ AltosSensorMM.java \ AltosSensorTM.java \ AltosState.java \ + AltosStateIterable.java \ AltosStateUpdate.java \ AltosTelemetry.java \ AltosTelemetryIterable.java \ diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index 4da4d591..f8435037 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -251,10 +251,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Speed extends AscentValueHold { void show (AltosState state, AltosListenerState listener_state) { - double speed = state.accel_speed; - if (!state.ascent) - speed = state.baro_speed; - show(AltosConvert.speed, speed); + show(AltosConvert.speed, state.speed); } public Speed (GridBagLayout layout, int y) { super (layout, y, "Speed"); @@ -287,8 +284,8 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Apogee extends AscentStatus { void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.drogue_sense); - lights.set(state.drogue_sense > 3.2); + show("%4.2f V", state.apogee_voltage); + lights.set(state.apogee_voltage > 3.7); } public Apogee (GridBagLayout layout, int y) { super(layout, y, "Apogee Igniter Voltage"); @@ -299,8 +296,8 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Main extends AscentStatus { void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.main_sense); - lights.set(state.main_sense > 3.2); + show("%4.2f V", state.main_voltage); + lights.set(state.main_voltage > 3.7); } public Main (GridBagLayout layout, int y) { super(layout, y, "Main Igniter Voltage"); @@ -368,11 +365,11 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { lon.hide(); } height.show(state, listener_state); - if (state.main_sense != AltosRecord.MISSING) + if (state.main_voltage != AltosRecord.MISSING) main.show(state, listener_state); else main.hide(); - if (state.drogue_sense != AltosRecord.MISSING) + if (state.apogee_voltage != AltosRecord.MISSING) apogee.show(state, listener_state); else apogee.hide(); diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java index 0676f99d..0b5a74e9 100644 --- a/altosui/AltosCSV.java +++ b/altosui/AltosCSV.java @@ -27,7 +27,7 @@ public class AltosCSV implements AltosWriter { boolean header_written; boolean seen_boost; int boost_tick; - LinkedList pad_records; + LinkedList pad_states; AltosState state; static final int ALTOS_CSV_VERSION = 5; @@ -105,47 +105,47 @@ public class AltosCSV implements AltosWriter { out.printf("version,serial,flight,call,time,clock,rssi,lqi"); } - void write_general(AltosRecord record) { + void write_general(AltosState state) { out.printf("%s, %d, %d, %s, %8.2f, %8.2f, %4d, %3d", - ALTOS_CSV_VERSION, record.serial, record.flight, record.callsign, - (double) record.time, (double) record.tick / 100.0, - record.rssi, - record.status & 0x7f); + ALTOS_CSV_VERSION, state.serial, state.flight, state.callsign, + (double) state.time, (double) state.tick / 100.0, + state.rssi, + state.status & 0x7f); } void write_flight_header() { out.printf("state,state_name"); } - void write_flight(AltosRecord record) { - out.printf("%d,%8s", record.state, record.state()); + void write_flight(AltosState state) { + out.printf("%d,%8s", state.state, state.state_name()); } void write_basic_header() { out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,battery_voltage,drogue_voltage,main_voltage"); } - void write_basic(AltosRecord record) { + void write_basic(AltosState state) { out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f,%5.2f", - record.acceleration(), - record.pressure(), - record.altitude(), - record.height(), - state.accel_speed, - state.baro_speed, - record.temperature(), - record.battery_voltage(), - record.drogue_voltage(), - record.main_voltage()); + state.acceleration, + state.pressure, + state.altitude, + state.height, + state.speed, + state.speed, + state.temperature, + state.battery_voltage, + state.apogee_voltage, + state.main_voltage); } void write_advanced_header() { out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z"); } - void write_advanced(AltosRecord record) { - AltosIMU imu = record.imu(); - AltosMag mag = record.mag(); + void write_advanced(AltosState state) { + AltosIMU imu = state.imu; + AltosMag mag = state.mag; if (imu == null) imu = new AltosIMU(); @@ -161,8 +161,8 @@ public class AltosCSV implements AltosWriter { out.printf("connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,hdop"); } - void write_gps(AltosRecord record) { - AltosGPS gps = record.gps; + void write_gps(AltosState state) { + AltosGPS gps = state.gps; if (gps == null) gps = new AltosGPS(); @@ -198,8 +198,8 @@ public class AltosCSV implements AltosWriter { } } - void write_gps_sat(AltosRecord record) { - AltosGPS gps = record.gps; + void write_gps_sat(AltosState state) { + AltosGPS gps = state.gps; for(int i = 1; i <= 32; i++) { int c_n0 = 0; if (gps != null && gps.cc_gps_sat != null) { @@ -221,8 +221,8 @@ public class AltosCSV implements AltosWriter { out.printf(",companion_%02d", i); } - void write_companion(AltosRecord record) { - AltosRecordCompanion companion = record.companion; + void write_companion(AltosState state) { + AltosRecordCompanion companion = state.companion; int channels_written = 0; if (companion == null) { @@ -256,50 +256,49 @@ public class AltosCSV implements AltosWriter { out.printf ("\n"); } - void write_one(AltosRecord record) { - state = new AltosState(record, state); - write_general(record); out.printf(","); - write_flight(record); out.printf(","); - write_basic(record); out.printf(","); - if (record.imu() != null || record.mag() != null) - write_advanced(record); - if (record.gps != null) { + void write_one(AltosState state) { + write_general(state); out.printf(","); + write_flight(state); out.printf(","); + write_basic(state); out.printf(","); + if (state.imu != null || state.mag != null) + write_advanced(state); + if (state.gps != null) { out.printf(","); - write_gps(record); out.printf(","); - write_gps_sat(record); + write_gps(state); out.printf(","); + write_gps_sat(state); } - if (record.companion != null) { + if (state.companion != null) { out.printf(","); - write_companion(record); + write_companion(state); } out.printf ("\n"); } void flush_pad() { - while (!pad_records.isEmpty()) { - write_one (pad_records.remove()); + while (!pad_states.isEmpty()) { + write_one (pad_states.remove()); } } - public void write(AltosRecord record) { - if (record.state == Altos.ao_flight_startup) + public void write(AltosState state) { + if (state.state == Altos.ao_flight_startup) return; if (!header_written) { - write_header(record.imu() != null || record.mag() != null, - record.gps != null, record.companion != null); + write_header(state.imu != null || state.mag != null, + state.gps != null, state.companion != null); header_written = true; } if (!seen_boost) { - if (record.state >= Altos.ao_flight_boost) { + if (state.state >= Altos.ao_flight_boost) { seen_boost = true; - boost_tick = record.tick; + boost_tick = state.tick; flush_pad(); } } if (seen_boost) - write_one(record); + write_one(state); else - pad_records.add(record); + pad_states.add(state); } public PrintStream out() { @@ -307,23 +306,23 @@ public class AltosCSV implements AltosWriter { } public void close() { - if (!pad_records.isEmpty()) { - boost_tick = pad_records.element().tick; + if (!pad_states.isEmpty()) { + boost_tick = pad_states.element().tick; flush_pad(); } out.close(); } - public void write(AltosRecordIterable iterable) { - iterable.write_comments(out()); - for (AltosRecord r : iterable) - write(r); + public void write(AltosStateIterable states) { + states.write_comments(out()); + for (AltosState state : states) + write(state); } public AltosCSV(PrintStream in_out, File in_name) { name = in_name; out = in_out; - pad_records = new LinkedList(); + pad_states = new LinkedList(); } public AltosCSV(File in_name) throws FileNotFoundException { diff --git a/altosui/AltosCSVUI.java b/altosui/AltosCSVUI.java index 42508346..4b48bdf6 100644 --- a/altosui/AltosCSVUI.java +++ b/altosui/AltosCSVUI.java @@ -31,7 +31,7 @@ public class AltosCSVUI JFileChooser csv_chooser; JPanel accessory; JComboBox combo_box; - AltosRecordIterable iterable; + Iterable states; AltosWriter writer; static String[] combo_box_items = { "Comma Separated Values (.CSV)", "Googleearth Data (.KML)" }; @@ -55,8 +55,8 @@ public class AltosCSVUI set_default_file(); } - public AltosCSVUI(JFrame frame, AltosRecordIterable in_iterable, File source_file) { - iterable = in_iterable; + public AltosCSVUI(JFrame frame, AltosStateIterable states, File source_file) { + this.states = states; csv_chooser = new JFileChooser(source_file); accessory = new JPanel(); @@ -91,7 +91,7 @@ public class AltosCSVUI writer = new AltosCSV(file); else writer = new AltosKML(file); - writer.write(iterable); + writer.write(states); writer.close(); } catch (FileNotFoundException ee) { JOptionPane.showMessageDialog(frame, diff --git a/altosui/AltosCompanionInfo.java b/altosui/AltosCompanionInfo.java index ebe1d1f9..1ed2c425 100644 --- a/altosui/AltosCompanionInfo.java +++ b/altosui/AltosCompanionInfo.java @@ -86,8 +86,8 @@ public class AltosCompanionInfo extends JTable { public void show(AltosState state, AltosListenerState listener_state) { if (state == null) return; - if (state.data.companion != null) - companion = state.data.companion; + if (state.companion != null) + companion = state.companion; info_reset(); info_add_row(0, "Companion board", "%s", board_name()); if (companion != null) { diff --git a/altosui/AltosDataChooser.java b/altosui/AltosDataChooser.java index c7b561d5..af6c245b 100644 --- a/altosui/AltosDataChooser.java +++ b/altosui/AltosDataChooser.java @@ -36,7 +36,7 @@ public class AltosDataChooser extends JFileChooser { return file; } - public AltosRecordIterable runDialog() { + public AltosStateIterable runDialog() { int ret; ret = showOpenDialog(frame); @@ -48,16 +48,10 @@ public class AltosDataChooser extends JFileChooser { try { if (filename.endsWith("eeprom")) { FileInputStream in = new FileInputStream(file); - return new AltosEepromIterable(in); + return new AltosEepromFile(in); } else if (filename.endsWith("telem")) { FileInputStream in = new FileInputStream(file); - return new AltosTelemetryIterable(in); - } else if (filename.endsWith("mega")) { - FileInputStream in = new FileInputStream(file); - return new AltosEepromMegaIterable(in); - } else if (filename.endsWith("mini")) { - FileInputStream in = new FileInputStream(file); - return new AltosEepromMiniIterable(in); + return null; // new AltosTelemetryIterable(in); } else { throw new FileNotFoundException(); } diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index 29d33ddc..2b6575cb 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -256,10 +256,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Speed extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - double speed = state.accel_speed; - if (!state.ascent) - speed = state.baro_speed; - show(AltosConvert.speed, speed); + show(AltosConvert.speed, state.speed); } public Speed (GridBagLayout layout, int x, int y) { super (layout, x, y, "Speed"); @@ -325,8 +322,8 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Apogee extends DescentStatus { void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.drogue_sense); - lights.set(state.drogue_sense > 3.2); + show("%4.2f V", state.apogee_voltage); + lights.set(state.apogee_voltage > 3.7); } public Apogee (GridBagLayout layout, int y) { super(layout, y, "Apogee Igniter Voltage"); @@ -337,8 +334,8 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Main extends DescentStatus { void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.main_sense); - lights.set(state.main_sense > 3.2); + show("%4.2f V", state.main_voltage); + lights.set(state.main_voltage > 3.7); } public Main (GridBagLayout layout, int y) { super(layout, y, "Main Igniter Voltage"); @@ -430,11 +427,11 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { lat.hide(); lon.hide(); } - if (state.main_sense != AltosRecord.MISSING) + if (state.main_voltage != AltosRecord.MISSING) main.show(state, listener_state); else main.hide(); - if (state.drogue_sense != AltosRecord.MISSING) + if (state.apogee_voltage != AltosRecord.MISSING) apogee.show(state, listener_state); else apogee.hide(); diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index 095bed99..70144fb2 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -113,7 +113,7 @@ public class AltosDisplayThread extends Thread { System.currentTimeMillis() - state.report_time >= 15000 || state.state == Altos.ao_flight_landed)) { - if (Math.abs(state.baro_speed) < 20 && state.height < 100) + if (Math.abs(state.speed) < 20 && state.height < 100) voice.speak("rocket landed safely"); else voice.speak("rocket may have crashed"); @@ -181,11 +181,11 @@ public class AltosDisplayThread extends Thread { synchronized boolean tell() { boolean ret = false; if (old_state == null || old_state.state != state.state) { - voice.speak(state.data.state()); + voice.speak(state.state_name()); if ((old_state == null || old_state.state <= Altos.ao_flight_boost) && state.state > Altos.ao_flight_boost) { voice.speak("max speed: %s.", - AltosConvert.speed.say_units(state.max_accel_speed + 0.5)); + AltosConvert.speed.say_units(state.max_speed + 0.5)); ret = true; } else if ((old_state == null || old_state.state < Altos.ao_flight_drogue) && state.state >= Altos.ao_flight_drogue) { @@ -218,11 +218,9 @@ public class AltosDisplayThread extends Thread { try { for (;;) { try { - AltosRecord record = reader.read(); - if (record == null) + state = reader.read(); + if (state == null) break; - old_state = state; - state = new AltosState(record, state); reader.update(state); show_safely(); told = tell(); diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 46715db6..95b17e2a 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -418,8 +418,9 @@ public class AltosEepromDownload implements Runnable { extension = "mega"; CaptureMega(eechunk); break; - case AltosLib.AO_LOG_FORMAT_MINI: - extension = "mini"; + case AltosLib.AO_LOG_FORMAT_EASYMINI: + case AltosLib.AO_LOG_FORMAT_TELEMINI: + extension = "eeprom"; CaptureMini(eechunk); break; } diff --git a/altosui/AltosFlightStats.java b/altosui/AltosFlightStats.java index dee31a8d..50deb6c8 100644 --- a/altosui/AltosFlightStats.java +++ b/altosui/AltosFlightStats.java @@ -24,8 +24,7 @@ public class AltosFlightStats { double max_height; double max_speed; double max_acceleration; - double[] state_accel_speed = new double[Altos.ao_flight_invalid + 1]; - double[] state_baro_speed = new double[Altos.ao_flight_invalid + 1]; + double[] state_speed = new double[Altos.ao_flight_invalid + 1]; double[] state_accel = new double[Altos.ao_flight_invalid + 1]; int[] state_count = new int[Altos.ao_flight_invalid + 1]; double[] state_start = new double[Altos.ao_flight_invalid + 1]; @@ -40,15 +39,18 @@ public class AltosFlightStats { boolean has_other_adc; boolean has_rssi; - double landed_time(AltosRecordIterable iterable) { - AltosState state = null; - for (AltosRecord record : iterable) { - state = new AltosState(record, state); + double landed_time(AltosStateIterable states) { + AltosState state = null; + for (AltosState s : states) { + state = s; if (state.state == Altos.ao_flight_landed) break; } + if (state == null) + return 0; + double landed_height = state.height; state = null; @@ -57,8 +59,8 @@ public class AltosFlightStats { double landed_time = -1000; - for (AltosRecord record : iterable) { - state = new AltosState(record, state); + for (AltosState s : states) { + state = s; if (state.height > landed_height + 10) { above = true; @@ -74,80 +76,70 @@ public class AltosFlightStats { return landed_time; } - double boost_time(AltosRecordIterable iterable) { - double boost_time = -1000; - - AltosState state = null; + double boost_time(AltosStateIterable states) { + double boost_time = AltosRecord.MISSING; + AltosState state = null; - for (AltosRecord record : iterable) { - state = new AltosState(record, state); - + for (AltosState s : states) { + state = s; if (state.acceleration < 1) boost_time = state.time; if (state.state >= Altos.ao_flight_boost) break; } - if (boost_time == -1000) + if (state == null) + return 0; + + if (boost_time == AltosRecord.MISSING) boost_time = state.time; return boost_time; } - public AltosFlightStats(AltosRecordIterable iterable) throws InterruptedException, IOException { - AltosState state = null; - AltosState new_state = null; - double boost_time = boost_time(iterable); + public AltosFlightStats(AltosStateIterable states) throws InterruptedException, IOException { + double boost_time = boost_time(states); double end_time = 0; - double landed_time = landed_time(iterable); + double landed_time = landed_time(states); - year = month = day = -1; - hour = minute = second = -1; - serial = flight = -1; - lat = lon = -1; + year = month = day = AltosRecord.MISSING; + hour = minute = second = AltosRecord.MISSING; + serial = flight = AltosRecord.MISSING; + lat = lon = AltosRecord.MISSING; has_gps = false; has_other_adc = false; has_rssi = false; - for (AltosRecord record : iterable) { - if (serial < 0) - serial = record.serial; - if ((record.seen & AltosRecord.seen_flight) != 0 && flight < 0) - flight = record.flight; - if ((record.seen & AltosRecord.seen_temp_volt) != 0) + for (AltosState state : states) { + if (serial == AltosRecord.MISSING && state.serial != AltosRecord.MISSING) + serial = state.serial; + if (flight == AltosRecord.MISSING && state.flight != AltosRecord.MISSING) + flight = state.flight; + if (state.battery_voltage != AltosRecord.MISSING) has_other_adc = true; - if (record.rssi != 0) + if (state.rssi != AltosRecord.MISSING) has_rssi = true; - new_state = new AltosState(record, state); - end_time = new_state.time; - state = new_state; + end_time = state.time; if (state.time >= boost_time && state.state < Altos.ao_flight_boost) state.state = Altos.ao_flight_boost; if (state.time >= landed_time && state.state < Altos.ao_flight_landed) state.state = Altos.ao_flight_landed; + if (state.gps != null && state.gps.locked) { + year = state.gps.year; + month = state.gps.month; + day = state.gps.day; + hour = state.gps.hour; + minute = state.gps.minute; + second = state.gps.second; + } if (0 <= state.state && state.state < Altos.ao_flight_invalid) { - if (state.state >= Altos.ao_flight_boost) { - if (state.gps != null && state.gps.locked && - year < 0) { - year = state.gps.year; - month = state.gps.month; - day = state.gps.day; - hour = state.gps.hour; - minute = state.gps.minute; - second = state.gps.second; - } - } state_accel[state.state] += state.acceleration; - state_accel_speed[state.state] += state.accel_speed; - state_baro_speed[state.state] += state.baro_speed; + state_speed[state.state] += state.speed; state_count[state.state]++; if (state_start[state.state] == 0.0) state_start[state.state] = state.time; if (state_end[state.state] < state.time) state_end[state.state] = state.time; max_height = state.max_height; - if (state.max_accel_speed != 0) - max_speed = state.max_accel_speed; - else - max_speed = state.max_baro_speed; + max_speed = state.max_speed; max_acceleration = state.max_acceleration; } if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { @@ -162,8 +154,7 @@ public class AltosFlightStats { } for (int s = Altos.ao_flight_startup; s <= Altos.ao_flight_landed; s++) { if (state_count[s] > 0) { - state_accel_speed[s] /= state_count[s]; - state_baro_speed[s] /= state_count[s]; + state_speed[s] /= state_count[s]; state_accel[s] /= state_count[s]; } if (state_start[s] == 0) diff --git a/altosui/AltosFlightStatsTable.java b/altosui/AltosFlightStatsTable.java index a35b5f63..f8a2d4de 100644 --- a/altosui/AltosFlightStatsTable.java +++ b/altosui/AltosFlightStatsTable.java @@ -106,11 +106,11 @@ public class AltosFlightStatsTable extends JComponent { String.format("%5.0f G", AltosConvert.meters_to_g(stats.state_accel[Altos.ao_flight_boost]))); } new FlightStat(layout, y++, "Drogue descent rate", - String.format("%5.0f m/s", stats.state_baro_speed[Altos.ao_flight_drogue]), - String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_baro_speed[Altos.ao_flight_drogue]))); + String.format("%5.0f m/s", stats.state_speed[Altos.ao_flight_drogue]), + String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue]))); new FlightStat(layout, y++, "Main descent rate", - String.format("%5.0f m/s", stats.state_baro_speed[Altos.ao_flight_main]), - String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_baro_speed[Altos.ao_flight_main]))); + String.format("%5.0f m/s", stats.state_speed[Altos.ao_flight_main]), + String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main]))); new FlightStat(layout, y++, "Ascent time", String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_boost] - stats.state_start[AltosLib.ao_flight_boost], AltosLib.state_name(Altos.ao_flight_boost)), diff --git a/altosui/AltosFlightStatus.java b/altosui/AltosFlightStatus.java index d2910414..0be7bb51 100644 --- a/altosui/AltosFlightStatus.java +++ b/altosui/AltosFlightStatus.java @@ -65,7 +65,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class Call extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - value.setText(state.data.callsign); + value.setText(state.callsign); } public Call (GridBagLayout layout, int x) { super (layout, x, "Callsign"); @@ -76,10 +76,10 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class Serial extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - if (state.data.serial == AltosRecord.MISSING) + if (state.serial == AltosRecord.MISSING) value.setText("none"); else - value.setText(String.format("%d", state.data.serial)); + value.setText(String.format("%d", state.serial)); } public Serial (GridBagLayout layout, int x) { super (layout, x, "Serial"); @@ -90,10 +90,10 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class Flight extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - if (state.data.flight == AltosRecord.MISSING) + if (state.flight == AltosRecord.MISSING) value.setText("none"); else - value.setText(String.format("%d", state.data.flight)); + value.setText(String.format("%d", state.flight)); } public Flight (GridBagLayout layout, int x) { super (layout, x, "Flight"); @@ -104,7 +104,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class FlightState extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - value.setText(state.data.state()); + value.setText(state.state_name()); } public FlightState (GridBagLayout layout, int x) { super (layout, x, "State"); @@ -115,7 +115,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class RSSI extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - value.setText(String.format("%d", state.data.rssi)); + value.setText(String.format("%d", state.rssi())); } public RSSI (GridBagLayout layout, int x) { super (layout, x, "RSSI"); diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index 6d010d23..423cf10c 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -130,7 +130,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A flightStatus.show(state, listener_state); flightInfo.show(state, listener_state); - if (state.data.companion != null) { + if (state.companion != null) { if (!has_companion) { pane.add("Companion", companion); has_companion= true; diff --git a/altosui/AltosGraphDataPoint.java b/altosui/AltosGraphDataPoint.java index 7454f447..537efc44 100644 --- a/altosui/AltosGraphDataPoint.java +++ b/altosui/AltosGraphDataPoint.java @@ -42,9 +42,10 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { public static final int data_pressure = 15; public double x() throws AltosUIDataMissing { - if (state.data.time < -2) + double time = state.time_since_boost(); + if (time < -2) throw new AltosUIDataMissing(-1); - return state.data.time; + return time; } public double y(int index) throws AltosUIDataMissing { @@ -63,16 +64,16 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { y = state.temperature; break; case data_battery_voltage: - y = state.battery; + y = state.battery_voltage; break; case data_drogue_voltage: - y = state.drogue_sense; + y = state.apogee_voltage; break; case data_main_voltage: - y = state.main_sense; + y = state.main_voltage; break; case data_rssi: - y = state.data.rssi; + y = state.rssi; break; case data_gps_height: y = state.gps_height; @@ -106,7 +107,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { public int id(int index) { if (index == data_state) { - int s = state.data.state; + int s = state.state; if (s < Altos.ao_flight_boost || s > Altos.ao_flight_landed) return -1; return s; @@ -116,7 +117,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { public String id_name(int index) { if (index == data_state) - return state.data.state(); + return state.state_name(); return ""; } diff --git a/altosui/AltosGraphDataSet.java b/altosui/AltosGraphDataSet.java index dc047e9a..1e469c8a 100644 --- a/altosui/AltosGraphDataSet.java +++ b/altosui/AltosGraphDataSet.java @@ -25,34 +25,31 @@ import org.altusmetrum.altosuilib_1.*; class AltosGraphIterator implements Iterator { AltosGraphDataSet dataSet; - Iterator iterator; - - AltosState state; + Iterator iterator; public boolean hasNext() { return iterator.hasNext(); } public AltosUIDataPoint next() { - state = new AltosState(iterator.next(), state); + AltosState state = iterator.next(); - if ((state.data.seen & AltosRecord.seen_flight) != 0) { - if (dataSet.callsign == null && state.data.callsign != null) - dataSet.callsign = state.data.callsign; + if (state.flight != AltosRecord.MISSING) { + if (dataSet.callsign == null && state.callsign != null) + dataSet.callsign = state.callsign; - if (dataSet.serial == 0 && state.data.serial != 0) - dataSet.serial = state.data.serial; + if (dataSet.serial == 0 && state.serial != 0) + dataSet.serial = state.serial; - if (dataSet.flight == 0 && state.data.flight != 0) - dataSet.flight = state.data.flight; + if (dataSet.flight == 0 && state.flight != 0) + dataSet.flight = state.flight; } return new AltosGraphDataPoint(state); } - public AltosGraphIterator (Iterator iterator, AltosGraphDataSet dataSet) { + public AltosGraphIterator (Iterator iterator, AltosGraphDataSet dataSet) { this.iterator = iterator; - this.state = null; this.dataSet = dataSet; } @@ -64,7 +61,7 @@ class AltosGraphIterable implements Iterable { AltosGraphDataSet dataSet; public Iterator iterator() { - return new AltosGraphIterator(dataSet.records.iterator(), dataSet); + return new AltosGraphIterator(dataSet.states.iterator(), dataSet); } public AltosGraphIterable(AltosGraphDataSet dataSet) { @@ -76,7 +73,7 @@ public class AltosGraphDataSet implements AltosUIDataSet { String callsign; int serial; int flight; - AltosRecordIterable records; + AltosStateIterable states; public String name() { if (callsign != null) @@ -89,8 +86,8 @@ public class AltosGraphDataSet implements AltosUIDataSet { return new AltosGraphIterable(this); } - public AltosGraphDataSet (AltosRecordIterable records) { - this.records = records; + public AltosGraphDataSet (AltosStateIterable states) { + this.states = states; this.callsign = null; this.serial = 0; this.flight = 0; diff --git a/altosui/AltosGraphUI.java b/altosui/AltosGraphUI.java index d8b8f6dd..376e9910 100644 --- a/altosui/AltosGraphUI.java +++ b/altosui/AltosGraphUI.java @@ -28,10 +28,9 @@ public class AltosGraphUI extends AltosUIFrame AltosFlightStatsTable statsTable; boolean has_gps; - void fill_map(AltosRecordIterable records) { + void fill_map(AltosStateIterable states) { boolean any_gps = false; - for (AltosRecord record : records) { - state = new AltosState(record, state); + for (AltosState state : states) { if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { if (map == null) map = new AltosSiteMap(); @@ -41,7 +40,7 @@ public class AltosGraphUI extends AltosUIFrame } } - AltosGraphUI(AltosRecordIterable records, File file) throws InterruptedException, IOException { + AltosGraphUI(AltosStateIterable states, File file) throws InterruptedException, IOException { super(file.getName()); state = null; @@ -49,8 +48,8 @@ public class AltosGraphUI extends AltosUIFrame enable = new AltosUIEnable(); - stats = new AltosFlightStats(records); - graphDataSet = new AltosGraphDataSet(records); + stats = new AltosFlightStats(states); + graphDataSet = new AltosGraphDataSet(states); graph = new AltosGraph(enable, stats, graphDataSet); @@ -61,7 +60,7 @@ public class AltosGraphUI extends AltosUIFrame pane.add("Flight Statistics", statsTable); has_gps = false; - fill_map(records); + fill_map(states); if (has_gps) pane.add("Map", map); diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index 3d16faf2..8601d76f 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -122,15 +122,15 @@ public class AltosInfoTable extends JTable { if (state.speed() != AltosRecord.MISSING) info_add_row(0, "Speed", "%8.1f m/s", state.speed()); if (state.speed() != AltosRecord.MISSING) - info_add_row(0, "Max Speed", "%8.1f m/s", state.max_accel_speed); + info_add_row(0, "Max Speed", "%8.1f m/s", state.max_speed); if (state.temperature != AltosRecord.MISSING) info_add_row(0, "Temperature", "%9.2f °C", state.temperature); - if (state.battery != AltosRecord.MISSING) - info_add_row(0, "Battery", "%9.2f V", state.battery); - if (state.drogue_sense != AltosRecord.MISSING) - info_add_row(0, "Drogue", "%9.2f V", state.drogue_sense); - if (state.main_sense != AltosRecord.MISSING) - info_add_row(0, "Main", "%9.2f V", state.main_sense); + if (state.battery_voltage != AltosRecord.MISSING) + info_add_row(0, "Battery", "%9.2f V", state.battery_voltage); + if (state.apogee_voltage != AltosRecord.MISSING) + info_add_row(0, "Drogue", "%9.2f V", state.apogee_voltage); + if (state.main_voltage != AltosRecord.MISSING) + info_add_row(0, "Main", "%9.2f V", state.main_voltage); } if (listener_state != null) { info_add_row(0, "CRC Errors", "%6d", listener_state.crc_errors); @@ -148,13 +148,13 @@ public class AltosInfoTable extends JTable { else info_add_row(1, "GPS state", "wait (%d)", state.gps_waiting); - if (state.data.gps.locked) + if (state.gps.locked) info_add_row(1, "GPS", " locked"); - else if (state.data.gps.connected) + else if (state.gps.connected) info_add_row(1, "GPS", " unlocked"); else info_add_row(1, "GPS", " missing"); - info_add_row(1, "Satellites", "%6d", state.data.gps.nsat); + info_add_row(1, "Satellites", "%6d", state.gps.nsat); info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S'); info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W'); info_add_row(1, "GPS altitude", "%6d", state.gps.alt); diff --git a/altosui/AltosKML.java b/altosui/AltosKML.java index 140f3f07..b79f5c9e 100644 --- a/altosui/AltosKML.java +++ b/altosui/AltosKML.java @@ -24,8 +24,8 @@ public class AltosKML implements AltosWriter { File name; PrintStream out; - int state = -1; - AltosRecord prev = null; + int flight_state = -1; + AltosState prev = null; double gps_start_altitude; static final String[] kml_state_colors = { @@ -83,7 +83,7 @@ public class AltosKML implements AltosWriter { "\n" + "\n"; - void start (AltosRecord record) { + void start (AltosState record) { out.printf(kml_header_start, record.flight, record.serial); out.printf("Date: %04d-%02d-%02d\n", record.gps.year, record.gps.month, record.gps.day); @@ -94,30 +94,30 @@ public class AltosKML implements AltosWriter { boolean started = false; - void state_start(AltosRecord record) { - String state_name = Altos.state_name(record.state); - out.printf(kml_style_start, state_name, kml_state_colors[record.state]); + void state_start(AltosState state) { + String state_name = Altos.state_name(state.state); + out.printf(kml_style_start, state_name, kml_state_colors[state.state]); out.printf("\tState: %s\n", state_name); out.printf("%s", kml_style_end); out.printf(kml_placemark_start, state_name, state_name); } - void state_end(AltosRecord record) { + void state_end(AltosState state) { out.printf("%s", kml_placemark_end); } - void coord(AltosRecord record) { - AltosGPS gps = record.gps; + void coord(AltosState state) { + AltosGPS gps = state.gps; double altitude; - if (record.height() != AltosRecord.MISSING) - altitude = record.height() + gps_start_altitude; + if (state.height != AltosRecord.MISSING) + altitude = state.height + gps_start_altitude; else altitude = gps.alt; out.printf(kml_coord_fmt, gps.lon, gps.lat, altitude, (double) gps.alt, - record.time, gps.nsat); + state.time, gps.nsat); } void end() { @@ -132,38 +132,40 @@ public class AltosKML implements AltosWriter { } } - public void write(AltosRecord record) { - AltosGPS gps = record.gps; + public void write(AltosState state) { + AltosGPS gps = state.gps; if (gps == null) return; - if ((record.seen & (AltosRecord.seen_gps_lat)) == 0) + if (gps.lat == AltosRecord.MISSING) return; - if ((record.seen & (AltosRecord.seen_gps_lon)) == 0) + if (gps.lon == AltosRecord.MISSING) return; if (!started) { - start(record); + start(state); started = true; gps_start_altitude = gps.alt; } - if (prev != null && prev.gps_sequence == record.gps_sequence) + if (prev != null && prev.gps_sequence == state.gps_sequence) return; - if (record.state != state) { - state = record.state; + if (state.state != flight_state) { + flight_state = state.state; if (prev != null) { - coord(record); + coord(state); state_end(prev); } - state_start(record); + state_start(state); } - coord(record); - prev = record; + coord(state); + prev = state; } - public void write(AltosRecordIterable iterable) { - for (AltosRecord record : iterable) - write(record); + public void write(AltosStateIterable states) { + for (AltosState state : states) { + if ((state.set & AltosState.set_gps) != 0) + write(state); + } } public AltosKML(File in_name) throws FileNotFoundException { diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 9dab52c4..38f273cf 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -243,24 +243,18 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio if (file != null) { String filename = file.getName(); try { - AltosRecordIterable records = null; + AltosStateIterable states = null; if (filename.endsWith("eeprom")) { FileInputStream in = new FileInputStream(file); - records = new AltosEepromIterable(in); + states = new AltosEepromFile(in); } else if (filename.endsWith("telem")) { FileInputStream in = new FileInputStream(file); - records = new AltosTelemetryIterable(in); - } else if (filename.endsWith("mega")) { - FileInputStream in = new FileInputStream(file); - records = new AltosEepromMegaIterable(in); - } else if (filename.endsWith("mini")) { - FileInputStream in = new FileInputStream(file); - records = new AltosEepromMiniIterable(in); + states = null; // new AltosTelemetryIterable(in); } else { throw new FileNotFoundException(filename); } try { - new AltosGraphUI(records, file); + new AltosGraphUI(states, file); } catch (InterruptedException ie) { } catch (IOException ie) { } diff --git a/altosui/AltosPad.java b/altosui/AltosPad.java index e2316a13..fed009cc 100644 --- a/altosui/AltosPad.java +++ b/altosui/AltosPad.java @@ -176,11 +176,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Battery extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.battery == AltosRecord.MISSING) + if (state == null || state.battery_voltage == AltosRecord.MISSING) hide(); else { - show("%4.2f V", state.battery); - lights.set(state.battery > 3.7); + show("%4.2f V", state.battery_voltage); + lights.set(state.battery_voltage > 3.7); } } public Battery (GridBagLayout layout, int y) { @@ -192,11 +192,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Apogee extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.drogue_sense == AltosRecord.MISSING) + if (state == null || state.apogee_voltage == AltosRecord.MISSING) hide(); else { - show("%4.2f V", state.drogue_sense); - lights.set(state.drogue_sense > 3.2); + show("%4.2f V", state.apogee_voltage); + lights.set(state.apogee_voltage > 3.7); } } public Apogee (GridBagLayout layout, int y) { @@ -208,11 +208,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Main extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.main_sense == AltosRecord.MISSING) + if (state == null || state.main_voltage == AltosRecord.MISSING) hide(); else { - show("%4.2f V", state.main_sense); - lights.set(state.main_sense > 3.2); + show("%4.2f V", state.main_voltage); + lights.set(state.main_voltage > 3.7); } } public Main (GridBagLayout layout, int y) { @@ -224,19 +224,19 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class LoggingReady extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.data.flight == AltosRecord.MISSING) { + if (state == null || state.flight == AltosRecord.MISSING) { hide(); } else { - if (state.data.flight != 0) { - if (state.data.state <= Altos.ao_flight_pad) + if (state.flight != 0) { + if (state.state <= Altos.ao_flight_pad) show("Ready to record"); - else if (state.data.state < Altos.ao_flight_landed) + else if (state.state < Altos.ao_flight_landed) show("Recording data"); else show("Recorded data"); } else show("Storage full"); - lights.set(state.data.flight != 0); + lights.set(state.flight != 0); } } public LoggingReady (GridBagLayout layout, int y) { diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index 0c903873..224e1e61 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -184,13 +184,13 @@ public class AltosScanUI try { for (;;) { try { - AltosRecord record = reader.read(); - if (record == null) + AltosState state = reader.read(); + if (state == null) continue; - if ((record.seen & AltosRecord.seen_flight) != 0) { - final AltosScanResult result = new AltosScanResult(record.callsign, - record.serial, - record.flight, + if (state.flight != AltosRecord.MISSING) { + final AltosScanResult result = new AltosScanResult(state.callsign, + state.serial, + state.flight, frequencies[frequency_index], telemetry); Runnable r = new Runnable() { diff --git a/altosui/AltosSiteMap.java b/altosui/AltosSiteMap.java index 23085f3e..c0926919 100644 --- a/altosui/AltosSiteMap.java +++ b/altosui/AltosSiteMap.java @@ -271,27 +271,34 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { int last_state = -1; public void show(double lat, double lon) { - initMaps(lat, lon); - scrollRocketToVisible(pt(lat, lon)); + System.out.printf ("show %g %g\n", lat, lon); + return; +// initMaps(lat, lon); +// scrollRocketToVisible(pt(lat, lon)); } public void show(final AltosState state, final AltosListenerState listener_state) { // if insufficient gps data, nothing to update - if (!state.gps.locked && state.gps.nsat < 4) + AltosGPS gps = state.gps; + + if (gps == null) + return; + + if (!gps.locked && gps.nsat < 4) return; if (!initialised) { - if (state.pad_lat != 0 || state.pad_lon != 0) { + if (state.pad_lat != AltosRecord.MISSING && state.pad_lon != AltosRecord.MISSING) { initMaps(state.pad_lat, state.pad_lon); initialised = true; - } else if (state.gps.lat != 0 || state.gps.lon != 0) { - initMaps(state.gps.lat, state.gps.lon); + } else if (gps.lat != AltosRecord.MISSING && gps.lon != AltosRecord.MISSING) { + initMaps(gps.lat, gps.lon); initialised = true; } else { return; } } - final Point2D.Double pt = pt(state.gps.lat, state.gps.lon); + final Point2D.Double pt = pt(gps.lat, gps.lon); if (last_pt == pt && last_state == state.state) return; diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 4362e36c..6d5ce185 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -290,9 +290,9 @@ public class AltosUI extends AltosUIFrame { AltosDataChooser chooser = new AltosDataChooser( AltosUI.this); - AltosRecordIterable iterable = chooser.runDialog(); - if (iterable != null) { - AltosFlightReader reader = new AltosReplayReader(iterable.iterator(), + Iterable states = chooser.runDialog(); + if (states != null) { + AltosFlightReader reader = new AltosReplayReader(states.iterator(), chooser.file()); new AltosFlightUI(voice, reader); } @@ -312,10 +312,10 @@ public class AltosUI extends AltosUIFrame { private void ExportData() { AltosDataChooser chooser; chooser = new AltosDataChooser(this); - AltosRecordIterable record_reader = chooser.runDialog(); - if (record_reader == null) + AltosStateIterable states = chooser.runDialog(); + if (states == null) return; - new AltosCSVUI(AltosUI.this, record_reader, chooser.file()); + new AltosCSVUI(AltosUI.this, states, chooser.file()); } /* Load a flight log CSV file and display a pretty graph. @@ -324,11 +324,11 @@ public class AltosUI extends AltosUIFrame { private void GraphData() { AltosDataChooser chooser; chooser = new AltosDataChooser(this); - AltosRecordIterable record_reader = chooser.runDialog(); - if (record_reader == null) + AltosStateIterable states = chooser.runDialog(); + if (states == null) return; try { - new AltosGraphUI(record_reader, chooser.file()); + new AltosGraphUI(states, chooser.file()); } catch (InterruptedException ie) { } catch (IOException ie) { } @@ -345,19 +345,15 @@ public class AltosUI extends AltosUIFrame { } } - static AltosRecordIterable open_logfile(File file) { + static AltosStateIterable open_logfile(File file) { try { FileInputStream in; in = new FileInputStream(file); if (file.getName().endsWith("eeprom")) - return new AltosEepromIterable(in); - else if (file.getName().endsWith("mega")) - return new AltosEepromMegaIterable(in); - else if (file.getName().endsWith("mini")) - return new AltosEepromMiniIterable(in); + return new AltosEepromFile(in); else - return new AltosTelemetryIterable(in); + return null; // new AltosTelemetryIterable(in); } catch (FileNotFoundException fe) { System.out.printf("%s\n", fe.getMessage()); return null; @@ -388,10 +384,11 @@ public class AltosUI extends AltosUIFrame { static final int process_graph = 3; static final int process_replay = 4; static final int process_summary = 5; + static final int process_cat = 6; static boolean process_csv(File input) { - AltosRecordIterable iterable = open_logfile(input); - if (iterable == null) + AltosStateIterable states = open_logfile(input); + if (states == null) return false; File output = Altos.replace_extension(input,".csv"); @@ -403,15 +400,15 @@ public class AltosUI extends AltosUIFrame { AltosWriter writer = open_csv(output); if (writer == null) return false; - writer.write(iterable); + writer.write(states); writer.close(); } return true; } static boolean process_kml(File input) { - AltosRecordIterable iterable = open_logfile(input); - if (iterable == null) + AltosStateIterable states = open_logfile(input); + if (states == null) return false; File output = Altos.replace_extension(input,".kml"); @@ -423,13 +420,13 @@ public class AltosUI extends AltosUIFrame { AltosWriter writer = open_kml(output); if (writer == null) return false; - writer.write(iterable); + writer.write(states); writer.close(); return true; } } - static AltosRecordIterable record_iterable(File file) { + static AltosStateIterable record_iterable(File file) { FileInputStream in; try { in = new FileInputStream(file); @@ -437,25 +434,18 @@ public class AltosUI extends AltosUIFrame { System.out.printf("Failed to open file '%s'\n", file); return null; } - AltosRecordIterable recs; - //AltosReplayReader reader; if (file.getName().endsWith("eeprom")) { - recs = new AltosEepromIterable(in); - } else if (file.getName().endsWith("mega")) { - recs = new AltosEepromMegaIterable(in); - } else if (file.getName().endsWith("mini")) { - recs = new AltosEepromMiniIterable(in); + return new AltosEepromFile(in); } else { - recs = new AltosTelemetryIterable(in); + return null; // new AltosTelemetryIterable(in); } - return recs; } static AltosReplayReader replay_file(File file) { - AltosRecordIterable recs = record_iterable(file); - if (recs == null) + AltosStateIterable states = record_iterable(file); + if (states == null) return null; - return new AltosReplayReader(recs.iterator(), file); + return new AltosReplayReader(states.iterator(), file); } static boolean process_replay(File file) { @@ -468,11 +458,11 @@ public class AltosUI extends AltosUIFrame { } static boolean process_graph(File file) { - AltosRecordIterable recs = record_iterable(file); - if (recs == null) + AltosStateIterable states = record_iterable(file); + if (states == null) return false; try { - new AltosGraphUI(recs, file); + new AltosGraphUI(states, file); return true; } catch (InterruptedException ie) { } catch (IOException ie) { @@ -481,11 +471,11 @@ public class AltosUI extends AltosUIFrame { } static boolean process_summary(File file) { - AltosRecordIterable iterable = record_iterable(file); - if (iterable == null) + AltosStateIterable states = record_iterable(file); + if (states == null) return false; try { - AltosFlightStats stats = new AltosFlightStats(iterable); + AltosFlightStats stats = new AltosFlightStats(states); if (stats.serial > 0) System.out.printf("Serial: %5d\n", stats.serial); if (stats.flight > 0) @@ -510,11 +500,11 @@ public class AltosUI extends AltosUIFrame { AltosConvert.meters_to_g(stats.max_acceleration)); } System.out.printf("Drogue rate: %6.0f m/s %6.0f ft/s\n", - stats.state_baro_speed[Altos.ao_flight_drogue], - AltosConvert.meters_to_feet(stats.state_baro_speed[Altos.ao_flight_drogue])); + stats.state_speed[Altos.ao_flight_drogue], + AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue])); System.out.printf("Main rate: %6.0f m/s %6.0f ft/s\n", - stats.state_baro_speed[Altos.ao_flight_main], - AltosConvert.meters_to_feet(stats.state_baro_speed[Altos.ao_flight_main])); + stats.state_speed[Altos.ao_flight_main], + AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main])); System.out.printf("Flight time: %6.0f s\n", stats.state_end[Altos.ao_flight_main] - stats.state_start[Altos.ao_flight_boost]); @@ -525,6 +515,27 @@ public class AltosUI extends AltosUIFrame { return false; } + static boolean process_cat(File file) { + try { + FileInputStream input = new FileInputStream(file); + AltosEepromFile eef = new AltosEepromFile(input); + + for (AltosState state : eef) { + if ((state.set & AltosState.set_gps) != 0) + System.out.printf ("time %g lat %g lon %g alt %g\n", + state.time_since_boost(), + state.gps.lat, + state.gps.lon, + state.gps.alt); + } + + } catch (Exception e) { + System.out.printf("Failed to open file '%s'\n", file); + return false; + } + return true; + } + public static void help(int code) { System.out.printf("Usage: altosui [OPTION]... [FILE]...\n"); System.out.printf(" Options:\n"); @@ -574,6 +585,8 @@ public class AltosUI extends AltosUIFrame { process = process_graph; else if (args[i].equals("--summary")) process = process_summary; + else if (args[i].equals("--cat")) + process = process_cat; else if (args[i].startsWith("--")) help(1); else { @@ -600,6 +613,9 @@ public class AltosUI extends AltosUIFrame { if (!process_summary(file)) ++errors; break; + case process_cat: + if (!process_cat(file)) + ++errors; } } } diff --git a/altosui/AltosWriter.java b/altosui/AltosWriter.java index 2f70b472..8de11bc9 100644 --- a/altosui/AltosWriter.java +++ b/altosui/AltosWriter.java @@ -22,9 +22,9 @@ import org.altusmetrum.altoslib_1.*; public interface AltosWriter { - public void write(AltosRecord record); + public void write(AltosState state); - public void write(AltosRecordIterable iterable); + public void write(AltosStateIterable states); public void close(); } -- 2.30.2