LinkedList<AltosRecord> 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
*
* 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() {
}
}
- 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();
out.printf(","); write_gps_header();
out.printf(","); write_gps_sat_header();
}
+ if (companion) {
+ out.printf(","); write_companion_header();
+ }
out.printf ("\n");
}
write_gps(record); out.printf(",");
write_gps_sat(record);
}
+ if (record.companion != null) {
+ out.printf(",");
+ write_companion(record);
+ }
out.printf ("\n");
}
}
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) {
--- /dev/null
+/*
+ * Copyright © 2010 Keith Packard <keithp@keithp.com>
+ *
+ * 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();
+ }
+}
AltosAscent ascent;
AltosDescent descent;
AltosLanded landed;
+ AltosCompanionInfo companion;
AltosSiteMap sitemap;
boolean has_map;
+ boolean has_companion;
private AltosFlightStatus flightStatus;
private AltosInfoTable flightInfo;
}
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;
flightInfo = new AltosInfoTable();
pane.add("Table", new JScrollPane(flightInfo));
+ companion = new AltosCompanionInfo();
+ has_companion = false;
+
sitemap = new AltosSiteMap();
has_map = false;
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;
int main_deploy;
int flight_log_max;
String firmware_version;
+
+ AltosRecordCompanion companion;
/*
* Values for our MP3H6115A pressure sensor
*
speed = old.speed;
height = old.height;
gps = new AltosGPS(old.gps);
+ companion = old.companion;
}
public AltosRecord() {
speed = MISSING;
height = MISSING;
gps = new AltosGPS();
+ companion = null;
}
}
--- /dev/null
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * 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];
+ }
+}
int speak_tick;
double speak_altitude;
-
void init (AltosRecord cur, AltosState prev_state) {
int i;
AltosRecord prev;
--- /dev/null
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * 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;
+ }
+}
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);
case packet_type_satellite:
r = new AltosTelemetryRecordSatellite(bytes);
break;
+ case packet_type_companion:
+ r = new AltosTelemetryRecordCompanion(bytes);
+ break;
default:
r = new AltosTelemetryRecordRaw(bytes);
break;
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;
GrabNDrag.java \
AltosAscent.java \
AltosChannelMenu.java \
+ AltosCompanionInfo.java \
AltosConfig.java \
AltosConfigData.java \
AltosConfigFreqUI.java \
AltosPreferences.java \
AltosReader.java \
AltosRecord.java \
+ AltosRecordCompanion.java \
AltosRecordIterable.java \
AltosTelemetryReader.java \
AltosTelemetryRecord.java \
AltosTelemetryRecordConfiguration.java \
AltosTelemetryRecordLocation.java \
AltosTelemetryRecordSatellite.java \
+ AltosTelemetryRecordCompanion.java \
AltosTelemetryRecordLegacy.java \
AltosTelemetryMap.java \
AltosReplayReader.java \