X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=ao-tools%2Faltosui%2FAltosUI.java;h=e63a004c67c5f5ef2e747da9373c2259f3ae50b5;hb=71191ecef3ba0e00d0f8a7cd1a24982bfa44ec72;hp=33ce274a26d7393f31e2fc2f43f150fcb82b3e8d;hpb=e1463d8e265dfd42c824d90088cd2a51b4cf8131;p=fw%2Faltos diff --git a/ao-tools/altosui/AltosUI.java b/ao-tools/altosui/AltosUI.java index 33ce274a..e63a004c 100644 --- a/ao-tools/altosui/AltosUI.java +++ b/ao-tools/altosui/AltosUI.java @@ -40,6 +40,10 @@ import altosui.AltosLog; import altosui.AltosVoice; import altosui.AltosFlightStatusTableModel; import altosui.AltosFlightInfoTableModel; +import altosui.AltosChannelMenu; +import altosui.AltosFlashUI; +import altosui.AltosLogfileChooser; +import altosui.AltosCSVUI; import libaltosJNI.*; @@ -164,21 +168,17 @@ public class AltosUI extends JFrame { flightInfoModel[i].finish(); } - public void show(AltosState state) { + public void show(AltosState state, int crc_errors) { flightStatusModel.set(state); info_reset(); - if (state.gps_ready) - info_add_row(0, "Ground state", "%s", "ready"); - else - info_add_row(0, "Ground state", "wait (%d)", - state.gps_waiting); info_add_row(0, "Rocket state", "%s", state.data.state()); info_add_row(0, "Callsign", "%s", state.data.callsign); info_add_row(0, "Rocket serial", "%6d", state.data.serial); info_add_row(0, "Rocket flight", "%6d", state.data.flight); info_add_row(0, "RSSI", "%6d dBm", state.data.rssi); + info_add_row(0, "CRC Errors", "%6d", crc_errors); info_add_row(0, "Height", "%6.0f m", state.height); info_add_row(0, "Max height", "%6.0f m", state.max_height); info_add_row(0, "Acceleration", "%8.1f m/s²", state.acceleration); @@ -193,6 +193,11 @@ public class AltosUI extends JFrame { if (state.gps == null) { info_add_row(1, "GPS", "not available"); } else { + if (state.gps_ready) + info_add_row(1, "GPS state", "%s", "ready"); + else + info_add_row(1, "GPS state", "wait (%d)", + state.gps_waiting); if (state.data.gps.locked) info_add_row(1, "GPS", " locked"); else if (state.data.gps.connected) @@ -260,7 +265,7 @@ public class AltosUI extends JFrame { private AltosState state; int reported_landing; - public void report(boolean last) { + public synchronized void report(boolean last) { if (state == null) return; @@ -274,7 +279,16 @@ public class AltosUI extends JFrame { } /* If the rocket isn't on the pad, then report height */ - if (state.state > Altos.ao_flight_pad) { + if (Altos.ao_flight_drogue <= state.state && + state.state < Altos.ao_flight_landed && + state.range >= 0) + { + voice.speak("Height %d, bearing %d, elevation %d, range %d.\n", + (int) (state.height + 0.5), + (int) (state.from_pad.bearing + 0.5), + (int) (state.elevation + 0.5), + (int) (state.range + 0.5)); + } else if (state.state > Altos.ao_flight_pad) { voice.speak("%d meters", (int) (state.height + 0.5)); } else { reported_landing = 0; @@ -284,7 +298,7 @@ public class AltosUI extends JFrame { * either we've got a landed report or we haven't heard from it in * a long time */ - if (!state.ascent && + if (state.state >= Altos.ao_flight_drogue && (last || System.currentTimeMillis() - state.report_time >= 15000 || state.state == Altos.ao_flight_landed)) @@ -294,7 +308,7 @@ public class AltosUI extends JFrame { else voice.speak("rocket may have crashed"); if (state.from_pad != null) - voice.speak("bearing %d degrees, range %d meters", + voice.speak("Bearing %d degrees, range %d meters.", (int) (state.from_pad.bearing + 0.5), (int) (state.from_pad.distance + 0.5)); ++reported_landing; @@ -307,7 +321,7 @@ public class AltosUI extends JFrame { state = null; try { for (;;) { - Thread.sleep(10000); + Thread.sleep(20000); report(false); } } catch (InterruptedException ie) { @@ -315,7 +329,10 @@ public class AltosUI extends JFrame { } public void notice(AltosState new_state) { + AltosState old_state = state; state = new_state; + if (old_state != null && old_state.state != state.state) + report(false); } } @@ -346,7 +363,11 @@ public class AltosUI extends JFrame { String name; - AltosRecord read() throws InterruptedException, ParseException { return null; } + int crc_errors; + + void init() { } + + AltosRecord read() throws InterruptedException, ParseException, AltosCRCException { return null; } void close() { } @@ -371,11 +392,14 @@ public class AltosUI extends JFrame { old_state = state; state = new AltosState(record, state); update(state); - show(state); + show(state, crc_errors); tell(state, old_state); idle_thread.notice(state); } catch (ParseException pp) { System.out.printf("Parse error: %d \"%s\"\n", pp.getErrorOffset(), pp.getMessage()); + } catch (AltosCRCException ce) { + ++crc_errors; + show(state, crc_errors); } } } catch (InterruptedException ee) { @@ -395,7 +419,7 @@ public class AltosUI extends JFrame { AltosSerial serial; LinkedBlockingQueue telem; - AltosRecord read() throws InterruptedException, ParseException { + AltosRecord read() throws InterruptedException, ParseException, AltosCRCException { return new AltosTelemetry(telem.take()); } @@ -417,6 +441,7 @@ public class AltosUI extends JFrame { if (device != null) { try { + stop_display(); serial_line.open(device); DeviceThread thread = new DeviceThread(serial_line); serial_line.set_channel(AltosPreferences.channel()); @@ -453,6 +478,14 @@ public class AltosUI extends JFrame { } } + void ConfigureTeleMetrum() { + new AltosConfig(AltosUI.this); + } + + void FlashImage() { + new AltosFlashUI(AltosUI.this); + } + /* * Open an existing telemetry file and replay it in realtime */ @@ -504,8 +537,12 @@ public class AltosUI extends JFrame { Thread display_thread; private void stop_display() { - if (display_thread != null && display_thread.isAlive()) + if (display_thread != null && display_thread.isAlive()) { display_thread.interrupt(); + try { + display_thread.join(); + } catch (InterruptedException ie) {} + } display_thread = null; } @@ -519,33 +556,12 @@ public class AltosUI extends JFrame { * Replay a flight from telemetry data */ private void Replay() { - JFileChooser logfile_chooser = new JFileChooser(); - - logfile_chooser.setDialogTitle("Select Flight Record File"); - logfile_chooser.setFileFilter(new FileNameExtensionFilter("Flight data file", "eeprom", "telem")); - logfile_chooser.setCurrentDirectory(AltosPreferences.logdir()); - int returnVal = logfile_chooser.showOpenDialog(AltosUI.this); - - if (returnVal == JFileChooser.APPROVE_OPTION) { - File file = logfile_chooser.getSelectedFile(); - if (file == null) - System.out.println("No file selected?"); - String filename = file.getName(); - try { - FileInputStream replay = new FileInputStream(file); - DisplayThread thread; - if (filename.endsWith("eeprom")) - thread = new ReplayEepromThread(replay, filename); - else - thread = new ReplayTelemetryThread(replay, filename); - run_display(thread); - } catch (FileNotFoundException ee) { - JOptionPane.showMessageDialog(AltosUI.this, - filename, - "Cannot open telemetry file", - JOptionPane.ERROR_MESSAGE); - } - } + AltosLogfileChooser chooser = new AltosLogfileChooser( + AltosUI.this); + AltosReader reader = chooser.runDialog(); + if (reader != null) + run_display(new ReplayThread(reader, + chooser.filename())); } /* Connect to TeleMetrum, either directly or through @@ -555,6 +571,14 @@ public class AltosUI extends JFrame { new AltosEepromDownload(AltosUI.this); } + /* Load a flight log file and write out a CSV file containing + * all of the data in standard units + */ + + private void ExportData() { + new AltosCSVUI(AltosUI.this); + } + /* Create the AltosUI menus */ private void createMenu() { @@ -585,6 +609,22 @@ public class AltosUI extends JFrame { }); menu.add(item); + item = new JMenuItem("Flash Image",KeyEvent.VK_F); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + FlashImage(); + } + }); + menu.add(item); + + item = new JMenuItem("Export Data",KeyEvent.VK_F); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ExportData(); + } + }); + menu.add(item); + item = new JMenuItem("Quit",KeyEvent.VK_Q); item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK)); @@ -628,6 +668,15 @@ public class AltosUI extends JFrame { }); 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 { @@ -680,33 +729,82 @@ public class AltosUI extends JFrame { // Channel menu { - menu = new JMenu("Channel", true); - menu.setMnemonic(KeyEvent.VK_C); - menubar.add(menu); - ButtonGroup group = new ButtonGroup(); - - for (int c = 0; c <= 9; c++) { - radioitem = new JRadioButtonMenuItem(String.format("Channel %1d (%7.3fMHz)", c, - 434.550 + c * 0.1), - c == AltosPreferences.channel()); - radioitem.setActionCommand(String.format("%d", c)); - radioitem.addActionListener(new ActionListener() { + menu = new AltosChannelMenu(AltosPreferences.channel()); + menu.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int new_channel = Integer.parseInt(e.getActionCommand()); AltosPreferences.set_channel(new_channel); serial_line.set_channel(new_channel); } - }); - menu.add(radioitem); - group.add(radioitem); - } + }); + menu.setMnemonic(KeyEvent.VK_C); + menubar.add(menu); } this.setJMenuBar(menubar); } + + static String replace_extension(String input, String extension) { + int dot = input.lastIndexOf("."); + if (dot > 0) + input = input.substring(0,dot); + return input.concat(extension); + } + + static AltosReader open_logfile(String filename) { + File file = new File (filename); + try { + FileInputStream in; + + in = new FileInputStream(file); + if (filename.endsWith("eeprom")) + return new AltosEepromReader(in); + else + return new AltosTelemetryReader(in); + } catch (FileNotFoundException fe) { + System.out.printf("Cannot open '%s'\n", filename); + return null; + } + } + + static AltosCSV open_csv(String filename) { + File file = new File (filename); + try { + return new AltosCSV(file); + } catch (FileNotFoundException fe) { + System.out.printf("Cannot open '%s'\n", filename); + return null; + } + } + + static void process_file(String input) { + String output = replace_extension(input,".csv"); + if (input.equals(output)) { + System.out.printf("Not processing '%s'\n", input); + return; + } + System.out.printf("Processing \"%s\" to \"%s\"\n", input, output); + AltosReader reader = open_logfile(input); + if (reader == null) + return; + AltosCSV writer = open_csv(output); + if (writer == null) + return; + writer.write(reader); + reader.close(); + writer.close(); + } + public static void main(final String[] args) { - AltosUI altosui = new AltosUI(); - altosui.setVisible(true); + + /* Handle batch-mode */ + if (args.length > 0) { + for (int i = 0; i < args.length; i++) + process_file(args[i]); + } else { + AltosUI altosui = new AltosUI(); + altosui.setVisible(true); + } } } \ No newline at end of file