diff options
204 files changed, 2803 insertions, 1511 deletions
| diff --git a/Makefile.am b/Makefile.am index 59cddb9f..bd7772e8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,3 +20,6 @@ fat:  	cd altosuilib && $(MAKE) all  	cd altosui && $(MAKE) fat  	cd micropeak && $(MAKE) fat + +set-java-versions: +	$(top_srcdir)/fix-java-versions org.altusmetrum.altoslib=$(ALTOSLIB_VERSION) org.altusmetrum.altosuilib=$(ALTOSUILIB_VERSION)
\ No newline at end of file diff --git a/altosdroid/AndroidManifest.xml b/altosdroid/AndroidManifest.xml index 7147c0b1..8ecfcbb5 100644 --- a/altosdroid/AndroidManifest.xml +++ b/altosdroid/AndroidManifest.xml @@ -18,7 +18,7 @@  <manifest xmlns:android="http://schemas.android.com/apk/res/android"        package="org.altusmetrum.AltosDroid"        android:versionCode="1" -      android:versionName="1.0"> +      android:versionName="1.1.9.3">      <uses-sdk android:targetSdkVersion="10" android:minSdkVersion="10"/>      <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />      <uses-permission android:name="android.permission.BLUETOOTH" /> diff --git a/altosdroid/Makefile.am b/altosdroid/Makefile.am index 3860e110..39f3c2b6 100644 --- a/altosdroid/Makefile.am +++ b/altosdroid/Makefile.am @@ -17,7 +17,7 @@ ZIPALIGN=$(SDK)/tools/zipalign  SRC_DIR=src/org/altusmetrum/AltosDroid  EXT_LIBDIR=libs  ALTOSLIB_SRCDIR=../altoslib -ALTOSLIB_JAR=AltosLib.jar +ALTOSLIB_JAR=altoslib_$(ALTOSLIB_VERSION).jar  ALTOSLIB=$(EXT_LIBDIR)/$(ALTOSLIB_JAR) @@ -54,9 +54,21 @@ bin/AltosDroid-debug.apk: $(SRC) $(ALTOSLIB)  bin/AltosDroid-release.apk: $(SRC) $(ALTOSLIB)  	ant release + +sign: +	jarsigner -keystore release.keystore \ +	   -signedjar bin/AltosDroid-release-signed.apk \ +	   bin/AltosDroid-release-unsigned.apk AltosDroid +	$(SDK)/tools/zipalign -f 4 \ +	   bin/AltosDroid-release-signed.apk \ +	   bin/AltosDroid-release.apk +  endif -clean: +clean: clean-local  	$(clean_command) +clean-local: +	rm -rf $(EXT_LIBDIR) +  .PHONY: $(SRC_DIR)/BuildInfo.java diff --git a/altosdroid/libs/.gitignore b/altosdroid/libs/.gitignore deleted file mode 100644 index b4e68f63..00000000 --- a/altosdroid/libs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -AltosLib.jar diff --git a/altosdroid/release.keystore b/altosdroid/release.keystoreBinary files differ new file mode 100644 index 00000000..53607dcb --- /dev/null +++ b/altosdroid/release.keystore diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java index 9fcc4eba..0aea06f1 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java @@ -31,7 +31,7 @@ import android.os.Handler;  //import android.os.Message;  import android.util.Log; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosBluetooth extends AltosLink { diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index ab1fb0de..caa1a1c5 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -43,7 +43,7 @@ import android.widget.TextView;  import android.widget.Toast;  import android.app.AlertDialog; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  /**   * This is the main Activity that displays the current chat session. @@ -119,7 +119,7 @@ public class AltosDroid extends Activity {  					Toast.makeText(ad.getApplicationContext(), "Connected to " + str, Toast.LENGTH_SHORT).show();  					ad.mAltosVoice.speak("Connected");  					//TEST! -					ad.mTextView.setText(Dumper.dump(ad.mConfigData)); +					//ad.mTextView.setText(Dumper.dump(ad.mConfigData));  					break;  				case TelemetryService.STATE_CONNECTING:  					ad.mTitle.setText(R.string.title_connecting); @@ -135,7 +135,7 @@ public class AltosDroid extends Activity {  			case MSG_TELEMETRY:  				ad.update_ui((AltosState) msg.obj);  				// TEST! -				ad.mTextView.setText(Dumper.dump(msg.obj)); +				//ad.mTextView.setText(Dumper.dump(msg.obj));  				break;  			}  		} diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java index 3b4bdcf8..fd4b0768 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java @@ -23,7 +23,7 @@ import android.content.Context;  import android.content.SharedPreferences;  import android.os.Environment; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosDroidPreferences implements AltosPreferencesBackend {  	public final static String        NAME    = "org.altusmetrum.AltosDroid"; diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java index 264e35c6..7da5c4a9 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java @@ -21,7 +21,7 @@ package org.altusmetrum.AltosDroid;  import android.speech.tts.TextToSpeech;
  import android.speech.tts.TextToSpeech.OnInitListener;
 -import org.altusmetrum.AltosLib.*;
 +import org.altusmetrum.altoslib_1.*;
  public class AltosVoice {
 diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java index b2dcdb48..3ece04ac 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java @@ -1,6 +1,6 @@  package org.altusmetrum.AltosDroid; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  import android.content.BroadcastReceiver;  import android.content.Context; diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java index 66e9c6bd..9460bdbc 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java @@ -25,7 +25,7 @@ import java.util.concurrent.*;  import android.util.Log;
  import android.os.Handler;
 -import org.altusmetrum.AltosLib.*;
 +import org.altusmetrum.altoslib_1.*;
  public class TelemetryReader extends Thread {
 diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java index 3cb498e8..5ff00a68 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java @@ -38,7 +38,7 @@ import android.os.RemoteException;  import android.util.Log;  import android.widget.Toast; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class TelemetryService extends Service { diff --git a/altoslib/AltosAccel.java b/altoslib/AltosAccel.java index d14764a2..d02b3238 100644 --- a/altoslib/AltosAccel.java +++ b/altoslib/AltosAccel.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosAccel extends AltosUnits { @@ -37,7 +37,7 @@ public class AltosAccel extends AltosUnits {  		return "meters per second squared";  	} -	int show_fraction(int width) { +	public int show_fraction(int width) {  		return width / 9;  	}  }
\ No newline at end of file diff --git a/altoslib/AltosCRCException.java b/altoslib/AltosCRCException.java index 101c5363..76e79add 100644 --- a/altoslib/AltosCRCException.java +++ b/altoslib/AltosCRCException.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosCRCException extends Exception {  	public int rssi; diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index 99b8e39d..12659d88 100644 --- a/altoslib/AltosConfigData.java +++ b/altoslib/AltosConfigData.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.util.*;  import java.text.*; @@ -116,12 +116,22 @@ public class AltosConfigData implements Iterable<String> {  		default:  			if (flight_log_max <= 0)  				return 1; +			int	log_max = flight_log_max * 1024;  			int	log_space = storage_size - storage_erase_unit; -			int	log_used = stored_flight * flight_log_max; +			int	log_used; + +			if (stored_flight <= 0) +				log_used = 0; +			else +				log_used = stored_flight * log_max; +			int	log_avail;  			if (log_used >= log_space) -				return 0; -			return (log_space - log_used) / flight_log_max; +				log_avail = 0; +			else +				log_avail = (log_space - log_used) / log_max; + +			return log_avail;  		}  	} @@ -196,7 +206,7 @@ public class AltosConfigData implements Iterable<String> {  		storage_size = -1;  		storage_erase_unit = -1; -		stored_flight = -1; +		stored_flight = 0;  	}  	public void parse_line(String line) { @@ -272,7 +282,7 @@ public class AltosConfigData implements Iterable<String> {  		/* Storage info replies */  		try { storage_size = get_int(line, "Storage size:"); } catch (Exception e) {} -		try { storage_erase_unit = get_int(line, "Storage erase unit"); } catch (Exception e) {} +		try { storage_erase_unit = get_int(line, "Storage erase unit:"); } catch (Exception e) {}  		/* Log listing replies */  		try { get_int(line, "flight"); stored_flight++; }  catch (Exception e) {} @@ -485,7 +495,6 @@ public class AltosConfigData implements Iterable<String> {  		reset();  		link.printf("c s\nf\nv\n");  		read_link(link, "software-version"); -		System.out.printf("Log format %d\n", log_format);  		switch (log_format) {  		case AltosLib.AO_LOG_FORMAT_FULL:  		case AltosLib.AO_LOG_FORMAT_TINY: diff --git a/altoslib/AltosConfigValues.java b/altoslib/AltosConfigValues.java index 40d5217e..027d10f4 100644 --- a/altoslib/AltosConfigValues.java +++ b/altoslib/AltosConfigValues.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public interface AltosConfigValues {  	/* set and get all of the dialog values */ diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index acd6c5f4..a42b36c4 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -18,7 +18,7 @@  /*   * Sensor data conversion functions   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosConvert {  	/* @@ -258,6 +258,10 @@ public class AltosConvert {  		return meters / 9.80665;  	} +	public static double c_to_f(double c) { +		return c * 9/5 + 32; +	} +  	public static boolean imperial_units = false;  	public static AltosDistance distance = new AltosDistance(); @@ -268,6 +272,8 @@ public class AltosConvert {  	public static AltosAccel accel = new AltosAccel(); +	public static AltosTemperature temperature = new AltosTemperature(); +  	public static String show_gs(String format, double a) {  		a = meters_to_g(a);  		format = format.concat(" g"); diff --git a/altoslib/AltosDistance.java b/altoslib/AltosDistance.java index a6026d4a..25028ac7 100644 --- a/altoslib/AltosDistance.java +++ b/altoslib/AltosDistance.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosDistance extends AltosUnits { @@ -37,13 +37,13 @@ public class AltosDistance extends AltosUnits {  		return "meters";  	} -	int show_fraction(int width) { +	public int show_fraction(int width) {  		if (AltosConvert.imperial_units)  			return width / 3;  		return width / 9;  	} -	int say_fraction() { +	public int say_fraction() {  		if (AltosConvert.imperial_units)  			return 1;  		return 0; diff --git a/altoslib/AltosEepromChunk.java b/altoslib/AltosEepromChunk.java index 77b22fe2..b1bba3bb 100644 --- a/altoslib/AltosEepromChunk.java +++ b/altoslib/AltosEepromChunk.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*;  import java.util.concurrent.*; diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java index 986b7a2c..bc698c80 100644 --- a/altoslib/AltosEepromIterable.java +++ b/altoslib/AltosEepromIterable.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosEepromLog.java b/altoslib/AltosEepromLog.java index 211fd706..20026c6d 100644 --- a/altoslib/AltosEepromLog.java +++ b/altoslib/AltosEepromLog.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*;  import java.util.concurrent.*; diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index af4f8aca..b077e26c 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*; diff --git a/altoslib/AltosEepromMegaIterable.java b/altoslib/AltosEepromMegaIterable.java index 16809089..a127f435 100644 --- a/altoslib/AltosEepromMegaIterable.java +++ b/altoslib/AltosEepromMegaIterable.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosEepromRecord.java b/altoslib/AltosEepromRecord.java index c7ced6a3..70ac1113 100644 --- a/altoslib/AltosEepromRecord.java +++ b/altoslib/AltosEepromRecord.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*; diff --git a/altoslib/AltosEepromTeleScience.java b/altoslib/AltosEepromTeleScience.java index 02ce4553..2a828cf3 100644 --- a/altoslib/AltosEepromTeleScience.java +++ b/altoslib/AltosEepromTeleScience.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*; diff --git a/altoslib/AltosFile.java b/altoslib/AltosFile.java index 1ab00b38..90dbc6db 100644 --- a/altoslib/AltosFile.java +++ b/altoslib/AltosFile.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib;  +package org.altusmetrum.altoslib_1;   import java.io.File;  import java.util.*; diff --git a/altoslib/AltosFlightReader.java b/altoslib/AltosFlightReader.java index cbd64153..3039b4dc 100644 --- a/altoslib/AltosFlightReader.java +++ b/altoslib/AltosFlightReader.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*;  import java.io.*; diff --git a/altoslib/AltosFrequency.java b/altoslib/AltosFrequency.java index e20f03b7..484a2fd9 100644 --- a/altoslib/AltosFrequency.java +++ b/altoslib/AltosFrequency.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosFrequency {  	public double	frequency; diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index ea0949ec..068d8c9c 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*; diff --git a/altoslib/AltosGPSQuery.java b/altoslib/AltosGPSQuery.java index e93af259..deb9d201 100644 --- a/altoslib/AltosGPSQuery.java +++ b/altoslib/AltosGPSQuery.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.util.concurrent.*; diff --git a/altoslib/AltosGPSSat.java b/altoslib/AltosGPSSat.java index faa1ec8d..8714dd8a 100644 --- a/altoslib/AltosGPSSat.java +++ b/altoslib/AltosGPSSat.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosGPSSat {  	public int	svid; diff --git a/altoslib/AltosGreatCircle.java b/altoslib/AltosGreatCircle.java index 76b71859..921356a5 100644 --- a/altoslib/AltosGreatCircle.java +++ b/altoslib/AltosGreatCircle.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.lang.Math; diff --git a/altoslib/AltosHeight.java b/altoslib/AltosHeight.java index da7ffdae..ed590812 100644 --- a/altoslib/AltosHeight.java +++ b/altoslib/AltosHeight.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosHeight extends AltosUnits { @@ -37,7 +37,7 @@ public class AltosHeight extends AltosUnits {  		return "meters";  	} -	int show_fraction(int width) { +	public int show_fraction(int width) {  		return width / 9;  	}  }
\ No newline at end of file diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java index c0eaf139..8f6731fa 100644 --- a/altoslib/AltosIMU.java +++ b/altoslib/AltosIMU.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosIMU {  	public int		accel_x; diff --git a/altoslib/AltosIMUQuery.java b/altoslib/AltosIMUQuery.java index 0965fa39..4ea5d963 100644 --- a/altoslib/AltosIMUQuery.java +++ b/altoslib/AltosIMUQuery.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java index 07d8930d..f2f75bbb 100644 --- a/altoslib/AltosIdleMonitor.java +++ b/altoslib/AltosIdleMonitor.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.io.*;  import java.util.concurrent.*; @@ -27,6 +27,7 @@ public class AltosIdleMonitor extends Thread {  	AltosState		state;  	boolean			remote;  	double			frequency; +	String			callsign;  	AltosState		previous_state;  	AltosConfigData		config_data;  	AltosGPS		gps; @@ -87,6 +88,7 @@ public class AltosIdleMonitor extends Thread {  		try {  			if (remote) {  				link.set_radio_frequency(frequency); +				link.set_callsign(callsign);  				link.start_remote();  			} else  				link.flush_input(); @@ -126,12 +128,29 @@ public class AltosIdleMonitor extends Thread {  	public void set_frequency(double in_frequency) {  		frequency = in_frequency; +		link.abort_reply(); +	} + +	public void set_callsign(String in_callsign) { +		callsign = in_callsign; +		link.abort_reply();  	}  	public void post_state() {  		listener.update(state);  	} +	public void abort() { +		if (isAlive()) { +			interrupt(); +			link.abort_reply(); +			try { +				join(); +			} catch (InterruptedException ie) { +			} +		} +	} +  	public void run() {  		try {  			for (;;) { diff --git a/altoslib/AltosIdleMonitorListener.java b/altoslib/AltosIdleMonitorListener.java index 9f9ababf..7f58d61c 100644 --- a/altoslib/AltosIdleMonitorListener.java +++ b/altoslib/AltosIdleMonitorListener.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public interface AltosIdleMonitorListener {  	public void update(AltosState state); diff --git a/altoslib/AltosIgnite.java b/altoslib/AltosIgnite.java index a48d0b69..85905900 100644 --- a/altoslib/AltosIgnite.java +++ b/altoslib/AltosIgnite.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.io.*;  import java.util.concurrent.*; diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 07516aeb..192da0a9 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.util.*;  import java.io.*; @@ -405,4 +405,8 @@ public class AltosLib {  			input = input.substring(0,dot);  		return input.concat(extension);  	} + +	public static File replace_extension(File input, String extension) { +		return new File(replace_extension(input.getPath(), extension)); +	}  } diff --git a/altoslib/AltosLine.java b/altoslib/AltosLine.java index 5627795a..b3bd20f9 100644 --- a/altoslib/AltosLine.java +++ b/altoslib/AltosLine.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosLine {  	public String	line; diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java index 1b722026..9eb25ce0 100644 --- a/altoslib/AltosLink.java +++ b/altoslib/AltosLink.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.io.*;  import java.util.concurrent.*; @@ -249,6 +249,7 @@ public abstract class AltosLink implements Runnable {  	public boolean monitor_mode = false;  	public int telemetry = AltosLib.ao_telemetry_standard;  	public double frequency; +	public String callsign;  	AltosConfigData	config_data;  	private int telemetry_len() { @@ -330,6 +331,7 @@ public abstract class AltosLink implements Runnable {  	}  	public void set_callsign(String callsign) { +		this.callsign = callsign;  		printf ("c c %s\n", callsign);  		flush_output();  	} @@ -363,5 +365,6 @@ public abstract class AltosLink implements Runnable {  	}  	public AltosLink() { +		callsign = "";  	}  } diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java index aa30190c..974c9f0f 100644 --- a/altoslib/AltosLog.java +++ b/altoslib/AltosLog.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.io.*;  import java.text.ParseException; diff --git a/altoslib/AltosMag.java b/altoslib/AltosMag.java index 0f8399ab..b3bbd92f 100644 --- a/altoslib/AltosMag.java +++ b/altoslib/AltosMag.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosMag {  	public int		x; diff --git a/altoslib/AltosMs5607.java b/altoslib/AltosMs5607.java index 318fea4d..606916b7 100644 --- a/altoslib/AltosMs5607.java +++ b/altoslib/AltosMs5607.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosMs5607 {  	public int	reserved; diff --git a/altoslib/AltosMs5607Query.java b/altoslib/AltosMs5607Query.java index 1aaec334..d39dbf26 100644 --- a/altoslib/AltosMs5607Query.java +++ b/altoslib/AltosMs5607Query.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosOrderedMegaRecord.java b/altoslib/AltosOrderedMegaRecord.java index 3aaf7b5b..b20a5bbd 100644 --- a/altoslib/AltosOrderedMegaRecord.java +++ b/altoslib/AltosOrderedMegaRecord.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.ParseException; diff --git a/altoslib/AltosOrderedRecord.java b/altoslib/AltosOrderedRecord.java index b4cfd8f2..63507d39 100644 --- a/altoslib/AltosOrderedRecord.java +++ b/altoslib/AltosOrderedRecord.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.ParseException; diff --git a/altoslib/AltosParse.java b/altoslib/AltosParse.java index e938a177..66bbeed5 100644 --- a/altoslib/AltosParse.java +++ b/altoslib/AltosParse.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*; diff --git a/altoslib/AltosPreferences.java b/altoslib/AltosPreferences.java index e50b9b5c..392497ef 100644 --- a/altoslib/AltosPreferences.java +++ b/altoslib/AltosPreferences.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosPreferencesBackend.java b/altoslib/AltosPreferencesBackend.java index a1184c0b..fb8a235a 100644 --- a/altoslib/AltosPreferencesBackend.java +++ b/altoslib/AltosPreferencesBackend.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.io.File; diff --git a/altoslib/AltosPyro.java b/altoslib/AltosPyro.java index 14051169..4dbb4223 100644 --- a/altoslib/AltosPyro.java +++ b/altoslib/AltosPyro.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.util.*;  import java.text.*; diff --git a/altoslib/AltosRecord.java b/altoslib/AltosRecord.java index 2c4b6fa5..f8c44cc5 100644 --- a/altoslib/AltosRecord.java +++ b/altoslib/AltosRecord.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public abstract class AltosRecord implements Comparable <AltosRecord>, Cloneable { diff --git a/altoslib/AltosRecordCompanion.java b/altoslib/AltosRecordCompanion.java index c8cc6cac..b153fb5b 100644 --- a/altoslib/AltosRecordCompanion.java +++ b/altoslib/AltosRecordCompanion.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosRecordCompanion {  	public final static int	board_id_telescience = 0x0a; diff --git a/altoslib/AltosRecordIterable.java b/altoslib/AltosRecordIterable.java index ed1787ed..62dbdfe3 100644 --- a/altoslib/AltosRecordIterable.java +++ b/altoslib/AltosRecordIterable.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosRecordMM.java b/altoslib/AltosRecordMM.java index 546f3055..bf64192c 100644 --- a/altoslib/AltosRecordMM.java +++ b/altoslib/AltosRecordMM.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosRecordMM extends AltosRecord { diff --git a/altoslib/AltosRecordNone.java b/altoslib/AltosRecordNone.java index d4ea305f..a95b6a9c 100644 --- a/altoslib/AltosRecordNone.java +++ b/altoslib/AltosRecordNone.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosRecordNone extends AltosRecord { diff --git a/altoslib/AltosRecordTM.java b/altoslib/AltosRecordTM.java index f6ed4966..c6cf3646 100644 --- a/altoslib/AltosRecordTM.java +++ b/altoslib/AltosRecordTM.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosRecordTM extends AltosRecord { diff --git a/altoslib/AltosReplayReader.java b/altoslib/AltosReplayReader.java index 50bef07a..a7e30370 100644 --- a/altoslib/AltosReplayReader.java +++ b/altoslib/AltosReplayReader.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosSensorMM.java b/altoslib/AltosSensorMM.java index b6f21ef0..8372d047 100644 --- a/altoslib/AltosSensorMM.java +++ b/altoslib/AltosSensorMM.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSensorTM.java b/altoslib/AltosSensorTM.java index 75158cbf..f5fa83a5 100644 --- a/altoslib/AltosSensorTM.java +++ b/altoslib/AltosSensorTM.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSpeed.java b/altoslib/AltosSpeed.java index 4e2daf5a..6fb624fb 100644 --- a/altoslib/AltosSpeed.java +++ b/altoslib/AltosSpeed.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosSpeed extends AltosUnits { @@ -37,7 +37,7 @@ public class AltosSpeed extends AltosUnits {  		return "meters per second";  	} -	int show_fraction(int width) { +	public int show_fraction(int width) {  		return width / 9;  	}  }
\ No newline at end of file diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 4f59c840..32d02f21 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -19,7 +19,7 @@   * Track flight state from telemetry or eeprom data stream   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosState {  	public AltosRecord data; diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index 15534158..e7322349 100644 --- a/altoslib/AltosTelemetry.java +++ b/altoslib/AltosTelemetry.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*; diff --git a/altoslib/AltosTelemetryIterable.java b/altoslib/AltosTelemetryIterable.java index e95c15e0..57033638 100644 --- a/altoslib/AltosTelemetryIterable.java +++ b/altoslib/AltosTelemetryIterable.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.io.*;  import java.util.*; diff --git a/altoslib/AltosTelemetryMap.java b/altoslib/AltosTelemetryMap.java index bc1486d8..7cca98b0 100644 --- a/altoslib/AltosTelemetryMap.java +++ b/altoslib/AltosTelemetryMap.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*;  import java.util.HashMap; diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index 94fa560b..f365b821 100644 --- a/altoslib/AltosTelemetryReader.java +++ b/altoslib/AltosTelemetryReader.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*;  import java.io.*; diff --git a/altoslib/AltosTelemetryRecord.java b/altoslib/AltosTelemetryRecord.java index 6a8cfd35..01215968 100644 --- a/altoslib/AltosTelemetryRecord.java +++ b/altoslib/AltosTelemetryRecord.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*;  public abstract class AltosTelemetryRecord { diff --git a/altoslib/AltosTelemetryRecordCompanion.java b/altoslib/AltosTelemetryRecordCompanion.java index 6ad17244..e016dd01 100644 --- a/altoslib/AltosTelemetryRecordCompanion.java +++ b/altoslib/AltosTelemetryRecordCompanion.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosTelemetryRecordCompanion extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordConfiguration.java b/altoslib/AltosTelemetryRecordConfiguration.java index 25242edc..472a6318 100644 --- a/altoslib/AltosTelemetryRecordConfiguration.java +++ b/altoslib/AltosTelemetryRecordConfiguration.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosTelemetryRecordConfiguration extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordGeneral.java b/altoslib/AltosTelemetryRecordGeneral.java index a53280cf..08cd6065 100644 --- a/altoslib/AltosTelemetryRecordGeneral.java +++ b/altoslib/AltosTelemetryRecordGeneral.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*; diff --git a/altoslib/AltosTelemetryRecordLegacy.java b/altoslib/AltosTelemetryRecordLegacy.java index 43189794..a734b188 100644 --- a/altoslib/AltosTelemetryRecordLegacy.java +++ b/altoslib/AltosTelemetryRecordLegacy.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  import java.text.*; diff --git a/altoslib/AltosTelemetryRecordLocation.java b/altoslib/AltosTelemetryRecordLocation.java index cddb773d..469a5400 100644 --- a/altoslib/AltosTelemetryRecordLocation.java +++ b/altoslib/AltosTelemetryRecordLocation.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosTelemetryRecordLocation extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordMegaData.java b/altoslib/AltosTelemetryRecordMegaData.java index 98b9f4c5..08df9ee1 100644 --- a/altoslib/AltosTelemetryRecordMegaData.java +++ b/altoslib/AltosTelemetryRecordMegaData.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosTelemetryRecordMegaData extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordMegaSensor.java b/altoslib/AltosTelemetryRecordMegaSensor.java index 93c001de..7548d699 100644 --- a/altoslib/AltosTelemetryRecordMegaSensor.java +++ b/altoslib/AltosTelemetryRecordMegaSensor.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosTelemetryRecordMegaSensor extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordRaw.java b/altoslib/AltosTelemetryRecordRaw.java index 51dd704d..a06348c1 100644 --- a/altoslib/AltosTelemetryRecordRaw.java +++ b/altoslib/AltosTelemetryRecordRaw.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosTelemetryRecordRaw extends AltosTelemetryRecord {  	int[]	bytes; diff --git a/altoslib/AltosTelemetryRecordSatellite.java b/altoslib/AltosTelemetryRecordSatellite.java index 2526afb6..3e93b337 100644 --- a/altoslib/AltosTelemetryRecordSatellite.java +++ b/altoslib/AltosTelemetryRecordSatellite.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosTelemetryRecordSatellite extends AltosTelemetryRecordRaw {  	int		channels; diff --git a/altoslib/AltosTelemetryRecordSensor.java b/altoslib/AltosTelemetryRecordSensor.java index f1fc156c..767a464a 100644 --- a/altoslib/AltosTelemetryRecordSensor.java +++ b/altoslib/AltosTelemetryRecordSensor.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTemperature.java b/altoslib/AltosTemperature.java new file mode 100644 index 00000000..2749eac0 --- /dev/null +++ b/altoslib/AltosTemperature.java @@ -0,0 +1,43 @@ +/* + * 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.altoslib_1; + +public class AltosTemperature extends AltosUnits { + +	public double value(double v) { +		if (AltosConvert.imperial_units) +			return AltosConvert.c_to_f(v); +		return v; +	} + +	public String show_units() { +		if (AltosConvert.imperial_units) +			return "°F"; +		return "°C"; +	} + +	public String say_units() { +		if (AltosConvert.imperial_units) +			return "degrees farenheit"; +		return "degrees celsius"; +	} + +	public int show_fraction(int width) { +		return width / 3; +	} +} diff --git a/altoslib/AltosUnits.java b/altoslib/AltosUnits.java index 47540c61..b8b3254c 100644 --- a/altoslib/AltosUnits.java +++ b/altoslib/AltosUnits.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public abstract class AltosUnits { @@ -25,7 +25,7 @@ public abstract class AltosUnits {  	public abstract String say_units(); -	abstract int show_fraction(int width); +	public abstract int show_fraction(int width);  	int say_fraction() {  		return 0; @@ -43,6 +43,10 @@ public abstract class AltosUnits {  		return String.format("%%1.%df %s", say_fraction(), say_units());  	} +	public String graph_format(int width) { +		return String.format(String.format("%%%d.%df", width, show_fraction(width)), 0.0); +	} +  	public String show(int width, double v) {  		return String.format(show_format(width), value(v));  	} diff --git a/altoslib/AltosUnitsListener.java b/altoslib/AltosUnitsListener.java index 50a00cdf..61a181a4 100644 --- a/altoslib/AltosUnitsListener.java +++ b/altoslib/AltosUnitsListener.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.AltosLib; +package org.altusmetrum.altoslib_1;  public interface AltosUnitsListener {  	public void units_changed(boolean imperial_units); diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 1b03c925..8e5701ad 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -2,99 +2,101 @@ AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation  JAVAROOT=bin +VERSION=1 +  CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH="bin:$(FREETTS)/*:/usr/share/java/*"  SRC=. -BIN=bin/org/altusmetrum/AltosLib -AltosLibdir = $(datadir)/java +altoslibdir = $(datadir)/java -AltosLib_JAVA = \ -	$(SRC)/AltosLib.java \ -	$(SRC)/AltosConfigData.java \ -	$(SRC)/AltosConfigValues.java \ -	$(SRC)/AltosConvert.java \ -	$(SRC)/AltosCRCException.java \ -	$(SRC)/AltosEepromChunk.java \ -	$(SRC)/AltosEepromIterable.java \ -	$(SRC)/AltosEepromLog.java \ -	$(SRC)/AltosEepromMega.java \ -	$(SRC)/AltosEepromMegaIterable.java \ -	$(SRC)/AltosEepromRecord.java \ -	$(SRC)/AltosEepromTeleScience.java \ -	$(SRC)/AltosFile.java \ -	$(SRC)/AltosFlightReader.java \ -	$(SRC)/AltosFrequency.java \ -	$(SRC)/AltosGPS.java \ -	$(SRC)/AltosGPSQuery.java \ -	$(SRC)/AltosGPSSat.java \ -	$(SRC)/AltosGreatCircle.java \ -	$(SRC)/AltosIdleMonitor.java \ -	$(SRC)/AltosIdleMonitorListener.java \ -	$(SRC)/AltosIgnite.java \ -	$(SRC)/AltosIMU.java \ -	$(SRC)/AltosIMUQuery.java \ -	$(SRC)/AltosLine.java \ -	$(SRC)/AltosLink.java \ -	$(SRC)/AltosLog.java \ -	$(SRC)/AltosMs5607.java \ -	$(SRC)/AltosMs5607Query.java \ -	$(SRC)/AltosOrderedRecord.java \ -	$(SRC)/AltosOrderedMegaRecord.java \ -	$(SRC)/AltosParse.java \ -	$(SRC)/AltosPreferences.java \ -	$(SRC)/AltosPreferencesBackend.java \ -	$(SRC)/AltosRecordCompanion.java \ -	$(SRC)/AltosRecordIterable.java \ -	$(SRC)/AltosRecord.java \ -	$(SRC)/AltosRecordNone.java \ -	$(SRC)/AltosRecordTM.java \ -	$(SRC)/AltosRecordMM.java \ -	$(SRC)/AltosReplayReader.java \ -	$(SRC)/AltosSensorMM.java \ -	$(SRC)/AltosSensorTM.java \ -	$(SRC)/AltosState.java \ -	$(SRC)/AltosTelemetry.java \ -	$(SRC)/AltosTelemetryIterable.java \ -	$(SRC)/AltosTelemetryMap.java \ -	$(SRC)/AltosTelemetryReader.java \ -	$(SRC)/AltosTelemetryRecordCompanion.java \ -	$(SRC)/AltosTelemetryRecordConfiguration.java \ -	$(SRC)/AltosTelemetryRecordGeneral.java \ -	$(SRC)/AltosTelemetryRecord.java \ -	$(SRC)/AltosTelemetryRecordLegacy.java \ -	$(SRC)/AltosTelemetryRecordLocation.java \ -	$(SRC)/AltosTelemetryRecordRaw.java \ -	$(SRC)/AltosTelemetryRecordSatellite.java \ -	$(SRC)/AltosTelemetryRecordSensor.java \ -	$(SRC)/AltosTelemetryRecordMegaSensor.java \ -	$(SRC)/AltosTelemetryRecordMegaData.java \ -	$(SRC)/AltosUnitsListener.java \ -	$(SRC)/AltosMs5607.java \ -	$(SRC)/AltosIMU.java \ -	$(SRC)/AltosMag.java \ -	$(SRC)/AltosUnits.java \ -	$(SRC)/AltosDistance.java \ -	$(SRC)/AltosHeight.java \ -	$(SRC)/AltosSpeed.java \ -	$(SRC)/AltosAccel.java \ -	$(SRC)/AltosPyro.java +altoslib_JAVA = \ +	AltosLib.java \ +	AltosConfigData.java \ +	AltosConfigValues.java \ +	AltosConvert.java \ +	AltosCRCException.java \ +	AltosEepromChunk.java \ +	AltosEepromIterable.java \ +	AltosEepromLog.java \ +	AltosEepromMega.java \ +	AltosEepromMegaIterable.java \ +	AltosEepromRecord.java \ +	AltosEepromTeleScience.java \ +	AltosFile.java \ +	AltosFlightReader.java \ +	AltosFrequency.java \ +	AltosGPS.java \ +	AltosGPSQuery.java \ +	AltosGPSSat.java \ +	AltosGreatCircle.java \ +	AltosIdleMonitor.java \ +	AltosIdleMonitorListener.java \ +	AltosIgnite.java \ +	AltosIMU.java \ +	AltosIMUQuery.java \ +	AltosLine.java \ +	AltosLink.java \ +	AltosLog.java \ +	AltosMs5607.java \ +	AltosMs5607Query.java \ +	AltosOrderedRecord.java \ +	AltosOrderedMegaRecord.java \ +	AltosParse.java \ +	AltosPreferences.java \ +	AltosPreferencesBackend.java \ +	AltosRecordCompanion.java \ +	AltosRecordIterable.java \ +	AltosRecord.java \ +	AltosRecordNone.java \ +	AltosRecordTM.java \ +	AltosRecordMM.java \ +	AltosReplayReader.java \ +	AltosSensorMM.java \ +	AltosSensorTM.java \ +	AltosState.java \ +	AltosTelemetry.java \ +	AltosTelemetryIterable.java \ +	AltosTelemetryMap.java \ +	AltosTelemetryReader.java \ +	AltosTelemetryRecordCompanion.java \ +	AltosTelemetryRecordConfiguration.java \ +	AltosTelemetryRecordGeneral.java \ +	AltosTelemetryRecord.java \ +	AltosTelemetryRecordLegacy.java \ +	AltosTelemetryRecordLocation.java \ +	AltosTelemetryRecordRaw.java \ +	AltosTelemetryRecordSatellite.java \ +	AltosTelemetryRecordSensor.java \ +	AltosTelemetryRecordMegaSensor.java \ +	AltosTelemetryRecordMegaData.java \ +	AltosUnitsListener.java \ +	AltosMs5607.java \ +	AltosIMU.java \ +	AltosMag.java \ +	AltosUnits.java \ +	AltosDistance.java \ +	AltosHeight.java \ +	AltosSpeed.java \ +	AltosTemperature.java \ +	AltosAccel.java \ +	AltosPyro.java -JAR=AltosLib.jar +JAR=altoslib_$(ALTOSLIB_VERSION).jar  all-local: $(JAR)  clean-local:  	-rm -rf bin $(JAR) -install-AltosLibJAVA: $(JAR) +install-altoslibJAVA: $(JAR)  	@$(NORMAL_INSTALL) -	test -z "$(AltosLibdir)" || $(MKDIR_P) "$(DESTDIR)$(AltosLibdir)" -	echo " $(INSTALL_DATA)" "$<" "'$(DESTDIR)$(AltosLibdir)/$(JAR)"; \ -	$(INSTALL_DATA) "$<" "$(DESTDIR)$(AltosLibdir)" +	test -z "$(altoslibdir)" || $(MKDIR_P) "$(DESTDIR)$(altoslibdir)" +	echo " $(INSTALL_DATA)" "$<" "'$(DESTDIR)$(altoslibdir)/$(JAR)"; \ +	$(INSTALL_DATA) "$<" "$(DESTDIR)$(altoslibdir)"  bin:  	mkdir -p bin -$(JAR): classAltosLib.stamp +$(JAR): classaltoslib.stamp  	jar cf $@ -C bin org diff --git a/altosui/Altos.java b/altosui/Altos.java index 98af26bc..d25736bf 100644 --- a/altosui/Altos.java +++ b/altosui/Altos.java @@ -20,74 +20,9 @@ package altosui;  import java.awt.*;  import libaltosJNI.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*; -public class Altos extends AltosLib { +public class Altos extends AltosUILib { -	static final int tab_elt_pad = 5; - -	static Font label_font; -	static Font value_font; -	static Font status_font; -	static Font table_label_font; -	static Font table_value_font; - -	final static int font_size_small = 1; -	final static int font_size_medium = 2; -	final static int font_size_large = 3; - -	static void set_fonts(int size) { -		int	brief_size; -		int	table_size; -		int	status_size; - -		switch (size) { -		case font_size_small: -			brief_size = 16; -			status_size = 18; -			table_size = 11; -			break; -		default: -		case font_size_medium: -			brief_size = 22; -			status_size = 24; -			table_size = 14; -			break; -		case font_size_large: -			brief_size = 26; -			status_size = 30; -			table_size = 17; -			break; -		} -		label_font = new Font("Dialog", Font.PLAIN, brief_size); -		value_font = new Font("Monospaced", Font.PLAIN, brief_size); -		status_font = new Font("SansSerif", Font.BOLD, status_size); -		table_label_font = new Font("SansSerif", Font.PLAIN, table_size); -		table_value_font = new Font("Monospaced", Font.PLAIN, table_size); -	} - -	static final int text_width = 20; - -	static public boolean initialized = false; -	static public 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; -	}  } diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index a05c4404..e90e0e23 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -19,7 +19,7 @@ package altosui;  import java.awt.*;  import javax.swing.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosAscent extends JComponent implements AltosFlightDisplay {  	GridBagLayout	layout; diff --git a/altosui/AltosBTDevice.java b/altosui/AltosBTDevice.java index 222b3c97..727a9f66 100644 --- a/altosui/AltosBTDevice.java +++ b/altosui/AltosBTDevice.java @@ -17,7 +17,7 @@  package altosui;  import libaltosJNI.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosBTDevice extends altos_bt_device implements AltosDevice { diff --git a/altosui/AltosBTKnown.java b/altosui/AltosBTKnown.java index 606c0349..1d42365b 100644 --- a/altosui/AltosBTKnown.java +++ b/altosui/AltosBTKnown.java @@ -17,8 +17,8 @@  package altosui;  import java.util.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosBTKnown implements Iterable<AltosBTDevice> {  	LinkedList<AltosBTDevice>	devices = new LinkedList<AltosBTDevice>(); diff --git a/altosui/AltosBTManage.java b/altosui/AltosBTManage.java index b7b632a7..4c9b7a6c 100644 --- a/altosui/AltosBTManage.java +++ b/altosui/AltosBTManage.java @@ -23,7 +23,7 @@ import javax.swing.*;  import javax.swing.plaf.basic.*;  import java.util.*;  import java.util.concurrent.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosBTManage extends AltosUIDialog implements ActionListener, Iterable<AltosBTDevice> {  	LinkedBlockingQueue<AltosBTDevice> found_devices; diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java index 1c929a7c..0676f99d 100644 --- a/altosui/AltosCSV.java +++ b/altosui/AltosCSV.java @@ -19,7 +19,7 @@ package altosui;  import java.io.*;  import java.util.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosCSV implements AltosWriter {  	File			name; diff --git a/altosui/AltosCSVUI.java b/altosui/AltosCSVUI.java index 83bf16a7..42508346 100644 --- a/altosui/AltosCSVUI.java +++ b/altosui/AltosCSVUI.java @@ -21,8 +21,8 @@ import java.awt.*;  import java.awt.event.*;  import javax.swing.*;  import java.io.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosCSVUI  	extends AltosUIDialog diff --git a/altosui/AltosCompanionInfo.java b/altosui/AltosCompanionInfo.java index f2019438..7dd36aec 100644 --- a/altosui/AltosCompanionInfo.java +++ b/altosui/AltosCompanionInfo.java @@ -19,7 +19,7 @@ package altosui;  import java.awt.*;  import javax.swing.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosCompanionInfo extends JTable {  	private AltosFlightInfoTableModel model; diff --git a/altosui/AltosConfig.java b/altosui/AltosConfig.java index 1cd61a89..4927d3f8 100644 --- a/altosui/AltosConfig.java +++ b/altosui/AltosConfig.java @@ -22,8 +22,8 @@ import javax.swing.*;  import java.io.*;  import java.util.concurrent.*;  import java.text.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosConfig implements ActionListener { diff --git a/altosui/AltosConfigFreqUI.java b/altosui/AltosConfigFreqUI.java index 75101e3d..c90b168f 100644 --- a/altosui/AltosConfigFreqUI.java +++ b/altosui/AltosConfigFreqUI.java @@ -21,8 +21,8 @@ import java.awt.*;  import java.awt.event.*;  import javax.swing.*;  import java.util.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  class AltosEditFreqUI extends AltosUIDialog implements ActionListener {  	Frame		frame; diff --git a/altosui/AltosConfigPyroUI.java b/altosui/AltosConfigPyroUI.java index 5cdaf564..3cac56c3 100644 --- a/altosui/AltosConfigPyroUI.java +++ b/altosui/AltosConfigPyroUI.java @@ -21,8 +21,8 @@ import java.awt.*;  import java.awt.event.*;  import javax.swing.*;  import javax.swing.event.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosConfigPyroUI  	extends AltosUIDialog diff --git a/altosui/AltosConfigTD.java b/altosui/AltosConfigTD.java index 794f8103..16c9e357 100644 --- a/altosui/AltosConfigTD.java +++ b/altosui/AltosConfigTD.java @@ -21,8 +21,8 @@ import java.awt.event.*;  import javax.swing.*;  import java.io.*;  import java.util.concurrent.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosConfigTD implements ActionListener { diff --git a/altosui/AltosConfigTDUI.java b/altosui/AltosConfigTDUI.java index 54073843..125780a9 100644 --- a/altosui/AltosConfigTDUI.java +++ b/altosui/AltosConfigTDUI.java @@ -21,8 +21,8 @@ import java.awt.*;  import java.awt.event.*;  import javax.swing.*;  import javax.swing.event.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosConfigTDUI  	extends AltosUIDialog diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index 599ed051..4fd0647e 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -21,8 +21,8 @@ import java.awt.*;  import java.awt.event.*;  import javax.swing.*;  import javax.swing.event.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosConfigUI  	extends AltosUIDialog diff --git a/altosui/AltosConfigureUI.java b/altosui/AltosConfigureUI.java index 0e411b03..5e42f430 100644 --- a/altosui/AltosConfigureUI.java +++ b/altosui/AltosConfigureUI.java @@ -22,7 +22,7 @@ import java.awt.event.*;  import java.beans.*;  import javax.swing.*;  import javax.swing.event.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosConfigureUI  	extends AltosUIConfigure @@ -31,6 +31,7 @@ public class AltosConfigureUI  	AltosVoice	voice;  	public JTextField	callsign_value; +	public JComboBox	position_value;  	/* DocumentListener interface methods */  	public void insertUpdate(DocumentEvent e) { @@ -42,7 +43,7 @@ public class AltosConfigureUI  	}  	public void changedUpdate(DocumentEvent e) { -		if (callsign_value != null)  +		if (callsign_value != null)  			AltosUIPreferences.set_callsign(callsign_value.getText());  	} @@ -81,7 +82,7 @@ public class AltosConfigureUI  		/* Callsign setting */  		pane.add(new JLabel("Callsign"), constraints(0, 1)); -		JTextField callsign_value = new JTextField(AltosUIPreferences.callsign()); +		callsign_value = new JTextField(AltosUIPreferences.callsign());  		callsign_value.getDocument().addDocumentListener(this);  		callsign_value.setToolTipText("Callsign sent in packet mode");  		pane.add(callsign_value, constraints(1, 2, GridBagConstraints.BOTH)); @@ -111,6 +112,36 @@ public class AltosConfigureUI  		row++;  	} +	final static String[] position_names = { +		"Top left", +		"Top", +		"Top right", +		"Left", +		"Center", +		"Right", +		"Bottom left", +		"Bottom", +		"Bottom right", +	}; +		 +	public void add_position() { +		pane.add(new JLabel ("Menu position"), constraints(0, 1)); +		 +		position_value = new JComboBox (position_names); +		position_value.setMaximumRowCount(position_names.length); +		int position = AltosUIPreferences.position(); +		position_value.setSelectedIndex(position); +		position_value.addActionListener(new ActionListener() { +				public void actionPerformed(ActionEvent e) { +					int	position = position_value.getSelectedIndex(); +					AltosUIPreferences.set_position(position); +				} +			}); +		pane.add(position_value, constraints(1, 2, GridBagConstraints.BOTH)); +		position_value.setToolTipText("Position of main AltosUI window"); +		row++; +	} +  	public AltosConfigureUI(JFrame owner, AltosVoice voice) {  		super(owner); diff --git a/altosui/AltosDataChooser.java b/altosui/AltosDataChooser.java index a8a2ca49..7de18afb 100644 --- a/altosui/AltosDataChooser.java +++ b/altosui/AltosDataChooser.java @@ -20,7 +20,8 @@ package altosui;  import javax.swing.*;  import javax.swing.filechooser.FileNameExtensionFilter;  import java.io.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosDataChooser extends JFileChooser {  	JFrame	frame; diff --git a/altosui/AltosDataPoint.java b/altosui/AltosDataPoint.java deleted file mode 100644 index 4956e9f3..00000000 --- a/altosui/AltosDataPoint.java +++ /dev/null @@ -1,27 +0,0 @@ - -// Copyright (c) 2010 Anthony Towns -// GPL v2 or later - -package altosui; - -interface AltosDataPoint { -    int version(); -    int serial(); -    int flight(); -    String callsign(); -    double time(); -    double rssi(); - -    int state(); -    String state_name(); - -    double acceleration(); -    double height(); -    double speed(); -    double temperature(); -    double battery_voltage(); -    double drogue_voltage(); -    double main_voltage(); -    boolean has_accel(); -} - diff --git a/altosui/AltosDataPointReader.java b/altosui/AltosDataPointReader.java deleted file mode 100644 index 88df081f..00000000 --- a/altosui/AltosDataPointReader.java +++ /dev/null @@ -1,79 +0,0 @@ - -// Copyright (c) 2010 Anthony Towns -// GPL v2 or later - -package altosui; - -import java.lang.UnsupportedOperationException; -import java.util.NoSuchElementException; -import java.util.Iterator; -import org.altusmetrum.AltosLib.*; - -class AltosDataPointReader implements Iterable<AltosDataPoint> { -    Iterator<AltosRecord> iter; -    AltosState state; -    boolean has_gps; -    boolean has_accel; -    boolean has_ignite; - -    final static int MISSING = AltosRecord.MISSING; - -    public AltosDataPointReader(AltosRecordIterable reader) { -        this.iter = reader.iterator(); -        this.state = null; -	has_accel = true; -	has_gps = reader.has_gps(); -	has_ignite = reader.has_ignite(); -    } - -    private void read_next_record()  -        throws NoSuchElementException -    { -        state = new AltosState(iter.next(), state); -    } - -    private AltosDataPoint current_dp() { -        assert this.state != null; -         -        return new AltosDataPoint() { -            public int version() { return state.data.version; } -            public int serial() { return state.data.serial; } -            public int flight() { return state.data.flight; } -            public String callsign() { return state.data.callsign; } -            public double time() { return state.data.time; } -            public double rssi() { return state.data.rssi; } - -            public int state() { return state.state; } -            public String state_name() { return state.data.state(); } - -            public double acceleration() { return state.acceleration; } -	    public double height() { return state.height; } -	    public double speed() { return state.speed(); } -            public double temperature() { return state.temperature; } -            public double battery_voltage() { return state.battery; } -            public double drogue_voltage() { return state.drogue_sense; } -            public double main_voltage() { return state.main_sense; } -	    public boolean has_accel() { return true; } // return state.acceleration != AltosRecord.MISSING; } -        }; -    } - -    public Iterator<AltosDataPoint> iterator() { -        return new Iterator<AltosDataPoint>() { -            public void remove() {  -                throw new UnsupportedOperationException();  -            } -            public boolean hasNext() { -		if (state != null && state.state == Altos.ao_flight_landed) -		    return false; -                return iter.hasNext(); -            } -            public AltosDataPoint next() { -		do { -		    read_next_record(); -		} while (state.data.time < -1.0 && hasNext()); -                return current_dp(); -            } -        }; -    } -} - diff --git a/altosui/AltosDebug.java b/altosui/AltosDebug.java index 482f4c36..c69369ef 100644 --- a/altosui/AltosDebug.java +++ b/altosui/AltosDebug.java @@ -18,7 +18,7 @@  package altosui;  import java.io.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosDebug extends AltosSerial { diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index 2ea7cbfa..821e3963 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -19,7 +19,7 @@ package altosui;  import java.awt.*;  import javax.swing.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosDescent extends JComponent implements AltosFlightDisplay {  	GridBagLayout	layout; diff --git a/altosui/AltosDeviceUIDialog.java b/altosui/AltosDeviceUIDialog.java index 7ed599a3..ceabe843 100644 --- a/altosui/AltosDeviceUIDialog.java +++ b/altosui/AltosDeviceUIDialog.java @@ -20,7 +20,7 @@ package altosui;  import javax.swing.*;  import java.awt.*;  import java.awt.event.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosDeviceUIDialog extends AltosDeviceDialog { diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index 1ba70c7e..6f8aa9ee 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -21,7 +21,7 @@ import java.awt.*;  import javax.swing.*;  import java.io.*;  import java.text.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosDisplayThread extends Thread { diff --git a/altosui/AltosEepromDelete.java b/altosui/AltosEepromDelete.java index b0459bb6..e81a35d1 100644 --- a/altosui/AltosEepromDelete.java +++ b/altosui/AltosEepromDelete.java @@ -21,7 +21,7 @@ import java.awt.event.*;  import javax.swing.*;  import java.io.*;  import java.util.concurrent.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosEepromDelete implements Runnable {  	AltosEepromList		flights; diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 21b46740..801d4ec0 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -23,7 +23,7 @@ import java.io.*;  import java.util.*;  import java.text.*;  import java.util.concurrent.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosEepromDownload implements Runnable { @@ -331,7 +331,7 @@ public class AltosEepromDownload implements Runnable {  		state = 0; state_block = log.start_block;  		for (block = log.start_block; !done && block < log.end_block; block++) { -			monitor.set_value(AltosLib.state_name(state), state, block - state_block); +			monitor.set_value(AltosLib.state_name(state), state, block - state_block, block - log.start_block);  			AltosEepromChunk	eechunk = new AltosEepromChunk(serial_line, block, block == log.start_block); diff --git a/altosui/AltosEepromList.java b/altosui/AltosEepromList.java index f9bd2748..a63d173d 100644 --- a/altosui/AltosEepromList.java +++ b/altosui/AltosEepromList.java @@ -21,7 +21,7 @@ import java.io.*;  import java.util.*;  import java.text.*;  import java.util.concurrent.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  /*   * Temporary structure to hold the list of stored flights; diff --git a/altosui/AltosEepromManage.java b/altosui/AltosEepromManage.java index cc9adb0c..7a721196 100644 --- a/altosui/AltosEepromManage.java +++ b/altosui/AltosEepromManage.java @@ -21,8 +21,8 @@ import java.awt.event.*;  import javax.swing.*;  import java.io.*;  import java.util.concurrent.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosEepromManage implements ActionListener { @@ -45,6 +45,15 @@ public class AltosEepromManage implements ActionListener {  		}  	} +	private int countDeletedFlights() { +		int count = 0; +		for (AltosEepromLog flight : flights) { +			if (flight.selected) +				count++; +		} +		return count; +	} +  	private String showDeletedFlights() {  		String	result = ""; @@ -94,7 +103,8 @@ public class AltosEepromManage implements ActionListener {  		} else if (cmd.equals("delete")) {  			if (success) {  				JOptionPane.showMessageDialog(frame, -							      String.format("Flights erased: %s", +							      String.format("%d flights erased: %s", +									    countDeletedFlights(),  									    showDeletedFlights()),  							      serial_line.device.toShortString(),  							      JOptionPane.INFORMATION_MESSAGE); diff --git a/altosui/AltosEepromMonitor.java b/altosui/AltosEepromMonitor.java index 8eae5eb8..50921da1 100644 --- a/altosui/AltosEepromMonitor.java +++ b/altosui/AltosEepromMonitor.java @@ -20,7 +20,7 @@ package altosui;  import java.awt.*;  import java.awt.event.*;  import javax.swing.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosEepromMonitor extends AltosUIDialog { @@ -101,7 +101,7 @@ public class AltosEepromMonitor extends AltosUIDialog {  		max_state = in_max_state;  		pbar = new JProgressBar();  		pbar.setMinimum(0); -		pbar.setMaximum((max_state - min_state) * 100); +		pbar.setMaximum(1000);  		pbar.setValue(0);  		pbar.setString("startup");  		pbar.setStringPainted(true); @@ -135,30 +135,28 @@ public class AltosEepromMonitor extends AltosUIDialog {  		cancel.addActionListener(l);  	} -	private void set_value_internal(String state_name, int in_state, int in_block) { -		int block = in_block; -		int state = in_state; - -		if (block > 100) -			block = 100; +	private void set_value_internal(String state_name, int state, int state_block, int block) { +		if (state_block > 100) +			state_block = 100;  		if (state < min_state) state = min_state;  		if (state >= max_state) state = max_state - 1;  		state -= min_state; -		int pos = state * 100 + block; +		int pos = state * 100 + state_block; -		pbar.setString(state_name); +		pbar.setString(String.format("block %d state %s", block, state_name));  		pbar.setValue(pos);  	} -	public void set_value(String in_state_name, int in_state, int in_block) { +	public void set_value(String in_state_name, int in_state, int in_state_block, int in_block) {  		final String state_name = in_state_name;  		final int state = in_state; +		final int state_block = in_state_block;  		final int block = in_block;  		Runnable r = new Runnable() {  				public void run() {  					try { -						set_value_internal(state_name, state, block); +						set_value_internal(state_name, state, state_block, block);  					} catch (Exception ex) {  					}  				} @@ -235,7 +233,7 @@ public class AltosEepromMonitor extends AltosUIDialog {  	}  	private void reset_internal() { -		set_value_internal("startup",min_state,0); +		set_value_internal("startup",min_state,0, 0);  		set_flight_internal(0);  		set_file_internal("");  	} diff --git a/altosui/AltosEepromSelect.java b/altosui/AltosEepromSelect.java index c0886212..a451aa3a 100644 --- a/altosui/AltosEepromSelect.java +++ b/altosui/AltosEepromSelect.java @@ -21,8 +21,8 @@ import javax.swing.*;  import javax.swing.border.*;  import java.awt.*;  import java.awt.event.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  class AltosEepromItem implements ActionListener {  	AltosEepromLog	log; diff --git a/altosui/AltosFlash.java b/altosui/AltosFlash.java index 7a98ee14..239d4dd7 100644 --- a/altosui/AltosFlash.java +++ b/altosui/AltosFlash.java @@ -20,7 +20,7 @@ package altosui;  import java.awt.event.*;  import javax.swing.*;  import java.io.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosFlash {  	File		file; diff --git a/altosui/AltosFlashUI.java b/altosui/AltosFlashUI.java index 921207bc..f26a3916 100644 --- a/altosui/AltosFlashUI.java +++ b/altosui/AltosFlashUI.java @@ -23,7 +23,7 @@ import javax.swing.*;  import javax.swing.filechooser.FileNameExtensionFilter;  import java.io.*;  import java.util.concurrent.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosFlashUI  	extends AltosUIDialog diff --git a/altosui/AltosFlightDisplay.java b/altosui/AltosFlightDisplay.java index 826f9522..d1ed7d2f 100644 --- a/altosui/AltosFlightDisplay.java +++ b/altosui/AltosFlightDisplay.java @@ -17,7 +17,7 @@  package altosui; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public interface AltosFlightDisplay {  	void reset(); diff --git a/altosui/AltosFlightStats.java b/altosui/AltosFlightStats.java index 1653ca57..da06bb3d 100644 --- a/altosui/AltosFlightStats.java +++ b/altosui/AltosFlightStats.java @@ -18,7 +18,7 @@  package altosui;  import java.io.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosFlightStats {  	double		max_height; @@ -34,6 +34,11 @@ public class AltosFlightStats {  	int		flight;  	int		year, month, day;  	int		hour, minute, second; +	double		lat, lon; +	double		pad_lat, pad_lon; +	boolean		has_gps; +	boolean		has_other_adc; +	boolean		has_rssi;  	double landed_time(AltosRecordIterable iterable) {  		AltosState	state = null; @@ -98,11 +103,19 @@ public class AltosFlightStats {  		year = month = day = -1;  		hour = minute = second = -1;  		serial = flight = -1; +		lat = lon = -1; +		has_gps = false; +		has_other_adc = false; +		has_rssi = false;  		for (AltosRecord record : iterable) {  			if (serial < 0)  				serial = record.serial;  			if ((record.seen & AltosRecord.seen_flight) != 0 && flight < 0)  				flight = record.flight; +			if ((record.seen & AltosRecord.seen_temp_volt) != 0) +				has_other_adc = true; +			if (record.rssi != 0) +				has_rssi = true;  			new_state = new AltosState(record, state);  			end_time = new_state.time;  			state = new_state; @@ -137,6 +150,15 @@ public class AltosFlightStats {  					max_speed = state.max_baro_speed;  				max_acceleration = state.max_acceleration;  			} +			if (state.gps.locked && state.gps.nsat >= 4) { +				if (state.state <= Altos.ao_flight_pad) { +					pad_lat = state.gps.lat; +					pad_lon = state.gps.lon; +				} +				lat = state.gps.lat; +				lon = state.gps.lon; +				has_gps = true; +			}  		}  		for (int s = Altos.ao_flight_startup; s <= Altos.ao_flight_landed; s++) {  			if (state_count[s] > 0) { diff --git a/altosui/AltosFlightStatsTable.java b/altosui/AltosFlightStatsTable.java index 1e0b94fa..a35b5f63 100644 --- a/altosui/AltosFlightStatsTable.java +++ b/altosui/AltosFlightStatsTable.java @@ -19,7 +19,7 @@ package altosui;  import java.awt.*;  import javax.swing.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosFlightStatsTable extends JComponent {  	GridBagLayout	layout; @@ -58,6 +58,17 @@ public class AltosFlightStatsTable extends JComponent {  	} +	static String pos(double p, String pos, String neg) { +		String	h = pos; +		if (p < 0) { +			h = neg; +			p = -p; +		} +		int deg = (int) Math.floor(p); +		double min = (p - Math.floor(p)) * 60.0; +		return String.format("%s %4d° %9.6f'", h, deg, min); +	} +  	public AltosFlightStatsTable(AltosFlightStats stats) {  		layout = new GridBagLayout(); @@ -65,12 +76,18 @@ public class AltosFlightStatsTable extends JComponent {  		int y = 0;  		new FlightStat(layout, y++, "Serial", String.format("%d", stats.serial));  		new FlightStat(layout, y++, "Flight", String.format("%d", stats.flight)); -		if (stats.year > 0) -			new FlightStat(layout, y++, "Date", -				       String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day)); -		if (stats.hour > 0) -			new FlightStat(layout, y++, "Time", +		if (stats.year > 0 && stats.hour > 0) +			new FlightStat(layout, y++, "Date/Time", +				       String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day),  				       String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); +		else { +			if (stats.year > 0) +				new FlightStat(layout, y++, "Date", +					       String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day)); +			if (stats.hour > 0) +				new FlightStat(layout, y++, "Time", +					       String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); +		}  		new FlightStat(layout, y++, "Maximum height",  			       String.format("%5.0f m", stats.max_height),  			       String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.max_height))); @@ -94,14 +111,29 @@ public class AltosFlightStatsTable extends JComponent {  		new FlightStat(layout, y++, "Main descent rate",  			       String.format("%5.0f m/s", stats.state_baro_speed[Altos.ao_flight_main]),  			       String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_baro_speed[Altos.ao_flight_main]))); -		for (int s = Altos.ao_flight_boost; s <= Altos.ao_flight_main; s++) { -			new FlightStat(layout, y++, String.format("%s time", AltosLib.state_name_capital(s)), -				       String.format("%6.0f s", stats.state_end[s] - stats.state_start[s])); -		} -		new FlightStat(layout, y++, "Flight Time", -			       String.format("%6.0f s", stats.state_end[Altos.ao_flight_main] - +		new FlightStat(layout, y++, "Ascent time", +			       String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_boost] - stats.state_start[AltosLib.ao_flight_boost], +					     AltosLib.state_name(Altos.ao_flight_boost)), +			       String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_fast] - stats.state_start[AltosLib.ao_flight_fast], +					     AltosLib.state_name(Altos.ao_flight_fast)), +			       String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_coast] - stats.state_start[AltosLib.ao_flight_coast], +					     AltosLib.state_name(Altos.ao_flight_coast))); +		new FlightStat(layout, y++, "Descent time", +			       String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_drogue] - stats.state_start[AltosLib.ao_flight_drogue], +					     AltosLib.state_name(Altos.ao_flight_drogue)), +			       String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_main] - stats.state_start[AltosLib.ao_flight_main], +					     AltosLib.state_name(Altos.ao_flight_main))); +		new FlightStat(layout, y++, "Flight time", +			       String.format("%6.1f s", stats.state_end[Altos.ao_flight_main] -  					     stats.state_start[Altos.ao_flight_boost])); -		 +		if (stats.has_gps) { +			new FlightStat(layout, y++, "Pad location", +				       pos(stats.pad_lat,"N","S"), +				       pos(stats.pad_lon,"E","W")); +			new FlightStat(layout, y++, "Last reported location", +				       pos(stats.lat,"N","S"), +				       pos(stats.lon,"E","W")); +		}  	}  }
\ No newline at end of file diff --git a/altosui/AltosFlightStatus.java b/altosui/AltosFlightStatus.java index b97c8dc6..20539a9f 100644 --- a/altosui/AltosFlightStatus.java +++ b/altosui/AltosFlightStatus.java @@ -19,7 +19,7 @@ package altosui;  import java.awt.*;  import javax.swing.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosFlightStatus extends JComponent implements AltosFlightDisplay {  	GridBagLayout	layout; diff --git a/altosui/AltosFlightStatusTableModel.java b/altosui/AltosFlightStatusTableModel.java index 56ad7e6f..6a327841 100644 --- a/altosui/AltosFlightStatusTableModel.java +++ b/altosui/AltosFlightStatusTableModel.java @@ -27,7 +27,7 @@ import java.util.*;  import java.text.*;  import java.util.prefs.*;  import java.util.concurrent.LinkedBlockingQueue; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosFlightStatusTableModel extends AbstractTableModel {  	private String[] columnNames = { diff --git a/altosui/AltosFlightStatusUpdate.java b/altosui/AltosFlightStatusUpdate.java index bef39e8d..bf679b85 100644 --- a/altosui/AltosFlightStatusUpdate.java +++ b/altosui/AltosFlightStatusUpdate.java @@ -18,7 +18,7 @@  package altosui;  import java.awt.event.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosFlightStatusUpdate implements ActionListener { diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index e2dc06bd..c8faab90 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -21,8 +21,8 @@ import java.awt.*;  import java.awt.event.*;  import javax.swing.*;  import java.util.concurrent.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, AltosFontListener {  	AltosVoice		voice; diff --git a/altosui/AltosFreqList.java b/altosui/AltosFreqList.java index 4edf088c..7464ac3e 100644 --- a/altosui/AltosFreqList.java +++ b/altosui/AltosFreqList.java @@ -18,7 +18,8 @@  package altosui;  import javax.swing.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosFreqList extends JComboBox { diff --git a/altosui/AltosGraph.java b/altosui/AltosGraph.java index fbcefd61..defe69a0 100644 --- a/altosui/AltosGraph.java +++ b/altosui/AltosGraph.java @@ -1,26 +1,221 @@ - -// Copyright (c) 2010 Anthony Towns -// GPL v2 or later +/* + * 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 altosui;  import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*; + +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 AltosVoltage extends AltosUnits { + +	public double value(double v) { +		return v; +	} + +	public String show_units() { +		return "V"; +	} + +	public String say_units() { +		return "volts"; +	} -import org.jfree.chart.JFreeChart; -import org.jfree.chart.ChartUtilities; - -abstract class AltosGraph { -    public String filename; -    public abstract void addData(AltosDataPoint d); -    public abstract JFreeChart createChart(); -    public String title; -    public void toPNG() throws java.io.IOException { toPNG(300, 500); } -    public void toPNG(int width, int height) -        throws java.io.IOException -    { -        File pngout = new File(filename); -        JFreeChart chart = createChart(); -        ChartUtilities.saveChartAsPNG(pngout, chart, width, height); -        System.out.println("Created " + filename); -    } +	public int show_fraction(int width) { +		return width / 2; +	}  } + +class AltosNsat extends AltosUnits { + +	public double value(double v) { +		return v; +	} + +	public String show_units() { +		return "Sats"; +	} + +	public String say_units() { +		return "Satellites"; +	} + +	public int show_fraction(int width) { +		return 0; +	} +} + +class AltosDbm extends AltosUnits { + +	public double value(double v) { +		return v; +	} + +	public String show_units() { +		return "dBm"; +	} + +	public String say_units() { +		return "d b m"; +	} + +	public int show_fraction(int width) { +		return 0; +	} +} + +public class AltosGraph extends AltosUIGraph { + +	static final private Color height_color = new Color(194,31,31); +	static final private Color gps_height_color = new Color(150,31,31); +	static final private Color range_color = new Color(100, 31, 31); +	static final private Color distance_color = new Color(100, 31, 194); +	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 voltage_color = new Color(194, 194, 31); +	static final private Color battery_voltage_color = new Color(194, 194, 31); +	static final private Color drogue_voltage_color = new Color(150, 150, 31); +	static final private Color main_voltage_color = new Color(100, 100, 31); +	static final private Color gps_nsat_color = new Color (194, 31, 194); +	static final private Color gps_nsat_solution_color = new Color (194, 31, 194); +	static final private Color gps_nsat_view_color = new Color (150, 31, 150); +	static final private Color temperature_color = new Color (31, 194, 194); +	static final private Color dbm_color = new Color(31, 100, 100); +	static final private Color state_color = new Color(0,0,0); + +	static AltosVoltage voltage_units = new AltosVoltage(); +	static AltosNsat nsat_units = new AltosNsat(); +	static AltosDbm dbm_units = new AltosDbm(); + +	AltosUIAxis	height_axis, speed_axis, accel_axis, voltage_axis, temperature_axis, nsat_axis, dbm_axis; +	AltosUIAxis	distance_axis; + +	public AltosGraph(AltosUIEnable enable, AltosFlightStats stats, AltosGraphDataSet dataSet) { +		super(enable); + +		height_axis = newAxis("Height", AltosConvert.height, height_color); +		speed_axis = newAxis("Speed", AltosConvert.speed, speed_color); +		accel_axis = newAxis("Acceleration", AltosConvert.accel, accel_color); +		voltage_axis = newAxis("Voltage", voltage_units, voltage_color); +		temperature_axis = newAxis("Temperature", AltosConvert.temperature, temperature_color, 0); +		nsat_axis = newAxis("Satellites", nsat_units, gps_nsat_color, +				    AltosUIAxis.axis_include_zero | AltosUIAxis.axis_integer); +		dbm_axis = newAxis("Signal Strength", dbm_units, dbm_color, 0); +		distance_axis = newAxis("Distance", AltosConvert.distance, range_color); + +		addMarker("State", AltosGraphDataPoint.data_state, state_color); +		addSeries("Height", +			  AltosGraphDataPoint.data_height, +			  AltosConvert.height, +			  height_color, +			  true, +			  height_axis); +		addSeries("Speed", +			  AltosGraphDataPoint.data_speed, +			  AltosConvert.speed, +			  speed_color, +			  true, +			  speed_axis); +		addSeries("Acceleration", +			  AltosGraphDataPoint.data_accel, +			  AltosConvert.accel, +			  accel_color, +			  true, +			  accel_axis); +		if (stats.has_gps) { +			addSeries("Range", +				  AltosGraphDataPoint.data_range, +				  AltosConvert.distance, +				  range_color, +				  false, +				  distance_axis); +			addSeries("Distance", +				  AltosGraphDataPoint.data_distance, +				  AltosConvert.distance, +				  distance_color, +				  false, +				  distance_axis); +			addSeries("GPS Height", +				  AltosGraphDataPoint.data_gps_height, +				  AltosConvert.height, +				  gps_height_color, +				  false, +				  height_axis); +			addSeries("GPS Satellites in Solution", +				  AltosGraphDataPoint.data_gps_nsat_solution, +				  nsat_units, +				  gps_nsat_solution_color, +				  false, +				  nsat_axis); +			addSeries("GPS Satellites in View", +				  AltosGraphDataPoint.data_gps_nsat_view, +				  nsat_units, +				  gps_nsat_view_color, +				  false, +			  nsat_axis); +		} +		if (stats.has_rssi) +			addSeries("Received Signal Strength", +				  AltosGraphDataPoint.data_rssi, +				  dbm_units, +				  dbm_color, +				  false, +				  dbm_axis); +		if (stats.has_other_adc) { +			addSeries("Temperature", +				  AltosGraphDataPoint.data_temperature, +				  AltosConvert.temperature, +				  temperature_color, +				  false, +				  temperature_axis); +			addSeries("Battery Voltage", +				  AltosGraphDataPoint.data_battery_voltage, +				  voltage_units, +				  battery_voltage_color, +				  false, +				  voltage_axis); +			addSeries("Drogue Voltage", +				  AltosGraphDataPoint.data_drogue_voltage, +				  voltage_units, +				  drogue_voltage_color, +				  false, +				  voltage_axis); +			addSeries("Main Voltage", +				  AltosGraphDataPoint.data_main_voltage, +				  voltage_units, +				  main_voltage_color, +				  false, +				  voltage_axis); +		} + +		setDataSet(dataSet); +	} +}
\ No newline at end of file diff --git a/altosui/AltosGraphDataPoint.java b/altosui/AltosGraphDataPoint.java new file mode 100644 index 00000000..8e6d6923 --- /dev/null +++ b/altosui/AltosGraphDataPoint.java @@ -0,0 +1,122 @@ +/* + * 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 altosui; + +import org.altusmetrum.altosuilib_1.*; +import org.altusmetrum.altoslib_1.*; + +public class AltosGraphDataPoint implements AltosUIDataPoint { + +	AltosState	state; + +	public static final int data_height = 0; +	public static final int data_speed = 1; +	public static final int data_accel = 2; +	public static final int data_temp = 3; +	public static final int data_battery_voltage = 4; +	public static final int data_drogue_voltage = 5; +	public static final int data_main_voltage = 6; +	public static final int data_rssi = 7; +	public static final int data_state = 8; +	public static final int data_gps_height = 9; +	public static final int data_gps_nsat_solution = 10; +	public static final int data_gps_nsat_view = 11; +	public static final int data_temperature = 12; +	public static final int data_range = 13; +	public static final int data_distance = 14; + +	public double x() throws AltosUIDataMissing { +		if (state.data.time < -2) +			throw new AltosUIDataMissing(-1); +		return state.data.time; +	} + +	public double y(int index) throws AltosUIDataMissing { +		double y = AltosRecord.MISSING; +		switch (index) { +		case data_height: +			y = state.height; +			break; +		case data_speed: +			y = state.speed(); +			break; +		case data_accel: +			y = state.acceleration; +			break; +		case data_temp: +			y = state.temperature; +			break; +		case data_battery_voltage: +			y = state.battery; +			break; +		case data_drogue_voltage: +			y = state.drogue_sense; +			break; +		case data_main_voltage: +			y = state.main_sense; +			break; +		case data_rssi: +			y = state.data.rssi; +			break; +		case data_gps_height: +			y = state.gps_height; +			break;	 +		case data_gps_nsat_solution: +			if (state.gps != null) +				y = state.gps.nsat; +			break; +		case data_gps_nsat_view: +			if (state.gps != null && state.gps.cc_gps_sat != null) +				y = state.gps.cc_gps_sat.length; +			break; +		case data_temperature: +			y = state.temperature; +			break; +		case data_range: +			y = state.range; +			break; +		case data_distance: +			if (state.from_pad != null) +				y = state.from_pad.distance; +			break; +		} +		if (y == AltosRecord.MISSING) +			throw new AltosUIDataMissing(index); +		return y; +	} + +	public int id(int index) { +		if (index == data_state) { +			int s = state.data.state; +			if (s < Altos.ao_flight_boost || s > Altos.ao_flight_landed) +				return -1; +			return s; +		} +		return 0; +	} + +	public String id_name(int index) { +		if (index == data_state) +			return state.data.state(); +		return ""; +	} + +	public AltosGraphDataPoint (AltosState state) { +		this.state = state; +	} +}
\ No newline at end of file diff --git a/altosui/AltosGraphDataSet.java b/altosui/AltosGraphDataSet.java new file mode 100644 index 00000000..092b7c74 --- /dev/null +++ b/altosui/AltosGraphDataSet.java @@ -0,0 +1,96 @@ +/* + * 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 altosui; + +import java.lang.*; +import java.io.*; +import java.util.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*; + +class AltosGraphIterator implements Iterator<AltosUIDataPoint> { +	AltosGraphDataSet	dataSet; +	Iterator<AltosRecord>	iterator; + +	AltosState	state; + +	public boolean hasNext() { +		return iterator.hasNext(); +	} + +	public AltosUIDataPoint next() { +		state = new AltosState(iterator.next(), state); + +		if (dataSet.callsign == null && state.data.callsign != null) +			dataSet.callsign = state.data.callsign; + +		if (dataSet.serial == 0 && state.data.serial != 0) +			dataSet.serial = state.data.serial; + +		if (dataSet.flight == 0 && state.data.flight != 0) +			dataSet.flight = state.data.flight; + +		return new AltosGraphDataPoint(state); +	} + +	public AltosGraphIterator (Iterator<AltosRecord> iterator, AltosGraphDataSet dataSet) { +		this.iterator = iterator; +		this.state = null; +		this.dataSet = dataSet; +	} + +	public void remove() { +	} +} + +class AltosGraphIterable implements Iterable<AltosUIDataPoint> { +	AltosGraphDataSet	dataSet; + +	public Iterator<AltosUIDataPoint> iterator() { +		return new AltosGraphIterator(dataSet.records.iterator(), dataSet); +	} + +	public AltosGraphIterable(AltosGraphDataSet dataSet) { +		this.dataSet = dataSet; +	} +} + +public class AltosGraphDataSet implements AltosUIDataSet { +	String			callsign; +	int			serial; +	int			flight; +	AltosRecordIterable	records; + +	public String name() { +		if (callsign != null) +			return String.format("%s - %d/%d", callsign, serial, flight); +		else +			return String.format("%d/%d", serial, flight); +	} + +	public Iterable<AltosUIDataPoint> dataPoints() { +		return new AltosGraphIterable(this); +	} + +	public AltosGraphDataSet (AltosRecordIterable records) { +		this.records = records; +		this.callsign = null; +		this.serial = 0; +		this.flight = 0; +	} +} diff --git a/altosui/AltosGraphTime.java b/altosui/AltosGraphTime.java deleted file mode 100644 index 62d516b2..00000000 --- a/altosui/AltosGraphTime.java +++ /dev/null @@ -1,235 +0,0 @@ - -// Copyright (c) 2010 Anthony Towns -// GPL v2 or later - -package altosui; - -import java.util.*; -import java.awt.Color; -import java.util.ArrayList; -import java.util.HashMap; -import org.jfree.chart.ChartUtilities; -import org.jfree.chart.JFreeChart; -import org.jfree.chart.axis.AxisLocation; -import org.jfree.chart.axis.NumberAxis; -import org.jfree.chart.labels.StandardXYToolTipGenerator; -import org.jfree.chart.plot.PlotOrientation; -import org.jfree.chart.plot.XYPlot; -import org.jfree.chart.plot.ValueMarker; -import org.jfree.chart.renderer.xy.StandardXYItemRenderer; -import org.jfree.chart.renderer.xy.XYItemRenderer; -import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; -import org.jfree.data.xy.XYSeries; -import org.jfree.data.xy.XYSeriesCollection; -import org.jfree.ui.RectangleAnchor; -import org.jfree.ui.TextAnchor; - -class AltosGraphTime extends AltosGraph { -    static interface Element { -        void attachGraph(AltosGraphTime g); -        void gotTimeData(double time, AltosDataPoint d); -        void addToPlot(AltosGraphTime g, XYPlot plot); -    } - -    static class TimeAxis implements Element { -        private int axis; -        private Color color; -        private String label; -        private AxisLocation locn; -        private double min_y = Double.NaN; - -        public TimeAxis(int axis, String label, Color color, AxisLocation locn) -        { -            this.axis = axis; -            this.color = color; -            this.label = label; -            this.locn = locn; -        } - -        public void setLowerBound(double min_y) { -            this.min_y = min_y; -        } - -        public void attachGraph(AltosGraphTime g) { return; } -        public void gotTimeData(double time, AltosDataPoint d) { return; } - -        public void addToPlot(AltosGraphTime g, XYPlot plot) { -            NumberAxis numAxis = new NumberAxis(label); -            if (!Double.isNaN(min_y)) -                numAxis.setLowerBound(min_y); -            plot.setRangeAxis(axis, numAxis); -            plot.setRangeAxisLocation(axis, locn); -            numAxis.setLabelPaint(color); -            numAxis.setTickLabelPaint(color); -            numAxis.setAutoRangeIncludesZero(false); -        } -    } - -    abstract static class TimeSeries implements Element { -        protected XYSeries series; -        private String axisName; -	private String axisUnits; -        private Color color; - -        public TimeSeries(String axisName, String axisUnits, String label, Color color) { -            this.series = new XYSeries(label); -            this.axisName = String.format("%s (%s)", axisName, axisUnits); -	    this.axisUnits = axisUnits; -            this.color = color; -        } - -        public void attachGraph(AltosGraphTime g) { -            g.setAxis(this, axisName, color); -        } -        abstract public void gotTimeData(double time, AltosDataPoint d); - -        public void addToPlot(AltosGraphTime g, XYPlot plot) { -            XYSeriesCollection dataset = new XYSeriesCollection(); -            dataset.addSeries(this.series); - -            XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false); -            renderer.setSeriesPaint(0, color); -	    StandardXYToolTipGenerator	tool_tip; - -	    tool_tip = new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})", axisUnits), -						      new java.text.DecimalFormat("0.00"), -						      new java.text.DecimalFormat("0.00")); -	    renderer.setBaseToolTipGenerator(tool_tip); - -            int dataNum = g.getDataNum(this); -            int axisNum = g.getAxisNum(this); - -            plot.setDataset(dataNum, dataset); -            plot.mapDatasetToRangeAxis(dataNum, axisNum); -            plot.setRenderer(dataNum, renderer); -        } -    } - -    static class StateMarker implements Element { -	private LinkedList<Double> times = new LinkedList<Double>(); -        private String name; -        private int state; -	private int prev_state = Altos.ao_flight_startup; - -        StateMarker(int state, String name) { -            this.state = state; -            this.name = name; -        } - -        public void attachGraph(AltosGraphTime g) { return; } -        public void gotTimeData(double time, AltosDataPoint d) { -	    if (prev_state != state && d.state() == state) -		times.add(time); -	    prev_state = d.state(); -        } - -        public void addToPlot(AltosGraphTime g, XYPlot plot) { -	    for (double time : times) { -		ValueMarker m = new ValueMarker(time); -		m.setLabel(name); -		m.setLabelAnchor(RectangleAnchor.TOP_RIGHT); -		m.setLabelTextAnchor(TextAnchor.TOP_LEFT); -		plot.addDomainMarker(m); -	    } -        } -    } - -    private String callsign = null; -    private Integer serial = null; -    private Integer flight = null;  - -    private ArrayList<Element> elements; -    private HashMap<String,Integer> axes; -    private HashMap<Element,Integer> datasets; -    private ArrayList<Integer> datasetAxis; - -    public AltosGraphTime(String title) { -        this.filename = title.toLowerCase().replaceAll("[^a-z0-9]","_")+".png"; -        this.title = title; -        this.elements = new ArrayList<Element>(); -        this.axes = new HashMap<String,Integer>(); -        this.datasets = new HashMap<Element,Integer>(); -        this.datasetAxis = new ArrayList<Integer>(); -    } - -    public AltosGraphTime addElement(Element e) { -        e.attachGraph(this); -        elements.add(e); -        return this; -    } - -    public void setAxis(Element ds, String axisName, Color color) { -        Integer axisNum = axes.get(axisName); -        int dsNum = datasetAxis.size(); -        if (axisNum == null) { -            axisNum = newAxis(axisName, color); -        } -        datasets.put(ds, dsNum); -        datasetAxis.add(axisNum); -    } - -    public int getAxisNum(Element ds) { -        return datasetAxis.get( datasets.get(ds) ).intValue(); -    } -    public int getDataNum(Element ds) { -        return datasets.get(ds).intValue(); -    } - -    private Integer newAxis(String name, Color color) { -        int cnt = axes.size(); -        AxisLocation locn = AxisLocation.BOTTOM_OR_LEFT; -        if (cnt > 0) { -            locn = AxisLocation.TOP_OR_RIGHT; -        } -        Integer res = new Integer(cnt); -        axes.put(name, res); -        this.addElement(new TimeAxis(cnt, name, color, locn)); -        return res; -    } - -    public void addData(AltosDataPoint d) { -        double time = d.time(); -        for (Element e : elements) { -            e.gotTimeData(time, d); -        } -        if (callsign == null) callsign = d.callsign(); -        if (serial == null) serial = new Integer(d.serial()); -        if (flight == null) flight = new Integer(d.flight()); -    } - -    public JFreeChart createChart() { -        NumberAxis xAxis = new NumberAxis("Time (s)"); -        xAxis.setAutoRangeIncludesZero(false); -        XYPlot plot = new XYPlot(); -        plot.setDomainAxis(xAxis); -        plot.setOrientation(PlotOrientation.VERTICAL); - -        if (serial != null && flight != null) { -            title = serial + "/" + flight + ": " + title; -        } -        if (callsign != null) { -            title = callsign + " - " + title; -        } - -        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, -                                plot, true); -        ChartUtilities.applyCurrentTheme(chart); - -        plot.setDomainPannable(true); -        plot.setRangePannable(true); -    -        for (Element e : elements) { -            e.addToPlot(this, plot); -        } - -        return chart; -    } - -    public void toPNG() throws java.io.IOException { -        if (axes.size() > 1) { -            toPNG(800, 500); -        } else { -            toPNG(300, 500); -        } -    } -} diff --git a/altosui/AltosGraphUI.java b/altosui/AltosGraphUI.java index d6891ffa..2f3575a4 100644 --- a/altosui/AltosGraphUI.java +++ b/altosui/AltosGraphUI.java @@ -9,8 +9,8 @@ import java.util.ArrayList;  import java.awt.*;  import javax.swing.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  import org.jfree.chart.ChartPanel;  import org.jfree.chart.JFreeChart; @@ -18,290 +18,58 @@ import org.jfree.ui.RefineryUtilities;  public class AltosGraphUI extends AltosUIFrame   { -    JTabbedPane	pane; - -    static final private Color red = new Color(194,31,31); -    static final private Color green = new Color(31,194,31); -    static final private Color blue = new Color(31,31,194); -    //static final private Color black = new Color(31,31,31); -    static final private Color yellow = new Color(194,194,31); -    //static final private Color cyan = new Color(31,194,194); -    static final private Color magenta = new Color(194,31,194); - -    static private class OverallGraphs { -        AltosGraphTime.Element height =  -		new AltosGraphTime.TimeSeries("Height", AltosConvert.height.show_units(), "Height (AGL)", red) { -                public void gotTimeData(double time, AltosDataPoint d) { -			double	height = d.height(); -			if (height != AltosRecord.MISSING) -				series.add(time, AltosConvert.height.value(height)); -                }  -            }; -     -        AltosGraphTime.Element speed = -		new AltosGraphTime.TimeSeries("Speed", AltosConvert.speed.show_units(), "Vertical Speed", green) {  -                public void gotTimeData(double time, AltosDataPoint d) { -		    double	speed = d.speed(); -		    if (speed != AltosRecord.MISSING) -			    series.add(time, AltosConvert.speed.value(speed)); -                } -            }; -     -        AltosGraphTime.Element acceleration = -		new AltosGraphTime.TimeSeries("Acceleration", -					      AltosConvert.accel.show_units(), -					      "Axial Acceleration", blue) -            { -                public void gotTimeData(double time, AltosDataPoint d) { -		    double acceleration = d.acceleration(); -		    if (acceleration != AltosRecord.MISSING) -			    series.add(time, AltosConvert.accel.value(acceleration)); -                } -            }; -     -        AltosGraphTime.Element temperature = -	    new AltosGraphTime.TimeSeries("Temperature", "\u00B0C",  -					  "Board temperature", red)  -            { -                public void gotTimeData(double time, AltosDataPoint d) { -		    double temp = d.temperature(); -		    if (temp != AltosRecord.MISSING) -			series.add(time, d.temperature()); -                } -            }; -     -        AltosGraphTime.Element drogue_voltage = -            new AltosGraphTime.TimeSeries("Voltage", "(V)", "Drogue Continuity", yellow)  -            { -                public void gotTimeData(double time, AltosDataPoint d) { -		    double v = d.drogue_voltage(); -		    if (v != AltosRecord.MISSING) -			series.add(time, v); -                } -            }; -     -        AltosGraphTime.Element main_voltage = -            new AltosGraphTime.TimeSeries("Voltage", "(V)", "Main Continuity", magenta)  -            { -                public void gotTimeData(double time, AltosDataPoint d) { -		    double v = d.main_voltage(); -		    if (v != AltosRecord.MISSING) -			series.add(time, v); -                } -            }; -     -        //AltosGraphTime.Element e_pad    = new AltosGraphTime.StateMarker(Altos.ao_flight_pad, "Pad"); -        AltosGraphTime.Element e_boost  = new AltosGraphTime.StateMarker(Altos.ao_flight_boost, "Boost"); -        AltosGraphTime.Element e_fast   = new AltosGraphTime.StateMarker(Altos.ao_flight_fast, "Fast"); -        AltosGraphTime.Element e_coast  = new AltosGraphTime.StateMarker(Altos.ao_flight_coast, "Coast"); -	AltosGraphTime.Element e_drogue = new AltosGraphTime.StateMarker(Altos.ao_flight_drogue, "Drogue"); -	AltosGraphTime.Element e_main   = new AltosGraphTime.StateMarker(Altos.ao_flight_main, "Main"); -        AltosGraphTime.Element e_landed = new AltosGraphTime.StateMarker(Altos.ao_flight_landed, "Landed"); -     -        protected AltosGraphTime myAltosGraphTime(String suffix) { -            return (new AltosGraphTime("Overall " + suffix)) -                .addElement(e_boost) -		.addElement(e_fast) -		.addElement(e_coast) -                .addElement(e_drogue) -                .addElement(e_main) -                .addElement(e_landed); -        } -     -        public ArrayList<AltosGraph> graphs() { -            ArrayList<AltosGraph> graphs = new ArrayList<AltosGraph>(); -     -	    graphs.add( myAltosGraphTime("Summary") -			.addElement(height) -			.addElement(speed) -			.addElement(acceleration) ); - -	    graphs.add( myAltosGraphTime("Summary") -			.addElement(height) -			.addElement(speed)); -     -            graphs.add( myAltosGraphTime("Altitude") -                    .addElement(height) ); -     -            graphs.add( myAltosGraphTime("Speed") -                    .addElement(speed) ); -     -	    graphs.add( myAltosGraphTime("Acceleration") -			.addElement(acceleration) ); -     -            graphs.add( myAltosGraphTime("Temperature") -                    .addElement(temperature) ); -     -	    graphs.add( myAltosGraphTime("Continuity") -			.addElement(drogue_voltage) -			.addElement(main_voltage) ); -     -            return graphs; -        } -    } - -    /* -    static private class AscentGraphs extends OverallGraphs { -        protected AltosGraphTime myAltosGraphTime(String suffix) { -            return (new AltosGraphTime("Ascent " + suffix) { -                public void addData(AltosDataPoint d) { -                    int state = d.state(); -                    if (Altos.ao_flight_boost <= state && state <= Altos.ao_flight_coast) { -                        super.addData(d); -                    } -                } -            }).addElement(e_boost) -              .addElement(e_fast) -              .addElement(e_coast); -        } -    } -    */ - -    /* -    static private class DescentGraphs extends OverallGraphs { -        protected AltosGraphTime myAltosGraphTime(String suffix) { -            return (new AltosGraphTime("Descent " + suffix) { -                public void addData(AltosDataPoint d) { -                    int state = d.state(); -                    if (Altos.ao_flight_drogue <= state && state <= Altos.ao_flight_main) { -                        super.addData(d); -                    } -                } -            }).addElement(e_drogue) -              .addElement(e_main); -            // ((XYGraph)graph[8]).ymin = new Double(-50); -        } -    } -    */ - -	public AltosGraphUI(AltosRecordIterable records, String name) throws InterruptedException, IOException { -		super(String.format("Altos Graph %s", name)); - -		AltosDataPointReader reader = new AltosDataPointReader (records); -         -		if (reader.has_accel) -		    init(reader, records, 0); -		else -		    init(reader, records, 1); +	JTabbedPane		pane; +	AltosGraph		graph; +	AltosUIEnable		enable; +	AltosSiteMap		map; +	AltosState		state; +	AltosGraphDataSet	graphDataSet; +	AltosFlightStats	stats; +	AltosFlightStatsTable	statsTable; + +	boolean fill_map(AltosRecordIterable records) { +		boolean		any_gps = false; +		for (AltosRecord record : records) { +			state = new AltosState(record, state); +			if (state.gps.locked && state.gps.nsat >= 4) { +				map.show(state, 0); +				any_gps = true; +			} +		} +		return any_gps;  	} -//    public AltosGraphUI(AltosDataPointReader data, int which) -    //  { -//        super("Altos Graph"); -//        init(data, which); -//    } - -    private void init(AltosDataPointReader data, AltosRecordIterable records, int which) throws InterruptedException, IOException { -	pane = new JTabbedPane(); - -        AltosGraph graph = createGraph(data, which); +	AltosGraphUI(AltosRecordIterable records, File file) throws InterruptedException, IOException { +		super(file.getName()); +		state = null; -        JFreeChart chart = graph.createChart(); -        ChartPanel chartPanel = new ChartPanel(chart); -        chartPanel.setMouseWheelEnabled(true); -        chartPanel.setPreferredSize(new java.awt.Dimension(800, 500)); -        pane.add(graph.title, chartPanel); +		pane = new JTabbedPane(); -	AltosFlightStatsTable stats = new AltosFlightStatsTable(new AltosFlightStats(records)); -	pane.add("Flight Statistics", stats); +		enable = new AltosUIEnable(); -	setContentPane (pane); +		stats = new AltosFlightStats(records); +		graphDataSet = new AltosGraphDataSet(records); -        pack(); +		graph = new AltosGraph(enable, stats, graphDataSet); -        RefineryUtilities.centerFrameOnScreen(this); +		statsTable = new AltosFlightStatsTable(stats); -        setDefaultCloseOperation(DISPOSE_ON_CLOSE); -        setVisible(true); -    } +		map = new AltosSiteMap(); -    private static AltosGraph createGraph(Iterable<AltosDataPoint> data, -            int which) -    { -        return createGraphsWhich(data, which).get(0); -    } +		pane.add("Flight Graph", graph.panel); +		pane.add("Configure Graph", enable); +		pane.add("Flight Statistics", statsTable); -    /* -    private static ArrayList<AltosGraph> createGraphs( -            Iterable<AltosDataPoint> data) -    { -        return createGraphsWhich(data, -1); -    } -    */ +		if (fill_map(records)) +			pane.add("Map", map); -    private static ArrayList<AltosGraph> createGraphsWhich( -            Iterable<AltosDataPoint> data, int which) -    { -        ArrayList<AltosGraph> graph = new ArrayList<AltosGraph>(); -        graph.addAll((new OverallGraphs()).graphs()); -//        graph.addAll((new AscentGraphs()).graphs()); -//        graph.addAll((new DescentGraphs()).graphs()); +		setContentPane (pane); -        if (which > 0) { -            if (which >= graph.size()) { -                which = 0; -            } -            AltosGraph g = graph.get(which); -            graph = new ArrayList<AltosGraph>(); -            graph.add(g); -        } +		pack(); -        for (AltosDataPoint dp : data) { -            for (AltosGraph g : graph) { -                g.addData(dp); -            } -        } - -        return graph; -    } +		setDefaultCloseOperation(DISPOSE_ON_CLOSE); +		setVisible(true); +		if (state != null) +			map.centre(state); +	}  } - -/* gnuplot bits... - * -300x400 - --------------------------------------------------------- -TOO HARD! :) - -"ascent-gps-accuracy.png" "Vertical error margin to apogee - GPS v Baro (m)" -    5:($7 < 6 ? $24-$11 : 1/0) -"descent-gps-accuracy.png" "Vertical error margin during descent - GPS v Baro (m)" -    5:($7 < 6 ? 1/0 : $24-$11) - -set output "overall-gps-accuracy.png" -set ylabel "distance above sea level (m)" -plot "telemetry.csv" using 5:11 with lines ti "baro altitude" axis x1y1, \ -    "telemetry.csv" using 5:24 with lines ti "gps altitude" axis x1y1 - -set term png tiny size 700,700 enhanced -set xlabel "m" -set ylabel "m" -set polar -set grid polar -set rrange[*:*] -set angles degrees - -set output "overall-gps-path.png" -#:30 with yerrorlines -plot "telemetry.csv" using (90-$33):($7 == 2 ? $31 : 1/0) with lines ti "pad", \ -    "telemetry.csv" using (90-$33):($7 == 3 ? $31 : 1/0) with lines ti "boost", \ -    "telemetry.csv" using (90-$33):($7 == 4 ? $31 : 1/0) with lines ti "fast", \ -    "telemetry.csv" using (90-$33):($7 == 5 ? $31 : 1/0) with lines ti "coast", \ -    "telemetry.csv" using (90-$33):($7 == 6 ? $31 : 1/0) with lines ti "drogue", \ -    "telemetry.csv" using (90-$33):($7 == 7 ? $31 : 1/0) with lines ti "main", \ -    "telemetry.csv" using (90-$33):($7 == 8 ? $31 : 1/0) with lines ti "landed" - -set output "ascent-gps-path.png" -plot "telemetry.csv" using (90-$33):($7 == 2 ? $31 : 1/0):30 with lines ti "pad", \ -    "telemetry.csv" using (90-$33):($7 == 3 ? $31 : 1/0):20 with lines ti "boost", \ -    "telemetry.csv" using (90-$33):($7 == 4 ? $31 : 1/0):10 with lines ti "fast", \ -    "telemetry.csv" using (90-$33):($7 == 5 ? $31 : 1/0):5 with lines ti "coast" - -set output "descent-gps-path.png" -plot "telemetry.csv" using (90-$33):($7 == 6 ? $31 : 1/0) with lines ti "drogue", \ -    "telemetry.csv" using (90-$33):($7 == 7 ? $31 : 1/0) with lines ti "main", \ -    "telemetry.csv" using (90-$33):($7 == 8 ? $31 : 1/0) with lines ti "landed" - - */ - - diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index 1b3dd547..8c883eeb 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -20,12 +20,13 @@ package altosui;  import java.awt.*;  import java.awt.event.*;  import javax.swing.*; +import javax.swing.event.*;  import java.io.*;  import java.util.concurrent.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*; -public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDisplay, AltosFontListener, AltosIdleMonitorListener { +public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDisplay, AltosFontListener, AltosIdleMonitorListener, DocumentListener {  	AltosDevice		device;  	JTabbedPane		pane;  	AltosPad		pad; @@ -36,11 +37,8 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl  	boolean			remote;  	void stop_display() { -		if (thread != null && thread.isAlive()) { -			thread.interrupt(); -			try { -				thread.join(); -			} catch (InterruptedException ie) {} +		if (thread != null) { +			thread.abort();  		}  		thread = null;  	} @@ -87,6 +85,48 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl  	Container	bag;  	AltosFreqList	frequencies; +	JTextField	callsign_value; + +	/* DocumentListener interface methods */ +	public void changedUpdate(DocumentEvent e) { +		if (callsign_value != null) { +			String	callsign = callsign_value.getText(); +			thread.set_callsign(callsign); +			AltosUIPreferences.set_callsign(callsign); +		} +	} + +	public void insertUpdate(DocumentEvent e) { +		changedUpdate(e); +	} + +	public void removeUpdate(DocumentEvent e) { +		changedUpdate(e); +	} + +	int row = 0; + +	public GridBagConstraints constraints (int x, int width, int fill) { +		GridBagConstraints c = new GridBagConstraints(); +		Insets insets = new Insets(4, 4, 4, 4); + +		c.insets = insets; +		c.fill = fill; +		if (width == 3) +			c.anchor = GridBagConstraints.CENTER; +		else if (x == 2) +			c.anchor = GridBagConstraints.EAST; +		else +			c.anchor = GridBagConstraints.WEST; +		c.gridx = x; +		c.gridwidth = width; +		c.gridy = row; +		return c; +	} + +	public GridBagConstraints constraints(int x, int width) { +		return constraints(x, width, GridBagConstraints.NONE); +	}  	public AltosIdleMonitorUI(JFrame in_owner)  		throws FileNotFoundException, AltosSerialInUseException, TimeoutException, InterruptedException { @@ -100,8 +140,6 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl  		bag = getContentPane();  		bag.setLayout(new GridBagLayout()); -		GridBagConstraints c = new GridBagConstraints(); -  		setTitle(String.format("AltOS %s", device.toShortString()));  		/* Stick frequency selector at top of table for telemetry monitoring */ @@ -116,23 +154,21 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl  									       frequency);  					}  			}); -			c.gridx = 0; -			c.gridy = 0; -			c.insets = new Insets(3, 3, 3, 3); -			c.anchor = GridBagConstraints.WEST; -			bag.add (frequencies, c); +			bag.add (frequencies, constraints(0, 1)); +			bag.add (new JLabel("Callsign:"), constraints(1, 1)); +			/* Add callsign configuration */ +			callsign_value = new JTextField(AltosUIPreferences.callsign()); +			callsign_value.getDocument().addDocumentListener(this); +			callsign_value.setToolTipText("Callsign sent in packet mode"); +			bag.add(callsign_value, constraints(2, 1, GridBagConstraints.BOTH)); +			row++;  		}  		/* Flight status is always visible */  		flightStatus = new AltosFlightStatus(); -		c.gridx = 0; -		c.gridy = 1; -		c.fill = GridBagConstraints.HORIZONTAL; -		c.weightx = 1; -		c.gridwidth = 2; -		bag.add(flightStatus, c); -		c.gridwidth = 1; +		bag.add(flightStatus, constraints(0, 3, GridBagConstraints.HORIZONTAL)); +		row++;  		/* The rest of the window uses a tabbed pane to  		 * show one of the alternate data views @@ -146,13 +182,7 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl  		pane.add("Table", new JScrollPane(flightInfo));  		/* Make the tabbed pane use the rest of the window space */ -		c.gridx = 0; -		c.gridy = 2; -		c.fill = GridBagConstraints.BOTH; -		c.weightx = 1; -		c.weighty = 1; -		c.gridwidth = 2; -		bag.add(pane, c); +		bag.add(pane, constraints(0, 3, GridBagConstraints.BOTH));  		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); diff --git a/altosui/AltosIgniteUI.java b/altosui/AltosIgniteUI.java index c1378eb9..14d4eebc 100644 --- a/altosui/AltosIgniteUI.java +++ b/altosui/AltosIgniteUI.java @@ -23,8 +23,8 @@ import javax.swing.*;  import java.io.*;  import java.text.*;  import java.util.concurrent.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosIgniteUI  	extends AltosUIDialog diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index 11d1b0c1..c06f57ec 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -20,7 +20,7 @@ package altosui;  import java.awt.*;  import javax.swing.*;  import javax.swing.table.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosInfoTable extends JTable {  	private AltosFlightInfoTableModel model; diff --git a/altosui/AltosKML.java b/altosui/AltosKML.java index 281638bf..84f9dc7a 100644 --- a/altosui/AltosKML.java +++ b/altosui/AltosKML.java @@ -18,7 +18,7 @@  package altosui;  import java.io.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosKML implements AltosWriter { diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 5e073f7d..e13229a8 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -21,7 +21,7 @@ import java.awt.*;  import java.awt.event.*;  import javax.swing.*;  import java.io.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosLanded extends JComponent implements AltosFlightDisplay, ActionListener {  	GridBagLayout	layout; @@ -257,7 +257,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio  						throw new FileNotFoundException(filename);  					}  					try { -						new AltosGraphUI(records, filename); +						new AltosGraphUI(records, file);  					} catch (InterruptedException ie) {  					} catch (IOException ie) {  					} diff --git a/altosui/AltosLaunch.java b/altosui/AltosLaunch.java index 0bad80aa..04948ee6 100644 --- a/altosui/AltosLaunch.java +++ b/altosui/AltosLaunch.java @@ -20,7 +20,7 @@ package altosui;  import java.io.*;  import java.util.concurrent.*;  import java.awt.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosLaunch {  	AltosDevice	device; diff --git a/altosui/AltosLaunchUI.java b/altosui/AltosLaunchUI.java index 7e7ed010..4d9fbda5 100644 --- a/altosui/AltosLaunchUI.java +++ b/altosui/AltosLaunchUI.java @@ -23,7 +23,7 @@ import javax.swing.*;  import java.io.*;  import java.text.*;  import java.util.concurrent.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  class FireButton extends JButton {  	protected void processMouseEvent(MouseEvent e) { diff --git a/altosui/AltosPad.java b/altosui/AltosPad.java index 2d9c8323..d13f6945 100644 --- a/altosui/AltosPad.java +++ b/altosui/AltosPad.java @@ -19,7 +19,7 @@ package altosui;  import java.awt.*;  import javax.swing.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosPad extends JComponent implements AltosFlightDisplay {  	GridBagLayout	layout; diff --git a/altosui/AltosRomconfigUI.java b/altosui/AltosRomconfigUI.java index 5fc786e2..cf4658af 100644 --- a/altosui/AltosRomconfigUI.java +++ b/altosui/AltosRomconfigUI.java @@ -20,7 +20,7 @@ package altosui;  import java.awt.*;  import java.awt.event.*;  import javax.swing.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosRomconfigUI  	extends AltosUIDialog diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index 14b52310..0c903873 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -25,8 +25,8 @@ import java.io.*;  import java.util.*;  import java.text.*;  import java.util.concurrent.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  class AltosScanResult {  	String		callsign; diff --git a/altosui/AltosSerial.java b/altosui/AltosSerial.java index 78d862d0..e869f1ab 100644 --- a/altosui/AltosSerial.java +++ b/altosui/AltosSerial.java @@ -25,8 +25,8 @@ import java.io.*;  import java.util.*;  import java.awt.*;  import javax.swing.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  import libaltosJNI.*; @@ -72,7 +72,7 @@ public class AltosSerial extends AltosLink  {  		Object[] options = { "Cancel" };  		JOptionPane	pane = new JOptionPane(); -		pane.setMessage(String.format("Connecting to %s, %7.3f MHz", device.toShortString(), frequency)); +		pane.setMessage(String.format("Connecting to %s, %7.3f MHz as %s", device.toShortString(), frequency, callsign));  		pane.setOptions(options);  		pane.setInitialValue(null); diff --git a/altosui/AltosSerialInUseException.java b/altosui/AltosSerialInUseException.java index 932a3684..b45d9157 100644 --- a/altosui/AltosSerialInUseException.java +++ b/altosui/AltosSerialInUseException.java @@ -16,7 +16,7 @@   */  package altosui; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosSerialInUseException extends Exception {  	public AltosDevice	device; diff --git a/altosui/AltosSiteMap.java b/altosui/AltosSiteMap.java index 4e939b88..f614eae6 100644 --- a/altosui/AltosSiteMap.java +++ b/altosui/AltosSiteMap.java @@ -23,7 +23,8 @@ import java.io.*;  import java.lang.Math;  import java.awt.geom.Point2D;  import java.util.concurrent.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {  	// preferred vertical step in a tile in naut. miles @@ -321,6 +322,22 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {  		last_state = state.state;  	} +	public void centre(Point2D.Double pt) { +		Rectangle r = comp.getVisibleRect(); +		Point2D.Double copt = translatePoint(pt, tileCoordOffset(topleft)); +		int dx = (int)copt.x - r.width/2 - r.x; +		int dy = (int)copt.y - r.height/2 - r.y; +		r.x += dx; +		r.y += dy; +		comp.scrollRectToVisible(r); +	} + +	public void centre(AltosState state) { +		if (!state.gps.locked && state.gps.nsat < 4) +			return; +		centre(pt(state.gps.lat, state.gps.lon)); +	} +  	public void draw_circle(double lat, double lon) {  		final Point2D.Double pt = pt(lat, lon); diff --git a/altosui/AltosSiteMapPreload.java b/altosui/AltosSiteMapPreload.java index f4dcc903..fd648abc 100644 --- a/altosui/AltosSiteMapPreload.java +++ b/altosui/AltosSiteMapPreload.java @@ -26,7 +26,7 @@ import java.text.*;  import java.lang.Math;  import java.net.URL;  import java.net.URLConnection; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  class AltosMapPos extends Box {  	AltosUI		owner; diff --git a/altosui/AltosSiteMapTile.java b/altosui/AltosSiteMapTile.java index e9d4a20b..10e65bcd 100644 --- a/altosui/AltosSiteMapTile.java +++ b/altosui/AltosSiteMapTile.java @@ -22,7 +22,7 @@ import java.awt.image.*;  import javax.swing.*;  import java.awt.geom.Point2D;  import java.awt.geom.Line2D; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosSiteMapTile extends JLayeredPane {  	JLabel mapLabel; diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 70142a93..9f8f6dda 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -22,8 +22,8 @@ import java.awt.event.*;  import javax.swing.*;  import java.io.*;  import java.util.concurrent.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class AltosUI extends AltosUIFrame {  	public AltosVoice voice = new AltosVoice(); @@ -48,7 +48,7 @@ public class AltosUI extends AltosUIFrame {  		} catch (FileNotFoundException ee) {  			JOptionPane.showMessageDialog(AltosUI.this,  						      ee.getMessage(), -						      "Cannot open target device", +						      String.format ("Cannot open %s", device.toShortString()),  						      JOptionPane.ERROR_MESSAGE);  		} catch (AltosSerialInUseException si) {  			JOptionPane.showMessageDialog(AltosUI.this, @@ -58,17 +58,17 @@ public class AltosUI extends AltosUIFrame {  						      JOptionPane.ERROR_MESSAGE);  		} catch (IOException ee) {  			JOptionPane.showMessageDialog(AltosUI.this, -						      device.toShortString(), -						      "Unkonwn I/O error", +						      String.format ("Unknown I/O error on %s", device.toShortString()), +						      "Unknown I/O error",  						      JOptionPane.ERROR_MESSAGE);  		} catch (TimeoutException te) {  			JOptionPane.showMessageDialog(this, -						      device.toShortString(), +						      String.format ("Timeout on %s", device.toShortString()),  						      "Timeout error",  						      JOptionPane.ERROR_MESSAGE);  		} catch (InterruptedException ie) {  			JOptionPane.showMessageDialog(this, -						      device.toShortString(), +						      String.format("Interrupted %s", device.toShortString()),  						      "Interrupted exception",  						      JOptionPane.ERROR_MESSAGE);  		} @@ -224,14 +224,6 @@ public class AltosUI extends AltosUIFrame {  		doLayout();  		validate(); -		setVisible(true); - -		Insets i = getInsets(); -		Dimension ps = rootPane.getPreferredSize(); -		ps.width += i.left + i.right; -		ps.height += i.top + i.bottom; -		setPreferredSize(ps); -		setSize(ps);  		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);  		addWindowListener(new WindowAdapter() {  			@Override @@ -239,6 +231,11 @@ public class AltosUI extends AltosUIFrame {  				System.exit(0);  			}  		}); + +		setLocationByPlatform(false); +		 +		/* Insets aren't set before the window is visible */ +		setVisible(true);  	}  	private void ConnectToDevice() { @@ -331,7 +328,7 @@ public class AltosUI extends AltosUIFrame {  		if (record_reader == null)  			return;  		try { -			new AltosGraphUI(record_reader, chooser.filename()); +			new AltosGraphUI(record_reader, chooser.file());  		} catch (InterruptedException ie) {  		} catch (IOException ie) {  		} @@ -348,15 +345,14 @@ public class AltosUI extends AltosUIFrame {  		}  	} -	static AltosRecordIterable open_logfile(String filename) { -		File file = new File (filename); +	static AltosRecordIterable open_logfile(File file) {  		try {  			FileInputStream in;  			in = new FileInputStream(file); -			if (filename.endsWith("eeprom")) +			if (file.getName().endsWith("eeprom"))  				return new AltosEepromIterable(in); -			else if (filename.endsWith("mega")) +			else if (file.getName().endsWith("mega"))  				return new AltosEepromMegaIterable(in);  			else  				return new AltosTelemetryIterable(in); @@ -366,8 +362,7 @@ public class AltosUI extends AltosUIFrame {  		}  	} -	static AltosWriter open_csv(String filename) { -		File file = new File (filename); +	static AltosWriter open_csv(File file) {  		try {  			return new AltosCSV(file);  		} catch (FileNotFoundException fe) { @@ -376,8 +371,7 @@ public class AltosUI extends AltosUIFrame {  		}  	} -	static AltosWriter open_kml(String filename) { -		File file = new File (filename); +	static AltosWriter open_kml(File file) {  		try {  			return new AltosKML(file);  		} catch (FileNotFoundException fe) { @@ -393,12 +387,12 @@ public class AltosUI extends AltosUIFrame {  	static final int process_replay = 4;  	static final int process_summary = 5; -	static boolean process_csv(String input) { +	static boolean process_csv(File input) {  		AltosRecordIterable iterable = open_logfile(input);  		if (iterable == null)  			return false; -		String output = Altos.replace_extension(input,".csv"); +		File output = Altos.replace_extension(input,".csv");  		System.out.printf("Processing \"%s\" to \"%s\"\n", input, output);  		if (input.equals(output)) {  			System.out.printf("Not processing '%s'\n", input); @@ -413,12 +407,12 @@ public class AltosUI extends AltosUIFrame {  		return true;  	} -	static boolean process_kml(String input) { +	static boolean process_kml(File input) {  		AltosRecordIterable iterable = open_logfile(input);  		if (iterable == null)  			return false; -		String output = Altos.replace_extension(input,".kml"); +		File output = Altos.replace_extension(input,".kml");  		System.out.printf("Processing \"%s\" to \"%s\"\n", input, output);  		if (input.equals(output)) {  			System.out.printf("Not processing '%s'\n", input); @@ -453,19 +447,15 @@ public class AltosUI extends AltosUIFrame {  		return recs;  	} -	static AltosRecordIterable record_iterable_file(String filename) { -		return record_iterable (new File(filename)); -	} - -	static AltosReplayReader replay_file(String filename) { -		AltosRecordIterable recs = record_iterable_file(filename); +	static AltosReplayReader replay_file(File file) { +		AltosRecordIterable recs = record_iterable(file);  		if (recs == null)  			return null; -		return new AltosReplayReader(recs.iterator(), new File(filename)); +		return new AltosReplayReader(recs.iterator(), file);  	} -	static boolean process_replay(String filename) { -		AltosReplayReader reader = replay_file(filename); +	static boolean process_replay(File file) { +		AltosReplayReader reader = replay_file(file);  		if (reader == null)  			return false;  		AltosFlightUI flight_ui = new AltosFlightUI(new AltosVoice(), reader); @@ -473,12 +463,12 @@ public class AltosUI extends AltosUIFrame {  		return true;  	} -	static boolean process_graph(String filename) { -		AltosRecordIterable recs = record_iterable_file(filename); +	static boolean process_graph(File file) { +		AltosRecordIterable recs = record_iterable(file);  		if (recs == null)  			return false;  		try { -			new AltosGraphUI(recs, filename); +			new AltosGraphUI(recs, file);  			return true;  		} catch (InterruptedException ie) {  		} catch (IOException ie) { @@ -486,8 +476,8 @@ public class AltosUI extends AltosUIFrame {  		return false;  	} -	static boolean process_summary(String filename) { -		AltosRecordIterable iterable = record_iterable_file(filename); +	static boolean process_summary(File file) { +		AltosRecordIterable iterable = record_iterable(file);  		if (iterable == null)  			return false;  		try { @@ -552,7 +542,6 @@ public class AltosUI extends AltosUIFrame {  		/* Handle batch-mode */  		if (args.length == 0) {  			AltosUI altosui = new AltosUI(); -			altosui.setVisible(true);  			java.util.List<AltosDevice> devices = AltosUSBDevice.list(Altos.product_basestation);  			for (AltosDevice device : devices) @@ -584,26 +573,27 @@ public class AltosUI extends AltosUIFrame {  				else if (args[i].startsWith("--"))  					help(1);  				else { +					File file = new File(args[i]);  					switch (process) {  					case process_none:  					case process_graph: -						if (!process_graph(args[i])) +						if (!process_graph(file))  							++errors;  						break;  					case process_replay: -						if (!process_replay(args[i])) +						if (!process_replay(file))  							++errors;  						break;  					case process_kml: -						if (!process_kml(args[i])) +						if (!process_kml(file))  							++errors;  						break;  					case process_csv: -						if (!process_csv(args[i])) +						if (!process_csv(file))  							++errors;  						break;  					case process_summary: -						if (!process_summary(args[i])) +						if (!process_summary(file))  							++errors;  						break;  					} diff --git a/altosui/AltosUIPreferences.java b/altosui/AltosUIPreferences.java deleted file mode 100644 index 9c56d031..00000000 --- a/altosui/AltosUIPreferences.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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 altosui; - -import java.io.*; -import java.util.*; -import java.awt.Component; -import javax.swing.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; - -public class AltosUIPreferences extends AltosPreferences { - -	/* font size preferences name */ -	final static String fontSizePreference = "FONT-SIZE"; - -	/* Look&Feel preference name */ -	final static String lookAndFeelPreference = "LOOK-AND-FEEL"; - -	/* UI Component to pop dialogs up */ -	static Component component; - -	static LinkedList<AltosFontListener> font_listeners; - -	static int font_size = Altos.font_size_medium; - -	static LinkedList<AltosUIListener> ui_listeners; - -	static String look_and_feel = null; - -	/* Serial debug */ -	static boolean serial_debug; - -	public static void init() { -		AltosPreferences.init(new AltosUIPreferencesBackend()); - -		font_listeners = new LinkedList<AltosFontListener>(); - -		font_size = backend.getInt(fontSizePreference, Altos.font_size_medium); -		Altos.set_fonts(font_size); -		look_and_feel = backend.getString(lookAndFeelPreference, UIManager.getSystemLookAndFeelClassName()); - -		ui_listeners = new LinkedList<AltosUIListener>(); -		serial_debug = backend.getBoolean(serialDebugPreference, false); -		AltosLink.set_debug(serial_debug); -	} - -	static { init(); } - -	static void set_component(Component in_component) { -		component = in_component; -	} - -	private static boolean check_dir(File dir) { -		if (!dir.exists()) { -			if (!dir.mkdirs()) { -				JOptionPane.showMessageDialog(component, -							      dir.getName(), -							      "Cannot create directory", -							      JOptionPane.ERROR_MESSAGE); -				return false; -			} -		} else if (!dir.isDirectory()) { -			JOptionPane.showMessageDialog(component, -						      dir.getName(), -						      "Is not a directory", -						      JOptionPane.ERROR_MESSAGE); -			return false; -		} -		return true; -	} - -	/* Configure the log directory. This is where all telemetry and eeprom files -	 * will be written to, and where replay will look for telemetry files -	 */ -	public static void ConfigureLog() { -		JFileChooser	logdir_chooser = new JFileChooser(logdir.getParentFile()); - -		logdir_chooser.setDialogTitle("Configure Data Logging Directory"); -		logdir_chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - -		if (logdir_chooser.showDialog(component, "Select Directory") == JFileChooser.APPROVE_OPTION) { -			File dir = logdir_chooser.getSelectedFile(); -			if (check_dir(dir)) -				set_logdir(dir); -		} -	} -	public static int font_size() { -		synchronized (backend) { -			return font_size; -		} -	} - -	static void set_fonts() { -	} - -	public static void set_font_size(int new_font_size) { -		synchronized (backend) { -			font_size = new_font_size; -			backend.putInt(fontSizePreference, font_size); -			flush_preferences(); -			Altos.set_fonts(font_size); -			for (AltosFontListener l : font_listeners) -				l.font_size_changed(font_size); -		} -	} - -	public static void register_font_listener(AltosFontListener l) { -		synchronized (backend) { -			font_listeners.add(l); -		} -	} - -	public static void unregister_font_listener(AltosFontListener l) { -		synchronized (backend) { -			font_listeners.remove(l); -		} -	} - -	public static void set_look_and_feel(String new_look_and_feel) { -		try { -			UIManager.setLookAndFeel(new_look_and_feel); -		} catch (Exception e) { -		} -		synchronized(backend) { -			look_and_feel = new_look_and_feel; -			backend.putString(lookAndFeelPreference, look_and_feel); -			flush_preferences(); -			for (AltosUIListener l : ui_listeners) -				l.ui_changed(look_and_feel); -		} -	} - -	public static String look_and_feel() { -		synchronized (backend) { -			return look_and_feel; -		} -	} - -	public static void register_ui_listener(AltosUIListener l) { -		synchronized(backend) { -			ui_listeners.add(l); -		} -	} - -	public static void unregister_ui_listener(AltosUIListener l) { -		synchronized (backend) { -			ui_listeners.remove(l); -		} -	} -	public static void set_serial_debug(boolean new_serial_debug) { -		AltosLink.set_debug(new_serial_debug); -		synchronized (backend) { -			serial_debug = new_serial_debug; -			backend.putBoolean(serialDebugPreference, serial_debug); -			flush_preferences(); -		} -	} - -	public static boolean serial_debug() { -		synchronized (backend) { -			return serial_debug; -		} -	} - -} diff --git a/altosui/AltosUIPreferencesBackend.java b/altosui/AltosUIPreferencesBackend.java index 3131fd32..0dac9fc7 100644 --- a/altosui/AltosUIPreferencesBackend.java +++ b/altosui/AltosUIPreferencesBackend.java @@ -19,7 +19,7 @@ package altosui;  import java.io.File;  import java.util.prefs.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  import javax.swing.filechooser.FileSystemView;  public class AltosUIPreferencesBackend implements AltosPreferencesBackend { diff --git a/altosui/AltosVoice.java b/altosui/AltosVoice.java index f84c1122..2ed6a8c2 100644 --- a/altosui/AltosVoice.java +++ b/altosui/AltosVoice.java @@ -20,6 +20,7 @@ package altosui;  import com.sun.speech.freetts.Voice;  import com.sun.speech.freetts.VoiceManager;  import java.util.concurrent.LinkedBlockingQueue; +import org.altusmetrum.altosuilib_1.*;  public class AltosVoice implements Runnable {  	VoiceManager			voice_manager; diff --git a/altosui/AltosWriter.java b/altosui/AltosWriter.java index 6806c50e..2f70b472 100644 --- a/altosui/AltosWriter.java +++ b/altosui/AltosWriter.java @@ -17,7 +17,7 @@  package altosui; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public interface AltosWriter { diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 7d000f7b..8ae1a72e 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -62,7 +62,6 @@ altosui_JAVA = \  	AltosLed.java \  	AltosLights.java \  	AltosPad.java \ -	AltosUIPreferences.java \  	AltosUIPreferencesBackend.java \  	AltosRomconfig.java \  	AltosRomconfigUI.java \ @@ -75,10 +74,9 @@ altosui_JAVA = \  	AltosSiteMapTile.java \  	AltosUI.java \  	AltosWriter.java \ -	AltosDataPointReader.java \ -	AltosDataPoint.java \  	AltosGraph.java \ -	AltosGraphTime.java \ +	AltosGraphDataPoint.java \ +	AltosGraphDataSet.java \  	AltosGraphUI.java \  	AltosDataChooser.java \  	AltosVoice.java \ @@ -100,10 +98,10 @@ FREETTS_CLASS= \  	freetts.jar  ALTOSLIB_CLASS=\ -	AltosLib.jar +	altoslib_$(ALTOSLIB_VERSION).jar  ALTOSUILIB_CLASS=\ -	altosuilib.jar +	altosuilib_$(ALTOSUILIB_VERSION).jar  LIBALTOS= \  	libaltos.so \ diff --git a/altosui/altos-windows.nsi b/altosui/altos-windows.nsi.in index 20dd65f0..cde54b41 100644 --- a/altosui/altos-windows.nsi +++ b/altosui/altos-windows.nsi.in @@ -88,7 +88,8 @@ Section "AltosUI Application"  	SetOutPath $INSTDIR  	File "altosui-fat.jar" -	File "AltosLib.jar" +	File "altoslib_@ALTOSLIB_VERSION@.jar" +	File "altosuilib_@ALTOSUILIB_VERSION@.jar"  	File "cmudict04.jar"  	File "cmulex.jar"  	File "cmu_time_awb.jar" diff --git a/altosuilib/AltosDevice.java b/altosuilib/AltosDevice.java index 69b025ba..2461df1b 100644 --- a/altosuilib/AltosDevice.java +++ b/altosuilib/AltosDevice.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altosuilib; +package org.altusmetrum.altosuilib_1;  import libaltosJNI.*; diff --git a/altosuilib/AltosDeviceDialog.java b/altosuilib/AltosDeviceDialog.java index cde545a7..73bc0b2f 100644 --- a/altosuilib/AltosDeviceDialog.java +++ b/altosuilib/AltosDeviceDialog.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altosuilib; +package org.altusmetrum.altosuilib_1;  import javax.swing.*;  import java.awt.*; diff --git a/altosuilib/AltosFontListener.java b/altosuilib/AltosFontListener.java index ef543264..da903352 100644 --- a/altosuilib/AltosFontListener.java +++ b/altosuilib/AltosFontListener.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altosuilib; +package org.altusmetrum.altosuilib_1;  public interface AltosFontListener {  	void font_size_changed(int font_size); diff --git a/altosuilib/AltosUnitsListener.java b/altosuilib/AltosPositionListener.java index 22c66cd4..e75d2de5 100644 --- a/altosuilib/AltosUnitsListener.java +++ b/altosuilib/AltosPositionListener.java @@ -1,5 +1,5 @@  /* - * Copyright © 2012 Keith Packard <keithp@keithp.com> + * 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 @@ -15,8 +15,8 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altosuilib; +package org.altusmetrum.altosuilib_1; -public interface AltosUnitsListener { -	public void units_changed(); +public interface AltosPositionListener { +	public void position_changed(int position);  } diff --git a/altosuilib/AltosUIAxis.java b/altosuilib/AltosUIAxis.java new file mode 100644 index 00000000..867b0384 --- /dev/null +++ b/altosuilib/AltosUIAxis.java @@ -0,0 +1,94 @@ +/* + * 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.altosuilib_1; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_1.*; + +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.*; + +public class AltosUIAxis extends NumberAxis { +	String		label; +	AltosUnits	units; +	Color		color; +	int		ref; +	int		visible; +	int		index; + +	public final static int	axis_integer = 1; +	public final static int axis_include_zero = 2; + +	public final static int axis_default = axis_include_zero; + +	public void set_units() { +		setLabel(String.format("%s (%s)", label, units.show_units())); +	} +	 +	public void set_enable(boolean enable) { +		if (enable) { +			visible++; +			if (visible > ref) +				System.out.printf("too many visible\n"); +		} else { +			visible--; +			if (visible < 0) +				System.out.printf("too few visible\n"); +		} +		setVisible(visible > 0); +		if (enable) +			autoAdjustRange(); +	} + +	public void ref(boolean enable) { +		++ref; +		if (enable) { +			++visible; +			setVisible(visible > 0); +		} +	} + +	public AltosUIAxis(String label, AltosUnits units, Color color, int index, int flags) { +		this.label = label; +		this.units = units; +		this.index = index; +		this.visible = 0; +		this.ref = 0; +		setLabelPaint(color); +		setTickLabelPaint(color); +		setVisible(false); +		if ((flags & axis_integer) != 0) +			setStandardTickUnits(NumberAxis.createIntegerTickUnits()); +		setAutoRangeIncludesZero((flags & axis_include_zero) != 0); +	} + +	public AltosUIAxis(String label, AltosUnits units, Color color, int index) { +		this(label, units, color, index, axis_default); +	} +} diff --git a/altosuilib/AltosUIConfigure.java b/altosuilib/AltosUIConfigure.java index 6c9a841e..9e72e403 100644 --- a/altosuilib/AltosUIConfigure.java +++ b/altosuilib/AltosUIConfigure.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altosuilib; +package org.altusmetrum.altosuilib_1;  import java.awt.*;  import java.awt.event.*; @@ -202,9 +202,10 @@ public class AltosUIConfigure  		row++;  	} -	public void add_serial_debug() { -		GridBagConstraints c = new GridBagConstraints(); +	public void add_position () { +	} +	public void add_serial_debug() {  		/* Serial debug setting */  		pane.add(new JLabel("Serial Debug"), constraints(0, 1)); @@ -217,12 +218,8 @@ public class AltosUIConfigure  				}  			});  		serial_debug.setToolTipText("Enable/Disable USB I/O getting sent to the console"); -		c.gridx = 1; -		c.gridy = row++; -		c.gridwidth = 3; -		c.fill = GridBagConstraints.NONE; -		c.anchor = GridBagConstraints.WEST; -		pane.add(serial_debug, c); +		pane.add(serial_debug, constraints(1,2)); +		row++;  	}  	public void add_bluetooth() { @@ -253,8 +250,10 @@ public class AltosUIConfigure  		add_log_dir();  		add_callsign();  		add_units(); +		add_serial_debug();  		add_font_size();  		add_look_and_feel(); +		add_position();  		add_bluetooth();  		add_frequencies(); diff --git a/altosuilib/AltosUIDataMissing.java b/altosuilib/AltosUIDataMissing.java new file mode 100644 index 00000000..c7b01859 --- /dev/null +++ b/altosuilib/AltosUIDataMissing.java @@ -0,0 +1,25 @@ +/* + * 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.altosuilib_1; + +public class AltosUIDataMissing extends Exception { +	public int	id; +	public AltosUIDataMissing(int id) { +		this.id = id; +	} +}
\ No newline at end of file diff --git a/altosuilib/AltosUIDataPoint.java b/altosuilib/AltosUIDataPoint.java new file mode 100644 index 00000000..d3020410 --- /dev/null +++ b/altosuilib/AltosUIDataPoint.java @@ -0,0 +1,25 @@ +/* + * 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.altosuilib_1; + +public interface AltosUIDataPoint { +	public abstract double x() throws AltosUIDataMissing; +	public abstract double y(int index) throws AltosUIDataMissing; +	public abstract int id(int index) throws AltosUIDataMissing; +	public abstract String id_name(int index) throws AltosUIDataMissing; +} diff --git a/altosuilib/AltosUIDataSet.java b/altosuilib/AltosUIDataSet.java new file mode 100644 index 00000000..6f23ef9a --- /dev/null +++ b/altosuilib/AltosUIDataSet.java @@ -0,0 +1,23 @@ +/* + * 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.altosuilib_1; + +public interface AltosUIDataSet { +	public abstract String name(); +	public abstract Iterable<AltosUIDataPoint> dataPoints(); +} diff --git a/altosuilib/AltosUIDialog.java b/altosuilib/AltosUIDialog.java index c0c33ba6..e1e699a7 100644 --- a/altosuilib/AltosUIDialog.java +++ b/altosuilib/AltosUIDialog.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altosuilib; +package org.altusmetrum.altosuilib_1;  import java.awt.*;  import java.awt.event.*; diff --git a/altosuilib/AltosUIEnable.java b/altosuilib/AltosUIEnable.java new file mode 100644 index 00000000..55486dea --- /dev/null +++ b/altosuilib/AltosUIEnable.java @@ -0,0 +1,121 @@ +/* + * 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.altosuilib_1; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.io.*; +import java.util.concurrent.*; +import java.util.*; +import org.altusmetrum.altoslib_1.*; + +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.*; + +public class AltosUIEnable extends Container { + +	Insets	il, ir; +	int	y; + +	class GraphElement implements ActionListener { +		AltosUIGrapher	grapher; +		JLabel		label; +		JRadioButton	enable; +		String		name; + +		public void actionPerformed(ActionEvent ae) { +			grapher.set_enable(enable.isSelected()); +		} + +		GraphElement (String name, AltosUIGrapher grapher, boolean enabled) { +			this.name = name; +			this.grapher = grapher; +			label = new JLabel(name); +			enable = new JRadioButton("Enable", enabled); +			grapher.set_enable(enabled);			   +			enable.addActionListener(this); +		} +	} + +	public void add(String name, AltosUIGrapher grapher, boolean enabled) { + +		GraphElement	e = new GraphElement(name, grapher, enabled); + +		/* Add label */ +		GridBagConstraints c = new GridBagConstraints(); +		c.gridx = 0; c.gridy = y; +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = il; +		add(e.label, c); + +		/* Add radio button */ +		c = new GridBagConstraints(); +		c.gridx = 1; c.gridy = y; +		c.fill = GridBagConstraints.HORIZONTAL; +		c.anchor = GridBagConstraints.CENTER; +		c.insets = ir; +		add(e.enable, c); + +		/* Next row */ +		y++; +	} + +	public void add_units() { +		/* Imperial units setting */ +		/* Add label */ +		GridBagConstraints c = new GridBagConstraints(); +		c.gridx = 0; c.gridy = 1000; +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = il; +		add(new JLabel("Imperial Units"), c); + +		JRadioButton imperial_units = new JRadioButton("Enable", AltosUIPreferences.imperial_units()); +		imperial_units.addActionListener(new ActionListener() { +				public void actionPerformed(ActionEvent e) { +					JRadioButton item = (JRadioButton) e.getSource(); +					boolean enabled = item.isSelected(); +					AltosUIPreferences.set_imperial_units(enabled); +				} +			}); +		imperial_units.setToolTipText("Use Imperial units instead of metric"); +		c = new GridBagConstraints(); +		c.gridx = 1; c.gridy = 1000; +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = il; +		add(imperial_units, c); +	} + +	public AltosUIEnable() { +		il = new Insets(4,4,4,4); +		ir = new Insets(4,4,4,4); +		y = 0; +		setLayout(new GridBagLayout()); +		add_units(); +	} +} diff --git a/altosuilib/AltosUIFrame.java b/altosuilib/AltosUIFrame.java index 409aea2e..3fc99910 100644 --- a/altosuilib/AltosUIFrame.java +++ b/altosuilib/AltosUIFrame.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altosuilib; +package org.altusmetrum.altosuilib_1;  import java.awt.*;  import java.awt.event.*; @@ -28,7 +28,7 @@ class AltosUIFrameListener extends WindowAdapter {  	}  } -public class AltosUIFrame extends JFrame implements AltosUIListener { +public class AltosUIFrame extends JFrame implements AltosUIListener, AltosPositionListener {  	public void ui_changed(String look_and_feel) {  		SwingUtilities.updateComponentTreeUI(this); @@ -66,17 +66,108 @@ public class AltosUIFrame extends JFrame implements AltosUIListener {  		setIconImages(icons);  	} +	private boolean location_by_platform = true; -	public AltosUIFrame() { +	public void setLocationByPlatform(boolean lbp) { +		location_by_platform = lbp; +		super.setLocationByPlatform(lbp); +	} +		 +	public void setSize() { +		/* Smash sizes around so that the window comes up in the right shape */ +		Insets i = getInsets(); +		Dimension ps = rootPane.getPreferredSize(); +		ps.width += i.left + i.right; +		ps.height += i.top + i.bottom; +		setPreferredSize(ps); +		setSize(ps); +	} + +	public void setPosition (int position) { +		Insets i = getInsets(); +		Dimension ps = getSize(); + +		/* Stick the window in the desired location on the screen */ +		setLocationByPlatform(false); +		GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); +		GraphicsConfiguration gc = gd.getDefaultConfiguration(); +		Rectangle r = gc.getBounds(); + +		/* compute X position */ +		int x = 0; +		int y = 0; +		switch (position) { +		case AltosUILib.position_top_left: +		case AltosUILib.position_left: +		case AltosUILib.position_bottom_left: +			x = 0; +			break; +		case AltosUILib.position_top: +		case AltosUILib.position_center: +		case AltosUILib.position_bottom: +			x = (r.width - ps.width) / 2; +			break; +		case AltosUILib.position_top_right: +		case AltosUILib.position_right: +		case AltosUILib.position_bottom_right: +			x = r.width - ps.width + i.right; +			break; +		} + +		/* compute Y position */ +		switch (position) { +		case AltosUILib.position_top_left: +		case AltosUILib.position_top: +		case AltosUILib.position_top_right: +			y = 0; +			break; +		case AltosUILib.position_left: +		case AltosUILib.position_center: +		case AltosUILib.position_right: +			y = (r.height - ps.height) / 2; +			break; +		case AltosUILib.position_bottom_left: +		case AltosUILib.position_bottom: +		case AltosUILib.position_bottom_right: +			y = r.height - ps.height + i.bottom; +			break; +		} +		setLocation(x, y); +	} + +	int position; + +	public void position_changed(int position) { +		this.position = position; +		if (!location_by_platform) +			setPosition(position); +	} + +	public void setVisible (boolean visible) { +		if (visible) +			setLocationByPlatform(location_by_platform); +		super.setVisible(visible); +		if (visible) { +			setSize(); +			if (!location_by_platform) +				setPosition(position); +		} +	} +		 +	void init() {  		AltosUIPreferences.register_ui_listener(this); +		AltosUIPreferences.register_position_listener(this); +		position = AltosUIPreferences.position();  		addWindowListener(new AltosUIFrameListener());  		set_icon();  	} +	public AltosUIFrame() { +		init(); +	} +  	public AltosUIFrame(String name) {  		super(name); -		AltosUIPreferences.register_ui_listener(this); -		addWindowListener(new AltosUIFrameListener()); -		set_icon(); +		init();  	}  } diff --git a/altosuilib/AltosUIGraph.java b/altosuilib/AltosUIGraph.java new file mode 100644 index 00000000..5c589c02 --- /dev/null +++ b/altosuilib/AltosUIGraph.java @@ -0,0 +1,155 @@ +/* + * 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.altosuilib_1; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_1.*; + +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.*; + +public class AltosUIGraph implements AltosUnitsListener { + +	XYPlot				plot; +	JFreeChart			chart; +	public ChartPanel		panel; +	NumberAxis			xAxis; +	AltosUIEnable			enable; +	ArrayList<AltosUIGrapher>	graphers; +	AltosUIDataSet			dataSet; +	int				axis_index; +	int				series_index; + +	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); + +	public JPanel panel() { +		return panel; +	} + +	public AltosUIAxis newAxis(String label, AltosUnits units, Color color, int flags) { +		AltosUIAxis axis = new AltosUIAxis(label, units, color, axis_index++, flags); +		plot.setRangeAxis(axis.index, axis); +		return axis; +	} + +	public AltosUIAxis newAxis(String label, AltosUnits units, Color color) { +		return newAxis(label, units, color, AltosUIAxis.axis_default); +	} + +	public void addSeries(String label, int fetch, AltosUnits units, Color color, +			      boolean enabled, AltosUIAxis axis) { +		AltosUISeries		series = new AltosUISeries(label, fetch, units, color, enabled, axis); +		XYSeriesCollection	dataset = new XYSeriesCollection(series); + +		series.renderer.setPlot(plot); +		plot.setDataset(series_index, dataset); +		plot.setRenderer(series_index, series.renderer); +		plot.mapDatasetToRangeAxis(series_index, axis.index); +		if (enable != null) +			enable.add(label, series, enabled); +		this.graphers.add(series); +		series_index++; +	} + +	public void addSeries(String label, int fetch, AltosUnits units, Color color) { +		addSeries(label, fetch, units, color, true, newAxis(label, units, color)); +	} +	 +	public void addMarker(String label, int fetch, Color color) { +		AltosUIMarker		marker = new AltosUIMarker(fetch, color, plot); +		if (enable != null) +			enable.add(label, marker, true); +		this.graphers.add(marker); +	} + +	public void resetData() { +		for (AltosUIGrapher g : graphers) +			g.clear(); +		if (dataSet != null) { +			for (AltosUIDataPoint dataPoint : dataSet.dataPoints()) +				for (AltosUIGrapher g : graphers) +					g.add(dataPoint); +		} +	} + +	public void units_changed(boolean imperial_units) { +		for (AltosUIGrapher g : graphers) +			g.set_units(); +		resetData(); +	} + +	public void setName (String name) { +		chart.setTitle(name); +	} + +	public void setDataSet (AltosUIDataSet dataSet) { +		this.dataSet = dataSet; +		resetData(); +		if (dataSet != null) +			setName(dataSet.name()); +	} + +	public AltosUIGraph(AltosUIEnable enable) { + +		this.enable = enable; +		this.graphers = new ArrayList<AltosUIGrapher>(); +		this.series_index = 0; +		this.axis_index = 0; + +		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); + +		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/altosuilib/AltosUIGrapher.java b/altosuilib/AltosUIGrapher.java new file mode 100644 index 00000000..c627fec5 --- /dev/null +++ b/altosuilib/AltosUIGrapher.java @@ -0,0 +1,46 @@ +/* + * 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.altosuilib_1; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_1.*; + +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.*; + +interface AltosUIGrapher { + +	public abstract void set_units(); +	 +	public abstract void clear(); + +	public abstract void add(AltosUIDataPoint dataPoint); + +	public abstract void set_enable(boolean enable); +} diff --git a/altosuilib/AltosUILib.java b/altosuilib/AltosUILib.java index 5d5f9aaa..1b121405 100644 --- a/altosuilib/AltosUILib.java +++ b/altosuilib/AltosUILib.java @@ -15,12 +15,12 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altosuilib; +package org.altusmetrum.altosuilib_1;  import java.awt.*;  import libaltosJNI.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosUILib extends AltosLib { @@ -36,7 +36,17 @@ public class AltosUILib extends AltosLib {  	final public static int font_size_medium = 2;  	final public static int font_size_large = 3; -	static void set_fonts(int size) { +	final public static int position_top_left = 0; +	final public static int position_top = 1; +	final public static int position_top_right = 2; +	final public static int position_left = 3; +	final public static int position_center = 4; +	final public static int position_right = 5; +	final public static int position_bottom_left = 6; +	final public static int position_bottom = 7; +	final public static int position_bottom_right = 8; + +	public static void set_fonts(int size) {  		int	brief_size;  		int	table_size;  		int	status_size; @@ -66,7 +76,7 @@ public class AltosUILib extends AltosLib {  		table_value_font = new Font("Monospaced", Font.PLAIN, table_size);  	} -	static final int text_width = 20; +	static public final int text_width = 20;  	static public boolean initialized = false;  	static public boolean loaded_library = false; diff --git a/altosuilib/AltosUIListener.java b/altosuilib/AltosUIListener.java index f4127f58..450dc0bf 100644 --- a/altosuilib/AltosUIListener.java +++ b/altosuilib/AltosUIListener.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altosuilib; +package org.altusmetrum.altosuilib_1;  public interface AltosUIListener {  	public void ui_changed(String look_and_feel); diff --git a/altosuilib/AltosUIMarker.java b/altosuilib/AltosUIMarker.java new file mode 100644 index 00000000..e2eb9028 --- /dev/null +++ b/altosuilib/AltosUIMarker.java @@ -0,0 +1,106 @@ +/* + * 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.altosuilib_1; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_1.*; + +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.*; + +public class AltosUIMarker implements AltosUIGrapher { +	ArrayList<ValueMarker>	markers; +	int			last_id; +	XYPlot			plot; +	boolean			enabled; +	int			fetch; +	Color			color; +	 +	private void remove_markers() { +		for (ValueMarker marker : markers) +			plot.removeDomainMarker(marker); +	} + +	private void add_markers() { +		for (ValueMarker marker : markers) +			plot.addDomainMarker(marker); +	} + +	public void set_units() { +	} + +	public void set_enable(boolean enable) { +		if (enabled == enable) +			return; +		if (enable) +			add_markers(); +		else +			remove_markers(); +		enabled = enable; +	} + +	public void clear() { +		if (enabled) +			remove_markers(); +		markers = new ArrayList<ValueMarker>(); +	} + +	public void add(AltosUIDataPoint dataPoint) { +		try { +			int id = dataPoint.id(fetch); +			if (id < 0) +				return; +			if (id == last_id) +				return; +			ValueMarker marker = new ValueMarker(dataPoint.x()); +			marker.setLabel(dataPoint.id_name(fetch)); +			marker.setLabelAnchor(RectangleAnchor.TOP_RIGHT); +			marker.setLabelTextAnchor(TextAnchor.TOP_LEFT); +			marker.setPaint(color); +			if (enabled) +				plot.addDomainMarker(marker); +			markers.add(marker); +			last_id = id; +		} catch (AltosUIDataMissing m) { +		} +	} + +	public AltosUIMarker (int fetch, Color color, XYPlot plot, boolean enable) { +		markers = new ArrayList<ValueMarker>(); +		last_id = -1; +		this.fetch = fetch; +		this.color = color; +		this.plot = plot; +		this.enabled = enable; +	} + +	public AltosUIMarker (int fetch, Color color, XYPlot plot) { +		this(fetch, color, plot, true); +	} +}
\ No newline at end of file diff --git a/altosuilib/AltosUIPreferences.java b/altosuilib/AltosUIPreferences.java index 485cb582..49321bce 100644 --- a/altosuilib/AltosUIPreferences.java +++ b/altosuilib/AltosUIPreferences.java @@ -15,13 +15,13 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altosuilib; +package org.altusmetrum.altosuilib_1;  import java.io.*;  import java.util.*;  import java.awt.Component;  import javax.swing.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  public class AltosUIPreferences extends AltosPreferences { @@ -31,6 +31,9 @@ public class AltosUIPreferences extends AltosPreferences {  	/* Look&Feel preference name */  	final static String lookAndFeelPreference = "LOOK-AND-FEEL"; +	/* Window position preference name */ +	final static String positionPreference = "POSITION"; +  	/* UI Component to pop dialogs up */  	static Component component; @@ -45,6 +48,10 @@ public class AltosUIPreferences extends AltosPreferences {  	/* Serial debug */  	public static boolean serial_debug; +	static LinkedList<AltosPositionListener> position_listeners; + +	public static int position = AltosUILib.position_top_left; +  	public static void init() {  		AltosPreferences.init(new AltosUIPreferencesBackend()); @@ -56,7 +63,11 @@ public class AltosUIPreferences extends AltosPreferences {  		ui_listeners = new LinkedList<AltosUIListener>();  		serial_debug = backend.getBoolean(serialDebugPreference, false); +  		AltosLink.set_debug(serial_debug); + +		position = backend.getInt(positionPreference, AltosUILib.position_top_left); +		position_listeners = new LinkedList<AltosPositionListener>();  	}  	static { init(); } @@ -177,4 +188,31 @@ public class AltosUIPreferences extends AltosPreferences {  		}  	} +	public static void register_position_listener(AltosPositionListener l) { +		synchronized(backend) { +			position_listeners.add(l); +		} +	} + +	public static void unregister_position_listener(AltosPositionListener l) { +		synchronized (backend) { +			position_listeners.remove(l); +		} +	} + +	public static void set_position(int new_position) { +		synchronized (backend) { +			position = new_position; +			backend.putInt(positionPreference, position); +			flush_preferences(); +			for (AltosPositionListener l : position_listeners) +				l.position_changed(position); +		} +	} + +	public static int position() { +		synchronized (backend) { +			return position; +		} +	}  } diff --git a/altosuilib/AltosUIPreferencesBackend.java b/altosuilib/AltosUIPreferencesBackend.java index c6c05e55..8a5386c3 100644 --- a/altosuilib/AltosUIPreferencesBackend.java +++ b/altosuilib/AltosUIPreferencesBackend.java @@ -15,11 +15,11 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altosuilib; +package org.altusmetrum.altosuilib_1;  import java.io.File;  import java.util.prefs.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*;  import javax.swing.filechooser.FileSystemView;  public class AltosUIPreferencesBackend implements AltosPreferencesBackend { diff --git a/altosuilib/AltosUISeries.java b/altosuilib/AltosUISeries.java new file mode 100644 index 00000000..ac09a3cc --- /dev/null +++ b/altosuilib/AltosUISeries.java @@ -0,0 +1,91 @@ +/* + * 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.altosuilib_1; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_1.*; + +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.*; + +public class AltosUISeries extends XYSeries implements AltosUIGrapher { +	AltosUIAxis	axis; +	String		label; +	AltosUnits	units; +	Color		color; +	XYItemRenderer	renderer; +	int		fetch; +	boolean		enable; +	 +	public void set_units() { +		axis.set_units(); +		StandardXYToolTipGenerator	ttg; + +		String  example = units.graph_format(4); + +		ttg = new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})", +								   units.show_units()), +						     new java.text.DecimalFormat(example), +						     new java.text.DecimalFormat(example)); +		renderer.setBaseToolTipGenerator(ttg); +	} + +	public void set_enable(boolean enable) { +		if (this.enable != enable) { +			this.enable = enable; +			renderer.setSeriesVisible(0, enable); +			axis.set_enable(enable); +		} +	} + +	public void add(AltosUIDataPoint dataPoint) { +		try { +			super.add(dataPoint.x(), units.value(dataPoint.y(fetch))); +		} catch (AltosUIDataMissing dm) { +		} +	} + +	public AltosUISeries (String label, int fetch, AltosUnits units, Color color, +			      boolean enable, AltosUIAxis axis) { +		super(label); +		this.label = label; +		this.fetch = fetch; +		this.units = units; +		this.color = color; +		this.enable = enable; +		this.axis = axis; + +		axis.ref(this.enable); + +		renderer = new XYLineAndShapeRenderer(true, false); +		renderer.setSeriesPaint(0, color); +		renderer.setSeriesVisible(0, enable); +		set_units(); +	} +} diff --git a/altosuilib/AltosUIVersion.java.in b/altosuilib/AltosUIVersion.java.in index 6fb3b38b..169cca1b 100644 --- a/altosuilib/AltosUIVersion.java.in +++ b/altosuilib/AltosUIVersion.java.in @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altosuilib; +package org.altusmetrum.altosuilib_1;  public class AltosUIVersion {  	public final static String version = "@VERSION@"; diff --git a/altosuilib/AltosUSBDevice.java b/altosuilib/AltosUSBDevice.java index bab16fb0..a5496597 100644 --- a/altosuilib/AltosUSBDevice.java +++ b/altosuilib/AltosUSBDevice.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altosuilib; +package org.altusmetrum.altosuilib_1;  import java.util.*;  import libaltosJNI.*; diff --git a/altosuilib/Makefile.am b/altosuilib/Makefile.am index da5fb848..0cd2aaea 100644 --- a/altosuilib/Makefile.am +++ b/altosuilib/Makefile.am @@ -9,21 +9,30 @@ SRC=.  altosuilibdir = $(datadir)/java  altosuilib_JAVA = \ -	AltosUIConfigure.java \  	AltosDevice.java \  	AltosDeviceDialog.java \ -	AltosUSBDevice.java \  	AltosFontListener.java \ +	AltosPositionListener.java \ +	AltosUIConfigure.java \ +	AltosUIAxis.java \ +	AltosUIDataMissing.java \ +	AltosUIDataPoint.java \ +	AltosUIDataSet.java \ +	AltosUIGraph.java \ +	AltosUIGrapher.java \  	AltosUIDialog.java \ +	AltosUIEnable.java \  	AltosUIFrame.java \  	AltosUILib.java \  	AltosUIListener.java \ +	AltosUIMarker.java \  	AltosUIPreferencesBackend.java \  	AltosUIPreferences.java \ +	AltosUISeries.java \  	AltosUIVersion.java \ -	AltosUnitsListener.java +	AltosUSBDevice.java -JAR=altosuilib.jar +JAR=altosuilib_$(ALTOSUILIB_VERSION).jar  all-local: $(JAR) diff --git a/configure.ac b/configure.ac index ee685344..448df6a4 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl  dnl Process this file with autoconf to create configure.  AC_PREREQ(2.57) -AC_INIT([altos], 1.1.9.2) +AC_INIT([altos], 1.2)  AC_CONFIG_SRCDIR([src/core/ao.h])  AM_INIT_AUTOMAKE([foreign dist-bzip2])  AM_MAINTAINER_MODE @@ -26,6 +26,18 @@ AM_MAINTAINER_MODE  VERSION_DASH=`echo $VERSION | sed 's/\./-/g'`  AC_SUBST(VERSION_DASH) + +dnl ========================================================================== +dnl Java library versions + +ALTOSUILIB_VERSION=1 +ALTOSLIB_VERSION=1 + +AC_SUBST(ALTOSLIB_VERSION) +AC_DEFINE(ALTOSLIB_VERSION,$ALTOSLIB_VERSION,[Version of the AltosLib package]) +AC_SUBST(ALTOSUILIB_VERSION) +AC_DEFINE(ALTOSUILIB_VERSION,$ALTOSUILIB_VERSION,[Version of the AltosUILib package]) +  dnl ==========================================================================  AM_CONFIG_HEADER(config.h) @@ -150,9 +162,11 @@ altosuilib/Makefile  altosuilib/AltosUIVersion.java  altosui/Makefile  altosui/Info.plist +altosui/altos-windows.nsi  libaltos/Makefile  micropeak/Makefile  micropeak/Info.plist +micropeak/micropeak-windows.nsi  altosdroid/Makefile  altosdroid/local.properties  ao-tools/Makefile diff --git a/doc/Makefile b/doc/Makefile index 53985431..59fd4ebb 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -18,6 +18,7 @@ DOC=$(HTML) $(PDF)  HTMLSTYLE=/usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl  FOSTYLE=/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl  PDFSTYLE= +IMAGES=telemetrum.svg telemini.svg  .SUFFIXES: .xsl .html .fo .pdf @@ -50,8 +51,8 @@ clean:  distclean:  	rm -f $(HTML) $(PDF) *.fo -altusmetrum.html: $(RELNOTES_XSL) -altusmetrum.fo: $(RELNOTES_XSL) +altusmetrum.html: $(RELNOTES_XSL) $(IMAGES) +altusmetrum.fo: $(RELNOTES_XSL) $(IMAGES)  indent:		altusmetrum.xsl  	xmlindent -i 2 < altusmetrum.xsl > altusmetrum.new diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 55f02e26..9fdd6b07 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -22,7 +22,7 @@        <surname>Towns</surname>      </author>      <copyright> -      <year>2012</year> +      <year>2013</year>        <holder>Bdale Garbee and Keith Packard</holder>      </copyright>      <legalnotice> @@ -122,7 +122,7 @@ NAR #88757, TRA #12200        support optional capabilities in the future.      </para>      <para> -      The newest device is TeleMini, a dual deploy altimeter with +      Our second device was TeleMini, a dual deploy altimeter with        radio telemetry and radio direction finding. This device is only        13mm by 38mm (½ inch by 1½ inches) and can fit easily in an 18mm         air-frame. @@ -172,8 +172,9 @@ NAR #88757, TRA #12200      <para>        The TeleMini battery can be charged by disconnecting it from the        TeleMini board and plugging it into a standalone battery charger  -      board, and connecting that via a USB cable to a laptop or other USB -      power source +      such as the LipoCharger product included in TeleMini Starter Kits,  +      and connecting that via a USB cable to a laptop or other USB +      power source.        </para>      <para>        The other active device in the starter kit is the TeleDongle USB to @@ -1583,7 +1584,9 @@ NAR #88757, TRA #12200          <title>On the Ground</title>          <para>            To receive the data stream from the rocket, you need an antenna and short -          feed-line connected to one of our <ulink url="http://www.altusmetrum.org/TeleDongle/">TeleDongle</ulink> units.  The +          feed-line connected to one of our <ulink url="http://www.altusmetrum.org/TeleDongle/">TeleDongle</ulink> units.  If possible, use an SMA to BNC  +	adapter instead of feedline between the antenna feedpoint and  +	TeleDongle, as this will give you the best performance.  The            TeleDongle in turn plugs directly into the USB port on a notebook            computer.  Because TeleDongle looks like a simple serial port, your computer            does not require special device drivers... just plug it in. @@ -1620,7 +1623,7 @@ NAR #88757, TRA #12200            So, to recap, on the ground the hardware you'll need includes:            <orderedlist inheritnum='inherit' numeration='arabic'>              <listitem> -              an antenna and feed-line +              an antenna and feed-line or adapter              </listitem>              <listitem>                a TeleDongle @@ -1643,7 +1646,9 @@ NAR #88757, TRA #12200              Arrow Antennas.            </ulink>            The 440-3 and 440-5 are both good choices for finding a -          TeleMetrum- or TeleMini- equipped rocket when used with a suitable 70cm HT. +          TeleMetrum- or TeleMini- equipped rocket when used with a suitable  +	  70cm HT.  TeleDongle and an SMA to BNC adapter fit perfectly +	  between the driven element and reflector of Arrow antennas.          </para>        </section>        <section> @@ -1669,22 +1674,36 @@ NAR #88757, TRA #12200        <section>          <title>Future Plans</title>          <para> -          In the future, we intend to offer "companion boards" for the rocket that will -          plug in to TeleMetrum to collect additional data, provide more pyro channels, -          and so forth.   +          In the future, we intend to offer "companion boards" for the rocket  +	  that will plug in to TeleMetrum to collect additional data, provide  +	  more pyro channels, and so forth.            </para>          <para> -          We are also working on the design of a hand-held ground terminal that will -          allow monitoring the rocket's status, collecting data during flight, and -          logging data after flight without the need for a notebook computer on the -          flight line.  Particularly since it is so difficult to read most notebook -          screens in direct sunlight, we think this will be a great thing to have. +	  Also under design is a new flight computer with more sensors, more +	  pyro channels, and a more powerful radio system designed for use +	  in multi-stage, complex, and extreme altitude projects.          </para>          <para> -          Because all of our work is open, both the hardware designs and the software, -          if you have some great idea for an addition to the current Altus Metrum family, -          feel free to dive in and help!  Or let us know what you'd like to see that -          we aren't already working on, and maybe we'll get excited about it too... +          We are also working on alternatives to TeleDongle.  One is a +	  a stand-alone, hand-held ground terminal that will allow monitoring  +	  the rocket's status, collecting data during flight, and logging data  +	  after flight without the need for a notebook computer on the +          flight line.  Particularly since it is so difficult to read most  +	  notebook screens in direct sunlight, we think this will be a great  +	  thing to have.  We are also working on a TeleDongle variant with +	  Bluetooth that will work with Android phones and tablets. +        </para> +        <para> +          Because all of our work is open, both the hardware designs and the  +	  software, if you have some great idea for an addition to the current  +	  Altus Metrum family, feel free to dive in and help!  Or let us know  +	  what you'd like to see that we aren't already working on, and maybe  +	  we'll get excited about it too... +        </para> +        <para> +	  Watch our  +	  <ulink url="http://altusmetrum.org/">web site</ulink> for more news  +	  and information as our family of products evolves!          </para>      </section>    </chapter> @@ -2492,6 +2511,37 @@ NAR #88757, TRA #12200      </para>    </appendix>    <appendix> +    <title>Drill Templates</title> +    <para> +      These images, when printed, provide precise templates for the +      mounting holes in Altus Metrum flight computers +    </para> +    <section> +      <title>TeleMetrum template</title> +      <para> +	TeleMetrum has overall dimensions of 1.000 x 2.750 inches, and the +	mounting holes are sized for use with 4-40 or M3 screws. +      </para> +      <mediaobject id="TeleMetrumTemplate"> +	<imageobject> +	  <imagedata format="SVG" fileref="telemetrum.svg"/> +	</imageobject> +      </mediaobject> +    </section> +    <section> +      <title>TeleMini template</title> +      <para> +	TeleMini has overall dimensions of 0.500 x 1.500 inches, and the +	mounting holes are sized for use with 2-56 or M2 screws. +      </para> +      <mediaobject id="TeleMiniTemplate"> +	<imageobject> +	  <imagedata format="SVG" fileref="telemini.svg"/> +	</imageobject> +      </mediaobject> +    </section> +  </appendix> +  <appendix>        <title>Calibration</title>        <para>          There are only two calibrations required for a TeleMetrum board, and diff --git a/doc/micropeak.xsl b/doc/micropeak.xsl index aa1adaef..2120acb2 100644 --- a/doc/micropeak.xsl +++ b/doc/micropeak.xsl @@ -3,7 +3,7 @@    "/usr/share/xml/docbook/schema/dtd/4.5/docbookx.dtd">  <book>    <title>MicroPeak Owner's Manual</title> -  <subtitle>A peak-recording altimeter for hobby rocketry</subtitle> +  <subtitle>A recording altimeter for hobby rocketry</subtitle>    <bookinfo>      <author>        <firstname>Keith</firstname> @@ -44,6 +44,15 @@  	  Add comments about EEPROM storage format and programming jig.  	</revremark>        </revision> +      <revision> +	<revnumber>1.2</revnumber> +	<date>20 January 2013</date> +	<revremark> +	  Add documentation for the MicroPeak USB adapter board. Note +	  the switch to a Kalman filter for peak altitude +	  determination. +	</revremark> +      </revision>      </revhistory>    </bookinfo>    <acknowledgements> @@ -176,6 +185,176 @@ NAR #88757, TRA #12200      </para>    </chapter>    <chapter> +    <title>The MicroPeak USB adapter</title> +    <para> +      MicroPeak stores barometric pressure information for the first +      48 seconds of the flight in on-board non-volatile memory. The +      contents of this memory can be downloaded to a computer using +      the MicroPeak USB adapter. +    </para> +    <section> +      <title>Installing the MicroPeak software</title> +      <para> +	The MicroPeak application runs on Linux, Mac OS X and +	Windows. You can download the latest version from +	<ulink url="http://altusmetrum.org/AltOS"/>. +      </para> +      <para> +	On Mac OS X and Windows, the FTDI USB device driver needs to +	be installed. A compatible version of this driver is included +	with the MicroPeak application, but you may want to download a +	newer version from <ulink +	url="http://www.ftdichip.com/FTDrivers.htm"/>. +      </para> +    </section> +    <section> +      <title>Downloading Micro Peak data</title> +      <itemizedlist> +	<listitem> +	  <para> +	    Connect the MicroPeak USB adapter to a USB cable and plug it +	    in to your computer. +	  </para> +	</listitem> +	<listitem> +	  <para> +	    Start the MicroPeak application, locate the File menu and +	    select the Download entry. +	  </para> +	</listitem> +	<listitem> +	  <para> +	    The MicroPeak USB adapter has a small phototransistor on the  +	    end of the board furthest from the USB connector. Locate +	    this and place the LED on the MicroPeak right over +	    it. Turn on the MicroPeak board and adjust the position +	    until the blue LED on the MicroPeak USB adapter blinks in +	    time with the orange LED on the MicroPeak board. +	  </para> +	</listitem> +	<listitem> +	  <para> +	    After the maximum flight height is reported, MicroPeak will +	    pause for a few seconds, blink the LED four times rapidly +	    and then send the data in one long blur on the LED. The +	    MicroPeak application should receive the data. When it does, +	    it will present the data in a graph and offer to save the +	    data to a file. If not, you can power cycle the MicroPeak +	    board and try again. +	  </para> +	</listitem> +      </itemizedlist> +    </section> +    <section> +      <title>Analyzing MicroPeak Data</title> +      <para> +	The MicroPeak application can present flight data in the form +	of a graph, a collection of computed statistics or in tabular +	form. +      </para> +      <para> +	MicroPeak collects raw barometric pressure data which is +	then used to compute the remaining data. Altitude is computed +	through a standard atmospheric model. Absolute error in this +	data will be affected by local atmospheric +	conditions. Fortunately, these errors tend to mostly cancel +	out, so the error in the height computation is much smaller +	than the error in altitude would be. +      </para> +      <para> +	Speed and acceleration are computed by first smoothing the +	height data with a Gaussian window averaging filter. For speed +	data, this average uses seven samples. For acceleration data, +	eleven samples are used. These were chosen to provide +	reasonably smooth speed and acceleration data, which would +	otherwise be swamped with noise. +      </para> +      <para> +	Under the Graph tab, the height, speed and acceleration values +	are displayed together. You can zoom in on the graph by +	clicking and dragging to sweep out an area of +	interest. Right-click on the plot to bring up a menu that will +	let you save, copy or print the graph. +      </para> +      <para> +	The Statistics tab presents overall data from the flight. Note +	that the Maximum height value is taken from the minumum +	pressure captured in flight, and may be different from the +	apparant apogee value as the on-board data are sampled twice +	as fast as the recorded values, or because the true apogee +	occurred after the on-board memory was full. Each value is +	presented in several units as appropriate. +      </para> +      <para> +	A table consisting of the both the raw barometric pressure +	data and values computed from that for each recorded time. +      </para> +      <para> +	The File menu has operations to open existing flight logs, +	Download new data from MicroPeak, Save a copy of the flight +	log to a new file, Export the tabular data (as seen in the Raw +	Data tab) to a file, change the application Preferences, Close +	the current window or close all windows and Exit the +	application. +      </para> +    </section> +    <section> +      <title>Configuring the MicroPeak application</title> +      <para> +	The MicroPeak application has a few user settings which are +	configured through the Preferences dialog, which can be +	accessed from the File menu. +      <itemizedlist> +	<listitem> +	  <para> +	    The Log Directory is where flight data will be saved to +	    and loaded from by default. Of course, you can always +	    navigate to other directories in the file chooser windows, +	    this setting is just the starting point. +	  </para> +	</listitem> +	<listitem> +	  <para> +	    If you prefer to see your graph data in feet and +	    miles per hour instead of meters and meters per second, +	    you can select Imperial Units. +	  </para> +	</listitem> +	<listitem> +	  <para> +	    To see what data is actually arriving over the serial +	    port, start the MicroPeak application from a command +	    prompt and select the Serial Debug option. This can be +	    useful in debugging serial communication problems, but +	    most people need never choose this. +	  </para> +	</listitem> +	<listitem> +	  <para> +	    You can adjust the size of the text in the Statistics tab +	    by changing the Font size preference. There are three +	    settings, with luck one will both fit on your screen and +	    provide readable values. +	  </para> +	</listitem> +	<listitem> +	  <para> +	    The Look & feel menu shows a list of available +	    application appearance choices. By default, the MicroPeak +	    application tries to blend in with other applications, but +	    you may choose some other appearance if you like. +	  </para> +	</listitem> +      </itemizedlist> +      </para> +      <para> +	Note that MicroPeak shares a subset of the AltosUI +	preferences, so if you use both of these applications, change +	in one application will affect the other. +      </para> +    </section> +  </chapter> +  <chapter>      <title>Technical Information</title>      <section>        <title>Barometric Sensor</title> @@ -193,8 +372,8 @@ NAR #88757, TRA #12200        <para>  	Ground pressure is computed from an average of 16 samples,  	taken while the altimeter is at rest. Flight pressure is -	computed from an exponential IIR filter designed to smooth out -	transients caused by mechanical stress on the barometer. +	computed from a Kalman filter designed to smooth out any minor +	noise in the sensor values.         </para>      </section>      <section> diff --git a/doc/telemetrum.svg b/doc/telemetrum.svg new file mode 100644 index 00000000..97c4e4a8 --- /dev/null +++ b/doc/telemetrum.svg @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> + +<svg +       xmlns:dc="http://purl.org/dc/elements/1.1/" +   xmlns:cc="http://creativecommons.org/ns#" +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +   xmlns:svg="http://www.w3.org/2000/svg" +   xmlns="http://www.w3.org/2000/svg" +   width="5in" +   height="2.5in" +   viewBox="0 0 500 250" +   preserveaspectratio="none" +   id="svg2" +   version="1.1"> +  <g transform="translate(112.5,75)" +     style="fill:none;stroke:#000000;stroke-width:1;stroke-linejoin:miter;font-family:Frutiger LT Std"> +    <!-- outline --> +    <rect width="275" height="100" x="0" y="0"/> +    <!-- holes --> +    <path d="M37.5,12.5 m-6.25,0 a6.25,6.25,0,1,0,12.5,0 a6.25,6.25,0,1,0,-12.5,0 l12.5,0 m-6.25,-6.25 l0,12.5"/> +    <path d="M262.5,12.5 m-6.25,0 a6.25,6.25,0,1,0,12.5,0 a6.25,6.25,0,1,0,-12.5,0 l12.5,0 m-6.25,-6.25 l0,12.5"/> +    <path d="M37.5,87.5 m-6.25,0 a6.25,6.25,0,1,0,12.5,0 a6.25,6.25,0,1,0,-12.5,0 l12.5,0 m-6.25,-6.25 l0,12.5"/> +    <path d="M262.5,87.5 m-6.25,0 a6.25,6.25,0,1,0,12.5,0 a6.25,6.25,0,1,0,-12.5,0 l12.5,0 m-6.25,-6.25 l0,12.5"/> +    <!-- arrow --> +    <path d="M50,50 l165,0"/> +    <path style="fill:#000000;stroke:none" d="M215,45 l10,5 l-10,5 z"/> +    <!-- label --> +    <text x="137.5" y="45" style="fill:#000000;stroke:none" text-anchor="middle">TeleMetrum</text> +    <g transform="rotate(90)"> +      <text x="50" y="-235" style="fill:#000000;stroke:none" text-anchor="middle">UP</text> +    </g> +  </g> +</svg>
\ No newline at end of file diff --git a/doc/telemini.svg b/doc/telemini.svg new file mode 100644 index 00000000..d07b4971 --- /dev/null +++ b/doc/telemini.svg @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> + +<svg +       xmlns:dc="http://purl.org/dc/elements/1.1/" +   xmlns:cc="http://creativecommons.org/ns#" +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +   xmlns:svg="http://www.w3.org/2000/svg" +   xmlns="http://www.w3.org/2000/svg" +   width="5in" +   height="2in" +   viewBox="0 0 500 200" +   preserveaspectratio="none" +   id="svg2" +   version="1.1"> +  <g transform="translate(175,75)" +     style="fill:none;stroke:#000000;stroke-width:1;stroke-linejoin:miter;font-family:Frutiger LT Std"> +    <!-- outline --> +    <rect width="150" height="50" x="0" y="0"/> +    <!-- holes --> +    <path d="M135,10 A5,5,0,1,0,145,10 A5,5,0,1,0,135,10 M135,10 l10,0 M140,5 l0,10"/> +    <path d="M135,40 A5,5,0,1,0,145,40 A5,5,0,1,0,135,40 M135,40 l10,0 M140,35 l0,10"/> +    <!-- arrow --> +    <path d="M25,25 l90,0"/> +    <path style="fill:#000000;stroke:none" d="M115,20 l10,5 l-10,5 z"/> +    <!-- label --> +    <text x="75" y="20" style="fill:#000000;stroke:none" text-anchor="middle">TeleMini</text> +    <g transform="rotate(90)"> +      <text x="25" y="-130" style="fill:#000000;stroke:none" text-anchor="middle">UP</text> +    </g> +  </g> +</svg>
\ No newline at end of file diff --git a/fix-java-versions b/fix-java-versions new file mode 100755 index 00000000..a417b67c --- /dev/null +++ b/fix-java-versions @@ -0,0 +1,11 @@ +#!/bin/sh -vx + +sed_opts='-i' + +for i in "$@"; do +	name=`echo $i | sed 's/=.*$//'` +	value=`echo $i | sed 's/.*=//'` +	sed_opts="$sed_opts -e s/${name}_*[0-9]*/${name}_${value}/g" +done + +find . -name '*.java*' -print0 | xargs -0 sed $sed_opts diff --git a/micropeak/.gitignore b/micropeak/.gitignore index fc99b31c..ab80492b 100644 --- a/micropeak/.gitignore +++ b/micropeak/.gitignore @@ -1,6 +1,19 @@  *.jar  Manifest.txt +Manifest-fat.txt  classes  *.stamp  micropeak  micropeak-test +micropeak-jdb +micropeak-windows.log +MicroPeak-Linux-* +MicroPeak-Mac-* +MicroPeak-Windows-* +*.dll +*.dylib +*.so +linux +macosx +CDM*.exe +FTDI*.dmg diff --git a/micropeak/FTDI.tar.gz b/micropeak/FTDI.tar.gzBinary files differ deleted file mode 100644 index cd08ecf2..00000000 --- a/micropeak/FTDI.tar.gz +++ /dev/null diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am index 4a7aaaa1..d45ecab9 100644 --- a/micropeak/Makefile.am +++ b/micropeak/Makefile.am @@ -44,10 +44,10 @@ LIBALTOS= \  	altos.dll  ALTOSLIB_CLASS=\ -	AltosLib.jar +	altoslib_$(ALTOSLIB_VERSION).jar  ALTOSUILIB_CLASS=\ -	altosuilib.jar +	altosuilib_$(ALTOSUILIB_VERSION).jar  # Icons  ICONDIR=$(top_srcdir)/icon @@ -74,27 +74,41 @@ all-local: micropeak-test micropeak-jdb $(JAR)  clean-local:  	-rm -rf classes $(JAR) $(FATJAR) \ -		$(LINUX_DIST) $(MACOSX_DIST) windows $(WINDOWS_DIST) \ +		MicroPeak-Linux-*.tar.bz2 MicroPeak-Mac-*.dmg MicroPeak-Windows-*.exe \  		$(ALTOSLIB_CLASS) \  		$(ALTOSUILIB_CLASS) \ -		$(JFREECHART_CLASS) $(JCOMMON_CLASS) $(LIBALTOS) Manifest.txt \ -		micropeak micropeak-test macosx linux windows +		$(JFREECHART_CLASS) $(JCOMMON_CLASS) $(LIBALTOS) Manifest.txt Manifest-fat.txt \ +		micropeak micropeak-test micropeak-jdb macosx linux windows micropeak-windows.log  LINUX_DIST=MicroPeak-Linux-$(VERSION).tar.bz2  MACOSX_DIST=MicroPeak-Mac-$(VERSION).dmg  WINDOWS_DIST=MicroPeak-Windows-$(VERSION_DASH).exe +MICROPEAK_DOC=$(top_srcdir)/doc/micropeak.pdf + +DOC=$(MICROPEAK_DOC) +  FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS)  LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC)  LINUX_EXTRA=micropeak-fat +MACOSX_DRIVER_URL=http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_2_18.dmg +MACOSX_DRIVER=FTDIUSBSerialDriver_v2_2_18.dmg  MACOSX_INFO_PLIST=Info.plist -MACOSX_DRIVER=FTDI.tar.gz  MACOSX_README=ReadMe-Mac.rtf -MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(MACOSX_DRIVER) $(MACOSX_README) +MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(MACOSX_DRIVER) $(MACOSX_README) $(DOC) + +$(MACOSX_DRIVER): +	wget $(MACOSX_DRIVER_URL) + +WINDOWS_DRIVER_URL=http://www.ftdichip.com/Drivers/CDM/CDM20824_Setup.exe +WINDOWS_DRIVER=CDM20824_Setup.exe + +$(WINDOWS_DRIVER): +	wget $(WINDOWS_DRIVER_URL) -WINDOWS_FILES=$(FAT_FILES) altos.dll altos64.dll $(top_srcdir)/telemetrum.inf $(WINDOWS_ICON) +WINDOWS_FILES=$(FAT_FILES) altos.dll altos64.dll $(DOC) $(WINDOWS_ICON) $(WINDOWS_DRIVER)  if FATINSTALL @@ -218,8 +232,9 @@ $(MACOSX_DIST): $(MACOSX_FILES)  	mkdir macosx  	cp -a MicroPeak.app macosx/  	cp -a $(MACOSX_README) macosx/ReadMe.rtf +	cp -a $(DOC) macosx  	cp -p Info.plist macosx/MicroPeak.app/Contents -	tar xzf $(MACOSX_DRIVER) -C macosx +	cp -p $(MACOSX_DRIVER) 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 diff --git a/micropeak/MicroData.java b/micropeak/MicroData.java index 71919ddb..4c0ed4c3 100644 --- a/micropeak/MicroData.java +++ b/micropeak/MicroData.java @@ -20,7 +20,8 @@ package org.altusmetrum.micropeak;  import java.lang.*;  import java.io.*;  import java.util.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  class MicroIterator implements Iterator<MicroDataPoint> {  	int		i; @@ -56,7 +57,40 @@ class MicroIterable implements Iterable<MicroDataPoint> {  	}  } -public class MicroData { +class MicroUIIterator implements Iterator<AltosUIDataPoint> { +	int		i; +	MicroData	data; + +	public boolean hasNext() { +		return i < data.pressures.length; +	} + +	public AltosUIDataPoint next() { +		return new MicroDataPoint(data, i++); +	} + +	public MicroUIIterator (MicroData data) { +		this.data = data; +		i = 0; +	} + +	public void remove() { +	} +} + +class MicroUIIterable implements Iterable<AltosUIDataPoint> { +	MicroData	data; + +	public Iterator<AltosUIDataPoint> iterator() { +		return new MicroUIIterator(data); +	} + +	public MicroUIIterable(MicroData data) { +		this.data = data; +	} +} + +public class MicroData implements AltosUIDataSet {  	public int		ground_pressure;  	public int		min_pressure;  	public int[]		pressures; @@ -64,8 +98,8 @@ public class MicroData {  	private double		ground_altitude;  	private ArrayList<Integer>	bytes;  	String			name; +	MicroStats		stats; -  	class FileEndedException extends Exception {  	} @@ -178,6 +212,14 @@ public class MicroData {  		return AltosConvert.pressure_to_altitude(pressures[i]);  	} +	public String name() { +		return name; +	} + +	public Iterable<AltosUIDataPoint> dataPoints() { +		return new MicroUIIterable(this); +	} +  	public Iterable<MicroDataPoint> points() {  		return new MicroIterable(this);  	} @@ -339,6 +381,7 @@ public class MicroData {  			crc_valid = crc == current_crc;  			time_step = 0.192; +			stats = new MicroStats(this);  		} catch (FileEndedException fe) {  			throw new IOException("File Ended Unexpectedly");  		} catch (NonHexcharException ne) { diff --git a/micropeak/MicroDataPoint.java b/micropeak/MicroDataPoint.java index c58708e6..61faf794 100644 --- a/micropeak/MicroDataPoint.java +++ b/micropeak/MicroDataPoint.java @@ -17,19 +17,58 @@  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) { +import org.altusmetrum.altosuilib_1.*; + +public class MicroDataPoint implements AltosUIDataPoint { +	public double		time; +	public double		pressure; +	public double		height; +	public double		speed; +	public double		accel; +	public MicroStats	stats; + +	public static final int data_height = 0; +	public static final int data_speed = 1; +	public static final int data_accel = 2; +	public static final int data_state = 3; + +	public double x() { +		return time; +	} + +	public double y(int index) { +		switch (index) { +		case data_height: +			return height; +		case data_speed: +			return speed; +		case data_accel: +			return accel; +		default: +			return 0; +		} +	} + +	public int id(int index) { +		if (index == data_state) { +			return stats.state(time); +		} +		return 0; +	} + +	public String id_name(int index) { +		if (index == data_state) +			return stats.state_name(time); +		return ""; +	} + +	public MicroDataPoint (double pressure, double height, double speed, double accel, double time, MicroStats stats) {  		this.pressure = pressure;  		this.height = height;  		this.speed = speed;  		this.accel = accel;  		this.time = time; +		this.stats = stats;  	}  	public MicroDataPoint(MicroData data, int i) { @@ -37,6 +76,7 @@ public class MicroDataPoint {  		     data.height(i),  		     data.speed(i),  		     data.acceleration(i), -		     data.time(i)); +		     data.time(i), +		     data.stats);  	}  }
\ No newline at end of file diff --git a/micropeak/MicroDeviceDialog.java b/micropeak/MicroDeviceDialog.java index 23195dac..533605d6 100644 --- a/micropeak/MicroDeviceDialog.java +++ b/micropeak/MicroDeviceDialog.java @@ -21,7 +21,7 @@ import javax.swing.*;  import java.awt.*;  import java.awt.event.*;  import java.util.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class MicroDeviceDialog extends AltosDeviceDialog { diff --git a/micropeak/MicroDownload.java b/micropeak/MicroDownload.java index 28a7550d..6f0ca4f6 100644 --- a/micropeak/MicroDownload.java +++ b/micropeak/MicroDownload.java @@ -23,8 +23,8 @@ import javax.swing.*;  import java.io.*;  import java.util.concurrent.*;  import java.util.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener {  	MicroPeak	owner; diff --git a/micropeak/MicroExport.java b/micropeak/MicroExport.java index 4b83bb4d..20a6f79a 100644 --- a/micropeak/MicroExport.java +++ b/micropeak/MicroExport.java @@ -23,8 +23,8 @@ import java.util.ArrayList;  import java.awt.*;  import javax.swing.*;  import javax.swing.filechooser.FileNameExtensionFilter; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class MicroExport extends JFileChooser { diff --git a/micropeak/MicroFile.java b/micropeak/MicroFile.java index 13d48380..cdd42e66 100644 --- a/micropeak/MicroFile.java +++ b/micropeak/MicroFile.java @@ -19,8 +19,8 @@ package org.altusmetrum.micropeak;  import java.io.*;  import java.util.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class MicroFile { diff --git a/micropeak/MicroFileChooser.java b/micropeak/MicroFileChooser.java index 21ddb0f8..7a3423b4 100644 --- a/micropeak/MicroFileChooser.java +++ b/micropeak/MicroFileChooser.java @@ -20,8 +20,8 @@ package org.altusmetrum.micropeak;  import javax.swing.*;  import javax.swing.filechooser.FileNameExtensionFilter;  import java.io.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class MicroFileChooser extends JFileChooser {  	JFrame	frame; diff --git a/micropeak/MicroFrame.java b/micropeak/MicroFrame.java index 03e3af0c..ef8b24cc 100644 --- a/micropeak/MicroFrame.java +++ b/micropeak/MicroFrame.java @@ -21,7 +21,7 @@ import java.awt.*;  import java.awt.event.*;  import javax.swing.*;  import java.util.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class MicroFrame extends AltosUIFrame {  	static String[] micro_icon_names = { diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java index 5aa127bb..50508a61 100644 --- a/micropeak/MicroGraph.java +++ b/micropeak/MicroGraph.java @@ -22,7 +22,8 @@ import java.util.ArrayList;  import java.awt.*;  import javax.swing.*; -import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  import org.jfree.ui.*;  import org.jfree.chart.*; @@ -34,146 +35,19 @@ 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); -	} - -	void set_enable(boolean enable) { -		renderer.setSeriesVisible(0, enable); -		axis.setVisible(enable); -	} - -	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; +public class MicroGraph extends AltosUIGraph {  	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)); -			} -		} -//		accelSeries.set_enable(false); -	} - -	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); +	static final private Color state_color = new Color(3,3,3); -		chart.setBackgroundPaint(background_color); -		chart.setBorderPaint(border_color); -		panel = new ChartPanel(chart); -		panel.setMouseWheelEnabled(true); -		panel.setPreferredSize(new java.awt.Dimension(800, 500)); +	public MicroGraph(AltosUIEnable enable) { +		super(enable); -		AltosPreferences.register_units_listener(this); +		addSeries("Height", MicroDataPoint.data_height, AltosConvert.height, height_color); +		addSeries("Speed", MicroDataPoint.data_speed, AltosConvert.speed, speed_color); +		addSeries("Acceleration", MicroDataPoint.data_accel, AltosConvert.accel, accel_color); +		addMarker("State", MicroDataPoint.data_state, state_color);  	}  }
\ No newline at end of file diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java index 5d128dfd..57f17dbe 100644 --- a/micropeak/MicroPeak.java +++ b/micropeak/MicroPeak.java @@ -23,16 +23,18 @@ import javax.swing.*;  import java.io.*;  import java.util.concurrent.*;  import java.util.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class MicroPeak extends MicroFrame implements ActionListener, ItemListener {  	File		filename;  	MicroGraph	graph; -	MicroStatsTable	stats; +	AltosUIEnable	enable; +	MicroStatsTable	statsTable;  	MicroRaw	raw;  	MicroData	data; +	MicroStats	stats;  	Container	container;  	JTabbedPane	pane;  	static int	number_of_windows; @@ -44,8 +46,9 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene  			return mp.SetData(data);  		}  		this.data = data; -		graph.setData(data); -		stats.setData(data); +		stats = new MicroStats(data); +		graph.setDataSet(data); +		statsTable.setStats(stats);  		raw.setData(data);  		setTitle(data.name);  		return this; @@ -231,15 +234,18 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene  		addWindowListener(new WindowAdapter() {  			@Override  			public void windowClosing(WindowEvent e) { +				statsTable.tell_closing();  				Close();  			}  		}); -		graph = new MicroGraph(); -		stats = new MicroStatsTable(); +		enable = new AltosUIEnable(); +		graph = new MicroGraph(enable); +		statsTable = new MicroStatsTable();  		raw = new MicroRaw();  		pane.add(graph.panel, "Graph"); -		pane.add(stats, "Statistics"); +		pane.add(enable, "Configure Graph"); +		pane.add(statsTable, "Statistics");  		JScrollPane scroll = new JScrollPane(raw);  		pane.add(scroll, "Raw Data");  		pane.doLayout(); @@ -255,7 +261,6 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene  		ps.height += i.top + i.bottom;  //		setPreferredSize(ps);  		setSize(ps); -		setLocationByPlatform(true);  		setVisible(true);  	} diff --git a/micropeak/MicroRaw.java b/micropeak/MicroRaw.java index 8546cffb..7337a1de 100644 --- a/micropeak/MicroRaw.java +++ b/micropeak/MicroRaw.java @@ -20,8 +20,8 @@ package org.altusmetrum.micropeak;  import java.awt.*;  import java.io.*;  import javax.swing.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class MicroRaw extends JTextArea { diff --git a/micropeak/MicroSave.java b/micropeak/MicroSave.java index 7879ff90..5088b7d7 100644 --- a/micropeak/MicroSave.java +++ b/micropeak/MicroSave.java @@ -24,8 +24,8 @@ import javax.swing.filechooser.FileNameExtensionFilter;  import java.io.*;  import java.util.concurrent.*;  import java.util.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class MicroSave extends JFileChooser { diff --git a/micropeak/MicroSerial.java b/micropeak/MicroSerial.java index 15ef8582..376223f1 100644 --- a/micropeak/MicroSerial.java +++ b/micropeak/MicroSerial.java @@ -20,7 +20,7 @@ package org.altusmetrum.micropeak;  import java.util.*;  import java.io.*;  import libaltosJNI.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class MicroSerial extends InputStream {  	SWIGTYPE_p_altos_file	file; diff --git a/micropeak/MicroStats.java b/micropeak/MicroStats.java index 90e9dd1f..99479cb4 100644 --- a/micropeak/MicroStats.java +++ b/micropeak/MicroStats.java @@ -18,8 +18,8 @@  package org.altusmetrum.micropeak;  import java.io.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*;  public class MicroStats {  	double		coast_height; @@ -150,6 +150,43 @@ public class MicroStats {  		return descent_height() / descent_duration();  	} +	public static final int state_startup = -1; +	public static final int state_pad = 0; +	public static final int state_boost = 1; +	public static final int state_coast = 2; +	public static final int state_descent = 3; +	public static final int state_landed = 4; + +	static final String state_names[] = { +		"pad", +		"boost", +		"coast", +		"descent", +		"landed" +	}; + +	public int state(double t) { +		if (t >= landed_time) +			return state_landed; +		if (t >= apogee_time) +			return state_descent; +		if (t >= coast_time) +			return state_coast; +		if (t >= 0) +			return state_boost; +		return state_pad; +	} + +	public static String state_name(int state) { +		if (state < 0 || state > state_landed) +			return "unknown"; +		return state_names[state]; +	} + +	public String state_name(double t) { +		return state_name(state(t)); +	} +  	public MicroStats(MicroData data) {  		this.data = data; diff --git a/micropeak/MicroStatsTable.java b/micropeak/MicroStatsTable.java index cf30fcb7..145bb70e 100644 --- a/micropeak/MicroStatsTable.java +++ b/micropeak/MicroStatsTable.java @@ -19,10 +19,10 @@ package org.altusmetrum.micropeak;  import java.awt.*;  import javax.swing.*; -import org.altusmetrum.AltosLib.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altosuilib_1.*; -public class MicroStatsTable extends JComponent { +public class MicroStatsTable extends JComponent implements AltosFontListener {  	GridBagLayout	layout;  	class MicroStat { @@ -35,6 +35,12 @@ public class MicroStatsTable extends JComponent {  			}  		} +		public void set_font() { +			for (int j = 0; j < texts.length; j++) +				texts[j].setFont(AltosUILib.value_font); +			label.setFont(AltosUILib.label_font); +		} +  		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); @@ -94,8 +100,20 @@ public class MicroStatsTable extends JComponent {  		flight_time.set_values(String.format("%6.1f s", stats.landed_time));  	} -	public void setData(MicroData data) { -		setStats(new MicroStats(data)); +	public void set_font() { +		max_height.set_font(); +		max_speed.set_font(); +		max_accel.set_font(); +		avg_accel.set_font(); +		boost_duration.set_font(); +		coast_duration.set_font(); +		descent_speed.set_font(); +		descent_duration.set_font(); +		flight_time.set_font(); +	} + +	public void font_size_changed(int font_size) { +		set_font();  	}  	public MicroStatsTable(MicroStats stats) { @@ -129,6 +147,13 @@ public class MicroStatsTable extends JComponent {  						 String.format("%6.1f s", stats.descent_duration()));  		flight_time = new MicroStat(layout, y++, "Flight Time",  					    String.format("%6.1f s", stats.landed_time)); +		set_font(); + +		AltosUIPreferences.register_font_listener(this); +	} + +	public void tell_closing() { +		AltosUIPreferences.unregister_font_listener(this);  	}  	public MicroStatsTable() { diff --git a/micropeak/MicroUSB.java b/micropeak/MicroUSB.java index f56d81d4..3bd61470 100644 --- a/micropeak/MicroUSB.java +++ b/micropeak/MicroUSB.java @@ -19,7 +19,7 @@ package org.altusmetrum.micropeak;  import java.util.*;  import libaltosJNI.*; -import org.altusmetrum.altosuilib.*; +import org.altusmetrum.altosuilib_1.*;  public class MicroUSB extends altos_device implements AltosDevice { diff --git a/micropeak/ReadMe-Mac.rtf b/micropeak/ReadMe-Mac.rtf index 64bbdeb6..f831c3f9 100644 --- a/micropeak/ReadMe-Mac.rtf +++ b/micropeak/ReadMe-Mac.rtf @@ -14,6 +14,6 @@ There are two files included in the Mac OS X distribution:\  \  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.\ +To communicate with the MicroPeak serial adapter, you need to installed the FTDI device drivers, which is done by double-clicking on the FTDIUSBSerialDriver disk image. Inside that is the FTDI USB Serial Driver package. Double click on that and it will guide you through the installation process.\  \ -Thanks for choosing AltusMetrum products!}
\ No newline at end of file +Thanks for choosing AltusMetrum products!} diff --git a/micropeak/micropeak-windows.nsi b/micropeak/micropeak-windows.nsi.in index 425048bd..656f8af3 100644 --- a/micropeak/micropeak-windows.nsi +++ b/micropeak/micropeak-windows.nsi.in @@ -68,8 +68,8 @@ Section "MicroPeak Application"  	SetOutPath $INSTDIR  	File "micropeak-fat.jar" -	File "AltosLib.jar" -	File "AltosUILib.jar" +	File "altoslib_@ALTOSLIB_VERSION@.jar" +	File "altosuilib_@ALTOSUILIB_VERSION@.jar"  	File "jfreechart.jar"  	File "jcommon.jar" @@ -80,6 +80,15 @@ Section "MicroPeak Application"  	CreateShortCut "$SMPROGRAMS\MicroPeak.lnk" "$SYSDIR\javaw.exe" "-jar micropeak-fat.jar" "$INSTDIR\micro-peak.ico"  SectionEnd +Section "FTDI USB Driver" +	SetOutPath $INSTDIR + +	File "CDM20824_Setup.exe" + +	StrCpy $2 "$INSTDIR\CDM20824_Setup.exe" +	ExecWait $2 +SectionEnd +  Section "MicroPeak Desktop Shortcut"  	CreateShortCut "$DESKTOP\MicroPeak.lnk" "$INSTDIR\micropeak-fat.jar"  "" "$INSTDIR\micro-peak.ico"  SectionEnd diff --git a/src/drivers/ao_mpu6000.c b/src/drivers/ao_mpu6000.c index 49596705..6d47482c 100644 --- a/src/drivers/ao_mpu6000.c +++ b/src/drivers/ao_mpu6000.c @@ -199,6 +199,24 @@ ao_mpu6000_setup(void)  	ao_delay(AO_MS_TO_TICKS(200));  	ao_mpu6000_sample(&test_mode); +#if TRIDGE +	// read the product ID rev c has 1/2 the sensitivity of rev d +    _mpu6000_product_id = _register_read(MPUREG_PRODUCT_ID); +    //Serial.printf("Product_ID= 0x%x\n", (unsigned) _mpu6000_product_id); + +    if ((_mpu6000_product_id == MPU6000ES_REV_C4) || (_mpu6000_product_id == MPU6000ES_REV_C5) || +        (_mpu6000_product_id == MPU6000_REV_C4) || (_mpu6000_product_id == MPU6000_REV_C5)) { +        // Accel scale 8g (4096 LSB/g) +        // Rev C has different scaling than rev D +        register_write(MPUREG_ACCEL_CONFIG,1<<3); +    } else { +        // Accel scale 8g (4096 LSB/g) +        register_write(MPUREG_ACCEL_CONFIG,2<<3); +    } +    hal.scheduler->delay(1); + +#endif +  	/* Configure accelerometer to +/-16G */  	ao_mpu6000_reg_write(MPU6000_ACCEL_CONFIG,  			     (0 << MPU600_ACCEL_CONFIG_XA_ST) | diff --git a/src/drivers/ao_mpu6000.h b/src/drivers/ao_mpu6000.h index 6aada9a9..f01e9e83 100644 --- a/src/drivers/ao_mpu6000.h +++ b/src/drivers/ao_mpu6000.h @@ -21,6 +21,27 @@  #define MPU6000_ADDR_WRITE	0xd0  #define MPU6000_ADDR_READ	0xd1 +/* From Tridge */ +#define MPUREG_XG_OFFS_TC 0x00 +#define MPUREG_YG_OFFS_TC 0x01 +#define MPUREG_ZG_OFFS_TC 0x02 +#define MPUREG_X_FINE_GAIN 0x03 +#define MPUREG_Y_FINE_GAIN 0x04 +#define MPUREG_Z_FINE_GAIN 0x05 +#define MPUREG_XA_OFFS_H 0x06 // X axis accelerometer offset (high byte) +#define MPUREG_XA_OFFS_L 0x07 // X axis accelerometer offset (low byte) +#define MPUREG_YA_OFFS_H 0x08 // Y axis accelerometer offset (high byte) +#define MPUREG_YA_OFFS_L 0x09 // Y axis accelerometer offset (low byte) +#define MPUREG_ZA_OFFS_H 0x0A // Z axis accelerometer offset (high byte) +#define MPUREG_ZA_OFFS_L 0x0B // Z axis accelerometer offset (low byte) +#define MPUREG_PRODUCT_ID 0x0C // Product ID Register +#define MPUREG_XG_OFFS_USRH 0x13 // X axis gyro offset (high byte) +#define MPUREG_XG_OFFS_USRL 0x14 // X axis gyro offset (low byte) +#define MPUREG_YG_OFFS_USRH 0x15 // Y axis gyro offset (high byte) +#define MPUREG_YG_OFFS_USRL 0x16 // Y axis gyro offset (low byte) +#define MPUREG_ZG_OFFS_USRH 0x17 // Z axis gyro offset (high byte) +#define MPUREG_ZG_OFFS_USRL 0x18 // Z axis gyro offset (low byte) +  #define MPU6000_SMPRT_DIV	0x19  #define MPU6000_CONFIG		0x1a @@ -163,4 +184,20 @@ extern struct ao_mpu6000_sample	ao_mpu6000_current;  void  ao_mpu6000_init(void); +/* Product ID Description for MPU6000 + * high 4 bits low 4 bits + * Product Name Product Revision + */ +#define MPU6000ES_REV_C4 0x14	/* 0001 0100 */ +#define MPU6000ES_REV_C5 0x15	/* 0001 0101 */ +#define MPU6000ES_REV_D6 0x16	/* 0001 0110 */ +#define MPU6000ES_REV_D7 0x17	/* 0001 0111 */ +#define MPU6000ES_REV_D8 0x18	/* 0001 1000 */ +#define MPU6000_REV_C4 0x54	/* 0101 0100 */ +#define MPU6000_REV_C5 0x55	/* 0101 0101 */ +#define MPU6000_REV_D6 0x56	/* 0101 0110 */ +#define MPU6000_REV_D7 0x57	/* 0101 0111 */ +#define MPU6000_REV_D8 0x58	/* 0101 1000 */ +#define MPU6000_REV_D9 0x59	/* 0101 1001 */ +  #endif /* _AO_MPU6000_H_ */ diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 0dbfae39..1d636037 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -811,30 +811,41 @@ extern struct stm_lcd stm_lcd;  #define STM_LCD_CLR_UDDC		(3)  #define STM_LCD_CLR_SOFC		(1) +/* The NVIC starts at 0xe000e100, so add that to the offsets to find the absolute address */ +  struct stm_nvic { -	vuint32_t	iser[3];	/* 0x000 */ +	vuint32_t	iser[8];	/* 0x000 0xe000e100 Set Enable Register */ + +	uint8_t		_unused020[0x080 - 0x020]; + +	vuint32_t	icer[8];	/* 0x080 0xe000e180 Clear Enable Register */ -	uint8_t		_unused00c[0x080 - 0x00c]; +	uint8_t		_unused0a0[0x100 - 0x0a0]; -	vuint32_t	icer[3];	/* 0x080 */ +	vuint32_t	ispr[8];	/* 0x100 0xe000e200 Set Pending Register */ -	uint8_t		_unused08c[0x100 - 0x08c]; +	uint8_t		_unused120[0x180 - 0x120]; -	vuint32_t	ispr[3];	/* 0x100 */ +	vuint32_t	icpr[8];	/* 0x180 0xe000e280 Clear Pending Register */ -	uint8_t		_unused10c[0x180 - 0x10c]; +	uint8_t		_unused1a0[0x200 - 0x1a0]; -	vuint32_t	icpr[3];	/* 0x180 */ +	vuint32_t	iabr[8];	/* 0x200 0xe000e300 Active Bit Register */ -	uint8_t		_unused18c[0x200 - 0x18c]; +	uint8_t		_unused220[0x300 - 0x220]; -	vuint32_t	iabr[3];	/* 0x200 */ +	vuint32_t	ipr[60];	/* 0x300 0xe000e400 Priority Register */ -	uint8_t		_unused20c[0x300 - 0x20c]; +	uint8_t		_unused3f0[0xc00 - 0x3f0]; -	vuint32_t	ipr[21];	/* 0x300 */ +	vuint32_t	cpuid_base;	/* 0xc00 0xe000ed00 CPUID Base Register */ +	vuint32_t	ics;		/* 0xc04 0xe000ed04 Interrupt Control State Register */ +	vuint32_t	vto;		/* 0xc08 0xe000ed08 Vector Table Offset Register */ +	vuint32_t	ai_rc;		/* 0xc0c 0xe000ed0c Application Interrupt/Reset Control Register */ +	vuint32_t	sc;		/* 0xc10 0xe000ed10 System Control Register */ +	vuint32_t	cc;		/* 0xc14 0xe000ed14 Configuration Control Register */ -	uint8_t		_unused324[0xe00 - 0x324]; +	uint8_t		_unusedc18[0xe00 - 0xc18];  	vuint32_t	stir;		/* 0xe00 */  }; diff --git a/src/test/Makefile b/src/test/Makefile index 87bd70fe..1c2d771e 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -62,5 +62,5 @@ ao_aprs_data.wav: ao_aprs_test  check: ao_fec_test ao_flight_test ao_flight_test_baro run-tests  	./ao_fec_test && ./run-tests -ao_micropeak_test: ao_micropeak_test.c ao_microflight.c -	cc $(CFLAGS) -o $@ ao_micropeak_test.c -lm
\ No newline at end of file +ao_micropeak_test: ao_micropeak_test.c ao_microflight.c ao_kalman.h +	cc $(CFLAGS) -o $@ ao_micropeak_test.c -lm diff --git a/src/test/ao_micropeak_test.c b/src/test/ao_micropeak_test.c index 04686402..5961bd93 100644 --- a/src/test/ao_micropeak_test.c +++ b/src/test/ao_micropeak_test.c @@ -67,10 +67,11 @@ ao_micro_report(void)  {  	if (running) {  		alt_t	ground = ao_pa_to_altitude(pa_ground); -		printf ("%6.2f %10d %10d %10d\n", now / 100.0, +		printf ("%6.3f %10d %10d %10d %10d %10d\n", now / 100.0,  			ao_pa_to_altitude(pa) - ground,  			ao_pa_to_altitude(ao_pa) - ground, -			ao_pa_to_altitude(pa_min) - ground); +			ao_pa_to_altitude(pa_min) - ground, +			ao_pa_speed, ao_pa_accel);  	}  } @@ -92,14 +93,24 @@ ao_pa_get(void)  	double		time;  	double		pressure;  	static double	last_time; +	static double	last_pressure;  	static int	been_here;  	static int	start_samples; +	static int	is_mp; +	static int	use_saved;  	if (been_here && start_samples < 100) {  		start_samples++;  		return;  	}  	ao_micro_report(); +	if (use_saved) { +		pa = last_pressure; +		now = last_time; +		use_saved = 0; +//		printf ("use saved %d %d\n", now, pa); +		return; +	}  	for (;;) {  		if (!fgets(line, sizeof (line), emulator_in))  			exit(0); @@ -119,15 +130,32 @@ ao_pa_get(void)  				}  			}  			continue; +		} else if (!strcmp(toks[0], "Time")) { +			time_id = 0; +			pa_id = 1; +			is_mp = 1; +			continue;  		}  		time = strtod(toks[time_id],NULL);  		pressure = strtod(toks[pa_id],NULL); -		if (been_here && time - last_time < 0.1) +		time *= 100; +		if (been_here && time - last_time < 0.096 * 100)  			continue; -		been_here = 1; +		if (is_mp && been_here) { +			double	avg_pressure = (pressure + last_pressure) / 2.0; +			double	avg_time = (time + last_time) / 2.0; + +			now = avg_time; +			pa = avg_pressure; +//			printf ("new %d %d\n", now, pa); +			use_saved = 1; +		} else { +			now = floor (time + 0.5); +			pa = pressure; +		} +		last_pressure = pressure;  		last_time = time; -		now = floor (time * 100 + 0.5); -		pa = pressure; +		been_here = 1;  		break;  	}  } diff --git a/src/test/plotmicro b/src/test/plotmicro index cdfcc581..bb8f4d1d 100755 --- a/src/test/plotmicro +++ b/src/test/plotmicro @@ -3,12 +3,14 @@ for i in "$@"; do  gnuplot -p << EOF &  set title "$i"  set ylabel "height (m)" +set y2label "accel (m/s²)"  set xlabel "time (s)"  set xtics border out nomirror  set ytics border out nomirror  set y2tics border out nomirror  plot "$i" using 1:2 with lines lt 2 axes x1y1 title "raw height",\       "$i" using 1:3 with lines lt 4 axes x1y1 title "kalman height",\ -     "$i" using 1:4 with lines lt 1 axes x1y1 title "max height" +     "$i" using 1:4 with lines lt 1 axes x1y1 title "max height",\ +     "$i" using 1:6 with lines lt 3 axes x1y2 title "pa accel"  EOF  done diff --git a/src/util/atmosphere.5c b/src/util/atmosphere.5c new file mode 100644 index 00000000..9b5107f0 --- /dev/null +++ b/src/util/atmosphere.5c @@ -0,0 +1,153 @@ +#!/usr/bin/nickle -f +/* + * Pressure Sensor Model, version 1.1 + * + * written by Holly Grimes + * + * Uses the International Standard Atmosphere as described in + *   "A Quick Derivation relating altitude to air pressure" (version 1.03) + *    from the Portland State Aerospace Society, except that the atmosphere + *    is divided into layers with each layer having a different lapse rate. + * + * Lapse rate data for each layer was obtained from Wikipedia on Sept. 1, 2007 + *    at site <http://en.wikipedia.org/wiki/International_Standard_Atmosphere + * + * Height measurements use the local tangent plane.  The postive z-direction is up. + * + * All measurements are given in SI units (Kelvin, Pascal, meter, meters/second^2). + *   The lapse rate is given in Kelvin/meter, the gas constant for air is given + *   in Joules/(kilogram-Kelvin). + */ + +const real GRAVITATIONAL_ACCELERATION = -9.80665; +const real AIR_GAS_CONSTANT = 287.053; +const int NUMBER_OF_LAYERS = 7; +const real MAXIMUM_ALTITUDE = 84852; +const real MINIMUM_PRESSURE = 0.3734; +const real LAYER0_BASE_TEMPERATURE = 288.15; +const real LAYER0_BASE_PRESSURE = 101325; + +/* lapse rate and base altitude for each layer in the atmosphere */ +const real[NUMBER_OF_LAYERS] lapse_rate = { +	-0.0065, 0.0, 0.001, 0.0028, 0.0, -0.0028, -0.002 +}; +const int[NUMBER_OF_LAYERS] base_altitude = { +	0, 11000, 20000, 32000, 47000, 51000, 71000 +}; + + +/* outputs atmospheric pressure associated with the given altitude. altitudes +   are measured with respect to the mean sea level */ +real altitude_to_pressure(real altitude) { + +   real base_temperature = LAYER0_BASE_TEMPERATURE; +   real base_pressure = LAYER0_BASE_PRESSURE; + +   real pressure; +   real base; /* base for function to determine pressure */ +   real exponent; /* exponent for function to determine pressure */ +   int layer_number; /* identifies layer in the atmosphere */ +   int delta_z; /* difference between two altitudes */ + +   if (altitude > MAXIMUM_ALTITUDE) /* FIX ME: use sensor data to improve model */ +      return 0; + +   /* calculate the base temperature and pressure for the atmospheric layer +      associated with the inputted altitude */ +   for(layer_number = 0; layer_number < NUMBER_OF_LAYERS - 1 && altitude > base_altitude[layer_number + 1]; layer_number++) { +      delta_z = base_altitude[layer_number + 1] - base_altitude[layer_number]; +      if (lapse_rate[layer_number] == 0.0) { +         exponent = GRAVITATIONAL_ACCELERATION * delta_z +              / AIR_GAS_CONSTANT / base_temperature; +         base_pressure *= exp(exponent); +      } +      else { +         base = (lapse_rate[layer_number] * delta_z / base_temperature) + 1.0; +         exponent = GRAVITATIONAL_ACCELERATION / +              (AIR_GAS_CONSTANT * lapse_rate[layer_number]); +         base_pressure *= pow(base, exponent); +      } +      base_temperature += delta_z * lapse_rate[layer_number]; +   } + +   /* calculate the pressure at the inputted altitude */ +   delta_z = altitude - base_altitude[layer_number]; +   if (lapse_rate[layer_number] == 0.0) { +      exponent = GRAVITATIONAL_ACCELERATION * delta_z +           / AIR_GAS_CONSTANT / base_temperature; +      pressure = base_pressure * exp(exponent); +   } +   else { +      base = (lapse_rate[layer_number] * delta_z / base_temperature) + 1.0; +      exponent = GRAVITATIONAL_ACCELERATION / +           (AIR_GAS_CONSTANT * lapse_rate[layer_number]); +      pressure = base_pressure * pow(base, exponent); +   } + +   return pressure; +} + + +/* outputs the altitude associated with the given pressure. the altitude +   returned is measured with respect to the mean sea level */ +real pressure_to_altitude(real pressure) { + +   real next_base_temperature = LAYER0_BASE_TEMPERATURE; +   real next_base_pressure = LAYER0_BASE_PRESSURE; + +   real altitude; +   real base_pressure; +   real base_temperature; +   real base; /* base for function to determine base pressure of next layer */ +   real exponent; /* exponent for function to determine base pressure +                             of next layer */ +   real coefficient; +   int layer_number; /* identifies layer in the atmosphere */ +   int delta_z; /* difference between two altitudes */ + +   if (pressure < 0)  /* illegal pressure */ +      return -1; +   if (pressure < MINIMUM_PRESSURE) /* FIX ME: use sensor data to improve model */ +      return MAXIMUM_ALTITUDE; + +   /* calculate the base temperature and pressure for the atmospheric layer +      associated with the inputted pressure. */ +   layer_number = -1; +   do { +      layer_number++; +      base_pressure = next_base_pressure; +      base_temperature = next_base_temperature; +      delta_z = base_altitude[layer_number + 1] - base_altitude[layer_number]; +      if (lapse_rate[layer_number] == 0.0) { +         exponent = GRAVITATIONAL_ACCELERATION * delta_z +              / AIR_GAS_CONSTANT / base_temperature; +         next_base_pressure *= exp(exponent); +      } +      else { +         base = (lapse_rate[layer_number] * delta_z / base_temperature) + 1.0; +         exponent = GRAVITATIONAL_ACCELERATION / +              (AIR_GAS_CONSTANT * lapse_rate[layer_number]); +         next_base_pressure *= pow(base, exponent); +      } +      next_base_temperature += delta_z * lapse_rate[layer_number]; +   } +   while(layer_number < NUMBER_OF_LAYERS - 1 && pressure < next_base_pressure); + +   /* calculate the altitude associated with the inputted pressure */ +   if (lapse_rate[layer_number] == 0.0) { +      coefficient = (AIR_GAS_CONSTANT / GRAVITATIONAL_ACCELERATION) +                                                    * base_temperature; +      altitude = base_altitude[layer_number] +                    + coefficient * log(pressure / base_pressure); +   } +   else { +      base = pressure / base_pressure; +      exponent = AIR_GAS_CONSTANT * lapse_rate[layer_number] +                                       / GRAVITATIONAL_ACCELERATION; +      coefficient = base_temperature / lapse_rate[layer_number]; +      altitude = base_altitude[layer_number] +                      + coefficient * (pow(base, exponent) - 1); +   } + +   return altitude; +} | 
