diff options
author | Keith Packard <keithp@keithp.com> | 2013-01-10 21:48:12 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2013-01-10 21:48:12 -0800 |
commit | 1ed6b13e87c1cc2d6618b6ba3a293ea6e3b5752e (patch) | |
tree | 10adf6f3c6b6c1ed2bf7540a9972fe72253cfa81 /micropeak | |
parent | acff2f466031fd1a8533fc315411c3734a8bacc6 (diff) | |
parent | d409417ff8e9ed9d406bf1c04542a4ecb574768b (diff) |
Merge remote-tracking branch 'origin/micropeak-logging'
Diffstat (limited to 'micropeak')
26 files changed, 2358 insertions, 0 deletions
diff --git a/micropeak/.gitignore b/micropeak/.gitignore new file mode 100644 index 00000000..fc99b31c --- /dev/null +++ b/micropeak/.gitignore @@ -0,0 +1,6 @@ +*.jar +Manifest.txt +classes +*.stamp +micropeak +micropeak-test diff --git a/micropeak/FTDI.tar.gz b/micropeak/FTDI.tar.gz Binary files differnew file mode 100644 index 00000000..cd08ecf2 --- /dev/null +++ b/micropeak/FTDI.tar.gz diff --git a/micropeak/Info.plist.in b/micropeak/Info.plist.in new file mode 100644 index 00000000..40984c5a --- /dev/null +++ b/micropeak/Info.plist.in @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"> +<plist version="0.9"> +<dict> + <key>CFBundleName</key> + <string>MicroPeak</string> + <key>CFBundleVersion</key> + <string>@VERSION@</string> + <key>CFBundleAllowMixedLocalizations</key> + <string>true</string> + <key>CFBundleExecutable</key> + <string>JavaApplicationStub</string> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleIdentifier</key> + <string>org.altusmetrum.micropeak</string> + <key>CFBundleSignature</key> + <string>Altu</string> + <key>CFBundleGetInfoString</key> + <string>MicroPeak UI version @VERSION@</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleIconFile</key> + <string>MicroPeak.icns</string> + <key>Java</key> + <dict> + <key>MainClass</key> + <string>org.altusmetrum.micropeak.MicroPeak</string> + <key>JVMVersion</key> + <string>1.5+</string> + <key>ClassPath</key> + <array> + <string>$JAVAROOT/micropeak.jar</string> + </array> + <key>Properties</key> + <dict> + <key>apple.laf.useScreenMenuBar</key> + <string>true</string> + </dict> + <key>VMOptions</key> + <array> + <string>-Xms512M</string> + <string>-Xmx512M</string> + <string>-Dosgi.clean=true</string> + </array> + </dict> +</dict> +</plist> diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am new file mode 100644 index 00000000..b80cabf2 --- /dev/null +++ b/micropeak/Makefile.am @@ -0,0 +1,239 @@ +JAVAROOT=classes +AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation + +CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH=".:classes:../altoslib/*:../altosuilib/*:../libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" + +bin_SCRIPTS=micropeak + +micropeakdir=$(datadir)/java + +micropeak_JAVA= \ + MicroPeak.java \ + MicroData.java \ + MicroDataPoint.java \ + MicroDownload.java \ + MicroExport.java \ + MicroFile.java \ + MicroFrame.java \ + MicroGraph.java \ + MicroRaw.java \ + MicroSave.java \ + MicroSerial.java \ + MicroStats.java \ + MicroStatsTable.java \ + MicroFileChooser.java \ + MicroDeviceDialog.java \ + MicroUSB.java + +JFREECHART_CLASS= \ + jfreechart.jar + +JCOMMON_CLASS=\ + jcommon.jar + +JAR=micropeak.jar + +FATJAR=micropeak-fat.jar + +LIBALTOS= \ + libaltos.so \ + libaltos.dylib \ + altos64.dll \ + altos.dll + +ALTOSLIB_CLASS=\ + AltosLib.jar + +ALTOSUILIB_CLASS=\ + altosuilib.jar + +# Icons +ICONDIR=$(top_srcdir)/icon + +JAVA_ICONS=\ + $(ICONDIR)/micropeak-16.png \ + $(ICONDIR)/micropeak-32.png \ + $(ICONDIR)/micropeak-48.png \ + $(ICONDIR)/micropeak-64.png \ + $(ICONDIR)/micropeak-128.png \ + $(ICONDIR)/micropeak-256.png + +# icon base names for jar +ICONJAR= -C $(ICONDIR) micropeak-16.png \ + -C $(ICONDIR) micropeak-32.png \ + -C $(ICONDIR) micropeak-48.png \ + -C $(ICONDIR) micropeak-64.png \ + -C $(ICONDIR) micropeak-128.png \ + -C $(ICONDIR) micropeak-256.png + +WINDOWS_ICON=$(ICONDIR)/micro-peak.ico + +all-local: micropeak-test micropeak-jdb $(JAR) + +clean-local: + -rm -rf classes $(JAR) $(FATJAR) \ + $(LINUX_DIST) $(MACOSX_DIST) windows $(WINDOWS_DIST) \ + $(ALTOSLIB_CLASS) \ + $(ALTOSUILIB_CLASS) \ + $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(LIBALTOS) Manifest.txt \ + micropeak micropeak-test macosx linux windows + +LINUX_DIST=MicroPeak-Linux-$(VERSION).tar.bz2 +MACOSX_DIST=MicroPeak-Mac-$(VERSION).dmg +WINDOWS_DIST=MicroPeak-Windows-$(VERSION_DASH).exe + +FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS) + +LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) +LINUX_EXTRA=micropeak-fat + +MACOSX_INFO_PLIST=Info.plist +MACOSX_DRIVER=FTDI.tar.gz +MACOSX_README=ReadMe-Mac.rtf +MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(MACOSX_DRIVER) $(MACOSX_README) + +WINDOWS_FILES=$(FAT_FILES) altos.dll altos64.dll $(top_srcdir)/telemetrum.inf $(WINDOWS_ICON) + +if FATINSTALL + +FATTARGET=$(FATDIR)/$(VERSION) + +LINUX_DIST_TARGET=$(FATTARGET)/$(LINUX_DIST) +MACOSX_DIST_TARGET=$(FATTARGET)/$(MACOSX_DIST) +WINDOWS_DIST_TARGET=$(FATTARGET)/$(WINDOWS_DIST) + +fat: $(LINUX_DIST_TARGET) $(MACOSX_DIST_TARGET) $(WINDOWS_DIST_TARGET) + +$(LINUX_DIST_TARGET): $(LINUX_DIST) + 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) $(MACOSX_DIST) $(WINDOWS_DIST) +endif + +micropeak: Makefile + echo "#!/bin/sh" > $@ + echo 'exec java -cp "$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="$(altoslibdir)" -jar "$(micropeakdir)/micropeak.jar" "$$@"' >> $@ + chmod +x $@ + +micropeak-jdb: Makefile + echo "#!/bin/sh" > $@ + echo 'exec jdb -classpath "classes:./*:../libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="../libaltos/.libs" org.altusmetrum.micropeak.MicroPeak "$$@"' >> $@ + chmod +x $@ + +micropeak-test: Makefile + echo "#!/bin/sh" > $@ + echo 'exec java -cp "./*:../libaltos/*:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="../libaltos/.libs" -jar micropeak.jar "$$@"' >> $@ + chmod +x $@ + +install-micropeakJAVA: micropeak.jar + @$(NORMAL_INSTALL) + test -z "$(micropeakdir)" || $(MKDIR_P) "$(DESTDIR)$(micropeakdir)" + echo " $(INSTALL_DATA)" "$<" "'$(DESTDIR)$(micropeakdir)/micropeak.jar'"; \ + $(INSTALL_DATA) "$<" "$(DESTDIR)$(micropeakdir)" + +$(JAR): classmicropeak.stamp Manifest.txt $(JAVA_ICONS) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) + jar cfm $@ Manifest.txt \ + $(ICONJAR) \ + -C classes org \ + -C ../libaltos libaltosJNI + +$(FATJAR): classmicropeak.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 + +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/MicroPeak + cp -p $(LINUX_FILES) linux/MicroPeak + cp -p micropeak-fat linux/MicroPeak/micropeak + chmod +x linux/MicroPeak/micropeak + tar cjf $@ -C linux MicroPeak + +$(MACOSX_DIST): $(MACOSX_FILES) + -rm -f $@ + -rm -rf macosx + mkdir macosx + cp -a MicroPeak.app macosx/ + cp -a $(MACOSX_README) macosx/ReadMe.rtf + cp -p Info.plist macosx/MicroPeak.app/Contents + tar xzf $(MACOSX_DRIVER) -C macosx + mkdir -p macosx/MicroPeak.app/Contents/Resources/Java + cp -p $(FATJAR) macosx/MicroPeak.app/Contents/Resources/Java/micropeak.jar + cp -p libaltos.dylib macosx/MicroPeak.app/Contents/Resources/Java + cp -p $(ALTOSLIB_CLASS) macosx/MicroPeak.app/Contents/Resources/Java + cp -p $(ALTOSUILIB_CLASS) macosx/MicroPeak.app/Contents/Resources/Java + cp -p $(JFREECHART_CLASS) macosx/MicroPeak.app/Contents/Resources/Java + cp -p $(JCOMMON_CLASS) macosx/MicroPeak.app/Contents/Resources/Java + genisoimage -D -V MicroPeak-$(VERSION) -no-pad -r -apple -o $@ macosx + +$(WINDOWS_DIST): $(WINDOWS_FILES) micropeak-windows.nsi + -rm -f $@ + makensis -Omicropeak-windows.log "-XOutFile $@" "-DVERSION=$(VERSION)" micropeak-windows.nsi + +Manifest.txt: Makefile + echo 'Main-Class: org.altusmetrum.micropeak.MicroPeak' > $@ + echo "Class-Path: $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(JCOMMON)/jcommon.jar $(JFREECHART)/jfreechart.jar" >> $@ + +Manifest-fat.txt: + echo 'Main-Class: org.altusmetrum.micropeak.MicroPeak' > $@ + echo "Class-Path: $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) jcommon.jar jfreechart.jar" >> $@ + diff --git a/micropeak/MicroData.java b/micropeak/MicroData.java new file mode 100644 index 00000000..f1204e11 --- /dev/null +++ b/micropeak/MicroData.java @@ -0,0 +1,344 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import java.lang.*; +import java.io.*; +import java.util.*; +import org.altusmetrum.AltosLib.*; + +class MicroIterator implements Iterator<MicroDataPoint> { + int i; + MicroData data; + + public boolean hasNext() { + return i < data.pressures.length; + } + + public MicroDataPoint next() { + return new MicroDataPoint(data, i++); + } + + public MicroIterator (MicroData data) { + this.data = data; + i = 0; + } + + public void remove() { + } +} + +class MicroIterable implements Iterable<MicroDataPoint> { + + MicroData data; + + public Iterator<MicroDataPoint> iterator() { + return new MicroIterator(data); + } + + public MicroIterable(MicroData data) { + this.data = data; + } +} + +public class MicroData { + public int ground_pressure; + public int min_pressure; + public int[] pressures; + private double time_step; + private double ground_altitude; + private ArrayList<Integer> bytes; + String name; + + + class FileEndedException extends Exception { + } + + class NonHexcharException extends Exception { + } + + class InvalidCrcException extends Exception { + } + + private int getc(InputStream f) throws IOException, FileEndedException { + int c = f.read(); + + if (c == -1) + throw new FileEndedException(); + bytes.add(c); + return c; + } + + private int get_nonwhite(InputStream f) throws IOException, FileEndedException { + int c; + + for (;;) { + c = getc(f); + if (!Character.isWhitespace(c)) + return c; + } + } + + private int get_hexc(InputStream f) throws IOException, FileEndedException, NonHexcharException { + int c = get_nonwhite(f); + + if ('0' <= c && c <= '9') + return c - '0'; + if ('a' <= c && c <= 'f') + return c - 'a' + 10; + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + throw new NonHexcharException(); + } + + private static final int POLY = 0x8408; + + private int log_crc(int crc, int b) { + int i; + + for (i = 0; i < 8; i++) { + if (((crc & 0x0001) ^ (b & 0x0001)) != 0) + crc = (crc >> 1) ^ POLY; + else + crc = crc >> 1; + b >>= 1; + } + return crc & 0xffff; + } + + int file_crc; + + private int get_hex(InputStream f) throws IOException, FileEndedException, NonHexcharException { + int a = get_hexc(f); + int b = get_hexc(f); + + int h = (a << 4) + b; + + file_crc = log_crc(file_crc, h); + return h; + } + + private boolean find_header(InputStream f) throws IOException { + try { + for (;;) { + if (get_nonwhite(f) == 'M' && get_nonwhite(f) == 'P') + return true; + } + } catch (FileEndedException fe) { + return false; + } + } + + private int get_32(InputStream f) throws IOException, FileEndedException, NonHexcharException { + int v = 0; + for (int i = 0; i < 4; i++) { + v += get_hex(f) << (i * 8); + } + return v; + } + + private int get_16(InputStream f) throws IOException, FileEndedException, NonHexcharException { + int v = 0; + for (int i = 0; i < 2; i++) { + v += get_hex(f) << (i * 8); + } + return v; + } + + private int swap16(int i) { + return ((i << 8) & 0xff00) | ((i >> 8) & 0xff); + } + + public boolean crc_valid; + + int mix_in (int high, int low) { + return high - (high & 0xffff) + low; + } + + boolean closer (int target, int a, int b) { + return Math.abs (target - a) < Math.abs(target - b); + } + + public double altitude(int i) { + return AltosConvert.pressure_to_altitude(pressures[i]); + } + + public Iterable<MicroDataPoint> points() { + return new MicroIterable(this); + } + + int fact(int n) { + if (n == 0) + return 1; + return n * fact(n-1); + } + + int choose(int n, int k) { + return fact(n) / (fact(k) * fact(n-k)); + } + + + public double avg_altitude(int center, int dist) { + int start = center - dist; + int stop = center + dist; + + if (start < 0) + start = 0; + if (stop >= pressures.length) + stop = pressures.length - 1; + + double sum = 0; + double div = 0; + + int n = dist * 2; + + for (int i = start; i <= stop; i++) { + int k = i - (center - dist); + int c = choose (n, k); + + sum += c * pressures[i]; + div += c; + } + + double pres = sum / div; + + double alt = AltosConvert.pressure_to_altitude(pres); + return alt; + } + + public double pressure(int i) { + return pressures[i]; + } + + public double height(int i) { + return altitude(i) - ground_altitude; + } + + static final int speed_avg = 3; + static final int accel_avg = 5; + + private double avg_speed(int center, int dist) { + if (center == 0) + return 0; + + double ai = avg_altitude(center, dist); + double aj = avg_altitude(center - 1, dist); + double s = (ai - aj) / time_step; + + return s; + } + + public double speed(int i) { + return avg_speed(i, speed_avg); + } + + public double acceleration(int i) { + if (i == 0) + return 0; + return (avg_speed(i, accel_avg) - avg_speed(i-1, accel_avg)) / time_step; + } + + public double time(int i) { + return i * time_step; + } + + public void save (OutputStream f) throws IOException { + for (int c : bytes) + f.write(c); + f.write('\n'); + } + + public void export (Writer f) throws IOException { + PrintWriter pw = new PrintWriter(f); + pw.printf(" Time, Press(Pa), Height(m), Height(f), Speed(m/s), Speed(mph), Speed(mach), Accel(m/s²), Accel(ft/s²), Accel(g)\n"); + for (MicroDataPoint point : points()) { + pw.printf("%6.3f,%10.0f,%10.1f,%10.1f,%11.2f,%11.2f,%12.4f,%12.2f,%13.2f,%10.4f\n", + point.time, + point.pressure, + point.height, + AltosConvert.meters_to_feet(point.height), + point.speed, + AltosConvert.meters_to_mph(point.speed), + AltosConvert.meters_to_mach(point.speed), + point.accel, + AltosConvert.meters_to_feet(point.accel), + AltosConvert.meters_to_g(point.accel)); + } + } + + public void set_name(String name) { + this.name = name; + } + + public MicroData (InputStream f, String name) throws IOException, InterruptedException { + this.name = name; + bytes = new ArrayList<Integer>(); + if (!find_header(f)) + throw new IOException("No MicroPeak data header found"); + try { + file_crc = 0xffff; + ground_pressure = get_32(f); + min_pressure = get_32(f); + int nsamples = get_16(f); + pressures = new int[nsamples + 1]; + + ground_altitude = AltosConvert.pressure_to_altitude(ground_pressure); + int cur = ground_pressure; + pressures[0] = cur; + for (int i = 0; i < nsamples; i++) { + int k = get_16(f); + int same = mix_in(cur, k); + int up = mix_in(cur + 0x10000, k); + int down = mix_in(cur - 0x10000, k); + + if (closer (cur, same, up)) { + if (closer (cur, same, down)) + cur = same; + else + cur = down; + } else { + if (closer (cur, up, down)) + cur = up; + else + cur = down; + } + + pressures[i+1] = cur; + } + + int current_crc = swap16(~file_crc & 0xffff); + int crc = get_16(f); + + crc_valid = crc == current_crc; + + time_step = 0.192; + } catch (FileEndedException fe) { + throw new IOException("File Ended Unexpectedly"); + } catch (NonHexcharException ne) { + throw new IOException("Non hexadecimal character found"); + } + } + + public MicroData() { + ground_pressure = 101000; + min_pressure = 101000; + pressures = new int[1]; + pressures[0] = 101000; + } + +} diff --git a/micropeak/MicroDataPoint.java b/micropeak/MicroDataPoint.java new file mode 100644 index 00000000..c58708e6 --- /dev/null +++ b/micropeak/MicroDataPoint.java @@ -0,0 +1,42 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +public class MicroDataPoint { + public double time; + public double pressure; + public double height; + public double speed; + public double accel; + + public MicroDataPoint (double pressure, double height, double speed, double accel, double time) { + this.pressure = pressure; + this.height = height; + this.speed = speed; + this.accel = accel; + this.time = time; + } + + public MicroDataPoint(MicroData data, int i) { + this(data.pressure(i), + data.height(i), + data.speed(i), + data.acceleration(i), + data.time(i)); + } +}
\ No newline at end of file diff --git a/micropeak/MicroDeviceDialog.java b/micropeak/MicroDeviceDialog.java new file mode 100644 index 00000000..7b8a630c --- /dev/null +++ b/micropeak/MicroDeviceDialog.java @@ -0,0 +1,50 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import org.altusmetrum.altosuilib.*; + +public class MicroDeviceDialog extends AltosDeviceDialog { + + public AltosDevice[] devices() { + java.util.List<MicroUSB> list = MicroUSB.list(); + int num_devices = list.size(); + AltosDevice[] devices = new AltosDevice[num_devices]; + + for (int i = 0; i < num_devices; i++) + devices[i] = list.get(i); + return devices; + } + + public MicroDeviceDialog (Frame in_frame, Component location) { + super(in_frame, location, 0); + } + + public static AltosDevice show (Component frameComp) { + Frame frame = JOptionPane.getFrameForComponent(frameComp); + MicroDeviceDialog dialog; + + dialog = new MicroDeviceDialog (frame, frameComp); + dialog.setVisible(true); + return dialog.getValue(); + } +} diff --git a/micropeak/MicroDownload.java b/micropeak/MicroDownload.java new file mode 100644 index 00000000..28a7550d --- /dev/null +++ b/micropeak/MicroDownload.java @@ -0,0 +1,144 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.io.*; +import java.util.concurrent.*; +import java.util.*; +import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; + +public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener { + MicroPeak owner; + Container pane; + AltosDevice device; + JButton cancel; + MicroData data; + MicroSerial serial; + + private void done_internal() { + setVisible(false); + if (data != null) { + if (data.crc_valid) { + owner = owner.SetData(data); + MicroSave save = new MicroSave(owner, data); + if (save.runDialog()) + owner.SetName(data.name); + } else { + JOptionPane.showMessageDialog(owner, + "Flight data corrupted", + "Download Failed", + JOptionPane.ERROR_MESSAGE); + } + } + dispose(); + } + + public void done() { + Runnable r = new Runnable() { + public void run() { + try { + done_internal(); + } catch (Exception ex) { + } + } + }; + SwingUtilities.invokeLater(r); + } + + public void run() { + try { + data = new MicroData(serial, device.toShortString()); + serial.close(); + } catch (FileNotFoundException fe) { + } catch (IOException ioe) { + } catch (InterruptedException ie) { + } + done(); + } + + Thread serial_thread; + + public void start() { + try { + serial = new MicroSerial(device); + } catch (FileNotFoundException fe) { + return; + } + serial_thread = new Thread(this); + serial_thread.start(); + } + + public void actionPerformed(ActionEvent ae) { + if (serial_thread != null) { + serial.close(); + serial_thread.interrupt(); + } + } + + public MicroDownload(MicroPeak owner, AltosDevice device) { + super (owner, "Download MicroPeak Data", false); + + GridBagConstraints c; + Insets il = new Insets(4,4,4,4); + Insets ir = new Insets(4,4,4,4); + + this.owner = owner; + this.device = device; + + pane = getContentPane(); + pane.setLayout(new GridBagLayout()); + + c = new GridBagConstraints(); + c.gridx = 0; c.gridy = 0; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + JLabel device_label = new JLabel("Device:"); + pane.add(device_label, c); + + c = new GridBagConstraints(); + c.gridx = 1; c.gridy = 0; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.anchor = GridBagConstraints.LINE_START; + c.insets = ir; + JLabel device_value = new JLabel(device.toString()); + pane.add(device_value, c); + + cancel = new JButton("Cancel"); + c = new GridBagConstraints(); + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.gridx = 0; c.gridy = 1; + c.gridwidth = GridBagConstraints.REMAINDER; + Insets ic = new Insets(4,4,4,4); + c.insets = ic; + pane.add(cancel, c); + + cancel.addActionListener(this); + + pack(); + setLocationRelativeTo(owner); + setVisible(true); + this.start(); + } +} diff --git a/micropeak/MicroExport.java b/micropeak/MicroExport.java new file mode 100644 index 00000000..4b83bb4d --- /dev/null +++ b/micropeak/MicroExport.java @@ -0,0 +1,105 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; + +public class MicroExport extends JFileChooser { + + JFrame frame; + MicroData data; + + public static void export(File file, MicroData data) throws FileNotFoundException, IOException { + FileWriter fw = new FileWriter(file); + data.export(fw); + fw.close(); + } + + public boolean runDialog() { + int ret; + + setSelectedFile(new File(AltosLib.replace_extension(data.name, ".csv"))); + for (;;) { + ret = showSaveDialog(frame); + if (ret != APPROVE_OPTION) + return false; + File file; + String filename; + file = getSelectedFile(); + if (file == null) + continue; + if (!file.getName().contains(".")) { + String fullname = file.getPath(); + file = new File(fullname.concat(".csv")); + } + filename = file.getName(); + if (file.exists()) { + if (file.isDirectory()) { + JOptionPane.showMessageDialog(frame, + String.format("\"%s\" is a directory", + filename), + "Directory", + JOptionPane.ERROR_MESSAGE); + continue; + } + int r = JOptionPane.showConfirmDialog(frame, + String.format("\"%s\" already exists. Overwrite?", + filename), + "Overwrite file?", + JOptionPane.YES_NO_OPTION); + if (r != JOptionPane.YES_OPTION) + continue; + + if (!file.canWrite()) { + JOptionPane.showMessageDialog(frame, + String.format("\"%s\" is not writable", + filename), + "File not writable", + JOptionPane.ERROR_MESSAGE); + continue; + } + } + try { + export(file, data); + return true; + } catch (FileNotFoundException fe) { + JOptionPane.showMessageDialog(frame, + fe.getMessage(), + "Cannot create file", + JOptionPane.ERROR_MESSAGE); + } catch (IOException ioe) { + } + } + } + + public MicroExport(JFrame frame, MicroData data) { + this.frame = frame; + this.data = data; + setDialogTitle("Export MicroPeak Data File"); + setFileFilter(new FileNameExtensionFilter("MicroPeak CSV file", + "csv")); + setCurrentDirectory(AltosUIPreferences.logdir()); + } +} diff --git a/micropeak/MicroFile.java b/micropeak/MicroFile.java new file mode 100644 index 00000000..13d48380 --- /dev/null +++ b/micropeak/MicroFile.java @@ -0,0 +1,45 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import java.io.*; +import java.util.*; +import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; + +public class MicroFile { + + public static File make(File directory, int year, int month, int day) { + for (int sequence = 1;; sequence++) { + String s = String.format("%04d-%02d-%02d-flight-%03d.mpd", + year, month, day, sequence); + File file = new File(directory, s); + if (!file.exists()) + return file; + } + } + + public static File make(File directory) { + Calendar cal = Calendar.getInstance(); + return make(directory, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH)); + } + + public static File make() { + return make(AltosUIPreferences.logdir()); + } +}
\ No newline at end of file diff --git a/micropeak/MicroFileChooser.java b/micropeak/MicroFileChooser.java new file mode 100644 index 00000000..21ddb0f8 --- /dev/null +++ b/micropeak/MicroFileChooser.java @@ -0,0 +1,55 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.io.*; +import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; + +public class MicroFileChooser extends JFileChooser { + JFrame frame; + String filename; + File file; + + public String filename() { + return filename; + } + + public File file() { + return file; + } + + public File runDialog() { + int ret; + + ret = showOpenDialog(frame); + if (ret == APPROVE_OPTION) + return getSelectedFile(); + return null; + } + + public MicroFileChooser(JFrame in_frame) { + frame = in_frame; + setDialogTitle("Select MicroPeak Data File"); + setFileFilter(new FileNameExtensionFilter("MicroPeak data file", + "mpd")); + setCurrentDirectory(AltosUIPreferences.logdir()); + } +} diff --git a/micropeak/MicroFrame.java b/micropeak/MicroFrame.java new file mode 100644 index 00000000..03e3af0c --- /dev/null +++ b/micropeak/MicroFrame.java @@ -0,0 +1,37 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.util.*; +import org.altusmetrum.altosuilib.*; + +public class MicroFrame extends AltosUIFrame { + static String[] micro_icon_names = { + "/micropeak-16.png", + "/micropeak-32.png", + "/micropeak-48.png", + "/micropeak-64.png", + "/micropeak-128.png", + "/micropeak-256.png" + }; + + static { set_icon_names(micro_icon_names); } +} diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java new file mode 100644 index 00000000..84320be3 --- /dev/null +++ b/micropeak/MicroGraph.java @@ -0,0 +1,173 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.AltosLib.*; + +import org.jfree.ui.*; +import org.jfree.chart.*; +import org.jfree.chart.plot.*; +import org.jfree.chart.axis.*; +import org.jfree.chart.renderer.*; +import org.jfree.chart.renderer.xy.*; +import org.jfree.chart.labels.*; +import org.jfree.data.xy.*; +import org.jfree.data.*; + +class MicroSeries extends XYSeries { + NumberAxis axis; + String label; + String units; + Color color; + XYItemRenderer renderer; + + void set_units(String units) { + this.units = units; + + axis.setLabel(String.format("%s (%s)", label, units)); + + StandardXYToolTipGenerator ttg; + + ttg = new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})", units), + new java.text.DecimalFormat("0.00"), + new java.text.DecimalFormat("0.00")); + renderer.setBaseToolTipGenerator(ttg); + } + + public MicroSeries (String label, String units, Color color) { + super(label); + this.label = label; + this.units = units; + this.color = color; + + axis = new NumberAxis(); + axis.setLabelPaint(color); + axis.setTickLabelPaint(color); + + renderer = new XYLineAndShapeRenderer(true, false); + renderer.setSeriesPaint(0, color); + set_units(units); + } +} + +public class MicroGraph implements AltosUnitsListener { + + XYPlot plot; + JFreeChart chart; + ChartPanel panel; + NumberAxis xAxis; + MicroSeries heightSeries; + MicroSeries speedSeries; + MicroSeries accelSeries; + + static final private Color height_color = new Color(194,31,31); + static final private Color speed_color = new Color(31,194,31); + static final private Color accel_color = new Color(31,31,194); + static final private Color gridline_color = new Color(0, 0, 0); + static final private Color border_color = new Color(255, 255, 255); + static final private Color background_color = new Color(255, 255, 255); + + MicroData data; + + public JPanel panel() { + return panel; + } + + private MicroSeries addSeries(int index, String label, String units, Color color) { + MicroSeries series = new MicroSeries(label, units, color); + XYSeriesCollection dataset = new XYSeriesCollection(series); + + series.renderer.setPlot(plot); + plot.setRangeAxis(index, series.axis); + plot.setDataset(index, dataset); + plot.setRenderer(index, series.renderer); + plot.mapDatasetToRangeAxis(index, index); + return series; + } + + public void resetData() { + heightSeries.clear(); + speedSeries.clear(); + accelSeries.clear(); + if (data != null) { + for (MicroDataPoint point : data.points()) { + heightSeries.add(point.time, AltosConvert.height.value(point.height)); + speedSeries.add(point.time, AltosConvert.speed.value(point.speed)); + accelSeries.add(point.time, AltosConvert.accel.value(point.accel)); + } + } + } + + public void setName (String name) { + chart.setTitle(name); + } + + public void setData (MicroData data) { + this.data = data; + if (data != null) + setName(data.name); + resetData(); + } + + public void units_changed(boolean imperial_units) { + heightSeries.set_units(AltosConvert.height.show_units()); + speedSeries.set_units(AltosConvert.speed.show_units()); + accelSeries.set_units(AltosConvert.accel.show_units()); + resetData(); + } + + public MicroGraph() { + + xAxis = new NumberAxis("Time (s)"); + + xAxis.setAutoRangeIncludesZero(true); + + plot = new XYPlot(); + plot.setDomainAxis(xAxis); + plot.setOrientation(PlotOrientation.VERTICAL); + plot.setDomainPannable(true); + plot.setRangePannable(true); + + chart = new JFreeChart("Flight", JFreeChart.DEFAULT_TITLE_FONT, + plot, true); + + ChartUtilities.applyCurrentTheme(chart); + + heightSeries = addSeries(0, "Height", AltosConvert.height.show_units(), height_color); + speedSeries = addSeries(1, "Speed", AltosConvert.speed.show_units(), speed_color); + accelSeries = addSeries(2, "Acceleration", AltosConvert.accel.show_units(), accel_color); + + plot.setDomainGridlinePaint(gridline_color); + plot.setRangeGridlinePaint(gridline_color); + plot.setBackgroundPaint(background_color); + plot.setBackgroundAlpha((float) 1); + + chart.setBackgroundPaint(background_color); + chart.setBorderPaint(border_color); + panel = new ChartPanel(chart); + panel.setMouseWheelEnabled(true); + panel.setPreferredSize(new java.awt.Dimension(800, 500)); + + AltosPreferences.register_units_listener(this); + } +}
\ No newline at end of file diff --git a/micropeak/MicroPeak.app/Contents/MacOS/JavaApplicationStub b/micropeak/MicroPeak.app/Contents/MacOS/JavaApplicationStub Binary files differnew file mode 100755 index 00000000..c661d3e1 --- /dev/null +++ b/micropeak/MicroPeak.app/Contents/MacOS/JavaApplicationStub diff --git a/micropeak/MicroPeak.app/Contents/PkgInfo b/micropeak/MicroPeak.app/Contents/PkgInfo new file mode 100644 index 00000000..8a43480f --- /dev/null +++ b/micropeak/MicroPeak.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPLAM.O diff --git a/micropeak/MicroPeak.app/Contents/Resources/MicroPeak.icns b/micropeak/MicroPeak.app/Contents/Resources/MicroPeak.icns Binary files differnew file mode 100644 index 00000000..9ba83bf5 --- /dev/null +++ b/micropeak/MicroPeak.app/Contents/Resources/MicroPeak.icns diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java new file mode 100644 index 00000000..5d128dfd --- /dev/null +++ b/micropeak/MicroPeak.java @@ -0,0 +1,305 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.io.*; +import java.util.concurrent.*; +import java.util.*; +import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; + +public class MicroPeak extends MicroFrame implements ActionListener, ItemListener { + + File filename; + MicroGraph graph; + MicroStatsTable stats; + MicroRaw raw; + MicroData data; + Container container; + JTabbedPane pane; + static int number_of_windows; + + MicroPeak SetData(MicroData data) { + MicroPeak mp = this; + if (this.data != null) { + mp = new MicroPeak(); + return mp.SetData(data); + } + this.data = data; + graph.setData(data); + stats.setData(data); + raw.setData(data); + setTitle(data.name); + return this; + } + + void SetName(String name) { + graph.setName(name); + setTitle(name); + } + + private static MicroData ReadFile(File filename) throws IOException, FileNotFoundException { + MicroData data = null; + FileInputStream fis = new FileInputStream(filename); + try { + data = new MicroData((InputStream) fis, filename.getName()); + } catch (InterruptedException ie) { + data = null; + } finally { + fis.close(); + } + return data; + } + + private void OpenFile(File filename) { + try { + SetData(ReadFile(filename)); + } catch (FileNotFoundException fne) { + JOptionPane.showMessageDialog(this, + fne.getMessage(), + "Cannot open file", + JOptionPane.ERROR_MESSAGE); + } catch (IOException ioe) { + JOptionPane.showMessageDialog(this, + ioe.getMessage(), + "File Read Error", + JOptionPane.ERROR_MESSAGE); + } + } + + private void SelectFile() { + MicroFileChooser chooser = new MicroFileChooser(this); + File file = chooser.runDialog(); + + if (file != null) + OpenFile(file); + } + + private void Preferences() { + new AltosUIConfigure(this); + } + + private void DownloadData() { + AltosDevice device = MicroDeviceDialog.show(this); + + if (device != null) + new MicroDownload(this, device); + } + + private void no_data() { + JOptionPane.showMessageDialog(this, + "No data available", + "No data", + JOptionPane.INFORMATION_MESSAGE); + } + + private void Save() { + if (data == null) { + no_data(); + return; + } + MicroSave save = new MicroSave (this, data); + if (save.runDialog()) + SetName(data.name); + } + + private void Export() { + if (data == null) { + no_data(); + return; + } + MicroExport export = new MicroExport (this, data); + export.runDialog(); + } + + private static void CommandGraph(File file) { + MicroPeak m = new MicroPeak(); + m.OpenFile(file); + } + + private static void CommandExport(File file) { + try { + MicroData d = ReadFile(file); + if (d != null) { + File csv = new File(AltosLib.replace_extension(file.getPath(), ".csv")); + try { + System.out.printf ("Export \"%s\" to \"%s\"\n", file.getPath(), csv.getPath()); + MicroExport.export(csv, d); + } catch (FileNotFoundException fe) { + System.err.printf("Cannot create file \"%s\" (%s)\n", csv.getName(), fe.getMessage()); + } catch (IOException ie) { + System.err.printf("Cannot write file \"%s\" (%s)\n", csv.getName(), ie.getMessage()); + } + } + } catch (IOException ie) { + System.err.printf("Cannot read file \"%s\" (%s)\n", file.getName(), ie.getMessage()); + } + } + + private void Close() { + setVisible(false); + dispose(); + --number_of_windows; + if (number_of_windows == 0) + System.exit(0); + } + + public void actionPerformed(ActionEvent ev) { + if ("Exit".equals(ev.getActionCommand())) + System.exit(0); + else if ("Close".equals(ev.getActionCommand())) + Close(); + else if ("Open".equals(ev.getActionCommand())) + SelectFile(); + else if ("Download".equals(ev.getActionCommand())) + DownloadData(); + else if ("Export".equals(ev.getActionCommand())) + Export(); + else if ("Preferences".equals(ev.getActionCommand())) + Preferences(); + else if ("Save a Copy".equals(ev.getActionCommand())) + Save(); + } + + public void itemStateChanged(ItemEvent e) { + } + + public MicroPeak() { + + ++number_of_windows; + + AltosUIPreferences.set_component(this); + + container = getContentPane(); + pane = new JTabbedPane(); + + setTitle("MicroPeak"); + + JMenuBar menuBar = new JMenuBar(); + setJMenuBar(menuBar); + + JMenu fileMenu = new JMenu("File"); + menuBar.add(fileMenu); + + JMenuItem openAction = new JMenuItem("Open"); + fileMenu.add(openAction); + openAction.addActionListener(this); + + JMenuItem downloadAction = new JMenuItem("Download"); + fileMenu.add(downloadAction); + downloadAction.addActionListener(this); + + JMenuItem saveAction = new JMenuItem("Save a Copy"); + fileMenu.add(saveAction); + saveAction.addActionListener(this); + + JMenuItem exportAction = new JMenuItem("Export"); + fileMenu.add(exportAction); + exportAction.addActionListener(this); + + JMenuItem preferencesAction = new JMenuItem("Preferences"); + fileMenu.add(preferencesAction); + preferencesAction.addActionListener(this); + + JMenuItem closeAction = new JMenuItem("Close"); + fileMenu.add(closeAction); + closeAction.addActionListener(this); + + JMenuItem exitAction = new JMenuItem("Exit"); + fileMenu.add(exitAction); + exitAction.addActionListener(this); + + setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + Close(); + } + }); + + graph = new MicroGraph(); + stats = new MicroStatsTable(); + raw = new MicroRaw(); + pane.add(graph.panel, "Graph"); + pane.add(stats, "Statistics"); + JScrollPane scroll = new JScrollPane(raw); + pane.add(scroll, "Raw Data"); + pane.doLayout(); + pane.validate(); + container.add(pane); + container.doLayout(); + container.validate(); + doLayout(); + validate(); + Insets i = getInsets(); + Dimension ps = pane.getPreferredSize(); + ps.width += i.left + i.right; + ps.height += i.top + i.bottom; +// setPreferredSize(ps); + setSize(ps); + setLocationByPlatform(true); + setVisible(true); + } + + public static void help(int code) { + System.out.printf("Usage: micropeak [OPTION] ... [FILE]...\n"); + System.out.printf(" Options:\n"); + System.out.printf(" --csv\tgenerate comma separated output for spreadsheets, etc\n"); + System.out.printf(" --graph\tgraph a flight\n"); + System.exit(code); + } + + public static void main(final String[] args) { + boolean opened = false; + boolean graphing = true; + + try { + UIManager.setLookAndFeel(AltosUIPreferences.look_and_feel()); + } catch (Exception e) { + } + + for (int i = 0; i < args.length; i++) { + if (args[i].equals("--help")) + help(0); + else if (args[i].equals("--export")) + graphing = false; + else if (args[i].equals("--graph")) + graphing = true; + else if (args[i].startsWith("--")) + help(1); + else { + File file = new File(args[i]); + try { + if (graphing) + CommandGraph(file); + else + CommandExport(file); + opened = true; + } catch (Exception e) { + System.err.printf("Error processing \"%s\": %s\n", + file.getName(), e.getMessage()); + } + } + } + if (!opened) + new MicroPeak(); + } +} diff --git a/micropeak/MicroRaw.java b/micropeak/MicroRaw.java new file mode 100644 index 00000000..8546cffb --- /dev/null +++ b/micropeak/MicroRaw.java @@ -0,0 +1,45 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import java.awt.*; +import java.io.*; +import javax.swing.*; +import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; + +public class MicroRaw extends JTextArea { + + public void setData(MicroData data) { + StringWriter sw = new StringWriter(); + try { + data.export(sw); + setRows(data.pressures.length + 1); + setText(sw.toString()); + } catch (IOException ie) { + setText(String.format("Error writing data: %s", ie.getMessage())); + } + setCaretPosition(0); + } + + public MicroRaw() { + super(1, 30); + setFont(AltosUILib.table_value_font); + setEditable(false); + } +} diff --git a/micropeak/MicroSave.java b/micropeak/MicroSave.java new file mode 100644 index 00000000..7879ff90 --- /dev/null +++ b/micropeak/MicroSave.java @@ -0,0 +1,107 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.io.*; +import java.util.concurrent.*; +import java.util.*; +import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; + +public class MicroSave extends JFileChooser { + + JFrame frame; + MicroData data; + + public static void save(File file, MicroData data) throws FileNotFoundException, IOException { + FileOutputStream fos = new FileOutputStream(file); + data.save(fos); + fos.close(); + } + + public boolean runDialog() { + int ret; + + for (;;) { + ret = showSaveDialog(frame); + if (ret != APPROVE_OPTION) + return false; + File file; + String filename; + file = getSelectedFile(); + if (file == null) + continue; + if (!file.getName().contains(".")) { + String fullname = file.getPath(); + file = new File(fullname.concat(".mpd")); + } + filename = file.getName(); + if (file.exists()) { + if (file.isDirectory()) { + JOptionPane.showMessageDialog(frame, + String.format("\"%s\" is a directory", + filename), + "Directory", + JOptionPane.ERROR_MESSAGE); + continue; + } + int r = JOptionPane.showConfirmDialog(frame, + String.format("\"%s\" already exists. Overwrite?", + filename), + "Overwrite file?", + JOptionPane.YES_NO_OPTION); + if (r != JOptionPane.YES_OPTION) + continue; + + if (!file.canWrite()) { + JOptionPane.showMessageDialog(frame, + String.format("\"%s\" is not writable", + filename), + "File not writable", + JOptionPane.ERROR_MESSAGE); + continue; + } + } + try { + save(file, data); + data.set_name(filename); + return true; + } catch (FileNotFoundException fe) { + JOptionPane.showMessageDialog(frame, + fe.getMessage(), + "Cannot create file", + JOptionPane.ERROR_MESSAGE); + } catch (IOException ioe) { + } + } + } + + public MicroSave(JFrame frame, MicroData data) { + this.frame = frame; + this.data = data; + setDialogTitle("Save MicroPeak Data File"); + setFileFilter(new FileNameExtensionFilter("MicroPeak data file", + "mpd")); + setCurrentDirectory(AltosUIPreferences.logdir()); + setSelectedFile(MicroFile.make()); + } +} diff --git a/micropeak/MicroSerial.java b/micropeak/MicroSerial.java new file mode 100644 index 00000000..15ef8582 --- /dev/null +++ b/micropeak/MicroSerial.java @@ -0,0 +1,55 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import java.util.*; +import java.io.*; +import libaltosJNI.*; +import org.altusmetrum.altosuilib.*; + +public class MicroSerial extends InputStream { + SWIGTYPE_p_altos_file file; + + public int read() { + int c = libaltos.altos_getchar(file, 0); + if (Thread.interrupted()) + return -1; + if (c == -1) + return -1; + if (AltosUIPreferences.serial_debug) + System.out.printf("%c", c); + return c; + } + + public void close() { + if (file != null) { + libaltos.altos_close(file); + file = null; + } + } + + public MicroSerial(AltosDevice device) throws FileNotFoundException { + file = device.open(); + if (file == null) { + final String message = device.getErrorString(); + throw new FileNotFoundException(String.format("%s (%s)", + device.toShortString(), + message)); + } + } +} diff --git a/micropeak/MicroStats.java b/micropeak/MicroStats.java new file mode 100644 index 00000000..056fac7d --- /dev/null +++ b/micropeak/MicroStats.java @@ -0,0 +1,162 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import java.io.*; +import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; + +public class MicroStats { + double coast_height; + double coast_time; + + double apogee_height; + double apogee_time; + + double landed_height; + double landed_time; + + double max_speed; + double max_accel; + + MicroData data; + + void find_landing() { + landed_height = 0; + + for (MicroDataPoint point : data.points()) { + landed_height = point.height; + landed_time = point.time; + } + + boolean above = false; + for (MicroDataPoint point : data.points()) { + if (point.height > landed_height + 10) { + above = true; + } else { + if (above && point.height < landed_height + 2) { + above = false; + landed_time = point.time; + } + } + } + } + + void find_apogee() { + apogee_height = 0; + apogee_time = 0; + + for (MicroDataPoint point : data.points()) { + if (point.height > apogee_height) { + apogee_height = point.height; + apogee_time = point.time; + } + } + } + + void find_coast() { + coast_height = 0; + coast_time = 0; + + for (MicroDataPoint point : data.points()) { + if (point.accel < -9.8) + break; + coast_time = point.time; + coast_height = point.height; + } + } + + void find_max_speed() { + max_speed = 0; + for (MicroDataPoint point : data.points()) { + if (point.time > apogee_time) + break; + if (point.speed > max_speed) + max_speed = point.speed; + } + } + + void find_max_accel() { + max_accel = 0; + for (MicroDataPoint point : data.points()) { + if (point.time > apogee_time) + break; + if (point.accel > max_accel) + max_accel = point.accel; + } + } + + double boost_duration() { + return coast_time; + } + + double boost_height() { + return coast_height; + } + + double boost_speed() { + return coast_height / coast_time; + } + + double boost_accel() { + return boost_speed() / boost_duration(); + } + + double coast_duration() { + return apogee_time - coast_time; + } + + double coast_height() { + return apogee_height - coast_height; + } + + double coast_speed() { + return coast_height() / coast_duration(); + } + + double coast_accel() { + return coast_speed() / coast_duration(); + } + + double descent_duration() { + return landed_time - apogee_time; + } + + double descent_height() { + return apogee_height - landed_height; + } + + double descent_speed() { + return descent_height() / descent_duration(); + } + + public MicroStats(MicroData data) { + + this.data = data; + + find_coast(); + find_apogee(); + find_landing(); + find_max_speed(); + find_max_accel(); + } + + public MicroStats() { + this(new MicroData()); + } +} diff --git a/micropeak/MicroStatsTable.java b/micropeak/MicroStatsTable.java new file mode 100644 index 00000000..f373e25d --- /dev/null +++ b/micropeak/MicroStatsTable.java @@ -0,0 +1,138 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; + +public class MicroStatsTable extends JComponent { + GridBagLayout layout; + + class MicroStat { + JLabel label; + JTextField[] texts; + + public void set_values(String ... values) { + for (int j = 0; j < values.length; j++) { + texts[j].setText(values[j]); + } + } + + public MicroStat(GridBagLayout layout, int y, String label_text, String ... values) { + GridBagConstraints c = new GridBagConstraints(); + c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad); + c.weighty = 1; + + label = new JLabel(label_text); + label.setFont(AltosUILib.label_font); + label.setHorizontalAlignment(SwingConstants.LEFT); + c.gridx = 0; c.gridy = y; + c.anchor = GridBagConstraints.WEST; + c.fill = GridBagConstraints.VERTICAL; + c.weightx = 0; + layout.setConstraints(label, c); + add(label); + + texts = new JTextField[values.length]; + for (int j = 0; j < values.length; j++) { + JTextField value = new JTextField(values[j]); + value.setFont(AltosUILib.value_font); + value.setHorizontalAlignment(SwingConstants.RIGHT); + texts[j] = value; + c.gridx = j+1; c.gridy = y; + c.anchor = GridBagConstraints.EAST; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1; + layout.setConstraints(value, c); + add(value); + } + } + } + + MicroStat max_height, max_speed; + MicroStat max_accel, avg_accel; + MicroStat boost_duration; + MicroStat coast_duration; + MicroStat descent_speed; + MicroStat descent_duration; + MicroStat flight_time; + + public void setStats(MicroStats stats) { + max_height.set_values(String.format("%5.0f m", stats.apogee_height), + String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.apogee_height))); + max_speed.set_values(String.format("%5.0f m/s", stats.max_speed), + String.format("%5.0f mph", AltosConvert.meters_to_mph(stats.max_speed)), + String.format("Mach %4.1f", AltosConvert.meters_to_mach(stats.max_speed))); + max_accel.set_values(String.format("%5.0f m/s²", stats.max_accel), + String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.max_accel)), + String.format("%5.0f G", AltosConvert.meters_to_g(stats.max_accel))); + avg_accel.set_values(String.format("%5.0f m/s²", stats.boost_accel(), + String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.boost_accel())), + String.format("%5.0f G", AltosConvert.meters_to_g(stats.boost_accel())))); + boost_duration.set_values(String.format("%6.1f s", stats.boost_duration())); + coast_duration.set_values(String.format("%6.1f s", stats.coast_duration())); + descent_speed.set_values(String.format("%5.0f m/s", stats.descent_speed()), + String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.descent_speed()))); + descent_duration.set_values(String.format("%6.1f s", stats.descent_duration())); + flight_time.set_values(String.format("%6.1f s", stats.landed_time)); + } + + public void setData(MicroData data) { + setStats(new MicroStats(data)); + } + + public MicroStatsTable(MicroStats stats) { + layout = new GridBagLayout(); + + setLayout(layout); + int y = 0; + max_height = new MicroStat(layout, y++, "Maximum height", + String.format("%5.0f m", stats.apogee_height), + String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.apogee_height))); + max_speed = new MicroStat(layout, y++, "Maximum speed", + String.format("%5.0f m/s", stats.max_speed), + String.format("%5.0f mph", AltosConvert.meters_to_mph(stats.max_speed)), + String.format("Mach %4.1f", AltosConvert.meters_to_mach(stats.max_speed))); + max_accel = new MicroStat(layout, y++, "Maximum boost acceleration", + String.format("%5.0f m/s²", stats.max_accel), + String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.max_accel)), + String.format("%5.0f G", AltosConvert.meters_to_g(stats.max_accel))); + avg_accel = new MicroStat(layout, y++, "Average boost acceleration", + String.format("%5.0f m/s²", stats.boost_accel(), + String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.boost_accel())), + String.format("%5.0f G", AltosConvert.meters_to_g(stats.boost_accel())))); + boost_duration = new MicroStat(layout, y++, "Boost duration", + String.format("%6.0f s", stats.boost_duration())); + coast_duration = new MicroStat(layout, y++, "Coast duration", + String.format("%6.1f s", stats.coast_duration())); + descent_speed = new MicroStat(layout, y++, "Descent rate", + String.format("%5.0f m/s", stats.descent_speed()), + String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.descent_speed()))); + descent_duration = new MicroStat(layout, y++, "Descent duration", + String.format("%6.1f s", stats.descent_duration())); + flight_time = new MicroStat(layout, y++, "Flight Time", + String.format("%6.0f s", stats.landed_time)); + } + + public MicroStatsTable() { + this(new MicroStats()); + } + +}
\ No newline at end of file diff --git a/micropeak/MicroUSB.java b/micropeak/MicroUSB.java new file mode 100644 index 00000000..f56d81d4 --- /dev/null +++ b/micropeak/MicroUSB.java @@ -0,0 +1,109 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * 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.micropeak; + +import java.util.*; +import libaltosJNI.*; +import org.altusmetrum.altosuilib.*; + +public class MicroUSB extends altos_device implements AltosDevice { + + static boolean initialized = false; + static boolean loaded_library = false; + + public static boolean load_library() { + if (!initialized) { + try { + System.loadLibrary("altos"); + libaltos.altos_init(); + loaded_library = true; + } catch (UnsatisfiedLinkError e) { + try { + System.loadLibrary("altos64"); + libaltos.altos_init(); + loaded_library = true; + } catch (UnsatisfiedLinkError e2) { + loaded_library = false; + } + } + initialized = true; + } + return loaded_library; + } + + public String toString() { + String name = getName(); + if (name == null) + name = "Altus Metrum"; + return String.format("%-24.24s %s", + name, getPath()); + } + + public String toShortString() { + String name = getName(); + if (name == null) + name = "Altus Metrum"; + return String.format("%s %s", + name, getPath()); + + } + + public String getErrorString() { + altos_error error = new altos_error(); + + libaltos.altos_get_last_error(error); + return String.format("%s (%d)", error.getString(), error.getCode()); + } + + public SWIGTYPE_p_altos_file open() { + return libaltos.altos_open(this); + } + + private boolean isMicro() { + if (getVendor() != 0x0403) + return false; + if (getProduct() != 0x6015) + return false; + return true; + } + + public boolean matchProduct(int product) { + return isMicro(); + } + + static java.util.List<MicroUSB> list() { + if (!load_library()) + return null; + + SWIGTYPE_p_altos_list list = libaltos.altos_ftdi_list_start(); + + ArrayList<MicroUSB> device_list = new ArrayList<MicroUSB>(); + if (list != null) { + for (;;) { + MicroUSB device = new MicroUSB(); + if (libaltos.altos_list_next(list, device) == 0) + break; + if (device.isMicro()) + device_list.add(device); + } + libaltos.altos_list_finish(list); + } + + return device_list; + } +}
\ No newline at end of file diff --git a/micropeak/ReadMe-Mac.rtf b/micropeak/ReadMe-Mac.rtf new file mode 100644 index 00000000..64bbdeb6 --- /dev/null +++ b/micropeak/ReadMe-Mac.rtf @@ -0,0 +1,19 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf510 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\margl1440\margr1440\vieww10800\viewh8400\viewkind0 +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural + +\f0\fs24 \cf0 Installing MicroPeak software for Mac OS X computers\ +\ +There are two files included in the Mac OS X distribution:\ +\ + 1) The MicroPeak application\ +\ + 2) The FTDI device drivers\ +\ +As with most Mac OS X applications, install MicroPeak by dragging it from the distribution disk image to a suitable place on your computer.\ +\ +To communicate with the MicroPeak serial adapter, you need to installed the FTDI device drivers, which is done by double-clicking on the FTDIUSBSerialDriver package file. That will guide you through the installation process.\ +\ +Thanks for choosing AltusMetrum products!}
\ No newline at end of file diff --git a/micropeak/micropeak-fat b/micropeak/micropeak-fat new file mode 100755 index 00000000..ace7548d --- /dev/null +++ b/micropeak/micropeak-fat @@ -0,0 +1,4 @@ +#!/bin/sh +me=`which "$0"` +dir=`dirname "$me"` +exec java -cp "$dir/*" -Djava.library.path="$dir" -jar "$dir"/micropeak-fat.jar "$@" diff --git a/micropeak/micropeak-windows.nsi b/micropeak/micropeak-windows.nsi new file mode 100644 index 00000000..425048bd --- /dev/null +++ b/micropeak/micropeak-windows.nsi @@ -0,0 +1,123 @@ +!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.jar" + File "AltosUILib.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 "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 |