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  | 
