From 24ffcf86c43290ce0f70fb4ee0984b3debdb8a5f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 19 Nov 2010 15:41:30 +0800 Subject: altosui: Add igniter ground testing code Not yet hooked up, but the UI is finished. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosIgniteUI.java | 183 ++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 ao-tools/altosui/AltosIgniteUI.java (limited to 'ao-tools/altosui/AltosIgniteUI.java') diff --git a/ao-tools/altosui/AltosIgniteUI.java b/ao-tools/altosui/AltosIgniteUI.java new file mode 100644 index 00000000..62da413c --- /dev/null +++ b/ao-tools/altosui/AltosIgniteUI.java @@ -0,0 +1,183 @@ +/* + * Copyright © 2010 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.*; +import javax.swing.event.*; +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; + +public class AltosIgniteUI + extends JDialog + implements ActionListener +{ + JFrame owner; + JLabel label; + JRadioButton apogee; + JRadioButton main; + JToggleButton arm; + JButton fire; + javax.swing.Timer timer; + + final static int timeout = 1 * 1000; + + int time_remaining; + + void set_arm_text() { + if (arm.isSelected()) + arm.setText(String.format("%d", time_remaining)); + else + arm.setText("Arm"); + } + + void start_timer() { + time_remaining = 10; + set_arm_text(); + timer.restart(); + } + + void stop_timer() { + time_remaining = 0; + arm.setSelected(false); + arm.setEnabled(false); + fire.setEnabled(false); + timer.stop(); + set_arm_text(); + } + + void cancel () { + apogee.setSelected(false); + main.setSelected(false); + fire.setEnabled(false); + stop_timer(); + } + + void tick_timer() { + --time_remaining; + if (time_remaining <= 0) + cancel(); + else + set_arm_text(); + } + + void fire() { + if (arm.isEnabled() && arm.isSelected() && time_remaining > 0) { + int igniter = AltosIgnite.None; + if (apogee.isSelected() && !main.isSelected()) + igniter = AltosIgnite.Apogee; + else if (main.isSelected() && !apogee.isSelected()) + igniter = AltosIgnite.Main; + System.out.printf ("fire %d\n", igniter); + cancel(); + } + } + + public void actionPerformed(ActionEvent e) { + String cmd = e.getActionCommand(); + if (cmd.equals("apogee") || cmd.equals("main")) { + stop_timer(); + arm.setEnabled(true); + } + + if (cmd.equals("apogee") && apogee.isSelected()) + main.setSelected(false); + if (cmd.equals("main") && main.isSelected()) + apogee.setSelected(false); + + if (cmd.equals("arm")) { + if (arm.isSelected()) { + fire.setEnabled(true); + start_timer(); + } else + cancel(); + } + if (cmd.equals("fire")) + fire(); + if (cmd.equals("tick")) + tick_timer(); + } + + public AltosIgniteUI(JFrame in_owner) { + Container pane = getContentPane(); + GridBagConstraints c = new GridBagConstraints(); + Insets i = new Insets(4,4,4,4); + + timer = new javax.swing.Timer(timeout, this); + timer.setActionCommand("tick"); + + owner = in_owner; + + pane.setLayout(new GridBagLayout()); + + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.insets = i; + c.weightx = 1; + c.weighty = 1; + + c.gridx = 0; + c.gridy = 0; + c.gridwidth = 2; + label = new JLabel ("Fire Igniter"); + pane.add(label, c); + + c.gridx = 0; + c.gridy = 1; + c.gridwidth = 1; + apogee = new JRadioButton ("Apogee"); + pane.add(apogee, c); + apogee.addActionListener(this); + apogee.setActionCommand("apogee"); + + c.gridx = 1; + c.gridy = 1; + c.gridwidth = 1; + main = new JRadioButton ("Main"); + pane.add(main, c); + main.addActionListener(this); + main.setActionCommand("main"); + + c.gridx = 0; + c.gridy = 2; + c.gridwidth = 1; + arm = new JToggleButton ("Arm"); + pane.add(arm, c); + arm.addActionListener(this); + arm.setActionCommand("arm"); + arm.setEnabled(false); + + c.gridx = 1; + c.gridy = 2; + c.gridwidth = 1; + fire = new JButton ("Fire"); + fire.setEnabled(false); + pane.add(fire, c); + fire.addActionListener(this); + fire.setActionCommand("fire"); + + pack(); + setLocationRelativeTo(owner); + setVisible(true); + } +} \ No newline at end of file -- cgit v1.2.3 From 9ffc2eb53a47e435f39b02896b0e43ae5f47f450 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 19 Nov 2010 18:25:48 -0800 Subject: altosui: Use timeouts to recover from broken packet links. This puts timeouts every place the system reads from the packet link and aborts the in-progress operation if it takes more than a second to get a response. Also mixed in here are persistent igniter status displays for the ejection testing UI. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosConfig.java | 95 +++++++++-------- ao-tools/altosui/AltosEepromDownload.java | 26 +++-- ao-tools/altosui/AltosFlashUI.java | 2 +- ao-tools/altosui/AltosIgnite.java | 58 ++++++----- ao-tools/altosui/AltosIgniteUI.java | 162 ++++++++++++++++++++++++++--- ao-tools/altosui/AltosSerial.java | 11 +- ao-tools/altosui/AltosTelemetryReader.java | 2 +- ao-tools/altosui/AltosUI.java | 6 +- 8 files changed, 268 insertions(+), 94 deletions(-) (limited to 'ao-tools/altosui/AltosIgniteUI.java') diff --git a/ao-tools/altosui/AltosConfig.java b/ao-tools/altosui/AltosConfig.java index a0fdb623..19503dcb 100644 --- a/ao-tools/altosui/AltosConfig.java +++ b/ao-tools/altosui/AltosConfig.java @@ -26,7 +26,7 @@ import java.io.*; import java.util.*; import java.text.*; import java.util.prefs.*; -import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.*; import libaltosJNI.*; @@ -123,12 +123,14 @@ public class AltosConfig implements Runnable, ActionListener { } } - void get_data() throws InterruptedException { + void get_data() throws InterruptedException, TimeoutException { try { start_serial(); serial_line.printf("c s\nv\n"); for (;;) { - String line = serial_line.get_reply(); + String line = serial_line.get_reply(1000); + if (line == null) + throw new TimeoutException(); get_int(line, "serial-number", serial); get_int(line, "Main deploy:", main_deploy); get_int(line, "Apogee delay:", apogee_delay); @@ -147,27 +149,34 @@ public class AltosConfig implements Runnable, ActionListener { } } - void init_ui () { + void init_ui () throws InterruptedException, TimeoutException { config_ui = new AltosConfigUI(owner); config_ui.addActionListener(this); set_ui(); } - void set_ui() { - try { - if (serial_line != null) - get_data(); - config_ui.set_serial(serial.get()); - config_ui.set_product(product.get()); - config_ui.set_version(version.get()); - config_ui.set_main_deploy(main_deploy.get()); - config_ui.set_apogee_delay(apogee_delay.get()); - config_ui.set_radio_channel(radio_channel.get()); - config_ui.set_radio_calibration(radio_calibration.get()); - config_ui.set_callsign(callsign.get()); - config_ui.set_clean(); - } catch (InterruptedException ie) { - } + void abort() { + JOptionPane.showMessageDialog(owner, + String.format("Connection to \"%s\" failed", + device.toString()), + "Connection Failed", + JOptionPane.ERROR_MESSAGE); + serial_line.close(); + serial_line = null; + } + + void set_ui() throws InterruptedException, TimeoutException { + if (serial_line != null) + get_data(); + config_ui.set_serial(serial.get()); + config_ui.set_product(product.get()); + config_ui.set_version(version.get()); + config_ui.set_main_deploy(main_deploy.get()); + config_ui.set_apogee_delay(apogee_delay.get()); + config_ui.set_radio_channel(radio_channel.get()); + config_ui.set_radio_calibration(radio_calibration.get()); + config_ui.set_callsign(callsign.get()); + config_ui.set_clean(); } void run_dialog() { @@ -198,28 +207,28 @@ public class AltosConfig implements Runnable, ActionListener { public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); - if (cmd.equals("Save")) { - save_data(); - set_ui(); - } else if (cmd.equals("Reset")) { - set_ui(); - } else if (cmd.equals("Reboot")) { - if (serial_line != null) { - try { + try { + if (cmd.equals("Save")) { + save_data(); + set_ui(); + } else if (cmd.equals("Reset")) { + set_ui(); + } else if (cmd.equals("Reboot")) { + if (serial_line != null) { start_serial(); serial_line.printf("r eboot\n"); - } catch (InterruptedException ie) { - } finally { - try { - stop_serial(); - } catch (InterruptedException ie) { - } + serial_line.flush_output(); + stop_serial(); + serial_line.close(); } - serial_line.close(); + } else if (cmd.equals("Close")) { + if (serial_line != null) + serial_line.close(); } - } else if (cmd.equals("Close")) { - if (serial_line != null) - serial_line.close(); + } catch (InterruptedException ie) { + abort(); + } catch (TimeoutException te) { + abort(); } } @@ -227,8 +236,10 @@ public class AltosConfig implements Runnable, ActionListener { try { init_ui(); config_ui.make_visible(); -// } catch (InterruptedException ie) { - } finally { + } catch (InterruptedException ie) { + abort(); + } catch (TimeoutException te) { + abort(); } } @@ -255,18 +266,18 @@ public class AltosConfig implements Runnable, ActionListener { } catch (FileNotFoundException ee) { JOptionPane.showMessageDialog(owner, String.format("Cannot open device \"%s\"", - device.getPath()), + device.toString()), "Cannot open target device", JOptionPane.ERROR_MESSAGE); } catch (AltosSerialInUseException si) { JOptionPane.showMessageDialog(owner, String.format("Device \"%s\" already in use", - device.getPath()), + device.toString()), "Device in use", JOptionPane.ERROR_MESSAGE); } catch (IOException ee) { JOptionPane.showMessageDialog(owner, - device.getPath(), + device.toString(), ee.getLocalizedMessage(), JOptionPane.ERROR_MESSAGE); } diff --git a/ao-tools/altosui/AltosEepromDownload.java b/ao-tools/altosui/AltosEepromDownload.java index 8996b924..912ff476 100644 --- a/ao-tools/altosui/AltosEepromDownload.java +++ b/ao-tools/altosui/AltosEepromDownload.java @@ -26,7 +26,7 @@ import java.io.*; import java.util.*; import java.text.*; import java.util.prefs.*; -import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.*; import libaltosJNI.*; @@ -78,7 +78,7 @@ public class AltosEepromDownload implements Runnable { Thread eeprom_thread; AltosEepromMonitor monitor; - void CaptureLog() throws IOException, InterruptedException { + void CaptureLog() throws IOException, InterruptedException, TimeoutException { int serial = 0; int block, state_block = 0; int addr; @@ -97,8 +97,10 @@ public class AltosEepromDownload implements Runnable { /* Pull the serial number out of the version information */ for (;;) { - String line = serial_line.get_reply(); + String line = serial_line.get_reply(1000); + if (line == null) + throw new TimeoutException(); if (line.startsWith("serial-number")) { try { serial = Integer.parseInt(line.substring(13).trim()); @@ -125,7 +127,9 @@ public class AltosEepromDownload implements Runnable { any_valid = false; monitor.set_value(state_names[state], state, block - state_block); for (addr = 0; addr < 0x100;) { - String line = serial_line.get_reply(); + String line = serial_line.get_reply(1000); + if (line == null) + throw new TimeoutException(); int[] values = ParseHex(line); if (values == null) { @@ -228,10 +232,16 @@ public class AltosEepromDownload implements Runnable { CaptureLog(); } catch (IOException ee) { JOptionPane.showMessageDialog(frame, - device.getPath(), + device.toString(), ee.getLocalizedMessage(), JOptionPane.ERROR_MESSAGE); } catch (InterruptedException ie) { + } catch (TimeoutException te) { + JOptionPane.showMessageDialog(frame, + String.format("Connection to \"%s\" failed", + device.toString()), + "Connection Failed", + JOptionPane.ERROR_MESSAGE); } if (remote) serial_line.printf("~"); @@ -256,18 +266,18 @@ public class AltosEepromDownload implements Runnable { } catch (FileNotFoundException ee) { JOptionPane.showMessageDialog(frame, String.format("Cannot open device \"%s\"", - device.getPath()), + device.toString()), "Cannot open target device", JOptionPane.ERROR_MESSAGE); } catch (AltosSerialInUseException si) { JOptionPane.showMessageDialog(frame, String.format("Device \"%s\" already in use", - device.getPath()), + device.toString()), "Device in use", JOptionPane.ERROR_MESSAGE); } catch (IOException ee) { JOptionPane.showMessageDialog(frame, - device.getPath(), + device.toString(), ee.getLocalizedMessage(), JOptionPane.ERROR_MESSAGE); } diff --git a/ao-tools/altosui/AltosFlashUI.java b/ao-tools/altosui/AltosFlashUI.java index b09cb594..d3b72c67 100644 --- a/ao-tools/altosui/AltosFlashUI.java +++ b/ao-tools/altosui/AltosFlashUI.java @@ -90,7 +90,7 @@ public class AltosFlashUI } catch (AltosSerialInUseException si) { JOptionPane.showMessageDialog(frame, String.format("Device \"%s\" already in use", - debug_dongle.getPath()), + debug_dongle.toString()), "Device in use", JOptionPane.ERROR_MESSAGE); } catch (IOException e) { diff --git a/ao-tools/altosui/AltosIgnite.java b/ao-tools/altosui/AltosIgnite.java index 5c27e8fa..8e92ec1b 100644 --- a/ao-tools/altosui/AltosIgnite.java +++ b/ao-tools/altosui/AltosIgnite.java @@ -18,6 +18,7 @@ package altosui; import java.io.*; +import java.util.concurrent.*; public class AltosIgnite { AltosDevice device; @@ -91,35 +92,40 @@ public class AltosIgnite { return Unknown; } - public int status(int igniter) { + public int status(int igniter) throws InterruptedException, TimeoutException { int status = Unknown; if (serial == null) return status; string_ref status_name = new string_ref(); - try { - start_serial(); - serial.printf("t\n"); - for (;;) { - String line = serial.get_reply(); - if (get_string(line, "Igniter: drogue Status: ", status_name)) - if (igniter == Apogee) - status = status(status_name.get()); - if (get_string(line, "Igniter: main Status: ", status_name)) { - if (igniter == Main) - status = status(status_name.get()); - break; - } - } - } catch (InterruptedException ie) { - } finally { - try { - stop_serial(); - } catch (InterruptedException ie) { + start_serial(); + serial.printf("t\n"); + for (;;) { + String line = serial.get_reply(1000); + if (line == null) + throw new TimeoutException(); + if (get_string(line, "Igniter: drogue Status: ", status_name)) + if (igniter == Apogee) + status = status(status_name.get()); + if (get_string(line, "Igniter: main Status: ", status_name)) { + if (igniter == Main) + status = status(status_name.get()); + break; } } + stop_serial(); return status; } + public String status_string(int status) { + switch (status) { + case Unknown: return "Unknown"; + case Ready: return "Ready"; + case Active: return "Active"; + case Open: return "Open"; + default: return "Unknown"; + } + } + public void fire(int igniter) { if (serial == null) return; @@ -142,14 +148,18 @@ public class AltosIgnite { } } + public void close() { + serial.close(); + serial = null; + } + public AltosIgnite(AltosDevice in_device) throws FileNotFoundException, AltosSerialInUseException { device = in_device; - serial = null; -// serial = new AltosSerial(device); + serial = new AltosSerial(device); remote = false; -// if (!device.matchProduct(AltosDevice.product_telemetrum)) -// remote = true; + if (!device.matchProduct(AltosDevice.product_telemetrum)) + remote = true; } } \ No newline at end of file diff --git a/ao-tools/altosui/AltosIgniteUI.java b/ao-tools/altosui/AltosIgniteUI.java index 62da413c..caecc3ef 100644 --- a/ao-tools/altosui/AltosIgniteUI.java +++ b/ao-tools/altosui/AltosIgniteUI.java @@ -27,22 +27,31 @@ import java.io.*; import java.util.*; import java.text.*; import java.util.prefs.*; +import java.util.concurrent.*; public class AltosIgniteUI extends JDialog implements ActionListener { + AltosDevice device; + AltosIgnite ignite; JFrame owner; JLabel label; JRadioButton apogee; + JLabel apogee_status_label; JRadioButton main; + JLabel main_status_label; JToggleButton arm; JButton fire; javax.swing.Timer timer; + int apogee_status; + int main_status; + final static int timeout = 1 * 1000; int time_remaining; + boolean timer_running; void set_arm_text() { if (arm.isSelected()) @@ -54,7 +63,7 @@ public class AltosIgniteUI void start_timer() { time_remaining = 10; set_arm_text(); - timer.restart(); + timer_running = true; } void stop_timer() { @@ -62,7 +71,7 @@ public class AltosIgniteUI arm.setSelected(false); arm.setEnabled(false); fire.setEnabled(false); - timer.stop(); + timer_running = false; set_arm_text(); } @@ -73,12 +82,47 @@ public class AltosIgniteUI stop_timer(); } + void get_ignite_status() throws InterruptedException, TimeoutException { + apogee_status = ignite.status(AltosIgnite.Apogee); + main_status = ignite.status(AltosIgnite.Main); + } + + void set_ignite_status() throws InterruptedException, TimeoutException { + get_ignite_status(); + apogee_status_label.setText(String.format("\"%s\"", ignite.status_string(apogee_status))); + main_status_label.setText(String.format("\"%s\"", ignite.status_string(main_status))); + } + + void close() { + timer.stop(); + setVisible(false); + ignite.close(); + } + + void abort() { + close(); + JOptionPane.showMessageDialog(owner, + String.format("Connection to \"%s\" failed", + device.toString()), + "Connection Failed", + JOptionPane.ERROR_MESSAGE); + } + void tick_timer() { - --time_remaining; - if (time_remaining <= 0) - cancel(); - else - set_arm_text(); + if (timer_running) { + --time_remaining; + if (time_remaining <= 0) + cancel(); + else + set_arm_text(); + } + try { + set_ignite_status(); + } catch (InterruptedException ie) { + abort(); + } catch (TimeoutException te) { + abort(); + } } void fire() { @@ -88,7 +132,7 @@ public class AltosIgniteUI igniter = AltosIgnite.Apogee; else if (main.isSelected() && !apogee.isSelected()) igniter = AltosIgnite.Main; - System.out.printf ("fire %d\n", igniter); + ignite.fire(igniter); cancel(); } } @@ -97,13 +141,18 @@ public class AltosIgniteUI String cmd = e.getActionCommand(); if (cmd.equals("apogee") || cmd.equals("main")) { stop_timer(); - arm.setEnabled(true); } - if (cmd.equals("apogee") && apogee.isSelected()) + if (cmd.equals("apogee") && apogee.isSelected()) { main.setSelected(false); - if (cmd.equals("main") && main.isSelected()) + if (apogee_status == AltosIgnite.Ready) + arm.setEnabled(true); + } + if (cmd.equals("main") && main.isSelected()) { apogee.setSelected(false); + if (main_status == AltosIgnite.Ready) + arm.setEnabled(true); + } if (cmd.equals("arm")) { if (arm.isSelected()) { @@ -116,15 +165,71 @@ public class AltosIgniteUI fire(); if (cmd.equals("tick")) tick_timer(); + if (cmd.equals("close")) { + close(); + } + } + + /* A window listener to catch closing events and tell the config code */ + class ConfigListener extends WindowAdapter { + AltosIgniteUI ui; + + public ConfigListener(AltosIgniteUI this_ui) { + ui = this_ui; + } + + public void windowClosing(WindowEvent e) { + ui.actionPerformed(new ActionEvent(e.getSource(), + ActionEvent.ACTION_PERFORMED, + "close")); + } + } + + private boolean open() { + device = AltosDeviceDialog.show(owner, AltosDevice.product_any); + if (device != null) { + try { + ignite = new AltosIgnite(device); + return true; + } catch (FileNotFoundException ee) { + JOptionPane.showMessageDialog(owner, + String.format("Cannot open device \"%s\"", + device.toString()), + "Cannot open target device", + JOptionPane.ERROR_MESSAGE); + } catch (AltosSerialInUseException si) { + JOptionPane.showMessageDialog(owner, + String.format("Device \"%s\" already in use", + device.toString()), + "Device in use", + JOptionPane.ERROR_MESSAGE); + } catch (IOException ee) { + JOptionPane.showMessageDialog(owner, + device.toString(), + ee.getLocalizedMessage(), + JOptionPane.ERROR_MESSAGE); + } + } + return false; } public AltosIgniteUI(JFrame in_owner) { + + owner = in_owner; + apogee_status = AltosIgnite.Unknown; + main_status = AltosIgnite.Unknown; + + if (!open()) + return; + Container pane = getContentPane(); GridBagConstraints c = new GridBagConstraints(); Insets i = new Insets(4,4,4,4); timer = new javax.swing.Timer(timeout, this); timer.setActionCommand("tick"); + timer_running = false; + timer.restart(); owner = in_owner; @@ -139,12 +244,14 @@ public class AltosIgniteUI c.gridx = 0; c.gridy = 0; c.gridwidth = 2; + c.anchor = GridBagConstraints.CENTER; label = new JLabel ("Fire Igniter"); pane.add(label, c); c.gridx = 0; c.gridy = 1; c.gridwidth = 1; + c.anchor = GridBagConstraints.WEST; apogee = new JRadioButton ("Apogee"); pane.add(apogee, c); apogee.addActionListener(this); @@ -153,14 +260,40 @@ public class AltosIgniteUI c.gridx = 1; c.gridy = 1; c.gridwidth = 1; + c.anchor = GridBagConstraints.WEST; + apogee_status_label = new JLabel(); + pane.add(apogee_status_label, c); + + c.gridx = 0; + c.gridy = 2; + c.gridwidth = 1; + c.anchor = GridBagConstraints.WEST; main = new JRadioButton ("Main"); pane.add(main, c); main.addActionListener(this); main.setActionCommand("main"); - c.gridx = 0; + c.gridx = 1; c.gridy = 2; c.gridwidth = 1; + c.anchor = GridBagConstraints.WEST; + main_status_label = new JLabel(); + pane.add(main_status_label, c); + + try { + set_ignite_status(); + } catch (InterruptedException ie) { + abort(); + return; + } catch (TimeoutException te) { + abort(); + return; + } + + c.gridx = 0; + c.gridy = 3; + c.gridwidth = 1; + c.anchor = GridBagConstraints.CENTER; arm = new JToggleButton ("Arm"); pane.add(arm, c); arm.addActionListener(this); @@ -168,8 +301,9 @@ public class AltosIgniteUI arm.setEnabled(false); c.gridx = 1; - c.gridy = 2; + c.gridy = 3; c.gridwidth = 1; + c.anchor = GridBagConstraints.CENTER; fire = new JButton ("Fire"); fire.setEnabled(false); pane.add(fire, c); @@ -179,5 +313,7 @@ public class AltosIgniteUI pack(); setLocationRelativeTo(owner); setVisible(true); + + addWindowListener(new ConfigListener(this)); } } \ No newline at end of file diff --git a/ao-tools/altosui/AltosSerial.java b/ao-tools/altosui/AltosSerial.java index 99a92fdb..0d32a5ae 100644 --- a/ao-tools/altosui/AltosSerial.java +++ b/ao-tools/altosui/AltosSerial.java @@ -132,6 +132,14 @@ public class AltosSerial implements Runnable { return line.line; } + public String get_reply(int timeout) throws InterruptedException { + flush_output(); + AltosLine line = reply_queue.poll(timeout, TimeUnit.MILLISECONDS); + if (line == null) + return null; + return line.line; + } + public void add_monitor(LinkedBlockingQueue q) { set_monitor(true); monitors.add(q); @@ -185,10 +193,9 @@ public class AltosSerial implements Runnable { throw new AltosSerialInUseException(device); devices_opened.add(device.getPath()); } - close(); altos = libaltos.altos_open(device); if (altos == null) - throw new FileNotFoundException(device.getPath()); + throw new FileNotFoundException(device.toString()); input_thread = new Thread(this); input_thread.start(); print("~\nE 0\n"); diff --git a/ao-tools/altosui/AltosTelemetryReader.java b/ao-tools/altosui/AltosTelemetryReader.java index ff02c722..379e0e67 100644 --- a/ao-tools/altosui/AltosTelemetryReader.java +++ b/ao-tools/altosui/AltosTelemetryReader.java @@ -55,7 +55,7 @@ class AltosTelemetryReader extends AltosFlightReader { device = in_device; serial = new AltosSerial(device); log = new AltosLog(serial); - name = device.getPath(); + name = device.toString(); telem = new LinkedBlockingQueue(); serial.add_monitor(telem); diff --git a/ao-tools/altosui/AltosUI.java b/ao-tools/altosui/AltosUI.java index c82c8e8a..b573ef7f 100644 --- a/ao-tools/altosui/AltosUI.java +++ b/ao-tools/altosui/AltosUI.java @@ -53,18 +53,18 @@ public class AltosUI extends JFrame { } catch (FileNotFoundException ee) { JOptionPane.showMessageDialog(AltosUI.this, String.format("Cannot open device \"%s\"", - device.getPath()), + device.toString()), "Cannot open target device", JOptionPane.ERROR_MESSAGE); } catch (AltosSerialInUseException si) { JOptionPane.showMessageDialog(AltosUI.this, String.format("Device \"%s\" already in use", - device.getPath()), + device.toString()), "Device in use", JOptionPane.ERROR_MESSAGE); } catch (IOException ee) { JOptionPane.showMessageDialog(AltosUI.this, - device.getPath(), + device.toString(), "Unkonwn I/O error", JOptionPane.ERROR_MESSAGE); } -- cgit v1.2.3 From 594e80572821f1848db062d0cff18ca8bf0d90ce Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 19 Nov 2010 22:44:48 -0800 Subject: altosui: switch channel selector to combo box. Shorten displayed device names A combo box displays the current value, which is quite nice to have. Add a 'toShortString' for AltosDevice so that the window frames and error messages don't have extra spaces generated by the altos_device toString method. Signed-off-by: Keith Packard --- ao-tools/altosui/AltosChannelMenu.java | 24 +++++------- ao-tools/altosui/AltosConfig.java | 8 ++-- ao-tools/altosui/AltosDebug.java | 2 +- ao-tools/altosui/AltosDevice.java | 9 +++++ ao-tools/altosui/AltosEepromDownload.java | 10 ++--- ao-tools/altosui/AltosFlashUI.java | 2 +- ao-tools/altosui/AltosFlightUI.java | 62 ++++++++++++++++-------------- ao-tools/altosui/AltosIgniteUI.java | 8 ++-- ao-tools/altosui/AltosSerial.java | 6 +-- ao-tools/altosui/AltosTelemetryReader.java | 2 +- ao-tools/altosui/AltosUI.java | 6 +-- 11 files changed, 74 insertions(+), 65 deletions(-) (limited to 'ao-tools/altosui/AltosIgniteUI.java') diff --git a/ao-tools/altosui/AltosChannelMenu.java b/ao-tools/altosui/AltosChannelMenu.java index 504c13c6..8069c853 100644 --- a/ao-tools/altosui/AltosChannelMenu.java +++ b/ao-tools/altosui/AltosChannelMenu.java @@ -28,8 +28,7 @@ import java.text.*; import java.util.prefs.*; import java.util.concurrent.LinkedBlockingQueue; -public class AltosChannelMenu extends JMenu implements ActionListener { - ButtonGroup group; +public class AltosChannelMenu extends JComboBox implements ActionListener { int channel; LinkedList listeners; @@ -38,33 +37,28 @@ public class AltosChannelMenu extends JMenu implements ActionListener { } public void actionPerformed(ActionEvent e) { - channel = Integer.parseInt(e.getActionCommand()); + channel = getSelectedIndex(); + + ActionEvent newe = new ActionEvent(this, channel, e.getActionCommand()); ListIterator i = listeners.listIterator(); - ActionEvent newe = new ActionEvent(this, channel, e.getActionCommand()); while (i.hasNext()) { ActionListener listener = i.next(); listener.actionPerformed(newe); } + setMaximumSize(getPreferredSize()); } public AltosChannelMenu(int current_channel) { - super("Channel", true); - group = new ButtonGroup(); channel = current_channel; listeners = new LinkedList(); - for (int c = 0; c <= 9; c++) { - JRadioButtonMenuItem radioitem = new JRadioButtonMenuItem(String.format("Channel %1d (%7.3fMHz)", c, - 434.550 + c * 0.1), - c == channel); - radioitem.setActionCommand(String.format("%d", c)); - radioitem.addActionListener(this); - add(radioitem); - group.add(radioitem); - } + for (int c = 0; c <= 9; c++) + addItem(String.format("Channel %1d (%7.3fMHz)", c, 434.550 + c * 0.1)); + setSelectedIndex(channel); + setMaximumRowCount(10); } } diff --git a/ao-tools/altosui/AltosConfig.java b/ao-tools/altosui/AltosConfig.java index 19503dcb..6bda20d8 100644 --- a/ao-tools/altosui/AltosConfig.java +++ b/ao-tools/altosui/AltosConfig.java @@ -158,7 +158,7 @@ public class AltosConfig implements Runnable, ActionListener { void abort() { JOptionPane.showMessageDialog(owner, String.format("Connection to \"%s\" failed", - device.toString()), + device.toShortString()), "Connection Failed", JOptionPane.ERROR_MESSAGE); serial_line.close(); @@ -266,18 +266,18 @@ public class AltosConfig implements Runnable, ActionListener { } catch (FileNotFoundException ee) { JOptionPane.showMessageDialog(owner, String.format("Cannot open device \"%s\"", - device.toString()), + device.toShortString()), "Cannot open target device", JOptionPane.ERROR_MESSAGE); } catch (AltosSerialInUseException si) { JOptionPane.showMessageDialog(owner, String.format("Device \"%s\" already in use", - device.toString()), + device.toShortString()), "Device in use", JOptionPane.ERROR_MESSAGE); } catch (IOException ee) { JOptionPane.showMessageDialog(owner, - device.toString(), + device.toShortString(), ee.getLocalizedMessage(), JOptionPane.ERROR_MESSAGE); } diff --git a/ao-tools/altosui/AltosDebug.java b/ao-tools/altosui/AltosDebug.java index 9aa35d3f..8d435b66 100644 --- a/ao-tools/altosui/AltosDebug.java +++ b/ao-tools/altosui/AltosDebug.java @@ -261,7 +261,7 @@ public class AltosDebug extends AltosSerial { printf ("R\n"); } - public AltosDebug (altos_device in_device) throws FileNotFoundException, AltosSerialInUseException { + public AltosDebug (AltosDevice in_device) throws FileNotFoundException, AltosSerialInUseException { super(in_device); } } \ No newline at end of file diff --git a/ao-tools/altosui/AltosDevice.java b/ao-tools/altosui/AltosDevice.java index f646305b..f0fda57b 100644 --- a/ao-tools/altosui/AltosDevice.java +++ b/ao-tools/altosui/AltosDevice.java @@ -101,6 +101,15 @@ public class AltosDevice extends altos_device { getName(), getSerial(), getPath()); } + public String toShortString() { + String name = getName(); + if (name == null) + name = "Altus Metrum"; + return String.format("%s %d %s", + name, getSerial(), getPath()); + + } + public boolean isAltusMetrum() { if (getVendor() != vendor_altusmetrum) return false; diff --git a/ao-tools/altosui/AltosEepromDownload.java b/ao-tools/altosui/AltosEepromDownload.java index 912ff476..fb5dcfc0 100644 --- a/ao-tools/altosui/AltosEepromDownload.java +++ b/ao-tools/altosui/AltosEepromDownload.java @@ -232,14 +232,14 @@ public class AltosEepromDownload implements Runnable { CaptureLog(); } catch (IOException ee) { JOptionPane.showMessageDialog(frame, - device.toString(), + device.toShortString(), ee.getLocalizedMessage(), JOptionPane.ERROR_MESSAGE); } catch (InterruptedException ie) { } catch (TimeoutException te) { JOptionPane.showMessageDialog(frame, String.format("Connection to \"%s\" failed", - device.toString()), + device.toShortString()), "Connection Failed", JOptionPane.ERROR_MESSAGE); } @@ -266,18 +266,18 @@ public class AltosEepromDownload implements Runnable { } catch (FileNotFoundException ee) { JOptionPane.showMessageDialog(frame, String.format("Cannot open device \"%s\"", - device.toString()), + device.toShortString()), "Cannot open target device", JOptionPane.ERROR_MESSAGE); } catch (AltosSerialInUseException si) { JOptionPane.showMessageDialog(frame, String.format("Device \"%s\" already in use", - device.toString()), + device.toShortString()), "Device in use", JOptionPane.ERROR_MESSAGE); } catch (IOException ee) { JOptionPane.showMessageDialog(frame, - device.toString(), + device.toShortString(), ee.getLocalizedMessage(), JOptionPane.ERROR_MESSAGE); } diff --git a/ao-tools/altosui/AltosFlashUI.java b/ao-tools/altosui/AltosFlashUI.java index d3b72c67..f63097ac 100644 --- a/ao-tools/altosui/AltosFlashUI.java +++ b/ao-tools/altosui/AltosFlashUI.java @@ -90,7 +90,7 @@ public class AltosFlashUI } catch (AltosSerialInUseException si) { JOptionPane.showMessageDialog(frame, String.format("Device \"%s\" already in use", - debug_dongle.toString()), + debug_dongle.toShortString()), "Device in use", JOptionPane.ERROR_MESSAGE); } catch (IOException e) { diff --git a/ao-tools/altosui/AltosFlightUI.java b/ao-tools/altosui/AltosFlightUI.java index 78b005c0..56ab7ebc 100644 --- a/ao-tools/altosui/AltosFlightUI.java +++ b/ao-tools/altosui/AltosFlightUI.java @@ -36,8 +36,6 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay { AltosFlightReader reader; AltosDisplayThread thread; - private Box vbox; - JTabbedPane pane; AltosPad pad; @@ -128,22 +126,47 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay { exit_on_close = true; } + Container bag; + public AltosFlightUI(AltosVoice in_voice, AltosFlightReader in_reader, final int serial) { AltosPreferences.init(this); voice = in_voice; reader = in_reader; + bag = getContentPane(); + bag.setLayout(new GridBagLayout()); + + GridBagConstraints c = new GridBagConstraints(); + java.net.URL imgURL = AltosUI.class.getResource("/altus-metrum-16x16.jpg"); if (imgURL != null) setIconImage(new ImageIcon(imgURL).getImage()); setTitle(String.format("AltOS %s", reader.name)); - flightStatus = new AltosFlightStatus(); + if (serial >= 0) { + // Channel menu + JComboBox channels = new AltosChannelMenu(AltosPreferences.channel(serial)); + channels.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int channel = Integer.parseInt(e.getActionCommand()); + reader.set_channel(channel); + AltosPreferences.set_channel(serial, channel); + } + }); + c.gridx = 0; + c.gridy = 0; + c.anchor = GridBagConstraints.WEST; + bag.add (channels, c); + } - vbox = new Box (BoxLayout.Y_AXIS); - vbox.add(flightStatus); + flightStatus = new AltosFlightStatus(); + c.gridx = 0; + c.gridy = 1; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + bag.add(flightStatus, c); pane = new JTabbedPane(); @@ -163,29 +186,12 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay { flightInfoPane = new JScrollPane(flightInfo.box()); pane.add("Table", flightInfoPane); - vbox.add(pane); - - this.add(vbox); - - if (serial >= 0) { - JMenuBar menubar = new JMenuBar(); - - // Channel menu - { - JMenu menu = new AltosChannelMenu(AltosPreferences.channel(serial)); - menu.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - int channel = Integer.parseInt(e.getActionCommand()); - reader.set_channel(channel); - AltosPreferences.set_channel(serial, channel); - } - }); - menu.setMnemonic(KeyEvent.VK_C); - menubar.add(menu); - } - - this.setJMenuBar(menubar); - } + c.gridx = 0; + c.gridy = 2; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1; + c.weighty = 1; + bag.add(pane, c); this.setSize(this.getPreferredSize()); this.validate(); diff --git a/ao-tools/altosui/AltosIgniteUI.java b/ao-tools/altosui/AltosIgniteUI.java index caecc3ef..0207e39f 100644 --- a/ao-tools/altosui/AltosIgniteUI.java +++ b/ao-tools/altosui/AltosIgniteUI.java @@ -103,7 +103,7 @@ public class AltosIgniteUI close(); JOptionPane.showMessageDialog(owner, String.format("Connection to \"%s\" failed", - device.toString()), + device.toShortString()), "Connection Failed", JOptionPane.ERROR_MESSAGE); } @@ -194,18 +194,18 @@ public class AltosIgniteUI } catch (FileNotFoundException ee) { JOptionPane.showMessageDialog(owner, String.format("Cannot open device \"%s\"", - device.toString()), + device.toShortString()), "Cannot open target device", JOptionPane.ERROR_MESSAGE); } catch (AltosSerialInUseException si) { JOptionPane.showMessageDialog(owner, String.format("Device \"%s\" already in use", - device.toString()), + device.toShortString()), "Device in use", JOptionPane.ERROR_MESSAGE); } catch (IOException ee) { JOptionPane.showMessageDialog(owner, - device.toString(), + device.toShortString(), ee.getLocalizedMessage(), JOptionPane.ERROR_MESSAGE); } diff --git a/ao-tools/altosui/AltosSerial.java b/ao-tools/altosui/AltosSerial.java index 0d32a5ae..ab74486b 100644 --- a/ao-tools/altosui/AltosSerial.java +++ b/ao-tools/altosui/AltosSerial.java @@ -38,7 +38,7 @@ public class AltosSerial implements Runnable { static List devices_opened = Collections.synchronizedList(new LinkedList()); - altos_device device; + AltosDevice device; SWIGTYPE_p_altos_file altos; LinkedList> monitors; LinkedBlockingQueue reply_queue; @@ -195,7 +195,7 @@ public class AltosSerial implements Runnable { } altos = libaltos.altos_open(device); if (altos == null) - throw new FileNotFoundException(device.toString()); + throw new FileNotFoundException(device.toShortString()); input_thread = new Thread(this); input_thread.start(); print("~\nE 0\n"); @@ -233,7 +233,7 @@ public class AltosSerial implements Runnable { } } - public AltosSerial(altos_device in_device) throws FileNotFoundException, AltosSerialInUseException { + public AltosSerial(AltosDevice in_device) throws FileNotFoundException, AltosSerialInUseException { device = in_device; line = ""; monitor_mode = false; diff --git a/ao-tools/altosui/AltosTelemetryReader.java b/ao-tools/altosui/AltosTelemetryReader.java index 379e0e67..de5f50e9 100644 --- a/ao-tools/altosui/AltosTelemetryReader.java +++ b/ao-tools/altosui/AltosTelemetryReader.java @@ -55,7 +55,7 @@ class AltosTelemetryReader extends AltosFlightReader { device = in_device; serial = new AltosSerial(device); log = new AltosLog(serial); - name = device.toString(); + name = device.toShortString(); telem = new LinkedBlockingQueue(); serial.add_monitor(telem); diff --git a/ao-tools/altosui/AltosUI.java b/ao-tools/altosui/AltosUI.java index b573ef7f..6bfde014 100644 --- a/ao-tools/altosui/AltosUI.java +++ b/ao-tools/altosui/AltosUI.java @@ -53,18 +53,18 @@ public class AltosUI extends JFrame { } catch (FileNotFoundException ee) { JOptionPane.showMessageDialog(AltosUI.this, String.format("Cannot open device \"%s\"", - device.toString()), + device.toShortString()), "Cannot open target device", JOptionPane.ERROR_MESSAGE); } catch (AltosSerialInUseException si) { JOptionPane.showMessageDialog(AltosUI.this, String.format("Device \"%s\" already in use", - device.toString()), + device.toShortString()), "Device in use", JOptionPane.ERROR_MESSAGE); } catch (IOException ee) { JOptionPane.showMessageDialog(AltosUI.this, - device.toString(), + device.toShortString(), "Unkonwn I/O error", JOptionPane.ERROR_MESSAGE); } -- cgit v1.2.3