From a55b132668a819cc26478a609cb79bd9190deb9d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 23 Aug 2010 23:01:36 -0700 Subject: altosui: Separate out log file choosing dialog to share with CSV generator This dialog will be shared with the CSV file generating code, so split it out instead of duplicating it. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosUI.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'ao-tools/altosui/AltosUI.java') diff --git a/ao-tools/altosui/AltosUI.java b/ao-tools/altosui/AltosUI.java index 9fd47ea7..64f96cdd 100644 --- a/ao-tools/altosui/AltosUI.java +++ b/ao-tools/altosui/AltosUI.java @@ -42,6 +42,7 @@ import altosui.AltosFlightStatusTableModel; import altosui.AltosFlightInfoTableModel; import altosui.AltosChannelMenu; import altosui.AltosFlashUI; +import altosui.AltosLogfileChooser; import libaltosJNI.*; @@ -529,17 +530,12 @@ public class AltosUI extends JFrame { * Replay a flight from telemetry data */ private void Replay() { - JFileChooser logfile_chooser = new JFileChooser(); + AltosLogfileChooser chooser = new AltosLogfileChooser( + AltosUI.this); - logfile_chooser.setDialogTitle("Select Flight Record File"); - logfile_chooser.setFileFilter(new FileNameExtensionFilter("Flight data file", "eeprom", "telem")); - logfile_chooser.setCurrentDirectory(AltosPreferences.logdir()); - int returnVal = logfile_chooser.showOpenDialog(AltosUI.this); + File file = chooser.runDialog(); - if (returnVal == JFileChooser.APPROVE_OPTION) { - File file = logfile_chooser.getSelectedFile(); - if (file == null) - System.out.println("No file selected?"); + if (file != null) { String filename = file.getName(); try { FileInputStream replay = new FileInputStream(file); -- cgit v1.2.3 From 634a550149e7c344a22a637ba484f115592b1018 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 23 Aug 2010 23:15:05 -0700 Subject: altosui: refactor logfile chooser dialog to share more code Move file opening logic into logfile chooser as it can be shared that way. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosLogfileChooser.java | 32 ++++++++++++++++++++++++++++--- ao-tools/altosui/AltosUI.java | 24 ++++------------------- 2 files changed, 33 insertions(+), 23 deletions(-) (limited to 'ao-tools/altosui/AltosUI.java') diff --git a/ao-tools/altosui/AltosLogfileChooser.java b/ao-tools/altosui/AltosLogfileChooser.java index 72d21fc8..3e9e4892 100644 --- a/ao-tools/altosui/AltosLogfileChooser.java +++ b/ao-tools/altosui/AltosLogfileChooser.java @@ -28,16 +28,42 @@ import java.text.*; import java.util.prefs.*; import altosui.AltosPreferences; +import altosui.AltosReader; +import altosui.AltosEepromReader; +import altosui.AltosTelemetryReader; public class AltosLogfileChooser extends JFileChooser { JFrame frame; + String filename; - public File runDialog() { + public String filename() { + return filename; + } + + public AltosReader runDialog() { int ret; ret = showOpenDialog(frame); - if (ret == APPROVE_OPTION) - return getSelectedFile(); + if (ret == APPROVE_OPTION) { + File file = getSelectedFile(); + if (file == null) + return null; + filename = file.getName(); + try { + FileInputStream in; + + in = new FileInputStream(file); + if (filename.endsWith("eeprom")) + return new AltosEepromReader(in); + else + return new AltosTelemetryReader(in); + } catch (FileNotFoundException fe) { + JOptionPane.showMessageDialog(frame, + filename, + "Cannot open file", + JOptionPane.ERROR_MESSAGE); + } + } return null; } diff --git a/ao-tools/altosui/AltosUI.java b/ao-tools/altosui/AltosUI.java index 64f96cdd..8a4c753f 100644 --- a/ao-tools/altosui/AltosUI.java +++ b/ao-tools/altosui/AltosUI.java @@ -532,26 +532,10 @@ public class AltosUI extends JFrame { private void Replay() { AltosLogfileChooser chooser = new AltosLogfileChooser( AltosUI.this); - - File file = chooser.runDialog(); - - if (file != null) { - String filename = file.getName(); - try { - FileInputStream replay = new FileInputStream(file); - DisplayThread thread; - if (filename.endsWith("eeprom")) - thread = new ReplayEepromThread(replay, filename); - else - thread = new ReplayTelemetryThread(replay, filename); - run_display(thread); - } catch (FileNotFoundException ee) { - JOptionPane.showMessageDialog(AltosUI.this, - filename, - "Cannot open telemetry file", - JOptionPane.ERROR_MESSAGE); - } - } + AltosReader reader = chooser.runDialog(); + if (reader != null) + run_display(new ReplayThread(reader, + chooser.filename())); } /* Connect to TeleMetrum, either directly or through -- cgit v1.2.3 From 7bd220dfd9b3fb0e42eb90c3b37eb7b4169eb21b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Aug 2010 00:29:11 -0700 Subject: altosui: Add ability to create CSV file from telem or eeprom files This creates a comma separated value file to export data for external programs. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosCSV.java | 120 +++++++++++++++++++++++++++--- ao-tools/altosui/AltosCSVUI.java | 83 +++++++++++++++++++++ ao-tools/altosui/AltosEepromReader.java | 4 +- ao-tools/altosui/AltosLogfileChooser.java | 9 ++- ao-tools/altosui/AltosReader.java | 2 + ao-tools/altosui/AltosUI.java | 17 +++++ ao-tools/altosui/Makefile | 1 + 7 files changed, 224 insertions(+), 12 deletions(-) create mode 100644 ao-tools/altosui/AltosCSVUI.java (limited to 'ao-tools/altosui/AltosUI.java') diff --git a/ao-tools/altosui/AltosCSV.java b/ao-tools/altosui/AltosCSV.java index 24936758..f12c0348 100644 --- a/ao-tools/altosui/AltosCSV.java +++ b/ao-tools/altosui/AltosCSV.java @@ -19,12 +19,20 @@ package altosui; import java.lang.*; import java.io.*; +import java.text.*; +import java.util.*; + import altosui.AltosRecord; +import altosui.AltosReader; public class AltosCSV { - File name; - PrintStream out; - boolean header_written; + File name; + PrintStream out; + boolean header_written; + boolean seen_boost; + int boost_tick; + LinkedList pad_records; + AltosState state; static final int ALTOS_CSV_VERSION = 1; @@ -45,6 +53,7 @@ public class AltosCSV { * acceleration (m/s²) * pressure (mBar) * altitude (m) + * height (m) * accelerometer speed (m/s) * barometer speed (m/s) * temp (°C) @@ -76,8 +85,9 @@ public class AltosCSV { } void write_general(AltosRecord record) { - out.printf("%s,%d,%d,%s,%d", - record.version, record.serial, record.flight, record.callsign, record.tick); + out.printf("%s,%d,%d,%s,%8.2f", + record.version, record.serial, record.flight, record.callsign, + (double) (record.tick - boost_tick) / 100.0); } void write_flight_header() { @@ -85,31 +95,123 @@ public class AltosCSV { } void write_flight(AltosRecord record) { - out.printf("%d,%s", record.state, record.state()); + out.printf("%d,%8s", record.state, record.state()); + } + + void write_basic_header() { + out.printf("acceleration pressure altitude height accel_speed baro_speed temperature battery_voltage drogue_voltage main_voltage"); + } + + void write_basic(AltosRecord record) { + out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f,%5.2f", + record.acceleration(), + record.pressure(), + record.altitude(), + record.height(), + record.accel_speed(), + state.baro_speed, + record.temperature(), + record.battery_voltage(), + record.drogue_voltage(), + record.main_voltage()); + } + + void write_gps_header() { + out.printf("connected locked nsat latitude longitude altitude year month day hour minute second"); + } + + void write_gps(AltosRecord record) { + AltosGPS gps = record.gps; + if (gps == null) + gps = new AltosGPS(); + + out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%6d,%5d,%3d,%3d,%3d,%3d,%3d", + gps.connected?1:0, + gps.locked?1:0, + gps.nsat, + gps.lat, + gps.lon, + gps.alt, + gps.year, + gps.month, + gps.day, + gps.hour, + gps.minute, + gps.second); } void write_header() { out.printf("# "); write_general_header(); out.printf(" "); write_flight_header(); + out.printf(" "); write_basic_header(); + out.printf(" "); write_gps_header(); + out.printf ("\n"); + } + + void write_one(AltosRecord record) { + state = new AltosState(record, state); + write_general(record); out.printf(","); + write_flight(record); out.printf(","); + write_basic(record); out.printf(","); + write_gps(record); out.printf ("\n"); } + void flush_pad() { + while (!pad_records.isEmpty()) { + write_one (pad_records.remove()); + } + } + public void write(AltosRecord record) { if (!header_written) { write_header(); header_written = true; } - write_general(record); out.printf(","); - write_flight(record); - out.printf ("\n"); + if (!seen_boost) { + if (record.state >= Altos.ao_flight_boost) { + seen_boost = true; + boost_tick = record.tick; + flush_pad(); + } + } + if (seen_boost) + write_one(record); + else + pad_records.add(record); } public PrintStream out() { return out; } + public void close() { + if (!pad_records.isEmpty()) { + boost_tick = pad_records.element().tick; + flush_pad(); + } + out.close(); + } + + public void write(AltosReader reader) { + AltosRecord record; + + reader.write_comments(out()); + try { + for (;;) { + record = reader.read(); + if (record == null) + break; + write(record); + } + } catch (IOException ie) { + } catch (ParseException pe) { + } + } + public AltosCSV(File in_name) throws FileNotFoundException { name = in_name; out = new PrintStream(name); + pad_records = new LinkedList(); } } diff --git a/ao-tools/altosui/AltosCSVUI.java b/ao-tools/altosui/AltosCSVUI.java new file mode 100644 index 00000000..2d812361 --- /dev/null +++ b/ao-tools/altosui/AltosCSVUI.java @@ -0,0 +1,83 @@ +/* + * Copyright © 2010 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.*; +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; +import java.util.concurrent.LinkedBlockingQueue; + +import altosui.AltosLogfileChooser; +import altosui.AltosCSV; + +public class AltosCSVUI + extends JDialog + implements Runnable, ActionListener +{ + JFrame frame; + Thread thread; + AltosReader reader; + AltosCSV writer; + + public void run() { + AltosLogfileChooser chooser; + + chooser = new AltosLogfileChooser(frame); + reader = chooser.runDialog(); + if (reader == null) + return; + JFileChooser csv_chooser; + + File file = chooser.file(); + String path = file.getPath(); + int dot = path.lastIndexOf("."); + if (dot >= 0) + path = path.substring(0,dot); + path = path.concat(".csv"); + csv_chooser = new JFileChooser(path); + int ret = csv_chooser.showSaveDialog(frame); + if (ret == JFileChooser.APPROVE_OPTION) { + try { + writer = new AltosCSV(csv_chooser.getSelectedFile()); + } catch (FileNotFoundException ee) { + JOptionPane.showMessageDialog(frame, + file.getName(), + "Cannot open file", + JOptionPane.ERROR_MESSAGE); + } + writer.write(reader); + reader.close(); + writer.close(); + } + } + + public void actionPerformed(ActionEvent e) { + } + + public AltosCSVUI(JFrame in_frame) { + frame = in_frame; + thread = new Thread(this); + thread.start(); + } +} diff --git a/ao-tools/altosui/AltosEepromReader.java b/ao-tools/altosui/AltosEepromReader.java index c29fd90b..deab2167 100644 --- a/ao-tools/altosui/AltosEepromReader.java +++ b/ao-tools/altosui/AltosEepromReader.java @@ -218,6 +218,7 @@ public class AltosEepromReader extends AltosReader { case Altos.AO_LOG_PRODUCT: break; case Altos.AO_LOG_SERIAL_NUMBER: + state.serial = record.a; break; case Altos.AO_LOG_SOFTWARE_VERSION: break; @@ -228,6 +229,7 @@ public class AltosEepromReader extends AltosReader { public void write_comments(PrintStream out) { Iterator iterator = records.iterator(); + out.printf("# Comments\n"); while (iterator.hasNext()) { AltosOrderedRecord record = iterator.next(); switch (record.cmd) { @@ -250,7 +252,7 @@ public class AltosEepromReader extends AltosReader { out.printf ("# Accel cal: %d %d\n", record.a, record.b); break; case Altos.AO_LOG_RADIO_CAL: - out.printf ("# Radio cal: %d %d\n", record.a); + out.printf ("# Radio cal: %d\n", record.a); break; case Altos.AO_LOG_MANUFACTURER: out.printf ("# Manufacturer: %s\n", record.data); diff --git a/ao-tools/altosui/AltosLogfileChooser.java b/ao-tools/altosui/AltosLogfileChooser.java index 3e9e4892..36b51de6 100644 --- a/ao-tools/altosui/AltosLogfileChooser.java +++ b/ao-tools/altosui/AltosLogfileChooser.java @@ -35,17 +35,22 @@ import altosui.AltosTelemetryReader; public class AltosLogfileChooser extends JFileChooser { JFrame frame; String filename; + File file; public String filename() { return filename; } + public File file() { + return file; + } + public AltosReader runDialog() { int ret; ret = showOpenDialog(frame); if (ret == APPROVE_OPTION) { - File file = getSelectedFile(); + file = getSelectedFile(); if (file == null) return null; filename = file.getName(); @@ -68,7 +73,7 @@ public class AltosLogfileChooser extends JFileChooser { } public AltosLogfileChooser(JFrame in_frame) { - in_frame = frame; + frame = in_frame; setDialogTitle("Select Flight Record File"); setFileFilter(new FileNameExtensionFilter("Flight data file", "eeprom", diff --git a/ao-tools/altosui/AltosReader.java b/ao-tools/altosui/AltosReader.java index 81779e2b..5be8795d 100644 --- a/ao-tools/altosui/AltosReader.java +++ b/ao-tools/altosui/AltosReader.java @@ -25,4 +25,6 @@ import altosui.AltosRecord; public class AltosReader { public AltosRecord read() throws IOException, ParseException { return null; } + public void close() { } + public void write_comments(PrintStream out) { } } diff --git a/ao-tools/altosui/AltosUI.java b/ao-tools/altosui/AltosUI.java index 8a4c753f..63cb486c 100644 --- a/ao-tools/altosui/AltosUI.java +++ b/ao-tools/altosui/AltosUI.java @@ -43,6 +43,7 @@ import altosui.AltosFlightInfoTableModel; import altosui.AltosChannelMenu; import altosui.AltosFlashUI; import altosui.AltosLogfileChooser; +import altosui.AltosCSVUI; import libaltosJNI.*; @@ -545,6 +546,14 @@ public class AltosUI extends JFrame { new AltosEepromDownload(AltosUI.this); } + /* Load a flight log file and write out a CSV file containing + * all of the data in standard units + */ + + private void ExportData() { + new AltosCSVUI(AltosUI.this); + } + /* Create the AltosUI menus */ private void createMenu() { @@ -583,6 +592,14 @@ public class AltosUI extends JFrame { }); menu.add(item); + item = new JMenuItem("Export Data",KeyEvent.VK_F); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ExportData(); + } + }); + menu.add(item); + item = new JMenuItem("Quit",KeyEvent.VK_Q); item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK)); diff --git a/ao-tools/altosui/Makefile b/ao-tools/altosui/Makefile index de78b765..1273e7d4 100644 --- a/ao-tools/altosui/Makefile +++ b/ao-tools/altosui/Makefile @@ -8,6 +8,7 @@ CLASSFILES=\ AltosConfigUI.class \ AltosConvert.class \ AltosCSV.class \ + AltosCSVUI.class \ AltosDebug.class \ AltosEepromDownload.class \ AltosEepromMonitor.class \ -- cgit v1.2.3 From 68967157cee620ebedcc8c2ffd6fc7656532087b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 26 Aug 2010 23:55:44 -0700 Subject: altosui: command line args are converted to csv format Signed-off-by: Keith Packard --- ao-tools/altosui/AltosUI.java | 63 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) (limited to 'ao-tools/altosui/AltosUI.java') diff --git a/ao-tools/altosui/AltosUI.java b/ao-tools/altosui/AltosUI.java index 63cb486c..4f3b5dde 100644 --- a/ao-tools/altosui/AltosUI.java +++ b/ao-tools/altosui/AltosUI.java @@ -719,8 +719,67 @@ public class AltosUI extends JFrame { this.setJMenuBar(menubar); } + + static String replace_extension(String input, String extension) { + int dot = input.lastIndexOf("."); + if (dot > 0) + input = input.substring(0,dot); + return input.concat(extension); + } + + static AltosReader open_logfile(String filename) { + File file = new File (filename); + try { + FileInputStream in; + + in = new FileInputStream(file); + if (filename.endsWith("eeprom")) + return new AltosEepromReader(in); + else + return new AltosTelemetryReader(in); + } catch (FileNotFoundException fe) { + System.out.printf("Cannot open '%s'\n", filename); + return null; + } + } + + static AltosCSV open_csv(String filename) { + File file = new File (filename); + try { + return new AltosCSV(file); + } catch (FileNotFoundException fe) { + System.out.printf("Cannot open '%s'\n", filename); + return null; + } + } + + static void process_file(String input) { + String output = replace_extension(input,".csv"); + if (input.equals(output)) { + System.out.printf("Not processing '%s'\n", input); + return; + } + System.out.printf("Processing \"%s\" to \"%s\"\n", input, output); + AltosReader reader = open_logfile(input); + if (reader == null) + return; + AltosCSV writer = open_csv(output); + if (writer == null) + return; + writer.write(reader); + reader.close(); + writer.close(); + } + public static void main(final String[] args) { - AltosUI altosui = new AltosUI(); - altosui.setVisible(true); + + /* Handle batch-mode */ + if (args.length > 0) { + for (int i = 0; i < args.length; i++) + process_file(args[i]); + } else { + AltosUI altosui = new AltosUI(); + altosui.setVisible(true); + } } } \ No newline at end of file -- cgit v1.2.3