package altosui;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Toolkit;
-import java.awt.Window;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import javax.swing.JFrame;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-import javax.swing.JRadioButtonMenuItem;
-import javax.swing.JSplitPane;
-import javax.swing.JTable;
-import javax.swing.KeyStroke;
-import javax.swing.table.TableCellEditor;
-import javax.swing.table.DefaultTableCellRenderer;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.filechooser.FileNameExtensionFilter;
+import javax.swing.table.AbstractTableModel;
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import gnu.io.CommPortIdentifier;
+
import altosui.AltosSerial;
import altosui.AltosSerialMonitor;
+import altosui.AltosTelemetry;
+import altosui.AltosState;
class AltosUIMonitor implements AltosSerialMonitor {
public void data(String data) {
}
}
+class AltosFlightStatusTableModel extends AbstractTableModel {
+ private String[] columnNames = {"Height (m)", "State", "RSSI (dBm)", "Speed (m/s)" };
+ private Object[] data = { 0, "idle", 0, 0 };
+
+ public int getColumnCount() { return columnNames.length; }
+ public int getRowCount() { return 1; }
+ public String getColumnName(int col) { return columnNames[col]; }
+ public Object getValueAt(int row, int col) { return data[col]; }
+
+ public void setValueAt(Object value, int col) {
+ data[col] = value;
+ fireTableCellUpdated(0, col);
+ }
+
+ public void setValueAt(Object value, int row, int col) {
+ setValueAt(value, col);
+ }
+
+ public void set(AltosState state) {
+ setValueAt(state.height, 0);
+ setValueAt(state.data.state, 1);
+ setValueAt(state.data.rssi, 2);
+ setValueAt(state.speed, 3);
+ }
+}
+
public class AltosUI extends JFrame {
private int channel = -1;
createMenu();
- serialLine = new AltosSerial("/dev/ttyACM0");
+ serialLine = new AltosSerial();
serialLine.monitor(new AltosUIMonitor());
- serialLine.start();
- Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
- size.width = size.width*9/10;
- size.height = size.height*9/10;
- this.setSize(size);
+ int dpi = Toolkit.getDefaultToolkit().getScreenResolution();
+ this.setSize(new Dimension (dpi * 5, dpi * 4));
this.validate();
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
});
}
+ final JFileChooser deviceChooser = new JFileChooser();
+ final JFileChooser logdirChooser = new JFileChooser();
+ final String logdirName = "TeleMetrum";
+ File logdir = null;
+
+ private void setLogdir() {
+ if (logdir == null)
+ logdir = new File(logdirChooser.getCurrentDirectory(), logdirName);
+ logdirChooser.setCurrentDirectory(logdir);
+ }
+
+ private void makeLogdir() {
+ setLogdir();
+ if (!logdir.exists()) {
+ if (!logdir.mkdirs())
+ JOptionPane.showMessageDialog(AltosUI.this,
+ logdir.getName(),
+ "Cannot create directory",
+ JOptionPane.ERROR_MESSAGE);
+ } else if (!logdir.isDirectory()) {
+ JOptionPane.showMessageDialog(AltosUI.this,
+ logdir.getName(),
+ "Is not a directory",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ private void PickSerialDevice() {
+ java.util.Enumeration<CommPortIdentifier> port_list = CommPortIdentifier.getPortIdentifiers();
+ while (port_list.hasMoreElements()) {
+ CommPortIdentifier identifier = port_list.nextElement();
+ System.out.println("Serial port " + identifier.getName());
+ }
+ }
+
+ private void ConnectToDevice() {
+ PickSerialDevice();
+ int returnVal = deviceChooser.showOpenDialog(AltosUI.this);
+
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ File file = deviceChooser.getSelectedFile();
+ try {
+ serialLine.open(file);
+ } catch (FileNotFoundException ee) {
+ JOptionPane.showMessageDialog(AltosUI.this,
+ file.getName(),
+ "Cannot open serial port",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+
+ String readline(FileInputStream s) throws IOException {
+ int c;
+ String line = "";
+
+ while ((c = s.read()) != -1) {
+ if (c == '\r')
+ continue;
+ if (c == '\n')
+ return line;
+ line = line + (char) c;
+ }
+ return null;
+ }
+
+ /*
+ * Open an existing telemetry file and replay it in realtime
+ */
+
+ private void Replay() {
+ setLogdir();
+ logdirChooser.setDialogTitle("Select Telemetry File");
+ logdirChooser.setFileFilter(new FileNameExtensionFilter("Telemetry file", "telem"));
+ int returnVal = logdirChooser.showOpenDialog(AltosUI.this);
+
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ File file = logdirChooser.getSelectedFile();
+ if (file == null)
+ System.out.println("No file selected?");
+ String filename = file.getName();
+ try {
+ FileInputStream replay = new FileInputStream(file);
+ String line;
+
+ try {
+ while ((line = readline(replay)) != null) {
+ try {
+ AltosTelemetry t = new AltosTelemetry(line);
+ System.out.println ("Version " + t.version + t.callsign);
+ } catch (ParseException pp) {
+ JOptionPane.showMessageDialog(AltosUI.this,
+ line,
+ "error parsing",
+ JOptionPane.ERROR_MESSAGE);
+ break;
+ }
+ }
+ } catch (IOException ee) {
+ JOptionPane.showMessageDialog(AltosUI.this,
+ filename,
+ "error reading",
+ JOptionPane.ERROR_MESSAGE);
+ } finally {
+ try {
+ replay.close();
+ } catch (IOException e) {}
+ }
+ } catch (FileNotFoundException ee) {
+ JOptionPane.showMessageDialog(AltosUI.this,
+ filename,
+ "Cannot open serial port",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+
+ private void SaveFlightData() {
+ }
+
private void createMenu() {
JMenuBar menubar = new JMenuBar();
JMenu menu;
item = new JMenuItem("Connect to Device",KeyEvent.VK_C);
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
+ ConnectToDevice();
}
});
menu.add(item);
item = new JMenuItem("Disconnect from Device",KeyEvent.VK_D);
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
+ serialLine.close();
}
});
menu.add(item);
item = new JMenuItem("Save Flight Data",KeyEvent.VK_S);
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
+ SaveFlightData();
}
});
menu.add(item);
item = new JMenuItem("Replay",KeyEvent.VK_R);
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
+ Replay();
}
});
menu.add(item);
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("Channel " + c + " (" +
- (434.550 + c * .1) + ")",
- c == 0);
+ radioitem = new JRadioButtonMenuItem(String.format("Channel %1d (%7.3fMHz)", c,
+ 434.550 + c * 0.1),
+ c == 0);
+ radioitem.setActionCommand(String.format("%d", c));
radioitem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
+ System.out.println("Command: " + e.getActionCommand() + " param: " +
+ e.paramString());
}
});
menu.add(radioitem);
+ group.add(radioitem);
}
}