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/AltosLogfileChooser.java | 52 +++++++++++++++++++++++++++++++ ao-tools/altosui/AltosUI.java | 14 +++------ ao-tools/altosui/Makefile | 1 + 3 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 ao-tools/altosui/AltosLogfileChooser.java (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosLogfileChooser.java b/ao-tools/altosui/AltosLogfileChooser.java new file mode 100644 index 00000000..72d21fc8 --- /dev/null +++ b/ao-tools/altosui/AltosLogfileChooser.java @@ -0,0 +1,52 @@ +/* + * 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 altosui.AltosPreferences; + +public class AltosLogfileChooser extends JFileChooser { + JFrame frame; + + public File runDialog() { + int ret; + + ret = showOpenDialog(frame); + if (ret == APPROVE_OPTION) + return getSelectedFile(); + return null; + } + + public AltosLogfileChooser(JFrame in_frame) { + in_frame = frame; + setDialogTitle("Select Flight Record File"); + setFileFilter(new FileNameExtensionFilter("Flight data file", + "eeprom", + "telem")); + setCurrentDirectory(AltosPreferences.logdir()); + } +} \ No newline at end of file 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); diff --git a/ao-tools/altosui/Makefile b/ao-tools/altosui/Makefile index affbac39..de78b765 100644 --- a/ao-tools/altosui/Makefile +++ b/ao-tools/altosui/Makefile @@ -22,6 +22,7 @@ CLASSFILES=\ AltosGreatCircle.class \ AltosHexfile.class \ AltosLog.class \ + AltosLogfileChooser.class \ AltosParse.class \ AltosPreferences.class \ AltosRecord.class \ -- 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') 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') 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 7d44cbd621d2b113ac2b802ef17e3d8a660ce7f2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Aug 2010 03:58:00 -0700 Subject: altosui: disable radio monitoring while using serial line for debugging --- ao-tools/altosui/AltosDebug.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosDebug.java b/ao-tools/altosui/AltosDebug.java index 83ea5bcb..df40410a 100644 --- a/ao-tools/altosui/AltosDebug.java +++ b/ao-tools/altosui/AltosDebug.java @@ -97,7 +97,7 @@ public class AltosDebug extends AltosSerial { void ensure_debug_mode() { if (!debug_mode) { - printf("D\n"); + printf("m 0\nD\n"); debug_mode = true; } } -- cgit v1.2.3 From d93787284c8e514a929edb9f944c98ae0206a33f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Aug 2010 03:59:09 -0700 Subject: altosui: Delay mapping Flash UI until flashing actually starts The flash operation may be abandoned before it even starts; this makes sure the UI doesn't flash up on the screen. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosFlash.java | 1 + ao-tools/altosui/AltosFlashUI.java | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosFlash.java b/ao-tools/altosui/AltosFlash.java index 0f92d6e7..7aeab89a 100644 --- a/ao-tools/altosui/AltosFlash.java +++ b/ao-tools/altosui/AltosFlash.java @@ -247,6 +247,7 @@ public class AltosFlash { int flash_addr = image.address; int image_start = 0; + action("start", 0); action(0, image.data.length); while (remain > 0 && !aborted) { int this_time = remain; diff --git a/ao-tools/altosui/AltosFlashUI.java b/ao-tools/altosui/AltosFlashUI.java index 0c2041e3..b88a16b3 100644 --- a/ao-tools/altosui/AltosFlashUI.java +++ b/ao-tools/altosui/AltosFlashUI.java @@ -57,8 +57,10 @@ public class AltosFlashUI } else { String cmd = e.getActionCommand(); if (cmd.equals("done")) - dispose(); - else { + ; + else if (cmd.equals("start")) { + setVisible(true); + } else { pbar.setValue(e.getID()); pbar.setString(cmd); } @@ -88,15 +90,14 @@ public class AltosFlashUI "Cannot open image", file.toString(), JOptionPane.ERROR_MESSAGE); - return; } catch (IOException e) { JOptionPane.showMessageDialog(frame, e.getMessage(), file.toString(), JOptionPane.ERROR_MESSAGE); - return; } catch (InterruptedException ie) { } + dispose(); } public void abort() { -- cgit v1.2.3 From f62b2aa08ebfd912b3c732397d43ff9f6162ec88 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Aug 2010 04:01:14 -0700 Subject: altosui: fetch existing romconfig for flashing --- ao-tools/altosui/AltosFlash.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosFlash.java b/ao-tools/altosui/AltosFlash.java index 7aeab89a..b7018555 100644 --- a/ao-tools/altosui/AltosFlash.java +++ b/ao-tools/altosui/AltosFlash.java @@ -315,6 +315,8 @@ public class AltosFlash { } public AltosRomconfig romconfig() { + if (!check_rom_config()) + return null; return rom_config; } -- cgit v1.2.3 From 220f3afdaa432c65f8ad45be7cdbe5c8a3616db3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Aug 2010 04:01:47 -0700 Subject: altosui: always display romconfig ui while flashing --- ao-tools/altosui/AltosFlashUI.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosFlashUI.java b/ao-tools/altosui/AltosFlashUI.java index b88a16b3..73a97a6b 100644 --- a/ao-tools/altosui/AltosFlashUI.java +++ b/ao-tools/altosui/AltosFlashUI.java @@ -72,14 +72,15 @@ public class AltosFlashUI flash.addActionListener(this); try { flash.open(); - if (!flash.check_rom_config()) { - AltosRomconfigUI romconfig_ui = new AltosRomconfigUI (frame); - romconfig_ui.showDialog(); - AltosRomconfig romconfig = romconfig_ui.romconfig(); - if (romconfig == null) - return; - flash.set_romconfig(romconfig); - } + AltosRomconfigUI romconfig_ui = new AltosRomconfigUI (frame); + + romconfig_ui.set(flash.romconfig()); + romconfig_ui.showDialog(); + + AltosRomconfig romconfig = romconfig_ui.romconfig(); + if (romconfig == null || !romconfig.valid()) + return; + flash.set_romconfig(romconfig); serial_value.setText(String.format("%d", flash.romconfig().serial_number)); file_value.setText(file.toString()); -- cgit v1.2.3 From ba086cc77273efe5397f60dcaccd1e3771441481 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Aug 2010 04:02:27 -0700 Subject: altosui: write USB serial number string while flashing USB serial number is encoded in UCS2 as a part of the string descriptors. Place those right after the other rom config bits so that altosui can find it. altosui is changed to write the serial number there. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosRomconfig.java | 49 +++++++++++++++++++++++++++++++++- ao-tools/altosui/AltosRomconfigUI.java | 21 ++++++++++++++- src/ao.h | 5 ++-- src/ao_product.c | 2 +- 4 files changed, 72 insertions(+), 5 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosRomconfig.java b/ao-tools/altosui/AltosRomconfig.java index 844da7c4..8c9cb27a 100644 --- a/ao-tools/altosui/AltosRomconfig.java +++ b/ao-tools/altosui/AltosRomconfig.java @@ -47,14 +47,57 @@ public class AltosRomconfig { } } + static void put_string(String value, byte[] bytes, int start) { + for (int i = 0; i < value.length(); i++) + bytes[start + i] = (byte) value.charAt(i); + } + + static final int AO_USB_DESC_STRING = 3; + + static void put_usb_serial(int value, byte[] bytes, int start) { + int offset = start + 0xa; + int string_num = 0; + System.out.printf("Put usb serial %d\n", value); + + while (offset < bytes.length && bytes[offset] != 0) { + if (bytes[offset + 1] == AO_USB_DESC_STRING) { + ++string_num; + if (string_num == 4) + break; + } + offset += ((int) bytes[offset]) & 0xff; + } + System.out.printf("offset %d content %d\n", + offset, bytes[offset]); + if (offset >= bytes.length || bytes[offset] == 0) + return; + int len = ((((int) bytes[offset]) & 0xff) - 2) / 2; + String fmt = String.format("%%0%dd", len); + System.out.printf("existing serial length %d format %s\n", len, fmt); + + String s = String.format(fmt, value); + if (s.length() != len) { + System.out.printf("weird usb length issue %s isn't %d\n", + s, len); + return; + } + for (int i = 0; i < len; i++) { + bytes[offset + 2 + i*2] = (byte) s.charAt(i); + bytes[offset + 2 + i*2+1] = 0; + } + } + public AltosRomconfig(byte[] bytes, int offset) { version = get_int(bytes, offset + 0, 2); check = get_int(bytes, offset + 2, 2); + System.out.printf("version %d check %d\n", version, check); if (check == (~version & 0xffff)) { switch (version) { + case 2: case 1: serial_number = get_int(bytes, offset + 4, 2); radio_calibration = get_int(bytes, offset + 6, 4); + System.out.printf("serial %d cal %d\n", serial_number, radio_calibration); valid = true; break; } @@ -77,6 +120,8 @@ public class AltosRomconfig { throw new IOException("image does not contain existing rom config"); switch (existing.version) { + case 2: + put_usb_serial(serial_number, bytes, offset); case 1: put_int(serial_number, bytes, offset + 4, 2); put_int(radio_calibration, bytes, offset + 6, 4); @@ -86,7 +131,9 @@ public class AltosRomconfig { public void write (AltosHexfile hexfile) throws IOException { write(hexfile.data, 0xa0 - hexfile.address); - new AltosRomconfig(hexfile); + AltosRomconfig check = new AltosRomconfig(hexfile); + if (!check.valid()) + throw new IOException("writing new rom config failed\n"); } public AltosRomconfig(int in_serial_number, int in_radio_calibration) { diff --git a/ao-tools/altosui/AltosRomconfigUI.java b/ao-tools/altosui/AltosRomconfigUI.java index 21c34ef4..bc511865 100644 --- a/ao-tools/altosui/AltosRomconfigUI.java +++ b/ao-tools/altosui/AltosRomconfigUI.java @@ -143,12 +143,31 @@ public class AltosRomconfigUI return Integer.parseInt(serial_value.getText()); } + void set_serial(int serial) { + serial_value.setText(String.format("%d", serial)); + } + int radio_calibration() { return Integer.parseInt(radio_calibration_value.getText()); } + void set_radio_calibration(int calibration) { + radio_calibration_value.setText(String.format("%d", calibration)); + } + + public void set(AltosRomconfig config) { + if (config != null && config.valid()) { + set_serial(config.serial_number); + set_radio_calibration(config.radio_calibration); + } + } + public AltosRomconfig romconfig() { - return new AltosRomconfig(serial(), radio_calibration()); + try { + return new AltosRomconfig(serial(), radio_calibration()); + } catch (NumberFormatException ne) { + return null; + } } public AltosRomconfig showDialog() { diff --git a/src/ao.h b/src/ao.h index 9c418db2..d289ced1 100644 --- a/src/ao.h +++ b/src/ao.h @@ -293,12 +293,13 @@ ao_led_init(uint8_t enable); * ao_romconfig.c */ -#define AO_ROMCONFIG_VERSION 1 +#define AO_ROMCONFIG_VERSION 2 extern __code __at (0x00a0) uint16_t ao_romconfig_version; extern __code __at (0x00a2) uint16_t ao_romconfig_check; extern __code __at (0x00a4) uint16_t ao_serial_number; extern __code __at (0x00a6) uint32_t ao_radio_cal; +extern __code __at (0x00aa) uint8_t ao_usb_descriptors []; /* * ao_usb.c @@ -1008,7 +1009,7 @@ ao_rssi_init(uint8_t rssi_led); * each instance of a product */ -extern const uint8_t ao_usb_descriptors []; +extern __code __at(0x00aa) uint8_t ao_usb_descriptors []; extern const char ao_version[]; extern const char ao_manufacturer[]; extern const char ao_product[]; diff --git a/src/ao_product.c b/src/ao_product.c index f0eb4c07..82d6298f 100644 --- a/src/ao_product.c +++ b/src/ao_product.c @@ -28,7 +28,7 @@ const char ao_product[] = AO_iProduct_STRING; #define LE_WORD(x) ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8)) /* USB descriptors in one giant block of bytes */ -const uint8_t ao_usb_descriptors [] = +__code __at(0x00aa) uint8_t ao_usb_descriptors [] = { /* Device descriptor */ 0x12, -- cgit v1.2.3 From 99400fdc0f19ef538fc362dde5c3ab5b7cdac409 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Aug 2010 16:43:38 -0700 Subject: altosui: flush replies from serial link when entering debug mode We use replies in debug mode a lot and depend on them matching the expected parameters. The case which caused trouble was using TeleMetrum to reprogram TeleDongle -- sending the 'm 0' command (to disable telemetry monitoring on TeleDongle) to the TeleMetrum caused it to reply 'Syntax Error' which confused the subsequent flashing operation. Flushing that reply gets things back in sync. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosDebug.java | 1 + ao-tools/altosui/AltosSerial.java | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosDebug.java b/ao-tools/altosui/AltosDebug.java index df40410a..06c9a0bd 100644 --- a/ao-tools/altosui/AltosDebug.java +++ b/ao-tools/altosui/AltosDebug.java @@ -98,6 +98,7 @@ public class AltosDebug extends AltosSerial { void ensure_debug_mode() { if (!debug_mode) { printf("m 0\nD\n"); + flush_reply(); debug_mode = true; } } diff --git a/ao-tools/altosui/AltosSerial.java b/ao-tools/altosui/AltosSerial.java index d02e25a9..3684f253 100644 --- a/ao-tools/altosui/AltosSerial.java +++ b/ao-tools/altosui/AltosSerial.java @@ -66,8 +66,10 @@ public class AltosSerial implements Runnable { LinkedBlockingQueue q = monitors.get(e); q.put(line); } - } else + } else { +// System.out.printf("GOT: %s\n", line); reply_queue.put(line); + } line = ""; } } else { @@ -80,6 +82,11 @@ public class AltosSerial implements Runnable { } public void flush_reply() { + libaltos.altos_flush(altos); + try { + Thread.sleep(100); + } catch (InterruptedException ie) { + } reply_queue.clear(); } @@ -132,6 +139,7 @@ public class AltosSerial implements Runnable { } public void print(String data) { +// System.out.printf("\"%s\" ", data); for (int i = 0; i < data.length(); i++) putc(data.charAt(i)); } -- cgit v1.2.3 From f0fd423d0bf83bc5c3f9d39e9c09397fbe8caed2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 26 Aug 2010 23:41:26 -0700 Subject: altosui: Move number parsing code to Altos general class This moves these shared functions to the global shared class. Signed-off-by: Keith Packard --- ao-tools/altosui/Altos.java | 86 ++++++++++++++++++++++++++++++++++++++++ ao-tools/altosui/AltosDebug.java | 43 ++------------------ ao-tools/altosui/AltosParse.java | 10 ++++- 3 files changed, 98 insertions(+), 41 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/altosui/Altos.java b/ao-tools/altosui/Altos.java index 53359e23..07bd01ae 100644 --- a/ao-tools/altosui/Altos.java +++ b/ao-tools/altosui/Altos.java @@ -114,4 +114,90 @@ public class Altos { static final int AO_GPS_DATE_VALID = (1 << 6); static final int AO_GPS_NUM_SAT_SHIFT = 0; static final int AO_GPS_NUM_SAT_MASK = 0xf; + + static boolean isspace(int c) { + switch (c) { + case ' ': + case '\t': + return true; + } + return false; + } + + static boolean ishex(int c) { + if ('0' <= c && c <= '9') + return true; + if ('a' <= c && c <= 'f') + return true; + if ('A' <= c && c <= 'F') + return true; + return false; + } + + static boolean ishex(String s) { + for (int i = 0; i < s.length(); i++) + if (!ishex(s.charAt(i))) + return false; + return true; + } + + static int fromhex(int c) { + if ('0' <= c && c <= '9') + return c - '0'; + if ('a' <= c && c <= 'f') + return c - 'a' + 10; + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + return -1; + } + + static int fromhex(String s) throws NumberFormatException { + int c, v = 0; + for (int i = 0; i < s.length(); i++) { + c = s.charAt(i); + if (!ishex(c)) { + if (i == 0) + throw new NumberFormatException(String.format("invalid hex \"%s\"", s)); + return v; + } + v = v * 16 + fromhex(c); + } + return v; + } + + static boolean isdec(int c) { + if ('0' <= c && c <= '9') + return true; + return false; + } + + static boolean isdec(String s) { + for (int i = 0; i < s.length(); i++) + if (!isdec(s.charAt(i))) + return false; + return true; + } + + static int fromdec(int c) { + if ('0' <= c && c <= '9') + return c - '0'; + return -1; + } + + static int fromdec(String s) throws NumberFormatException { + int c, v = 0; + int sign = 1; + for (int i = 0; i < s.length(); i++) { + c = s.charAt(i); + if (i == 0 && c == '-') { + sign = -1; + } else if (!isdec(c)) { + if (i == 0) + throw new NumberFormatException(String.format("invalid number \"%s\"", s)); + return v; + } else + v = v * 10 + fromdec(c); + } + return v * sign; + } } diff --git a/ao-tools/altosui/AltosDebug.java b/ao-tools/altosui/AltosDebug.java index 06c9a0bd..ca2e5a90 100644 --- a/ao-tools/altosui/AltosDebug.java +++ b/ao-tools/altosui/AltosDebug.java @@ -58,41 +58,6 @@ public class AltosDebug extends AltosSerial { public static final byte GET_CHIP_ID = 0x68; - static boolean ishex(int c) { - if ('0' <= c && c <= '9') - return true; - if ('a' <= c && c <= 'f') - return true; - if ('A' <= c && c <= 'F') - return true; - return false; - } - - static boolean ishex(String s) { - for (int i = 0; i < s.length(); i++) - if (!ishex(s.charAt(i))) - return false; - return true; - } - static boolean isspace(int c) { - switch (c) { - case ' ': - case '\t': - return true; - } - return false; - } - - static int fromhex(int c) { - if ('0' <= c && c <= '9') - return c - '0'; - if ('a' <= c && c <= 'f') - return c - 'a' + 10; - if ('A' <= c && c <= 'F') - return c - 'A' + 10; - return -1; - } - boolean debug_mode; void ensure_debug_mode() { @@ -145,14 +110,14 @@ public class AltosDebug extends AltosSerial { int start = 0; while (i < length) { String line = get_reply().trim(); - if (!ishex(line) || line.length() % 2 != 0) + if (!Altos.ishex(line) || line.length() % 2 != 0) throw new IOException( String.format ("Invalid reply \"%s\"", line)); int this_time = line.length() / 2; for (int j = 0; j < this_time; j++) - data[start + j] = (byte) ((fromhex(line.charAt(j*2)) << 4) + - fromhex(line.charAt(j*2+1))); + data[start + j] = (byte) ((Altos.fromhex(line.charAt(j*2)) << 4) + + Altos.fromhex(line.charAt(j*2+1))); start += this_time; i += this_time; } @@ -199,7 +164,7 @@ public class AltosDebug extends AltosSerial { String line = get_reply().trim(); String tokens[] = line.split("\\s+"); for (int j = 0; j < tokens.length; j++) { - if (!ishex(tokens[j]) || + if (!Altos.ishex(tokens[j]) || tokens[j].length() != 2) throw new IOException( String.format diff --git a/ao-tools/altosui/AltosParse.java b/ao-tools/altosui/AltosParse.java index a60dc694..4d82de78 100644 --- a/ao-tools/altosui/AltosParse.java +++ b/ao-tools/altosui/AltosParse.java @@ -20,10 +20,16 @@ package altosui; import java.text.*; import java.lang.*; +import altosui.Altos; + public class AltosParse { + static boolean isdigit(char c) { + return '0' <= c && c <= '9'; + } + static int parse_int(String v) throws ParseException { try { - return Integer.parseInt(v); + return Altos.fromdec(v); } catch (NumberFormatException e) { throw new ParseException("error parsing int " + v, 0); } @@ -31,7 +37,7 @@ public class AltosParse { static int parse_hex(String v) throws ParseException { try { - return Integer.parseInt(v, 16); + return Altos.fromhex(v); } catch (NumberFormatException e) { throw new ParseException("error parsing hex " + v, 0); } -- cgit v1.2.3 From 3dc67c1401976d6e9e2e942d5a4707a4810a0404 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 26 Aug 2010 23:43:00 -0700 Subject: altosui: Add AltosGreatCircle constructors This adds constructurs from AltosGPS pairs and also one from empty args (which defines both distance and bearing as 0). Signed-off-by: Keith Packard --- ao-tools/altosui/AltosGreatCircle.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosGreatCircle.java b/ao-tools/altosui/AltosGreatCircle.java index 878da03e..07c02c16 100644 --- a/ao-tools/altosui/AltosGreatCircle.java +++ b/ao-tools/altosui/AltosGreatCircle.java @@ -17,6 +17,8 @@ package altosui; +import altosui.AltosGPS; + import java.lang.Math; public class AltosGreatCircle { @@ -28,8 +30,8 @@ public class AltosGreatCircle { static final double rad = Math.PI / 180; static final double earth_radius = 6371.2 * 1000; /* in meters */ - AltosGreatCircle (double start_lat, double start_lon, - double end_lat, double end_lon) + public AltosGreatCircle (double start_lat, double start_lon, + double end_lat, double end_lon) { double lat1 = rad * start_lat; double lon1 = rad * -start_lon; @@ -63,4 +65,13 @@ public class AltosGreatCircle { distance = d * earth_radius; bearing = course * 180/Math.PI; } + + public AltosGreatCircle(AltosGPS start, AltosGPS end) { + this(start.lat, start.lon, end.lat, end.lon); + } + + public AltosGreatCircle() { + distance = 0; + bearing = 0; + } } -- cgit v1.2.3 From 651f6102ac79459fc8d5679d852c963dcb5bb3fc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 26 Aug 2010 23:44:25 -0700 Subject: altosui: add rssi and distance/dir from pad to CSV files Just adds a couple more fields to the CSV files that might be interesting. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosCSV.java | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosCSV.java b/ao-tools/altosui/AltosCSV.java index f12c0348..db50e7a2 100644 --- a/ao-tools/altosui/AltosCSV.java +++ b/ao-tools/altosui/AltosCSV.java @@ -44,6 +44,7 @@ public class AltosCSV { * flight number * callsign * time (seconds since boost) + * rssi * * Flight status * state @@ -74,6 +75,8 @@ public class AltosCSV { * hour (0-23) * minute (0-59) * second (0-59) + * from_pad_dist (m) + * from_pad_dir (deg true) * * GPS Sat data * hdop @@ -81,13 +84,14 @@ public class AltosCSV { */ void write_general_header() { - out.printf("version serial flight call time"); + out.printf("version serial flight call time rssi"); } void write_general(AltosRecord record) { - out.printf("%s,%d,%d,%s,%8.2f", + out.printf("%s,%d,%d,%s,%8.2f,%4d", record.version, record.serial, record.flight, record.callsign, - (double) (record.tick - boost_tick) / 100.0); + (double) record.time, + record.rssi); } void write_flight_header() { @@ -117,7 +121,7 @@ public class AltosCSV { } void write_gps_header() { - out.printf("connected locked nsat latitude longitude altitude year month day hour minute second"); + out.printf("connected locked nsat latitude longitude altitude year month day hour minute second pad_dist pad_dir"); } void write_gps(AltosRecord record) { @@ -125,7 +129,11 @@ public class AltosCSV { if (gps == null) gps = new AltosGPS(); - out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%6d,%5d,%3d,%3d,%3d,%3d,%3d", + AltosGreatCircle from_pad = state.from_pad; + if (from_pad == null) + from_pad = new AltosGreatCircle(); + + out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%6d,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%4.0f", gps.connected?1:0, gps.locked?1:0, gps.nsat, @@ -137,7 +145,9 @@ public class AltosCSV { gps.day, gps.hour, gps.minute, - gps.second); + gps.second, + from_pad.distance, + from_pad.bearing); } void write_header() { @@ -205,7 +215,9 @@ public class AltosCSV { write(record); } } catch (IOException ie) { + System.out.printf("IOException\n"); } catch (ParseException pe) { + System.out.printf("ParseException %s\n", pe.getMessage()); } } @@ -214,4 +226,8 @@ public class AltosCSV { out = new PrintStream(name); pad_records = new LinkedList(); } + + public AltosCSV(String in_string) throws FileNotFoundException { + this(new File(in_string)); + } } -- cgit v1.2.3 From e383595cd281687de903fb6176564bbef270cb83 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 26 Aug 2010 23:47:38 -0700 Subject: altosui: AltosEepromReader was mis-setting boost tick It was supposed to use record.tick instead of the (unset) state.tick value. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosEepromReader.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosEepromReader.java b/ao-tools/altosui/AltosEepromReader.java index deab2167..3f2d4c62 100644 --- a/ao-tools/altosui/AltosEepromReader.java +++ b/ao-tools/altosui/AltosEepromReader.java @@ -133,8 +133,6 @@ public class AltosEepromReader extends AltosReader { ground_pres += state.pres; state.ground_pres = (int) (ground_pres / n_pad_samples); state.flight_pres = state.ground_pres; - System.out.printf("ground pressure %d altitude %f\n", - record.b, state.altitude()); ground_accel += state.accel; state.ground_accel = (int) (ground_accel / n_pad_samples); state.flight_accel = state.ground_accel; @@ -156,7 +154,6 @@ public class AltosEepromReader extends AltosReader { seen |= seen_deploy; break; case Altos.AO_LOG_STATE: - System.out.printf("state %d\n", record.a); state.state = record.a; break; case Altos.AO_LOG_GPS_TIME: @@ -298,10 +295,10 @@ public class AltosEepromReader extends AltosReader { break; tick = record.tick; if (!saw_boost && record.cmd == Altos.AO_LOG_STATE && - record.a == Altos.ao_flight_boost) + record.a >= Altos.ao_flight_boost) { saw_boost = true; - boost_tick = state.tick; + boost_tick = tick; } records.add(record); } -- cgit v1.2.3 From 0942912163255523d923140c01afbdb5da1c19b5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 26 Aug 2010 23:49:37 -0700 Subject: altosui: Add support for old (version < 3) telemetry files This lets the code read telemetry files from pre-released versions of the software. Not strictly necessary for production, but useful for analysing old files. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosGPS.java | 61 ++++++++++++++++++++++-------------- ao-tools/altosui/AltosTelemetry.java | 34 ++++++++++++++------ 2 files changed, 63 insertions(+), 32 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosGPS.java b/ao-tools/altosui/AltosGPS.java index b3ee67e8..acb6fb2c 100644 --- a/ao-tools/altosui/AltosGPS.java +++ b/ao-tools/altosui/AltosGPS.java @@ -52,14 +52,16 @@ public class AltosGPS { AltosGPSSat[] cc_gps_sat; /* tracking data */ - void ParseGPSTime(String date, String time) throws ParseException { + void ParseGPSDate(String date) throws ParseException { String[] ymd = date.split("-"); if (ymd.length != 3) throw new ParseException("error parsing GPS date " + date + " got " + ymd.length, 0); year = AltosParse.parse_int(ymd[0]); month = AltosParse.parse_int(ymd[1]); day = AltosParse.parse_int(ymd[2]); + } + void ParseGPSTime(String time) throws ParseException { String[] hms = time.split(":"); if (hms.length != 3) throw new ParseException("Error parsing GPS time " + time + " got " + hms.length, 0); @@ -73,7 +75,7 @@ public class AltosGPS { hour = minute = second = 0; } - public AltosGPS(String[] words, int i) throws ParseException { + public AltosGPS(String[] words, int i, int version) throws ParseException { AltosParse.word(words[i++], "GPS"); nsat = AltosParse.parse_int(words[i++]); AltosParse.word(words[i++], "sat"); @@ -92,32 +94,44 @@ public class AltosGPS { locked = true; connected = true; - ParseGPSTime(words[i], words[i+1]); i += 2; + if (version > 1) + ParseGPSDate(words[i++]); + else + year = month = day = 0; + ParseGPSTime(words[i++]); lat = AltosParse.parse_coord(words[i++]); lon = AltosParse.parse_coord(words[i++]); - alt = AltosParse.parse_int(AltosParse.strip_suffix(words[i++], "m")); - ground_speed = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(H)")); - course = AltosParse.parse_int(AltosParse.strip_suffix(words[i++], "°")); - climb_rate = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(V)")); - hdop = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "(hdop)")); - h_error = AltosParse.parse_int(AltosParse.strip_suffix(words[i++], "(herr)")); - v_error = AltosParse.parse_int(AltosParse.strip_suffix(words[i++], "(verr)")); + alt = AltosParse.parse_int(words[i++]); + if (version > 1 || (i < words.length && !words[i].equals("SAT"))) { + ground_speed = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(H)")); + course = AltosParse.parse_int(words[i++]); + climb_rate = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(V)")); + hdop = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "(hdop)")); + h_error = AltosParse.parse_int(words[i++]); + v_error = AltosParse.parse_int(words[i++]); + } } else { i++; } - AltosParse.word(words[i++], "SAT"); - int tracking_channels = 0; - if (words[i].equals("not-connected")) - tracking_channels = 0; - else - tracking_channels = AltosParse.parse_int(words[i]); - i++; - cc_gps_sat = new AltosGPS.AltosGPSSat[tracking_channels]; - for (int chan = 0; chan < tracking_channels; chan++) { - cc_gps_sat[chan] = new AltosGPS.AltosGPSSat(); - cc_gps_sat[chan].svid = AltosParse.parse_int(words[i++]); - cc_gps_sat[chan].c_n0 = AltosParse.parse_int(words[i++]); - } + if (i < words.length) { + AltosParse.word(words[i++], "SAT"); + int tracking_channels = 0; + if (words[i].equals("not-connected")) + tracking_channels = 0; + else + tracking_channels = AltosParse.parse_int(words[i]); + i++; + cc_gps_sat = new AltosGPS.AltosGPSSat[tracking_channels]; + for (int chan = 0; chan < tracking_channels; chan++) { + cc_gps_sat[chan] = new AltosGPS.AltosGPSSat(); + cc_gps_sat[chan].svid = AltosParse.parse_int(words[i++]); + /* Older versions included SiRF status bits */ + if (version < 2) + i++; + cc_gps_sat[chan].c_n0 = AltosParse.parse_int(words[i++]); + } + } else + cc_gps_sat = new AltosGPS.AltosGPSSat[0]; } public void set_latitude(int in_lat) { @@ -172,6 +186,7 @@ public class AltosGPS { nsat = old.nsat; locked = old.locked; connected = old.connected; + date_valid = old.date_valid; lat = old.lat; /* degrees (+N -S) */ lon = old.lon; /* degrees (+E -W) */ alt = old.alt; /* m */ diff --git a/ao-tools/altosui/AltosTelemetry.java b/ao-tools/altosui/AltosTelemetry.java index af29b8c0..bc62690b 100644 --- a/ao-tools/altosui/AltosTelemetry.java +++ b/ao-tools/altosui/AltosTelemetry.java @@ -57,8 +57,12 @@ public class AltosTelemetry extends AltosRecord { String[] words = line.split("\\s+"); int i = 0; - AltosParse.word (words[i++], "VERSION"); - version = AltosParse.parse_int(words[i++]); + if (words[i].equals("CALL")) { + version = 0; + } else { + AltosParse.word (words[i++], "VERSION"); + version = AltosParse.parse_int(words[i++]); + } AltosParse.word (words[i++], "CALL"); callsign = words[i++]; @@ -66,12 +70,19 @@ public class AltosTelemetry extends AltosRecord { AltosParse.word (words[i++], "SERIAL"); serial = AltosParse.parse_int(words[i++]); - AltosParse.word (words[i++], "FLIGHT"); - flight = AltosParse.parse_int(words[i++]); + if (version >= 2) { + AltosParse.word (words[i++], "FLIGHT"); + flight = AltosParse.parse_int(words[i++]); + } else + flight = 0; AltosParse.word(words[i++], "RSSI"); rssi = AltosParse.parse_int(words[i++]); + /* Older telemetry data had mis-computed RSSI value */ + if (version <= 2) + rssi = (rssi + 74) / 2 - 74; + AltosParse.word(words[i++], "STATUS"); status = AltosParse.parse_hex(words[i++]); @@ -113,12 +124,17 @@ public class AltosTelemetry extends AltosRecord { AltosParse.word(words[i++], "gp:"); ground_pres = AltosParse.parse_int(words[i++]); - AltosParse.word(words[i++], "a+:"); - accel_plus_g = AltosParse.parse_int(words[i++]); + if (version >= 1) { + AltosParse.word(words[i++], "a+:"); + accel_plus_g = AltosParse.parse_int(words[i++]); - AltosParse.word(words[i++], "a-:"); - accel_minus_g = AltosParse.parse_int(words[i++]); + AltosParse.word(words[i++], "a-:"); + accel_minus_g = AltosParse.parse_int(words[i++]); + } else { + accel_plus_g = ground_accel; + accel_minus_g = ground_accel + 530; + } - gps = new AltosGPS(words, i); + gps = new AltosGPS(words, i, version); } } -- cgit v1.2.3 From a16db143fc7ca72dc91e7989420049192114642d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 26 Aug 2010 23:50:51 -0700 Subject: altosui: Serial line is in UTF-8 encoding. Deal with it. We read bytes from the serial line and need to convert each line into a string. So, save the bytes and at EOL, pass the whole mess to the string constructor with the appropriate encoding info. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosSerial.java | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosSerial.java b/ao-tools/altosui/AltosSerial.java index 3684f253..5b47960f 100644 --- a/ao-tools/altosui/AltosSerial.java +++ b/ao-tools/altosui/AltosSerial.java @@ -45,6 +45,8 @@ public class AltosSerial implements Runnable { LinkedBlockingQueue reply_queue; Thread input_thread; String line; + byte[] line_bytes; + int line_count; public void run () { int c; @@ -60,7 +62,14 @@ public class AltosSerial implements Runnable { continue; synchronized(this) { if (c == '\n') { - if (line != "") { + if (line_count != 0) { + try { + line = new String(line_bytes, 0, line_count, "UTF-8"); + } catch (UnsupportedEncodingException ue) { + line = ""; + for (int i = 0; i < line_count; i++) + line = line + line_bytes[i]; + } if (line.startsWith("VERSION")) { for (int e = 0; e < monitors.size(); e++) { LinkedBlockingQueue q = monitors.get(e); @@ -70,10 +79,19 @@ public class AltosSerial implements Runnable { // System.out.printf("GOT: %s\n", line); reply_queue.put(line); } + line_count = 0; line = ""; } } else { - line = line + (char) c; + if (line_bytes == null) { + line_bytes = new byte[256]; + } else if (line_count == line_bytes.length) { + byte[] new_line_bytes = new byte[line_count * 2]; + System.arraycopy(line_bytes, 0, new_line_bytes, 0, line_count); + line_bytes = new_line_bytes; + } + line_bytes[line_count] = (byte) c; + line_count++; } } } @@ -139,7 +157,7 @@ public class AltosSerial implements Runnable { } public void print(String data) { -// System.out.printf("\"%s\" ", data); +//h System.out.printf("\"%s\" ", data); for (int i = 0; i < data.length(); i++) putc(data.charAt(i)); } -- cgit v1.2.3 From 49364608b59de7421ab00d87d2685bc3b5f58411 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 26 Aug 2010 23:53:06 -0700 Subject: altosui: When parsing saved telem files, errors shouldn't abort file Make syntax errors in telem files just skip the current line and move on to the next one instead of abandoning the whole file. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosTelemetryReader.java | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosTelemetryReader.java b/ao-tools/altosui/AltosTelemetryReader.java index f1f6788c..a3402f9c 100644 --- a/ao-tools/altosui/AltosTelemetryReader.java +++ b/ao-tools/altosui/AltosTelemetryReader.java @@ -47,20 +47,25 @@ public class AltosTelemetryReader extends AltosReader { try { for (;;) { String line = AltosRecord.gets(input); - if (line == null) + if (line == null) { break; - AltosTelemetry record = new AltosTelemetry(line); - if (record == null) - break; - if (!saw_boost && record.state >= Altos.ao_flight_boost) - { - saw_boost = true; - boost_tick = record.tick; } - records.add(record); + try { + AltosTelemetry record = new AltosTelemetry(line); + if (record == null) + break; + if (!saw_boost && record.state >= Altos.ao_flight_boost) + { + saw_boost = true; + boost_tick = record.tick; + } + records.add(record); + } catch (ParseException pe) { + System.out.printf("parse exception %s\n", pe.getMessage()); + } } } catch (IOException io) { - } catch (ParseException pe) { + System.out.printf("io exception\n"); } record_iterator = records.iterator(); try { -- cgit v1.2.3 From 7e0506dc2014b7178f52b950e8c1cb820b35f9c6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 26 Aug 2010 23:54:53 -0700 Subject: altosui: Remove debug printf from AltosState.java Signed-off-by: Keith Packard --- ao-tools/altosui/AltosState.java | 5 ----- 1 file changed, 5 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/altosui/AltosState.java b/ao-tools/altosui/AltosState.java index deeb4c77..c13dfe68 100644 --- a/ao-tools/altosui/AltosState.java +++ b/ao-tools/altosui/AltosState.java @@ -124,11 +124,6 @@ public class AltosState { } if (state == Altos.ao_flight_pad) { - if (data.gps == null) - System.out.printf("on pad, gps null\n"); - else - System.out.printf ("on pad gps lat %f lon %f locked %d nsat %d\n", - data.gps.lat, data.gps.lon, data.gps.locked ? 1 : 0, data.gps.nsat); if (data.gps != null && data.gps.locked && data.gps.nsat >= 4) { npad++; if (npad > 1) { -- 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') 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