From 2fa7785f9efdefaf0fc2fa8e0b03c85047613b84 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 28 May 2014 16:08:30 -0700 Subject: [PATCH] telegps: Add first version of telegps Not much implemented yet, but a shell of the UI and the map Signed-off-by: Keith Packard --- Makefile.am | 4 +- configure.ac | 3 + telegps/Info.plist.in | 50 +++ telegps/Makefile.am | 268 +++++++++++++++ telegps/TeleGPS.java | 543 +++++++++++++++++++++++++++++++ telegps/TeleGPSStatus.java | 164 ++++++++++ telegps/TeleGPSStatusUpdate.java | 41 +++ telegps/telegps-windows.nsi.in | 132 ++++++++ telegps/telegps.1 | 46 +++ telegps/telegps.desktop.in | 10 + 10 files changed, 1259 insertions(+), 2 deletions(-) create mode 100644 telegps/Info.plist.in create mode 100644 telegps/Makefile.am create mode 100644 telegps/TeleGPS.java create mode 100644 telegps/TeleGPSStatus.java create mode 100644 telegps/TeleGPSStatusUpdate.java create mode 100644 telegps/telegps-windows.nsi.in create mode 100644 telegps/telegps.1 create mode 100644 telegps/telegps.desktop.in diff --git a/Makefile.am b/Makefile.am index f035bb39..919dc2a9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS=ao-tools src doc icon altoslib libaltos altosuilib altosui micropeak ao-utils altosdroid +SUBDIRS=ao-tools src doc icon altoslib libaltos altosuilib altosui micropeak ao-utils altosdroid telegps EXTRA_DIST = ChangeLog @@ -22,4 +22,4 @@ fat: cd micropeak && $(MAKE) fat set-java-versions: - $(top_srcdir)/fix-java-versions org.altusmetrum.altoslib=$(ALTOSLIB_VERSION) org.altusmetrum.altosuilib=$(ALTOSUILIB_VERSION) \ No newline at end of file + $(top_srcdir)/fix-java-versions org.altusmetrum.altoslib=$(ALTOSLIB_VERSION) org.altusmetrum.altosuilib=$(ALTOSUILIB_VERSION) diff --git a/configure.ac b/configure.ac index dfbe59bc..4f7874bb 100644 --- a/configure.ac +++ b/configure.ac @@ -511,6 +511,9 @@ libaltos/Makefile micropeak/Makefile micropeak/Info.plist micropeak/micropeak-windows.nsi +telegps/Makefile +telegps/Info.plist +telegps/telegps-windows.nsi altosdroid/Makefile altosdroid/local.properties ao-tools/Makefile diff --git a/telegps/Info.plist.in b/telegps/Info.plist.in new file mode 100644 index 00000000..40984c5a --- /dev/null +++ b/telegps/Info.plist.in @@ -0,0 +1,50 @@ + + + + + CFBundleName + MicroPeak + CFBundleVersion + @VERSION@ + CFBundleAllowMixedLocalizations + true + CFBundleExecutable + JavaApplicationStub + CFBundleDevelopmentRegion + English + CFBundlePackageType + APPL + CFBundleIdentifier + org.altusmetrum.micropeak + CFBundleSignature + Altu + CFBundleGetInfoString + MicroPeak UI version @VERSION@ + CFBundleInfoDictionaryVersion + 6.0 + CFBundleIconFile + MicroPeak.icns + Java + + MainClass + org.altusmetrum.micropeak.MicroPeak + JVMVersion + 1.5+ + ClassPath + + $JAVAROOT/micropeak.jar + + Properties + + apple.laf.useScreenMenuBar + true + + VMOptions + + -Xms512M + -Xmx512M + -Dosgi.clean=true + + + + diff --git a/telegps/Makefile.am b/telegps/Makefile.am new file mode 100644 index 00000000..cd2de1f9 --- /dev/null +++ b/telegps/Makefile.am @@ -0,0 +1,268 @@ +JAVAROOT=classes +AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked -source 6 + +man_MANS=telegps.1 + +altoslibdir=$(libdir)/altos + +CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH=".:classes:../altoslib/*:../altosuilib/*:../libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" + +bin_SCRIPTS=telegps + +telegpsdir=$(datadir)/java + +telegps_JAVA= \ + TeleGPS.java \ + TeleGPSStatus.java \ + TeleGPSStatusUpdate.java + +JFREECHART_CLASS= \ + jfreechart.jar + +JCOMMON_CLASS=\ + jcommon.jar + +JAR=telegps.jar + +FATJAR=telegps-fat.jar + +LIBALTOS= \ + libaltos.so \ + libaltos.dylib \ + altos64.dll \ + altos.dll + +ALTOSLIB_CLASS=\ + altoslib_$(ALTOSLIB_VERSION).jar + +ALTOSUILIB_CLASS=\ + altosuilib_$(ALTOSUILIB_VERSION).jar + +# Icons +ICONDIR=$(top_srcdir)/icon + +JAVA_ICONS=\ + $(ICONDIR)/telegps-16.png \ + $(ICONDIR)/telegps-32.png \ + $(ICONDIR)/telegps-48.png \ + $(ICONDIR)/telegps-64.png \ + $(ICONDIR)/telegps-128.png \ + $(ICONDIR)/telegps-256.png + +# icon base names for jar +ICONJAR= -C $(ICONDIR) telegps-16.png \ + -C $(ICONDIR) telegps-32.png \ + -C $(ICONDIR) telegps-48.png \ + -C $(ICONDIR) telegps-64.png \ + -C $(ICONDIR) telegps-128.png \ + -C $(ICONDIR) telegps-256.png + +WINDOWS_ICON=$(ICONDIR)/telegps.ico + +desktopdir = $(datadir)/applications +desktop_file = telegps.desktop +desktop_SCRIPTS = $(desktop_file) + +all-local: telegps-test telegps-jdb $(JAR) + +clean-local: + -rm -rf classes $(JAR) $(FATJAR) \ + TeleGPS-Linux-*.tar.bz2 TeleGPS-Mac-*.dmg TeleGPS-Windows-*.exe \ + $(ALTOSLIB_CLASS) \ + $(ALTOSUILIB_CLASS) \ + $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(LIBALTOS) Manifest.txt Manifest-fat.txt \ + telegps telegps-test telegps-jdb macosx linux windows telegps-windows.log \ + telegps-windows.nsi + +EXTRA_DIST = $(desktop_file).in + +$(desktop_file): $(desktop_file).in + sed -e 's#%bindir%#@bindir@#' -e 's#%icondir%#$(datadir)/icons/hicolor/scalable/apps#' ${srcdir}/telegps.desktop.in > $@ + chmod +x $@ + +LINUX_DIST=TeleGPS-Linux-$(VERSION).tar.bz2 +LINUX_SH=TeleGPS-Linux-$(VERSION).sh +MACOSX_DIST=TeleGPS-Mac-$(VERSION).dmg +WINDOWS_DIST=TeleGPS-Windows-$(VERSION_DASH).exe + +MICROPEAK_DOC=$(top_srcdir)/doc/telegps.pdf + +DOC=$(MICROPEAK_DOC) + +FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS) + +LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) telegps.desktop.in ../icon/telegps.svg +LINUX_EXTRA=telegps-fat telegps.desktop.in + +MACOSX_DRIVER_URL=http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_2_18.dmg +MACOSX_DRIVER=FTDIUSBSerialDriver_v2_2_18.dmg +MACOSX_INFO_PLIST=Info.plist +MACOSX_README=ReadMe-Mac.rtf +MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(MACOSX_DRIVER) $(MACOSX_README) $(DOC) + +$(MACOSX_DRIVER): + wget $(MACOSX_DRIVER_URL) + +WINDOWS_DRIVER_URL=http://www.ftdichip.com/Drivers/CDM/CDM20824_Setup.exe +WINDOWS_DRIVER=CDM20824_Setup.exe + +$(WINDOWS_DRIVER): + wget $(WINDOWS_DRIVER_URL) + +WINDOWS_FILES=$(FAT_FILES) altos.dll altos64.dll $(DOC) $(WINDOWS_ICON) $(WINDOWS_DRIVER) + +if FATINSTALL + +FATTARGET=$(FATDIR)/$(VERSION) + +LINUX_DIST_TARGET=$(FATTARGET)/$(LINUX_DIST) +LINUX_SH_TARGET=$(FATTARGET)/$(LINUX_SH) +MACOSX_DIST_TARGET=$(FATTARGET)/$(MACOSX_DIST) +WINDOWS_DIST_TARGET=$(FATTARGET)/$(WINDOWS_DIST) + +fat: $(LINUX_DIST_TARGET) $(LINUX_SH_TARGET) $(MACOSX_DIST_TARGET) $(WINDOWS_DIST_TARGET) + +$(LINUX_DIST_TARGET): $(LINUX_DIST) + mkdir -p $(FATTARGET) + cp -p $< $@ + +$(LINUX_SH_TARGET): $(LINUX_SH) + mkdir -p $(FATTARGET) + cp -p $< $@ + +$(MACOSX_DIST_TARGET): $(MACOSX_DIST) + mkdir -p $(FATTARGET) + cp -p $< $@ + +$(WINDOWS_DIST_TARGET): $(WINDOWS_DIST) + mkdir -p $(FATTARGET) + cp -p $< $@ + +else +fat: $(LINUX_DIST) $(LINUX_SH) $(MACOSX_DIST) $(WINDOWS_DIST) +endif + +telegps: Makefile + echo "#!/bin/sh" > $@ + echo 'exec java -Djava.library.path="$(altoslibdir)" -jar "$(telegpsdir)/telegps.jar" "$$@"' >> $@ + chmod +x $@ + +telegps-jdb: Makefile + echo "#!/bin/sh" > $@ + echo 'exec jdb -classpath "classes:./*:../libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="../libaltos/.libs" org.altusmetrum.telegps.TeleGPS "$$@"' >> $@ + chmod +x $@ + +telegps-test: Makefile + echo "#!/bin/sh" > $@ + echo 'exec java -Djava.library.path="../libaltos/.libs" -jar telegps.jar "$$@"' >> $@ + chmod +x $@ + +install-telegpsJAVA: telegps.jar + @$(NORMAL_INSTALL) + test -z "$(telegpsdir)" || $(MKDIR_P) "$(DESTDIR)$(telegpsdir)" + echo " $(INSTALL_DATA)" "$<" "'$(DESTDIR)$(telegpsdir)/telegps.jar'"; \ + $(INSTALL_DATA) "$<" "$(DESTDIR)$(telegpsdir)" + +$(JAR): classtelegps.stamp Manifest.txt $(JAVA_ICONS) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) + jar cfm $@ Manifest.txt \ + $(ICONJAR) \ + -C classes org \ + -C ../libaltos libaltosJNI + +$(FATJAR): classtelegps.stamp Manifest-fat.txt $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(JAVA_ICONS) + jar cfm $@ Manifest-fat.txt \ + $(ICONJAR) \ + -C classes org \ + -C ../libaltos libaltosJNI + +classaltosui.stamp: $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) + +libaltos.so: build-libaltos + -rm -f "$@" + $(LN_S) ../libaltos/.libs/"$@" . + +libaltos.dylib: + -rm -f "$@" + $(LN_S) ../libaltos/"$@" . + +altos.dll: ../libaltos/altos.dll + -rm -f "$@" + $(LN_S) ../libaltos/"$@" . + +altos64.dll: ../libaltos/altos64.dll + -rm -f "$@" + $(LN_S) ../libaltos/"$@" . + +../libaltos/.libs/libaltos.so: build-libaltos + +../libaltos/altos.dll: build-altos-dll + +../libaltos/altos64.dll: build-altos64-dll + +build-libaltos: + +cd ../libaltos && make libaltos.la +build-altos-dll: + +cd ../libaltos && make altos.dll + +build-altos64-dll: + +cd ../libaltos && make altos64.dll + +$(ALTOSLIB_CLASS): + -rm -f "$@" + $(LN_S) ../altoslib/"$@" . + +$(ALTOSUILIB_CLASS): + -rm -f "$@" + $(LN_S) ../altosuilib/"$@" . + +$(JFREECHART_CLASS): + -rm -f "$@" + $(LN_S) "$(JFREECHART)"/"$@" . + +$(JCOMMON_CLASS): + -rm -f "$@" + $(LN_S) "$(JCOMMON)"/"$@" . + +$(LINUX_DIST): $(LINUX_FILES) $(LINUX_EXTRA) + -rm -f $@ + -rm -rf linux + mkdir -p linux/TeleGPS + cp -p $(LINUX_FILES) linux/TeleGPS + cp -p telegps-fat linux/TeleGPS/telegps + chmod +x linux/TeleGPS/telegps + tar cjf $@ -C linux TeleGPS + +$(LINUX_SH): $(LINUX_DIST) $(srcdir)/../altosui/linux-install.sh + sed 's/AltOS/TeleGPS/g' $(srcdir)/../altosui/linux-install.sh | cat - $(LINUX_DIST) > $@ + chmod +x $@ + +$(MACOSX_DIST): $(MACOSX_FILES) + -rm -f $@ + -rm -rf macosx + mkdir macosx + cp -a TeleGPS.app macosx/ + cp -a $(MACOSX_README) macosx/ReadMe.rtf + cp -a $(DOC) macosx + cp -p Info.plist macosx/TeleGPS.app/Contents + cp -p $(MACOSX_DRIVER) macosx + mkdir -p macosx/TeleGPS.app/Contents/Resources/Java + cp -p $(FATJAR) macosx/TeleGPS.app/Contents/Resources/Java/telegps.jar + cp -p libaltos.dylib macosx/TeleGPS.app/Contents/Resources/Java + cp -p $(ALTOSLIB_CLASS) macosx/TeleGPS.app/Contents/Resources/Java + cp -p $(ALTOSUILIB_CLASS) macosx/TeleGPS.app/Contents/Resources/Java + cp -p $(JFREECHART_CLASS) macosx/TeleGPS.app/Contents/Resources/Java + cp -p $(JCOMMON_CLASS) macosx/TeleGPS.app/Contents/Resources/Java + genisoimage -D -V TeleGPS-$(VERSION) -no-pad -r -apple -o $@ macosx + +$(WINDOWS_DIST): $(WINDOWS_FILES) telegps-windows.nsi + -rm -f $@ + makensis -Otelegps-windows.log "-XOutFile $@" "-DVERSION=$(VERSION)" telegps-windows.nsi + +Manifest.txt: Makefile + echo 'Main-Class: org.altusmetrum.telegps.TeleGPS' > $@ + echo "Class-Path: $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS)/freetts.jar $(JCOMMON)/jcommon.jar $(JFREECHART)/jfreechart.jar" >> $@ + +Manifest-fat.txt: + echo 'Main-Class: org.altusmetrum.telegps.TeleGPS' > $@ + echo "Class-Path: $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) freetts.jar jcommon.jar jfreechart.jar" >> $@ + diff --git a/telegps/TeleGPS.java b/telegps/TeleGPS.java new file mode 100644 index 00000000..45482dec --- /dev/null +++ b/telegps/TeleGPS.java @@ -0,0 +1,543 @@ +/* + * Copyright © 2014 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 java.awt.event.*; +import javax.swing.*; +import java.io.*; +import java.util.concurrent.*; +import java.util.*; +import org.altusmetrum.altoslib_4.*; +import org.altusmetrum.altosuilib_2.*; + +public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFontListener, ActionListener { + + static String[] telegps_icon_names = { + "/telegps-16.png", + "/telegps-32.png", + "/telegps-48.png", + "/telegps-64.png", + "/telegps-128.png", + "/telegps-256.png" + }; + + static { set_icon_names(telegps_icon_names); } + + static AltosVoice voice; + + static AltosVoice voice() { + if (voice == null) + voice = new AltosVoice(); + return voice; + } + + AltosFlightReader reader; + AltosDisplayThread thread; + + JTabbedPane pane; + + AltosSiteMap sitemap; + boolean has_map; + + JMenuBar menu_bar; + JMenu file_menu; + JMenu monitor_menu; + JMenu device_menu; + + /* File menu */ + final static String new_command = "new"; + final static String preferences_command = "preferences"; + final static String load_maps_command = "loadmaps"; + final static String close_command = "close"; + final static String exit_command = "exit"; + + static final String[][] file_menu_entries = new String[][] { + { "New Window", new_command }, + { "Preferences", preferences_command }, + { "Load Maps", load_maps_command }, + { "Close", close_command }, + { "Exit", exit_command }, + }; + + /* Monitor menu */ + final static String monitor_command = "monitor"; + final static String disconnect_command = "disconnect"; + final static String scan_command = "scan"; + + static final String[][] monitor_menu_entries = new String[][] { + { "Monitor Device", monitor_command }, + { "Disconnect", disconnect_command }, + { "Scan Channels", scan_command }, + }; + + /* Device menu */ + final static String download_command = "download"; + final static String configure_command = "configure"; + final static String export_command = "export"; + final static String graph_command = "graph"; + + static final String[][] device_menu_entries = new String[][] { + { "Download Data", download_command }, + { "Configure Device", configure_command }, + { "Export Data", export_command }, + { "Graph Data", graph_command }, + }; + +// private AltosInfoTable flightInfo; + + boolean exit_on_close = false; + + void stop_display() { + if (thread != null && thread.isAlive()) { + thread.interrupt(); + try { + thread.join(); + } catch (InterruptedException ie) {} + } + thread = null; + } + + public void reset() { + sitemap.reset(); + } + + public void set_font() { + sitemap.set_font(); + } + + public void font_size_changed(int font_size) { + set_font(); + } + + +// AltosFlightStatusUpdate status_update; + + public void show(AltosState state, AltosListenerState listener_state) { +// status_update.saved_state = state; + + if (state == null) + state = new AltosState(); + + sitemap.show(state, listener_state); + telegps_status.show(state, listener_state); + } + + Container bag; + AltosFreqList frequencies; + JLabel telemetry; + TeleGPSStatus telegps_status; + TeleGPSStatusUpdate status_update; + + ActionListener show_timer; + + void new_window() { + new TeleGPS(); + } + + void preferences() { + } + + void load_maps() { + new AltosSiteMapPreload(this); + } + + void monitor() { + AltosDevice device = AltosDeviceUIDialog.show(this, + AltosLib.product_basestation); + if (device == null) + return; + if (reader != null) + disconnect(); + try { + AltosFlightReader reader = new AltosTelemetryReader(new AltosSerial(device)); + set_reader(reader); + add_frequency_menu(device.getSerial(), reader); + } catch (FileNotFoundException ee) { + JOptionPane.showMessageDialog(this, + ee.getMessage(), + String.format ("Cannot open %s", device.toShortString()), + JOptionPane.ERROR_MESSAGE); + } catch (AltosSerialInUseException si) { + JOptionPane.showMessageDialog(this, + String.format("Device \"%s\" already in use", + device.toShortString()), + "Device in use", + JOptionPane.ERROR_MESSAGE); + } catch (IOException ee) { + JOptionPane.showMessageDialog(this, + String.format ("Unknown I/O error on %s", device.toShortString()), + "Unknown I/O error", + JOptionPane.ERROR_MESSAGE); + } catch (TimeoutException te) { + JOptionPane.showMessageDialog(this, + String.format ("Timeout on %s", device.toShortString()), + "Timeout error", + JOptionPane.ERROR_MESSAGE); + } catch (InterruptedException ie) { + JOptionPane.showMessageDialog(this, + String.format("Interrupted %s", device.toShortString()), + "Interrupted exception", + JOptionPane.ERROR_MESSAGE); + } + } + + void disconnect() { + setTitle("TeleGPS"); + stop_display(); + remove_frequency_menu(); + } + + void scan() { + } + + void download(){ + } + + void configure() { + } + + void export() { + } + + void graph() { + } + + public void actionPerformed(ActionEvent ev) { + + /* File menu */ + if (new_command.equals(ev.getActionCommand())) { + new_window(); + return; + } + if (preferences_command.equals(ev.getActionCommand())) { + preferences(); + return; + } + if (load_maps_command.equals(ev.getActionCommand())) { + load_maps(); + return; + } + if (close_command.equals(ev.getActionCommand())) { + close(); + return; + } + if (exit_command.equals(ev.getActionCommand())) + System.exit(0); + + /* Monitor menu */ + if (monitor_command.equals(ev.getActionCommand())) { + monitor(); + return; + } + if (disconnect_command.equals(ev.getActionCommand())) { + disconnect(); + return; + } + if (scan_command.equals(ev.getActionCommand())) { + scan(); + return; + } + + /* Device menu */ + if (download_command.equals(ev.getActionCommand())) { + download(); + return; + } + if (configure_command.equals(ev.getActionCommand())) { + configure(); + return; + } + if (export_command.equals(ev.getActionCommand())) { + export(); + return; + } + if (graph_command.equals(ev.getActionCommand())) { + graph(); + return; + } + } + + void add_frequency_menu(int serial, final AltosFlightReader reader) { + // Channel menu + frequencies = new AltosFreqList(AltosUIPreferences.frequency(serial)); + frequencies.set_product("Monitor"); + frequencies.set_serial(serial); + frequencies.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + double frequency = frequencies.frequency(); + try { + reader.set_frequency(frequency); + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + reader.save_frequency(); + } + }); + menu_bar.add(frequencies); + } + + void remove_frequency_menu() { + if (frequencies != null) { + menu_bar.remove(frequencies); + frequencies = null; + } + } + + public void set_reader(AltosFlightReader reader) { + setTitle(String.format("TeleGPS %s", reader.name)); + thread = new AltosDisplayThread(this, voice(), this, reader); + thread.start(); + } + + static int number_of_windows; + + private void close() { + AltosUIPreferences.unregister_font_listener(this); + setVisible(false); + dispose(); + --number_of_windows; + if (number_of_windows == 0) + System.exit(0); + } + + private void add_menu(JMenu menu, String label, String action) { + JMenuItem item = new JMenuItem(label); + menu.add(item); + item.addActionListener(this); + item.setActionCommand(action); + } + + + private JMenu make_menu(String label, String[][] items) { + JMenu menu = new JMenu(label); + for (int i = 0; i < items.length; i++) + add_menu(menu, items[i][0], items[i][1]); + menu_bar.add(menu); + return menu; + } + + public TeleGPS() { + + AltosUIPreferences.set_component(this); + + reader = null; + + bag = getContentPane(); + bag.setLayout(new GridBagLayout()); + + GridBagConstraints c = new GridBagConstraints(); + + setTitle("TeleGPS"); + + menu_bar = new JMenuBar(); + setJMenuBar(menu_bar); + + file_menu = make_menu("File", file_menu_entries); + monitor_menu = make_menu("Monitor", monitor_menu_entries); + device_menu = make_menu("Device", device_menu_entries); + + int serial = -1; + + /* TeleGPS status is always visible */ + telegps_status = new TeleGPSStatus(); + c.gridx = 0; + c.gridy = 1; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.gridwidth = 2; + bag.add(telegps_status, c); + c.gridwidth = 1; + + + /* The rest of the window uses a tabbed pane to + * show one of the alternate data views + */ + pane = new JTabbedPane(); + + /* Make the tabbed pane use the rest of the window space */ + c.gridx = 0; + c.gridy = 2; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1; + c.weighty = 1; + c.gridwidth = 2; + bag.add(pane, c); + + sitemap = new AltosSiteMap(); + pane.add("Site Map", sitemap); + + setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + + AltosUIPreferences.register_font_listener(this); + + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + close(); + } + }); + + pack(); + setVisible(true); + + ++number_of_windows; + + status_update = new TeleGPSStatusUpdate(telegps_status); + + new javax.swing.Timer(100, status_update).start(); + } + + public TeleGPS(AltosFlightReader reader) { + this(); + set_reader(reader); + } + + static AltosStateIterable record_iterable(File file) { + FileInputStream in; + try { + in = new FileInputStream(file); + } catch (Exception e) { + System.out.printf("Failed to open file '%s'\n", file); + return null; + } + if (file.getName().endsWith("telem")) + return new AltosTelemetryFile(in); + else + return new AltosEepromFile(in); + } + + static AltosReplayReader replay_file(File file) { + AltosStateIterable states = record_iterable(file); + if (states == null) + return null; + return new AltosReplayReader(states.iterator(), file); + } + + static boolean process_replay(File file) { + AltosReplayReader new_reader = replay_file(file); + if (new_reader == null) + return false; + + new TeleGPS(new_reader); + return true; + } + + static final int process_none = 0; + static final int process_csv = 1; + static final int process_kml = 2; + static final int process_graph = 3; + static final int process_replay = 4; + static final int process_summary = 5; + static final int process_cat = 6; + + public static boolean load_library(Frame frame) { + if (!AltosUILib.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 static void help(int code) { + System.out.printf("Usage: altosui [OPTION]... [FILE]...\n"); + System.out.printf(" Options:\n"); + System.out.printf(" --fetchmaps \tpre-fetch maps for site map view\n"); + System.out.printf(" --replay \t\trelive the glory of past flights \n"); + System.out.printf(" --graph \t\tgraph a flight\n"); + System.out.printf(" --csv\tgenerate comma separated output for spreadsheets, etc\n"); + System.out.printf(" --kml\tgenerate KML output for use with Google Earth\n"); + System.exit(code); + } + + public static void main(String[] args) { + int errors = 0; + + load_library(null); + try { + UIManager.setLookAndFeel(AltosUIPreferences.look_and_feel()); + } catch (Exception e) { + } + + boolean any_created = false; + + + /* Handle batch-mode */ + int process = process_none; + for (int i = 0; i < args.length; i++) { + if (args[i].equals("--help")) + help(0); + else if (args[i].equals("--fetchmaps")) { + if (args.length < i + 3) { + help(1); + } else { + double lat = Double.parseDouble(args[i+1]); + double lon = Double.parseDouble(args[i+2]); + AltosSiteMap.prefetchMaps(lat, lon); + i += 2; + } + } else if (args[i].equals("--replay")) + process = process_replay; + else if (args[i].equals("--kml")) + process = process_kml; + else if (args[i].equals("--csv")) + process = process_csv; + else if (args[i].equals("--graph")) + process = process_graph; + else if (args[i].equals("--summary")) + process = process_summary; + else if (args[i].equals("--cat")) + process = process_cat; + else if (args[i].startsWith("--")) + help(1); + else { + File file = new File(args[i]); + switch (process) { + case process_graph: + ++errors; + break; + case process_none: + case process_replay: + if (!process_replay(file)) + ++errors; + any_created = true; + break; + case process_kml: + ++errors; + break; + case process_csv: + ++errors; + break; + case process_summary: + ++errors; + break; + case process_cat: + ++errors; + } + } + } + if (errors != 0) + System.exit(errors); + if (!any_created) + new TeleGPS(); + } +} diff --git a/telegps/TeleGPSStatus.java b/telegps/TeleGPSStatus.java new file mode 100644 index 00000000..fd66b279 --- /dev/null +++ b/telegps/TeleGPSStatus.java @@ -0,0 +1,164 @@ +/* + * 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 TeleGPSStatus extends JComponent implements AltosFlightDisplay { + GridBagLayout layout; + + public class FlightValue { + JLabel label; + JTextField value; + + void show(AltosState state, AltosListenerState listener_state) {} + + void reset() { + value.setText(""); + } + + void set_font() { + label.setFont(AltosUILib.status_font); + value.setFont(AltosUILib.status_font); + } + + void setVisible(boolean visible) { + label.setVisible(visible); + value.setVisible(visible); + } + + public FlightValue (GridBagLayout layout, int x, String text) { + GridBagConstraints c = new GridBagConstraints(); + c.insets = new Insets(5, 5, 5, 5); + c.anchor = GridBagConstraints.CENTER; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1; + c.weighty = 1; + + label = new JLabel(text); + label.setFont(AltosUILib.status_font); + label.setHorizontalAlignment(SwingConstants.CENTER); + c.gridx = x; c.gridy = 0; + layout.setConstraints(label, c); + add(label); + + value = new JTextField(""); + value.setFont(AltosUILib.status_font); + value.setHorizontalAlignment(SwingConstants.CENTER); + c.gridx = x; c.gridy = 1; + layout.setConstraints(value, c); + add(value); + } + } + + class Call extends FlightValue { + void show(AltosState state, AltosListenerState listener_state) { + value.setText(state.callsign); + if (state.callsign == null) + setVisible(false); + else + setVisible(true); + } + public Call (GridBagLayout layout, int x) { + super (layout, x, "Callsign"); + } + } + + Call call; + + class Serial extends FlightValue { + void show(AltosState state, AltosListenerState listener_state) { + if (state.serial == AltosLib.MISSING) + value.setText("none"); + else + value.setText(String.format("%d", state.serial)); + } + public Serial (GridBagLayout layout, int x) { + super (layout, x, "Serial"); + } + } + + Serial serial; + + class RSSI extends FlightValue { + void show(AltosState state, AltosListenerState listener_state) { + value.setText(String.format("%d", state.rssi())); + if (state.rssi == AltosLib.MISSING) + setVisible(false); + else + setVisible(true); + } + public RSSI (GridBagLayout layout, int x) { + super (layout, x, "RSSI"); + } + } + + RSSI rssi; + + class LastPacket extends FlightValue { + void show(AltosState state, AltosListenerState listener_state) { + long secs = (System.currentTimeMillis() - state.received_time + 500) / 1000; + value.setText(String.format("%d", secs)); + } + public LastPacket(GridBagLayout layout, int x) { + super (layout, x, "Age"); + } + } + + LastPacket last_packet; + + public void reset () { + call.reset(); + serial.reset(); + rssi.reset(); + last_packet.reset(); + } + + public void set_font () { + call.set_font(); + serial.set_font(); + rssi.set_font(); + last_packet.set_font(); + } + + public void show (AltosState state, AltosListenerState listener_state) { + call.show(state, listener_state); + serial.show(state, listener_state); + rssi.show(state, listener_state); + last_packet.show(state, listener_state); + } + + public int height() { + Dimension d = layout.preferredLayoutSize(this); + return d.height; + } + + public TeleGPSStatus() { + layout = new GridBagLayout(); + + setLayout(layout); + + call = new Call(layout, 0); + serial = new Serial(layout, 1); + rssi = new RSSI(layout, 4); + last_packet = new LastPacket(layout, 5); + } +} diff --git a/telegps/TeleGPSStatusUpdate.java b/telegps/TeleGPSStatusUpdate.java new file mode 100644 index 00000000..e7684d88 --- /dev/null +++ b/telegps/TeleGPSStatusUpdate.java @@ -0,0 +1,41 @@ +/* + * Copyright © 2012 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.event.*; +import org.altusmetrum.altoslib_4.*; + +public class TeleGPSStatusUpdate implements ActionListener { + + public AltosState saved_state; + public AltosListenerState saved_listener_state; + TeleGPSStatus status; + + public void actionPerformed (ActionEvent e) { + if (saved_state != null) { + if (saved_listener_state == null) + saved_listener_state = new AltosListenerState(); + status.show(saved_state, saved_listener_state); + } + } + + public TeleGPSStatusUpdate (TeleGPSStatus in_status) { + status = in_status; + } +} + diff --git a/telegps/telegps-windows.nsi.in b/telegps/telegps-windows.nsi.in new file mode 100644 index 00000000..656f8af3 --- /dev/null +++ b/telegps/telegps-windows.nsi.in @@ -0,0 +1,132 @@ +!addplugindir Instdrv/NSIS/Plugins +; Definitions for Java 1.6 Detection +!define JRE_VERSION "1.6" +!define JRE_ALTERNATE "1.7" +!define JRE_URL "http://javadl.sun.com/webapps/download/AutoDL?BundleId=52247&/jre-6u27-windows-i586-p.exe" +!define PRODUCT_NAME "Altus Metrum Windows Software" + +Name "Altus Metrum MicroPeak Installer" + +; Default install directory +InstallDir "$PROGRAMFILES\AltusMetrum" + +; Tell the installer where to re-install a new version +InstallDirRegKey HKLM "Software\AltusMetrum" "Install_Dir" + +LicenseText "GNU General Public License Version 2" +LicenseData "../COPYING" + +; Need admin privs for Vista or Win7 +RequestExecutionLevel admin + +ShowInstDetails Show + +ComponentText "Altus Metrum MicroPeak Software Installer" + +Function GetJRE + MessageBox MB_OK "${PRODUCT_NAME} uses Java ${JRE_VERSION} 32-bit, it will now \ + be downloaded and installed" + + StrCpy $2 "$TEMP\Java Runtime Environment.exe" + nsisdl::download /TIMEOUT=30000 ${JRE_URL} $2 + Pop $R0 ;Get the return value + StrCmp $R0 "success" +3 + MessageBox MB_OK "Download failed: $R0" + Quit + ExecWait $2 + Delete $2 +FunctionEnd + + +Function DetectJRE + ReadRegStr $2 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment" \ + "CurrentVersion" + StrCmp $2 ${JRE_VERSION} done + + StrCmp $2 ${JRE_ALTERNATE} done + + Call GetJRE + + done: +FunctionEnd + +; Pages to present + +Page license +Page components +Page directory +Page instfiles + +UninstPage uninstConfirm +UninstPage instfiles + +; And the stuff to install + +Section "MicroPeak Application" + Call DetectJRE + + SetOutPath $INSTDIR + + File "micropeak-fat.jar" + File "altoslib_@ALTOSLIB_VERSION@.jar" + File "altosuilib_@ALTOSUILIB_VERSION@.jar" + File "jfreechart.jar" + File "jcommon.jar" + + File "*.dll" + + File "../icon/*.ico" + + CreateShortCut "$SMPROGRAMS\MicroPeak.lnk" "$SYSDIR\javaw.exe" "-jar micropeak-fat.jar" "$INSTDIR\micro-peak.ico" +SectionEnd + +Section "FTDI USB Driver" + SetOutPath $INSTDIR + + File "CDM20824_Setup.exe" + + StrCpy $2 "$INSTDIR\CDM20824_Setup.exe" + ExecWait $2 +SectionEnd + +Section "MicroPeak Desktop Shortcut" + CreateShortCut "$DESKTOP\MicroPeak.lnk" "$INSTDIR\micropeak-fat.jar" "" "$INSTDIR\micro-peak.ico" +SectionEnd + +Section "Documentation" + + SetOutPath $INSTDIR + + File "../doc/micropeak.pdf" +SectionEnd + +Section "Uninstaller" + + ; Deal with the uninstaller + + SetOutPath $INSTDIR + + ; Write the install path to the registry + WriteRegStr HKLM SOFTWARE\AltusMetrum "Install_Dir" "$INSTDIR" + + ; Write the uninstall keys for windows + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "DisplayName" "Altus Metrum" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "UninstallString" '"$INSTDIR\uninstall.exe"' + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoModify" "1" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoRepair" "1" + + WriteUninstaller "uninstall.exe" +SectionEnd + +Section "Uninstall" + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" + DeleteRegKey HKLM "Software\AltusMetrum" + + Delete "$INSTDIR\*.*" + RMDir "$INSTDIR" + + ; Remove shortcuts, if any + Delete "$SMPROGRAMS\MicroPeak.lnk" + Delete "$DESKTOP\MicroPeak.lnk" + +SectionEnd diff --git a/telegps/telegps.1 b/telegps/telegps.1 new file mode 100644 index 00000000..57fa4489 --- /dev/null +++ b/telegps/telegps.1 @@ -0,0 +1,46 @@ +.\" +.\" Copyright © 2010 Bdale Garbee +.\" +.\" 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; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" 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. +.\" +.\" +.TH ALTOSUI 1 "altosui" "" +.SH NAME +altosui \- Rocket flight monitor +.SH SYNOPSIS +.B "altosui" +.SH DESCRIPTION +.I altosui +connects to a TeleDongle or TeleMetrum device through a USB serial device. +It provides a menu-oriented +user interface to monitor, record and review rocket flight data. +.SH USAGE +When connected to a TeleDongle device, altosui turns on the radio +receiver and listens for telemetry packets. It displays the received +telemetry data, and reports flight status via voice synthesis. All +received telemetry information is recorded to a file. +.P +When connected to a TeleMetrum device, altosui can be used to configure the +TeleMetrum, and to downloads the eeprom data and store it in a file. +.P +A number of other menu options exist, including the ability to export flight +data in different formats. +.SH FILES +All data log files are recorded into a user-specified directory +(default ~/TeleMetrum). Files are named using the current date, the serial +number of the reporting device, the flight number recorded in the data +and either '.telem' for telemetry data or '.eeprom' for eeprom data. +.SH AUTHOR +Keith Packard diff --git a/telegps/telegps.desktop.in b/telegps/telegps.desktop.in new file mode 100644 index 00000000..abdf286f --- /dev/null +++ b/telegps/telegps.desktop.in @@ -0,0 +1,10 @@ +[Desktop Entry] +Type=Application +Name=MicroPeak +GenericName=MicroPeak download and analysis +Comment=View and log data from MicroPeak altimeters +Icon=%icondir%/micropeak.svg +Exec=%bindir%/micropeak %f +Terminal=false +MimeType=text/plain; +Categories=Education;Electronics;Science; -- 2.30.2