From de2b6ec1cdfd48c948bff7edbfe2540440429b1b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 2 Oct 2017 16:55:18 -0700 Subject: altoslib,altosuilib,altosui: log_format/device_type TeleGPS selects stateless When the device being analyzed has no flight state, we want to use the 'stateless' state so that the UI can display reasonable information. This bit was lost in the recent AltosState shuffle and this patch brings it back. Signed-off-by: Keith Packard --- altoslib/AltosEepromRecord.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'altoslib/AltosEepromRecord.java') diff --git a/altoslib/AltosEepromRecord.java b/altoslib/AltosEepromRecord.java index 094584fe..e937c3d0 100644 --- a/altoslib/AltosEepromRecord.java +++ b/altoslib/AltosEepromRecord.java @@ -83,7 +83,7 @@ public abstract class AltosEepromRecord implements Comparable /* AltosDataProvider */ public void provide_data(AltosDataListener listener, AltosCalData cal_data) { - cal_data.set_tick(tick()); + listener.set_tick(tick()); if (cmd() == AltosLib.AO_LOG_FLIGHT) cal_data.set_boost_tick(); listener.set_time(cal_data.time()); -- cgit v1.2.3 From 749400fd244eba38806c623d2a35722642230698 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 22 Oct 2017 14:04:09 -0500 Subject: altoslib: Move temp GPS API from cal_data to data_listener This makes the API more consistent, and means that the listener is responsible for mangaing the temp gps state. In particular, the AltosDataListener set_gps API now calls the cal_data function. Signed-off-by: Keith Packard --- altoslib/AltosCalData.java | 39 ++++---- altoslib/AltosDataListener.java | 13 ++- altoslib/AltosEepromDownload.java | 1 + altoslib/AltosEepromRecord.java | 6 +- altoslib/AltosEepromRecordFull.java | 12 +-- altoslib/AltosEepromRecordMega.java | 4 +- altoslib/AltosEepromRecordMetrum.java | 6 +- altoslib/AltosFlightListener.java | 162 ---------------------------------- altoslib/AltosFlightSeries.java | 1 + altoslib/AltosReplayReader.java | 2 +- altoslib/AltosState.java | 1 + altoslib/AltosTelemetryLocation.java | 7 +- altoslib/AltosTelemetrySatellite.java | 3 +- 13 files changed, 47 insertions(+), 210 deletions(-) delete mode 100644 altoslib/AltosFlightListener.java (limited to 'altoslib/AltosEepromRecord.java') diff --git a/altoslib/AltosCalData.java b/altoslib/AltosCalData.java index 7415d5ad..fdea5e21 100644 --- a/altoslib/AltosCalData.java +++ b/altoslib/AltosCalData.java @@ -199,7 +199,6 @@ public class AltosCalData { tick = AltosLib.MISSING; prev_tick = AltosLib.MISSING; temp_gps = null; - prev_gps = null; temp_gps_sat_tick = AltosLib.MISSING; accel = AltosLib.MISSING; } @@ -244,11 +243,14 @@ public class AltosCalData { public double gps_pad_altitude = AltosLib.MISSING; - public void set_gps(AltosGPS gps) { - if ((state != AltosLib.MISSING && state < AltosLib.ao_flight_boost) || gps_pad == null) - gps_pad = gps; - if (gps_pad_altitude == AltosLib.MISSING && gps.alt != AltosLib.MISSING) - gps_pad_altitude = gps.alt; + public void set_cal_gps(AltosGPS gps) { + if (gps.locked && gps.nsat >= 4) { + if ((state != AltosLib.MISSING && state < AltosLib.ao_flight_boost) || gps_pad == null) + gps_pad = gps; + if (gps_pad_altitude == AltosLib.MISSING && gps.alt != AltosLib.MISSING) + gps_pad_altitude = gps.alt; + } + temp_gps = null; } /* @@ -256,33 +258,24 @@ public class AltosCalData { * object and then deliver the result atomically to the listener */ AltosGPS temp_gps = null; - AltosGPS prev_gps = null; int temp_gps_sat_tick = AltosLib.MISSING; - public AltosGPS temp_gps() { + public AltosGPS temp_cal_gps() { return temp_gps; } - public void reset_temp_gps() { - if (temp_gps != null) { - if (temp_gps.locked && temp_gps.nsat >= 4) - set_gps(temp_gps); - prev_gps = temp_gps; - temp_gps = null; - } + public void reset_temp_cal_gps() { + if (temp_gps != null) + set_cal_gps(temp_gps); } - public boolean gps_pending() { + public boolean cal_gps_pending() { return temp_gps != null; } - public AltosGPS make_temp_gps(int tick, boolean sats) { - if (temp_gps == null) { - if (prev_gps != null) - temp_gps = prev_gps.clone(); - else - temp_gps = new AltosGPS(); - } + public AltosGPS make_temp_cal_gps(int tick, boolean sats) { + if (temp_gps == null) + temp_gps = new AltosGPS(); if (sats) { if (tick != temp_gps_sat_tick) temp_gps.cc_gps_sat = null; diff --git a/altoslib/AltosDataListener.java b/altoslib/AltosDataListener.java index 359d04c9..9a1e1465 100644 --- a/altoslib/AltosDataListener.java +++ b/altoslib/AltosDataListener.java @@ -111,7 +111,18 @@ public abstract class AltosDataListener { public abstract void set_apogee_voltage(double volts); public abstract void set_main_voltage(double volts); - public abstract void set_gps(AltosGPS gps); + public void set_gps(AltosGPS gps) { + AltosCalData cal_data = cal_data(); + cal_data.set_cal_gps(gps); + } + + public AltosGPS make_temp_gps(boolean sats) { + return cal_data().make_temp_cal_gps(tick(), sats); + } + + public AltosGPS temp_gps() { + return cal_data().temp_cal_gps(); + } public abstract void set_orient(double orient); public abstract void set_gyro(double roll, double pitch, double yaw); diff --git a/altoslib/AltosEepromDownload.java b/altoslib/AltosEepromDownload.java index 33f0dd17..3df8a5b4 100644 --- a/altoslib/AltosEepromDownload.java +++ b/altoslib/AltosEepromDownload.java @@ -40,6 +40,7 @@ class AltosEepromNameData extends AltosDataListener { public void set_main_voltage(double volts) { } public void set_gps(AltosGPS gps) { + super.set_gps(gps); if (gps != null && gps.year != AltosLib.MISSING && gps.month != AltosLib.MISSING && diff --git a/altoslib/AltosEepromRecord.java b/altoslib/AltosEepromRecord.java index e937c3d0..12519e6b 100644 --- a/altoslib/AltosEepromRecord.java +++ b/altoslib/AltosEepromRecord.java @@ -90,11 +90,9 @@ public abstract class AltosEepromRecord implements Comparable /* Flush any pending GPS changes */ if (!AltosLib.is_gps_cmd(cmd())) { - AltosGPS gps = cal_data.temp_gps(); - if (gps != null) { + AltosGPS gps = listener.temp_gps(); + if (gps != null) listener.set_gps(gps); - cal_data.reset_temp_gps(); - } } } diff --git a/altoslib/AltosEepromRecordFull.java b/altoslib/AltosEepromRecordFull.java index 32df9578..7e92d353 100644 --- a/altoslib/AltosEepromRecordFull.java +++ b/altoslib/AltosEepromRecordFull.java @@ -53,7 +53,7 @@ public class AltosEepromRecordFull extends AltosEepromRecord { listener.set_state(data16(0)); break; case AltosLib.AO_LOG_GPS_TIME: - gps = cal_data.make_temp_gps(tick(),false); + gps = listener.make_temp_gps(false); gps.hour = data8(0); gps.minute = data8(1); @@ -67,29 +67,29 @@ public class AltosEepromRecordFull extends AltosEepromRecord { AltosLib.AO_GPS_NUM_SAT_SHIFT; break; case AltosLib.AO_LOG_GPS_LAT: - gps = cal_data.make_temp_gps(tick(),false); + gps = listener.make_temp_gps(false); int lat32 = data32(0); gps.lat = (double) lat32 / 1e7; break; case AltosLib.AO_LOG_GPS_LON: - gps = cal_data.make_temp_gps(tick(),false); + gps = listener.make_temp_gps(false); int lon32 = data32(0); gps.lon = (double) lon32 / 1e7; break; case AltosLib.AO_LOG_GPS_ALT: - gps = cal_data.make_temp_gps(tick(),false); + gps = listener.make_temp_gps(false); gps.alt = data16(0); break; case AltosLib.AO_LOG_GPS_SAT: - gps = cal_data.make_temp_gps(tick(),true); + gps = listener.make_temp_gps(true); int svid = data16(0); int c_n0 = data16(2); gps.add_sat(svid, c_n0); break; case AltosLib.AO_LOG_GPS_DATE: - gps = cal_data.make_temp_gps(tick(),false); + gps = listener.make_temp_gps(false); gps.year = data8(0) + 2000; gps.month = data8(1); gps.day = data8(2); diff --git a/altoslib/AltosEepromRecordMega.java b/altoslib/AltosEepromRecordMega.java index ad3e23fd..ea5aff5c 100644 --- a/altoslib/AltosEepromRecordMega.java +++ b/altoslib/AltosEepromRecordMega.java @@ -188,7 +188,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord { listener.set_pyro_fired(pyro()); break; case AltosLib.AO_LOG_GPS_TIME: - gps = cal_data.make_temp_gps(tick(), false); + gps = listener.make_temp_gps(false); gps.lat = latitude() / 1e7; gps.lon = longitude() / 1e7; @@ -231,7 +231,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord { } break; case AltosLib.AO_LOG_GPS_SAT: - gps = cal_data.make_temp_gps(tick(), true); + gps = listener.make_temp_gps(true); int n = nsat(); if (n > max_sat) diff --git a/altoslib/AltosEepromRecordMetrum.java b/altoslib/AltosEepromRecordMetrum.java index 3da50544..888a06cc 100644 --- a/altoslib/AltosEepromRecordMetrum.java +++ b/altoslib/AltosEepromRecordMetrum.java @@ -91,7 +91,7 @@ public class AltosEepromRecordMetrum extends AltosEepromRecord { listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m())); break; case AltosLib.AO_LOG_GPS_POS: - gps = cal_data.make_temp_gps(tick(), false); + gps = listener.make_temp_gps(false); gps.lat = latitude() / 1e7; gps.lon = longitude() / 1e7; if (config_data().altitude_32()) @@ -100,7 +100,7 @@ public class AltosEepromRecordMetrum extends AltosEepromRecord { gps.alt = altitude_low(); break; case AltosLib.AO_LOG_GPS_TIME: - gps = cal_data.make_temp_gps(tick(), false); + gps = listener.make_temp_gps(false); gps.hour = hour(); gps.minute = minute(); @@ -119,7 +119,7 @@ public class AltosEepromRecordMetrum extends AltosEepromRecord { gps.pdop = pdop() / 10.0; break; case AltosLib.AO_LOG_GPS_SAT: - gps = cal_data.make_temp_gps(tick(), true); + gps = listener.make_temp_gps(true); int n = nsat(); for (int i = 0; i < n; i++) diff --git a/altoslib/AltosFlightListener.java b/altoslib/AltosFlightListener.java deleted file mode 100644 index d61831a9..00000000 --- a/altoslib/AltosFlightListener.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright © 2017 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, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -package org.altusmetrum.altoslib_12; - -public abstract class AltosFlightListener { - - public int flight; - public int serial; - public int tick; - public int boost_tick; - public int state; - - public double accel_plus_g; - public double accel_minus_g; - public double accel; - - public double ground_pressure; - public double ground_altitude; - - AltosGPS temp_gps; - int temp_gps_sat_tick; - int gps_sequence; - - /* AltosEepromRecord */ - public void set_boost_tick(int boost_tick) { - if (boost_tick != AltosLib.MISSING) - this.boost_tick = boost_tick; - } - - public void set_tick(int tick) { - if (tick != AltosLib.MISSING) - this.tick = tick; - } - - public double time() { - if (tick == AltosLib.MISSING) - return AltosLib.MISSING; - if (boost_tick != AltosLib.MISSING) - return (tick - boost_tick) / 100.0; - else - return tick / 100.0; - } - - public double boost_time() { - if (boost_tick == AltosLib.MISSING) - return AltosLib.MISSING; - return boost_tick / 100.0; - } - - public abstract void set_rssi(int rssi, int status); - public abstract void set_received_time(long received_time); - - /* AltosEepromRecordFull */ - - public void set_serial(int serial) { - if (serial != AltosLib.MISSING) - this.serial = serial; - } - - public void set_state(int state) { - if (state != AltosLib.MISSING) - this.state = state; - } - - public int state() { return state; } - - public abstract void set_ground_accel(double ground_accel); - public void set_flight(int flight) { - if (flight != AltosLib.MISSING) - this.flight = flight; - } - public int flight() { - return flight; - } - - public abstract void set_accel(double accel); - public abstract void set_acceleration(double accel); - public abstract void set_accel_g(double accel_plus_g, double accel_minus_g); - public abstract void set_pressure(double pa); - public abstract void set_thrust(double N); - - public abstract void set_temperature(double deg_c); - public abstract void set_battery_voltage(double volts); - - public abstract void set_apogee_voltage(double volts); - public abstract void set_main_voltage(double volts); - - public void set_temp_gps() { - temp_gps = null; - } - - public boolean gps_pending() { - return temp_gps != null; - } - - public AltosGPS make_temp_gps(boolean sats) { - if (temp_gps == null) { - temp_gps = new AltosGPS(); - } - if (sats) { - if (tick != temp_gps_sat_tick) - temp_gps.cc_gps_sat = null; - temp_gps_sat_tick = tick; - } - return temp_gps; - } - - public void set_ground_pressure(double ground_pressure) { - if (ground_pressure != AltosLib.MISSING) { - this.ground_pressure = ground_pressure; - this.ground_altitude = AltosConvert.pressure_to_altitude(ground_pressure); - } - } - - public abstract void set_accel_ground(double along, double across, double through); - public abstract void set_gyro_zero(double roll, double pitch, double yaw); - public abstract void check_imu_wrap(AltosIMU imu); - public abstract void set_imu(AltosIMU imu); - public abstract void set_mag(AltosMag mag); - public abstract void set_pyro_voltage(double volts); - public abstract void set_igniter_voltage(double[] voltage); - public abstract void set_pyro_fired(int pyro_mask); - - public void copy(AltosFlightListener old) { - flight = old.flight; - serial = old.serial; - tick = old.tick; - boost_tick = old.boost_tick; - accel_plus_g = old.accel_plus_g; - accel_minus_g = old.accel_minus_g; - ground_pressure = old.ground_pressure; - ground_altitude = old.ground_altitude; - temp_gps = old.temp_gps; - temp_gps_sat_tick = old.temp_gps_sat_tick; - } - - public void init() { - flight = AltosLib.MISSING; - serial = AltosLib.MISSING; - tick = AltosLib.MISSING; - boost_tick = AltosLib.MISSING; - accel_plus_g = AltosLib.MISSING; - accel_minus_g = AltosLib.MISSING; - accel = AltosLib.MISSING; - ground_pressure = AltosLib.MISSING; - ground_altitude = AltosLib.MISSING; - temp_gps = null; - temp_gps_sat_tick = AltosLib.MISSING; - } -} diff --git a/altoslib/AltosFlightSeries.java b/altoslib/AltosFlightSeries.java index 2eaf8033..d130d3ad 100644 --- a/altoslib/AltosFlightSeries.java +++ b/altoslib/AltosFlightSeries.java @@ -532,6 +532,7 @@ public class AltosFlightSeries extends AltosDataListener { public static final String gps_hdop_name = "GPS Horizontal Dilution of Precision"; public void set_gps(AltosGPS gps) { + super.set_gps(gps); if (gps_series == null) gps_series = new ArrayList(); gps_series.add(new AltosGPSTimeValue(time(), gps)); diff --git a/altoslib/AltosReplayReader.java b/altoslib/AltosReplayReader.java index 24b425b7..7ce4197b 100644 --- a/altoslib/AltosReplayReader.java +++ b/altoslib/AltosReplayReader.java @@ -70,7 +70,7 @@ class AltosReplay extends AltosDataListener implements Runnable { public void set_apogee_voltage(double volts) { state.set_apogee_voltage(volts); } public void set_main_voltage(double volts) { state.set_main_voltage(volts); } - public void set_gps(AltosGPS gps) { state.set_gps(gps); } + public void set_gps(AltosGPS gps) { super.set_gps(gps); state.set_gps(gps); } public void set_orient(double orient) { state.set_orient(orient); } public void set_gyro(double roll, double pitch, double yaw) { state.set_gyro(roll, pitch, yaw); } diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 54c70094..68097faf 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -887,6 +887,7 @@ public class AltosState extends AltosDataListener { } public void set_gps(AltosGPS gps) { + super.set_gps(gps); if (gps != null) { this.gps = gps; update_gps(); diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java index f4366e33..e2925a58 100644 --- a/altoslib/AltosTelemetryLocation.java +++ b/altoslib/AltosTelemetryLocation.java @@ -54,7 +54,7 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard { AltosCalData cal_data = listener.cal_data(); - AltosGPS gps = cal_data.make_temp_gps(tick(), false); + AltosGPS gps = listener.make_temp_gps(false); int flags = flags(); gps.nsat = flags & 0xf; @@ -77,12 +77,7 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard { gps.ground_speed = ground_speed() * 1.0e-2; gps.course = course() * 2; gps.climb_rate = climb_rate() * 1.0e-2; - - if (gps.nsat >= 4) - cal_data.set_gps(gps); } listener.set_gps(gps); - cal_data.set_gps(gps); - cal_data.reset_temp_gps(); } } diff --git a/altoslib/AltosTelemetrySatellite.java b/altoslib/AltosTelemetrySatellite.java index 60bc4a51..0965df9f 100644 --- a/altoslib/AltosTelemetrySatellite.java +++ b/altoslib/AltosTelemetrySatellite.java @@ -49,10 +49,9 @@ public class AltosTelemetrySatellite extends AltosTelemetryStandard { AltosCalData cal_data = listener.cal_data(); - AltosGPS gps = cal_data.make_temp_gps(tick(), true); + AltosGPS gps = listener.make_temp_gps(true); gps.cc_gps_sat = sats(); listener.set_gps(gps); - cal_data.reset_temp_gps(); } } -- cgit v1.2.3 From 9a7b4f02ad32ca43a45ed9fe446b8db96e60b5e5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 11 Nov 2017 20:49:20 -0800 Subject: altoslib: Improve EEprom download * Catch and report CRC errors * Deal with corrupted flight records * Add ability to immediately graph new data * Check before overwriting existing files Signed-off-by: Keith Packard --- altoslib/AltosEeprom.java | 1 + altoslib/AltosEepromDownload.java | 42 +++++++++++++++----- altoslib/AltosEepromList.java | 4 +- altoslib/AltosEepromLog.java | 18 +++++++-- altoslib/AltosEepromMonitor.java | 6 ++- altoslib/AltosEepromRecord.java | 25 +++++++----- altoslib/AltosEepromRecordSet.java | 6 +-- altoslib/AltosFile.java | 17 +++++++- altosui/AltosUI.java | 13 +++++- altosuilib/AltosEepromDelete.java | 2 +- altosuilib/AltosEepromManage.java | 72 ++++++++++++++++++++------------- altosuilib/AltosEepromMonitorUI.java | 77 +++++++++++++++++------------------- altosuilib/AltosEepromSelect.java | 74 +++++++++++++++++++++++++++++----- telegps/TeleGPS.java | 19 ++++++++- 14 files changed, 260 insertions(+), 116 deletions(-) (limited to 'altoslib/AltosEepromRecord.java') diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java index ad7bf881..124bd478 100644 --- a/altoslib/AltosEeprom.java +++ b/altoslib/AltosEeprom.java @@ -22,6 +22,7 @@ public class AltosEeprom { private AltosJson config; ArrayList data; private AltosConfigData config_data; + int errors = 0; /* * Public accessor APIs diff --git a/altoslib/AltosEepromDownload.java b/altoslib/AltosEepromDownload.java index 3df8a5b4..547b523f 100644 --- a/altoslib/AltosEepromDownload.java +++ b/altoslib/AltosEepromDownload.java @@ -200,25 +200,47 @@ public class AltosEepromDownload implements Runnable { AltosFile f = MakeFile(flights.config_data.serial, log.flight, name_data); - monitor.set_filename(f.toString()); + log.set_file(f); - FileWriter w = new FileWriter(f); + boolean do_write = true; - eeprom.write(w); - w.close(); + if (f.exists()) + do_write = monitor.check_overwrite(f); + + if (do_write) { + FileWriter w = new FileWriter(f); + + eeprom.write(w); + w.close(); + } + + if (eeprom.errors != 0) + throw new ParseException(String.format("%d CRC Errors", eeprom.errors), 0); + } + + static String label(int flight) { + if (flight < 0) + return "Corrupt"; + else + return "Flight"; + } + + static int flight(int flight) { + if (flight < 0) + return -flight; + return flight; } public void run () { boolean success = false; try { - boolean failed = false; if (remote) link.start_remote(); for (AltosEepromLog log : flights) { parse_errors = null; - if (log.selected) { + if (log.download_selected) { monitor.reset(); try { CaptureLog(log); @@ -226,16 +248,16 @@ public class AltosEepromDownload implements Runnable { LogError(e.getMessage()); } } + success = true; if (parse_errors != null) { - failed = true; - monitor.show_message(String.format("Flight %d download error. Valid log data saved\n%s", - log.flight, + monitor.show_message(String.format("%s %d download error. Valid log data saved\n%s", + label(log.flight), + flight(log.flight), parse_errors), link.name, AltosEepromMonitor.WARNING_MESSAGE); } } - success = !failed; } catch (IOException ee) { monitor.show_message(ee.getLocalizedMessage(), link.name, diff --git a/altoslib/AltosEepromList.java b/altoslib/AltosEepromList.java index 55d47e20..c55bcaaa 100644 --- a/altoslib/AltosEepromList.java +++ b/altoslib/AltosEepromList.java @@ -87,7 +87,7 @@ public class AltosEepromList extends ArrayList { start = AltosParse.parse_hex(tokens[3]); if (tokens[4].equals("end")) end = AltosParse.parse_hex(tokens[5]); - if (flight > 0 && start >= 0 && end > 0) + if (flight != 0 && start >= 0 && end > 0) flights.add(new AltosEepromFlight(flight, start, end)); } catch (ParseException pe) { System.out.printf("Parse error %s\n", pe.toString()); } } @@ -115,4 +115,4 @@ public class AltosEepromList extends ArrayList { link.flush_output(); } } -} \ No newline at end of file +} diff --git a/altoslib/AltosEepromLog.java b/altoslib/AltosEepromLog.java index 8d1f3fc4..ba722b89 100644 --- a/altoslib/AltosEepromLog.java +++ b/altoslib/AltosEepromLog.java @@ -18,6 +18,7 @@ package org.altusmetrum.altoslib_12; +import java.io.*; import java.text.*; import java.util.concurrent.*; @@ -32,7 +33,15 @@ public class AltosEepromLog { public int start_block; public int end_block; - public boolean selected; + public boolean download_selected; + public boolean delete_selected; + public boolean graph_selected; + + public File file; + + public void set_file(File file) { + this.file = file; + } public AltosEepromLog(AltosConfigData config_data, AltosLink link, @@ -50,8 +59,11 @@ public class AltosEepromLog { serial = config_data.serial; /* - * Select all flights for download + * Select all flights for download and graph, but not + * for delete */ - selected = true; + download_selected = true; + delete_selected = false; + graph_selected = true; } } diff --git a/altoslib/AltosEepromMonitor.java b/altoslib/AltosEepromMonitor.java index a99ec687..11144a3a 100644 --- a/altoslib/AltosEepromMonitor.java +++ b/altoslib/AltosEepromMonitor.java @@ -18,6 +18,8 @@ package org.altusmetrum.altoslib_12; +import java.io.*; + public interface AltosEepromMonitor { public void set_block(int in_block); @@ -28,8 +30,6 @@ public interface AltosEepromMonitor { public void set_flight(int in_flight); - public void set_filename(String in_file); - public void set_thread(Thread eeprom_thread); final static int INFO_MESSAGE = 0; @@ -38,6 +38,8 @@ public interface AltosEepromMonitor { public void show_message(String message, String title, int message_type); + public Boolean check_overwrite(File file); + public void start(); public void done(boolean success); diff --git a/altoslib/AltosEepromRecord.java b/altoslib/AltosEepromRecord.java index 12519e6b..43e8ea4d 100644 --- a/altoslib/AltosEepromRecord.java +++ b/altoslib/AltosEepromRecord.java @@ -50,8 +50,22 @@ public abstract class AltosEepromRecord implements Comparable return data8(i) | (data8(i+1) << 8) | (data8(i+2) << 16) | (data8(i+3) << 24); } + public boolean empty(int s) { + for (int i = 0; i < length; i++) + if (eeprom.data8(s + i) != 0xff) + return false; + return true; + } + public boolean valid(int s) { - return AltosConvert.checksum(eeprom.data, s, length) == 0; + int ck = AltosConvert.checksum(eeprom.data, s, length); + + if (ck != 0) { + ++eeprom.errors; + System.out.printf("invalid checksum 0x%x at 0x%x\n", ck, s); + return false; + } + return true; } public boolean valid() { @@ -100,25 +114,18 @@ public abstract class AltosEepromRecord implements Comparable int s = start + length; while (s + length <= eeprom.data.size()) { - if (valid(s)) + if (!empty(s) && valid(s)) return s; s += length; } return -1; } - public boolean hasNext() { - return next_start() >= 0; - } - public abstract AltosEepromRecord next(); public AltosEepromRecord(AltosEeprom eeprom, int start, int length) { this.eeprom = eeprom; this.start = start; this.length = length; - - while (start + length < eeprom.data.size() && !valid()) - start += length; } } diff --git a/altoslib/AltosEepromRecordSet.java b/altoslib/AltosEepromRecordSet.java index d91ae3ac..82a5ea2a 100644 --- a/altoslib/AltosEepromRecordSet.java +++ b/altoslib/AltosEepromRecordSet.java @@ -97,7 +97,7 @@ public class AltosEepromRecordSet implements AltosRecordSet { int tick = 0; boolean first = true; - for (;;) { + do { int t = record.tick(); if (first) { @@ -110,10 +110,8 @@ public class AltosEepromRecordSet implements AltosRecordSet { } record.wide_tick = tick; ordered.add(record); - if (!record.hasNext()) - break; record = record.next(); - } + } while (record != null); } public AltosEepromRecordSet(InputStream input) throws IOException { diff --git a/altoslib/AltosFile.java b/altoslib/AltosFile.java index 69f779c1..6f98b87a 100644 --- a/altoslib/AltosFile.java +++ b/altoslib/AltosFile.java @@ -36,10 +36,23 @@ public class AltosFile extends File { return String.format("-via-%04d", receiver); } + static private String label(int flight) { + if (flight < 0) + return "corrupt"; + else + return "flight"; + } + + static private int flight(int flight) { + if (flight < 0) + return -flight; + return flight; + } + public AltosFile(int year, int month, int day, int serial, int flight, int receiver, String extension) { super (AltosPreferences.logdir(), - String.format("%04d-%02d-%02d-serial-%s-flight-%s%s.%s", - year, month, day, number(serial), number(flight), receiver(receiver), extension)); + String.format("%04d-%02d-%02d-serial-%s-%s-%s%s.%s", + year, month, day, number(serial), label(flight), number(flight(flight)), receiver(receiver), extension)); } public AltosFile(int year, int month, int day, int serial, int flight, String extension) { diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index bc8eaa71..02e49a94 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -26,7 +26,7 @@ import java.util.concurrent.*; import org.altusmetrum.altoslib_12.*; import org.altusmetrum.altosuilib_12.*; -public class AltosUI extends AltosUIFrame { +public class AltosUI extends AltosUIFrame implements AltosEepromGrapher { public AltosVoice voice = new AltosVoice(); public static boolean load_library(Frame frame) { @@ -320,8 +320,17 @@ public class AltosUI extends AltosUIFrame { /* Connect to TeleMetrum, either directly or through * a TeleDongle over the packet link */ + + public void graph_flights(AltosEepromList flights) { + for (AltosEepromLog flight : flights) { + if (flight.graph_selected && flight.file != null) { + process_graph(flight.file); + } + } + } + private void SaveFlightData() { - new AltosEepromManage(AltosUI.this, AltosLib.product_any); + new AltosEepromManage(this, this, AltosLib.product_any); } private static AltosFlightSeries make_series(AltosRecordSet set) { diff --git a/altosuilib/AltosEepromDelete.java b/altosuilib/AltosEepromDelete.java index 87e80a51..d7dde6df 100644 --- a/altosuilib/AltosEepromDelete.java +++ b/altosuilib/AltosEepromDelete.java @@ -84,7 +84,7 @@ public class AltosEepromDelete implements Runnable { serial_line.start_remote(); for (AltosEepromLog log : flights) { - if (log.selected) { + if (log.delete_selected) { DeleteLog(log); } } diff --git a/altosuilib/AltosEepromManage.java b/altosuilib/AltosEepromManage.java index 93827139..1adf1f0a 100644 --- a/altosuilib/AltosEepromManage.java +++ b/altosuilib/AltosEepromManage.java @@ -33,6 +33,7 @@ public class AltosEepromManage implements ActionListener { AltosEepromList flights; AltosEepromDownload download; AltosEepromDelete delete; + AltosEepromGrapher grapher; public void finish() { if (serial_line != null) { @@ -48,7 +49,7 @@ public class AltosEepromManage implements ActionListener { private int countDeletedFlights() { int count = 0; for (AltosEepromLog flight : flights) { - if (flight.selected) + if (flight.delete_selected) count++; } return count; @@ -58,7 +59,7 @@ public class AltosEepromManage implements ActionListener { String result = ""; for (AltosEepromLog flight : flights) { - if (flight.selected) { + if (flight.delete_selected) { if (result.equals("")) result = String.format("%d", flight.flight); else @@ -68,38 +69,49 @@ public class AltosEepromManage implements ActionListener { return result; } - public boolean download_done() { - AltosEepromSelect select = new AltosEepromSelect(frame, flights, "Delete"); - - if (select.run()) { - boolean any_selected = false; - for (AltosEepromLog flight : flights) - any_selected = any_selected || flight.selected; - if (any_selected) { - delete = new AltosEepromDelete(frame, - serial_line, - remote, - flights); - delete.addActionListener(this); - /* - * Start flight log delete - */ - - delete.start(); - return true; - } + public boolean delete_start() { + + boolean any_selected = false; + for (AltosEepromLog flight : flights) + any_selected = any_selected || flight.delete_selected; + if (any_selected) { + delete = new AltosEepromDelete(frame, + serial_line, + remote, + flights); + delete.addActionListener(this); + /* + * Start flight log delete + */ + + delete.start(); + return true; } return false; } + public void graph_start() { + boolean any_selected = false; + for (AltosEepromLog flight : flights) { + if (!flight.download_selected) + flight.graph_selected = false; + any_selected = any_selected || flight.graph_selected; + } + if (any_selected && grapher != null) + grapher.graph_flights(flights); + } + public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); boolean success = e.getID() != 0; boolean running = false; if (cmd.equals("download")) { - if (success) - running = download_done(); + if (success) { + running = delete_start(); + if (!running) + graph_start(); + } } else if (cmd.equals("delete")) { if (success) { JOptionPane.showMessageDialog(frame, @@ -108,6 +120,7 @@ public class AltosEepromManage implements ActionListener { showDeletedFlights()), serial_line.device.toShortString(), JOptionPane.INFORMATION_MESSAGE); + graph_start(); } } if (!running) @@ -126,12 +139,12 @@ public class AltosEepromManage implements ActionListener { serial_line.device.toShortString(), JOptionPane.INFORMATION_MESSAGE); } else { - AltosEepromSelect select = new AltosEepromSelect(frame, flights, "Download"); + AltosEepromSelect select = new AltosEepromSelect(frame, flights, grapher != null); if (select.run()) { boolean any_selected = false; for (AltosEepromLog flight : flights) - any_selected = any_selected || flight.selected; + any_selected = any_selected || flight.download_selected; if (any_selected) { AltosEepromMonitorUI monitor = new AltosEepromMonitorUI(frame); monitor.addActionListener(this); @@ -147,7 +160,9 @@ public class AltosEepromManage implements ActionListener { download.start(); running = true; } else { - running = download_done(); + running = delete_start(); + if (!running) + graph_start(); } } } @@ -205,11 +220,12 @@ public class AltosEepromManage implements ActionListener { } } - public AltosEepromManage(JFrame given_frame, int product) { + public AltosEepromManage(JFrame given_frame, AltosEepromGrapher grapher, int product) { //boolean running = false; frame = given_frame; + this.grapher = grapher; device = AltosDeviceUIDialog.show(frame, product); remote = false; diff --git a/altosuilib/AltosEepromMonitorUI.java b/altosuilib/AltosEepromMonitorUI.java index 3427fe0f..fc6c95c6 100644 --- a/altosuilib/AltosEepromMonitorUI.java +++ b/altosuilib/AltosEepromMonitorUI.java @@ -18,11 +18,18 @@ package org.altusmetrum.altosuilib_12; +import java.io.*; +import java.util.*; +import java.util.concurrent.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import org.altusmetrum.altoslib_12.*; + class result_holder { + static int result; + } + public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMonitor { JFrame owner; Container pane; @@ -32,7 +39,6 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo JLabel file_label; JLabel serial_value; JLabel flight_value; - JLabel file_value; JButton cancel; JProgressBar pbar; ActionListener listener; @@ -42,6 +48,8 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo public AltosEepromMonitorUI(JFrame owner) { super (owner, "Download Flight Data", false); + setMinimumSize(new Dimension(600, 100)); + this.owner = owner; GridBagConstraints c; @@ -85,30 +93,11 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo flight_value = new JLabel(""); pane.add(flight_value, c); - c = new GridBagConstraints(); - c.fill = GridBagConstraints.NONE; - c.gridx = 0; c.gridy = 2; - c.anchor = GridBagConstraints.LINE_START; - c.insets = il; - file_label = new JLabel("File:"); - pane.add(file_label, c); - - c = new GridBagConstraints(); - c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1; - c.gridx = 1; c.gridy = 2; - c.anchor = GridBagConstraints.LINE_START; - c.insets = ir; - file_value = new JLabel(""); - pane.add(file_value, c); - pbar = new JProgressBar(); pbar.setMinimum(0); pbar.setMaximum(progress_max); - pbar.setValue(0); - pbar.setString("startup"); pbar.setStringPainted(true); - pbar.setPreferredSize(new Dimension(600, 20)); + set_block_internal(0); c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.CENTER; @@ -118,7 +107,6 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo c.insets = ib; pane.add(pbar, c); - cancel = new JButton("Cancel"); c = new GridBagConstraints(); c.fill = GridBagConstraints.NONE; @@ -141,8 +129,9 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo final Thread eeprom_thread = in_eeprom_thread; cancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - if (eeprom_thread != null) + if (eeprom_thread != null) { eeprom_thread.interrupt(); + } } }); } @@ -162,6 +151,7 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo s = String.format("block %d of %d", block, max_block); pbar.setString(s); + pbar.setStringPainted(true); pbar.setValue((int) (pos * progress_max)); } @@ -216,23 +206,6 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo SwingUtilities.invokeLater(r); } - private void set_filename_internal(String filename) { - file_value.setText(String.format("%s", filename)); - } - - public void set_filename(String in_filename) { - final String filename = in_filename; - Runnable r = new Runnable() { - public void run() { - try { - set_filename_internal(filename); - } catch (Exception ex) { - } - } - }; - SwingUtilities.invokeLater(r); - } - private void done_internal(boolean success) { listener.actionPerformed(new ActionEvent(this, success ? 1 : 0, @@ -258,7 +231,6 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo set_max(1); set_block_internal(0); set_flight_internal(0); - set_filename_internal(""); } public void reset() { @@ -293,6 +265,29 @@ public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMo joption_message_type); } + public Boolean check_overwrite(File in_file) { + final Semaphore check_overwrite_done = new Semaphore(0); + final File file = in_file; + final result_holder result = new result_holder(); + + Runnable r = new Runnable() { + public void run() { + result_holder.result = JOptionPane.showConfirmDialog(owner, + String.format("\"%s\" already exists, overwrite?", + file.toString()), + "Overwrite Existing File?", + JOptionPane.YES_NO_OPTION); + check_overwrite_done.release(); + } + }; + + SwingUtilities.invokeLater(r); + try { + check_overwrite_done.acquire(); + } catch (Exception e) {} + return result_holder.result == JOptionPane.YES_OPTION; + } + public void show_message(String in_message, String in_title, int in_message_type) { final String message = in_message; final String title = in_title; diff --git a/altosuilib/AltosEepromSelect.java b/altosuilib/AltosEepromSelect.java index 0c890c8b..f88f2bd6 100644 --- a/altosuilib/AltosEepromSelect.java +++ b/altosuilib/AltosEepromSelect.java @@ -27,23 +27,35 @@ import org.altusmetrum.altoslib_12.*; class AltosEepromItem implements ActionListener { AltosEepromLog log; JLabel label; - JCheckBox action; + JCheckBox download; JCheckBox delete; + JCheckBox graph; public void actionPerformed(ActionEvent e) { - log.selected = action.isSelected(); + log.download_selected = download.isSelected(); + log.delete_selected = delete.isSelected(); + log.graph_selected = graph.isSelected(); } public AltosEepromItem(AltosEepromLog in_log) { log = in_log; String text; - text = String.format("Flight #%02d", log.flight); + if (log.flight >= 0) + text = String.format("Flight #%02d", log.flight); + else + text = String.format("Corrupt #%02d", -log.flight); label = new JLabel(text); - action = new JCheckBox("", log.selected); - action.addActionListener(this); + download = new JCheckBox("", log.download_selected); + download.addActionListener(this); + + delete = new JCheckBox("", log.delete_selected); + delete.addActionListener(this); + + graph = new JCheckBox("", log.graph_selected); + graph.addActionListener(this); } } @@ -72,7 +84,7 @@ public class AltosEepromSelect extends AltosUIDialog implements ActionListener { public AltosEepromSelect (JFrame in_frame, AltosEepromList flights, - String action) { + boolean has_graph) { super(in_frame, String.format("Flight list for serial %d", flights.config_data.serial), true); frame = in_frame; @@ -81,7 +93,7 @@ public class AltosEepromSelect extends AltosUIDialog implements ActionListener { Container contentPane = getContentPane(); /* First, we create a pane containing the dialog's header/title */ - JLabel selectLabel = new JLabel(String.format ("Select flights to %s", action), SwingConstants.CENTER); + JLabel selectLabel = new JLabel(String.format ("Select flights"), SwingConstants.CENTER); JPanel labelPane = new JPanel(); labelPane.setLayout(new BoxLayout(labelPane, BoxLayout.X_AXIS)); @@ -118,9 +130,31 @@ public class AltosEepromSelect extends AltosUIDialog implements ActionListener { c.weightx = 0.5; c.anchor = GridBagConstraints.CENTER; c.insets = i; - JLabel downloadHeaderLabel = new JLabel(action); + JLabel downloadHeaderLabel = new JLabel("Download"); flightPane.add(downloadHeaderLabel, c); + /* Delete Header */ + c = new GridBagConstraints(); + c.gridx = 2; c.gridy = 0; + c.fill = GridBagConstraints.NONE; + c.weightx = 0.5; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + JLabel deleteHeaderLabel = new JLabel("Delete"); + flightPane.add(deleteHeaderLabel, c); + + if (has_graph) { + /* Graph Header */ + c = new GridBagConstraints(); + c.gridx = 3; c.gridy = 0; + c.fill = GridBagConstraints.NONE; + c.weightx = 0.5; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + JLabel graphHeaderLabel = new JLabel("Graph"); + flightPane.add(graphHeaderLabel, c); + } + /* Add the flights to the GridBag */ AltosEepromItem item; int itemNumber = 1; @@ -139,14 +173,34 @@ public class AltosEepromSelect extends AltosUIDialog implements ActionListener { c.insets = i; flightPane.add(item.label, c); - /* Add action checkbox for the flight */ + /* Add download checkbox for the flight */ c = new GridBagConstraints(); c.gridx = 1; c.gridy = itemNumber; c.fill = GridBagConstraints.NONE; c.weightx = 0.5; c.anchor = GridBagConstraints.CENTER; c.insets = i; - flightPane.add(item.action, c); + flightPane.add(item.download, c); + + /* Add delete checkbox for the flight */ + c = new GridBagConstraints(); + c.gridx = 2; c.gridy = itemNumber; + c.fill = GridBagConstraints.NONE; + c.weightx = 0.5; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + flightPane.add(item.delete, c); + + if (has_graph) { + /* Add graph checkbox for the flight */ + c = new GridBagConstraints(); + c.gridx = 3; c.gridy = itemNumber; + c.fill = GridBagConstraints.NONE; + c.weightx = 0.5; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + flightPane.add(item.graph, c); + } itemNumber++; } diff --git a/telegps/TeleGPS.java b/telegps/TeleGPS.java index 3646f000..1433c9e1 100644 --- a/telegps/TeleGPS.java +++ b/telegps/TeleGPS.java @@ -30,7 +30,7 @@ import org.altusmetrum.altosuilib_12.*; public class TeleGPS extends AltosUIFrame - implements AltosFlightDisplay, AltosFontListener, AltosUnitsListener, ActionListener + implements AltosFlightDisplay, AltosFontListener, AltosUnitsListener, ActionListener, AltosEepromGrapher { static String[] telegps_icon_names = { @@ -280,7 +280,7 @@ public class TeleGPS } void download(){ - new AltosEepromManage(this, AltosLib.product_telegps); + new AltosEepromManage(this, this, AltosLib.product_telegps); } void configure() { @@ -316,6 +316,21 @@ public class TeleGPS } } + public void graph_flights(AltosEepromList list) { + for (AltosEepromLog log : list) { + if (log.file != null) { + AltosRecordSet set = record_set(log.file); + if (set != null) { + try { + new TeleGPSGraphUI(set, log.file); + } catch (InterruptedException ie) { + } catch (IOException ie) { + } + } + } + } + } + void flash() { AltosFlashUI.show(this); } -- cgit v1.2.3