From c7f540330c040c521f9d7626009a406e704a5e41 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 12 Aug 2011 14:58:34 -0700 Subject: [PATCH] altosui: Add companion support to the flight UI and CSV conversion Shows the companion data in a new tab. Also put companion data into CSV file. Signed-off-by: Keith Packard --- altosui/AltosCSV.java | 49 ++++++++- altosui/AltosCompanionInfo.java | 111 +++++++++++++++++++++ altosui/AltosFlightUI.java | 20 +++- altosui/AltosRecord.java | 5 + altosui/AltosRecordCompanion.java | 38 +++++++ altosui/AltosState.java | 1 - altosui/AltosTelemetryRecordCompanion.java | 52 ++++++++++ altosui/AltosTelemetryRecordRaw.java | 10 +- altosui/Makefile.am | 3 + 9 files changed, 281 insertions(+), 8 deletions(-) create mode 100644 altosui/AltosCompanionInfo.java create mode 100644 altosui/AltosRecordCompanion.java create mode 100644 altosui/AltosTelemetryRecordCompanion.java diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java index 5277c160..cf649db0 100644 --- a/altosui/AltosCSV.java +++ b/altosui/AltosCSV.java @@ -31,9 +31,9 @@ public class AltosCSV implements AltosWriter { LinkedList pad_records; AltosState state; - static final int ALTOS_CSV_VERSION = 2; + static final int ALTOS_CSV_VERSION = 3; - /* Version 2 format: + /* Version 3 format: * * General info * version number @@ -81,6 +81,13 @@ public class AltosCSV implements AltosWriter { * * GPS Sat data * C/N0 data for all 32 valid SDIDs + * + * Companion data + * companion_id (1-255. 10 is TeleScience) + * time of last companion data (seconds since boost) + * update_period (0.1-2.55 minimum telemetry interval) + * channels (0-12) + * channel data for all 12 possible channels */ void write_general_header() { @@ -179,7 +186,32 @@ public class AltosCSV implements AltosWriter { } } - void write_header(boolean gps) { + void write_companion_header() { + out.printf("companion_id,companion_time,companion_update,companion_channels"); + for (int i = 0; i < 12; i++) + out.printf(",companion_%02d", i); + } + + void write_companion(AltosRecord record) { + AltosRecordCompanion companion = record.companion; + + int channels_written = 0; + if (companion == null) { + out.printf("0,0,0,0"); + } else { + out.printf("%3d,%5.2f,%5.2f,%2d", + companion.board_id, + (companion.tick - boost_tick) / 100.0, + companion.update_period / 100.0, + companion.channels); + for (; channels_written < companion.channels; channels_written++) + out.printf(",%5d", companion.companion_data[channels_written]); + } + for (; channels_written < 12; channels_written++) + out.printf(",0"); + } + + void write_header(boolean gps, boolean companion) { out.printf("#"); write_general_header(); out.printf(","); write_flight_header(); out.printf(","); write_basic_header(); @@ -187,6 +219,9 @@ public class AltosCSV implements AltosWriter { out.printf(","); write_gps_header(); out.printf(","); write_gps_sat_header(); } + if (companion) { + out.printf(","); write_companion_header(); + } out.printf ("\n"); } @@ -200,6 +235,10 @@ public class AltosCSV implements AltosWriter { write_gps(record); out.printf(","); write_gps_sat(record); } + if (record.companion != null) { + out.printf(","); + write_companion(record); + } out.printf ("\n"); } @@ -210,8 +249,10 @@ public class AltosCSV implements AltosWriter { } public void write(AltosRecord record) { + if (record.state == Altos.ao_flight_startup) + return; if (!header_written) { - write_header(record.gps != null); + write_header(record.gps != null, record.companion != null); header_written = true; } if (!seen_boost) { diff --git a/altosui/AltosCompanionInfo.java b/altosui/AltosCompanionInfo.java new file mode 100644 index 00000000..f287a8ea --- /dev/null +++ b/altosui/AltosCompanionInfo.java @@ -0,0 +1,111 @@ +/* + * 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; + +public class AltosCompanionInfo extends JTable { + private AltosFlightInfoTableModel model; + + private Font infoLabelFont = new Font("SansSerif", Font.PLAIN, 14); + private Font infoValueFont = new Font("Monospaced", Font.PLAIN, 14); + + static final int info_columns = 2; + static final int info_rows = 17; + + int desired_row_height() { + FontMetrics infoValueMetrics = getFontMetrics(infoValueFont); + return (infoValueMetrics.getHeight() + infoValueMetrics.getLeading()) * 18 / 10; + } + + public AltosCompanionInfo() { + super(new AltosFlightInfoTableModel(info_rows, info_columns)); + model = (AltosFlightInfoTableModel) getModel(); + setFont(infoValueFont); + setAutoResizeMode(AUTO_RESIZE_ALL_COLUMNS); + setShowGrid(true); + setRowHeight(desired_row_height()); + doLayout(); + } + + public Dimension getPreferredScrollableViewportSize() { + return getPreferredSize(); + } + + void info_reset() { + model.reset(); + } + + void info_add_row(int col, String name, String value) { + model.addRow(col, name, value); + } + + void info_add_row(int col, String name, String format, Object... parameters) { + info_add_row (col, name, String.format(format, parameters)); + } + + void info_finish() { + model.finish(); + } + + public void clear() { + model.clear(); + } + + AltosRecordCompanion companion; + + public String board_name() { + if (companion == null) + return "None"; + switch (companion.board_id) { + case AltosRecordCompanion.board_id_telescience: + return "TeleScience"; + default: + return String.format("%02x\n", companion.board_id); + } + } + + public void show(AltosState state, int crc_errors) { + if (state == null) + return; + if (state.data.companion != null) + companion = state.data.companion; + info_reset(); + info_add_row(0, "Companion board", "%s", board_name()); + if (companion != null) { + info_add_row(0, "Last Data", "%5d", companion.tick); + info_add_row(0, "Update period", "%5.2f s", + companion.update_period / 100.0); + info_add_row(0, "Channels", "%3d", companion.channels); + + for (int i = 0; i < companion.channels; i++) + info_add_row(1, String.format("Channel %2d", i), + "%6d", companion.companion_data[i]); + } + info_finish(); + } +} diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index f0626e7c..51768046 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -39,8 +39,10 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay { AltosAscent ascent; AltosDescent descent; AltosLanded landed; + AltosCompanionInfo companion; AltosSiteMap sitemap; boolean has_map; + boolean has_companion; private AltosFlightStatus flightStatus; private AltosInfoTable flightInfo; @@ -96,7 +98,20 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay { } flightStatus.show(state, crc_errors); flightInfo.show(state, crc_errors); - if (state.gps != null) { + + if (state.data.companion != null) { + if (!has_companion) { + pane.add("Companion", companion); + has_companion= true; + } + companion.show(state, crc_errors); + } else { + if (has_companion) { + pane.remove(companion); + has_companion = false; + } + } + if (state.gps != null && state.gps.connected) { if (!has_map) { pane.add("Site Map", sitemap); has_map = true; @@ -216,6 +231,9 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay { flightInfo = new AltosInfoTable(); pane.add("Table", new JScrollPane(flightInfo)); + companion = new AltosCompanionInfo(); + has_companion = false; + sitemap = new AltosSiteMap(); has_map = false; diff --git a/altosui/AltosRecord.java b/altosui/AltosRecord.java index 144b1c3c..ce6d86ab 100644 --- a/altosui/AltosRecord.java +++ b/altosui/AltosRecord.java @@ -32,6 +32,7 @@ public class AltosRecord { static final int seen_gps_time = 16; static final int seen_gps_lat = 32; static final int seen_gps_lon = 64; + static final int seen_companion = 128; int seen; int version; @@ -74,6 +75,8 @@ public class AltosRecord { int main_deploy; int flight_log_max; String firmware_version; + + AltosRecordCompanion companion; /* * Values for our MP3H6115A pressure sensor * @@ -267,6 +270,7 @@ public class AltosRecord { speed = old.speed; height = old.height; gps = new AltosGPS(old.gps); + companion = old.companion; } public AltosRecord() { @@ -296,5 +300,6 @@ public class AltosRecord { speed = MISSING; height = MISSING; gps = new AltosGPS(); + companion = null; } } diff --git a/altosui/AltosRecordCompanion.java b/altosui/AltosRecordCompanion.java new file mode 100644 index 00000000..0a8f9f4b --- /dev/null +++ b/altosui/AltosRecordCompanion.java @@ -0,0 +1,38 @@ +/* + * Copyright © 2011 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; + +public class AltosRecordCompanion { + final static int board_id_telescience = 0x0a; + final static int MAX_CHANNELS = 12; + + int tick; + int board_id; + int update_period; + int channels; + int[] companion_data; + + public AltosRecordCompanion(int in_channels) { + channels = in_channels; + if (channels < 0) + channels = 0; + if (channels > MAX_CHANNELS) + channels = MAX_CHANNELS; + companion_data = new int[channels]; + } +} diff --git a/altosui/AltosState.java b/altosui/AltosState.java index 378930bf..072cb790 100644 --- a/altosui/AltosState.java +++ b/altosui/AltosState.java @@ -73,7 +73,6 @@ public class AltosState { int speak_tick; double speak_altitude; - void init (AltosRecord cur, AltosState prev_state) { int i; AltosRecord prev; diff --git a/altosui/AltosTelemetryRecordCompanion.java b/altosui/AltosTelemetryRecordCompanion.java new file mode 100644 index 00000000..11b349e1 --- /dev/null +++ b/altosui/AltosTelemetryRecordCompanion.java @@ -0,0 +1,52 @@ +/* + * Copyright © 2011 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; + +public class AltosTelemetryRecordCompanion extends AltosTelemetryRecordRaw { + + AltosRecordCompanion companion; + + public AltosTelemetryRecordCompanion(int[] in_bytes) { + super(in_bytes); + + int off = 0; + if (uint8(6) == 0) + off = 1; + int channels = uint8(7+off); + + if (off != 0 && channels >= 12) + channels = 11; + + companion = new AltosRecordCompanion(channels); + companion.tick = tick; + companion.board_id = uint8(5); + companion.update_period = uint8(6+off); + for (int i = 0; i < channels; i++) + companion.companion_data[i] = uint16(8 + off + i * 2); + } + + public AltosRecord update_state(AltosRecord previous) { + AltosRecord next = super.update_state(previous); + + next.companion = companion; + next.seen |= AltosRecord.seen_sensor | AltosRecord.seen_temp_volt; + + companion.tick = tick; + return next; + } +} diff --git a/altosui/AltosTelemetryRecordRaw.java b/altosui/AltosTelemetryRecordRaw.java index 4b34f017..39b2ba07 100644 --- a/altosui/AltosTelemetryRecordRaw.java +++ b/altosui/AltosTelemetryRecordRaw.java @@ -33,6 +33,7 @@ public class AltosTelemetryRecordRaw implements AltosTelemetryRecord { final static int packet_type_configuration = 0x04; final static int packet_type_location = 0x05; final static int packet_type_satellite = 0x06; + final static int packet_type_companion = 0x07; final static int PKT_APPEND_STATUS_1_CRC_OK = (1 << 7); final static int PKT_APPEND_STATUS_1_LQI_MASK = (0x7f); @@ -89,6 +90,9 @@ public class AltosTelemetryRecordRaw implements AltosTelemetryRecord { case packet_type_satellite: r = new AltosTelemetryRecordSatellite(bytes); break; + case packet_type_companion: + r = new AltosTelemetryRecordCompanion(bytes); + break; default: r = new AltosTelemetryRecordRaw(bytes); break; @@ -139,9 +143,11 @@ public class AltosTelemetryRecordRaw implements AltosTelemetryRecord { public AltosRecord update_state(AltosRecord previous) { AltosRecord next; - if (previous != null) + if (previous != null) { next = new AltosRecord(previous); - else + while (tick < previous.tick) + tick += 65536; + } else next = new AltosRecord(); next.serial = serial; next.tick = tick; diff --git a/altosui/Makefile.am b/altosui/Makefile.am index bab8f816..83510352 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -20,6 +20,7 @@ altosui_JAVA = \ GrabNDrag.java \ AltosAscent.java \ AltosChannelMenu.java \ + AltosCompanionInfo.java \ AltosConfig.java \ AltosConfigData.java \ AltosConfigFreqUI.java \ @@ -77,6 +78,7 @@ altosui_JAVA = \ AltosPreferences.java \ AltosReader.java \ AltosRecord.java \ + AltosRecordCompanion.java \ AltosRecordIterable.java \ AltosTelemetryReader.java \ AltosTelemetryRecord.java \ @@ -86,6 +88,7 @@ altosui_JAVA = \ AltosTelemetryRecordConfiguration.java \ AltosTelemetryRecordLocation.java \ AltosTelemetryRecordSatellite.java \ + AltosTelemetryRecordCompanion.java \ AltosTelemetryRecordLegacy.java \ AltosTelemetryMap.java \ AltosReplayReader.java \ -- 2.30.2