Merge branch 'buttonbox' of git://git.gag.com/fw/altos into buttonbox
authorAnthony Towns <aj@erisian.com.au>
Wed, 17 Nov 2010 19:54:06 +0000 (05:54 +1000)
committerAnthony Towns <aj@erisian.com.au>
Wed, 17 Nov 2010 19:54:06 +0000 (05:54 +1000)
Conflicts:
ao-tools/altosui/AltosFlightUI.java

45 files changed:
ao-tools/altosui/Altos.java
ao-tools/altosui/AltosAscent.java
ao-tools/altosui/AltosCSVUI.java
ao-tools/altosui/AltosConfig.java
ao-tools/altosui/AltosConfigUI.java
ao-tools/altosui/AltosConfigureUI.java [new file with mode: 0644]
ao-tools/altosui/AltosDataPointReader.java
ao-tools/altosui/AltosDebug.java
ao-tools/altosui/AltosDescent.java
ao-tools/altosui/AltosDeviceDialog.java
ao-tools/altosui/AltosEepromDownload.java
ao-tools/altosui/AltosEepromIterable.java
ao-tools/altosui/AltosEepromMonitor.java
ao-tools/altosui/AltosEepromRecord.java
ao-tools/altosui/AltosFile.java
ao-tools/altosui/AltosFlash.java
ao-tools/altosui/AltosFlashUI.java
ao-tools/altosui/AltosFlightInfoTableModel.java
ao-tools/altosui/AltosFlightStatus.java [new file with mode: 0644]
ao-tools/altosui/AltosFlightUI.java
ao-tools/altosui/AltosGPS.java
ao-tools/altosui/AltosGraph.java
ao-tools/altosui/AltosGraphDataChooser.java
ao-tools/altosui/AltosGraphTime.java
ao-tools/altosui/AltosGraphUI.java
ao-tools/altosui/AltosGreatCircle.java
ao-tools/altosui/AltosInfoTable.java
ao-tools/altosui/AltosLanded.java
ao-tools/altosui/AltosLog.java
ao-tools/altosui/AltosPad.java
ao-tools/altosui/AltosParse.java
ao-tools/altosui/AltosReader.java
ao-tools/altosui/AltosRecord.java
ao-tools/altosui/AltosRecordIterable.java
ao-tools/altosui/AltosRomconfig.java
ao-tools/altosui/AltosRomconfigUI.java
ao-tools/altosui/AltosSerial.java
ao-tools/altosui/AltosSerialInUseException.java [new file with mode: 0644]
ao-tools/altosui/AltosState.java
ao-tools/altosui/AltosStatusTable.java [deleted file]
ao-tools/altosui/AltosTelemetry.java
ao-tools/altosui/AltosTelemetryIterable.java
ao-tools/altosui/AltosTelemetryReader.java
ao-tools/altosui/AltosUI.java
ao-tools/altosui/Makefile.am

