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
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)
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.
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.*;
* 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.*;
* 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.*;
* 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.*;
* 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.altosuilib.*;
+import org.altusmetrum.altoslib_1.*;
+import org.altusmetrum.altosuilib_1.*;
public class Altos extends AltosUILib {
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
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 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 {
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 {
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altosuilib.*;
+import org.altusmetrum.altosuilib_1.*;
public class AltosEepromMonitor extends AltosUIDialog {
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;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_1.*;
public class AltosFlightStatsTable extends JComponent {
GridBagLayout layout;
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.altosuilib.*;
+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";
+ }
+
+ 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";
+ }
-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 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) {
+ 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);
+ 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);
+ addSeries("Received Signal Strength",
+ AltosGraphDataPoint.data_rssi,
+ dbm_units,
+ dbm_color,
+ false,
+ dbm_axis);
+ 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);
+ }
+}
\ 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;
+ JTabbedPane pane;
+ AltosGraph graph;
+ AltosUIEnable enable;
- 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);
+ AltosGraphUI(AltosRecordIterable records, String file) throws InterruptedException, IOException {
+ pane = new JTabbedPane();
- 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) );
+ enable = new AltosUIEnable();
- 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;
- }
- }
+ AltosGraph graph = new AltosGraph(enable);
- /*
- 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);
- }
- }
- */
+ graph.setDataSet(new AltosGraphDataSet(records));
- /*
- 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);
- }
- }
- */
+ pane.add("Flight Graph", graph.panel);
+ pane.add("Configure Graph", enable);
- public AltosGraphUI(AltosRecordIterable records, String name) throws InterruptedException, IOException {
- super(String.format("Altos Graph %s", name));
+ AltosFlightStatsTable stats = new AltosFlightStatsTable(new AltosFlightStats(records));
+ pane.add("Flight Statistics", stats);
- AltosDataPointReader reader = new AltosDataPointReader (records);
-
- if (reader.has_accel)
- init(reader, records, 0);
- else
- init(reader, records, 1);
- }
-
-// 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);
-
- 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);
-
- AltosFlightStatsTable stats = new AltosFlightStatsTable(new AltosFlightStats(records));
- pane.add("Flight Statistics", stats);
-
- setContentPane (pane);
-
- pack();
-
- RefineryUtilities.centerFrameOnScreen(this);
-
- setDefaultCloseOperation(DISPOSE_ON_CLOSE);
- setVisible(true);
- }
-
- private static AltosGraph createGraph(Iterable<AltosDataPoint> data,
- int which)
- {
- return createGraphsWhich(data, which).get(0);
- }
-
- /*
- private static ArrayList<AltosGraph> createGraphs(
- Iterable<AltosDataPoint> data)
- {
- return createGraphsWhich(data, -1);
- }
- */
-
- 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);
+ }
}
-
-/* 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 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 AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDisplay, AltosFontListener, AltosIdleMonitorListener {
AltosDevice device;
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;
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.*;
*/
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.altosuilib.*;
+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
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();
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.*;
+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 {
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 \
* 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);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib;
+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);
+ }
+
+ 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.*;
--- /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.*;
--- /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 {
* 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 {
* 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)
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)
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
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+ <key>CFBundleName</key>
+ <string>MicroPeak</string>
+ <key>CFBundleVersion</key>
+ <string>1.1.9.3</string>
+ <key>CFBundleAllowMixedLocalizations</key>
+ <string>true</string>
+ <key>CFBundleExecutable</key>
+ <string>JavaApplicationStub</string>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.altusmetrum.micropeak</string>
+ <key>CFBundleSignature</key>
+ <string>Altu</string>
+ <key>CFBundleGetInfoString</key>
+ <string>MicroPeak UI version 1.1.9.3</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleIconFile</key>
+ <string>MicroPeak.icns</string>
+ <key>Java</key>
+ <dict>
+ <key>MainClass</key>
+ <string>org.altusmetrum.micropeak.MicroPeak</string>
+ <key>JVMVersion</key>
+ <string>1.5+</string>
+ <key>ClassPath</key>
+ <array>
+ <string>$JAVAROOT/micropeak.jar</string>
+ </array>
+ <key>Properties</key>
+ <dict>
+ <key>apple.laf.useScreenMenuBar</key>
+ <string>true</string>
+ </dict>
+ <key>VMOptions</key>
+ <array>
+ <string>-Xms512M</string>
+ <string>-Xmx512M</string>
+ <string>-Dosgi.clean=true</string>
+ </array>
+ </dict>
+</dict>
+</plist>
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)
MACOSX_DRIVER=FTDIUSBSerialDriver_v2_2_18.dmg
MACOSX_INFO_PLIST=Info.plist
MACOSX_README=ReadMe-Mac.rtf
-MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(MACOSX_DRIVER) $(MACOSX_README)
+MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(MACOSX_DRIVER) $(MACOSX_README) $(DOC)
$(MACOSX_DRIVER):
wget $(MACOSX_DRIVER_URL)
$(WINDOWS_DRIVER):
wget $(WINDOWS_DRIVER_URL)
-WINDOWS_FILES=$(FAT_FILES) altos.dll altos64.dll $(top_srcdir)/telemetrum.inf $(WINDOWS_ICON) $(WINDOWS_DRIVER)
+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
cp -p $(MACOSX_DRIVER) macosx
mkdir -p 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();
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 {
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_ */
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;
+}