From 60666630789b6925d7e16160ebdc88ccd23f51de Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Mon, 18 Sep 2017 20:43:14 -0600 Subject: be more aggressive about removing and ignoring .mdwn files --- telegps/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'telegps') diff --git a/telegps/Makefile.am b/telegps/Makefile.am index a1c4a0a1..9dd2ceac 100644 --- a/telegps/Makefile.am +++ b/telegps/Makefile.am @@ -128,7 +128,7 @@ clean-local: altoslib_*.jar altosuilib_*.jar \ $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(FREETTS_CLASS) $(LIBALTOS) Manifest.txt Manifest-fat.txt \ telegps telegps-test telegps-jdb macosx linux windows telegps-windows.log \ - telegps-windows.nsi *.desktop $(MDWN) + telegps-windows.nsi *.desktop *.mdwn EXTRA_DIST = $(desktop_file).in -- cgit v1.2.3 From 98dc29a7a964f8d653b73989c6751695d168844c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 2 Oct 2017 19:33:37 -0700 Subject: altoslib: Add user-selectable filter width for data smoothing Also switch smoothing window to Kaiser and change default accel filter width to 1 second instead of 4 seconds. Now users can play with the filter and see what it does. Signed-off-by: Keith Packard --- altoslib/AltosFlightSeries.java | 90 +++++++++++++++++++++++++---------- altoslib/AltosTimeSeries.java | 42 ++++++++++++++-- altoslib/Makefile.am | 1 + altosui/AltosGraphUI.java | 23 +++++++-- altosuilib/AltosFlightStatsTable.java | 84 ++++++++++++++++++++++++-------- altosuilib/AltosGraph.java | 8 +--- altosuilib/AltosUIEnable.java | 82 ++++++++++++++++++++++++++++++- altosuilib/AltosUIGraph.java | 4 ++ altosuilib/AltosUITimeSeries.java | 3 +- micropeak/MicroPeak.java | 23 ++++++++- telegps/TeleGPSGraphUI.java | 26 ++++++++-- 11 files changed, 320 insertions(+), 66 deletions(-) (limited to 'telegps') diff --git a/altoslib/AltosFlightSeries.java b/altoslib/AltosFlightSeries.java index ab7943b3..02bf64ff 100644 --- a/altoslib/AltosFlightSeries.java +++ b/altoslib/AltosFlightSeries.java @@ -21,7 +21,7 @@ public class AltosFlightSeries extends AltosDataListener { public ArrayList series = new ArrayList(); public double speed_filter_width = 4.0; - public double accel_filter_width = 4.0; + public double accel_filter_width = 1.0; public int[] indices() { int[] indices = new int[series.size()]; @@ -160,6 +160,7 @@ public class AltosFlightSeries extends AltosDataListener { } public AltosTimeSeries accel_series; + public boolean accel_computed; public static final String accel_name = "Accel"; @@ -174,17 +175,44 @@ public class AltosFlightSeries extends AltosDataListener { accel_series = add_series(accel_name, AltosConvert.accel); accel_series.add(time(), acceleration); + accel_computed = false; } - private void compute_accel() { - if (accel_series != null) - return; + private AltosTimeSeries compute_accel() { + AltosTimeSeries new_accel_series = null; if (speed_series != null) { - AltosTimeSeries temp_series = make_series(speed_name, AltosConvert.speed); - speed_series.filter(temp_series, accel_filter_width); - accel_series = add_series(accel_name, AltosConvert.accel); - temp_series.differentiate(accel_series); + AltosTimeSeries temp_series; + if (accel_filter_width > 0) { + temp_series = make_series(speed_name, AltosConvert.speed); + speed_series.filter(temp_series, accel_filter_width); + } else + temp_series = speed_series; + + new_accel_series = make_series(accel_name, AltosConvert.accel); + temp_series.differentiate(new_accel_series); + } + return new_accel_series; + } + + public void set_filter(double speed_filter, double accel_filter) { + this.speed_filter_width = speed_filter; + this.accel_filter_width = accel_filter; + + AltosTimeSeries new_speed_series = compute_speed(); + + if (new_speed_series != null) { + speed_series.erase_values(); + for (AltosTimeValue tv : new_speed_series) + speed_series.add(tv); + } + if (accel_computed) { + AltosTimeSeries new_accel_series = compute_accel(); + if (new_accel_series != null) { + accel_series.erase_values(); + for (AltosTimeValue tv : new_accel_series) + accel_series.add(tv); + } } } @@ -268,21 +296,24 @@ public class AltosFlightSeries extends AltosDataListener { public static final String speed_name = "Speed"; - private void compute_speed() { - if (speed_series != null) - return; - + private AltosTimeSeries compute_speed() { + AltosTimeSeries new_speed_series = null; AltosTimeSeries alt_speed_series = null; AltosTimeSeries accel_speed_series = null; if (altitude_series != null) { - AltosTimeSeries temp_series = make_series(altitude_name, AltosConvert.height); - altitude_series.filter(temp_series, speed_filter_width); + AltosTimeSeries temp_series; + + if (speed_filter_width > 0) { + temp_series = make_series(speed_name, AltosConvert.height); + altitude_series.filter(temp_series, speed_filter_width); + } else + temp_series = altitude_series; alt_speed_series = make_series(speed_name, AltosConvert.speed); temp_series.differentiate(alt_speed_series); } - if (accel_series != null) { + if (accel_series != null && !accel_computed) { if (orient_series != null) { vert_accel_series = add_series(vert_accel_name, AltosConvert.accel); @@ -318,26 +349,25 @@ public class AltosFlightSeries extends AltosDataListener { } } if (apogee_time == AltosLib.MISSING) { - speed_series = alt_speed_series; + new_speed_series = alt_speed_series; } else { - speed_series = make_series(speed_name, AltosConvert.speed); + new_speed_series = make_series(speed_name, AltosConvert.speed); for (AltosTimeValue d : accel_speed_series) { if (d.time <= apogee_time) - speed_series.add(d); + new_speed_series.add(d); } for (AltosTimeValue d : alt_speed_series) { if (d.time > apogee_time) - speed_series.add(d); + new_speed_series.add(d); } } } else if (alt_speed_series != null) { - speed_series = alt_speed_series; + new_speed_series = alt_speed_series; } else if (accel_speed_series != null) { - speed_series = accel_speed_series; + new_speed_series = accel_speed_series; } - if (speed_series != null) - add_series(speed_series); + return new_speed_series; } public AltosTimeSeries orient_series; @@ -690,8 +720,18 @@ public class AltosFlightSeries extends AltosDataListener { public void finish() { compute_orient(); - compute_speed(); - compute_accel(); + if (speed_series == null) { + speed_series = compute_speed(); + if (speed_series != null) + add_series(speed_series); + } + if (accel_series == null) { + accel_series = compute_accel(); + if (accel_series != null) { + add_series(accel_series); + accel_computed = true; + } + } compute_height(); } diff --git a/altoslib/AltosTimeSeries.java b/altoslib/AltosTimeSeries.java index 9f3b4d80..7208c176 100644 --- a/altoslib/AltosTimeSeries.java +++ b/altoslib/AltosTimeSeries.java @@ -20,15 +20,30 @@ public class AltosTimeSeries implements Iterable, Comparable values; + boolean data_changed; public int compareTo(AltosTimeSeries other) { return label.compareTo(other.label); } public void add(AltosTimeValue tv) { + data_changed = true; values.add(tv); } + public void erase_values() { + data_changed = true; + this.values = new ArrayList(); + } + + public void clear_changed() { + data_changed = false; + } + +// public boolean changed() { +// return data_changed; +// } + public void add(double time, double value) { add(new AltosTimeValue(time, value)); } @@ -264,14 +279,35 @@ public class AltosTimeSeries implements Iterable, Comparable 0); + return s; + } + + private static double kaiser(double n, double m, double beta) { + double alpha = m / 2; + double t = (n - alpha) / alpha; + + if (t > 1) + t = 1; + double k = i0 (beta * Math.sqrt (1 - t*t)) / i0(beta); + return k; + } + + private double filter_coeff(double dist, double width) { + return kaiser(dist + width/2.0, width, 2 * Math.PI); } public AltosTimeSeries filter(AltosTimeSeries f, double width) { + double half_width = width/2; + int half_point = values.size() / 2; for (int i = 0; i < values.size(); i++) { double center_time = values.get(i).time; double left_time = center_time - half_width; diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 08af9496..2a1cb8e4 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -55,6 +55,7 @@ altoslib_JAVA = \ AltosEepromList.java \ AltosEepromLog.java \ AltosFile.java \ + AltosFilterListener.java \ AltosFlash.java \ AltosFlashListener.java \ AltosDataListener.java \ diff --git a/altosui/AltosGraphUI.java b/altosui/AltosGraphUI.java index 042f9277..f387ed9b 100644 --- a/altosui/AltosGraphUI.java +++ b/altosui/AltosGraphUI.java @@ -31,7 +31,7 @@ import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.ui.RefineryUtilities; -public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, AltosUnitsListener +public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, AltosUnitsListener, AltosFilterListener { JTabbedPane pane; AltosGraph graph; @@ -82,6 +82,23 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt enable.units_changed(imperial_units); } + AltosUIFlightSeries flight_series; + + public void filter_changed(double speed_filter, double accel_filter) { + flight_series.set_filter(speed_filter, accel_filter); + graph.filter_changed(); + stats = new AltosFlightStats(flight_series); + statsTable.filter_changed(stats); + } + + public double speed_filter() { + return flight_series.speed_filter_width; + } + + public double accel_filter() { + return flight_series.accel_filter_width; + } + AltosGraphUI(AltosRecordSet set, File file) throws InterruptedException, IOException { super(file.getName()); AltosCalData cal_data = set.cal_data(); @@ -89,9 +106,9 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt pane = new JTabbedPane(); - enable = new AltosUIEnable(); + flight_series = new AltosUIFlightSeries(cal_data); - AltosUIFlightSeries flight_series = new AltosUIFlightSeries(cal_data); + enable = new AltosUIEnable(this); set.capture_series(flight_series); diff --git a/altosuilib/AltosFlightStatsTable.java b/altosuilib/AltosFlightStatsTable.java index 415c0244..8f7e9bff 100644 --- a/altosuilib/AltosFlightStatsTable.java +++ b/altosuilib/AltosFlightStatsTable.java @@ -38,6 +38,11 @@ public class AltosFlightStatsTable extends JComponent implements AltosFontListen value[i].setFont(AltosUILib.value_font); } + public void set(String ... values) { + for (int j = 0; j < values.length; j++) + value[j].setText(values[j]); + } + public FlightStat(GridBagLayout layout, int y, String label_text, String ... values) { GridBagConstraints c = new GridBagConstraints(); c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad); @@ -87,6 +92,43 @@ public class AltosFlightStatsTable extends JComponent implements AltosFontListen return String.format("%s %4d° %9.6f'", h, deg, min); } + private FlightStat max_height_stat; + private FlightStat max_speed_stat; + private FlightStat max_accel_stat; + private FlightStat boost_accel_stat; + private FlightStat drogue_descent_stat; + private FlightStat main_descent_stat; + + public void set_values(AltosFlightStats stats) { + if (max_height_stat != null && stats.max_height != AltosLib.MISSING) { + max_height_stat.set(String.format("%6.1f m", stats.max_height), + String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.max_height))); + } + if (max_speed_stat != null && stats.max_speed != AltosLib.MISSING) { + max_speed_stat.set(String.format("%6.1f m/s", stats.max_speed), + String.format("%5.0f fps", AltosConvert.mps_to_fps(stats.max_speed)), + String.format("Mach %4.1f", AltosConvert.meters_to_mach(stats.max_speed))); + } + if (max_accel_stat != null && stats.max_acceleration != AltosLib.MISSING) { + max_accel_stat.set(String.format("%6.1f m/s²", stats.max_acceleration), + String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.max_acceleration)), + String.format("%6.2f G", AltosConvert.meters_to_g(stats.max_acceleration))); + } + if (boost_accel_stat != null && stats.state_accel[AltosLib.ao_flight_boost] != AltosLib.MISSING) { + boost_accel_stat.set(String.format("%6.1f m/s²", stats.state_accel[AltosLib.ao_flight_boost]), + String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.state_accel[AltosLib.ao_flight_boost])), + String.format("%6.2f G", AltosConvert.meters_to_g(stats.state_accel[AltosLib.ao_flight_boost]))); + } + if (drogue_descent_stat != null && stats.state_speed[AltosLib.ao_flight_drogue] != AltosLib.MISSING) { + drogue_descent_stat.set(String.format("%6.1f m/s", -stats.state_speed[AltosLib.ao_flight_drogue]), + String.format("%5.0f ft/s", -AltosConvert.meters_to_feet(stats.state_speed[AltosLib.ao_flight_drogue]))); + } + if (main_descent_stat != null && stats.state_speed[AltosLib.ao_flight_main] != AltosLib.MISSING) { + main_descent_stat.set(String.format("%6.1f m/s", -stats.state_speed[AltosLib.ao_flight_main]), + String.format("%5.0f ft/s", -AltosConvert.meters_to_feet(stats.state_speed[AltosLib.ao_flight_main]))); + } + } + public void set_stats(AltosFlightStats stats) { int y = 0; if (stats.serial != AltosLib.MISSING) { @@ -113,9 +155,9 @@ public class AltosFlightStatsTable extends JComponent implements AltosFontListen String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); } if (stats.max_height != AltosLib.MISSING) { - new FlightStat(layout, y++, "Maximum height", - String.format("%6.1f m", stats.max_height), - String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.max_height))); + max_height_stat = new FlightStat(layout, y++, "Maximum height", + String.format("%6.1f m", stats.max_height), + String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.max_height))); } if (stats.max_gps_height != AltosLib.MISSING) { new FlightStat(layout, y++, "Maximum GPS height", @@ -123,21 +165,21 @@ public class AltosFlightStatsTable extends JComponent implements AltosFontListen String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.max_gps_height))); } if (stats.max_speed != AltosLib.MISSING) { - new FlightStat(layout, y++, "Maximum speed", - String.format("%6.1f m/s", stats.max_speed), - String.format("%5.0f fps", AltosConvert.mps_to_fps(stats.max_speed)), - String.format("Mach %4.1f", AltosConvert.meters_to_mach(stats.max_speed))); + max_speed_stat = new FlightStat(layout, y++, "Maximum speed", + String.format("%6.1f m/s", stats.max_speed), + String.format("%5.0f fps", AltosConvert.mps_to_fps(stats.max_speed)), + String.format("Mach %4.1f", AltosConvert.meters_to_mach(stats.max_speed))); } if (stats.max_acceleration != AltosLib.MISSING) - new FlightStat(layout, y++, "Maximum boost acceleration", - String.format("%6.1f m/s²", stats.max_acceleration), - String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.max_acceleration)), - String.format("%6.2f G", AltosConvert.meters_to_g(stats.max_acceleration))); + max_accel_stat = new FlightStat(layout, y++, "Maximum boost acceleration", + String.format("%6.1f m/s²", stats.max_acceleration), + String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.max_acceleration)), + String.format("%6.2f G", AltosConvert.meters_to_g(stats.max_acceleration))); if (stats.state_accel[AltosLib.ao_flight_boost] != AltosLib.MISSING) - new FlightStat(layout, y++, "Average boost acceleration", - String.format("%6.1f m/s²", stats.state_accel[AltosLib.ao_flight_boost]), - String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.state_accel[AltosLib.ao_flight_boost])), - String.format("%6.2f G", AltosConvert.meters_to_g(stats.state_accel[AltosLib.ao_flight_boost]))); + boost_accel_stat = new FlightStat(layout, y++, "Average boost acceleration", + String.format("%6.1f m/s²", stats.state_accel[AltosLib.ao_flight_boost]), + String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.state_accel[AltosLib.ao_flight_boost])), + String.format("%6.2f G", AltosConvert.meters_to_g(stats.state_accel[AltosLib.ao_flight_boost]))); if (stats.state_time[AltosLib.ao_flight_boost] != 0 || stats.state_time[AltosLib.ao_flight_fast] != 0 || stats.state_time[AltosLib.ao_flight_coast] != 0) { double boost_time = stats.state_time[AltosLib.ao_flight_boost]; @@ -167,14 +209,14 @@ public class AltosFlightStatsTable extends JComponent implements AltosFontListen label = "Descent rate"; else label = "Drogue descent rate"; - new FlightStat(layout, y++, label, + drogue_descent_stat = new FlightStat(layout, y++, label, String.format("%6.1f m/s", -stats.state_speed[AltosLib.ao_flight_drogue]), String.format("%5.0f ft/s", -AltosConvert.meters_to_feet(stats.state_speed[AltosLib.ao_flight_drogue]))); } if (stats.state_speed[AltosLib.ao_flight_main] != AltosLib.MISSING) - new FlightStat(layout, y++, "Main descent rate", - String.format("%6.1f m/s", -stats.state_speed[AltosLib.ao_flight_main]), - String.format("%5.0f ft/s", -AltosConvert.meters_to_feet(stats.state_speed[AltosLib.ao_flight_main]))); + main_descent_stat = new FlightStat(layout, y++, "Main descent rate", + String.format("%6.1f m/s", -stats.state_speed[AltosLib.ao_flight_main]), + String.format("%5.0f ft/s", -AltosConvert.meters_to_feet(stats.state_speed[AltosLib.ao_flight_main]))); if (stats.state_time[AltosLib.ao_flight_drogue] != 0 || stats.state_time[AltosLib.ao_flight_main] != 0) { double drogue_duration = stats.state_time[AltosLib.ao_flight_drogue]; double main_duration = stats.state_time[AltosLib.ao_flight_main]; @@ -210,6 +252,10 @@ public class AltosFlightStatsTable extends JComponent implements AltosFontListen AltosUIPreferences.unregister_font_listener(this); } + public void filter_changed(AltosFlightStats stats) { + set_values(stats); + } + public AltosFlightStatsTable() { layout = new GridBagLayout(); diff --git a/altosuilib/AltosGraph.java b/altosuilib/AltosGraph.java index 5df95233..3f610285 100644 --- a/altosuilib/AltosGraph.java +++ b/altosuilib/AltosGraph.java @@ -92,7 +92,7 @@ public class AltosGraph extends AltosUIGraph { AltosUIAxis gyro_axis, orient_axis, mag_axis; AltosUIAxis course_axis, dop_axis, tick_axis; - if (stats.serial != AltosLib.MISSING && stats.product != null && stats.flight != AltosLib.MISSING) + if (stats != null && stats.serial != AltosLib.MISSING && stats.product != null && stats.flight != AltosLib.MISSING) setName(String.format("%s %d flight %d\n", stats.product, stats.serial, stats.flight)); height_axis = newAxis("Height", AltosConvert.height, height_color); @@ -327,12 +327,6 @@ public class AltosGraph extends AltosUIGraph { return flight_series.series(cal_data); } - public void set_filter(double filter) { - System.out.printf("filter set to %f\n", filter); - flight_series.set_filter(filter, filter); - units_changed(false); - } - public void set_data(AltosFlightStats stats, AltosUIFlightSeries flight_series) { set_series(setup(stats, flight_series)); } diff --git a/altosuilib/AltosUIEnable.java b/altosuilib/AltosUIEnable.java index 0c23fa8d..4bd07c52 100644 --- a/altosuilib/AltosUIEnable.java +++ b/altosuilib/AltosUIEnable.java @@ -21,6 +21,7 @@ package org.altusmetrum.altosuilib_12; import java.awt.*; import java.awt.event.*; import javax.swing.*; +import javax.swing.event.*; import java.io.*; import java.util.concurrent.*; import java.util.*; @@ -36,12 +37,17 @@ import org.jfree.chart.labels.*; import org.jfree.data.xy.*; import org.jfree.data.*; -public class AltosUIEnable extends Container { +public class AltosUIEnable extends Container implements ChangeListener { Insets il, ir; int y; int x; JCheckBox imperial_units; + JLabel speed_filter_label; + JSlider speed_filter; + JLabel accel_filter_label; + JSlider accel_filter; + AltosFilterListener filter_listener; static final int max_rows = 14; @@ -69,11 +75,15 @@ public class AltosUIEnable extends Container { } } + LinkedList elements = new LinkedList(); + public void add(String name, AltosUIGrapher grapher, boolean enabled) { GraphElement e = new GraphElement(name, grapher, enabled); GridBagConstraints c = new GridBagConstraints(); + elements.add(e); + /* Add element */ c = new GridBagConstraints(); c.gridx = x; c.gridy = y; @@ -90,6 +100,17 @@ public class AltosUIEnable extends Container { } } + public void stateChanged(ChangeEvent e) { + JSlider filter = (JSlider) e.getSource(); + if (!filter.getValueIsAdjusting()) { + double speed_value = (int) speed_filter.getValue() / 1000.0; + double accel_value = (int) accel_filter.getValue() / 1000.0; + if (filter_listener != null) { + filter_listener.filter_changed(speed_value, accel_value); + } + } + } + public void add_units() { /* Imperial units setting */ @@ -109,9 +130,66 @@ public class AltosUIEnable extends Container { c.anchor = GridBagConstraints.LINE_START; c.insets = il; add(imperial_units, c); + + speed_filter_label = new JLabel("Speed Filter(ms)"); + c = new GridBagConstraints(); + c.gridx = 0; c.gridy = 1001; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + add(speed_filter_label, c); + + speed_filter = new JSlider(JSlider.HORIZONTAL, 0, 10000, (int) (filter_listener.speed_filter() * 1000.0)); + Hashtable label_table = new Hashtable(); + for (int i = 0; i <= 10000; i += 5000) { + label_table.put(new Integer(i), new JLabel(String.format("%d", i))); + } + speed_filter.setPaintTicks(true); + speed_filter.setMajorTickSpacing(1000); + speed_filter.setMinorTickSpacing(250); + speed_filter.setLabelTable(label_table); + speed_filter.setPaintTrack(false); + speed_filter.setSnapToTicks(true); + speed_filter.setPaintLabels(true); + speed_filter.addChangeListener(this); + + c = new GridBagConstraints(); + c.gridx = 1; c.gridy = 1001; + c.gridwidth = 1000; c.gridheight = 1; + c.fill = GridBagConstraints.BOTH; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + add(speed_filter, c); + + accel_filter_label = new JLabel("Acceleration Filter(ms)"); + c = new GridBagConstraints(); + c.gridx = 0; c.gridy = 1002; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + add(accel_filter_label, c); + + accel_filter = new JSlider(JSlider.HORIZONTAL, 0, 10000, (int) (filter_listener.accel_filter() * 1000.0)); + accel_filter.setPaintTicks(true); + accel_filter.setMajorTickSpacing(1000); + accel_filter.setMinorTickSpacing(250); + accel_filter.setLabelTable(label_table); + accel_filter.setPaintTrack(false); + accel_filter.setSnapToTicks(true); + accel_filter.setPaintLabels(true); + accel_filter.addChangeListener(this); + + c = new GridBagConstraints(); + c.gridx = 1; c.gridy = 1002; + c.gridwidth = 1000; c.gridheight = 1; + c.fill = GridBagConstraints.BOTH; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + add(accel_filter, c); } - public AltosUIEnable() { + public AltosUIEnable(AltosFilterListener filter_listener) { + this.filter_listener = filter_listener; il = new Insets(4,4,4,4); ir = new Insets(4,4,4,4); x = 0; diff --git a/altosuilib/AltosUIGraph.java b/altosuilib/AltosUIGraph.java index 0caabcfa..efc3d493 100644 --- a/altosuilib/AltosUIGraph.java +++ b/altosuilib/AltosUIGraph.java @@ -95,6 +95,10 @@ public class AltosUIGraph implements AltosUnitsListener { s.set_units(); } + public void filter_changed() { + units_changed(false); + } + public void setName (String name) { chart.setTitle(name); } diff --git a/altosuilib/AltosUITimeSeries.java b/altosuilib/AltosUITimeSeries.java index 08f95ca7..71166064 100644 --- a/altosuilib/AltosUITimeSeries.java +++ b/altosuilib/AltosUITimeSeries.java @@ -89,7 +89,7 @@ public class AltosUITimeSeries extends AltosTimeSeries implements AltosUIGrapher public void fireSeriesChanged() { } - void set_data() { + public void set_data() { if (marker) { if (markers != null) { for (ValueMarker marker : markers) @@ -124,6 +124,7 @@ public class AltosUITimeSeries extends AltosTimeSeries implements AltosUIGrapher } xy_series.setNotify(true); } + clear_changed(); } public void set_units() { diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java index 749d0f64..c6a2a3c9 100644 --- a/micropeak/MicroPeak.java +++ b/micropeak/MicroPeak.java @@ -27,7 +27,7 @@ import java.util.*; import org.altusmetrum.altoslib_12.*; import org.altusmetrum.altosuilib_12.*; -public class MicroPeak extends MicroFrame implements ActionListener, ItemListener { +public class MicroPeak extends MicroFrame implements ActionListener, ItemListener, AltosFilterListener { File filename; AltosGraph graph; @@ -206,6 +206,25 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene Preferences(); } + public void filter_changed(double speed_filter, double accel_filter) { + data.flight_series.set_filter(speed_filter, accel_filter); + graph.filter_changed(); + data.flight_stats = new AltosFlightStats(data.flight_series); + statsTable.filter_changed(data.flight_stats); + } + + public double speed_filter() { + if (data != null && data.flight_series != null) + return data.flight_series.speed_filter_width; + return 4.0; + } + + public double accel_filter() { + if (data != null && data.flight_series != null) + return data.flight_series.accel_filter_width; + return 1.0; + } + public MicroPeak() { ++number_of_windows; @@ -267,7 +286,7 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene } }); - enable = new AltosUIEnable(); + enable = new AltosUIEnable(this); graph = new AltosGraph(enable); statsTable = new AltosFlightStatsTable(); diff --git a/telegps/TeleGPSGraphUI.java b/telegps/TeleGPSGraphUI.java index 9d8c6bf5..c68f2bad 100644 --- a/telegps/TeleGPSGraphUI.java +++ b/telegps/TeleGPSGraphUI.java @@ -34,7 +34,7 @@ import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.ui.RefineryUtilities; -public class TeleGPSGraphUI extends AltosUIFrame implements AltosFontListener, AltosUnitsListener +public class TeleGPSGraphUI extends AltosUIFrame implements AltosFontListener, AltosUnitsListener, AltosFilterListener { JTabbedPane pane; AltosGraph graph; @@ -92,20 +92,38 @@ public class TeleGPSGraphUI extends AltosUIFrame implements AltosFontListener, A enable.units_changed(imperial_units); } + AltosUIFlightSeries flight_series; + + public void filter_changed(double speed_filter, double accel_filter) { + flight_series.set_filter(speed_filter, accel_filter); + graph.filter_changed(); + stats = new AltosFlightStats(flight_series); + statsTable.filter_changed(stats); + } + + public double speed_filter() { + return flight_series.speed_filter_width; + } + + public double accel_filter() { + return flight_series.accel_filter_width; + } + TeleGPSGraphUI(AltosRecordSet set, File file) throws InterruptedException, IOException { super(file.getName()); AltosCalData cal_data = set.cal_data(); - AltosUIFlightSeries flight_series = new AltosUIFlightSeries(cal_data); + flight_series = new AltosUIFlightSeries(cal_data); set.capture_series(flight_series); flight_series.finish(); pane = new JTabbedPane(); - enable = new AltosUIEnable(); + graph = new AltosGraph(enable, stats, flight_series); + stats = new AltosFlightStats(flight_series); - graph = new AltosGraph(enable, stats, flight_series); + enable = new AltosUIEnable(this); statsTable = new AltosFlightStatsTable(stats); -- 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 'telegps') 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