index 997550e005ac91fc1de2cdbb03c67aad6c88355e..197e98db7956bc4645fbcadb1ec9e8fe5f596320 100644 (file)
@@ -67,6 +67,12 @@ public class Altos {
 
        static boolean map_initialized = false;
 
+       static final int tab_elt_pad = 5;
+
+       static final Font label_font = new Font("Dialog", Font.PLAIN, 22);
+       static final Font value_font = new Font("Monospaced", Font.PLAIN, 22);
+       static final Font status_font = new Font("SansSerif", Font.BOLD, 24);
+
        static void initialize_map()
        {
                string_to_state.put("startup", ao_flight_startup);
index 51fa1a89d0f0a3b3ad315f2d62f1274c4671887b..38ced95eeb3593712a734b643f716e09fa1fed9c 100644 (file)
@@ -30,8 +30,53 @@ import java.util.concurrent.LinkedBlockingQueue;
 
 public class AltosAscent extends JComponent implements AltosFlightDisplay {
        GridBagLayout   layout;
-       Font            label_font;
-       Font            value_font;
+
+       public class AscentStatus {
+               JLabel          label;
+               JTextField      value;
+               AltosLights     lights;
+
+               void show(AltosState state, int crc_errors) {}
+               void reset() {
+                       value.setText("");
+                       lights.set(false);
+               }
+
+               public AscentStatus (GridBagLayout layout, int y, String text) {
+                       GridBagConstraints      c = new GridBagConstraints();
+                       c.weighty = 1;
+
+                       lights = new AltosLights();
+                       c.gridx = 0; c.gridy = y;
+                       c.anchor = GridBagConstraints.CENTER;
+                       c.fill = GridBagConstraints.VERTICAL;
+                       c.weightx = 0;
+                       layout.setConstraints(lights, c);
+                       add(lights);
+
+                       label = new JLabel(text);
+                       label.setFont(Altos.label_font);
+                       label.setHorizontalAlignment(SwingConstants.LEFT);
+                       c.gridx = 1; c.gridy = y;
+                       c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
+                       c.anchor = GridBagConstraints.WEST;
+                       c.fill = GridBagConstraints.VERTICAL;
+                       c.weightx = 0;
+                       layout.setConstraints(label, c);
+                       add(label);
+
+                       value = new JTextField(15);
+                       value.setFont(Altos.value_font);
+                       value.setHorizontalAlignment(SwingConstants.RIGHT);
+                       c.gridx = 2; c.gridy = y;
+                       c.anchor = GridBagConstraints.WEST;
+                       c.fill = GridBagConstraints.BOTH;
+                       c.weightx = 1;
+                       layout.setConstraints(value, c);
+                       add(value);
+
+               }
+       }
 
        public class AscentValue {
                JLabel          label;
@@ -43,23 +88,27 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
                }
                public AscentValue (GridBagLayout layout, int y, String text) {
                        GridBagConstraints      c = new GridBagConstraints();
+                       c.weighty = 1;
 
                        label = new JLabel(text);
-                       label.setFont(label_font);
+                       label.setFont(Altos.label_font);
                        label.setHorizontalAlignment(SwingConstants.LEFT);
                        c.gridx = 0; c.gridy = y;
-                       c.insets = new Insets(10, 10, 10, 10);
+                       c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
                        c.anchor = GridBagConstraints.WEST;
+                       c.fill = GridBagConstraints.VERTICAL;
+                       c.weightx = 0;
                        layout.setConstraints(label, c);
                        add(label);
 
                        value = new JTextField(30);
-                       value.setFont(value_font);
+                       value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 1; c.gridy = y;
                        c.anchor = GridBagConstraints.WEST;
-                       c.fill = GridBagConstraints.HORIZONTAL;
+                       c.fill = GridBagConstraints.BOTH;
                        c.gridwidth = 2;
+                       c.weightx = 1;
                        layout.setConstraints(value, c);
                        add(value);
                }
@@ -88,29 +137,36 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
                }
                public AscentValueHold (GridBagLayout layout, int y, String text) {
                        GridBagConstraints      c = new GridBagConstraints();
+                       c.weighty = 1;
 
                        label = new JLabel(text);
-                       label.setFont(label_font);
+                       label.setFont(Altos.label_font);
                        label.setHorizontalAlignment(SwingConstants.LEFT);
                        c.gridx = 0; c.gridy = y;
-                       c.insets = new Insets(10, 10, 10, 10);
+                       c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
                        c.anchor = GridBagConstraints.WEST;
+                       c.fill = GridBagConstraints.VERTICAL;
+                       c.weightx = 0;
                        layout.setConstraints(label, c);
                        add(label);
 
                        value = new JTextField(15);
-                       value.setFont(value_font);
+                       value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 1; c.gridy = y;
                        c.anchor = GridBagConstraints.EAST;
+                       c.fill = GridBagConstraints.BOTH;
+                       c.weightx = 1;
                        layout.setConstraints(value, c);
                        add(value);
 
                        max_value = new JTextField(15);
-                       max_value.setFont(value_font);
+                       max_value.setFont(Altos.value_font);
                        max_value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
                        c.anchor = GridBagConstraints.EAST;
+                       c.fill = GridBagConstraints.BOTH;
+                       c.weightx = 1;
                        layout.setConstraints(max_value, c);
                        add(max_value);
                }
@@ -164,6 +220,30 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
                return String.format("%s %4d° %9.6f", h, deg, min);
        }
 
+       class Apogee extends AscentStatus {
+               void show (AltosState state, int crc_errors) {
+                       value.setText(String.format("%4.2f V", state.drogue_sense));
+                       lights.set(state.drogue_sense > 3.2);
+               }
+               public Apogee (GridBagLayout layout, int y) {
+                       super(layout, y, "Apogee Igniter Voltage");
+               }
+       }
+
+       Apogee apogee;
+
+       class Main extends AscentStatus {
+               void show (AltosState state, int crc_errors) {
+                       value.setText(String.format("%4.2f V", state.main_sense));
+                       lights.set(state.main_sense > 3.2);
+               }
+               public Main (GridBagLayout layout, int y) {
+                       super(layout, y, "Main Igniter Voltage");
+               }
+       }
+
+       Main main;
+
        class Lat extends AscentValue {
                void show (AltosState state, int crc_errors) {
                        if (state.gps != null)
@@ -195,6 +275,8 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
        public void reset() {
                lat.reset();
                lon.reset();
+               main.reset();
+               apogee.reset();
                height.reset();
                speed.reset();
                accel.reset();
@@ -204,6 +286,8 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
                lat.show(state, crc_errors);
                lon.show(state, crc_errors);
                height.show(state, crc_errors);
+               main.show(state, crc_errors);
+               apogee.show(state, crc_errors);
                speed.show(state, crc_errors);
                accel.show(state, crc_errors);
        }
@@ -213,15 +297,15 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
                JLabel                  cur, max;
 
                cur = new JLabel("Current");
-               cur.setFont(label_font);
+               cur.setFont(Altos.label_font);
                c = new GridBagConstraints();
                c.gridx = 1; c.gridy = y;
-               c.insets = new Insets(10, 10, 10, 10);
+               c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
                layout.setConstraints(cur, c);
                add(cur);
 
                max = new JLabel("Maximum");
-               max.setFont(label_font);
+               max.setFont(Altos.label_font);
                c.gridx = 2; c.gridy = y;
                layout.setConstraints(max, c);
                add(max);
@@ -230,8 +314,6 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
        public AltosAscent() {
                layout = new GridBagLayout();
 
-               label_font = new Font("Dialog", Font.PLAIN, 24);
-               value_font = new Font("Monospaced", Font.PLAIN, 24);
                setLayout(layout);
 
                /* Elements in ascent display:
@@ -246,5 +328,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
                accel = new Accel(layout, 3);
                lat = new Lat(layout, 4);
                lon = new Lon(layout, 5);
+               apogee = new Apogee(layout, 6);
+               main = new Main(layout, 7);
        }
 }
index eb620ba82a7ab69176a266e89fadab2cd5d1e96c..16f253380419029dfb788823741e18ec550276c5 100644 (file)
@@ -28,9 +28,6 @@ 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
index b7474f3b2fa56faea8ee6d14858da68916e064f1..a0fdb6236cfc3491cfb45abf7eb2d8dba4ab2360 100644 (file)
@@ -28,20 +28,6 @@ import java.text.*;
 import java.util.prefs.*;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import altosui.Altos;
-import altosui.AltosSerial;
-import altosui.AltosSerialMonitor;
-import altosui.AltosRecord;
-import altosui.AltosTelemetry;
-import altosui.AltosState;
-import altosui.AltosDeviceDialog;
-import altosui.AltosPreferences;
-import altosui.AltosLog;
-import altosui.AltosVoice;
-import altosui.AltosFlightStatusTableModel;
-import altosui.AltosFlightInfoTableModel;
-import altosui.AltosConfigUI;
-
 import libaltosJNI.*;
 
 public class AltosConfig implements Runnable, ActionListener {
@@ -212,12 +198,26 @@ public class AltosConfig implements Runnable, ActionListener {
 
        public void actionPerformed(ActionEvent e) {
                String  cmd = e.getActionCommand();
-               if (cmd.equals("save")) {
+               if (cmd.equals("Save")) {
                        save_data();
                        set_ui();
-               } else if (cmd.equals("reset")) {
+               } else if (cmd.equals("Reset")) {
                        set_ui();
-               } else if (cmd.equals("close")) {
+               } else if (cmd.equals("Reboot")) {
+                       if (serial_line != null) {
+                               try {
+                                       start_serial();
+                                       serial_line.printf("r eboot\n");
+                               } catch (InterruptedException ie) {
+                               } finally {
+                                       try {
+                                               stop_serial();
+                                       } catch (InterruptedException ie) {
+                                       }
+                               }
+                               serial_line.close();
+                       }
+               } else if (cmd.equals("Close")) {
                        if (serial_line != null)
                                serial_line.close();
                }
@@ -245,10 +245,9 @@ public class AltosConfig implements Runnable, ActionListener {
                product = new string_ref("unknown");
 
                device = AltosDeviceDialog.show(owner, AltosDevice.product_any);
-               serial_line = new AltosSerial();
                if (device != null) {
                        try {
-                               serial_line.open(device);
+                               serial_line = new AltosSerial(device);
                                if (!device.matchProduct(AltosDevice.product_telemetrum))
                                        remote = true;
                                config_thread = new Thread(this);
@@ -259,6 +258,12 @@ public class AltosConfig implements Runnable, ActionListener {
                                                                            device.getPath()),
                                                              "Cannot open target device",
                                                              JOptionPane.ERROR_MESSAGE);
+                       } catch (AltosSerialInUseException si) {
+                               JOptionPane.showMessageDialog(owner,
+                                                             String.format("Device \"%s\" already in use",
+                                                                           device.getPath()),
+                                                             "Device in use",
+                                                             JOptionPane.ERROR_MESSAGE);
                        } catch (IOException ee) {
                                JOptionPane.showMessageDialog(owner,
                                                              device.getPath(),
index 37128573c966ea39cd57fba2c7f5fab6dc8da63a..ca89f58d39de23b6f9becc002336efe0e43639e3 100644 (file)
@@ -29,19 +29,6 @@ import java.text.*;
 import java.util.prefs.*;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import altosui.Altos;
-import altosui.AltosSerial;
-import altosui.AltosSerialMonitor;
-import altosui.AltosRecord;
-import altosui.AltosTelemetry;
-import altosui.AltosState;
-import altosui.AltosDeviceDialog;
-import altosui.AltosPreferences;
-import altosui.AltosLog;
-import altosui.AltosVoice;
-import altosui.AltosFlightStatusTableModel;
-import altosui.AltosFlightInfoTableModel;
-
 import libaltosJNI.*;
 
 public class AltosConfigUI
@@ -74,6 +61,7 @@ public class AltosConfigUI
 
        JButton         save;
        JButton         reset;
+       JButton         reboot;
        JButton         close;
 
        ActionListener  listener;
@@ -105,7 +93,7 @@ public class AltosConfigUI
                public void windowClosing(WindowEvent e) {
                        ui.actionPerformed(new ActionEvent(e.getSource(),
                                                           ActionEvent.ACTION_PERFORMED,
-                                                          "close"));
+                                                          "Close"));
                }
        }
 
@@ -125,7 +113,7 @@ public class AltosConfigUI
                /* Product */
                c = new GridBagConstraints();
                c.gridx = 0; c.gridy = 0;
-               c.gridwidth = 3;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.NONE;
                c.anchor = GridBagConstraints.LINE_START;
                c.insets = il;
@@ -133,8 +121,8 @@ public class AltosConfigUI
                pane.add(product_label, c);
 
                c = new GridBagConstraints();
-               c.gridx = 3; c.gridy = 0;
-               c.gridwidth = 3;
+               c.gridx = 4; c.gridy = 0;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.HORIZONTAL;
                c.weightx = 1;
                c.anchor = GridBagConstraints.LINE_START;
@@ -145,7 +133,7 @@ public class AltosConfigUI
                /* Version */
                c = new GridBagConstraints();
                c.gridx = 0; c.gridy = 1;
-               c.gridwidth = 3;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.NONE;
                c.anchor = GridBagConstraints.LINE_START;
                c.insets = il;
@@ -154,8 +142,8 @@ public class AltosConfigUI
                pane.add(version_label, c);
 
                c = new GridBagConstraints();
-               c.gridx = 3; c.gridy = 1;
-               c.gridwidth = 3;
+               c.gridx = 4; c.gridy = 1;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.HORIZONTAL;
                c.weightx = 1;
                c.anchor = GridBagConstraints.LINE_START;
@@ -167,7 +155,7 @@ public class AltosConfigUI
                /* Serial */
                c = new GridBagConstraints();
                c.gridx = 0; c.gridy = 2;
-               c.gridwidth = 3;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.NONE;
                c.anchor = GridBagConstraints.LINE_START;
                c.insets = il;
@@ -176,8 +164,8 @@ public class AltosConfigUI
                pane.add(serial_label, c);
 
                c = new GridBagConstraints();
-               c.gridx = 3; c.gridy = 2;
-               c.gridwidth = 3;
+               c.gridx = 4; c.gridy = 2;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.HORIZONTAL;
                c.weightx = 1;
                c.anchor = GridBagConstraints.LINE_START;
@@ -189,7 +177,7 @@ public class AltosConfigUI
                /* Main deploy */
                c = new GridBagConstraints();
                c.gridx = 0; c.gridy = 3;
-               c.gridwidth = 3;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.NONE;
                c.anchor = GridBagConstraints.LINE_START;
                c.insets = il;
@@ -198,8 +186,8 @@ public class AltosConfigUI
                pane.add(main_deploy_label, c);
 
                c = new GridBagConstraints();
-               c.gridx = 3; c.gridy = 3;
-               c.gridwidth = 3;
+               c.gridx = 4; c.gridy = 3;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.HORIZONTAL;
                c.weightx = 1;
                c.anchor = GridBagConstraints.LINE_START;
@@ -213,7 +201,7 @@ public class AltosConfigUI
                /* Apogee delay */
                c = new GridBagConstraints();
                c.gridx = 0; c.gridy = 4;
-               c.gridwidth = 3;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.NONE;
                c.anchor = GridBagConstraints.LINE_START;
                c.insets = il;
@@ -222,8 +210,8 @@ public class AltosConfigUI
                pane.add(apogee_delay_label, c);
 
                c = new GridBagConstraints();
-               c.gridx = 3; c.gridy = 4;
-               c.gridwidth = 3;
+               c.gridx = 4; c.gridy = 4;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.HORIZONTAL;
                c.weightx = 1;
                c.anchor = GridBagConstraints.LINE_START;
@@ -237,7 +225,7 @@ public class AltosConfigUI
                /* Radio channel */
                c = new GridBagConstraints();
                c.gridx = 0; c.gridy = 5;
-               c.gridwidth = 3;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.NONE;
                c.anchor = GridBagConstraints.LINE_START;
                c.insets = il;
@@ -246,8 +234,8 @@ public class AltosConfigUI
                pane.add(radio_channel_label, c);
 
                c = new GridBagConstraints();
-               c.gridx = 3; c.gridy = 5;
-               c.gridwidth = 3;
+               c.gridx = 4; c.gridy = 5;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.HORIZONTAL;
                c.weightx = 1;
                c.anchor = GridBagConstraints.LINE_START;
@@ -261,7 +249,7 @@ public class AltosConfigUI
                /* Radio Calibration */
                c = new GridBagConstraints();
                c.gridx = 0; c.gridy = 6;
-               c.gridwidth = 3;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.NONE;
                c.anchor = GridBagConstraints.LINE_START;
                c.insets = il;
@@ -270,8 +258,8 @@ public class AltosConfigUI
                pane.add(radio_calibration_label, c);
 
                c = new GridBagConstraints();
-               c.gridx = 3; c.gridy = 6;
-               c.gridwidth = 3;
+               c.gridx = 4; c.gridy = 6;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.HORIZONTAL;
                c.weightx = 1;
                c.anchor = GridBagConstraints.LINE_START;
@@ -284,7 +272,7 @@ public class AltosConfigUI
                /* Callsign */
                c = new GridBagConstraints();
                c.gridx = 0; c.gridy = 7;
-               c.gridwidth = 3;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.NONE;
                c.anchor = GridBagConstraints.LINE_START;
                c.insets = il;
@@ -293,50 +281,61 @@ public class AltosConfigUI
                pane.add(callsign_label, c);
 
                c = new GridBagConstraints();
-               c.gridx = 3; c.gridy = 7;
-               c.gridwidth = 3;
+               c.gridx = 4; c.gridy = 7;
+               c.gridwidth = 4;
                c.fill = GridBagConstraints.HORIZONTAL;
                c.weightx = 1;
                c.anchor = GridBagConstraints.LINE_START;
                c.insets = ir;
                c.ipady = 5;
-               callsign_value = new JTextField("N0CALL");
+               callsign_value = new JTextField(AltosPreferences.callsign());
                callsign_value.getDocument().addDocumentListener(this);
                pane.add(callsign_value, c);
 
                /* Buttons */
                c = new GridBagConstraints();
                c.gridx = 0; c.gridy = 8;
-               c.gridwidth = 6;
+               c.gridwidth = 2;
                c.fill = GridBagConstraints.NONE;
                c.anchor = GridBagConstraints.LINE_START;
                c.insets = il;
                save = new JButton("Save");
                pane.add(save, c);
                save.addActionListener(this);
-               save.setActionCommand("save");
+               save.setActionCommand("Save");
 
                c = new GridBagConstraints();
-               c.gridx = 0; c.gridy = 8;
-               c.gridwidth = 6;
+               c.gridx = 2; c.gridy = 8;
+               c.gridwidth = 2;
                c.fill = GridBagConstraints.NONE;
                c.anchor = GridBagConstraints.CENTER;
                c.insets = il;
                reset = new JButton("Reset");
                pane.add(reset, c);
                reset.addActionListener(this);
-               reset.setActionCommand("reset");
+               reset.setActionCommand("Reset");
 
                c = new GridBagConstraints();
-               c.gridx = 0; c.gridy = 8;
-               c.gridwidth = 6;
+               c.gridx = 4; c.gridy = 8;
+               c.gridwidth = 2;
+               c.fill = GridBagConstraints.NONE;
+               c.anchor = GridBagConstraints.CENTER;
+               c.insets = il;
+               reboot = new JButton("Reboot");
+               pane.add(reboot, c);
+               reboot.addActionListener(this);
+               reboot.setActionCommand("Reboot");
+
+               c = new GridBagConstraints();
+               c.gridx = 6; c.gridy = 8;
+               c.gridwidth = 2;
                c.fill = GridBagConstraints.NONE;
                c.anchor = GridBagConstraints.LINE_END;
                c.insets = il;
                close = new JButton("Close");
                pane.add(close, c);
                close.addActionListener(this);
-               close.setActionCommand("close");
+               close.setActionCommand("Close");
 
                addWindowListener(new ConfigListener(this));
        }
@@ -349,12 +348,12 @@ public class AltosConfigUI
        }
 
        /* If any values have been changed, confirm before closing */
-       public boolean check_dirty() {
+       public boolean check_dirty(String operation) {
                if (dirty) {
-                       Object[] options = { "Close anyway", "Keep editing" };
+                       Object[] options = { String.format("%s anyway", operation), "Keep editing" };
                        int i;
                        i = JOptionPane.showOptionDialog(this,
-                                                        "Configuration modified, close anyway?",
+                                                        String.format("Configuration modified. %s anyway?", operation),
                                                         "Configuration Modified",
                                                         JOptionPane.DEFAULT_OPTION,
                                                         JOptionPane.WARNING_MESSAGE,
@@ -369,11 +368,11 @@ public class AltosConfigUI
        public void actionPerformed(ActionEvent e) {
                String  cmd = e.getActionCommand();
 
-               if (cmd.equals("close"))
-                       if (!check_dirty())
+               if (cmd.equals("Close") || cmd.equals("Reboot"))
+                       if (!check_dirty(cmd))
                                return;
                listener.actionPerformed(e);
-               if (cmd.equals("close")) {
+               if (cmd.equals("Close") || cmd.equals("Reboot")) {
                        setVisible(false);
                        dispose();
                }
diff --git a/ao-tools/altosui/AltosConfigureUI.java b/ao-tools/altosui/AltosConfigureUI.java
new file mode 100644 (file)
index 0000000..64c17ea
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * 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 javax.swing.event.*;
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.util.prefs.*;
+import java.util.concurrent.LinkedBlockingQueue;
+
+public class AltosConfigureUI
+       extends JDialog
+       implements DocumentListener
+{
+       JFrame          owner;
+       AltosVoice      voice;
+       Container       pane;
+
+       JRadioButton    enable_voice;
+       JButton         test_voice;
+       JButton         close;
+
+       JButton         configure_log;
+       JTextField      log_directory;
+
+       JLabel          callsign_label;
+       JTextField      callsign_value;
+
+       /* DocumentListener interface methods */
+       public void changedUpdate(DocumentEvent e) {
+               AltosPreferences.set_callsign(callsign_value.getText());
+       }
+
+       public void insertUpdate(DocumentEvent e) {
+               changedUpdate(e);
+       }
+
+       public void removeUpdate(DocumentEvent e) {
+               changedUpdate(e);
+       }
+
+       public AltosConfigureUI(JFrame in_owner, AltosVoice in_voice) {
+               super(in_owner, "Configure AltosUI", false);
+
+               GridBagConstraints      c;
+
+               Insets insets = new Insets(4, 4, 4, 4);
+
+               owner = in_owner;
+               voice = in_voice;
+               pane = getContentPane();
+               pane.setLayout(new GridBagLayout());
+
+               c = new GridBagConstraints();
+               c.insets = insets;
+               c.fill = GridBagConstraints.NONE;
+               c.anchor = GridBagConstraints.CENTER;
+
+               /* Enable Voice */
+               c.gridx = 0;
+               c.gridy = 0;
+               enable_voice = new JRadioButton("Enable Voice", AltosPreferences.voice());
+               enable_voice.addActionListener(new ActionListener() {
+                               public void actionPerformed(ActionEvent e) {
+                                       JRadioButton item = (JRadioButton) e.getSource();
+                                       boolean enabled = item.isSelected();
+                                       AltosPreferences.set_voice(enabled);
+                                       if (enabled)
+                                               voice.speak_always("Enable voice.");
+                                       else
+                                               voice.speak_always("Disable voice.");
+                               }
+                       });
+               pane.add(enable_voice, c);
+               c.gridx = 1;
+               c.gridy = 0;
+               test_voice = new JButton("Test Voice");
+               test_voice.addActionListener(new ActionListener() {
+                               public void actionPerformed(ActionEvent e) {
+                                       voice.speak("That's one small step for man; one giant leap for mankind.");
+                               }
+                       });
+               pane.add(test_voice, c);
+
+               configure_log = new JButton("Configure Log");
+               configure_log.addActionListener(new ActionListener() {
+                               public void actionPerformed(ActionEvent e) {
+                                       AltosPreferences.ConfigureLog();
+                                       log_directory.setText(AltosPreferences.logdir().getPath());
+                               }
+                       });
+               c.gridwidth = 1;
+
+               c.gridx = 0;
+               c.gridy = 2;
+               pane.add(configure_log, c);
+
+               log_directory = new JTextField(AltosPreferences.logdir().getPath());
+               c.gridx = 1;
+               c.gridy = 2;
+               c.fill = GridBagConstraints.BOTH;
+               pane.add(log_directory, c);
+
+               callsign_label = new JLabel("Callsign");
+               c.gridx = 0;
+               c.gridy = 3;
+               pane.add(callsign_label, c);
+
+               callsign_value = new JTextField(AltosPreferences.callsign());
+               callsign_value.getDocument().addDocumentListener(this);
+               c.gridx = 1;
+               c.gridy = 3;
+               pane.add(callsign_value, c);
+
+               close = new JButton("Close");
+               close.addActionListener(new ActionListener() {
+                               public void actionPerformed(ActionEvent e) {
+                                       setVisible(false);
+                               }
+                       });
+               c.gridx = 0;
+               c.gridy = 4;
+               c.gridwidth = 2;
+               c.fill = GridBagConstraints.NONE;
+               pane.add(close, c);
+
+               pack();
+               setLocationRelativeTo(owner);
+               setVisible(true);
+       }
+}
index 4d7831e4c880e259a7f251abf3bcbbb5a55fa556..7704310b6f676ba9e3abfb5eae0a7ee6a9e6e2e6 100644 (file)
@@ -10,11 +10,6 @@ import java.lang.UnsupportedOperationException;
 import java.util.NoSuchElementException;
 import java.util.Iterator;
 
-import altosui.AltosDataPoint;
-import altosui.AltosRecordIterable;
-import altosui.AltosRecord;
-import altosui.AltosState;
-
 class AltosDataPointReader implements Iterable<AltosDataPoint> {
     Iterator<AltosRecord> iter;
     AltosState state;
index 3f469d48214dfc4ec9a999c425631ea55ba8d0b0..9aa35d3f2f834813d7cfdd51a5dbf2a631b750ee 100644 (file)
@@ -19,11 +19,10 @@ package altosui;
 
 import java.lang.*;
 import java.io.*;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.LinkedList;
-import java.util.Iterator;
-import altosui.AltosSerial;
-import altosui.AltosRomconfig;
+import java.util.concurrent.*;
+import java.util.*;
+
+import libaltosJNI.*;
 
 public class AltosDebug extends AltosSerial {
 
@@ -261,4 +260,8 @@ public class AltosDebug extends AltosSerial {
        public void reset() {
                printf ("R\n");
        }
+
+       public AltosDebug (altos_device in_device) throws FileNotFoundException, AltosSerialInUseException {
+               super(in_device);
+       }
 }
\ No newline at end of file
index 56d3e4feeee45db70cd9dbd10d786f44ca5088a4..aacd2998dc4b0cf09c0ceaebd075b59d08cb025f 100644 (file)
@@ -30,9 +30,53 @@ import java.util.concurrent.LinkedBlockingQueue;
 
 public class AltosDescent extends JComponent implements AltosFlightDisplay {
        GridBagLayout   layout;
-       Font            label_font;
-       Font            value_font;
 
+       public class DescentStatus {
+               JLabel          label;
+               JTextField      value;
+               AltosLights     lights;
+
+               void show(AltosState state, int crc_errors) {}
+               void reset() {
+                       value.setText("");
+                       lights.set(false);
+               }
+
+               public DescentStatus (GridBagLayout layout, int y, String text) {
+                       GridBagConstraints      c = new GridBagConstraints();
+                       c.weighty = 1;
+
+                       lights = new AltosLights();
+                       c.gridx = 0; c.gridy = y;
+                       c.anchor = GridBagConstraints.CENTER;
+                       c.fill = GridBagConstraints.VERTICAL;
+                       c.weightx = 0;
+                       layout.setConstraints(lights, c);
+                       add(lights);
+
+                       label = new JLabel(text);
+                       label.setFont(Altos.label_font);
+                       label.setHorizontalAlignment(SwingConstants.LEFT);
+                       c.gridx = 1; c.gridy = y;
+                       c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
+                       c.anchor = GridBagConstraints.WEST;
+                       c.fill = GridBagConstraints.VERTICAL;
+                       c.weightx = 0;
+                       layout.setConstraints(label, c);
+                       add(label);
+
+                       value = new JTextField(15);
+                       value.setFont(Altos.value_font);
+                       value.setHorizontalAlignment(SwingConstants.RIGHT);
+                       c.gridx = 2; c.gridy = y;
+                       c.anchor = GridBagConstraints.WEST;
+                       c.fill = GridBagConstraints.BOTH;
+                       c.weightx = 1;
+                       layout.setConstraints(value, c);
+                       add(value);
+
+               }
+       }
        public class DescentValue {
                JLabel          label;
                JTextField      value;
@@ -46,25 +90,28 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                        value.setText(String.format(format, v));
                }
 
-               public DescentValue (GridBagLayout layout, int y, String text) {
+               public DescentValue (GridBagLayout layout, int x, int y, String text) {
                        GridBagConstraints      c = new GridBagConstraints();
+                       c.weighty = 1;
 
                        label = new JLabel(text);
-                       label.setFont(label_font);
+                       label.setFont(Altos.label_font);
                        label.setHorizontalAlignment(SwingConstants.LEFT);
-                       c.gridx = 0; c.gridy = y;
-                       c.insets = new Insets(10, 10, 10, 10);
+                       c.gridx = x + 0; c.gridy = y;
+                       c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
                        c.anchor = GridBagConstraints.WEST;
+                       c.fill = GridBagConstraints.VERTICAL;
+                       c.weightx = 0;
                        layout.setConstraints(label, c);
                        add(label);
 
-                       value = new JTextField(30);
-                       value.setFont(value_font);
+                       value = new JTextField(17);
+                       value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
-                       c.gridx = 1; c.gridy = y;
-                       c.gridwidth = 2;
+                       c.gridx = x + 1; c.gridy = y;
                        c.anchor = GridBagConstraints.WEST;
-                       c.fill = GridBagConstraints.HORIZONTAL;
+                       c.fill = GridBagConstraints.BOTH;
+                       c.weightx = 1;
                        layout.setConstraints(value, c);
                        add(value);
                }
@@ -74,8 +121,8 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                void show (AltosState state, int crc_errors) {
                        show("%6.0f m", state.height);
                }
-               public Height (GridBagLayout layout, int y) {
-                       super (layout, y, "Height");
+               public Height (GridBagLayout layout, int x, int y) {
+                       super (layout, x, y, "Height");
                }
        }
 
@@ -88,8 +135,8 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                                speed = state.baro_speed;
                        show("%6.0f m/s", speed);
                }
-               public Speed (GridBagLayout layout, int y) {
-                       super (layout, y, "Speed");
+               public Speed (GridBagLayout layout, int x, int y) {
+                       super (layout, x, y, "Speed");
                }
        }
 
@@ -113,8 +160,8 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                        else
                                value.setText("???");
                }
-               public Lat (GridBagLayout layout, int y) {
-                       super (layout, y, "Latitude");
+               public Lat (GridBagLayout layout, int x, int y) {
+                       super (layout, x, y, "Latitude");
                }
        }
 
@@ -127,61 +174,90 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                        else
                                value.setText("???");
                }
-               public Lon (GridBagLayout layout, int y) {
-                       super (layout, y, "Longitude");
+               public Lon (GridBagLayout layout, int x, int y) {
+                       super (layout, x, y, "Longitude");
                }
        }
 
        Lon lon;
 
+       class Apogee extends DescentStatus {
+               void show (AltosState state, int crc_errors) {
+                       value.setText(String.format("%4.2f V", state.drogue_sense));
+                       lights.set(state.drogue_sense > 3.2);
+               }
+               public Apogee (GridBagLayout layout, int y) {
+                       super(layout, y, "Apogee Igniter Voltage");
+               }
+       }
+
+       Apogee apogee;
+
+       class Main extends DescentStatus {
+               void show (AltosState state, int crc_errors) {
+                       value.setText(String.format("%4.2f V", state.main_sense));
+                       lights.set(state.main_sense > 3.2);
+               }
+               public Main (GridBagLayout layout, int y) {
+                       super(layout, y, "Main Igniter Voltage");
+               }
+       }
+
+       Main main;
+
        class Bearing {
                JLabel          label;
                JTextField      value;
                JTextField      value_deg;
-        void reset () {
+               void reset () {
                        value.setText("");
                        value_deg.setText("");
-        }
+               }
                void show (AltosState state, int crc_errors) {
                        if (state.from_pad != null) {
-                value.setText(state.from_pad.bearing_words(
-                                AltosGreatCircle.BEARING_LONG));
+                               value.setText(state.from_pad.bearing_words(
+                                                     AltosGreatCircle.BEARING_LONG));
                                value_deg.setText(String.format("%3.0f°", state.from_pad.bearing));
                        } else {
                                value.setText("???");
                                value_deg.setText("???");
-            }
-               }
-               public Bearing (GridBagLayout layout, int y) {
-            GridBagConstraints      c = new GridBagConstraints();
-
-            label = new JLabel("Bearing");
-            label.setFont(label_font);
-            label.setHorizontalAlignment(SwingConstants.LEFT);
-            c.gridx = 0; c.gridy = y;
-            c.insets = new Insets(10, 10, 10, 10);
-            c.anchor = GridBagConstraints.WEST;
-            layout.setConstraints(label, c);
-            add(label);
-
-            value = new JTextField(30);
-            value.setFont(value_font);
-            value.setHorizontalAlignment(SwingConstants.RIGHT);
-            c.gridx = 1; c.gridy = y;
-            c.anchor = GridBagConstraints.EAST;
-            c.fill = GridBagConstraints.HORIZONTAL;
-            layout.setConstraints(value, c);
-            add(value);
-
-            value_deg = new JTextField(5);
-            value_deg.setFont(value_font);
-            value_deg.setHorizontalAlignment(SwingConstants.RIGHT);
-            c.gridx = 2; c.gridy = y;
-            c.anchor = GridBagConstraints.EAST;
-            c.fill = GridBagConstraints.HORIZONTAL;
-
-            layout.setConstraints(value_deg, c);
-            add(value_deg);
+                       }
+               }
+               public Bearing (GridBagLayout layout, int x, int y) {
+                       GridBagConstraints      c = new GridBagConstraints();
+                       c.weighty = 1;
+
+                       label = new JLabel("Bearing");
+                       label.setFont(Altos.label_font);
+                       label.setHorizontalAlignment(SwingConstants.LEFT);
+                       c.gridx = x + 0; c.gridy = y;
+                       c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
+                       c.anchor = GridBagConstraints.WEST;
+                       c.weightx = 0;
+                       c.fill = GridBagConstraints.VERTICAL;
+                       layout.setConstraints(label, c);
+                       add(label);
+
+                       value = new JTextField(30);
+                       value.setFont(Altos.value_font);
+                       value.setHorizontalAlignment(SwingConstants.RIGHT);
+                       c.gridx = x + 1; c.gridy = y;
+                       c.anchor = GridBagConstraints.EAST;
+                       c.weightx = 1;
+                       c.gridwidth = 2;
+                       c.fill = GridBagConstraints.BOTH;
+                       layout.setConstraints(value, c);
+                       add(value);
+
+                       value_deg = new JTextField(5);
+                       value_deg.setFont(Altos.value_font);
+                       value_deg.setHorizontalAlignment(SwingConstants.RIGHT);
+                       c.gridx = x + 3; c.gridy = y;
+                       c.anchor = GridBagConstraints.EAST;
+                       c.weightx = 1;
+                       c.fill = GridBagConstraints.BOTH;
+                       layout.setConstraints(value_deg, c);
+                       add(value_deg);
                }
        }
 
@@ -194,8 +270,8 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                        else
                                value.setText("???");
                }
-               public Elevation (GridBagLayout layout, int y) {
-                       super (layout, y, "Elevation");
+               public Elevation (GridBagLayout layout, int x, int y) {
+                       super (layout, x, y, "Elevation");
                }
        }
 
@@ -205,8 +281,8 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                void show (AltosState state, int crc_errors) {
                        show("%6.0f m", state.range);
                }
-               public Range (GridBagLayout layout, int y) {
-                       super (layout, y, "Range");
+               public Range (GridBagLayout layout, int x, int y) {
+                       super (layout, x, y, "Range");
                }
        }
 
@@ -220,6 +296,8 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                bearing.reset();
                elevation.reset();
                range.reset();
+               main.reset();
+               apogee.reset();
        }
 
        public void show(AltosState state, int crc_errors) {
@@ -230,22 +308,22 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                range.show(state, crc_errors);
                lat.show(state, crc_errors);
                lon.show(state, crc_errors);
+               main.show(state, crc_errors);
+               apogee.show(state, crc_errors);
        }
 
        public AltosDescent() {
                layout = new GridBagLayout();
 
-               label_font = new Font("Dialog", Font.PLAIN, 24);
-               value_font = new Font("Monospaced", Font.PLAIN, 24);
                setLayout(layout);
 
                /* Elements in descent display */
-               speed = new Speed(layout, 0);
-               height = new Height(layout, 1);
-               bearing = new Bearing(layout, 2);
-               elevation = new Elevation(layout, 3);
-               range = new Range(layout, 4);
-               lat = new Lat(layout, 5);
-               lon = new Lon(layout, 6);
+               speed = new Speed(layout, 0, 0);        height = new Height(layout, 2, 0);
+               elevation = new Elevation(layout, 0, 1); range = new Range(layout, 2, 1);
+               bearing = new Bearing(layout, 0, 2);
+               lat = new Lat(layout, 0, 3);
+               lon = new Lon(layout, 0, 4);
+               apogee = new Apogee(layout, 5);
+               main = new Main(layout, 6);
        }
 }
index ec78e2889fcdef70f1ac37be7eb240f8705945d1..2966ad1e52bd44a6855d07e47fe3c68bad6bd9b1 100644 (file)
@@ -26,7 +26,6 @@ import libaltosJNI.libaltos;
 import libaltosJNI.altos_device;
 import libaltosJNI.SWIGTYPE_p_altos_file;
 import libaltosJNI.SWIGTYPE_p_altos_list;
-import altosui.AltosDevice;
 
 public class AltosDeviceDialog extends JDialog implements ActionListener {
 
index 8efc94d284db7618db4c538a1c4db37fbbf29a11..8996b9243a5284cc8a5b2606a6d15abc648e653b 100644 (file)
@@ -28,18 +28,6 @@ import java.text.*;
 import java.util.prefs.*;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import altosui.Altos;
-import altosui.AltosSerial;
-import altosui.AltosSerialMonitor;
-import altosui.AltosRecord;
-import altosui.AltosTelemetry;
-import altosui.AltosState;
-import altosui.AltosDeviceDialog;
-import altosui.AltosPreferences;
-import altosui.AltosLog;
-import altosui.AltosVoice;
-import altosui.AltosEepromMonitor;
-
 import libaltosJNI.*;
 
 public class AltosEepromDownload implements Runnable {
@@ -256,12 +244,11 @@ public class AltosEepromDownload implements Runnable {
                frame = given_frame;
                device = AltosDeviceDialog.show(frame, AltosDevice.product_any);
 
-               serial_line = new AltosSerial();
                remote = false;
 
                if (device != null) {
                        try {
-                               serial_line.open(device);
+                               serial_line = new AltosSerial(device);
                                if (!device.matchProduct(AltosDevice.product_telemetrum))
                                        remote = true;
                                eeprom_thread = new Thread(this);
@@ -272,6 +259,12 @@ public class AltosEepromDownload implements Runnable {
                                                                            device.getPath()),
                                                              "Cannot open target device",
                                                              JOptionPane.ERROR_MESSAGE);
+                       } catch (AltosSerialInUseException si) {
+                               JOptionPane.showMessageDialog(frame,
+                                                             String.format("Device \"%s\" already in use",
+                                                                           device.getPath()),
+                                                             "Device in use",
+                                                             JOptionPane.ERROR_MESSAGE);
                        } catch (IOException ee) {
                                JOptionPane.showMessageDialog(frame,
                                                              device.getPath(),
index 2f1e7e9066db2e94f0a3d4bae33ccfd76c1764dc..fc6833216c8a0ea36d441b1d62d084092e040023 100644 (file)
@@ -28,14 +28,6 @@ import java.text.*;
 import java.util.prefs.*;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import altosui.AltosRecord;
-import altosui.AltosState;
-import altosui.AltosDeviceDialog;
-import altosui.AltosPreferences;
-import altosui.AltosLog;
-import altosui.AltosVoice;
-import altosui.AltosEepromMonitor;
-
 /*
  * AltosRecords with an index field so they can be sorted by tick while preserving
  * the original ordering for elements with matching ticks
index b88fdd2924cc4f60e9e7e2f407e79b2c9c9acd1d..7ff00eadb0c371051ae48050ca154c3bf39f824e 100644 (file)
@@ -28,16 +28,6 @@ import java.text.*;
 import java.util.prefs.*;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import altosui.AltosSerial;
-import altosui.AltosSerialMonitor;
-import altosui.AltosRecord;
-import altosui.AltosTelemetry;
-import altosui.AltosState;
-import altosui.AltosDeviceDialog;
-import altosui.AltosPreferences;
-import altosui.AltosLog;
-import altosui.AltosVoice;
-
 public class AltosEepromMonitor extends JDialog {
 
        Container       pane;
index 95cbe0159d60d86c39655a0cd70cc5d8b4ad9e29..5a6738177601a8e60dc9008d01e5ee22599936d6 100644 (file)
@@ -28,17 +28,6 @@ import java.text.*;
 import java.util.prefs.*;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import altosui.AltosSerial;
-import altosui.AltosSerialMonitor;
-import altosui.AltosRecord;
-import altosui.AltosTelemetry;
-import altosui.AltosState;
-import altosui.AltosDeviceDialog;
-import altosui.AltosPreferences;
-import altosui.AltosLog;
-import altosui.AltosVoice;
-import altosui.AltosEepromMonitor;
-
 public class AltosEepromRecord {
        public int      cmd;
        public int      tick;
index 7f65381f43926dd1cea5f2e14ae0d604567627cc..06360572f8e23c0a8d8731afebf0095cf6c2c028 100644 (file)
@@ -20,8 +20,6 @@ package altosui;
 import java.lang.*;
 import java.io.File;
 import java.util.*;
-import altosui.AltosTelemetry;
-import altosui.AltosPreferences;
 
 class AltosFile extends File {
 
index a3e431cdf7dd9c60bde16953d40f116236420b0b..fa2465d337748a0af7ee0fd79dcdd0c80d5e8552 100644 (file)
@@ -28,8 +28,6 @@ import java.text.*;
 import java.util.prefs.*;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import altosui.AltosHexfile;
-
 public class AltosFlash {
        File            file;
        FileInputStream input;
@@ -331,17 +329,14 @@ public class AltosFlash {
                return rom_config;
        }
 
-       public void open() throws IOException, FileNotFoundException, InterruptedException {
+       public AltosFlash(File in_file, AltosDevice in_debug_dongle)
+               throws IOException, FileNotFoundException, AltosSerialInUseException, InterruptedException {
+               file = in_file;
+               debug_dongle = in_debug_dongle;
+               debug = new AltosDebug(in_debug_dongle);
                input = new FileInputStream(file);
                image = new AltosHexfile(input);
-               debug.open(debug_dongle);
                if (!debug.check_connection())
                        throw new IOException("Debug port not connected");
        }
-
-       public AltosFlash(File in_file, AltosDevice in_debug_dongle) {
-               file = in_file;
-               debug_dongle = in_debug_dongle;
-               debug = new AltosDebug();
-       }
 }
\ No newline at end of file
index 86f57a5fb3c862e755f1909c4310357e7b59bc09..b09cb59472e0d6c2608161bce26d2f838ae0fdbd 100644 (file)
@@ -28,9 +28,6 @@ import java.text.*;
 import java.util.prefs.*;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import altosui.AltosHexfile;
-import altosui.AltosFlash;
-
 public class AltosFlashUI
        extends JDialog
        implements Runnable, ActionListener
@@ -68,10 +65,9 @@ public class AltosFlashUI
        }
 
        public void run() {
-               flash = new AltosFlash(file, debug_dongle);
-               flash.addActionListener(this);
                try {
-                       flash.open();
+                       flash = new AltosFlash(file, debug_dongle);
+                       flash.addActionListener(this);
                        AltosRomconfigUI romconfig_ui = new AltosRomconfigUI (frame);
 
                        romconfig_ui.set(flash.romconfig());
@@ -91,6 +87,12 @@ public class AltosFlashUI
                                                      "Cannot open image",
                                                      file.toString(),
                                                      JOptionPane.ERROR_MESSAGE);
+               } catch (AltosSerialInUseException si) {
+                       JOptionPane.showMessageDialog(frame,
+                                                     String.format("Device \"%s\" already in use",
+                                                                   debug_dongle.getPath()),
+                                                     "Device in use",
+                                                     JOptionPane.ERROR_MESSAGE);
                } catch (IOException e) {
                        JOptionPane.showMessageDialog(frame,
                                                      e.getMessage(),
index 2a22e3e50b48b682173034455f6f26848536ca47..3355ff527beba857378aa2cd5b6e62ec211f1d03 100644 (file)
@@ -46,7 +46,7 @@ public class AltosFlightInfoTableModel extends AbstractTableModel {
        public int getColumnCount() { return columnNames.length; }
        public String getColumnName(int col) { return columnNames[col]; }
 
-       public int getRowCount() { return 20; }
+       public int getRowCount() { return 17; }
 
        int     current_row = 0;
        int     prev_num_rows = 0;
diff --git a/ao-tools/altosui/AltosFlightStatus.java b/ao-tools/altosui/AltosFlightStatus.java
new file mode 100644 (file)
index 0000000..59c9e9d
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * 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 AltosFlightStatus extends JComponent implements AltosFlightDisplay {
+       GridBagLayout   layout;
+
+       public class FlightValue {
+               JLabel          label;
+               JTextField      value;
+
+               void show(AltosState state, int crc_errors) {}
+
+               void reset() {
+                       value.setText("");
+               }
+               public FlightValue (GridBagLayout layout, int x, String text) {
+                       GridBagConstraints      c = new GridBagConstraints();
+                       c.insets = new Insets(5, 5, 5, 5);
+                       c.anchor = GridBagConstraints.CENTER;
+                       c.fill = GridBagConstraints.BOTH;
+                       c.weightx = 1;
+                       c.weighty = 1;
+
+                       label = new JLabel(text);
+                       label.setFont(Altos.status_font);
+                       label.setHorizontalAlignment(SwingConstants.CENTER);
+                       c.gridx = x; c.gridy = 0;
+                       layout.setConstraints(label, c);
+                       add(label);
+
+                       value = new JTextField("");
+                       value.setFont(Altos.status_font);
+                       value.setHorizontalAlignment(SwingConstants.CENTER);
+                       c.gridx = x; c.gridy = 1;
+                       layout.setConstraints(value, c);
+                       add(value);
+               }
+       }
+
+       class Call extends FlightValue {
+               void show(AltosState state, int crc_errors) {
+                       value.setText(state.data.callsign);
+               }
+               public Call (GridBagLayout layout, int x) {
+                       super (layout, x, "Callsign");
+               }
+       }
+
+       Call call;
+
+       class Serial extends FlightValue {
+               void show(AltosState state, int crc_errors) {
+                       value.setText(String.format("%d", state.data.serial));
+               }
+               public Serial (GridBagLayout layout, int x) {
+                       super (layout, x, "Serial");
+               }
+       }
+
+       Serial serial;
+
+       class Flight extends FlightValue {
+               void show(AltosState state, int crc_errors) {
+                       value.setText(String.format("%d", state.data.flight));
+               }
+               public Flight (GridBagLayout layout, int x) {
+                       super (layout, x, "Flight");
+               }
+       }
+
+       Flight flight;
+
+       class FlightState extends FlightValue {
+               void show(AltosState state, int crc_errors) {
+                       value.setText(state.data.state());
+               }
+               public FlightState (GridBagLayout layout, int x) {
+                       super (layout, x, "State");
+               }
+       }
+
+       FlightState flight_state;
+
+       class RSSI extends FlightValue {
+               void show(AltosState state, int crc_errors) {
+                       value.setText(String.format("%d", state.data.rssi));
+               }
+               public RSSI (GridBagLayout layout, int x) {
+                       super (layout, x, "RSSI (dBm)");
+               }
+       }
+
+       RSSI rssi;
+
+       public void reset () {
+               call.reset();
+               serial.reset();
+               flight.reset();
+               flight_state.reset();
+               rssi.reset();
+       }
+
+       public void show (AltosState state, int crc_errors) {
+               call.show(state, crc_errors);
+               serial.show(state, crc_errors);
+               flight.show(state, crc_errors);
+               flight_state.show(state, crc_errors);
+               rssi.show(state, crc_errors);
+       }
+
+       public int height() {
+               Dimension d = layout.preferredLayoutSize(this);
+               return d.height;
+       }
+
+       public AltosFlightStatus() {
+               layout = new GridBagLayout();
+
+               setLayout(layout);
+
+               call = new Call(layout, 0);
+               serial = new Serial(layout, 1);
+               flight = new Flight(layout, 2);
+               flight_state = new FlightState(layout, 3);
+               rssi = new RSSI(layout, 4);
+       }
+}
index f56b3d1bd4cf200a79e6e8736fc1234ceaf486c9..1372cc00d8da9368ded43ae3bb15c771d0862b71 100644 (file)
@@ -46,7 +46,8 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay {
        AltosLanded     landed;
     AltosSiteMap    sitemap;
 
-       private AltosStatusTable flightStatus;
+       private AltosFlightStatus flightStatus;
+       private JScrollPane flightInfoPane;
        private AltosInfoTable flightInfo;
 
        static final int tab_pad = 1;
@@ -56,6 +57,8 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay {
 
        int cur_tab = 0;
 
+       boolean exit_on_close = false;
+
        int which_tab(AltosState state) {
                if (state.state < Altos.ao_flight_boost)
                        return tab_pad;
@@ -119,13 +122,17 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay {
                        }
                        cur_tab = tab;
                }
-               flightStatus.set(state);
+               flightStatus.show(state, crc_errors);
                flightInfo.show(state, crc_errors);
                sitemap.show(state, crc_errors);
        }
 
+       public void set_exit_on_close() {
+               exit_on_close = true;
+       }
+
        public AltosFlightUI(AltosVoice in_voice, AltosFlightReader in_reader, final int serial) {
-        AltosPreferences.init(this);
+               AltosPreferences.init(this);
 
                voice = in_voice;
                reader = in_reader;
@@ -136,7 +143,7 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay {
 
                setTitle(String.format("AltOS %s", reader.name));
 
-               flightStatus = new AltosStatusTable();
+               flightStatus = new AltosFlightStatus();
 
                vbox = new Box (BoxLayout.Y_AXIS);
                vbox.add(flightStatus);
@@ -156,7 +163,8 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay {
                pane.add("Landed", landed);
 
                flightInfo = new AltosInfoTable();
-               pane.add("Table", new JScrollPane(flightInfo.box()));
+               flightInfoPane = new JScrollPane(flightInfo.box());
+               pane.add("Table", flightInfoPane);
 
         sitemap = new AltosSiteMap();
         pane.add("Site Map", sitemap);
@@ -185,7 +193,7 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay {
                        this.setJMenuBar(menubar);
                }
 
-               this.setSize(new Dimension (width(), height()));
+               this.setSize(this.getPreferredSize());
                this.validate();
 
                setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
@@ -195,6 +203,8 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay {
                                disconnect();
                                setVisible(false);
                                dispose();
+                               if (exit_on_close)
+                                       System.exit(0);
                        }
                });
 
index acb6fb2c8bbbdcb4c211022951ea13fb1427c2d2..83821842374041f7ec47328d87f0c07a941291f4 100644 (file)
@@ -19,8 +19,6 @@ package altosui;
 
 import java.lang.*;
 import java.text.*;
-import altosui.AltosParse;
-
 
 public class AltosGPS {
        public class AltosGPSSat {
index fa3b87c11b89f90d86a1f775c5fcb4015a9615aa..58c27979a74502a8268b10d7f76bb4b47d979827 100644 (file)
@@ -9,8 +9,6 @@ import java.io.*;
 import org.jfree.chart.JFreeChart;
 import org.jfree.chart.ChartUtilities;
 
-import altosui.AltosDataPoint;
-
 abstract class AltosGraph {
     public String filename;
     public abstract void addData(AltosDataPoint d);
index caa14118244fc495c24acfbeb0941d683b2b2aa3..d128f4d5862a4cc5f3d9bb9edea0914b60c79f64 100644 (file)
@@ -27,11 +27,6 @@ import java.util.*;
 import java.text.*;
 import java.util.prefs.*;
 
-import altosui.AltosPreferences;
-import altosui.AltosDataPointReader;
-import altosui.AltosEepromIterable;
-import altosui.AltosTelemetryIterable;
-
 public class AltosGraphDataChooser extends JFileChooser {
        JFrame  frame;
        String  filename;
index ab01b88888dabdd75ef0fe4938727f2852585adb..a5451280ca9d0d4a486e8f95b5edcfb430868c0f 100644 (file)
@@ -24,9 +24,6 @@ import org.jfree.data.xy.XYSeriesCollection;
 import org.jfree.ui.RectangleAnchor;
 import org.jfree.ui.TextAnchor;
 
-import altosui.AltosDataPoint;
-import altosui.AltosGraph;
-
 class AltosGraphTime extends AltosGraph {
     static interface Element {
         void attachGraph(AltosGraphTime g);
index 25643c766257fcdbbd1581de265136095964a6e8..908aa3b45baeab54a2900a4a7304f239bbc53e26 100644 (file)
@@ -17,9 +17,6 @@ import org.jfree.chart.axis.AxisLocation;
 import org.jfree.ui.ApplicationFrame;
 import org.jfree.ui.RefineryUtilities;
 
-import altosui.AltosDataPoint;
-import altosui.AltosGraphTime;
-
 public class AltosGraphUI extends JFrame 
 {
     static final private Color red = new Color(194,31,31);
index aa6ae3b9b0017ac47be6fca59fbdc00c7b7b00fe..fb1b6ab3e129fa3781fcafe95a0e46a325cc083f 100644 (file)
@@ -17,8 +17,6 @@
 
 package altosui;
 
-import altosui.AltosGPS;
-
 import java.lang.Math;
 
 public class AltosGreatCircle {
index 9964ab101b6dbb3258a0b6fb132f8e7e45dc47f4..9f2bef5be6e3712230291fc43e6b4f15313e210d 100644 (file)
@@ -28,9 +28,6 @@ import java.text.*;
 import java.util.prefs.*;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import altosui.AltosFlightInfoTableModel;
-import altosui.AltosState;
-
 public class AltosInfoTable {
        private Box                       box;
        private JTable                    table[];
index d170ccad4574d11962b1e2c77dcee52ea3c9d28d..0656ea6cfda717c857cfd6b9c5f42b6d18d65d91 100644 (file)
@@ -48,6 +48,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay {
 
                public LandedValue (GridBagLayout layout, int y, String text) {
                        GridBagConstraints      c = new GridBagConstraints();
+                       c.weighty = 1;
 
                        label = new JLabel(text);
                        label.setFont(label_font);
@@ -55,6 +56,8 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay {
                        c.gridx = 0; c.gridy = y;
                        c.insets = new Insets(10, 10, 10, 10);
                        c.anchor = GridBagConstraints.WEST;
+                       c.weightx = 0;
+                       c.fill = GridBagConstraints.VERTICAL;
                        layout.setConstraints(label, c);
                        add(label);
 
@@ -63,7 +66,8 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay {
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 1; c.gridy = y;
                        c.anchor = GridBagConstraints.WEST;
-                       c.fill = GridBagConstraints.HORIZONTAL;
+                       c.weightx = 1;
+                       c.fill = GridBagConstraints.BOTH;
                        layout.setConstraints(value, c);
                        add(value);
                }
@@ -192,8 +196,8 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay {
        public AltosLanded() {
                layout = new GridBagLayout();
 
-               label_font = new Font("Dialog", Font.PLAIN, 24);
-               value_font = new Font("Monospaced", Font.PLAIN, 24);
+               label_font = new Font("Dialog", Font.PLAIN, 22);
+               value_font = new Font("Monospaced", Font.PLAIN, 22);
                setLayout(layout);
 
                /* Elements in descent display */
index fed96c28b0c238b20b7c7db72ef5e586383bd8e1..137147d5cc1aa2079c66ef1cf7d865a0cf2e3965 100644 (file)
@@ -22,9 +22,6 @@ import java.lang.*;
 import java.util.*;
 import java.text.ParseException;
 import java.util.concurrent.LinkedBlockingQueue;
-import altosui.AltosSerial;
-import altosui.AltosFile;
-import altosui.AltosLine;
 
 /*
  * This creates a thread to capture telemetry data and write it to
index da047072dd5d0ca52e29859b234e9ab76978f185..77289f896a039126d3f008e2673af851e85ed692 100644 (file)
@@ -30,8 +30,6 @@ import java.util.concurrent.LinkedBlockingQueue;
 
 public class AltosPad extends JComponent implements AltosFlightDisplay {
        GridBagLayout   layout;
-       Font            label_font;
-       Font            value_font;
 
        public class LaunchStatus {
                JLabel          label;
@@ -46,29 +44,34 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
 
                public LaunchStatus (GridBagLayout layout, int y, String text) {
                        GridBagConstraints      c = new GridBagConstraints();
+                       c.weighty = 1;
 
                        lights = new AltosLights();
                        c.gridx = 0; c.gridy = y;
                        c.anchor = GridBagConstraints.CENTER;
-                       c.fill = GridBagConstraints.CENTER;
+                       c.fill = GridBagConstraints.VERTICAL;
+                       c.weightx = 0;
                        layout.setConstraints(lights, c);
                        add(lights);
 
                        label = new JLabel(text);
-                       label.setFont(label_font);
+                       label.setFont(Altos.label_font);
                        label.setHorizontalAlignment(SwingConstants.LEFT);
                        c.gridx = 1; c.gridy = y;
-                       c.insets = new Insets(10, 10, 10, 10);
+                       c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
                        c.anchor = GridBagConstraints.WEST;
-                       c.fill = GridBagConstraints.WEST;
+                       c.fill = GridBagConstraints.VERTICAL;
+                       c.weightx = 0;
                        layout.setConstraints(label, c);
                        add(label);
 
                        value = new JTextField(15);
-                       value.setFont(value_font);
+                       value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
                        c.anchor = GridBagConstraints.WEST;
+                       c.fill = GridBagConstraints.BOTH;
+                       c.weightx = 1;
                        layout.setConstraints(value, c);
                        add(value);
 
@@ -85,22 +88,26 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
                }
                public LaunchValue (GridBagLayout layout, int y, String text) {
                        GridBagConstraints      c = new GridBagConstraints();
+                       c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad);
+                       c.weighty = 1;
 
                        label = new JLabel(text);
-                       label.setFont(label_font);
+                       label.setFont(Altos.label_font);
                        label.setHorizontalAlignment(SwingConstants.LEFT);
                        c.gridx = 1; c.gridy = y;
-                       c.insets = new Insets(10, 10, 10, 10);
                        c.anchor = GridBagConstraints.WEST;
+                       c.fill = GridBagConstraints.VERTICAL;
+                       c.weightx = 0;
                        layout.setConstraints(label, c);
                        add(label);
 
                        value = new JTextField(30);
-                       value.setFont(value_font);
+                       value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
                        c.anchor = GridBagConstraints.EAST;
-                       c.fill = GridBagConstraints.HORIZONTAL;
+                       c.fill = GridBagConstraints.BOTH;
+                       c.weightx = 1;
                        layout.setConstraints(value, c);
                        add(value);
                }
@@ -142,17 +149,32 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
 
        Main main;
 
-       class GPS extends LaunchStatus {
+       class GPSLocked extends LaunchStatus {
                void show (AltosState state, int crc_errors) {
                        value.setText(String.format("%4d sats", state.gps.nsat));
+                       lights.set(state.gps.locked);
+               }
+               public GPSLocked (GridBagLayout layout, int y) {
+                       super (layout, y, "GPS Locked");
+               }
+       }
+
+       GPSLocked gps_locked;
+
+       class GPSReady extends LaunchStatus {
+               void show (AltosState state, int crc_errors) {
+                       if (state.gps_ready)
+                               value.setText("Ready");
+                       else
+                               value.setText(String.format("Waiting %d", state.gps_waiting));
                        lights.set(state.gps_ready);
                }
-               public GPS (GridBagLayout layout, int y) {
-                       super (layout, y, "GPS Status");
+               public GPSReady (GridBagLayout layout, int y) {
+                       super (layout, y, "GPS Ready");
                }
        }
 
-       GPS gps;
+       GPSReady gps_ready;
 
        String pos(double p, String pos, String neg) {
                String  h = pos;
@@ -202,7 +224,8 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
                battery.reset();
                apogee.reset();
                main.reset();
-               gps.reset();
+               gps_locked.reset();
+               gps_ready.reset();
                pad_lat.reset();
                pad_lon.reset();
                pad_alt.reset();
@@ -212,7 +235,8 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
                battery.show(state, crc_errors);
                apogee.show(state, crc_errors);
                main.show(state, crc_errors);
-               gps.show(state, crc_errors);
+               gps_locked.show(state, crc_errors);
+               gps_ready.show(state, crc_errors);
                pad_lat.show(state, crc_errors);
                pad_lon.show(state, crc_errors);
                pad_alt.show(state, crc_errors);
@@ -221,27 +245,25 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
        public AltosPad() {
                layout = new GridBagLayout();
 
-               GridBagConstraints      c;
-
-               label_font = new Font("Dialog", Font.PLAIN, 24);
-               value_font = new Font("Monospaced", Font.PLAIN, 24);
                setLayout(layout);
 
-               c = new GridBagConstraints();
                /* Elements in pad display:
                 *
                 * Battery voltage
                 * Igniter continuity
-                * GPS lock status and location
+                * GPS lock status
+                * GPS ready status
+                * GPS location
                 * Pad altitude
                 * RSSI
                 */
                battery = new Battery(layout, 0);
                apogee = new Apogee(layout, 1);
                main = new Main(layout, 2);
-               gps = new GPS(layout, 3);
-               pad_lat = new PadLat(layout, 4);
-               pad_lon = new PadLon(layout, 5);
-               pad_alt = new PadAlt(layout, 6);
+               gps_locked = new GPSLocked(layout, 3);
+               gps_ready = new GPSReady(layout, 4);
+               pad_lat = new PadLat(layout, 5);
+               pad_lon = new PadLon(layout, 6);
+               pad_alt = new PadAlt(layout, 7);
        }
 }
index 4d82de7816ef2d625d3ef3ec386116c2bae527d7..fbfcaaee7493c86275c0184c1ecfcdf900edd6a2 100644 (file)
@@ -20,8 +20,6 @@ package altosui;
 import java.text.*;
 import java.lang.*;
 
-import altosui.Altos;
-
 public class AltosParse {
        static boolean isdigit(char c) {
                return '0' <= c && c <= '9';
index 5be8795dc7e2a774f2dd21e1c25ddf3797f657b6..b9280a0cee1bf1ad13c17e299fe3403f05ed60b0 100644 (file)
@@ -21,8 +21,6 @@ import java.io.*;
 import java.util.*;
 import java.text.*;
 
-import altosui.AltosRecord;
-
 public class AltosReader {
        public AltosRecord read() throws IOException, ParseException { return null; }
        public void close() { }
index 004847678b71feff904b0295aff4cfb0338b14b2..1160a2736299743e81ae484d878570dadc79aa5a 100644 (file)
@@ -21,8 +21,6 @@ import java.lang.*;
 import java.text.*;
 import java.util.HashMap;
 import java.io.*;
-import altosui.AltosConvert;
-import altosui.AltosGPS;
 
 public class AltosRecord {
        int     version;
index 147ecc140aa4db58a7d8304dffe3c7d5bc1d4930..a7df92d11eb830dc4405b6e42fa56571a89f53ee 100644 (file)
@@ -28,14 +28,6 @@ import java.text.*;
 import java.util.prefs.*;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import altosui.AltosRecord;
-import altosui.AltosState;
-import altosui.AltosDeviceDialog;
-import altosui.AltosPreferences;
-import altosui.AltosLog;
-import altosui.AltosVoice;
-import altosui.AltosEepromMonitor;
-
 public abstract class AltosRecordIterable implements Iterable<AltosRecord> {
        public abstract Iterator<AltosRecord> iterator();
        public void write_comments(PrintStream out) { }
index 22d2dbd3af09d6fe8c33ac43c12c18729e80f6ab..55056b5e521cff94803addea48d17d7e6f9c9277 100644 (file)
@@ -17,7 +17,6 @@
 
 package altosui;
 import java.io.*;
-import altosui.AltosHexfile;
 
 public class AltosRomconfig {
        public boolean  valid;
index 2134975dd833b7a0ae246b4178549f75542b27fe..e1dc974e67ac4e520b0a0cf89594bf4ac926a243 100644 (file)
@@ -28,8 +28,6 @@ import java.util.*;
 import java.text.*;
 import java.util.prefs.*;
 
-import altosui.AltosRomconfig;
-
 public class AltosRomconfigUI
        extends JDialog
        implements ActionListener
index d6848e57b6419c86ce8a32ff97e1399c5a4fc2a5..99a92fdba5153c69aa8569de3a21012220172a43 100644 (file)
@@ -23,16 +23,10 @@ package altosui;
 
 import java.lang.*;
 import java.io.*;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.LinkedList;
-import java.util.Iterator;
-import altosui.AltosSerialMonitor;
-import altosui.AltosLine;
-import libaltosJNI.libaltos;
-import libaltosJNI.altos_device;
-import libaltosJNI.SWIGTYPE_p_altos_file;
-import libaltosJNI.SWIGTYPE_p_altos_list;
-import libaltosJNI.libaltosConstants;
+import java.util.concurrent.*;
+import java.util.*;
+
+import libaltosJNI.*;
 
 /*
  * This class reads from the serial port and places each received
@@ -42,6 +36,9 @@ import libaltosJNI.libaltosConstants;
 
 public class AltosSerial implements Runnable {
 
+       static List<String> devices_opened = Collections.synchronizedList(new LinkedList<String>());
+
+       altos_device device;
        SWIGTYPE_p_altos_file altos;
        LinkedList<LinkedBlockingQueue<AltosLine>> monitors;
        LinkedBlockingQueue<AltosLine> reply_queue;
@@ -146,10 +143,6 @@ public class AltosSerial implements Runnable {
                        set_monitor(false);
        }
 
-       public boolean opened() {
-               return altos != null;
-       }
-
        public void close() {
                if (altos != null) {
                        libaltos.altos_close(altos);
@@ -166,6 +159,9 @@ public class AltosSerial implements Runnable {
                        libaltos.altos_free(altos);
                        altos = null;
                }
+               synchronized (devices_opened) {
+                       devices_opened.remove(device.getPath());
+               }
        }
 
        public void putc(char c) {
@@ -183,7 +179,12 @@ public class AltosSerial implements Runnable {
                print(String.format(format, arguments));
        }
 
-       public void open(altos_device device) throws FileNotFoundException {
+       private void open() throws FileNotFoundException, AltosSerialInUseException {
+               synchronized (devices_opened) {
+                       if (devices_opened.contains(device.getPath()))
+                               throw new AltosSerialInUseException(device);
+                       devices_opened.add(device.getPath());
+               }
                close();
                altos = libaltos.altos_open(device);
                if (altos == null)
@@ -225,12 +226,12 @@ public class AltosSerial implements Runnable {
                }
        }
 
-       public AltosSerial() {
-               altos = null;
-               input_thread = null;
+       public AltosSerial(altos_device in_device) throws FileNotFoundException, AltosSerialInUseException {
+               device = in_device;
                line = "";
                monitor_mode = false;
                monitors = new LinkedList<LinkedBlockingQueue<AltosLine>> ();
                reply_queue = new LinkedBlockingQueue<AltosLine> ();
+               open();
        }
 }
diff --git a/ao-tools/altosui/AltosSerialInUseException.java b/ao-tools/altosui/AltosSerialInUseException.java
new file mode 100644 (file)
index 0000000..4b108c7
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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 libaltosJNI.*;
+
+public class AltosSerialInUseException extends Exception {
+       public altos_device     device;
+
+       public AltosSerialInUseException (altos_device in_device) {
+               device = in_device;
+       }
+}
index 86eb636a19687561c093565eaae2410eed96c70a..ec499d5acf2110e776e2096decf83e8b088a69e8 100644 (file)
@@ -21,9 +21,6 @@
 
 package altosui;
 
-import altosui.AltosRecord;
-import altosui.AltosGPS;
-
 public class AltosState {
        AltosRecord data;
 
diff --git a/ao-tools/altosui/AltosStatusTable.java b/ao-tools/altosui/AltosStatusTable.java
deleted file mode 100644 (file)
index 0d3a5d1..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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;
-
-import altosui.AltosFlightStatusTableModel;
-import altosui.AltosFlightInfoTableModel;
-
-public class AltosStatusTable extends JTable {
-       private AltosFlightStatusTableModel flightStatusModel;
-
-       private Font statusFont = new Font("SansSerif", Font.BOLD, 24);
-
-       public AltosStatusTable() {
-               super((TableModel) new AltosFlightStatusTableModel());
-               flightStatusModel = (AltosFlightStatusTableModel) getModel();
-
-               setFont(statusFont);
-
-               TableColumnModel tcm = getColumnModel();
-
-               for (int i = 0; i < flightStatusModel.getColumnCount(); i++) {
-                       DefaultTableCellRenderer       r = new DefaultTableCellRenderer();
-                       r.setFont(statusFont);
-                       r.setHorizontalAlignment(SwingConstants.CENTER);
-                       tcm.getColumn(i).setCellRenderer(r);
-               }
-
-               setRowHeight(rowHeight());
-               setShowGrid(false);
-       }
-
-       public int rowHeight() {
-               FontMetrics     statusMetrics = getFontMetrics(statusFont);
-               return (statusMetrics.getHeight() + statusMetrics.getLeading()) * 15 / 10;
-       }
-
-       public int height() {
-               return rowHeight * 4;
-       }
-
-       public void set(AltosState state) {
-               flightStatusModel.set(state);
-       }
-}
index be22dac60aa308c8e170f960b3718f79c6088bdd..bdb6466a46d7d66ec03914cad9653bac9b71c8a9 100644 (file)
@@ -20,10 +20,6 @@ package altosui;
 import java.lang.*;
 import java.text.*;
 import java.util.HashMap;
-import altosui.AltosConvert;
-import altosui.AltosRecord;
-import altosui.AltosGPS;
-import altosui.AltosCRCException;
 
 /*
  * Telemetry data contents
index 0a125c98b1cd31ecfccfab99d47b70db24cd2184..a71ab8726d0dce64bf1b746e0e13e61e444c84b3 100644 (file)
@@ -20,7 +20,6 @@ package altosui;
 import java.io.*;
 import java.util.*;
 import java.text.*;
-import altosui.AltosTelemetry;
 
 public class AltosTelemetryIterable extends AltosRecordIterable {
        LinkedList<AltosRecord> records;
index 03e694f8bc7dfef11338d43fba62d8e6dd0eacb9..ff02c7225c00762b1516e420edb778d7317fe89b 100644 (file)
@@ -50,14 +50,14 @@ class AltosTelemetryReader extends AltosFlightReader {
                serial.set_callsign(callsign);
        }
 
-       public AltosTelemetryReader (AltosDevice in_device) throws FileNotFoundException, IOException {
+       public AltosTelemetryReader (AltosDevice in_device)
+               throws FileNotFoundException, AltosSerialInUseException, IOException {
                device = in_device;
-               serial = new AltosSerial();
+               serial = new AltosSerial(device);
                log = new AltosLog(serial);
                name = device.getPath();
 
                telem = new LinkedBlockingQueue<AltosLine>();
                serial.add_monitor(telem);
-        serial.open(device);
        }
 }
index 2861444da7b5e9008e875d3285d7f225226ea18a..bedf24598c2bd29406dcf304dc093176b3073e49 100644 (file)
@@ -28,25 +28,6 @@ import java.text.*;
 import java.util.prefs.*;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import altosui.Altos;
-import altosui.AltosSerial;
-import altosui.AltosSerialMonitor;
-import altosui.AltosRecord;
-import altosui.AltosTelemetry;
-import altosui.AltosState;
-import altosui.AltosDeviceDialog;
-import altosui.AltosPreferences;
-import altosui.AltosLog;
-import altosui.AltosVoice;
-import altosui.AltosFlightInfoTableModel;
-import altosui.AltosFlashUI;
-import altosui.AltosLogfileChooser;
-import altosui.AltosCSVUI;
-import altosui.AltosLine;
-import altosui.AltosStatusTable;
-import altosui.AltosInfoTable;
-import altosui.AltosDisplayThread;
-
 import libaltosJNI.*;
 
 public class AltosUI extends JFrame {
@@ -75,6 +56,12 @@ public class AltosUI extends JFrame {
                                                                    device.getPath()),
                                                      "Cannot open target device",
                                                      JOptionPane.ERROR_MESSAGE);
+               } catch (AltosSerialInUseException si) {
+                       JOptionPane.showMessageDialog(AltosUI.this,
+                                                     String.format("Device \"%s\" already in use",
+                                                                   device.getPath()),
+                                                     "Device in use",
+                                                     JOptionPane.ERROR_MESSAGE);
                } catch (IOException ee) {
                        JOptionPane.showMessageDialog(AltosUI.this,
                                                      device.getPath(),
@@ -157,9 +144,28 @@ public class AltosUI extends JFrame {
                                        }
                                });
 
-               setTitle("AltOS");
+               b = addButton(0, 2, "Configure AltosUI");
+               b.addActionListener(new ActionListener() {
+                               public void actionPerformed(ActionEvent e) {
+                                       ConfigureAltosUI();
+                               }
+                       });
+
+               b = addButton(1, 2, "Flash Image");
+               b.addActionListener(new ActionListener() {
+                               public void actionPerformed(ActionEvent e) {
+                                       FlashImage();
+                               }
+                       });
 
-               createMenu();
+               b = addButton(2, 2, "Quit");
+               b.addActionListener(new ActionListener() {
+                               public void actionPerformed(ActionEvent e) {
+                                       System.exit(0);
+                               }
+                       });
+
+               setTitle("AltOS");
 
                pane.doLayout();
                pane.validate();
@@ -245,139 +251,8 @@ public class AltosUI extends JFrame {
                new AltosGraphUI(AltosUI.this);
        }
 
-       /* Create the AltosUI menus
-        */
-       private void createMenu() {
-               JMenuBar menubar = new JMenuBar();
-               JMenu menu;
-               JMenuItem item;
-               JRadioButtonMenuItem radioitem;
-
-               // File menu
-               {
-                       menu = new JMenu("File");
-                       menu.setMnemonic(KeyEvent.VK_F);
-                       menubar.add(menu);
-
-                       item = new JMenuItem("Flash Image",KeyEvent.VK_I);
-                       item.addActionListener(new ActionListener() {
-                                       public void actionPerformed(ActionEvent e) {
-                                               FlashImage();
-                                       }
-                               });
-                       menu.add(item);
-
-                       item = new JMenuItem("Export Data",KeyEvent.VK_E);
-                       item.addActionListener(new ActionListener() {
-                                       public void actionPerformed(ActionEvent e) {
-                                               ExportData();
-                                       }
-                               });
-                       menu.add(item);
-
-                       item = new JMenuItem("Graph Data",KeyEvent.VK_G);
-                       item.addActionListener(new ActionListener() {
-                                       public void actionPerformed(ActionEvent e) {
-                                               GraphData();
-                                       }
-                               });
-                       menu.add(item);
-
-                       item = new JMenuItem("Quit",KeyEvent.VK_Q);
-                       item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
-                                                                  ActionEvent.CTRL_MASK));
-                       item.addActionListener(new ActionListener() {
-                                       public void actionPerformed(ActionEvent e) {
-                                               System.out.printf("exiting\n");
-                                               System.exit(0);
-                                       }
-                               });
-                       menu.add(item);
-               }
-
-               // Device menu
-               if (false) {
-                       menu = new JMenu("Device");
-                       menu.setMnemonic(KeyEvent.VK_D);
-                       menubar.add(menu);
-
-                       item = new JMenuItem("Connect to Device",KeyEvent.VK_C);
-                       item.addActionListener(new ActionListener() {
-                                       public void actionPerformed(ActionEvent e) {
-                                               ConnectToDevice();
-                                       }
-                               });
-                       menu.add(item);
-
-                       menu.addSeparator();
-
-                       item = new JMenuItem("Set Callsign",KeyEvent.VK_S);
-                       item.addActionListener(new ActionListener() {
-                                       public void actionPerformed(ActionEvent e) {
-                                               ConfigureCallsign();
-                                       }
-                               });
-
-                       menu.add(item);
-
-                       item = new JMenuItem("Configure TeleMetrum device",KeyEvent.VK_T);
-                       item.addActionListener(new ActionListener() {
-                                       public void actionPerformed(ActionEvent e) {
-                                               ConfigureTeleMetrum();
-                                       }
-                               });
-
-                       menu.add(item);
-               }
-               // Log menu
-               {
-                       menu = new JMenu("Log");
-                       menu.setMnemonic(KeyEvent.VK_L);
-                       menubar.add(menu);
-
-                       item = new JMenuItem("New Log",KeyEvent.VK_N);
-                       item.addActionListener(new ActionListener() {
-                                       public void actionPerformed(ActionEvent e) {
-                                       }
-                               });
-                       menu.add(item);
-
-                       item = new JMenuItem("Configure Log",KeyEvent.VK_C);
-                       item.addActionListener(new ActionListener() {
-                                       public void actionPerformed(ActionEvent e) {
-                                               AltosPreferences.ConfigureLog();
-                                       }
-                               });
-                       menu.add(item);
-               }
-               // Voice menu
-               {
-                       menu = new JMenu("Voice", true);
-                       menu.setMnemonic(KeyEvent.VK_V);
-                       menubar.add(menu);
-
-                       radioitem = new JRadioButtonMenuItem("Enable Voice", AltosPreferences.voice());
-                       radioitem.addActionListener(new ActionListener() {
-                                       public void actionPerformed(ActionEvent e) {
-                                               JRadioButtonMenuItem item = (JRadioButtonMenuItem) e.getSource();
-                                               boolean enabled = item.isSelected();
-                                               AltosPreferences.set_voice(enabled);
-                                               if (enabled)
-                                                       voice.speak_always("Enable voice.");
-                                               else
-                                                       voice.speak_always("Disable voice.");
-                                       }
-                               });
-                       menu.add(radioitem);
-                       item = new JMenuItem("Test Voice",KeyEvent.VK_T);
-                       item.addActionListener(new ActionListener() {
-                                       public void actionPerformed(ActionEvent e) {
-                                               voice.speak("That's one small step for man; one giant leap for mankind.");
-                                       }
-                               });
-                       menu.add(item);
-               }
-               this.setJMenuBar(menubar);
+       private void ConfigureAltosUI() {
+               new AltosConfigureUI(AltosUI.this, voice);
        }
 
        static AltosRecordIterable open_logfile(String filename) {
@@ -456,26 +331,27 @@ public class AltosUI extends JFrame {
        public static void main(final String[] args) {
                int     process = 0;
                /* Handle batch-mode */
-        if (args.length == 2 && args[0].equals("--replay")) {
-            String filename = args[1];
-            FileInputStream in;
-            try {
-                in = new FileInputStream(filename);
-            } catch (Exception e) {
-                System.out.printf("Failed to open file '%s'\n", filename);
-                return;
-            }
-            AltosRecordIterable recs;
-            AltosReplayReader reader;
-            if (filename.endsWith("eeprom")) {
-              recs = new AltosEepromIterable(in);
-            } else {
-              recs = new AltosTelemetryIterable(in); 
-            }
-            reader = new AltosReplayReader(recs.iterator(), filename);
-            new AltosFlightUI(new AltosVoice(), reader);
-            return;
-        } else if (args.length > 0) {
+               if (args.length == 2 && args[0].equals("--replay")) {
+                       String filename = args[1];
+                       FileInputStream in;
+                       try {
+                               in = new FileInputStream(filename);
+                       } catch (Exception e) {
+                               System.out.printf("Failed to open file '%s'\n", filename);
+                               return;
+                       }
+                       AltosRecordIterable recs;
+                       AltosReplayReader reader;
+                       if (filename.endsWith("eeprom")) {
+                               recs = new AltosEepromIterable(in);
+                       } else {
+                               recs = new AltosTelemetryIterable(in);
+                       }
+                       reader = new AltosReplayReader(recs.iterator(), filename);
+                       AltosFlightUI flight_ui = new AltosFlightUI(new AltosVoice(), reader);
+                       flight_ui.set_exit_on_close();
+                       return;
+               } else if (args.length > 0) {
                        for (int i = 0; i < args.length; i++) {
                                if (args[i].equals("--kml"))
                                        process |= process_kml;
index fc532863008aaec0297aa182149b7d6b756ea6f5..1c24ce13396fe0d2e58da7b616188763b78461a7 100644 (file)
@@ -14,6 +14,7 @@ altosui_JAVA = \
        AltosChannelMenu.java \
        AltosConfig.java \
        AltosConfigUI.java \
+       AltosConfigureUI.java \
        AltosConvert.java \
        AltosCRCException.java \
        AltosCSV.java \
@@ -33,7 +34,7 @@ altosui_JAVA = \
        AltosFlightDisplay.java \
        AltosFlightInfoTableModel.java \
        AltosFlightReader.java \
-       AltosFlightStatusTableModel.java \
+       AltosFlightStatus.java \
        AltosFlightUI.java \
        AltosGPS.java \
        AltosGreatCircle.java \
@@ -58,10 +59,10 @@ altosui_JAVA = \
        AltosRomconfig.java \
        AltosRomconfigUI.java \
        AltosSerial.java \
+       AltosSerialInUseException.java \
        AltosSerialMonitor.java \
        AltosSiteMap.java \
        AltosState.java \
-       AltosStatusTable.java \
        AltosTelemetry.java \
        AltosTelemetryIterable.java \
        AltosUI.java \