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
<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" />
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)
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
+++ /dev/null
-AltosLib.jar
//import android.os.Message;
import android.util.Log;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class AltosBluetooth extends AltosLink {
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.
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);
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;
}
}
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";
import android.speech.tts.TextToSpeech;\r
import android.speech.tts.TextToSpeech.OnInitListener;\r
\r
-import org.altusmetrum.AltosLib.*;\r
+import org.altusmetrum.altoslib_1.*;\r
\r
public class AltosVoice {\r
\r
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.util.Log;\r
import android.os.Handler;\r
\r
-import org.altusmetrum.AltosLib.*;\r
+import org.altusmetrum.altoslib_1.*;\r
\r
\r
public class TelemetryReader extends Thread {\r
import android.util.Log;
import android.widget.Toast;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class TelemetryService extends Service {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
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
* 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;
* 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.*;
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;
}
}
storage_size = -1;
storage_erase_unit = -1;
- stored_flight = -1;
+ stored_flight = 0;
}
public void parse_line(String line) {
/* 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) {}
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:
* 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 */
/*
* Sensor data conversion functions
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
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();
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");
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
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;
* 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.*;
* 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.*;
* 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.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
* 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.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
* 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.*;
* 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.*;
* 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;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.util.concurrent.*;
* 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;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
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
* 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;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.util.concurrent.TimeoutException;
* 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.*;
AltosState state;
boolean remote;
double frequency;
+ String callsign;
AltosState previous_state;
AltosConfigData config_data;
AltosGPS gps;
try {
if (remote) {
link.set_radio_frequency(frequency);
+ link.set_callsign(callsign);
link.start_remote();
} else
link.flush_input();
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 (;;) {
* 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);
* 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.*;
* 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.*;
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));
+ }
}
* 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;
* 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.*;
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() {
}
public void set_callsign(String callsign) {
+ this.callsign = callsign;
printf ("c c %s\n", callsign);
flush_output();
}
}
public AltosLink() {
+ callsign = "";
}
}
* 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;
* 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;
* 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;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.ParseException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.ParseException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
* 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.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.io.File;
* 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.*;
* 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 {
* 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;
* 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.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosRecordMM extends AltosRecord {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosRecordNone extends AltosRecord {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosRecordTM extends AltosRecord {
* 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.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
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
* Track flight state from telemetry or eeprom data stream
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosState {
public AltosRecord data;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
* 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.*;
* 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;
* 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.*;
* 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 {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordCompanion extends AltosTelemetryRecordRaw {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordConfiguration extends AltosTelemetryRecordRaw {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordLocation extends AltosTelemetryRecordRaw {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordMegaData extends AltosTelemetryRecordRaw {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordMegaSensor extends AltosTelemetryRecordRaw {
* 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;
* 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;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw {
--- /dev/null
+/*
+ * 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;
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
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;
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));
}
* 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);
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
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;
- }
}
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class AltosAscent extends JComponent implements AltosFlightDisplay {
GridBagLayout layout;
package altosui;
import libaltosJNI.*;
-import org.altusmetrum.altosuilib.*;
+import org.altusmetrum.altosuilib_1.*;
public class AltosBTDevice extends altos_bt_device implements AltosDevice {
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>();
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;
import java.io.*;
import java.util.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class AltosCSV implements AltosWriter {
File name;
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
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class AltosCompanionInfo extends JTable {
private AltosFlightInfoTableModel model;
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 {
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;
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
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 {
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
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
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altosuilib.*;
+import org.altusmetrum.altosuilib_1.*;
public class AltosConfigureUI
extends AltosUIConfigure
AltosVoice voice;
public JTextField callsign_value;
+ public JComboBox position_value;
/* DocumentListener interface methods */
public void insertUpdate(DocumentEvent e) {
}
public void changedUpdate(DocumentEvent e) {
- if (callsign_value != null)
+ if (callsign_value != null)
AltosUIPreferences.set_callsign(callsign_value.getText());
}
/* 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));
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);
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;
+++ /dev/null
-
-// 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();
-}
-
+++ /dev/null
-
-// 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();
- }
- };
- }
-}
-
package altosui;
import java.io.*;
-import org.altusmetrum.altosuilib.*;
+import org.altusmetrum.altosuilib_1.*;
public class AltosDebug extends AltosSerial {
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class AltosDescent extends JComponent implements AltosFlightDisplay {
GridBagLayout layout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
-import org.altusmetrum.altosuilib.*;
+import org.altusmetrum.altosuilib_1.*;
public class AltosDeviceUIDialog extends AltosDeviceDialog {
import javax.swing.*;
import java.io.*;
import java.text.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class AltosDisplayThread extends Thread {
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;
import java.util.*;
import java.text.*;
import java.util.concurrent.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
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);
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;
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 {
}
}
+ private int countDeletedFlights() {
+ int count = 0;
+ for (AltosEepromLog flight : flights) {
+ if (flight.selected)
+ count++;
+ }
+ return count;
+ }
+
private String showDeletedFlights() {
String result = "";
} 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);
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altosuilib.*;
+import org.altusmetrum.altosuilib_1.*;
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);
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) {
}
}
}
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("");
}
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;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
-import org.altusmetrum.altosuilib.*;
+import org.altusmetrum.altosuilib_1.*;
public class AltosFlash {
File file;
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
package altosui;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public interface AltosFlightDisplay {
void reset();
package altosui;
import java.io.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class AltosFlightStats {
double max_height;
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;
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;
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) {
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class AltosFlightStatsTable extends JComponent {
GridBagLayout layout;
}
+ 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();
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)));
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
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class AltosFlightStatus extends JComponent implements AltosFlightDisplay {
GridBagLayout layout;
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 = {
package altosui;
import java.awt.event.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class AltosFlightStatusUpdate implements ActionListener {
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;
package altosui;
import javax.swing.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
+import org.altusmetrum.altosuilib_1.*;
public class AltosFreqList extends JComboBox {
-
-// 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+ }
+}
+++ /dev/null
-
-// 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);
- }
- }
-}
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;
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"
-
- */
-
-
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;
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;
}
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 {
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 */
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
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);
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
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;
package altosui;
import java.io.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class AltosKML implements AltosWriter {
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;
throw new FileNotFoundException(filename);
}
try {
- new AltosGraphUI(records, filename);
+ new AltosGraphUI(records, file);
} catch (InterruptedException ie) {
} catch (IOException ie) {
}
import java.io.*;
import java.util.concurrent.*;
import java.awt.*;
-import org.altusmetrum.altosuilib.*;
+import org.altusmetrum.altosuilib_1.*;
public class AltosLaunch {
AltosDevice device;
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) {
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class AltosPad extends JComponent implements AltosFlightDisplay {
GridBagLayout layout;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altosuilib.*;
+import org.altusmetrum.altosuilib_1.*;
public class AltosRomconfigUI
extends AltosUIDialog
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;
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.*;
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);
*/
package altosui;
-import org.altusmetrum.altosuilib.*;
+import org.altusmetrum.altosuilib_1.*;
public class AltosSerialInUseException extends Exception {
public AltosDevice device;
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
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);
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;
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;
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();
} 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,
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);
}
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
System.exit(0);
}
});
+
+ setLocationByPlatform(false);
+
+ /* Insets aren't set before the window is visible */
+ setVisible(true);
}
private void ConnectToDevice() {
if (record_reader == null)
return;
try {
- new AltosGraphUI(record_reader, chooser.filename());
+ new AltosGraphUI(record_reader, chooser.file());
} catch (InterruptedException ie) {
} catch (IOException ie) {
}
}
}
- 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);
}
}
- 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) {
}
}
- 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) {
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);
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);
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);
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) {
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 {
/* 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)
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;
}
+++ /dev/null
-/*
- * 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;
- }
- }
-
-}
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 {
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;
package altosui;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public interface AltosWriter {
AltosLed.java \
AltosLights.java \
AltosPad.java \
- AltosUIPreferences.java \
AltosUIPreferencesBackend.java \
AltosRomconfig.java \
AltosRomconfigUI.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 \
freetts.jar
ALTOSLIB_CLASS=\
- AltosLib.jar
+ altoslib_$(ALTOSLIB_VERSION).jar
ALTOSUILIB_CLASS=\
- altosuilib.jar
+ altosuilib_$(ALTOSUILIB_VERSION).jar
LIBALTOS= \
libaltos.so \
+++ /dev/null
-!addplugindir Instdrv/NSIS/Plugins
-; Definitions for Java 1.6 Detection
-!define JRE_VERSION "1.6"
-!define JRE_ALTERNATE "1.7"
-!define JRE_URL "http://javadl.sun.com/webapps/download/AutoDL?BundleId=52247&/jre-6u27-windows-i586-p.exe"
-!define PRODUCT_NAME "Altus Metrum Windows Software"
-
-Name "Altus Metrum Installer"
-
-; Default install directory
-InstallDir "$PROGRAMFILES\AltusMetrum"
-
-; Tell the installer where to re-install a new version
-InstallDirRegKey HKLM "Software\AltusMetrum" "Install_Dir"
-
-LicenseText "GNU General Public License Version 2"
-LicenseData "../COPYING"
-
-; Need admin privs for Vista or Win7
-RequestExecutionLevel admin
-
-ShowInstDetails Show
-
-ComponentText "Altus Metrum Software and Driver Installer"
-
-Function GetJRE
- MessageBox MB_OK "${PRODUCT_NAME} uses Java ${JRE_VERSION} 32-bit, it will now \
- be downloaded and installed"
-
- StrCpy $2 "$TEMP\Java Runtime Environment.exe"
- nsisdl::download /TIMEOUT=30000 ${JRE_URL} $2
- Pop $R0 ;Get the return value
- StrCmp $R0 "success" +3
- MessageBox MB_OK "Download failed: $R0"
- Quit
- ExecWait $2
- Delete $2
-FunctionEnd
-
-
-Function DetectJRE
- ReadRegStr $2 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment" \
- "CurrentVersion"
- StrCmp $2 ${JRE_VERSION} done
-
- StrCmp $2 ${JRE_ALTERNATE} done
-
- Call GetJRE
-
- done:
-FunctionEnd
-
-; Pages to present
-
-Page license
-Page components
-Page directory
-Page instfiles
-
-UninstPage uninstConfirm
-UninstPage instfiles
-
-; And the stuff to install
-
-Section "Install Driver" InstDriver
-
- InstDrv::InitDriverSetup /NOUNLOAD {4D36E96D-E325-11CE-BFC1-08002BE10318} AltusMetrumSerial
- Pop $0
- DetailPrint "InitDriverSetup: $0"
- InstDrv::DeleteOemInfFiles /NOUNLOAD
- InstDrv::CreateDevice /NOUNLOAD
-
- SetOutPath $TEMP
- File "../telemetrum.inf"
- InstDrv::InstallDriver /NOUNLOAD "$TEMP\telemetrum.inf"
-
- SetOutPath $INSTDIR
- File "../telemetrum.inf"
-
- SetOutPath $WINDIR\Inf
- File "../telemetrum.inf"
-
-SectionEnd
-
-Section "AltosUI Application"
- Call DetectJRE
-
- SetOutPath $INSTDIR
-
- File "altosui-fat.jar"
- File "AltosLib.jar"
- File "cmudict04.jar"
- File "cmulex.jar"
- File "cmu_time_awb.jar"
- File "cmutimelex.jar"
- File "cmu_us_kal.jar"
- File "en_us.jar"
- File "freetts.jar"
- File "jfreechart.jar"
- File "jcommon.jar"
-
- File "*.dll"
-
- File "../icon/*.ico"
-
- CreateShortCut "$SMPROGRAMS\AltusMetrum.lnk" "$SYSDIR\javaw.exe" "-jar altosui-fat.jar" "$INSTDIR\altus-metrum.ico"
-SectionEnd
-
-Section "AltosUI Desktop Shortcut"
- CreateShortCut "$DESKTOP\AltusMetrum.lnk" "$INSTDIR\altosui-fat.jar" "" "$INSTDIR\altus-metrum.ico"
-SectionEnd
-
-Section "TeleMetrum and TeleDongle Firmware"
-
- SetOutPath $INSTDIR
-
- File "../src/telemetrum-v1.0/telemetrum-v1.0-${VERSION}.ihx"
- File "../src/telemetrum-v1.1/telemetrum-v1.1-${VERSION}.ihx"
- File "../src/telemetrum-v1.2/telemetrum-v1.2-${VERSION}.ihx"
- File "../src/telemini-v1.0/telemini-v1.0-${VERSION}.ihx"
- File "../src/teledongle-v0.2/teledongle-v0.2-${VERSION}.ihx"
-
-SectionEnd
-
-Section "Documentation"
-
- SetOutPath $INSTDIR
-
- File "../doc/altusmetrum.pdf"
- File "../doc/altos.pdf"
- File "../doc/telemetry.pdf"
- File "../doc/telemetrum-outline.pdf"
- File "../doc/megametrum-outline.pdf"
-SectionEnd
-
-Section "Uninstaller"
-
- ; Deal with the uninstaller
-
- SetOutPath $INSTDIR
-
- ; Write the install path to the registry
- WriteRegStr HKLM SOFTWARE\AltusMetrum "Install_Dir" "$INSTDIR"
-
- ; Write the uninstall keys for windows
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "DisplayName" "Altus Metrum"
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "UninstallString" '"$INSTDIR\uninstall.exe"'
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoModify" "1"
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoRepair" "1"
-
- WriteUninstaller "uninstall.exe"
-SectionEnd
-
-Section "Uninstall"
- DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum"
- DeleteRegKey HKLM "Software\AltusMetrum"
-
- Delete "$INSTDIR\*.*"
- RMDir "$INSTDIR"
-
- ; Remove .inf file
- Delete "$WINDIR\Inf\telemetrum.inf"
-
- ; Remove devices
- InstDrv::InitDriverSetup /NOUNLOAD {4D36E96D-E325-11CE-BFC1-08002BE10318} AltusMetrumSerial
- InstDrv::DeleteOemInfFiles /NOUNLOAD
- InstDrv::RemoveAllDevices
-
- ; Remove shortcuts, if any
- Delete "$SMPROGRAMS\AltusMetrum.lnk"
- Delete "$DESKTOP\AltusMetrum.lnk"
-
-SectionEnd
--- /dev/null
+!addplugindir Instdrv/NSIS/Plugins
+; Definitions for Java 1.6 Detection
+!define JRE_VERSION "1.6"
+!define JRE_ALTERNATE "1.7"
+!define JRE_URL "http://javadl.sun.com/webapps/download/AutoDL?BundleId=52247&/jre-6u27-windows-i586-p.exe"
+!define PRODUCT_NAME "Altus Metrum Windows Software"
+
+Name "Altus Metrum Installer"
+
+; Default install directory
+InstallDir "$PROGRAMFILES\AltusMetrum"
+
+; Tell the installer where to re-install a new version
+InstallDirRegKey HKLM "Software\AltusMetrum" "Install_Dir"
+
+LicenseText "GNU General Public License Version 2"
+LicenseData "../COPYING"
+
+; Need admin privs for Vista or Win7
+RequestExecutionLevel admin
+
+ShowInstDetails Show
+
+ComponentText "Altus Metrum Software and Driver Installer"
+
+Function GetJRE
+ MessageBox MB_OK "${PRODUCT_NAME} uses Java ${JRE_VERSION} 32-bit, it will now \
+ be downloaded and installed"
+
+ StrCpy $2 "$TEMP\Java Runtime Environment.exe"
+ nsisdl::download /TIMEOUT=30000 ${JRE_URL} $2
+ Pop $R0 ;Get the return value
+ StrCmp $R0 "success" +3
+ MessageBox MB_OK "Download failed: $R0"
+ Quit
+ ExecWait $2
+ Delete $2
+FunctionEnd
+
+
+Function DetectJRE
+ ReadRegStr $2 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment" \
+ "CurrentVersion"
+ StrCmp $2 ${JRE_VERSION} done
+
+ StrCmp $2 ${JRE_ALTERNATE} done
+
+ Call GetJRE
+
+ done:
+FunctionEnd
+
+; Pages to present
+
+Page license
+Page components
+Page directory
+Page instfiles
+
+UninstPage uninstConfirm
+UninstPage instfiles
+
+; And the stuff to install
+
+Section "Install Driver" InstDriver
+
+ InstDrv::InitDriverSetup /NOUNLOAD {4D36E96D-E325-11CE-BFC1-08002BE10318} AltusMetrumSerial
+ Pop $0
+ DetailPrint "InitDriverSetup: $0"
+ InstDrv::DeleteOemInfFiles /NOUNLOAD
+ InstDrv::CreateDevice /NOUNLOAD
+
+ SetOutPath $TEMP
+ File "../telemetrum.inf"
+ InstDrv::InstallDriver /NOUNLOAD "$TEMP\telemetrum.inf"
+
+ SetOutPath $INSTDIR
+ File "../telemetrum.inf"
+
+ SetOutPath $WINDIR\Inf
+ File "../telemetrum.inf"
+
+SectionEnd
+
+Section "AltosUI Application"
+ Call DetectJRE
+
+ SetOutPath $INSTDIR
+
+ File "altosui-fat.jar"
+ File "altoslib_@ALTOSLIB_VERSION@.jar"
+ File "altosuilib_@ALTOSUILIB_VERSION@.jar"
+ File "cmudict04.jar"
+ File "cmulex.jar"
+ File "cmu_time_awb.jar"
+ File "cmutimelex.jar"
+ File "cmu_us_kal.jar"
+ File "en_us.jar"
+ File "freetts.jar"
+ File "jfreechart.jar"
+ File "jcommon.jar"
+
+ File "*.dll"
+
+ File "../icon/*.ico"
+
+ CreateShortCut "$SMPROGRAMS\AltusMetrum.lnk" "$SYSDIR\javaw.exe" "-jar altosui-fat.jar" "$INSTDIR\altus-metrum.ico"
+SectionEnd
+
+Section "AltosUI Desktop Shortcut"
+ CreateShortCut "$DESKTOP\AltusMetrum.lnk" "$INSTDIR\altosui-fat.jar" "" "$INSTDIR\altus-metrum.ico"
+SectionEnd
+
+Section "TeleMetrum and TeleDongle Firmware"
+
+ SetOutPath $INSTDIR
+
+ File "../src/telemetrum-v1.0/telemetrum-v1.0-${VERSION}.ihx"
+ File "../src/telemetrum-v1.1/telemetrum-v1.1-${VERSION}.ihx"
+ File "../src/telemetrum-v1.2/telemetrum-v1.2-${VERSION}.ihx"
+ File "../src/telemini-v1.0/telemini-v1.0-${VERSION}.ihx"
+ File "../src/teledongle-v0.2/teledongle-v0.2-${VERSION}.ihx"
+
+SectionEnd
+
+Section "Documentation"
+
+ SetOutPath $INSTDIR
+
+ File "../doc/altusmetrum.pdf"
+ File "../doc/altos.pdf"
+ File "../doc/telemetry.pdf"
+ File "../doc/telemetrum-outline.pdf"
+ File "../doc/megametrum-outline.pdf"
+SectionEnd
+
+Section "Uninstaller"
+
+ ; Deal with the uninstaller
+
+ SetOutPath $INSTDIR
+
+ ; Write the install path to the registry
+ WriteRegStr HKLM SOFTWARE\AltusMetrum "Install_Dir" "$INSTDIR"
+
+ ; Write the uninstall keys for windows
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "DisplayName" "Altus Metrum"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "UninstallString" '"$INSTDIR\uninstall.exe"'
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoModify" "1"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoRepair" "1"
+
+ WriteUninstaller "uninstall.exe"
+SectionEnd
+
+Section "Uninstall"
+ DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum"
+ DeleteRegKey HKLM "Software\AltusMetrum"
+
+ Delete "$INSTDIR\*.*"
+ RMDir "$INSTDIR"
+
+ ; Remove .inf file
+ Delete "$WINDIR\Inf\telemetrum.inf"
+
+ ; Remove devices
+ InstDrv::InitDriverSetup /NOUNLOAD {4D36E96D-E325-11CE-BFC1-08002BE10318} AltusMetrumSerial
+ InstDrv::DeleteOemInfFiles /NOUNLOAD
+ InstDrv::RemoveAllDevices
+
+ ; Remove shortcuts, if any
+ Delete "$SMPROGRAMS\AltusMetrum.lnk"
+ Delete "$DESKTOP\AltusMetrum.lnk"
+
+SectionEnd
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib;
+package org.altusmetrum.altosuilib_1;
import libaltosJNI.*;
* 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.*;
* 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);
--- /dev/null
+/*
+ * 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 AltosPositionListener {
+ public void position_changed(int position);
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
* 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.*;
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));
}
});
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() {
add_log_dir();
add_callsign();
add_units();
+ add_serial_debug();
add_font_size();
add_look_and_feel();
+ add_position();
add_bluetooth();
add_frequencies();
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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();
+}
* 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.*;
--- /dev/null
+/*
+ * 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();
+ }
+}
* 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.*;
}
}
-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);
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();
}
}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+}
* 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 {
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;
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;
* 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);
--- /dev/null
+/*
+ * 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
* 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 {
/* 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;
/* 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());
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(); }
}
}
+ 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;
+ }
+ }
}
* 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 {
--- /dev/null
+/*
+ * 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();
+ }
+}
* 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@";
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib;
+package org.altusmetrum.altosuilib_1;
import java.util.*;
import libaltosJNI.*;
+++ /dev/null
-/*
- * 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;
-
-public interface AltosUnitsListener {
- public void units_changed();
-}
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)
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
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)
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
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
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
<surname>Towns</surname>
</author>
<copyright>
- <year>2012</year>
+ <year>2013</year>
<holder>Bdale Garbee and Keith Packard</holder>
</copyright>
<legalnotice>
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.
<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
<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.
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
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>
<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>
once you enable the voice output!
</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>
"/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>
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>
charge gasses.
</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>
<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>
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+#!/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
*.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
altos.dll
ALTOSLIB_CLASS=\
- AltosLib.jar
+ altoslib_$(ALTOSLIB_VERSION).jar
ALTOSUILIB_CLASS=\
- altosuilib.jar
+ altosuilib_$(ALTOSUILIB_VERSION).jar
# Icons
ICONDIR=$(top_srcdir)/icon
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
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
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;
}
}
-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;
private double ground_altitude;
private ArrayList<Integer> bytes;
String name;
+ MicroStats stats;
-
class FileEndedException extends Exception {
}
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);
}
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) {
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) {
data.height(i),
data.speed(i),
data.acceleration(i),
- data.time(i));
+ data.time(i),
+ data.stats);
}
}
\ No newline at end of file
import java.awt.*;
import java.awt.event.*;
import java.util.*;
-import org.altusmetrum.altosuilib.*;
+import org.altusmetrum.altosuilib_1.*;
public class MicroDeviceDialog extends AltosDeviceDialog {
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;
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 {
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 {
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;
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 = {
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.*;
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
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;
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;
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();
ps.height += i.top + i.bottom;
// setPreferredSize(ps);
setSize(ps);
- setLocationByPlatform(true);
setVisible(true);
}
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 {
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 {
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;
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;
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;
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 {
}
}
+ 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);
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) {
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() {
import java.util.*;
import libaltosJNI.*;
-import org.altusmetrum.altosuilib.*;
+import org.altusmetrum.altosuilib_1.*;
public class MicroUSB extends altos_device implements AltosDevice {
\
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!}
+++ /dev/null
-!addplugindir Instdrv/NSIS/Plugins
-; Definitions for Java 1.6 Detection
-!define JRE_VERSION "1.6"
-!define JRE_ALTERNATE "1.7"
-!define JRE_URL "http://javadl.sun.com/webapps/download/AutoDL?BundleId=52247&/jre-6u27-windows-i586-p.exe"
-!define PRODUCT_NAME "Altus Metrum Windows Software"
-
-Name "Altus Metrum MicroPeak Installer"
-
-; Default install directory
-InstallDir "$PROGRAMFILES\AltusMetrum"
-
-; Tell the installer where to re-install a new version
-InstallDirRegKey HKLM "Software\AltusMetrum" "Install_Dir"
-
-LicenseText "GNU General Public License Version 2"
-LicenseData "../COPYING"
-
-; Need admin privs for Vista or Win7
-RequestExecutionLevel admin
-
-ShowInstDetails Show
-
-ComponentText "Altus Metrum MicroPeak Software Installer"
-
-Function GetJRE
- MessageBox MB_OK "${PRODUCT_NAME} uses Java ${JRE_VERSION} 32-bit, it will now \
- be downloaded and installed"
-
- StrCpy $2 "$TEMP\Java Runtime Environment.exe"
- nsisdl::download /TIMEOUT=30000 ${JRE_URL} $2
- Pop $R0 ;Get the return value
- StrCmp $R0 "success" +3
- MessageBox MB_OK "Download failed: $R0"
- Quit
- ExecWait $2
- Delete $2
-FunctionEnd
-
-
-Function DetectJRE
- ReadRegStr $2 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment" \
- "CurrentVersion"
- StrCmp $2 ${JRE_VERSION} done
-
- StrCmp $2 ${JRE_ALTERNATE} done
-
- Call GetJRE
-
- done:
-FunctionEnd
-
-; Pages to present
-
-Page license
-Page components
-Page directory
-Page instfiles
-
-UninstPage uninstConfirm
-UninstPage instfiles
-
-; And the stuff to install
-
-Section "MicroPeak Application"
- Call DetectJRE
-
- SetOutPath $INSTDIR
-
- File "micropeak-fat.jar"
- File "AltosLib.jar"
- File "AltosUILib.jar"
- File "jfreechart.jar"
- File "jcommon.jar"
-
- File "*.dll"
-
- File "../icon/*.ico"
-
- CreateShortCut "$SMPROGRAMS\MicroPeak.lnk" "$SYSDIR\javaw.exe" "-jar micropeak-fat.jar" "$INSTDIR\micro-peak.ico"
-SectionEnd
-
-Section "MicroPeak Desktop Shortcut"
- CreateShortCut "$DESKTOP\MicroPeak.lnk" "$INSTDIR\micropeak-fat.jar" "" "$INSTDIR\micro-peak.ico"
-SectionEnd
-
-Section "Documentation"
-
- SetOutPath $INSTDIR
-
- File "../doc/micropeak.pdf"
-SectionEnd
-
-Section "Uninstaller"
-
- ; Deal with the uninstaller
-
- SetOutPath $INSTDIR
-
- ; Write the install path to the registry
- WriteRegStr HKLM SOFTWARE\AltusMetrum "Install_Dir" "$INSTDIR"
-
- ; Write the uninstall keys for windows
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "DisplayName" "Altus Metrum"
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "UninstallString" '"$INSTDIR\uninstall.exe"'
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoModify" "1"
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoRepair" "1"
-
- WriteUninstaller "uninstall.exe"
-SectionEnd
-
-Section "Uninstall"
- DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum"
- DeleteRegKey HKLM "Software\AltusMetrum"
-
- Delete "$INSTDIR\*.*"
- RMDir "$INSTDIR"
-
- ; Remove shortcuts, if any
- Delete "$SMPROGRAMS\MicroPeak.lnk"
- Delete "$DESKTOP\MicroPeak.lnk"
-
-SectionEnd
--- /dev/null
+!addplugindir Instdrv/NSIS/Plugins
+; Definitions for Java 1.6 Detection
+!define JRE_VERSION "1.6"
+!define JRE_ALTERNATE "1.7"
+!define JRE_URL "http://javadl.sun.com/webapps/download/AutoDL?BundleId=52247&/jre-6u27-windows-i586-p.exe"
+!define PRODUCT_NAME "Altus Metrum Windows Software"
+
+Name "Altus Metrum MicroPeak Installer"
+
+; Default install directory
+InstallDir "$PROGRAMFILES\AltusMetrum"
+
+; Tell the installer where to re-install a new version
+InstallDirRegKey HKLM "Software\AltusMetrum" "Install_Dir"
+
+LicenseText "GNU General Public License Version 2"
+LicenseData "../COPYING"
+
+; Need admin privs for Vista or Win7
+RequestExecutionLevel admin
+
+ShowInstDetails Show
+
+ComponentText "Altus Metrum MicroPeak Software Installer"
+
+Function GetJRE
+ MessageBox MB_OK "${PRODUCT_NAME} uses Java ${JRE_VERSION} 32-bit, it will now \
+ be downloaded and installed"
+
+ StrCpy $2 "$TEMP\Java Runtime Environment.exe"
+ nsisdl::download /TIMEOUT=30000 ${JRE_URL} $2
+ Pop $R0 ;Get the return value
+ StrCmp $R0 "success" +3
+ MessageBox MB_OK "Download failed: $R0"
+ Quit
+ ExecWait $2
+ Delete $2
+FunctionEnd
+
+
+Function DetectJRE
+ ReadRegStr $2 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment" \
+ "CurrentVersion"
+ StrCmp $2 ${JRE_VERSION} done
+
+ StrCmp $2 ${JRE_ALTERNATE} done
+
+ Call GetJRE
+
+ done:
+FunctionEnd
+
+; Pages to present
+
+Page license
+Page components
+Page directory
+Page instfiles
+
+UninstPage uninstConfirm
+UninstPage instfiles
+
+; And the stuff to install
+
+Section "MicroPeak Application"
+ Call DetectJRE
+
+ SetOutPath $INSTDIR
+
+ File "micropeak-fat.jar"
+ File "altoslib_@ALTOSLIB_VERSION@.jar"
+ File "altosuilib_@ALTOSUILIB_VERSION@.jar"
+ File "jfreechart.jar"
+ File "jcommon.jar"
+
+ File "*.dll"
+
+ File "../icon/*.ico"
+
+ CreateShortCut "$SMPROGRAMS\MicroPeak.lnk" "$SYSDIR\javaw.exe" "-jar micropeak-fat.jar" "$INSTDIR\micro-peak.ico"
+SectionEnd
+
+Section "FTDI USB Driver"
+ SetOutPath $INSTDIR
+
+ File "CDM20824_Setup.exe"
+
+ StrCpy $2 "$INSTDIR\CDM20824_Setup.exe"
+ ExecWait $2
+SectionEnd
+
+Section "MicroPeak Desktop Shortcut"
+ CreateShortCut "$DESKTOP\MicroPeak.lnk" "$INSTDIR\micropeak-fat.jar" "" "$INSTDIR\micro-peak.ico"
+SectionEnd
+
+Section "Documentation"
+
+ SetOutPath $INSTDIR
+
+ File "../doc/micropeak.pdf"
+SectionEnd
+
+Section "Uninstaller"
+
+ ; Deal with the uninstaller
+
+ SetOutPath $INSTDIR
+
+ ; Write the install path to the registry
+ WriteRegStr HKLM SOFTWARE\AltusMetrum "Install_Dir" "$INSTDIR"
+
+ ; Write the uninstall keys for windows
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "DisplayName" "Altus Metrum"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "UninstallString" '"$INSTDIR\uninstall.exe"'
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoModify" "1"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoRepair" "1"
+
+ WriteUninstaller "uninstall.exe"
+SectionEnd
+
+Section "Uninstall"
+ DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum"
+ DeleteRegKey HKLM "Software\AltusMetrum"
+
+ Delete "$INSTDIR\*.*"
+ RMDir "$INSTDIR"
+
+ ; Remove shortcuts, if any
+ Delete "$SMPROGRAMS\MicroPeak.lnk"
+ Delete "$DESKTOP\MicroPeak.lnk"
+
+SectionEnd
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) |
#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
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_ */
#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 */
};
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
{
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);
}
}
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);
}
}
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;
}
}
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
--- /dev/null
+#!/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;
+}