From: Keith Packard Date: Thu, 29 May 2014 04:56:52 +0000 (-0700) Subject: telegps: Add 'Info' tab X-Git-Tag: 1.3.2.2~44 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=3871b9ac036e3adfa1da089245fc7973b268c921;hp=4cec35564324f909dcddeb7c0d83a2daa8223042 telegps: Add 'Info' tab This contains a summary of the tracking info, including position, speed and course. Signed-off-by: Keith Packard --- diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index 484f6213..a65669da 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -371,4 +371,30 @@ public class AltosConvert { return 94; return (int) Math.floor (1.0/2.0 * (24.0e6/32.0) / freq + 0.5); } + + public static final int BEARING_LONG = 0; + public static final int BEARING_SHORT = 1; + public static final int BEARING_VOICE = 2; + + public static String bearing_to_words(int length, double bearing) { + String [][] bearing_string = { + { + "North", "North North East", "North East", "East North East", + "East", "East South East", "South East", "South South East", + "South", "South South West", "South West", "West South West", + "West", "West North West", "North West", "North North West" + }, { + "N", "NNE", "NE", "ENE", + "E", "ESE", "SE", "SSE", + "S", "SSW", "SW", "WSW", + "W", "WNW", "NW", "NNW" + }, { + "north", "nor nor east", "north east", "east nor east", + "east", "east sow east", "south east", "sow sow east", + "south", "sow sow west", "south west", "west sow west", + "west", "west nor west", "north west", "nor nor west " + } + }; + return bearing_string[length][(int)((bearing / 90 * 8 + 1) / 2)%16]; + } } diff --git a/altoslib/AltosGreatCircle.java b/altoslib/AltosGreatCircle.java index 39df4fc8..4782c34d 100644 --- a/altoslib/AltosGreatCircle.java +++ b/altoslib/AltosGreatCircle.java @@ -30,30 +30,12 @@ public class AltosGreatCircle implements Cloneable { static final double rad = Math.PI / 180; static final double earth_radius = 6371.2 * 1000; /* in meters */ - public static final int BEARING_LONG = 0; - public static final int BEARING_SHORT = 1; - public static final int BEARING_VOICE = 2; + public static final int BEARING_LONG = AltosConvert.BEARING_LONG; + public static final int BEARING_SHORT = AltosConvert.BEARING_SHORT; + public static final int BEARING_VOICE = AltosConvert.BEARING_VOICE; public String bearing_words(int length) { - String [][] bearing_string = { - { - "North", "North North East", "North East", "East North East", - "East", "East South East", "South East", "South South East", - "South", "South South West", "South West", "West South West", - "West", "West North West", "North West", "North North West" - }, { - "N", "NNE", "NE", "ENE", - "E", "ESE", "SE", "SSE", - "S", "SSW", "SW", "WSW", - "W", "WNW", "NW", "NNW" - }, { - "north", "nor nor east", "north east", "east nor east", - "east", "east sow east", "south east", "sow sow east", - "south", "sow sow west", "south west", "west sow west", - "west", "west nor west", "north west", "nor nor west " - } - }; - return bearing_string[length][(int)((bearing / 90 * 8 + 1) / 2)%16]; + return AltosConvert.bearing_to_words(length, bearing); } public AltosGreatCircle (double start_lat, double start_lon, double start_alt, diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 9e8e22ac..1162e522 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -389,6 +389,10 @@ public class AltosState implements Cloneable { private AltosGpsAltitude gps_altitude; + private AltosValue gps_ground_speed; + private AltosValue gps_ascent_rate; + private AltosValue gps_course; + public double altitude() { double a = altitude.value(); if (a != AltosLib.MISSING) @@ -419,6 +423,18 @@ public class AltosState implements Cloneable { gps_altitude.set(new_gps_altitude, time); } + public double gps_ground_speed() { + return gps_ground_speed.value(); + } + + public double gps_ascent_rate() { + return gps_ascent_rate.value(); + } + + public double gps_course() { + return gps_course.value(); + } + class AltosPressure extends AltosValue { void set(double p, double time) { super.set(p, time); @@ -695,6 +711,8 @@ public class AltosState implements Cloneable { gps_altitude = new AltosGpsAltitude(); gps_ground_altitude = new AltosGpsGroundAltitude(); + gps_ground_speed = new AltosValue(); + gps_ascent_rate = new AltosValue(); speak_tick = AltosLib.MISSING; speak_altitude = AltosLib.MISSING; @@ -877,6 +895,12 @@ public class AltosState implements Cloneable { gps_ground_altitude.set(gps.alt, time); } gps_altitude.set(gps.alt, time); + if (gps.climb_rate != AltosLib.MISSING) + gps_ascent_rate.set(gps.climb_rate, time); + if (gps.ground_speed != AltosLib.MISSING) + gps_ground_speed.set(gps.ground_speed, time); + if (gps.course != AltosLib.MISSING) + gps_course.set(gps.course, time); } if (gps.lat != 0 && gps.lon != 0 && pad_lat != AltosLib.MISSING && diff --git a/altosui/AltosCSVUI.java b/altosui/AltosCSVUI.java deleted file mode 100644 index a0fceee5..00000000 --- a/altosui/AltosCSVUI.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 java.io.*; -import org.altusmetrum.altoslib_4.*; -import org.altusmetrum.altosuilib_2.*; - -public class AltosCSVUI - extends AltosUIDialog - implements ActionListener -{ - JFileChooser csv_chooser; - JPanel accessory; - JComboBox combo_box; - Iterable states; - AltosWriter writer; - - static String[] combo_box_items = { "Comma Separated Values (.CSV)", "Googleearth Data (.KML)" }; - - void set_default_file() { - File current = csv_chooser.getSelectedFile(); - String current_name = current.getName(); - String new_name = null; - String selected = (String) combo_box.getSelectedItem(); - - if (selected.contains("CSV")) - new_name = Altos.replace_extension(current_name, ".csv"); - else if (selected.contains("KML")) - new_name = Altos.replace_extension(current_name, ".kml"); - if (new_name != null) - csv_chooser.setSelectedFile(new File(new_name)); - } - - public void actionPerformed(ActionEvent e) { - if (e.getActionCommand().equals("comboBoxChanged")) - set_default_file(); - } - - public AltosCSVUI(JFrame frame, AltosStateIterable states, File source_file) { - this.states = states; - csv_chooser = new JFileChooser(source_file); - - accessory = new JPanel(); - accessory.setLayout(new GridBagLayout()); - - GridBagConstraints c = new GridBagConstraints(); - c.fill = GridBagConstraints.NONE; - c.weightx = 1; - c.weighty = 0; - c.insets = new Insets (4, 4, 4, 4); - - JLabel accessory_label = new JLabel("Export File Type"); - c.gridx = 0; - c.gridy = 0; - accessory.add(accessory_label, c); - - combo_box = new JComboBox(combo_box_items); - combo_box.addActionListener(this); - c.gridx = 0; - c.gridy = 1; - accessory.add(combo_box, c); - - csv_chooser.setAccessory(accessory); - csv_chooser.setSelectedFile(source_file); - set_default_file(); - int ret = csv_chooser.showSaveDialog(frame); - if (ret == JFileChooser.APPROVE_OPTION) { - File file = csv_chooser.getSelectedFile(); - String type = (String) combo_box.getSelectedItem(); - try { - if (type.contains("CSV")) - writer = new AltosCSV(file); - else - writer = new AltosKML(file); - writer.write(states); - writer.close(); - } catch (FileNotFoundException ee) { - JOptionPane.showMessageDialog(frame, - ee.getMessage(), - "Cannot open file", - JOptionPane.ERROR_MESSAGE); - } - } - } -} diff --git a/altosui/AltosDataChooser.java b/altosui/AltosDataChooser.java deleted file mode 100644 index 43726a44..00000000 --- a/altosui/AltosDataChooser.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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 javax.swing.*; -import javax.swing.filechooser.FileNameExtensionFilter; -import java.io.*; -import org.altusmetrum.altoslib_4.*; -import org.altusmetrum.altosuilib_2.*; - -public class AltosDataChooser extends JFileChooser { - JFrame frame; - String filename; - File file; - - public String filename() { - return filename; - } - - public File file() { - return file; - } - - public AltosStateIterable runDialog() { - int ret; - - ret = showOpenDialog(frame); - if (ret == APPROVE_OPTION) { - file = getSelectedFile(); - if (file == null) - return null; - filename = file.getName(); - try { - if (filename.endsWith("eeprom")) { - FileInputStream in = new FileInputStream(file); - return new AltosEepromFile(in); - } else if (filename.endsWith("telem")) { - FileInputStream in = new FileInputStream(file); - return new AltosTelemetryFile(in); - } else { - throw new FileNotFoundException(); - } - } catch (FileNotFoundException fe) { - JOptionPane.showMessageDialog(frame, - fe.getMessage(), - "Cannot open file", - JOptionPane.ERROR_MESSAGE); - } - } - return null; - } - - public AltosDataChooser(JFrame in_frame) { - frame = in_frame; - setDialogTitle("Select Flight Record File"); - setFileFilter(new FileNameExtensionFilter("TeleMetrum eeprom file", - "eeprom")); - setFileFilter(new FileNameExtensionFilter("Telemetry file", - "telem")); - setFileFilter(new FileNameExtensionFilter("TeleMega eeprom file", - "mega")); - setFileFilter(new FileNameExtensionFilter("EasyMini eeprom file", - "mini")); - setFileFilter(new FileNameExtensionFilter("Flight data file", - "telem", "eeprom", "mega", "mini")); - setCurrentDirectory(AltosUIPreferences.logdir()); - } -} diff --git a/altosui/AltosLed.java b/altosui/AltosLed.java deleted file mode 100644 index 93064f1e..00000000 --- a/altosui/AltosLed.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 javax.swing.*; - -public class AltosLed extends JLabel { - ImageIcon on, off; - - ImageIcon create_icon(String path) { - java.net.URL imgURL = AltosUI.class.getResource(path); - if (imgURL != null) - return new ImageIcon(imgURL); - System.err.printf("Cannot find icon \"%s\"\n", path); - return null; - } - - public void set(boolean set) { - if (set) - setIcon(on); - else - setIcon(off); - } - - public AltosLed(String on_path, String off_path) { - on = create_icon(on_path); - off = create_icon(off_path); - setIcon(off); - } -} diff --git a/altosui/AltosLights.java b/altosui/AltosLights.java deleted file mode 100644 index 7ad22f3e..00000000 --- a/altosui/AltosLights.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 javax.swing.*; - -public class AltosLights extends JComponent { - - GridBagLayout gridbag; - - AltosLed red, green; - - ImageIcon create_icon(String path, String description) { - java.net.URL imgURL = AltosUI.class.getResource(path); - if (imgURL != null) - return new ImageIcon(imgURL, description); - System.err.printf("Cannot find icon \"%s\"\n", path); - return null; - } - - public void set (boolean on) { - if (on) { - red.set(false); - green.set(true); - } else { - red.set(true); - green.set(false); - } - } - - public AltosLights() { - GridBagConstraints c; - gridbag = new GridBagLayout(); - setLayout(gridbag); - - c = new GridBagConstraints(); - red = new AltosLed("/redled.png", "/grayled.png"); - c.gridx = 0; c.gridy = 0; - c.insets = new Insets (0, 5, 0, 5); - gridbag.setConstraints(red, c); - add(red); - red.set(true); - green = new AltosLed("/greenled.png", "/grayled.png"); - c.gridx = 1; c.gridy = 0; - gridbag.setConstraints(green, c); - add(green); - green.set(false); - } -} diff --git a/altosui/Makefile.am b/altosui/Makefile.am index c834646d..9eff1614 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -20,7 +20,6 @@ altosui_JAVA = \ AltosConfigureUI.java \ AltosConfigTD.java \ AltosConfigTDUI.java \ - AltosCSVUI.java \ AltosDescent.java \ AltosFlashUI.java \ AltosFlightInfoTableModel.java \ @@ -36,8 +35,6 @@ altosui_JAVA = \ AltosLaunchUI.java \ AltosInfoTable.java \ AltosLanded.java \ - AltosLed.java \ - AltosLights.java \ AltosPad.java \ AltosUIPreferencesBackend.java \ AltosRomconfigUI.java \ @@ -45,8 +42,7 @@ altosui_JAVA = \ AltosGraph.java \ AltosGraphDataPoint.java \ AltosGraphDataSet.java \ - AltosGraphUI.java \ - AltosDataChooser.java + AltosGraphUI.java JFREECHART_CLASS= \ jfreechart.jar @@ -94,20 +90,13 @@ JAVA_ICONS=\ $(ICONDIR)/altus-metrum-128.png \ $(ICONDIR)/altus-metrum-256.png -ICONS= $(ICONDIR)/redled.png $(ICONDIR)/redoff.png \ - $(ICONDIR)/greenled.png $(ICONDIR)/greenoff.png \ - $(ICONDIR)/grayled.png $(ICONDIR)/grayoff.png - # icon base names for jar ICONJAR= -C $(ICONDIR) altus-metrum-16.png \ -C $(ICONDIR) altus-metrum-32.png \ -C $(ICONDIR) altus-metrum-48.png \ -C $(ICONDIR) altus-metrum-64.png \ -C $(ICONDIR) altus-metrum-128.png \ - -C $(ICONDIR) altus-metrum-256.png \ - -C $(ICONDIR) redled.png -C $(ICONDIR) redoff.png \ - -C $(ICONDIR) greenled.png -C $(ICONDIR) greenoff.png \ - -C $(ICONDIR) grayon.png -C $(ICONDIR) grayled.png + -C $(ICONDIR) altus-metrum-256.png WINDOWS_ICON=$(ICONDIR)/altus-metrum.ico diff --git a/altosuilib/AltosCSVUI.java b/altosuilib/AltosCSVUI.java new file mode 100644 index 00000000..0a5e4fa2 --- /dev/null +++ b/altosuilib/AltosCSVUI.java @@ -0,0 +1,103 @@ +/* + * 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 org.altusmetrum.altosuilib_2; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.io.*; +import org.altusmetrum.altoslib_4.*; + +public class AltosCSVUI + extends AltosUIDialog + implements ActionListener +{ + JFileChooser csv_chooser; + JPanel accessory; + JComboBox combo_box; + Iterable states; + AltosWriter writer; + + static String[] combo_box_items = { "Comma Separated Values (.CSV)", "Googleearth Data (.KML)" }; + + void set_default_file() { + File current = csv_chooser.getSelectedFile(); + String current_name = current.getName(); + String new_name = null; + String selected = (String) combo_box.getSelectedItem(); + + if (selected.contains("CSV")) + new_name = AltosLib.replace_extension(current_name, ".csv"); + else if (selected.contains("KML")) + new_name = AltosLib.replace_extension(current_name, ".kml"); + if (new_name != null) + csv_chooser.setSelectedFile(new File(new_name)); + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("comboBoxChanged")) + set_default_file(); + } + + public AltosCSVUI(JFrame frame, AltosStateIterable states, File source_file) { + this.states = states; + csv_chooser = new JFileChooser(source_file); + + accessory = new JPanel(); + accessory.setLayout(new GridBagLayout()); + + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.NONE; + c.weightx = 1; + c.weighty = 0; + c.insets = new Insets (4, 4, 4, 4); + + JLabel accessory_label = new JLabel("Export File Type"); + c.gridx = 0; + c.gridy = 0; + accessory.add(accessory_label, c); + + combo_box = new JComboBox(combo_box_items); + combo_box.addActionListener(this); + c.gridx = 0; + c.gridy = 1; + accessory.add(combo_box, c); + + csv_chooser.setAccessory(accessory); + csv_chooser.setSelectedFile(source_file); + set_default_file(); + int ret = csv_chooser.showSaveDialog(frame); + if (ret == JFileChooser.APPROVE_OPTION) { + File file = csv_chooser.getSelectedFile(); + String type = (String) combo_box.getSelectedItem(); + try { + if (type.contains("CSV")) + writer = new AltosCSV(file); + else + writer = new AltosKML(file); + writer.write(states); + writer.close(); + } catch (FileNotFoundException ee) { + JOptionPane.showMessageDialog(frame, + ee.getMessage(), + "Cannot open file", + JOptionPane.ERROR_MESSAGE); + } + } + } +} diff --git a/altosuilib/AltosDataChooser.java b/altosuilib/AltosDataChooser.java new file mode 100644 index 00000000..14d28115 --- /dev/null +++ b/altosuilib/AltosDataChooser.java @@ -0,0 +1,82 @@ +/* + * 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 org.altusmetrum.altosuilib_2; + +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.io.*; +import org.altusmetrum.altoslib_4.*; + +public class AltosDataChooser extends JFileChooser { + JFrame frame; + String filename; + File file; + + public String filename() { + return filename; + } + + public File file() { + return file; + } + + public AltosStateIterable runDialog() { + int ret; + + ret = showOpenDialog(frame); + if (ret == APPROVE_OPTION) { + file = getSelectedFile(); + if (file == null) + return null; + filename = file.getName(); + try { + if (filename.endsWith("eeprom")) { + FileInputStream in = new FileInputStream(file); + return new AltosEepromFile(in); + } else if (filename.endsWith("telem")) { + FileInputStream in = new FileInputStream(file); + return new AltosTelemetryFile(in); + } else { + throw new FileNotFoundException(); + } + } catch (FileNotFoundException fe) { + JOptionPane.showMessageDialog(frame, + fe.getMessage(), + "Cannot open file", + JOptionPane.ERROR_MESSAGE); + } + } + return null; + } + + public AltosDataChooser(JFrame in_frame) { + frame = in_frame; + setDialogTitle("Select Flight Record File"); + setFileFilter(new FileNameExtensionFilter("TeleMetrum eeprom file", + "eeprom")); + setFileFilter(new FileNameExtensionFilter("Telemetry file", + "telem")); + setFileFilter(new FileNameExtensionFilter("TeleMega eeprom file", + "mega")); + setFileFilter(new FileNameExtensionFilter("EasyMini eeprom file", + "mini")); + setFileFilter(new FileNameExtensionFilter("Flight data file", + "telem", "eeprom", "mega", "mini")); + setCurrentDirectory(AltosUIPreferences.logdir()); + } +} diff --git a/altosuilib/AltosLed.java b/altosuilib/AltosLed.java new file mode 100644 index 00000000..2debb62a --- /dev/null +++ b/altosuilib/AltosLed.java @@ -0,0 +1,45 @@ +/* + * 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 org.altusmetrum.altosuilib_2; + +import javax.swing.*; + +public class AltosLed extends JLabel { + ImageIcon on, off; + + ImageIcon create_icon(String path) { + java.net.URL imgURL = AltosUILib.class.getResource(path); + if (imgURL != null) + return new ImageIcon(imgURL); + System.err.printf("Cannot find icon \"%s\"\n", path); + return null; + } + + public void set(boolean set) { + if (set) + setIcon(on); + else + setIcon(off); + } + + public AltosLed(String on_path, String off_path) { + on = create_icon(on_path); + off = create_icon(off_path); + setIcon(off); + } +} diff --git a/altosuilib/AltosLights.java b/altosuilib/AltosLights.java new file mode 100644 index 00000000..c91b70e9 --- /dev/null +++ b/altosuilib/AltosLights.java @@ -0,0 +1,65 @@ +/* + * 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 org.altusmetrum.altosuilib_2; + +import java.awt.*; +import javax.swing.*; + +public class AltosLights extends JComponent { + + GridBagLayout gridbag; + + AltosLed red, green; + + ImageIcon create_icon(String path, String description) { + java.net.URL imgURL = AltosUILib.class.getResource(path); + if (imgURL != null) + return new ImageIcon(imgURL, description); + System.err.printf("Cannot find icon \"%s\"\n", path); + return null; + } + + public void set (boolean on) { + if (on) { + red.set(false); + green.set(true); + } else { + red.set(true); + green.set(false); + } + } + + public AltosLights() { + GridBagConstraints c; + gridbag = new GridBagLayout(); + setLayout(gridbag); + + c = new GridBagConstraints(); + red = new AltosLed("/redled.png", "/grayled.png"); + c.gridx = 0; c.gridy = 0; + c.insets = new Insets (0, 5, 0, 5); + gridbag.setConstraints(red, c); + add(red); + red.set(true); + green = new AltosLed("/greenled.png", "/grayled.png"); + c.gridx = 1; c.gridy = 0; + gridbag.setConstraints(green, c); + add(green); + green.set(false); + } +} diff --git a/altosuilib/Makefile.am b/altosuilib/Makefile.am index 4dc4c47f..f554fd74 100644 --- a/altosuilib/Makefile.am +++ b/altosuilib/Makefile.am @@ -50,6 +50,10 @@ altosuilib_JAVA = \ AltosEepromManage.java \ AltosEepromMonitorUI.java \ AltosEepromSelect.java \ + AltosCSVUI.java \ + AltosDataChooser.java \ + AltosLights.java \ + AltosLed.java \ AltosBTDevice.java \ AltosBTDeviceIterator.java \ AltosBTManage.java \ @@ -58,6 +62,18 @@ altosuilib_JAVA = \ JAR=altosuilib_$(ALTOSUILIB_VERSION).jar +# Icons +ICONDIR=$(top_srcdir)/icon + +ICONS= $(ICONDIR)/redled.png $(ICONDIR)/redoff.png \ + $(ICONDIR)/greenled.png $(ICONDIR)/greenoff.png \ + $(ICONDIR)/grayon.png $(ICONDIR)/grayled.png + +# icon base names for jar +ICONJAR= -C $(ICONDIR) redled.png -C $(ICONDIR) redoff.png \ + -C $(ICONDIR) greenled.png -C $(ICONDIR) greenoff.png \ + -C $(ICONDIR) grayon.png -C $(ICONDIR) grayled.png + all-local: $(JAR) clean-local: @@ -72,5 +88,5 @@ install-altosuilibJAVA: $(JAR) $(JAVAROOT): mkdir -p $(JAVAROOT) -$(JAR): classaltosuilib.stamp - jar cf $@ -C $(JAVAROOT) . +$(JAR): classaltosuilib.stamp $(ICONS) + jar cf $@ $(ICONJAR) -C $(JAVAROOT) . diff --git a/icon/telegps-128.png b/icon/telegps-128.png new file mode 100644 index 00000000..f1343d9e Binary files /dev/null and b/icon/telegps-128.png differ diff --git a/icon/telegps-16.png b/icon/telegps-16.png new file mode 100644 index 00000000..5bd45999 Binary files /dev/null and b/icon/telegps-16.png differ diff --git a/icon/telegps-256.png b/icon/telegps-256.png new file mode 100644 index 00000000..46e1670a Binary files /dev/null and b/icon/telegps-256.png differ diff --git a/icon/telegps-32.png b/icon/telegps-32.png new file mode 100644 index 00000000..c8588899 Binary files /dev/null and b/icon/telegps-32.png differ diff --git a/icon/telegps-48.png b/icon/telegps-48.png new file mode 100644 index 00000000..3bee98e6 Binary files /dev/null and b/icon/telegps-48.png differ diff --git a/icon/telegps-512.png b/icon/telegps-512.png new file mode 100644 index 00000000..47c47003 Binary files /dev/null and b/icon/telegps-512.png differ diff --git a/icon/telegps-64.png b/icon/telegps-64.png new file mode 100644 index 00000000..0ee086a6 Binary files /dev/null and b/icon/telegps-64.png differ diff --git a/icon/telegps.ico b/icon/telegps.ico new file mode 100644 index 00000000..bedf04ef Binary files /dev/null and b/icon/telegps.ico differ diff --git a/icon/telegps.svg b/icon/telegps.svg new file mode 100644 index 00000000..256b8c5a --- /dev/null +++ b/icon/telegps.svg @@ -0,0 +1,215 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/telegps/Makefile.am b/telegps/Makefile.am index 280b1e40..f8e2e63c 100644 --- a/telegps/Makefile.am +++ b/telegps/Makefile.am @@ -15,6 +15,7 @@ telegps_JAVA= \ TeleGPS.java \ TeleGPSStatus.java \ TeleGPSStatusUpdate.java \ + TeleGPSInfo.java \ TeleGPSConfig.java \ TeleGPSConfigUI.java \ TeleGPSPreferences.java diff --git a/telegps/TeleGPS.java b/telegps/TeleGPS.java index ad46fbdd..1bb505e0 100644 --- a/telegps/TeleGPS.java +++ b/telegps/TeleGPS.java @@ -53,6 +53,7 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo JTabbedPane pane; AltosSiteMap sitemap; + TeleGPSInfo gps_info; boolean has_map; JMenuBar menu_bar; @@ -115,10 +116,12 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo public void reset() { sitemap.reset(); + gps_info.reset(); } public void set_font() { sitemap.set_font(); + gps_info.set_font(); } public void font_size_changed(int font_size) { @@ -135,6 +138,7 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo state = new AltosState(); sitemap.show(state, listener_state); + gps_info.show(state, listener_state); telegps_status.show(state, listener_state); } @@ -225,6 +229,12 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo } void export() { + AltosDataChooser chooser; + chooser = new AltosDataChooser(this); + AltosStateIterable states = chooser.runDialog(); + if (states == null) + return; + new AltosCSVUI(this, states, chooser.file()); } void graph() { @@ -394,6 +404,9 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo sitemap = new AltosSiteMap(); pane.add("Site Map", sitemap); + gps_info = new TeleGPSInfo(); + pane.add("Info", gps_info); + setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); AltosUIPreferences.register_font_listener(this); diff --git a/telegps/TeleGPSInfo.java b/telegps/TeleGPSInfo.java new file mode 100644 index 00000000..0fba77d5 --- /dev/null +++ b/telegps/TeleGPSInfo.java @@ -0,0 +1,511 @@ +/* + * 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 org.altusmetrum.telegps; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; + +public class TeleGPSInfo extends JComponent implements AltosFlightDisplay { + GridBagLayout layout; + JLabel cur, max; + + public class Info { + JLabel label; + JTextField value; + AltosLights lights; + + void show() { + value.setVisible(true); + lights.setVisible(true); + label.setVisible(true); + } + + void hide() { + value.setVisible(false); + lights.setVisible(false); + label.setVisible(false); + } + + void show(AltosState state, AltosListenerState listener_state) {} + + void show(String s) { + show(); + value.setText(s); + } + + void show(AltosUnits units, double v) { + show(units.show(8, v)); + } + + void show(String format, double v) { + show(String.format(format, v)); + } + + void reset() { + lights.set(false); + value.setText(""); + } + + void set_font() { + label.setFont(AltosUILib.label_font); + value.setFont(AltosUILib.value_font); + } + + public Info (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(AltosUILib.label_font); + label.setHorizontalAlignment(SwingConstants.LEFT); + c.gridx = 1; c.gridy = y; + c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad); + c.anchor = GridBagConstraints.WEST; + c.fill = GridBagConstraints.VERTICAL; + c.weightx = 0; + layout.setConstraints(label, c); + add(label); + + value = new JTextField(AltosUILib.text_width); + value.setFont(AltosUILib.value_font); + value.setHorizontalAlignment(SwingConstants.RIGHT); + c.gridx = 2; c.gridy = y; + c.gridwidth = 2; + c.anchor = GridBagConstraints.WEST; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1; + layout.setConstraints(value, c); + add(value); + } + } + + public class Value { + JLabel label; + JTextField value; + void show(AltosState state, AltosListenerState listener_state) {} + + void reset() { + value.setText(""); + } + + void show() { + label.setVisible(true); + value.setVisible(true); + } + + void show(String s) { + show(); + value.setText(s); + } + + void show(AltosUnits units, double v) { + show(units.show(8, v)); + } + + void show(String format, double v) { + show(String.format(format, v)); + } + + void hide() { + label.setVisible(false); + value.setVisible(false); + } + void set_font() { + label.setFont(AltosUILib.label_font); + value.setFont(AltosUILib.value_font); + } + + public Value (GridBagLayout layout, int y, String text) { + GridBagConstraints c = new GridBagConstraints(); + c.weighty = 1; + + label = new JLabel(text); + label.setFont(AltosUILib.label_font); + label.setHorizontalAlignment(SwingConstants.LEFT); + c.gridx = 1; c.gridy = y; + c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad); + c.anchor = GridBagConstraints.WEST; + c.fill = GridBagConstraints.VERTICAL; + c.weightx = 0; + layout.setConstraints(label, c); + add(label); + + value = new JTextField(AltosUILib.text_width); + value.setFont(AltosUILib.value_font); + value.setHorizontalAlignment(SwingConstants.RIGHT); + c.gridx = 2; c.gridy = y; + c.anchor = GridBagConstraints.WEST; + c.fill = GridBagConstraints.BOTH; + c.gridwidth = 2; + c.weightx = 1; + layout.setConstraints(value, c); + add(value); + } + } + + public abstract class DualValue { + JLabel label; + JTextField value1; + JTextField value2; + + void reset() { + value1.setText(""); + value2.setText(""); + } + + void show() { + label.setVisible(true); + value1.setVisible(true); + value2.setVisible(true); + } + + void hide() { + label.setVisible(false); + value1.setVisible(false); + value2.setVisible(false); + } + + void set_font() { + label.setFont(AltosUILib.label_font); + value1.setFont(AltosUILib.value_font); + value2.setFont(AltosUILib.value_font); + } + + abstract void show(AltosState state, AltosListenerState listener_state); + + void show(String v1, String v2) { + show(); + value1.setText(v1); + value2.setText(v2); + } + void show(String f1, double v1, String f2, double v2) { + show(); + value1.setText(String.format(f1, v1)); + value2.setText(String.format(f2, v2)); + } + + public DualValue (GridBagLayout layout, int x, int y, String text) { + GridBagConstraints c = new GridBagConstraints(); + c.weighty = 1; + + label = new JLabel(text); + label.setFont(AltosUILib.label_font); + label.setHorizontalAlignment(SwingConstants.LEFT); + c.gridx = x + 1; c.gridy = y; + c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad); + c.anchor = GridBagConstraints.WEST; + c.fill = GridBagConstraints.VERTICAL; + c.weightx = 0; + layout.setConstraints(label, c); + add(label); + + value1 = new JTextField(AltosUILib.text_width); + value1.setFont(AltosUILib.value_font); + value1.setHorizontalAlignment(SwingConstants.RIGHT); + c.gridx = x + 2; c.gridy = y; + c.anchor = GridBagConstraints.WEST; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1; + layout.setConstraints(value1, c); + add(value1); + + value2 = new JTextField(AltosUILib.text_width); + value2.setFont(AltosUILib.value_font); + value2.setHorizontalAlignment(SwingConstants.RIGHT); + c.gridx = x + 3; c.gridy = y; + c.anchor = GridBagConstraints.WEST; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1; + c.gridwidth = 1; + layout.setConstraints(value2, c); + add(value2); + } + } + + public class ValueHold { + JLabel label; + JTextField value; + JTextField max_value; + double max; + + void show(AltosState state, AltosListenerState listener_state) {} + + void reset() { + value.setText(""); + max_value.setText(""); + max = AltosLib.MISSING; + } + + void set_font() { + label.setFont(AltosUILib.label_font); + value.setFont(AltosUILib.value_font); + max_value.setFont(AltosUILib.value_font); + } + + void show(AltosUnits units, double v) { + if (v == AltosLib.MISSING) { + value.setText("Missing"); + max_value.setText("Missing"); + } else { + value.setText(units.show(8, v)); + if (v > max || max == AltosLib.MISSING) { + max_value.setText(units.show(8, v)); + max = v; + } + } + } + + void hide() { + label.setVisible(false); + value.setVisible(false); + max_value.setVisible(false); + } + + public ValueHold (GridBagLayout layout, int y, String text) { + GridBagConstraints c = new GridBagConstraints(); + c.weighty = 1; + + label = new JLabel(text); + label.setFont(AltosUILib.label_font); + label.setHorizontalAlignment(SwingConstants.LEFT); + c.gridx = 1; c.gridy = y; + c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad); + c.anchor = GridBagConstraints.WEST; + c.fill = GridBagConstraints.VERTICAL; + c.weightx = 0; + layout.setConstraints(label, c); + add(label); + + value = new JTextField(AltosUILib.text_width); + value.setFont(AltosUILib.value_font); + value.setHorizontalAlignment(SwingConstants.RIGHT); + c.gridx = 2; c.gridy = y; + c.anchor = GridBagConstraints.EAST; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1; + layout.setConstraints(value, c); + add(value); + + max_value = new JTextField(AltosUILib.text_width); + max_value.setFont(AltosUILib.value_font); + max_value.setHorizontalAlignment(SwingConstants.RIGHT); + c.gridx = 3; c.gridy = y; + c.anchor = GridBagConstraints.EAST; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1; + layout.setConstraints(max_value, c); + add(max_value); + } + } + + + class Altitude extends ValueHold { + void show (AltosState state, AltosListenerState listener_state) { + show(AltosConvert.height, state.altitude()); + } + public Altitude (GridBagLayout layout, int y) { + super (layout, y, "Altitude"); + } + } + + Altitude altitude; + + class AscentRate extends ValueHold { + void show (AltosState state, AltosListenerState listener_state) { + show(AltosConvert.speed, state.gps_ascent_rate()); + } + public AscentRate (GridBagLayout layout, int y) { + super (layout, y, "Ascent Rate"); + } + } + + AscentRate ascent_rate; + + class GroundSpeed extends ValueHold { + void show (AltosState state, AltosListenerState listener_state) { + show(AltosConvert.speed, state.gps_ground_speed()); + } + public GroundSpeed (GridBagLayout layout, int y) { + super (layout, y, "Ground Speed"); + } + } + + GroundSpeed ground_speed; + + String pos(double p, String pos, String neg) { + String h = pos; + if (p < 0) { + h = neg; + p = -p; + } + int deg = (int) Math.floor(p); + double min = (p - Math.floor(p)) * 60.0; + return String.format("%s %4d° %9.6f", h, deg, min); + } + + class Course extends DualValue { + void show (AltosState state, AltosListenerState listener_state) { + double course = state.gps_course(); + if (course != AltosLib.MISSING) + show( String.format("%3.0f°", course), + AltosConvert.bearing_to_words( + AltosConvert.BEARING_LONG, + course)); + } + public Course (GridBagLayout layout, int y) { + super (layout, 0, y, "Course"); + } + } + + Course course; + + class Lat extends Value { + void show (AltosState state, AltosListenerState listener_state) { + if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING) + show(pos(state.gps.lat,"N", "S")); + else + show("???"); + } + public Lat (GridBagLayout layout, int y) { + super (layout, y, "Latitude"); + } + } + + Lat lat; + + class Lon extends Value { + void show (AltosState state, AltosListenerState listener_state) { + if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING) + show(pos(state.gps.lon,"E", "W")); + else + show("???"); + } + public Lon (GridBagLayout layout, int y) { + super (layout, y, "Longitude"); + } + } + + Lon lon; + + class GPSLocked extends Info { + void show (AltosState state, AltosListenerState listener_state) { + if (state == null || state.gps == null) + hide(); + else { + show("%4d sats", state.gps.nsat); + lights.set(state.gps.locked && state.gps.nsat >= 4); + } + } + public GPSLocked (GridBagLayout layout, int y) { + super (layout, y, "GPS Locked"); + } + } + + GPSLocked gps_locked; + + public void reset() { + lat.reset(); + lon.reset(); + altitude.reset(); + ground_speed.reset(); + ascent_rate.reset(); + course.reset(); + gps_locked.reset(); + } + + public void set_font() { + cur.setFont(AltosUILib.label_font); + max.setFont(AltosUILib.label_font); + lat.set_font(); + lon.set_font(); + altitude.set_font(); + ground_speed.set_font(); + ascent_rate.set_font(); + course.set_font(); + gps_locked.set_font(); + } + + public void show(AltosState state, AltosListenerState listener_state) { + if (state.gps != null && state.gps.connected) { + lat.show(state, listener_state); + lon.show(state, listener_state); + } else { + lat.hide(); + lon.hide(); + } + altitude.show(state, listener_state); + ground_speed.show(state, listener_state); + ascent_rate.show(state, listener_state); + course.show(state, listener_state); + gps_locked.show(state, listener_state); + } + + public void labels(GridBagLayout layout, int y) { + GridBagConstraints c; + + cur = new JLabel("Current"); + cur.setFont(AltosUILib.label_font); + c = new GridBagConstraints(); + c.gridx = 2; c.gridy = y; + c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad); + layout.setConstraints(cur, c); + add(cur); + + max = new JLabel("Maximum"); + max.setFont(AltosUILib.label_font); + c.gridx = 3; c.gridy = y; + layout.setConstraints(max, c); + add(max); + } + + public String getName() { + return "Info"; + } + + public TeleGPSInfo() { + layout = new GridBagLayout(); + + setLayout(layout); + + /* Elements in ascent display: + * + * lat + * lon + * height + */ + int y = 0; + labels(layout, y++); + altitude = new Altitude(layout, y++); + ground_speed = new GroundSpeed(layout, y++); + ascent_rate = new AscentRate(layout, y++); + course = new Course(layout, y++); + lat = new Lat(layout, y++); + lon = new Lon(layout, y++); + gps_locked = new GPSLocked(layout, y++); + } +}