X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=ao-tools%2Faltosui%2FAltosUI.java;h=ad02f2ef990149ae21325a99699418fe84cf2745;hp=37625e8e47f1944d899527f64dfa0f11eefe14fe;hb=61590b8729831cb138b2ba6b88802c208d114753;hpb=887b11f6b9c81b9f15348d54017e700ca7dc5e55 diff --git a/ao-tools/altosui/AltosUI.java b/ao-tools/altosui/AltosUI.java index 37625e8e..ad02f2ef 100644 --- a/ao-tools/altosui/AltosUI.java +++ b/ao-tools/altosui/AltosUI.java @@ -70,8 +70,22 @@ public class AltosUI extends JFrame { public AltosVoice voice = new AltosVoice(); + public static boolean load_library(Frame frame) { + if (!AltosDevice.load_library()) { + JOptionPane.showMessageDialog(frame, + String.format("No AltOS library in \"%s\"", + System.getProperty("java.library.path","")), + "Cannot load device access library", + JOptionPane.ERROR_MESSAGE); + return false; + } + return true; + } + public AltosUI() { + load_library(null); + String[] statusNames = { "Height (m)", "State", "RSSI (dBm)", "Speed (m/s)" }; Object[][] statusData = { { "0", "pad", "-50", "0" } }; @@ -231,11 +245,19 @@ public class AltosUI extends JFrame { if (state.npad > 0) { if (state.from_pad != null) { - info_add_row(1, "Distance from pad", "%6.0f m", state.from_pad.distance); - info_add_row(1, "Direction from pad", "%6.0f°", state.from_pad.bearing); + info_add_row(1, "Distance from pad", "%6d m", + (int) (state.from_pad.distance + 0.5)); + info_add_row(1, "Direction from pad", "%6d°", + (int) (state.from_pad.bearing + 0.5)); + info_add_row(1, "Elevation from pad", "%6d°", + (int) (state.elevation + 0.5)); + info_add_row(1, "Range from pad", "%6d m", + (int) (state.range + 0.5)); } else { info_add_row(1, "Distance from pad", "unknown"); info_add_row(1, "Direction from pad", "unknown"); + info_add_row(1, "Elevation from pad", "unknown"); + info_add_row(1, "Range from pad", "unknown"); } info_add_deg(1, "Pad latitude", state.pad_lat, 'N', 'S'); info_add_deg(1, "Pad longitude", state.pad_lon, 'E', 'W'); @@ -269,8 +291,11 @@ public class AltosUI extends JFrame { class IdleThread extends Thread { + boolean started; private AltosState state; int reported_landing; + int report_interval; + long report_time; public synchronized void report(boolean last) { if (state == null) @@ -322,47 +347,88 @@ public class AltosUI extends JFrame { } } + long now () { + return System.currentTimeMillis(); + } + + void set_report_time() { + report_time = now() + report_interval; + } + public void run () { reported_landing = 0; state = null; + report_interval = 10000; try { for (;;) { - Thread.sleep(20000); + set_report_time(); + for (;;) { + voice.drain(); + synchronized (this) { + long sleep_time = report_time - now(); + if (sleep_time <= 0) + break; + wait(sleep_time); + } + } report(false); } } catch (InterruptedException ie) { + try { + voice.drain(); + } catch (InterruptedException iie) { } } } - public void notice(AltosState new_state) { + public synchronized void notice(AltosState new_state, boolean spoken) { AltosState old_state = state; state = new_state; - if (old_state != null && old_state.state != state.state) - report(false); + if (!started && state.state > Altos.ao_flight_pad) { + started = true; + start(); + } + + if (state.state < Altos.ao_flight_drogue) + report_interval = 10000; + else + report_interval = 20000; + if (old_state != null && old_state.state != state.state) { + report_time = now(); + this.notify(); + } else if (spoken) + set_report_time(); } } - private void tell(AltosState state, AltosState old_state) { + private boolean tell(AltosState state, AltosState old_state) { + boolean ret = false; if (old_state == null || old_state.state != state.state) { voice.speak(state.data.state()); if ((old_state == null || old_state.state <= Altos.ao_flight_boost) && state.state > Altos.ao_flight_boost) { voice.speak("max speed: %d meters per second.", (int) (state.max_speed + 0.5)); + ret = true; } else if ((old_state == null || old_state.state < Altos.ao_flight_drogue) && state.state >= Altos.ao_flight_drogue) { voice.speak("max height: %d meters.", (int) (state.max_height + 0.5)); + ret = true; } } if (old_state == null || old_state.gps_ready != state.gps_ready) { - if (state.gps_ready) + if (state.gps_ready) { voice.speak("GPS ready"); - else if (old_state != null) + ret = true; + } + else if (old_state != null) { voice.speak("GPS lost"); + ret = true; + } } old_state = state; + return ret; } class DisplayThread extends Thread { @@ -376,20 +442,21 @@ public class AltosUI extends JFrame { AltosRecord read() throws InterruptedException, ParseException, AltosCRCException, IOException { return null; } - void close() { } + void close(boolean interrupted) { } void update(AltosState state) throws InterruptedException { } public void run() { + boolean interrupted = false; String line; AltosState state = null; AltosState old_state = null; + boolean told; idle_thread = new IdleThread(); info_reset(); info_finish(); - idle_thread.start(); try { for (;;) { try { @@ -400,8 +467,8 @@ public class AltosUI extends JFrame { state = new AltosState(record, state); update(state); show(state, crc_errors); - tell(state, old_state); - idle_thread.notice(state); + told = tell(state, old_state); + idle_thread.notice(state, told); } catch (ParseException pp) { System.out.printf("Parse error: %d \"%s\"\n", pp.getErrorOffset(), pp.getMessage()); } catch (AltosCRCException ce) { @@ -410,14 +477,18 @@ public class AltosUI extends JFrame { } } } catch (InterruptedException ee) { + interrupted = true; } catch (IOException ie) { JOptionPane.showMessageDialog(AltosUI.this, String.format("Error reading from \"%s\"", name), "Telemetry Read Error", JOptionPane.ERROR_MESSAGE); } finally { - close(); + close(interrupted); idle_thread.interrupt(); + try { + idle_thread.join(); + } catch (InterruptedException ie) {} } } @@ -438,7 +509,7 @@ public class AltosUI extends JFrame { return new AltosTelemetry(l.line); } - void close() { + void close(boolean interrupted) { serial.close(); serial.remove_monitor(telem); } @@ -452,7 +523,8 @@ public class AltosUI extends JFrame { } private void ConnectToDevice() { - AltosDevice device = AltosDeviceDialog.show(AltosUI.this, AltosDevice.BaseStation); + AltosDevice device = AltosDeviceDialog.show(AltosUI.this, + AltosDevice.product_basestation); if (device != null) { try { @@ -522,8 +594,9 @@ public class AltosUI extends JFrame { return null; } - public void close () { - report(); + public void close (boolean interrupted) { + if (!interrupted) + report(); } public ReplayThread(AltosReader in_reader, String in_name) { @@ -594,6 +667,13 @@ public class AltosUI extends JFrame { new AltosCSVUI(AltosUI.this); } + /* Load a flight log CSV file and display a pretty graph. + */ + + private void GraphData() { + new AltosGraphUI(AltosUI.this); + } + /* Create the AltosUI menus */ private void createMenu() { @@ -640,6 +720,14 @@ public class AltosUI extends JFrame { }); menu.add(item); + item = new JMenuItem("Graph Data",KeyEvent.VK_F); + 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)); @@ -822,4 +910,4 @@ public class AltosUI extends JFrame { altosui.setVisible(true); } } -} \ No newline at end of file +}