*
* 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.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_4.*;
-import org.altusmetrum.altosuilib_2.*;
+import java.text.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class TeleGPS
extends AltosUIFrame
- implements AltosFlightDisplay, AltosFontListener, AltosUnitsListener, ActionListener
+ implements AltosFlightDisplay, AltosFontListener, AltosUnitsListener, ActionListener, AltosEepromGrapher
{
static String[] telegps_icon_names = {
- "/telegps-16.png",
- "/telegps-32.png",
- "/telegps-48.png",
- "/telegps-64.png",
- "/telegps-128.png",
- "/telegps-256.png"
+ "/altusmetrum-telegps-16.png",
+ "/altusmetrum-telegps-32.png",
+ "/altusmetrum-telegps-48.png",
+ "/altusmetrum-telegps-64.png",
+ "/altusmetrum-telegps-128.png",
+ "/altusmetrum-telegps-256.png"
};
static { set_icon_names(telegps_icon_names); }
AltosFlightReader reader;
TeleGPSDisplayThread thread;
+ boolean idle_mode;
JMenuBar menu_bar;
JMenu file_menu;
JMenu monitor_menu;
JMenu device_menu;
- AltosFreqList frequencies;
+ AltosUIFreqList frequencies;
+ ActionListener frequency_listener;
+ AltosUIRateList rates;
+ ActionListener rate_listener;
Container bag;
JTabbedPane pane;
- AltosUIMap map;
+ AltosUIMap map;
TeleGPSInfo gps_info;
+ TeleGPSState gps_state;
AltosInfoTable info_table;
LinkedList<AltosFlightDisplay> displays;
/* File menu */
final static String new_command = "new";
- final static String preferences_command = "preferences";
+ final static String graph_command = "graph";
+ final static String export_command = "export";
final static String load_maps_command = "loadmaps";
+ final static String preferences_command = "preferences";
final static String close_command = "close";
final static String exit_command = "exit";
static final String[][] file_menu_entries = new String[][] {
{ "New Window", new_command },
- { "Preferences", preferences_command },
+ { "Graph Data", graph_command },
+ { "Export Data", export_command },
{ "Load Maps", load_maps_command },
+ { "Preferences", preferences_command },
{ "Close", close_command },
{ "Exit", exit_command },
};
/* Monitor menu */
- final static String monitor_command = "monitor";
+ final static String connect_command = "connect";
final static String disconnect_command = "disconnect";
final static String scan_command = "scan";
static final String[][] monitor_menu_entries = new String[][] {
- { "Monitor Device", monitor_command },
+ { "Connect Device", connect_command },
{ "Disconnect", disconnect_command },
{ "Scan Channels", scan_command },
};
/* Device menu */
final static String download_command = "download";
- final static String export_command = "export";
- final static String graph_command = "graph";
final static String configure_command = "configure";
final static String flash_command = "flash";
static final String[][] device_menu_entries = new String[][] {
{ "Download Data", download_command },
{ "Configure Device", configure_command },
- { "Export Data", export_command },
- { "Graph Data", graph_command },
{ "Flash Device", flash_command },
};
public void show(AltosState state, AltosListenerState listener_state) {
try {
status_update.saved_state = state;
+ status_update.saved_listener_state = listener_state;
if (state == null)
- state = new AltosState();
+ state = new AltosState(new AltosCalData());
int i = 0;
for (AltosFlightDisplay display : displays) {
void disconnect() {
setTitle("TeleGPS");
stop_display();
- remove_frequency_menu();
+ telegps_status.stop();
+
+ telegps_status.disable_receive();
+ disable_frequency_menu();
+ disable_rate_menu();
}
- void connect(AltosDevice device) {
- if (reader != null)
- disconnect();
+ void connect_flight(AltosDevice device) {
try {
AltosFlightReader reader = new AltosTelemetryReader(new AltosSerial(device));
- set_reader(reader);
- add_frequency_menu(device.getSerial(), reader);
+ set_reader(reader, device, false);
} catch (FileNotFoundException ee) {
JOptionPane.showMessageDialog(this,
ee.getMessage(),
}
}
- void monitor() {
+ void connect_idle(AltosDevice device) {
+ try {
+ AltosFlightReader reader = new AltosIdleReader(new AltosSerial(device), false);
+ set_reader(reader, device, true);
+ } catch (FileNotFoundException ee) {
+ JOptionPane.showMessageDialog(this,
+ ee.getMessage(),
+ String.format ("Cannot open %s", device.toShortString()),
+ JOptionPane.ERROR_MESSAGE);
+ } catch (AltosSerialInUseException si) {
+ JOptionPane.showMessageDialog(this,
+ String.format("Device \"%s\" already in use",
+ device.toShortString()),
+ "Device in use",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (IOException ee) {
+ JOptionPane.showMessageDialog(this,
+ String.format ("Unknown I/O error on %s", device.toShortString()),
+ "Unknown I/O error",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (TimeoutException te) {
+ JOptionPane.showMessageDialog(this,
+ String.format ("Timeout on %s", device.toShortString()),
+ "Timeout error",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (InterruptedException ie) {
+ JOptionPane.showMessageDialog(this,
+ String.format("Interrupted %s", device.toShortString()),
+ "Interrupted exception",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ void connect(AltosDevice device) {
+ if (reader != null)
+ disconnect();
+ if (device.matchProduct(AltosLib.product_basestation))
+ connect_flight(device);
+ else
+ connect_idle(device);
+ }
+
+ void connect() {
AltosDevice device = AltosDeviceUIDialog.show(this,
- AltosLib.product_basestation);
+ AltosLib.product_any);
if (device == null)
return;
connect(device);
}
void download(){
- new AltosEepromManage(this, AltosLib.product_telegps);
+ new AltosEepromManage(this, this, AltosLib.product_telegps);
}
void configure() {
new TeleGPSConfig(this);
}
+ private static AltosFlightSeries make_series(AltosRecordSet set) {
+ AltosFlightSeries series = new AltosFlightSeries(set.cal_data());
+ set.capture_series(series);
+ series.finish();
+ return series;
+ }
+
void export() {
- AltosDataChooser chooser;
- chooser = new AltosDataChooser(this);
- AltosStateIterable states = chooser.runDialog();
- if (states == null)
+ AltosDataChooser chooser = new AltosDataChooser(this);
+
+ AltosRecordSet set = chooser.runDialog();
+ if (set == null)
return;
- new AltosCSVUI(this, states, chooser.file());
+ AltosFlightSeries series = make_series(set);
+ new AltosCSVUI(this, series, chooser.file());
}
void graph() {
- AltosDataChooser chooser;
- chooser = new AltosDataChooser(this);
- AltosStateIterable states = chooser.runDialog();
- if (states == null)
+ AltosDataChooser chooser = new AltosDataChooser(this);
+ AltosRecordSet set = chooser.runDialog();
+ if (set == null)
return;
try {
- new TeleGPSGraphUI(states, chooser.file());
+ new TeleGPSGraphUI(set, chooser.file());
} catch (InterruptedException ie) {
} catch (IOException ie) {
}
}
+ public void graph_flights(AltosEepromList list) {
+ for (AltosEepromLog log : list) {
+ if (log.file != null) {
+ AltosRecordSet set = record_set(log.file);
+ if (set != null) {
+ try {
+ new TeleGPSGraphUI(set, log.file);
+ } catch (InterruptedException ie) {
+ } catch (IOException ie) {
+ }
+ }
+ }
+ }
+ }
+
void flash() {
AltosFlashUI.show(this);
}
System.exit(0);
/* Monitor menu */
- if (monitor_command.equals(ev.getActionCommand())) {
- monitor();
+ if (connect_command.equals(ev.getActionCommand())) {
+ connect();
return;
}
if (disconnect_command.equals(ev.getActionCommand())) {
}
}
- void add_frequency_menu(int serial, final AltosFlightReader reader) {
- // Channel menu
- if (frequencies != null)
- return;
+ void enable_frequency_menu(int serial, final AltosFlightReader reader) {
- frequencies = new AltosFreqList(AltosUIPreferences.frequency(serial));
- frequencies.set_product("Monitor");
- frequencies.set_serial(serial);
- frequencies.addActionListener(new ActionListener() {
+ if (frequency_listener != null)
+ disable_frequency_menu();
+
+ frequency_listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
double frequency = frequencies.frequency();
try {
}
reader.save_frequency();
}
- });
- menu_bar.add(frequencies);
+ };
+
+ frequencies.addActionListener(frequency_listener);
+ frequencies.set_product("Monitor");
+ frequencies.set_serial(serial);
+ frequencies.set_frequency(AltosUIPreferences.frequency(serial));
+ frequencies.setEnabled(true);
+
+ }
+
+ void disable_frequency_menu() {
+ if (frequency_listener != null) {
+ frequencies.removeActionListener(frequency_listener);
+ frequencies.setEnabled(false);
+ frequency_listener = null;
+ }
+
}
- void remove_frequency_menu() {
- if (frequencies != null) {
- menu_bar.remove(frequencies);
- menu_bar.repaint();
- frequencies = null;
+ void enable_rate_menu(int serial, final AltosFlightReader reader) {
+
+ if (rate_listener != null)
+ disable_rate_menu();
+
+ rate_listener = new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ int rate = rates.rate();
+ try {
+ reader.set_telemetry_rate(rate);
+ } catch (TimeoutException te) {
+ } catch (InterruptedException ie) {
+ }
+ reader.save_telemetry_rate();
+ }
+ };
+
+ rates.addActionListener(rate_listener);
+ rates.set_product("Monitor");
+ rates.set_serial(serial);
+ rates.set_rate(AltosUIPreferences.telemetry_rate(serial));
+ rates.setEnabled(reader.supports_telemetry_rate(AltosLib.ao_telemetry_rate_2400));
+ }
+
+ void disable_rate_menu() {
+ if (rate_listener != null) {
+ rates.removeActionListener(rate_listener);
+ rates.setEnabled(false);
+ rate_listener = null;
}
+
}
- public void set_reader(AltosFlightReader reader) {
+ public void set_reader(AltosFlightReader reader, AltosDevice device, boolean idle_mode) {
+ this.idle_mode = idle_mode;
+ status_update = new TeleGPSStatusUpdate(telegps_status);
+
+ telegps_status.start(status_update);
+
setTitle(String.format("TeleGPS %s", reader.name));
thread = new TeleGPSDisplayThread(this, voice(), this, reader);
thread.start();
+
+ if (device != null) {
+ if (idle_mode) {
+ disable_frequency_menu();
+ disable_rate_menu();
+ } else {
+ enable_frequency_menu(device.getSerial(), reader);
+ enable_rate_menu(device.getSerial(), reader);
+ }
+ }
}
static int number_of_windows;
}
private void close() {
+ disconnect();
AltosUIPreferences.unregister_font_listener(this);
AltosPreferences.unregister_units_listener(this);
setVisible(false);
private JMenu make_menu(String label, String[][] items) {
JMenu menu = new JMenu(label);
- for (int i = 0; i < items.length; i++)
+ for (int i = 0; i < items.length; i++) {
+ if (MAC_OS_X) {
+ if (items[i][1].equals("exit"))
+ continue;
+ if (items[i][1].equals("preferences"))
+ continue;
+ }
add_menu(menu, items[i][0], items[i][1]);
+ }
menu_bar.add(menu);
return menu;
}
+ /* OSXAdapter interfaces */
+ public void macosx_file_handler(String path) {
+ process_graph(new File(path));
+ }
+
+ public void macosx_quit_handler() {
+ System.exit(0);
+ }
+
+ public void macosx_preferences_handler() {
+ preferences();
+ }
+
public TeleGPS() {
AltosUIPreferences.set_component(this);
+ register_for_macosx_events();
+
reader = null;
bag = getContentPane();
bag.setLayout(new GridBagLayout());
- GridBagConstraints c = new GridBagConstraints();
-
setTitle("TeleGPS");
menu_bar = new JMenuBar();
file_menu = make_menu("File", file_menu_entries);
monitor_menu = make_menu("Monitor", monitor_menu_entries);
device_menu = make_menu("Device", device_menu_entries);
+
+ set_inset(3);
+ frequencies = new AltosUIFreqList();
+ frequencies.setEnabled(false);
+ bag.add(frequencies, constraints (0, 1));
+
+ rates = new AltosUIRateList();
+ rates.setEnabled(false);
+ bag.add(rates, constraints(1, 1));
+ next_row();
+ set_inset(0);
+
displays = new LinkedList<AltosFlightDisplay>();
int serial = -1;
/* TeleGPS status is always visible */
telegps_status = new TeleGPSStatus();
- c.gridx = 0;
- c.gridy = 1;
- c.fill = GridBagConstraints.HORIZONTAL;
- c.weightx = 1;
- c.gridwidth = 2;
- bag.add(telegps_status, c);
- c.gridwidth = 1;
+ bag.add(telegps_status, constraints(0, 3, GridBagConstraints.HORIZONTAL));
+ next_row();
+
displays.add(telegps_status);
pane = new JTabbedPane();
/* Make the tabbed pane use the rest of the window space */
- c.gridx = 0;
- c.gridy = 2;
- c.fill = GridBagConstraints.BOTH;
- c.weightx = 1;
- c.weighty = 1;
- c.gridwidth = 2;
- bag.add(pane, c);
+ bag.add(pane, constraints(0, 3, GridBagConstraints.BOTH));
map = new AltosUIMap();
- pane.add("Map", map);
+ pane.add(map.getName(), map);
displays.add(map);
gps_info = new TeleGPSInfo();
- pane.add("Info", gps_info);
+ pane.add(gps_info.getName(), gps_info);
displays.add(gps_info);
+ gps_state = new TeleGPSState();
+ pane.add(gps_state.getName(), gps_state);
+ displays.add(gps_state);
+
info_table = new AltosInfoTable();
pane.add("Table", info_table);
displays.add(info_table);
setVisible(true);
add_window();
-
- status_update = new TeleGPSStatusUpdate(telegps_status);
-
- new javax.swing.Timer(100, status_update).start();
}
- public TeleGPS(AltosFlightReader reader) {
+ public TeleGPS(AltosFlightReader reader, boolean idle_mode) {
this();
- set_reader(reader);
+ set_reader(reader, null, idle_mode);
}
public TeleGPS(AltosDevice device) {
connect(device);
}
- static AltosStateIterable record_iterable(File file) {
- FileInputStream in;
+ static AltosRecordSet record_set(File file) {
try {
- in = new FileInputStream(file);
- } catch (Exception e) {
- System.out.printf("Failed to open file '%s'\n", file);
- return null;
- }
- if (file.getName().endsWith("telem"))
- return new AltosTelemetryFile(in);
- else
- return new AltosEepromFile(in);
+ return AltosLib.record_set(file);
+ } catch (IOException ie) {
+ System.out.printf("%s\n", ie.getMessage());
+ }
+ return null;
}
static AltosReplayReader replay_file(File file) {
- AltosStateIterable states = record_iterable(file);
- if (states == null)
+ AltosRecordSet set = record_set(file);
+ if (set == null)
return null;
- return new AltosReplayReader(states.iterator(), file);
+ return new AltosReplayReader(set, file);
}
static boolean process_graph(File file) {
- AltosStateIterable states = record_iterable(file);
- if (states == null)
+ AltosRecordSet set = record_set(file);
+ if (set == null)
return false;
try {
- new TeleGPSGraphUI(states, file);
+ new TeleGPSGraphUI(set, file);
} catch (Exception e) {
return false;
}
if (new_reader == null)
return false;
- new TeleGPS(new_reader);
+ new TeleGPS(new_reader, true);
return true;
}
public static void help(int code) {
System.out.printf("Usage: altosui [OPTION]... [FILE]...\n");
System.out.printf(" Options:\n");
- System.out.printf(" --fetchmaps <lat> <lon>\tpre-fetch maps for site map view\n");
System.out.printf(" --replay <filename>\t\trelive the glory of past flights \n");
System.out.printf(" --graph <filename>\t\tgraph a flight\n");
System.out.printf(" --csv\tgenerate comma separated output for spreadsheets, etc\n");
for (int i = 0; i < args.length; i++) {
if (args[i].equals("--help"))
help(0);
- else if (args[i].equals("--fetchmaps")) {
- if (args.length < i + 3) {
- help(1);
- } else {
- double lat = Double.parseDouble(args[i+1]);
- double lon = Double.parseDouble(args[i+2]);
- AltosUIMap.prefetch_maps(lat, lon);
- i += 2;
- }
- } else if (args[i].equals("--replay"))
+ else if (args[i].equals("--replay"))
process = process_replay;
else if (args[i].equals("--kml"))
process = process_kml;