summaryrefslogtreecommitdiff
path: root/altoslib
diff options
context:
space:
mode:
Diffstat (limited to 'altoslib')
-rw-r--r--altoslib/AltosAccel.java2
-rw-r--r--altoslib/AltosCRCException.java2
-rw-r--r--altoslib/AltosCSV.java234
-rw-r--r--altoslib/AltosCalData.java406
-rw-r--r--altoslib/AltosCompanion.java2
-rw-r--r--altoslib/AltosConfigData.java243
-rw-r--r--altoslib/AltosConfigDataException.java2
-rw-r--r--altoslib/AltosConfigValues.java2
-rw-r--r--altoslib/AltosConvert.java112
-rw-r--r--altoslib/AltosDataListener.java95
-rw-r--r--altoslib/AltosDataProvider.java (renamed from altoslib/AltosStateUpdate.java)6
-rw-r--r--altoslib/AltosDebug.java2
-rw-r--r--altoslib/AltosDistance.java4
-rw-r--r--altoslib/AltosEeprom.java317
-rw-r--r--altoslib/AltosEepromChunk.java38
-rw-r--r--altoslib/AltosEepromDownload.java277
-rw-r--r--altoslib/AltosEepromFile.java119
-rw-r--r--altoslib/AltosEepromHeader.java335
-rw-r--r--altoslib/AltosEepromIterable.java127
-rw-r--r--altoslib/AltosEepromList.java2
-rw-r--r--altoslib/AltosEepromLog.java43
-rw-r--r--altoslib/AltosEepromMega.java287
-rw-r--r--altoslib/AltosEepromMini.java116
-rw-r--r--altoslib/AltosEepromMonitor.java6
-rw-r--r--altoslib/AltosEepromRecord.java126
-rw-r--r--altoslib/AltosEepromRecordFireTwo.java (renamed from altoslib/AltosEepromFireTwo.java)74
-rw-r--r--altoslib/AltosEepromRecordFull.java114
-rw-r--r--altoslib/AltosEepromRecordGps.java (renamed from altoslib/AltosEepromGPS.java)96
-rw-r--r--altoslib/AltosEepromRecordMega.java260
-rw-r--r--altoslib/AltosEepromRecordMetrum.java (renamed from altoslib/AltosEepromMetrum2.java)101
-rw-r--r--altoslib/AltosEepromRecordMini.java105
-rw-r--r--altoslib/AltosEepromRecordSet.java120
-rw-r--r--altoslib/AltosEepromRecordTiny.java86
-rw-r--r--altoslib/AltosEepromTM.java206
-rw-r--r--altoslib/AltosEepromTMini.java160
-rw-r--r--altoslib/AltosFile.java6
-rw-r--r--altoslib/AltosFlash.java2
-rw-r--r--altoslib/AltosFlashListener.java2
-rw-r--r--altoslib/AltosFlightDisplay.java2
-rw-r--r--altoslib/AltosFlightListener.java162
-rw-r--r--altoslib/AltosFlightReader.java6
-rw-r--r--altoslib/AltosFlightSeries.java697
-rw-r--r--altoslib/AltosFlightStats.java299
-rw-r--r--altoslib/AltosFontListener.java2
-rw-r--r--altoslib/AltosForce.java49
-rw-r--r--altoslib/AltosFrequency.java2
-rw-r--r--altoslib/AltosGPS.java14
-rw-r--r--altoslib/AltosGPSSat.java2
-rw-r--r--altoslib/AltosGPSTimeValue.java28
-rw-r--r--altoslib/AltosGreatCircle.java2
-rw-r--r--altoslib/AltosHeight.java2
-rw-r--r--altoslib/AltosHexfile.java2
-rw-r--r--altoslib/AltosHexsym.java2
-rw-r--r--altoslib/AltosIMU.java87
-rw-r--r--altoslib/AltosIdle.java2
-rw-r--r--altoslib/AltosIdleFetch.java85
-rw-r--r--altoslib/AltosIdleMonitor.java14
-rw-r--r--altoslib/AltosIdleMonitorListener.java2
-rw-r--r--altoslib/AltosIdleReader.java25
-rw-r--r--altoslib/AltosIgnite.java5
-rw-r--r--altoslib/AltosImage.java2
-rw-r--r--altoslib/AltosJson.java123
-rw-r--r--altoslib/AltosKML.java87
-rw-r--r--altoslib/AltosLatLon.java2
-rw-r--r--altoslib/AltosLatitude.java2
-rw-r--r--altoslib/AltosLaunchSite.java2
-rw-r--r--altoslib/AltosLaunchSiteListener.java2
-rw-r--r--altoslib/AltosLaunchSites.java2
-rw-r--r--altoslib/AltosLib.java55
-rw-r--r--altoslib/AltosLine.java2
-rw-r--r--altoslib/AltosLink.java4
-rw-r--r--altoslib/AltosListenerState.java2
-rw-r--r--altoslib/AltosLocation.java2
-rw-r--r--altoslib/AltosLog.java31
-rw-r--r--altoslib/AltosLongitude.java2
-rw-r--r--altoslib/AltosMag.java43
-rw-r--r--altoslib/AltosMap.java30
-rw-r--r--altoslib/AltosMapCache.java2
-rw-r--r--altoslib/AltosMapCacheListener.java2
-rw-r--r--altoslib/AltosMapInterface.java2
-rw-r--r--altoslib/AltosMapLine.java34
-rw-r--r--altoslib/AltosMapLoader.java2
-rw-r--r--altoslib/AltosMapLoaderListener.java2
-rw-r--r--altoslib/AltosMapMark.java2
-rw-r--r--altoslib/AltosMapPath.java2
-rw-r--r--altoslib/AltosMapPathPoint.java2
-rw-r--r--altoslib/AltosMapRectangle.java2
-rw-r--r--altoslib/AltosMapStore.java4
-rw-r--r--altoslib/AltosMapStoreListener.java2
-rw-r--r--altoslib/AltosMapTile.java2
-rw-r--r--altoslib/AltosMapTileListener.java2
-rw-r--r--altoslib/AltosMapTransform.java2
-rw-r--r--altoslib/AltosMapTypeListener.java2
-rw-r--r--altoslib/AltosMapZoomListener.java2
-rw-r--r--altoslib/AltosMma655x.java11
-rw-r--r--altoslib/AltosMs5607.java179
-rw-r--r--altoslib/AltosNoSymbol.java2
-rw-r--r--altoslib/AltosOrient.java2
-rw-r--r--altoslib/AltosParse.java2
-rw-r--r--altoslib/AltosPointDouble.java2
-rw-r--r--altoslib/AltosPointInt.java2
-rw-r--r--altoslib/AltosPreferences.java8
-rw-r--r--altoslib/AltosPreferencesBackend.java2
-rw-r--r--altoslib/AltosPresTemp.java25
-rw-r--r--altoslib/AltosPressure.java (renamed from altoslib/AltosStateIterable.java)43
-rw-r--r--altoslib/AltosProgrammer.java2
-rw-r--r--altoslib/AltosPyro.java6
-rw-r--r--altoslib/AltosPyroName.java32
-rw-r--r--altoslib/AltosQuaternion.java46
-rw-r--r--altoslib/AltosRecordSet.java22
-rw-r--r--altoslib/AltosRectangle.java2
-rw-r--r--altoslib/AltosReplayReader.java129
-rw-r--r--altoslib/AltosRomconfig.java2
-rw-r--r--altoslib/AltosRotation.java31
-rw-r--r--altoslib/AltosRotationRate.java38
-rw-r--r--altoslib/AltosSavedState.java2
-rw-r--r--altoslib/AltosSelfFlash.java2
-rw-r--r--altoslib/AltosSensorEMini.java20
-rw-r--r--altoslib/AltosSensorMM.java2
-rw-r--r--altoslib/AltosSensorMega.java16
-rw-r--r--altoslib/AltosSensorMetrum.java10
-rw-r--r--altoslib/AltosSensorTGPS.java6
-rw-r--r--altoslib/AltosSensorTM.java17
-rw-r--r--altoslib/AltosSensorTMini2.java10
-rw-r--r--altoslib/AltosSensorTMini3.java10
-rw-r--r--altoslib/AltosSpeed.java2
-rw-r--r--altoslib/AltosState.java653
-rw-r--r--altoslib/AltosStateName.java32
-rw-r--r--altoslib/AltosStringInputStream.java61
-rw-r--r--altoslib/AltosTelemetry.java70
-rw-r--r--altoslib/AltosTelemetryCompanion.java25
-rw-r--r--altoslib/AltosTelemetryConfiguration.java60
-rw-r--r--altoslib/AltosTelemetryFile.java145
-rw-r--r--altoslib/AltosTelemetryIterable.java34
-rw-r--r--altoslib/AltosTelemetryLegacy.java54
-rw-r--r--altoslib/AltosTelemetryLocation.java110
-rw-r--r--altoslib/AltosTelemetryMap.java2
-rw-r--r--altoslib/AltosTelemetryMegaData.java78
-rw-r--r--altoslib/AltosTelemetryMegaSensor.java88
-rw-r--r--altoslib/AltosTelemetryMetrumData.java25
-rw-r--r--altoslib/AltosTelemetryMetrumSensor.java58
-rw-r--r--altoslib/AltosTelemetryMini2.java62
-rw-r--r--altoslib/AltosTelemetryMini3.java60
-rw-r--r--altoslib/AltosTelemetryRaw.java8
-rw-r--r--altoslib/AltosTelemetryReader.java34
-rw-r--r--altoslib/AltosTelemetrySatellite.java29
-rw-r--r--altoslib/AltosTelemetrySensor.java80
-rw-r--r--altoslib/AltosTelemetryStandard.java27
-rw-r--r--altoslib/AltosTemperature.java2
-rw-r--r--altoslib/AltosTime.java33
-rw-r--r--altoslib/AltosTimeSeries.java307
-rw-r--r--altoslib/AltosTimeValue.java28
-rw-r--r--altoslib/AltosUnits.java10
-rw-r--r--altoslib/AltosUnitsListener.java2
-rw-r--r--altoslib/AltosUnitsRange.java2
-rw-r--r--altoslib/AltosUnknownProduct.java2
-rw-r--r--altoslib/AltosVersion.java.in2
-rw-r--r--altoslib/AltosVoltage.java2
-rw-r--r--altoslib/AltosWriter.java4
-rw-r--r--altoslib/Makefile.am38
160 files changed, 5255 insertions, 3846 deletions
diff --git a/altoslib/AltosAccel.java b/altoslib/AltosAccel.java
index 31aa7c1b..8fefefc5 100644
--- a/altoslib/AltosAccel.java
+++ b/altoslib/AltosAccel.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
diff --git a/altoslib/AltosCRCException.java b/altoslib/AltosCRCException.java
index 80dca140..5c398d3c 100644
--- a/altoslib/AltosCRCException.java
+++ b/altoslib/AltosCRCException.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosCRCException extends Exception {
public int rssi;
diff --git a/altoslib/AltosCSV.java b/altoslib/AltosCSV.java
index b5199456..f55b4785 100644
--- a/altoslib/AltosCSV.java
+++ b/altoslib/AltosCSV.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
@@ -27,16 +27,17 @@ public class AltosCSV implements AltosWriter {
boolean header_written;
boolean seen_boost;
int boost_tick;
- LinkedList<AltosState> pad_states;
- AltosState state;
- static boolean has_basic;
- static boolean has_battery;
- static boolean has_flight_state;
- static boolean has_advanced;
- static boolean has_gps;
- static boolean has_gps_sat;
- static boolean has_companion;
+ boolean has_basic;
+ boolean has_battery;
+ boolean has_flight_state;
+ boolean has_advanced;
+ boolean has_gps;
+ boolean has_gps_sat;
+ boolean has_companion;
+
+ AltosFlightSeries series;
+ int[] indices;
static final int ALTOS_CSV_VERSION = 5;
@@ -117,71 +118,116 @@ public class AltosCSV implements AltosWriter {
out.printf("version,serial,flight,call,time,clock,rssi,lqi");
}
- void write_general(AltosState state) {
+ double time() {
+ return series.time(indices);
+ }
+
+ int rssi() {
+ return (int) series.value(AltosFlightSeries.rssi_name, indices);
+ }
+
+ int status() {
+ return (int) series.value(AltosFlightSeries.status_name, indices);
+ }
+
+ void write_general() {
+ double time = time();
out.printf("%s, %d, %d, %s, %8.2f, %8.2f, %4d, %3d",
- ALTOS_CSV_VERSION, state.serial, state.flight, state.callsign,
- (double) state.time_since_boost(), (double) state.tick / 100.0,
- state.rssi,
- state.status & 0x7f);
+ ALTOS_CSV_VERSION, series.cal_data().serial,
+ series.cal_data().flight, series.cal_data().callsign,
+ time, time,
+ rssi(), status() & 0x7f);
}
void write_flight_header() {
out.printf("state,state_name");
}
- void write_flight(AltosState state) {
- out.printf("%d,%8s", state.state(), state.state_name());
+ int state() {
+ return (int) series.value(AltosFlightSeries.state_name, indices);
+ }
+
+ void write_flight() {
+ int state = state();
+ out.printf("%d,%8s", state, AltosLib.state_name(state));
}
void write_basic_header() {
out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,drogue_voltage,main_voltage");
}
- void write_basic(AltosState state) {
+ double acceleration() { return series.value(AltosFlightSeries.accel_name, indices); }
+ double pressure() { return series.value(AltosFlightSeries.pressure_name, indices); }
+ double altitude() { return series.value(AltosFlightSeries.altitude_name, indices); }
+ double height() { return series.value(AltosFlightSeries.height_name, indices); }
+ double speed() { return series.value(AltosFlightSeries.speed_name, indices); }
+ double temperature() { return series.value(AltosFlightSeries.temperature_name, indices); }
+ double apogee_voltage() { return series.value(AltosFlightSeries.apogee_voltage_name, indices); }
+ double main_voltage() { return series.value(AltosFlightSeries.main_voltage_name, indices); }
+
+ void write_basic() {
out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f",
- state.acceleration(),
- state.pressure(),
- state.altitude(),
- state.height(),
- state.speed(),
- state.speed(),
- state.temperature,
- state.apogee_voltage,
- state.main_voltage);
+ acceleration(),
+ pressure(),
+ altitude(),
+ height(),
+ speed(),
+ speed(),
+ temperature(),
+ apogee_voltage(),
+ main_voltage());
}
void write_battery_header() {
out.printf("battery_voltage");
}
- void write_battery(AltosState state) {
- out.printf("%5.2f", state.battery_voltage);
+ double battery_voltage() { return series.value(AltosFlightSeries.battery_voltage_name, indices); }
+
+ void write_battery() {
+ out.printf("%5.2f", battery_voltage());
}
void write_advanced_header() {
out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z");
}
- void write_advanced(AltosState state) {
+ double accel_along() { return series.value(AltosFlightSeries.accel_along_name, indices); }
+ double accel_across() { return series.value(AltosFlightSeries.accel_across_name, indices); }
+ double accel_through() { return series.value(AltosFlightSeries.accel_through_name, indices); }
+
+ double gyro_roll() { return series.value(AltosFlightSeries.gyro_roll_name, indices); }
+ double gyro_pitch() { return series.value(AltosFlightSeries.gyro_pitch_name, indices); }
+ double gyro_yaw() { return series.value(AltosFlightSeries.gyro_yaw_name, indices); }
+
+ double mag_along() { return series.value(AltosFlightSeries.mag_along_name, indices); }
+ double mag_across() { return series.value(AltosFlightSeries.mag_across_name, indices); }
+ double mag_through() { return series.value(AltosFlightSeries.mag_through_name, indices); }
+
+ void write_advanced() {
out.printf("%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f",
- state.accel_along(), state.accel_across(), state.accel_through(),
- state.gyro_roll(), state.gyro_pitch(), state.gyro_yaw(),
- state.mag_along(), state.mag_across(), state.mag_through());
+ accel_along(), accel_across(), accel_through(),
+ gyro_roll(), gyro_pitch(), gyro_yaw(),
+ mag_along(), mag_across(), mag_through());
}
void write_gps_header() {
out.printf("connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,pdop,hdop,vdop");
}
- void write_gps(AltosState state) {
- AltosGPS gps = state.gps;
- if (gps == null)
- gps = new AltosGPS();
+ void write_gps() {
+ AltosGPS gps = series.gps_before(series.time(indices));
+
+ AltosGreatCircle from_pad;
- AltosGreatCircle from_pad = state.from_pad;
- if (from_pad == null)
+ if (series.cal_data().gps_pad != null && gps != null)
+ from_pad = new AltosGreatCircle(series.cal_data().gps_pad, gps);
+ else
from_pad = new AltosGreatCircle();
+ if (gps == null)
+ gps = new AltosGPS();
+
out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f,%6.1f,%6.1f",
gps.connected?1:0,
gps.locked?1:0,
@@ -196,9 +242,9 @@ public class AltosCSV implements AltosWriter {
gps.minute,
gps.second,
from_pad.distance,
- state.range,
+ from_pad.range,
from_pad.bearing,
- state.elevation,
+ from_pad.elevation,
gps.pdop,
gps.hdop,
gps.vdop);
@@ -212,8 +258,8 @@ public class AltosCSV implements AltosWriter {
}
}
- void write_gps_sat(AltosState state) {
- AltosGPS gps = state.gps;
+ void write_gps_sat() {
+ AltosGPS gps = series.gps_before(series.time(indices));
for(int i = 1; i <= 32; i++) {
int c_n0 = 0;
if (gps != null && gps.cc_gps_sat != null) {
@@ -230,12 +276,15 @@ public class AltosCSV implements AltosWriter {
}
void write_companion_header() {
+/*
out.printf("companion_id,companion_time,companion_update,companion_channels");
for (int i = 0; i < 12; i++)
out.printf(",companion_%02d", i);
+*/
}
- void write_companion(AltosState state) {
+ void write_companion() {
+/*
AltosCompanion companion = state.companion;
int channels_written = 0;
@@ -252,6 +301,7 @@ public class AltosCSV implements AltosWriter {
}
for (; channels_written < 12; channels_written++)
out.printf(",0");
+*/
}
void write_header() {
@@ -287,63 +337,47 @@ public class AltosCSV implements AltosWriter {
out.printf ("\n");
}
- void write_one(AltosState state) {
- write_general(state);
+ void write_one() {
+ write_general();
if (has_flight_state) {
out.printf(",");
- write_flight(state);
+ write_flight();
}
if (has_basic) {
out.printf(",");
- write_basic(state);
+ write_basic();
}
if (has_battery) {
out.printf(",");
- write_battery(state);
+ write_battery();
}
if (has_advanced) {
out.printf(",");
- write_advanced(state);
+ write_advanced();
}
if (has_gps) {
out.printf(",");
- write_gps(state);
+ write_gps();
}
if (has_gps_sat) {
out.printf(",");
- write_gps_sat(state);
+ write_gps_sat();
}
if (has_companion) {
out.printf(",");
- write_companion(state);
+ write_companion();
}
out.printf ("\n");
}
- private void flush_pad() {
- while (!pad_states.isEmpty()) {
- write_one (pad_states.remove());
- }
- }
-
- private void write(AltosState state) {
- if (state.state() == AltosLib.ao_flight_startup)
+ private void write() {
+ if (state() == AltosLib.ao_flight_startup)
return;
if (!header_written) {
write_header();
header_written = true;
}
- if (!seen_boost) {
- if (state.state() >= AltosLib.ao_flight_boost) {
- seen_boost = true;
- boost_tick = state.tick;
- flush_pad();
- }
- }
- if (seen_boost)
- write_one(state);
- else
- pad_states.add(state);
+ write_one();
}
private PrintStream out() {
@@ -351,15 +385,15 @@ public class AltosCSV implements AltosWriter {
}
public void close() {
- if (!pad_states.isEmpty()) {
- boost_tick = pad_states.element().tick;
- flush_pad();
- }
out.close();
}
- public void write(AltosStateIterable states) {
- states.write_comments(out());
+ public void write(AltosFlightSeries series) {
+// series.write_comments(out());
+
+ this.series = series;
+
+ series.finish();
has_flight_state = false;
has_basic = false;
@@ -368,31 +402,37 @@ public class AltosCSV implements AltosWriter {
has_gps = false;
has_gps_sat = false;
has_companion = false;
- for (AltosState state : states) {
- if (state.state() != AltosLib.ao_flight_stateless && state.state() != AltosLib.ao_flight_invalid && state.state() != AltosLib.ao_flight_startup)
- has_flight_state = true;
- if (state.acceleration() != AltosLib.MISSING || state.pressure() != AltosLib.MISSING)
- has_basic = true;
- if (state.battery_voltage != AltosLib.MISSING)
- has_battery = true;
- if (state.accel_across() != AltosLib.MISSING)
- has_advanced = true;
- if (state.gps != null) {
- has_gps = true;
- if (state.gps.cc_gps_sat != null)
- has_gps_sat = true;
- }
- if (state.companion != null)
- has_companion = true;
+
+ if (series.has_series(AltosFlightSeries.state_name))
+ has_flight_state = true;
+ if (series.has_series(AltosFlightSeries.accel_name) || series.has_series(AltosFlightSeries.pressure_name))
+ has_basic = true;
+ if (series.has_series(AltosFlightSeries.battery_voltage_name))
+ has_battery = true;
+ if (series.has_series(AltosFlightSeries.accel_across_name))
+ has_advanced = true;
+
+ if (series.gps_series != null)
+ has_gps = true;
+ if (series.sats_in_view != null)
+ has_gps_sat = true;
+ /*
+ if (state.companion != null)
+ has_companion = true;
+ */
+
+ indices = series.indices();
+
+ for (;;) {
+ write();
+ if (!series.step_indices(indices))
+ break;
}
- for (AltosState state : states)
- write(state);
}
public AltosCSV(PrintStream in_out, File in_name) {
name = in_name;
out = in_out;
- pad_states = new LinkedList<AltosState>();
}
public AltosCSV(File in_name) throws FileNotFoundException {
diff --git a/altoslib/AltosCalData.java b/altoslib/AltosCalData.java
new file mode 100644
index 00000000..b49e3792
--- /dev/null
+++ b/altoslib/AltosCalData.java
@@ -0,0 +1,406 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+/*
+ * Calibration and other data needed to construct 'real' values from various data
+ * sources.
+ */
+
+public class AltosCalData {
+ public int flight = AltosLib.MISSING;
+
+ public void set_flight(int flight) {
+ if (flight != AltosLib.MISSING)
+ this.flight = flight;
+ }
+
+ public String callsign = null;
+
+ public void set_callsign(String callsign) {
+ if (callsign != null)
+ this.callsign = callsign;
+ }
+
+ public String firmware_version = null;
+
+ public void set_firmware_version(String firmware_version) {
+ if (firmware_version != null)
+ this.firmware_version = firmware_version;
+ }
+
+ public String product = null;
+
+ public void set_product(String product) {
+ if (product != null)
+ this.product = product;
+ }
+
+ public int serial = AltosLib.MISSING;
+
+ public void set_serial(int serial) {
+ if (serial != AltosLib.MISSING)
+ this.serial = serial;
+ }
+
+ public int receiver_serial = AltosLib.MISSING;
+
+ public void set_receiver_serial(int receiver_serial) {
+ if (receiver_serial != AltosLib.MISSING)
+ this.receiver_serial = receiver_serial;
+ }
+
+ public int device_type = AltosLib.MISSING;
+
+ public void set_device_type(int device_type) {
+ if (device_type != AltosLib.MISSING) {
+ this.device_type = device_type;
+ if (product == null)
+ set_product(AltosLib.product_name(device_type));
+ }
+ }
+
+ public int config_major = AltosLib.MISSING;
+ public int config_minor = AltosLib.MISSING;
+ public int flight_log_max = AltosLib.MISSING;
+
+ public void set_config(int major, int minor, int log_max) {
+ if (major != AltosLib.MISSING)
+ config_major = major;
+ if (minor != AltosLib.MISSING)
+ config_minor = minor;
+ if (log_max != AltosLib.MISSING)
+ flight_log_max = log_max;
+ }
+
+ public double apogee_delay = AltosLib.MISSING;
+ public double main_deploy = AltosLib.MISSING;
+
+ public void set_flight_params(double apogee_delay, double main_deploy) {
+ if (apogee_delay != AltosLib.MISSING)
+ this.apogee_delay = apogee_delay;
+ if (main_deploy != AltosLib.MISSING)
+ this.main_deploy = main_deploy;
+ }
+
+ public double accel_plus_g = AltosLib.MISSING;
+ public double accel_minus_g = AltosLib.MISSING;
+ public double ground_accel = AltosLib.MISSING;
+
+ public void set_accel_plus_minus(double plus, double minus) {
+ if (plus != AltosLib.MISSING && minus != AltosLib.MISSING) {
+ if (plus == minus)
+ return;
+ accel_plus_g = plus;
+ accel_minus_g = minus;
+ }
+ }
+
+ public void set_ground_accel(double ground_accel) {
+ if (ground_accel != AltosLib.MISSING)
+ this.ground_accel = ground_accel;
+ }
+
+ /* Raw acceleration value */
+ public double accel = AltosLib.MISSING;
+
+ public void set_accel(double accel) {
+ this.accel = accel;
+ }
+
+ public boolean mma655x_inverted = false;
+
+ public void set_mma655x_inverted(boolean inverted) {
+ mma655x_inverted = inverted;
+ }
+
+ public int pad_orientation = AltosLib.MISSING;
+
+ public void set_pad_orientation(int orientation) {
+ if (orientation != AltosLib.MISSING)
+ pad_orientation = orientation;
+ }
+
+ /* Compute acceleration */
+ public double acceleration(double sensor) {
+ return AltosConvert.acceleration_from_sensor(sensor, accel_plus_g, accel_minus_g, ground_accel);
+ }
+
+ public AltosMs5607 ms5607 = null;
+
+ public void set_ms5607(AltosMs5607 ms5607) {
+ this.ms5607 = ms5607;
+ }
+
+ public double ground_pressure = AltosLib.MISSING;
+ public double ground_altitude = AltosLib.MISSING;
+
+ public void set_ground_pressure(double ground_pressure) {
+ if (ground_pressure != AltosLib.MISSING) {
+ this.ground_pressure = ground_pressure;
+ this.ground_altitude = AltosConvert.pressure_to_altitude(ground_pressure);
+ }
+ }
+
+ public void set_ground_altitude(double ground_altitude) {
+ if (ground_altitude != AltosLib.MISSING)
+ this.ground_altitude = ground_altitude;
+ }
+
+ /* Compute pressure */
+
+ public AltosPresTemp pressure_ms5607(int raw_pres, int raw_temp) {
+ if (ms5607 == null)
+ return new AltosPresTemp(AltosLib.MISSING, AltosLib.MISSING);
+ return ms5607.pres_temp(raw_pres, raw_temp);
+ }
+
+ public int tick = AltosLib.MISSING;
+ private int first_tick = AltosLib.MISSING;
+ private int prev_tick = AltosLib.MISSING;
+
+ public void set_tick(int tick) {
+ if (tick != AltosLib.MISSING) {
+ if (prev_tick != AltosLib.MISSING) {
+ while (tick < prev_tick - 1000) {
+ tick += 65536;
+ }
+ }
+ if (first_tick == AltosLib.MISSING)
+ first_tick = tick;
+ prev_tick = tick;
+ this.tick = tick;
+ }
+ }
+
+ /* Reset all values which change during flight
+ */
+ public void reset() {
+ state = AltosLib.MISSING;
+ tick = AltosLib.MISSING;
+ prev_tick = AltosLib.MISSING;
+ temp_gps = null;
+ prev_gps = null;
+ temp_gps_sat_tick = AltosLib.MISSING;
+ accel = AltosLib.MISSING;
+ }
+
+ public int boost_tick = AltosLib.MISSING;
+
+ public void set_boost_tick() {
+ boost_tick = tick;
+ }
+
+ public double ticks_per_sec = 100.0;
+
+ public void set_ticks_per_sec(double ticks_per_sec) {
+ this.ticks_per_sec = ticks_per_sec;
+ }
+
+ public double time() {
+ if (tick == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ if (boost_tick != AltosLib.MISSING)
+ return (tick - boost_tick) / ticks_per_sec;
+ if (first_tick != AltosLib.MISSING)
+ return (tick - first_tick) / ticks_per_sec;
+ return tick / ticks_per_sec;
+ }
+
+ public double boost_time() {
+ if (boost_tick == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return boost_tick / ticks_per_sec;
+ }
+
+ public int state = AltosLib.MISSING;
+
+ public void set_state(int state) {
+ if (state >= AltosLib.ao_flight_boost && boost_tick == AltosLib.MISSING)
+ set_boost_tick();
+ this.state = state;
+ }
+
+ public AltosGPS gps_pad = null;
+
+ public double gps_pad_altitude = AltosLib.MISSING;
+
+ public void set_gps(AltosGPS gps) {
+ if ((state != AltosLib.MISSING && state < AltosLib.ao_flight_boost) || gps_pad == null)
+ gps_pad = gps;
+ if (gps_pad_altitude == AltosLib.MISSING && gps.alt != AltosLib.MISSING)
+ gps_pad_altitude = gps.alt;
+ }
+
+ /*
+ * While receiving GPS data, we construct a temporary GPS state
+ * object and then deliver the result atomically to the listener
+ */
+ AltosGPS temp_gps = null;
+ AltosGPS prev_gps = null;
+ int temp_gps_sat_tick = AltosLib.MISSING;
+
+ public AltosGPS temp_gps() {
+ return temp_gps;
+ }
+
+ public void reset_temp_gps() {
+ if (temp_gps != null) {
+ if (temp_gps.locked && temp_gps.nsat >= 4)
+ set_gps(temp_gps);
+ prev_gps = temp_gps;
+ temp_gps = null;
+ }
+ }
+
+ public boolean gps_pending() {
+ return temp_gps != null;
+ }
+
+ public AltosGPS make_temp_gps(int tick, boolean sats) {
+ if (temp_gps == null) {
+ if (prev_gps != null)
+ temp_gps = prev_gps.clone();
+ else
+ temp_gps = new AltosGPS();
+ }
+ if (sats) {
+ if (tick != temp_gps_sat_tick)
+ temp_gps.cc_gps_sat = null;
+ temp_gps_sat_tick = tick;
+ }
+ return temp_gps;
+ }
+
+ public double accel_zero_along, accel_zero_across, accel_zero_through;
+
+ public void set_accel_zero(double zero_along, double zero_across, double zero_through) {
+ if (zero_along != AltosLib.MISSING) {
+ accel_zero_along = zero_along;
+ accel_zero_across = zero_across;
+ accel_zero_through = zero_through;
+ }
+ }
+
+ public double accel_along(double counts) {
+ return AltosIMU.convert_accel(counts - accel_zero_along);
+ }
+
+ public double accel_across(double counts) {
+ return AltosIMU.convert_accel(counts - accel_zero_across);
+ }
+
+ public double accel_through(double counts) {
+ return AltosIMU.convert_accel(counts - accel_zero_through);
+ }
+
+ public double gyro_zero_roll, gyro_zero_pitch, gyro_zero_yaw;
+
+ public void set_gyro_zero(double roll, double pitch, double yaw) {
+ if (roll != AltosLib.MISSING) {
+ gyro_zero_roll = roll;
+ gyro_zero_pitch = pitch;
+ gyro_zero_yaw = yaw;
+ imu_wrap_checked = false;
+ }
+ }
+
+ public double gyro_roll(double counts) {
+ if (gyro_zero_roll == AltosLib.MISSING || counts == AltosLib.MISSING)
+ return AltosLib.MISSING;
+
+ return AltosIMU.gyro_degrees_per_second(counts, gyro_zero_roll);
+ }
+
+ public double gyro_pitch(double counts) {
+ if (gyro_zero_pitch == AltosLib.MISSING || counts == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return AltosIMU.gyro_degrees_per_second(counts, gyro_zero_pitch);
+ }
+
+ public double gyro_yaw(double counts) {
+ if (gyro_zero_yaw == AltosLib.MISSING || counts == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return AltosIMU.gyro_degrees_per_second(counts, gyro_zero_yaw);
+ }
+
+ private double gyro_zero_overflow(double first) {
+ double v = first / 128.0;
+ if (v < 0)
+ v = Math.ceil(v);
+ else
+ v = Math.floor(v);
+ if (v != 0)
+ System.out.printf("Adjusting gyro axis by %g steps\n", v);
+ return v * 128.0;
+ }
+
+ /* Initial TeleMega log format had only 16 bits for gyro cal, so the top 9 bits got lost as the
+ * cal data are scaled by 512. Use the first sample to adjust the cal value, assuming that it is
+ * from a time of fairly low rotation speed. Fixed in later TeleMega firmware by storing 32 bits
+ * of cal values.
+ */
+ private boolean imu_wrap_checked = false;
+
+ public void check_imu_wrap(double roll, double pitch, double yaw) {
+ if (!imu_wrap_checked) {
+ gyro_zero_roll += gyro_zero_overflow(roll);
+ gyro_zero_pitch += gyro_zero_overflow(pitch);
+ gyro_zero_yaw += gyro_zero_overflow(yaw);
+ imu_wrap_checked = true;
+ }
+ }
+
+ public double mag_along(double along) {
+ if (along == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return AltosMag.convert_gauss(along);
+ }
+
+ public double mag_across(double across) {
+ if (across == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return AltosMag.convert_gauss(across);
+ }
+
+ public double mag_through(double through) {
+ if (through == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return AltosMag.convert_gauss(through);
+ }
+
+ public AltosCalData() {
+ }
+
+ public AltosCalData(AltosConfigData config_data) {
+ set_serial(config_data.serial);
+ set_ticks_per_sec(100.0);
+ set_flight(config_data.flight);
+ set_callsign(config_data.callsign);
+ set_config(config_data.config_major, config_data.config_minor, config_data.flight_log_max);
+ set_firmware_version(config_data.version);
+ set_flight_params(config_data.apogee_delay / ticks_per_sec, config_data.apogee_lockout / ticks_per_sec);
+ set_pad_orientation(config_data.pad_orientation);
+ set_product(config_data.product);
+ set_accel_plus_minus(config_data.accel_cal_plus, config_data.accel_cal_minus);
+ set_accel_zero(config_data.accel_zero_along, config_data.accel_zero_across, config_data.accel_zero_through);
+ set_ms5607(config_data.ms5607);
+ try {
+ set_mma655x_inverted(config_data.mma655x_inverted());
+ } catch (AltosUnknownProduct up) {
+ }
+ set_pad_orientation(config_data.pad_orientation);
+ }
+}
diff --git a/altoslib/AltosCompanion.java b/altoslib/AltosCompanion.java
index 2c03c922..5ce333f8 100644
--- a/altoslib/AltosCompanion.java
+++ b/altoslib/AltosCompanion.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java
index 6b55cc6f..97a80bcb 100644
--- a/altoslib/AltosConfigData.java
+++ b/altoslib/AltosConfigData.java
@@ -16,13 +16,13 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.*;
import java.text.*;
import java.util.concurrent.*;
-public class AltosConfigData implements Iterable<String> {
+public class AltosConfigData {
/* Version information */
public String manufacturer;
@@ -33,9 +33,7 @@ public class AltosConfigData implements Iterable<String> {
public int log_space;
public String version;
public int altitude_32;
-
- /* Strings returned */
- public LinkedList<String> lines;
+ public int config_major, config_minor;
/* Config information */
/* HAS_FLIGHT*/
@@ -96,14 +94,13 @@ public class AltosConfigData implements Iterable<String> {
public int accel_zero_along, accel_zero_across, accel_zero_through;
/* ms5607 data */
- public int ms5607_reserved;
- public int ms5607_sens;
- public int ms5607_off;
- public int ms5607_tcs;
- public int ms5607_tco;
- public int ms5607_tref;
- public int ms5607_tempsens;
- public int ms5607_crc;
+ AltosMs5607 ms5607;
+
+ public AltosMs5607 ms5607() {
+ if (ms5607 == null)
+ ms5607 = new AltosMs5607();
+ return ms5607;
+ }
public static String get_string(String line, String label) throws ParseException {
if (line.startsWith(label)) {
@@ -142,21 +139,17 @@ public class AltosConfigData implements Iterable<String> {
throw new ParseException("mismatch", 0);
}
- public Iterator<String> iterator() {
- return lines.iterator();
- }
-
public int log_space() {
- if (log_space > 0)
+ if (log_space != AltosLib.MISSING)
return log_space;
- if (storage_size > 0) {
+ if (storage_size != AltosLib.MISSING) {
int space = storage_size;
- if (storage_erase_unit > 0 && use_flash_for_config())
+ if (storage_erase_unit != AltosLib.MISSING && use_flash_for_config())
space -= storage_erase_unit;
- if (space > 0)
+ if (space != AltosLib.MISSING)
return space;
}
return 0;
@@ -214,6 +207,10 @@ public class AltosConfigData implements Iterable<String> {
return r;
}
+ public boolean altitude_32() {
+ return altitude_32 == 1;
+ }
+
public int compare_version(String other) {
int[] me = parse_version(version);
int[] them = parse_version(other);
@@ -233,63 +230,63 @@ public class AltosConfigData implements Iterable<String> {
}
public void reset() {
- lines = new LinkedList<String>();
-
- manufacturer = "unknown";
- product = "unknown";
- serial = 0;
- flight = 0;
+ manufacturer = null;
+ product = null;
+ serial = AltosLib.MISSING;
+ flight = AltosLib.MISSING;
log_format = AltosLib.AO_LOG_FORMAT_UNKNOWN;
- log_space = -1;
+ log_space = AltosLib.MISSING;
version = "unknown";
+ config_major = AltosLib.MISSING;
+ config_minor = AltosLib.MISSING;
- main_deploy = -1;
- apogee_delay = -1;
- apogee_lockout = -1;
+ main_deploy = AltosLib.MISSING;
+ apogee_delay = AltosLib.MISSING;
+ apogee_lockout = AltosLib.MISSING;
- radio_frequency = -1;
+ radio_frequency = AltosLib.MISSING;
callsign = null;
- radio_enable = -1;
- radio_calibration = -1;
- radio_channel = -1;
- radio_setting = -1;
- telemetry_rate = -1;
+ radio_enable = AltosLib.MISSING;
+ radio_calibration = AltosLib.MISSING;
+ radio_channel = AltosLib.MISSING;
+ radio_setting = AltosLib.MISSING;
+ telemetry_rate = AltosLib.MISSING;
- accel_cal_plus = -1;
- accel_cal_minus = -1;
- pad_orientation = -1;
+ accel_cal_plus = AltosLib.MISSING;
+ accel_cal_minus = AltosLib.MISSING;
+ pad_orientation = AltosLib.MISSING;
- flight_log_max = -1;
- log_fixed = -1;
- ignite_mode = -1;
+ flight_log_max = AltosLib.MISSING;
+ log_fixed = AltosLib.MISSING;
+ ignite_mode = AltosLib.MISSING;
- aes_key = "";
+ aes_key = null;
- pyro = 0;
- npyro = 0;
+ pyro = AltosLib.MISSING;
+ npyro = AltosLib.MISSING;
pyros = null;
- pyro_firing_time = -1;
+ pyro_firing_time = AltosLib.MISSING;
- aprs_interval = -1;
- aprs_ssid = -1;
- aprs_format = -1;
+ aprs_interval = AltosLib.MISSING;
+ aprs_ssid = AltosLib.MISSING;
+ aprs_format = AltosLib.MISSING;
- beep = -1;
+ beep = AltosLib.MISSING;
- tracker_motion = -1;
- tracker_interval = -1;
+ tracker_motion = AltosLib.MISSING;
+ tracker_interval = AltosLib.MISSING;
- storage_size = -1;
- storage_erase_unit = -1;
- stored_flight = 0;
+ storage_size = AltosLib.MISSING;
+ storage_erase_unit = AltosLib.MISSING;
+ stored_flight = AltosLib.MISSING;
- accel_zero_along = -1;
- accel_zero_across = -1;
- accel_zero_through = -1;
+ accel_zero_along = AltosLib.MISSING;
+ accel_zero_across = AltosLib.MISSING;
+ accel_zero_through = AltosLib.MISSING;
}
public void parse_line(String line) {
- lines.add(line);
+
/* Version replies */
try { manufacturer = get_string(line, "manufacturer"); } catch (Exception e) {}
try { product = get_string(line, "product"); } catch (Exception e) {}
@@ -302,17 +299,31 @@ public class AltosConfigData implements Iterable<String> {
/* Version also contains MS5607 info, which we ignore here */
- try { ms5607_reserved = get_int(line, "ms5607 reserved:"); } catch (Exception e) {}
- try { ms5607_sens = get_int(line, "ms5607 sens:"); } catch (Exception e) {}
- try { ms5607_off = get_int(line, "ms5607 off:"); } catch (Exception e) {}
- try { ms5607_tcs = get_int(line, "ms5607 tcs:"); } catch (Exception e) {}
- try { ms5607_tco = get_int(line, "ms5607 tco:"); } catch (Exception e) {}
- try { ms5607_tref = get_int(line, "ms5607 tref:"); } catch (Exception e) {}
- try { ms5607_tempsens = get_int(line, "ms5607 tempsens:"); } catch (Exception e) {}
- try { ms5607_crc = get_int(line, "ms5607 crc:"); } catch (Exception e) {}
+ try { ms5607().reserved = get_int(line, "ms5607 reserved:"); } catch (Exception e) {}
+ try { ms5607().sens = get_int(line, "ms5607 sens:"); } catch (Exception e) {}
+ try { ms5607().off = get_int(line, "ms5607 off:"); } catch (Exception e) {}
+ try { ms5607().tcs = get_int(line, "ms5607 tcs:"); } catch (Exception e) {}
+ try { ms5607().tco = get_int(line, "ms5607 tco:"); } catch (Exception e) {}
+ try { ms5607().tref = get_int(line, "ms5607 tref:"); } catch (Exception e) {}
+ try { ms5607().tempsens = get_int(line, "ms5607 tempsens:"); } catch (Exception e) {}
+ try { ms5607().crc = get_int(line, "ms5607 crc:"); } catch (Exception e) {}
/* Config show replies */
+ try {
+ if (line.startsWith("Config version")) {
+ String[] bits = line.split("\\s+");
+ if (bits.length >= 3) {
+ String[] cfg = bits[2].split("\\.");
+
+ if (cfg.length >= 2) {
+ config_major = Integer.parseInt(cfg[0]);
+ config_minor = Integer.parseInt(cfg[1]);
+ }
+ }
+ }
+ } catch (Exception e) {}
+
/* HAS_FLIGHT */
try { main_deploy = get_int(line, "Main deploy:"); } catch (Exception e) {}
try { apogee_delay = get_int(line, "Apogee delay:"); } catch (Exception e) {}
@@ -361,7 +372,7 @@ public class AltosConfigData implements Iterable<String> {
pyros = new AltosPyro[npyro];
pyro = 0;
} catch (Exception e) {}
- if (npyro > 0) {
+ if (npyro != AltosLib.MISSING) {
try {
AltosPyro p = new AltosPyro(pyro, line);
if (pyro < npyro)
@@ -425,24 +436,23 @@ public class AltosConfigData implements Iterable<String> {
}
public boolean has_frequency() {
- return radio_frequency >= 0 || radio_setting >= 0 || radio_channel >= 0;
+ return radio_frequency != AltosLib.MISSING || radio_setting != AltosLib.MISSING || radio_channel != AltosLib.MISSING;
}
public boolean has_telemetry_rate() {
- return telemetry_rate >= 0;
+ return telemetry_rate != AltosLib.MISSING;
}
public void set_frequency(double freq) {
int frequency = radio_frequency;
int setting = radio_setting;
- if (frequency > 0) {
+ if (frequency != AltosLib.MISSING) {
radio_frequency = (int) Math.floor (freq * 1000 + 0.5);
- radio_channel = -1;
- } else if (setting > 0) {
- radio_setting =AltosConvert.radio_frequency_to_setting(freq,
- radio_calibration);
- radio_channel = -1;
+ radio_channel = AltosLib.MISSING;
+ } else if (setting != AltosLib.MISSING) {
+ radio_setting =AltosConvert.radio_frequency_to_setting(freq, radio_calibration);
+ radio_channel = AltosLib.MISSING;
} else {
radio_channel = AltosConvert.radio_frequency_to_channel(freq);
}
@@ -452,12 +462,12 @@ public class AltosConfigData implements Iterable<String> {
int channel = radio_channel;
int setting = radio_setting;
- if (radio_frequency < 0 && channel < 0 && setting < 0)
- return -1;
+ if (radio_frequency == AltosLib.MISSING && channel == AltosLib.MISSING && setting == AltosLib.MISSING)
+ return AltosLib.MISSING;
- if (channel < 0)
+ if (channel == AltosLib.MISSING)
channel = 0;
- if (setting < 0)
+ if (setting == AltosLib.MISSING)
setting = 0;
return AltosConvert.radio_to_frequency(radio_frequency,
@@ -492,56 +502,56 @@ public class AltosConfigData implements Iterable<String> {
public void get_values(AltosConfigValues source) throws AltosConfigDataException {
/* HAS_FLIGHT */
- if (main_deploy >= 0)
+ if (main_deploy != AltosLib.MISSING)
main_deploy = source.main_deploy();
- if (apogee_delay >= 0)
+ if (apogee_delay != AltosLib.MISSING)
apogee_delay = source.apogee_delay();
- if (apogee_lockout >= 0)
+ if (apogee_lockout != AltosLib.MISSING)
apogee_lockout = source.apogee_lockout();
/* HAS_RADIO */
if (has_frequency())
set_frequency(source.radio_frequency());
- if (radio_enable >= 0)
+ if (radio_enable != AltosLib.MISSING)
radio_enable = source.radio_enable();
if (callsign != null)
callsign = source.callsign();
- if (telemetry_rate >= 0)
+ if (telemetry_rate != AltosLib.MISSING)
telemetry_rate = source.telemetry_rate();
/* HAS_ACCEL */
- if (pad_orientation >= 0)
+ if (pad_orientation != AltosLib.MISSING)
pad_orientation = source.pad_orientation();
/* HAS_LOG */
- if (flight_log_max >= 0)
+ if (flight_log_max != AltosLib.MISSING)
flight_log_max = source.flight_log_max();
/* HAS_IGNITE */
- if (ignite_mode >= 0)
+ if (ignite_mode != AltosLib.MISSING)
ignite_mode = source.ignite_mode();
/* AO_PYRO_NUM */
- if (npyro > 0)
+ if (npyro != AltosLib.MISSING)
pyros = source.pyros();
- if (pyro_firing_time >= 0)
+ if (pyro_firing_time != AltosLib.MISSING)
pyro_firing_time = source.pyro_firing_time();
/* HAS_APRS */
- if (aprs_interval >= 0)
+ if (aprs_interval != AltosLib.MISSING)
aprs_interval = source.aprs_interval();
- if (aprs_ssid >= 0)
+ if (aprs_ssid != AltosLib.MISSING)
aprs_ssid = source.aprs_ssid();
- if (aprs_format >= 0)
+ if (aprs_format != AltosLib.MISSING)
aprs_format = source.aprs_format();
/* HAS_BEEP */
- if (beep >= 0)
+ if (beep != AltosLib.MISSING)
beep = source.beep();
/* HAS_TRACKER */
- if (tracker_motion >= 0)
+ if (tracker_motion != AltosLib.MISSING)
tracker_motion = source.tracker_motion();
- if (tracker_interval >= 0)
+ if (tracker_interval != AltosLib.MISSING)
tracker_interval = source.tracker_interval();
}
@@ -561,7 +571,7 @@ public class AltosConfigData implements Iterable<String> {
if (log_space() == 0)
max_enabled = false;
- if (log_fixed > 0)
+ if (log_fixed != AltosLib.MISSING)
max_enabled = false;
switch (log_format) {
@@ -569,7 +579,7 @@ public class AltosConfigData implements Iterable<String> {
max_enabled = false;
break;
default:
- if (stored_flight > 0)
+ if (stored_flight != AltosLib.MISSING)
max_enabled = false;
break;
}
@@ -581,7 +591,7 @@ public class AltosConfigData implements Iterable<String> {
dest.set_ignite_mode(ignite_mode);
dest.set_pad_orientation(pad_orientation);
dest.set_callsign(callsign);
- if (npyro > 0)
+ if (npyro != AltosLib.MISSING)
dest.set_pyros(pyros);
else
dest.set_pyros(null);
@@ -605,17 +615,17 @@ public class AltosConfigData implements Iterable<String> {
public void save(AltosLink link, boolean remote) throws InterruptedException, TimeoutException {
/* HAS_FLIGHT */
- if (main_deploy >= 0)
+ if (main_deploy != AltosLib.MISSING)
link.printf("c m %d\n", main_deploy);
- if (apogee_delay >= 0)
+ if (apogee_delay != AltosLib.MISSING)
link.printf("c d %d\n", apogee_delay);
- if (apogee_lockout >= 0)
+ if (apogee_lockout != AltosLib.MISSING)
link.printf("c L %d\n", apogee_lockout);
/* HAS_RADIO */
if (has_frequency()) {
- boolean has_frequency = radio_frequency >= 0;
- boolean has_setting = radio_setting > 0;
+ boolean has_frequency = radio_frequency != AltosLib.MISSING;
+ boolean has_setting = radio_setting != AltosLib.MISSING;
double frequency = frequency();
link.set_radio_frequency(frequency,
has_frequency,
@@ -631,7 +641,7 @@ public class AltosConfigData implements Iterable<String> {
}
}
- if (telemetry_rate >= 0) {
+ if (telemetry_rate != AltosLib.MISSING) {
link.printf("c T %d\n", telemetry_rate);
if (remote) {
link.flush_output();
@@ -653,12 +663,12 @@ public class AltosConfigData implements Iterable<String> {
}
}
- if (radio_enable >= 0)
+ if (radio_enable != AltosLib.MISSING)
link.printf("c e %d\n", radio_enable);
/* HAS_ACCEL */
/* UI doesn't support accel cal */
- if (pad_orientation >= 0)
+ if (pad_orientation != AltosLib.MISSING)
link.printf("c o %d\n", pad_orientation);
/* HAS_LOG */
@@ -666,36 +676,36 @@ public class AltosConfigData implements Iterable<String> {
link.printf("c l %d\n", flight_log_max);
/* HAS_IGNITE */
- if (ignite_mode >= 0)
+ if (ignite_mode != AltosLib.MISSING)
link.printf("c i %d\n", ignite_mode);
/* HAS_AES */
/* UI doesn't support AES key config */
/* AO_PYRO_NUM */
- if (npyro > 0) {
+ if (npyro != AltosLib.MISSING) {
for (int p = 0; p < pyros.length; p++) {
link.printf("c P %s\n",
pyros[p].toString());
}
}
- if (pyro_firing_time >= 0)
+ if (pyro_firing_time != AltosLib.MISSING)
link.printf("c I %d\n", (int) (pyro_firing_time * 100.0 + 0.5));
/* HAS_APRS */
- if (aprs_interval >= 0)
+ if (aprs_interval != AltosLib.MISSING)
link.printf("c A %d\n", aprs_interval);
- if (aprs_ssid >= 0)
+ if (aprs_ssid != AltosLib.MISSING)
link.printf("c S %d\n", aprs_ssid);
- if (aprs_format >= 0)
+ if (aprs_format != AltosLib.MISSING)
link.printf("c C %d\n", aprs_format);
/* HAS_BEEP */
- if (beep >= 0)
+ if (beep != AltosLib.MISSING)
link.printf("c b %d\n", beep);
/* HAS_TRACKER */
- if (tracker_motion >= 0 && tracker_interval >= 0)
+ if (tracker_motion != AltosLib.MISSING && tracker_interval != AltosLib.MISSING)
link.printf("c t %d %d\n", tracker_motion, tracker_interval);
/* HAS_GYRO */
@@ -719,5 +729,4 @@ public class AltosConfigData implements Iterable<String> {
break;
}
}
-
}
diff --git a/altoslib/AltosConfigDataException.java b/altoslib/AltosConfigDataException.java
index 59a8e9c1..fe6336b6 100644
--- a/altoslib/AltosConfigDataException.java
+++ b/altoslib/AltosConfigDataException.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosConfigDataException extends Exception {
diff --git a/altoslib/AltosConfigValues.java b/altoslib/AltosConfigValues.java
index bc20d21d..170b1112 100644
--- a/altoslib/AltosConfigValues.java
+++ b/altoslib/AltosConfigValues.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosConfigValues {
/* set and get all of the dialog values */
diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java
index 8617a12c..ed16541a 100644
--- a/altoslib/AltosConvert.java
+++ b/altoslib/AltosConvert.java
@@ -19,9 +19,14 @@
/*
* Sensor data conversion functions
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
+
+import java.util.*;
public class AltosConvert {
+
+ public static final double gravity = 9.80665;
+
/*
* Pressure Sensor Model, version 1.1
*
@@ -42,20 +47,20 @@ public class AltosConvert {
* in Joules/(kilogram-Kelvin).
*/
- public static final double GRAVITATIONAL_ACCELERATION = -9.80665;
- public static final double AIR_GAS_CONSTANT = 287.053;
- public static final double NUMBER_OF_LAYERS = 7;
- public static final double MAXIMUM_ALTITUDE = 84852.0;
- public static final double MINIMUM_PRESSURE = 0.3734;
- public static final double LAYER0_BASE_TEMPERATURE = 288.15;
- public static final double LAYER0_BASE_PRESSURE = 101325;
+ private static final double GRAVITATIONAL_ACCELERATION = -gravity;
+ private static final double AIR_GAS_CONSTANT = 287.053;
+ private static final double NUMBER_OF_LAYERS = 7;
+ private static final double MAXIMUM_ALTITUDE = 84852.0;
+ private static final double MINIMUM_PRESSURE = 0.3734;
+ private static final double LAYER0_BASE_TEMPERATURE = 288.15;
+ private static final double LAYER0_BASE_PRESSURE = 101325;
/* lapse rate and base altitude for each layer in the atmosphere */
- public static final double[] lapse_rate = {
+ private static final double[] lapse_rate = {
-0.0065, 0.0, 0.001, 0.0028, 0.0, -0.0028, -0.002
};
- public static final int[] base_altitude = {
+ private static final int[] base_altitude = {
0, 11000, 20000, 32000, 47000, 51000, 71000
};
@@ -179,6 +184,18 @@ public class AltosConvert {
return altitude;
}
+ public static double degrees_to_radians(double degrees) {
+ if (degrees == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return degrees * (Math.PI / 180.0);
+ }
+
+ public static double radians_to_degrees(double radians) {
+ if (radians == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return radians * (180.0 / Math.PI);
+ }
+
public static double
cc_battery_to_voltage(double battery)
{
@@ -186,7 +203,7 @@ public class AltosConvert {
}
public static double
- cc_ignitor_to_voltage(double ignite)
+ cc_igniter_to_voltage(double ignite)
{
return ignite / 32767 * 15.0;
}
@@ -253,7 +270,15 @@ public class AltosConvert {
return 3.3 * mega_adc(raw) * (5.1 + 10.0) / 10.0;
}
- static double easy_mini_voltage(int sensor, int serial) {
+ static double easy_mini_2_adc(int raw) {
+ return raw / 4095.0;
+ }
+
+ static double easy_mini_1_adc(int raw) {
+ return raw / 32767.0;
+ }
+
+ static double easy_mini_1_voltage(int sensor, int serial) {
double supply = 3.3;
double diode_offset = 0.0;
@@ -267,7 +292,13 @@ public class AltosConvert {
if (serial < 1665)
diode_offset = 0.150;
- return sensor / 32767.0 * supply * 127/27 + diode_offset;
+ return easy_mini_1_adc(sensor) * supply * 127/27 + diode_offset;
+ }
+
+ static double easy_mini_2_voltage(int sensor) {
+ double supply = 3.3;
+
+ return easy_mini_2_adc(sensor) * supply * 127/27;
}
public static double radio_to_frequency(int freq, int setting, int cal, int channel) {
@@ -305,6 +336,10 @@ public class AltosConvert {
return 434.550 + channel * 0.100;
}
+ public static int telem_to_rssi(int telem) {
+ return telem / 2 - 74;
+ }
+
public static int[] ParseHex(String line) {
String[] tokens = line.split("\\s+");
int[] array = new int[tokens.length];
@@ -370,12 +405,48 @@ public class AltosConvert {
return psi * 6894.76;
}
+ public static double pa_to_psi(double pa) {
+ return pa / 6894.76;
+ }
+
+ public static double n_to_lb(double n) {
+ return n * 0.22480894;
+ }
+
+ public static double lb_to_n(double lb) {
+ return lb / 0.22480894;
+ }
+
+ public static double acceleration_from_sensor(double sensor, double plus_g, double minus_g, double ground) {
+
+ if (sensor == AltosLib.MISSING)
+ return AltosLib.MISSING;
+
+ if (plus_g == AltosLib.MISSING || minus_g == AltosLib.MISSING)
+ return AltosLib.MISSING;
+
+ if (ground == AltosLib.MISSING)
+ ground = plus_g;
+
+ double counts_per_g = (plus_g - minus_g) / 2.0;
+ double counts_per_mss = counts_per_g / gravity;
+
+ if (counts_per_mss == 0)
+ return AltosLib.MISSING;
+
+ return (sensor - ground) / counts_per_mss;
+ }
+
public static boolean imperial_units = false;
public static AltosDistance distance = new AltosDistance();
public static AltosHeight height = new AltosHeight();
+ public static AltosPressure pressure = new AltosPressure();
+
+ public static AltosForce force = new AltosForce();
+
public static AltosSpeed speed = new AltosSpeed();
public static AltosAccel accel = new AltosAccel();
@@ -390,6 +461,14 @@ public class AltosConvert {
public static AltosLongitude longitude = new AltosLongitude();
+ public static AltosRotationRate rotation_rate = new AltosRotationRate();
+
+ public static AltosStateName state_name = new AltosStateName();
+
+ public static AltosPyroName pyro_name = new AltosPyroName();
+
+ public static AltosUnits magnetic_field = null;
+
public static String show_gs(String format, double a) {
a = meters_to_g(a);
format = format.concat(" g");
@@ -407,6 +486,13 @@ public class AltosConvert {
return csum & 0xff;
}
+ public static int checksum(List<Byte> data, int start, int length) {
+ int csum = 0x5a;
+ for (int i = 0; i < length; i++)
+ csum += data.get(i+start);
+ return csum & 0xff;
+ }
+
public static double beep_value_to_freq(int value) {
if (value == 0)
return 4000;
diff --git a/altoslib/AltosDataListener.java b/altoslib/AltosDataListener.java
new file mode 100644
index 00000000..5f89b3e4
--- /dev/null
+++ b/altoslib/AltosDataListener.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public abstract class AltosDataListener {
+
+ private AltosCalData cal_data = null;
+
+ public double time = AltosLib.MISSING;
+ public int state = AltosLib.MISSING;
+
+ public void set_tick(int tick) {
+ cal_data.set_tick(tick);
+ set_time(cal_data.time());
+ }
+
+ public AltosCalData cal_data() {
+ if (cal_data == null)
+ cal_data = new AltosCalData();
+ return cal_data;
+ }
+
+ public void set_time(double time) {
+ if (time != AltosLib.MISSING)
+ this.time = time;
+ }
+
+ public void set_serial(int serial) {
+ cal_data().set_serial(serial);
+ }
+
+ public double time() {
+ return time;
+ }
+
+ public void set_state(int state) {
+ cal_data().set_state(state);
+ if (state != AltosLib.MISSING)
+ this.state = state;
+ }
+
+ public void set_flight(int flight) {
+ cal_data().set_flight(flight);
+ }
+
+ /* Called after all records are captured */
+ public void finish() {
+ }
+
+ public abstract void set_rssi(int rssi, int status);
+ public abstract void set_received_time(long received_time);
+
+ public abstract void set_acceleration(double accel);
+ public abstract void set_pressure(double pa);
+ public abstract void set_thrust(double N);
+
+ public abstract void set_kalman(double height, double speed, double accel);
+
+ public abstract void set_temperature(double deg_c);
+ public abstract void set_battery_voltage(double volts);
+
+ public abstract void set_apogee_voltage(double volts);
+ public abstract void set_main_voltage(double volts);
+
+ public abstract void set_gps(AltosGPS gps);
+
+ public abstract void set_orient(double orient);
+ public abstract void set_gyro(double roll, double pitch, double yaw);
+ public abstract void set_accel_ground(double along, double across, double through);
+ public abstract void set_accel(double along, double across, double through);
+ public abstract void set_mag(double along, double across, double through);
+ public abstract void set_pyro_voltage(double volts);
+ public abstract void set_igniter_voltage(double[] voltage);
+ public abstract void set_pyro_fired(int pyro_mask);
+ public abstract void set_companion(AltosCompanion companion);
+
+ public AltosDataListener() {
+ }
+
+ public AltosDataListener(AltosCalData cal_data) {
+ this.cal_data = cal_data;
+ }
+}
diff --git a/altoslib/AltosStateUpdate.java b/altoslib/AltosDataProvider.java
index e9698cba..9589a8e6 100644
--- a/altoslib/AltosStateUpdate.java
+++ b/altoslib/AltosDataProvider.java
@@ -16,8 +16,8 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
-public interface AltosStateUpdate {
- public void update_state(AltosState state) throws InterruptedException, AltosUnknownProduct;
+public interface AltosDataProvider {
+ public void provide_data(AltosDataListener listener) throws InterruptedException, AltosUnknownProduct;
}
diff --git a/altoslib/AltosDebug.java b/altoslib/AltosDebug.java
index aa1b298f..24a25933 100644
--- a/altoslib/AltosDebug.java
+++ b/altoslib/AltosDebug.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
diff --git a/altoslib/AltosDistance.java b/altoslib/AltosDistance.java
index 0239c5ce..38efbf1a 100644
--- a/altoslib/AltosDistance.java
+++ b/altoslib/AltosDistance.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosDistance extends AltosUnits {
@@ -96,7 +96,7 @@ public class AltosDistance extends AltosUnits {
}
};
- range_imperial[1] = new AltosUnitsRange(AltosConvert.feet_to_meters(1000),
+ range_imperial[1] = new AltosUnitsRange(AltosConvert.feet_to_meters(5280),
"mi", "miles") {
double value(double v) {
return AltosConvert.meters_to_miles(v);
diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java
index 6ed14d3a..ad7bf881 100644
--- a/altoslib/AltosEeprom.java
+++ b/altoslib/AltosEeprom.java
@@ -1,132 +1,291 @@
/*
- * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ * Copyright © 2017 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; either version 2 of the License, or
+ * the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 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_11;
+package org.altusmetrum.altoslib_12;
-import java.io.*;
import java.util.*;
-import java.text.*;
+import java.io.*;
+
+public class AltosEeprom {
-public abstract class AltosEeprom implements AltosStateUpdate {
- public int cmd;
- public int tick;
- public int data8[];
- public boolean valid;
+ private AltosJson config;
+ ArrayList<Byte> data;
+ private AltosConfigData config_data;
- public int data8(int i) {
- return data8[i];
+ /*
+ * Public accessor APIs
+ */
+ public int data8(int offset) {
+ return ((int) data.get(offset)) & 0xff;
}
- public int data16(int i) {
- return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16;
+ public int data16(int offset) {
+ return data8(offset) | (data8(offset+1) << 8);
}
- public int data24(int i) {
- return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16);
+ public int data24(int offset) {
+ return (data8(offset) |
+ (data8(offset+1) << 8) |
+ (data8(offset+2) << 16));
}
- public int data32(int i) {
- return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24);
+ public int data32(int offset) {
+ return (data8(offset) |
+ (data8(offset+1) << 8) |
+ (data8(offset+2) << 16) |
+ (data8(offset+3) << 24));
}
- public boolean has_seconds() { return false; }
+ public int size() {
+ return data.size();
+ }
- public int seconds() { return 0; }
+ public AltosConfigData config_data() {
+ if (config_data == null) {
+ config_data = (AltosConfigData) config.make(AltosConfigData.class);
+ if (config_data == null)
+ config_data = new AltosConfigData();
- public final static int header_length = 4;
+ if (config_data.log_format == AltosLib.AO_LOG_FORMAT_UNKNOWN) {
+ config_data.log_format = AltosLib.AO_LOG_FORMAT_FULL;
+ if (config_data.product != null) {
+ if (config_data.product.startsWith("TeleMetrum"))
+ config_data.log_format = AltosLib.AO_LOG_FORMAT_FULL;
+ else if (config_data.product.startsWith("TeleMini"))
+ config_data.log_format = AltosLib.AO_LOG_FORMAT_TINY;
+ }
+ }
+ }
+ return config_data;
+ }
+
+ private void write_config(Writer w) throws IOException {
+ config.write(w, 0, true);
+ w.append('\n');
+ }
+
+ /*
+ * Private I/O APIs
+ */
+ private void write_data(Writer w) throws IOException {
+ PrintWriter pw = new PrintWriter(w);
- public abstract int record_length();
+ for (int i = 0; i < data.size(); i++) {
+ if (i > 0) {
+ if ((i & 0x1f) == 0)
+ pw.printf("\n");
+ else
+ pw.printf(" ");
+ }
+ pw.printf("%02x", data.get(i));
+ }
+ w.append('\n');
+ }
- public void update_state(AltosState state) {
- if (cmd == AltosLib.AO_LOG_FLIGHT)
- state.set_boost_tick(tick);
- else
- state.set_tick(tick);
+ private boolean read_config(InputStream stream) throws IOException {
+ config = AltosJson.fromInputStream(stream);
+ if (config == null)
+ return false;
+ return true;
}
- public void write(PrintStream out) {
- out.printf("%c %04x", cmd, tick);
- if (data8 != null) {
- for (int i = 0; i < data8.length; i++)
- out.printf (" %02x", data8[i]);
+ private String read_line(InputStream stream) throws IOException {
+ StringBuffer buffer = null;
+ int c;
+
+ for (;;) {
+ c = stream.read();
+ if (c == -1 && buffer == null)
+ return null;
+ if (buffer == null)
+ buffer = new StringBuffer();
+ if (c == -1 || c == '\n')
+ return buffer.toString();
+ buffer.append((char) c);
}
- out.printf ("\n");
}
- public String string() {
- String s;
+ private boolean read_data(InputStream stream) throws IOException {
+ String s;
+
+ data = new ArrayList<Byte>();
+ while ((s = read_line(stream)) != null) {
- s = String.format("%c %04x", cmd, tick);
- if (data8 != null) {
- for (int i = 0; i < data8.length; i++) {
- String d = String.format(" %02x", data8[i]);
- s = s.concat(d);
+ String[] tokens = s.split("\\s+");
+
+ for (int i = 0; i < tokens.length; i++) {
+ if (tokens[i].length() > 0) {
+ try {
+ data.add((byte) AltosLib.fromhex(tokens[i]));
+ } catch (NumberFormatException e) {
+ throw new IOException(e.toString());
+ }
+ }
}
}
- s = s.concat("\n");
- return s;
+ return true;
}
- void parse_chunk(AltosEepromChunk chunk, int start) throws ParseException {
- cmd = chunk.data(start);
+ private boolean read_old_config(InputStream stream) throws IOException {
+ AltosConfigData cfg = new AltosConfigData();
+ for (;;) {
+ boolean done = false;
- int data_length = record_length() - header_length;
+ /* The data starts with an upper case F character followed by a space */
+ stream.mark(2);
+ int first = stream.read();
+ if (first == 'F') {
+ int second = stream.read();
+ if (second == ' ')
+ done = true;
+ }
+ stream.reset();
+ if (done)
+ break;
- valid = !chunk.erased(start, record_length());
- if (valid) {
- if (AltosConvert.checksum(chunk.data, start, record_length()) != 0)
- throw new ParseException(String.format("invalid checksum at 0x%x",
- chunk.address + start), 0);
- } else {
- cmd = AltosLib.AO_LOG_INVALID;
+ String line = read_line(stream);
+ if (line == null)
+ return false;
+ cfg.parse_line(line);
}
+ config = new AltosJson(cfg);
+ return true;
+ }
- tick = chunk.data16(start+2);
+ private boolean read_old_data(InputStream stream) throws IOException {
+ String line;
- data8 = new int[data_length];
- for (int i = 0; i < data_length; i++)
- data8[i] = chunk.data(start + header_length + i);
- }
+ data = new ArrayList<Byte>();
+ while ((line = read_line(stream)) != null) {
+ String[] tokens = line.split("\\s+");
- void parse_string(String line) {
- valid = false;
- tick = 0;
- cmd = AltosLib.AO_LOG_INVALID;
+ /* Make sure there's at least a type and time */
+ if (tokens.length < 2)
+ break;
- int data_length = record_length() - header_length;
+ /* packet type */
+ if (tokens[0].length() != 1)
+ break;
+ int start = data.size();
- if (line == null)
- return;
- try {
- String[] tokens = line.split("\\s+");
+ if (config_data().log_format != AltosLib.AO_LOG_FORMAT_TINY) {
+ byte cmd = (byte) tokens[0].codePointAt(0);
+ data.add(cmd);
- if (tokens[0].length() == 1) {
- if (tokens.length == 2 + data_length) {
- cmd = tokens[0].codePointAt(0);
- tick = Integer.parseInt(tokens[1],16);
- valid = true;
- data8 = new int[data_length];
+ int time = AltosLib.fromhex(tokens[1]);
- for (int i = 0; i < data_length; i++)
- data8[i] = Integer.parseInt(tokens[2 + i],16);
+ data.add((byte) 0);
+ data.add((byte) (time & 0xff));
+ data.add((byte) (time >> 8));
+ }
+ if (tokens.length == 4) {
+ /* Handle ancient log files */
+ if (config_data().log_format == AltosLib.AO_LOG_FORMAT_TINY) {
+ /*
+ * Ancient TeleMini log files stored "extra" data to pretend
+ * that it was a TeleMetrum device. Throw that away and
+ * just save the actual log data.
+ */
+ int a = AltosLib.fromhex(tokens[2]);
+ int b = AltosLib.fromhex(tokens[3]);
+ if (a != 0)
+ b = 0x8000 | a;
+ data.add((byte) (b & 0xff));
+ data.add((byte) ((b >> 8)));
+ } else {
+ for (int i = 2; i < tokens.length; i++) {
+ int v = AltosLib.fromhex(tokens[i]);
+ data.add((byte) (v & 0xff));
+ data.add((byte) ((v >> 8)));
+ }
+ /* Re-compute the checksum byte */
+ data.set(start + 1, (byte) (256 - AltosConvert.checksum(data, start, data.size() - start)));
}
+ } else {
+ for (int i = 2; i < tokens.length; i++)
+ data.add((byte) AltosLib.fromhex(tokens[i]));
+ /* Re-compute the checksum byte */
+ data.set(start + 1, (byte) (256 - AltosConvert.checksum(data, start, data.size() - start)));
}
- } catch (NumberFormatException ne) {
}
+ return true;
+ }
+
+ private void read(InputStream stream) throws IOException {
+ BufferedInputStream bis = new BufferedInputStream(stream);
+
+ bis.mark(1);
+ int c = bis.read();
+ bis.reset();
+
+ if (c == '{') {
+ if (!read_config(bis))
+ throw new IOException("failed to read config");
+ if (!read_data(bis))
+ throw new IOException("failed to read data");
+ } else {
+ if (!read_old_config(bis))
+ throw new IOException("failed to read old config");
+ if (!read_old_data(bis))
+ throw new IOException("failed to read old data");
+ }
+ }
+
+ /*
+ * Public APIs for I/O
+ */
+ public void write(Writer w) throws IOException {
+ write_config(w);
+ write_data(w);
+ }
+
+ public String toString() {
+ try {
+ Writer w = new StringWriter();
+
+ write(w);
+ return w.toString();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public void print() throws IOException {
+ System.out.printf("%s", toString());
+ }
+
+ /*
+ * Constructors
+ */
+ public AltosEeprom(InputStream stream) throws IOException {
+ read(stream);
+ }
+
+ public AltosEeprom(String s) throws IOException {
+ read(new AltosStringInputStream(s));
+ }
+
+ public AltosEeprom(AltosJson config, ArrayList<Byte> data) {
+ this.config = config;
+ this.data = data;
+ }
+
+ public AltosEeprom(AltosConfigData config_data, ArrayList<Byte> data) {
+ this.config = new AltosJson(config_data);
+ this.data = data;
+ }
+
+ public AltosEeprom() {
}
}
diff --git a/altoslib/AltosEepromChunk.java b/altoslib/AltosEepromChunk.java
index 32d9f8ea..4f12c190 100644
--- a/altoslib/AltosEepromChunk.java
+++ b/altoslib/AltosEepromChunk.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.util.concurrent.*;
@@ -63,40 +63,8 @@ public class AltosEepromChunk {
return true;
}
- public AltosEeprom eeprom(int offset, int log_format, AltosState state) throws ParseException {
- AltosEeprom eeprom = null;
- switch (log_format) {
- case AltosLib.AO_LOG_FORMAT_FULL:
- eeprom = new AltosEepromTM(this, offset);
- break;
- case AltosLib.AO_LOG_FORMAT_TINY:
- eeprom = new AltosEepromTMini(this, offset, state);
- break;
- case AltosLib.AO_LOG_FORMAT_TELEMETRY:
- case AltosLib.AO_LOG_FORMAT_TELESCIENCE:
- break;
- case AltosLib.AO_LOG_FORMAT_TELEMEGA:
- case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
- eeprom = new AltosEepromMega(this, offset, log_format);
- break;
- case AltosLib.AO_LOG_FORMAT_TELEMETRUM:
- eeprom = new AltosEepromMetrum2(this, offset);
- break;
- case AltosLib.AO_LOG_FORMAT_TELEMINI2:
- case AltosLib.AO_LOG_FORMAT_TELEMINI3:
- case AltosLib.AO_LOG_FORMAT_EASYMINI:
- eeprom = new AltosEepromMini(this, offset);
- break;
- case AltosLib.AO_LOG_FORMAT_TELEGPS:
- eeprom = new AltosEepromGPS(this, offset);
- break;
- case AltosLib.AO_LOG_FORMAT_TELEFIRETWO:
- eeprom = new AltosEepromFireTwo(this, offset);
- break;
- default:
- throw new ParseException("unknown eeprom format " + log_format, 0);
- }
- return eeprom;
+ public boolean erased() {
+ return erased(0, chunk_size);
}
public AltosEepromChunk(AltosLink link, int block, boolean flush)
diff --git a/altoslib/AltosEepromDownload.java b/altoslib/AltosEepromDownload.java
index c38fcfdf..33f0dd17 100644
--- a/altoslib/AltosEepromDownload.java
+++ b/altoslib/AltosEepromDownload.java
@@ -16,13 +16,60 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
import java.text.*;
import java.util.concurrent.*;
+class AltosEepromNameData extends AltosDataListener {
+ AltosGPS gps = null;
+
+ public void set_rssi(int rssi, int status) { }
+ public void set_received_time(long received_time) { }
+
+ public void set_acceleration(double accel) { }
+ public void set_pressure(double pa) { }
+ public void set_thrust(double N) { }
+
+ public void set_temperature(double deg_c) { }
+ public void set_battery_voltage(double volts) { }
+
+ public void set_apogee_voltage(double volts) { }
+ public void set_main_voltage(double volts) { }
+
+ public void set_gps(AltosGPS gps) {
+ if (gps != null &&
+ gps.year != AltosLib.MISSING &&
+ gps.month != AltosLib.MISSING &&
+ gps.day != AltosLib.MISSING) {
+ this.gps = gps;
+ }
+ }
+
+ public boolean done() {
+ if (gps == null)
+ return false;
+ return true;
+ }
+
+ public void set_gyro(double roll, double pitch, double yaw) { }
+ public void set_accel_ground(double along, double across, double through) { }
+ public void set_accel(double along, double across, double through) { }
+ public void set_mag(double along, double across, double through) { }
+ public void set_pyro_voltage(double volts) { }
+ public void set_igniter_voltage(double[] voltage) { }
+ public void set_pyro_fired(int pyro_mask) { }
+ public void set_companion(AltosCompanion companion) { }
+ public void set_kalman(double height, double speed, double acceleration) { }
+ public void set_orient(double new_orient) { }
+
+ public AltosEepromNameData(AltosCalData cal_data) {
+ super(cal_data);
+ }
+}
+
public class AltosEepromDownload implements Runnable {
AltosLink link;
@@ -30,65 +77,38 @@ public class AltosEepromDownload implements Runnable {
Thread eeprom_thread;
AltosEepromMonitor monitor;
- boolean want_file;
- FileWriter eeprom_file;
- LinkedList<String> eeprom_pending;
-
AltosEepromList flights;
- boolean success;
String parse_errors;
- AltosState state;
- private void FlushPending() throws IOException {
- for (String s : flights.config_data) {
- eeprom_file.write(s);
- eeprom_file.write('\n');
- }
+ private boolean has_gps_date(AltosState state) {
+ if (state == null)
+ return false;
- for (String s : eeprom_pending)
- eeprom_file.write(s);
+ AltosGPS gps = state.gps;
+
+ return gps != null &&
+ gps.year != AltosLib.MISSING &&
+ gps.month != AltosLib.MISSING &&
+ gps.day != AltosLib.MISSING;
}
- private void CheckFile(boolean force) throws IOException {
- if (eeprom_file != null)
- return;
- if (force || (state.flight != 0 && want_file)) {
- AltosFile eeprom_name;
- AltosGPS gps = state.gps;
-
- if (gps != null &&
- gps.year != AltosLib.MISSING &&
- gps.month != AltosLib.MISSING &&
- gps.day != AltosLib.MISSING)
- {
- eeprom_name = new AltosFile(gps.year, gps.month, gps.day,
- state.serial, state.flight, "eeprom");
- } else
- eeprom_name = new AltosFile(state.serial, state.flight, "eeprom");
-
- eeprom_file = new FileWriter(eeprom_name);
- if (eeprom_file != null) {
- monitor.set_filename(eeprom_name.getName());
- FlushPending();
- eeprom_pending = null;
- }
- }
+ private AltosFile MakeFile(int serial, int flight, AltosEepromNameData name_data) throws IOException {
+ AltosFile eeprom_name;
+
+ if (name_data.gps != null) {
+ AltosGPS gps = name_data.gps;
+ eeprom_name = new AltosFile(gps.year, gps.month, gps.day,
+ serial, flight, "eeprom");
+ } else
+ eeprom_name = new AltosFile(serial, flight, "eeprom");
+
+ return eeprom_name;
}
boolean done;
int prev_state;
int state_block;
- void LogEeprom(AltosEeprom r) throws IOException {
- if (r.cmd != AltosLib.AO_LOG_INVALID) {
- String line = r.string();
- if (eeprom_file != null)
- eeprom_file.write(line);
- else
- eeprom_pending.add(line);
- }
- }
-
void LogError(String error) {
if (parse_errors != null)
parse_errors.concat(error.concat("\n"));
@@ -96,112 +116,100 @@ public class AltosEepromDownload implements Runnable {
parse_errors = error;
}
- void CaptureEeprom(AltosEepromChunk eechunk, int log_format) throws IOException, ParseException {
- boolean any_valid = false;
- boolean got_flight = false;
-
- int record_length = 8;
-
- state.set_serial(flights.config_data.serial);
- monitor.set_serial(flights.config_data.serial);
-
- for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += record_length) {
- AltosEeprom r = null;
-
- try {
- r = eechunk.eeprom(i, log_format, state);
- } catch (ParseException pe) {
- LogError(pe.getMessage());
- r = null;
- }
+ class BlockCache extends Hashtable<Integer,AltosEepromChunk> {
+ AltosEepromLog log;
- if (r == null)
- continue;
-
- record_length = r.record_length();
-
- r.update_state(state);
+ AltosEepromChunk get(int start, boolean add) throws TimeoutException, InterruptedException {
+ if (contains(start))
+ return super.get(start);
+ AltosEepromChunk eechunk = new AltosEepromChunk(link, start, start == log.start_block);
+ if (add)
+ put(start, eechunk);
+ return eechunk;
+ }
- if (!got_flight && state.flight != AltosLib.MISSING)
- monitor.set_flight(state.flight);
+ public BlockCache(AltosEepromLog log) {
+ this.log = log;
+ }
+ }
- /* Monitor state transitions to update display */
- if (state.state() != AltosLib.ao_flight_invalid &&
- state.state() <= AltosLib.ao_flight_landed)
- {
- if (state.state() > AltosLib.ao_flight_pad)
- want_file = true;
- if (state.state() == AltosLib.ao_flight_landed)
- done = true;
- }
+ int FindLastLog(AltosEepromLog log, BlockCache cache) throws TimeoutException, InterruptedException {
+ int low = log.start_block;
+ int high = log.end_block - 1;
- if (state.gps != null)
- want_file = true;
+ while (low <= high) {
+ int mid = (high + low) / 2;
- if (r.valid) {
- any_valid = true;
- LogEeprom(r);
- }
+ if (!cache.get(mid, true).erased())
+ low = mid + 1;
+ else
+ high = mid - 1;
}
- if (!any_valid)
- done = true;
-
- CheckFile(false);
+ return low;
}
void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException, ParseException {
int block, state_block = 0;
int log_format = flights.config_data.log_format;
-
- state = new AltosState();
+ BlockCache cache = new BlockCache(log);
done = false;
if (flights.config_data.serial < 0)
throw new IOException("no serial number found");
- /* Reset per-capture variables */
- want_file = false;
- eeprom_pending = new LinkedList<String>();
-
/* Set serial number in the monitor dialog window */
- /* Now scan the eeprom, reading blocks of data and converting to .eeprom file form */
-
- state_block = log.start_block;
- prev_state = AltosLib.ao_flight_startup;
- for (block = log.start_block; !done && block < log.end_block; block++) {
- AltosEepromChunk eechunk = new AltosEepromChunk(link, block, block == log.start_block);
-
- /*
- * Guess what kind of data is there if the device
- * didn't tell us
- */
-
- if (log_format == AltosLib.AO_LOG_FORMAT_UNKNOWN) {
- if (block == log.start_block) {
- if (eechunk.data(0) == AltosLib.AO_LOG_FLIGHT)
- log_format = AltosLib.AO_LOG_FORMAT_FULL;
- else
- log_format = AltosLib.AO_LOG_FORMAT_TINY;
- }
- }
+ monitor.set_serial(log.serial);
+ monitor.set_flight(log.flight);
- CaptureEeprom (eechunk, log_format);
+ int start_block = log.start_block;
+ int end_block = FindLastLog(log, cache);
- if (state.state() != prev_state && state.state() != AltosLib.ao_flight_invalid) {
- state_block = block;
- prev_state = state.state();
- }
+ monitor.set_max(end_block - start_block - 1);
- monitor.set_value(state.state_name(),
- state.state(),
- block - state_block,
- block - log.start_block);
+ ArrayList<Byte> data = new ArrayList<Byte>();
+
+ /* Now scan the eeprom, reading blocks of data to create a byte array of data */
+
+ for (block = start_block; block < end_block; block++) {
+ monitor.set_block(block - start_block);
+
+ AltosEepromChunk eechunk = cache.get(block, false);
+
+ for (int i = 0; i < eechunk.data.length; i++)
+ data.add((byte) eechunk.data[i]);
}
- CheckFile(true);
+
+ /* Construct our internal representation of the eeprom data */
+ AltosEeprom eeprom = new AltosEeprom(flights.config_data, data);
+
+ /* Now see if we can't actually parse the resulting
+ * file to generate a better filename. Note that this
+ * doesn't need to work; we'll still save the data using
+ * a less accurate name.
+ */
+ AltosEepromRecordSet set = new AltosEepromRecordSet(eeprom);
+ AltosEepromNameData name_data = new AltosEepromNameData(set.cal_data());
+
+ for (AltosEepromRecord record : set.ordered) {
+ record.provide_data(name_data, set.cal_data());
+ if (name_data.done())
+ break;
+ }
+
+ AltosFile f = MakeFile(flights.config_data.serial, log.flight, name_data);
+
+ monitor.set_filename(f.toString());
+
+ FileWriter w = new FileWriter(f);
+
+ eeprom.write(w);
+ w.close();
}
public void run () {
+ boolean success = false;
+
try {
boolean failed = false;
if (remote)
@@ -211,16 +219,11 @@ public class AltosEepromDownload implements Runnable {
parse_errors = null;
if (log.selected) {
monitor.reset();
- eeprom_file = null;
try {
CaptureLog(log);
} catch (ParseException e) {
LogError(e.getMessage());
}
- if (eeprom_file != null) {
- eeprom_file.flush();
- eeprom_file.close();
- }
}
if (parse_errors != null) {
failed = true;
@@ -273,12 +276,6 @@ public class AltosEepromDownload implements Runnable {
link = given_link;
remote = given_remote;
flights = given_flights;
- success = false;
-
- if (flights.config_data.log_has_state())
- monitor.set_states(AltosLib.ao_flight_boost, AltosLib.ao_flight_landed);
- else
- monitor.set_states(AltosLib.ao_flight_invalid, AltosLib.ao_flight_invalid);
monitor.start();
}
diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java
index 5544ec37..067f0302 100644
--- a/altoslib/AltosEepromFile.java
+++ b/altoslib/AltosEepromFile.java
@@ -16,127 +16,36 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
import java.text.*;
-class AltosEepromIterator implements Iterator<AltosState> {
- AltosState state;
- Iterator<AltosEeprom> body;
- AltosEeprom next;
- boolean seen;
+public class AltosEepromFile implements AltosRecordSet {
- public boolean hasNext() {
- return !seen || body.hasNext();
- }
-
- public AltosState next() {
- if (seen) {
- AltosState n = state.clone();
- AltosEeprom e = body.next();
-
- e.update_state(n);
- state = n;
- }
- seen = true;
- return state;
- }
-
- public void remove () {
- }
-
- public AltosEepromIterator(AltosState start, Iterator<AltosEeprom> body) {
- this.state = start;
- this.body = body;
- this.seen = false;
- }
-}
-
-public class AltosEepromFile extends AltosStateIterable {
-
- AltosEepromIterable headers;
- AltosEepromIterable body;
- AltosState start;
+ AltosEepromRecordSet set;
public void write_comments(PrintStream out) {
- headers.write(out);
}
public void write(PrintStream out) {
- headers.write(out);
- body.write(out);
+ out.printf("%s\n", set.eeprom.toString());
}
- public AltosEepromFile(FileInputStream input) {
- headers = new AltosEepromIterable(AltosEepromHeader.read(input));
-
- start = headers.state();
- if (start.state() != AltosLib.ao_flight_stateless)
- start.set_state(AltosLib.ao_flight_pad);
-
- if (start.log_format == AltosLib.MISSING) {
- if (start.product != null) {
- if (start.product.startsWith("TeleMetrum"))
- start.log_format = AltosLib.AO_LOG_FORMAT_FULL;
- else if (start.product.startsWith("TeleMini"))
- start.log_format = AltosLib.AO_LOG_FORMAT_TINY;
- }
- }
-
- switch (start.log_format) {
- case AltosLib.AO_LOG_FORMAT_FULL:
- body = new AltosEepromIterable(AltosEepromTM.read(input));
- break;
- case AltosLib.AO_LOG_FORMAT_TINY:
- body = new AltosEepromIterable(AltosEepromTMini.read(input));
- break;
- case AltosLib.AO_LOG_FORMAT_TELEMETRY:
- case AltosLib.AO_LOG_FORMAT_TELESCIENCE:
- case AltosLib.AO_LOG_FORMAT_TELEMEGA:
- case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
- body = new AltosEepromIterable(AltosEepromMega.read(input, start.log_format));
- break;
- case AltosLib.AO_LOG_FORMAT_TELEMETRUM:
- body = new AltosEepromIterable(AltosEepromMetrum2.read(input));
- break;
- case AltosLib.AO_LOG_FORMAT_TELEMINI2:
- case AltosLib.AO_LOG_FORMAT_TELEMINI3:
- case AltosLib.AO_LOG_FORMAT_EASYMINI:
- body = new AltosEepromIterable(AltosEepromMini.read(input));
- break;
- case AltosLib.AO_LOG_FORMAT_TELEGPS:
- body = new AltosEepromIterable(AltosEepromGPS.read(input));
- break;
- case AltosLib.AO_LOG_FORMAT_TELEFIRETWO:
- body = new AltosEepromIterable(AltosEepromFireTwo.read(input));
- break;
- default:
- body = new AltosEepromIterable(new LinkedList<AltosEeprom>());
- break;
- }
+ public AltosEepromFile(InputStream input) throws IOException {
+ set = new AltosEepromRecordSet(input);
+ }
- /* Find boost tick */
- AltosState state = start.clone();
- for (AltosEeprom eeprom : body) {
- eeprom.update_state(state);
- state.finish_update();
- if (state.state() >= AltosLib.ao_flight_boost) {
- start.set_boost_tick(state.tick);
- break;
- }
- }
+ public AltosConfigData config_data() {
+ return set.config_data();
}
- public Iterator<AltosState> iterator() {
- AltosState state = start.clone();
- Iterator<AltosEeprom> i = body.iterator();
+ public AltosCalData cal_data() {
+ return set.cal_data();
+ }
- while (i.hasNext() && !state.valid()) {
- i.next().update_state(state);
- state.finish_update();
- }
- return new AltosEepromIterator(state, i);
+ public void capture_series(AltosDataListener series) {
+ set.capture_series(series);
}
}
diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java
deleted file mode 100644
index 37b666b4..00000000
--- a/altoslib/AltosEepromHeader.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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_11;
-
-import java.io.*;
-import java.util.*;
-import java.text.*;
-
-public class AltosEepromHeader extends AltosEeprom {
-
- public int cmd;
- public String data;
- public int config_a, config_b, config_c;
- public boolean last;
- public boolean valid;
-
- public int record_length () { return 0; }
-
- /* XXX pull rest of config data to state */
- public void update_state(AltosState state) {
- switch (cmd) {
- case AltosLib.AO_LOG_CONFIG_VERSION:
- break;
- case AltosLib.AO_LOG_MAIN_DEPLOY:
- break;
- case AltosLib.AO_LOG_APOGEE_DELAY:
- break;
- case AltosLib.AO_LOG_RADIO_CHANNEL:
- break;
- case AltosLib.AO_LOG_CALLSIGN:
- state.set_callsign(data);
- break;
- case AltosLib.AO_LOG_ACCEL_CAL:
- state.set_accel_g(config_a, config_b);
- break;
- case AltosLib.AO_LOG_RADIO_CAL:
- break;
- case AltosLib.AO_LOG_MANUFACTURER:
- break;
- case AltosLib.AO_LOG_PRODUCT:
- state.product = data;
- break;
- case AltosLib.AO_LOG_LOG_FORMAT:
- state.set_log_format(config_a);
- break;
- case AltosLib.AO_LOG_SERIAL_NUMBER:
- state.set_serial(config_a);
- break;
- case AltosLib.AO_LOG_BARO_RESERVED:
- state.make_baro();
- state.baro.reserved = config_a;
- break;
- case AltosLib.AO_LOG_BARO_SENS:
- state.make_baro();
- state.baro.sens = config_a;
- break;
- case AltosLib.AO_LOG_BARO_OFF:
- state.make_baro();
- state.baro.off = config_a;
- break;
- case AltosLib.AO_LOG_BARO_TCS:
- state.make_baro();
- state.baro.tcs = config_a;
- break;
- case AltosLib.AO_LOG_BARO_TCO:
- state.make_baro();
- state.baro.tco = config_a;
- break;
- case AltosLib.AO_LOG_BARO_TREF:
- state.make_baro();
- state.baro.tref = config_a;
- break;
- case AltosLib.AO_LOG_BARO_TEMPSENS:
- state.make_baro();
- state.baro.tempsens = config_a;
- break;
- case AltosLib.AO_LOG_BARO_CRC:
- state.make_baro();
- state.baro.crc = config_a;
- break;
- case AltosLib.AO_LOG_IMU_CAL:
- state.set_accel_zero(config_a, config_b, config_c);
- break;
- case AltosLib.AO_LOG_SOFTWARE_VERSION:
- state.set_firmware_version(data);
- break;
- case AltosLib.AO_LOG_FREQUENCY:
- case AltosLib.AO_LOG_APOGEE_LOCKOUT:
- case AltosLib.AO_LOG_RADIO_RATE:
- case AltosLib.AO_LOG_IGNITE_MODE:
- break;
- case AltosLib.AO_LOG_PAD_ORIENTATION:
- state.set_pad_orientation(config_a);
- break;
- case AltosLib.AO_LOG_RADIO_ENABLE:
- case AltosLib.AO_LOG_AES_KEY:
- case AltosLib.AO_LOG_APRS:
- case AltosLib.AO_LOG_BEEP_SETTING:
- case AltosLib.AO_LOG_TRACKER_SETTING:
- case AltosLib.AO_LOG_PYRO_TIME:
- case AltosLib.AO_LOG_APRS_ID:
- break;
- case AltosLib.AO_LOG_ALTITUDE_32:
- state.set_altitude_32(config_a);
- break;
- }
- }
-
- public void write(PrintStream out) {
- switch (cmd) {
- case AltosLib.AO_LOG_CONFIG_VERSION:
- out.printf("# Config version: %s\n", data);
- break;
- case AltosLib.AO_LOG_MAIN_DEPLOY:
- out.printf("# Main deploy: %s\n", config_a);
- break;
- case AltosLib.AO_LOG_APOGEE_DELAY:
- out.printf("# Apogee delay: %s\n", config_a);
- break;
- case AltosLib.AO_LOG_RADIO_CHANNEL:
- out.printf("# Radio channel: %s\n", config_a);
- break;
- case AltosLib.AO_LOG_CALLSIGN:
- out.printf("# Callsign: %s\n", data);
- break;
- case AltosLib.AO_LOG_ACCEL_CAL:
- out.printf ("# Accel cal: %d %d\n", config_a, config_b);
- break;
- case AltosLib.AO_LOG_RADIO_CAL:
- out.printf ("# Radio cal: %d\n", config_a);
- break;
- case AltosLib.AO_LOG_MAX_FLIGHT_LOG:
- out.printf ("# Max flight log: %d\n", config_a);
- break;
- case AltosLib.AO_LOG_MANUFACTURER:
- out.printf ("# Manufacturer: %s\n", data);
- break;
- case AltosLib.AO_LOG_PRODUCT:
- out.printf ("# Product: %s\n", data);
- break;
- case AltosLib.AO_LOG_SERIAL_NUMBER:
- out.printf ("# Serial number: %d\n", config_a);
- break;
- case AltosLib.AO_LOG_SOFTWARE_VERSION:
- out.printf ("# Software version: %s\n", data);
- break;
- case AltosLib.AO_LOG_BARO_RESERVED:
- out.printf ("# Baro reserved: %d\n", config_a);
- break;
- case AltosLib.AO_LOG_BARO_SENS:
- out.printf ("# Baro sens: %d\n", config_a);
- break;
- case AltosLib.AO_LOG_BARO_OFF:
- out.printf ("# Baro off: %d\n", config_a);
- break;
- case AltosLib.AO_LOG_BARO_TCS:
- out.printf ("# Baro tcs: %d\n", config_a);
- break;
- case AltosLib.AO_LOG_BARO_TCO:
- out.printf ("# Baro tco: %d\n", config_a);
- break;
- case AltosLib.AO_LOG_BARO_TREF:
- out.printf ("# Baro tref: %d\n", config_a);
- break;
- case AltosLib.AO_LOG_BARO_TEMPSENS:
- out.printf ("# Baro tempsens: %d\n", config_a);
- break;
- case AltosLib.AO_LOG_BARO_CRC:
- out.printf ("# Baro crc: %d\n", config_a);
- break;
- case AltosLib.AO_LOG_IMU_CAL:
- out.printf ("# IMU cal: %d %d %d\n", config_a, config_b, config_c);
- break;
- case AltosLib.AO_LOG_FREQUENCY:
- case AltosLib.AO_LOG_APOGEE_LOCKOUT:
- case AltosLib.AO_LOG_RADIO_RATE:
- case AltosLib.AO_LOG_IGNITE_MODE:
- break;
- case AltosLib.AO_LOG_PAD_ORIENTATION:
- out.printf("# Pad orientation: %d\n", config_a);
- break;
- case AltosLib.AO_LOG_RADIO_ENABLE:
- case AltosLib.AO_LOG_AES_KEY:
- case AltosLib.AO_LOG_APRS:
- case AltosLib.AO_LOG_BEEP_SETTING:
- case AltosLib.AO_LOG_TRACKER_SETTING:
- case AltosLib.AO_LOG_PYRO_TIME:
- case AltosLib.AO_LOG_APRS_ID:
- break;
- case AltosLib.AO_LOG_ALTITUDE_32:
- out.printf("# Altitude-32: %d\n", config_a);
- break;
- }
- }
-
- public AltosEepromHeader (String[] tokens) {
- last = false;
- valid = true;
- try {
- if (tokens[0].equals("Config") && tokens[1].equals("version:")) {
- cmd = AltosLib.AO_LOG_CONFIG_VERSION;
- data = tokens[2];
- } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) {
- cmd = AltosLib.AO_LOG_MAIN_DEPLOY;
- config_a = Integer.parseInt(tokens[2]);
- } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) {
- cmd = AltosLib.AO_LOG_APOGEE_DELAY;
- config_a = Integer.parseInt(tokens[2]);
- } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) {
- cmd = AltosLib.AO_LOG_RADIO_CHANNEL;
- config_a = Integer.parseInt(tokens[2]);
- } else if (tokens[0].equals("Callsign:")) {
- cmd = AltosLib.AO_LOG_CALLSIGN;
- data = tokens[1].replaceAll("\"","");
- } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) {
- cmd = AltosLib.AO_LOG_ACCEL_CAL;
- config_a = Integer.parseInt(tokens[3]);
- config_b = Integer.parseInt(tokens[5]);
- } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) {
- cmd = AltosLib.AO_LOG_RADIO_CAL;
- config_a = Integer.parseInt(tokens[2]);
- } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) {
- cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG;
- config_a = Integer.parseInt(tokens[3]);
- } else if (tokens[0].equals("manufacturer")) {
- cmd = AltosLib.AO_LOG_MANUFACTURER;
- data = tokens[1];
- } else if (tokens[0].equals("product")) {
- cmd = AltosLib.AO_LOG_PRODUCT;
- data = tokens[1];
- } else if (tokens[0].equals("serial-number")) {
- cmd = AltosLib.AO_LOG_SERIAL_NUMBER;
- config_a = Integer.parseInt(tokens[1]);
- } else if (tokens[0].equals("log-format")) {
- cmd = AltosLib.AO_LOG_LOG_FORMAT;
- config_a = Integer.parseInt(tokens[1]);
- } else if (tokens[0].equals("altitude-32")) {
- cmd = AltosLib.AO_LOG_ALTITUDE_32;
- config_a = Integer.parseInt(tokens[1]);
- } else if (tokens[0].equals("software-version")) {
- cmd = AltosLib.AO_LOG_SOFTWARE_VERSION;
- data = tokens[1];
- last = true;
- } else if (tokens[0].equals("ms5607")) {
- if (tokens[1].equals("reserved:")) {
- cmd = AltosLib.AO_LOG_BARO_RESERVED;
- config_a = Integer.parseInt(tokens[2]);
- } else if (tokens[1].equals("sens:")) {
- cmd = AltosLib.AO_LOG_BARO_SENS;
- config_a = Integer.parseInt(tokens[2]);
- } else if (tokens[1].equals("off:")) {
- cmd = AltosLib.AO_LOG_BARO_OFF;
- config_a = Integer.parseInt(tokens[2]);
- } else if (tokens[1].equals("tcs:")) {
- cmd = AltosLib.AO_LOG_BARO_TCS;
- config_a = Integer.parseInt(tokens[2]);
- } else if (tokens[1].equals("tco:")) {
- cmd = AltosLib.AO_LOG_BARO_TCO;
- config_a = Integer.parseInt(tokens[2]);
- } else if (tokens[1].equals("tref:")) {
- cmd = AltosLib.AO_LOG_BARO_TREF;
- config_a = Integer.parseInt(tokens[2]);
- } else if (tokens[1].equals("tempsens:")) {
- cmd = AltosLib.AO_LOG_BARO_TEMPSENS;
- config_a = Integer.parseInt(tokens[2]);
- } else if (tokens[1].equals("crc:")) {
- cmd = AltosLib.AO_LOG_BARO_CRC;
- config_a = Integer.parseInt(tokens[2]);
- } else {
- cmd = AltosLib.AO_LOG_INVALID;
- data = tokens[2];
- }
- } else if (tokens[0].equals("IMU") && tokens[1].equals("cal")) {
- cmd = AltosLib.AO_LOG_IMU_CAL;
- config_a = Integer.parseInt(tokens[3]);
- config_b = Integer.parseInt(tokens[5]);
- config_c = Integer.parseInt(tokens[7]);
- } else if (tokens[0].equals("Pad") && tokens[1].equals("orientation:")) {
- cmd = AltosLib.AO_LOG_PAD_ORIENTATION;
- config_a = Integer.parseInt(tokens[2]);
- } else
- valid = false;
- } catch (Exception e) {
- valid = false;
- }
- }
-
- static public LinkedList<AltosEeprom> read(FileInputStream input) {
- LinkedList<AltosEeprom> headers = new LinkedList<AltosEeprom>();
-
- for (;;) {
- try {
- String line = AltosLib.gets(input);
- if (line == null)
- break;
- AltosEepromHeader header = new AltosEepromHeader(line);
- headers.add(header);
- if (header.last)
- break;
- } catch (IOException ie) {
- break;
- }
- }
-
- return headers;
- }
-
- static public void write (PrintStream out, LinkedList<AltosEepromHeader> headers) {
- out.printf("# Comments\n");
- for (AltosEepromHeader header : headers) {
- header.write(out);
- }
-
- }
-
- public AltosEepromHeader (String line) {
- this(line.split("\\s+"));
- }
-}
diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java
deleted file mode 100644
index 77632ac1..00000000
--- a/altoslib/AltosEepromIterable.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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_11;
-
-import java.io.*;
-import java.util.*;
-import java.text.*;
-
-class AltosEepromOrdered implements Comparable<AltosEepromOrdered> {
- AltosEeprom eeprom;
- int index;
- int tick;
-
- int cmdi() {
- if (eeprom.cmd == AltosLib.AO_LOG_FLIGHT)
- return 0;
- return 1;
- }
-
- public int compareTo(AltosEepromOrdered o) {
- int cmd_diff = cmdi() - o.cmdi();
-
- if (cmd_diff != 0)
- return cmd_diff;
-
- if (eeprom.has_seconds() && o.eeprom.has_seconds()) {
- int seconds_diff = eeprom.seconds() - o.eeprom.seconds();
-
- if (seconds_diff != 0)
- return seconds_diff;
- }
-
- int tick_diff = tick - o.tick;
-
- if (tick_diff != 0)
- return tick_diff;
- return index - o.index;
- }
-
- AltosEepromOrdered (AltosEeprom eeprom, int index, int tick) {
- this.eeprom = eeprom;
- this.index = index;
- this.tick = tick;
- }
-}
-
-class AltosEepromOrderedIterator implements Iterator<AltosEeprom> {
- TreeSet<AltosEepromOrdered> olist;
- Iterator<AltosEepromOrdered> oiterator;
-
- public AltosEepromOrderedIterator(Iterable<AltosEeprom> eeproms) {
- olist = new TreeSet<AltosEepromOrdered>();
-
- int tick = 0;
- int index = 0;
- boolean first = true;
-
- for (AltosEeprom e : eeproms) {
- int t = e.tick;
- if (first)
- tick = t;
- else {
- while (t < tick - 32767)
- t += 65536;
- tick = t;
- }
- olist.add(new AltosEepromOrdered(e, index++, tick));
- first = false;
- }
-
- oiterator = olist.iterator();
- }
-
- public boolean hasNext() {
- return oiterator.hasNext();
- }
-
- public AltosEeprom next() {
- return oiterator.next().eeprom;
- }
-
- public void remove () {
- }
-}
-
-public class AltosEepromIterable implements Iterable<AltosEeprom> {
- public LinkedList<AltosEeprom> eeproms;
-
- public void write(PrintStream out) {
- for (AltosEeprom eeprom : eeproms)
- eeprom.write(out);
- }
-
- public AltosState state() {
- AltosState state = new AltosState();
-
- for (AltosEeprom header : eeproms)
- header.update_state(state);
- return state;
- }
-
- public AltosEepromIterable(LinkedList<AltosEeprom> eeproms) {
- this.eeproms = eeproms;
- }
-
- public Iterator<AltosEeprom> iterator() {
- if (eeproms == null)
- eeproms = new LinkedList<AltosEeprom>();
- return new AltosEepromOrderedIterator(eeproms);
- }
-}
diff --git a/altoslib/AltosEepromList.java b/altoslib/AltosEepromList.java
index fc72fd95..55d47e20 100644
--- a/altoslib/AltosEepromList.java
+++ b/altoslib/AltosEepromList.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
diff --git a/altoslib/AltosEepromLog.java b/altoslib/AltosEepromLog.java
index 1bca6563..8d1f3fc4 100644
--- a/altoslib/AltosEepromLog.java
+++ b/altoslib/AltosEepromLog.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.util.concurrent.*;
@@ -32,8 +32,6 @@ public class AltosEepromLog {
public int start_block;
public int end_block;
- public int year, month, day;
-
public boolean selected;
public AltosEepromLog(AltosConfigData config_data,
@@ -43,7 +41,6 @@ public class AltosEepromLog {
throws InterruptedException, TimeoutException {
int block;
- boolean has_date = false;
flight = in_flight;
if (flight != 0)
@@ -56,43 +53,5 @@ public class AltosEepromLog {
* Select all flights for download
*/
selected = true;
-
- /*
- * Look in TeleMetrum log data for date
- */
- if (config_data.log_format == AltosLib.AO_LOG_FORMAT_UNKNOWN ||
- config_data.log_format == AltosLib.AO_LOG_FORMAT_FULL)
- {
- /*
- * Only look in the first two blocks so that this
- * process doesn't take a long time
- */
- if (in_end_block > in_start_block + 2)
- in_end_block = in_start_block + 2;
-
- for (block = in_start_block; block < in_end_block; block++) {
- AltosEepromChunk eechunk = new AltosEepromChunk(link, block, block == in_start_block);
-
- for (int i = 0; i < AltosEepromChunk.chunk_size; i += AltosEepromTM.record_length) {
- try {
- AltosEepromTM r = new AltosEepromTM(eechunk, i);
-
- if (r.cmd == AltosLib.AO_LOG_FLIGHT) {
- flight = r.b;
- has_flight = true;
- }
- if (r.cmd == AltosLib.AO_LOG_GPS_DATE) {
- year = 2000 + (r.a & 0xff);
- month = (r.a >> 8) & 0xff;
- day = (r.b & 0xff);
- has_date = true;
- }
- } catch (ParseException pe) {
- }
- }
- if (has_date && has_flight)
- break;
- }
- }
}
}
diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java
deleted file mode 100644
index 082d6054..00000000
--- a/altoslib/AltosEepromMega.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright © 2011 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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_11;
-
-import java.io.*;
-import java.util.*;
-import java.text.*;
-
-public class AltosEepromMega extends AltosEeprom {
- public static final int record_length = 32;
-
- public static final int max_sat = 12;
-
- private int log_format;
-
- public int record_length() { return record_length; }
-
- /* AO_LOG_FLIGHT elements */
- public int flight() { return data16(0); }
- public int ground_accel() { return data16(2); }
- public int ground_pres() { return data32(4); }
- public int ground_accel_along() { return data16(8); }
- public int ground_accel_across() { return data16(10); }
- public int ground_accel_through() { return data16(12); }
- public int ground_roll() {
- switch (log_format) {
- case AltosLib.AO_LOG_FORMAT_TELEMEGA:
- return data32(16);
- case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
- return data16(14);
- default:
- return AltosLib.MISSING;
- }
- }
- public int ground_pitch() {
- switch (log_format) {
- case AltosLib.AO_LOG_FORMAT_TELEMEGA:
- return data32(20);
- case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
- return data16(16);
- default:
- return AltosLib.MISSING;
- }
- }
- public int ground_yaw() {
- switch (log_format) {
- case AltosLib.AO_LOG_FORMAT_TELEMEGA:
- return data32(24);
- case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
- return data16(18);
- default:
- return AltosLib.MISSING;
- }
- }
-
- /* AO_LOG_STATE elements */
- public int state() { return data16(0); }
- public int reason() { return data16(2); }
-
- /* AO_LOG_SENSOR elements */
- public int pres() { return data32(0); }
- public int temp() { return data32(4); }
- public int accel_x() { return data16(8); }
- public int accel_y() { return data16(10); }
- public int accel_z() { return data16(12); }
- public int gyro_x() { return data16(14); }
- public int gyro_y() { return data16(16); }
- public int gyro_z() { return data16(18); }
- public int mag_x() { return data16(20); }
- public int mag_y() { return data16(22); }
- public int mag_z() { return data16(24); }
- public int accel() { return data16(26); }
-
- /* AO_LOG_TEMP_VOLT elements */
- public int v_batt() { return data16(0); }
- public int v_pbatt() { return data16(2); }
- public int nsense() { return data16(4); }
- public int sense(int i) { return data16(6 + i * 2); }
- public int pyro() { return data16(26); }
-
- /* AO_LOG_GPS_TIME elements */
- public int latitude() { return data32(0); }
- public int longitude() { return data32(4); }
- public int altitude_low() { return data16(8); }
- public int hour() { return data8(10); }
- public int minute() { return data8(11); }
- public int second() { return data8(12); }
- public int flags() { return data8(13); }
- public int year() { return data8(14); }
- public int month() { return data8(15); }
- public int day() { return data8(16); }
- public int course() { return data8(17); }
- public int ground_speed() { return data16(18); }
- public int climb_rate() { return data16(20); }
- public int pdop() { return data8(22); }
- public int hdop() { return data8(23); }
- public int vdop() { return data8(24); }
- public int mode() { return data8(25); }
- public int altitude_high() { return data16(26); }
-
- /* AO_LOG_GPS_SAT elements */
- public int nsat() { return data16(0); }
- public int svid(int n) { return data8(2 + n * 2); }
- public int c_n(int n) { return data8(2 + n * 2 + 1); }
-
- public AltosEepromMega (AltosEepromChunk chunk, int start, int log_format) throws ParseException {
- this.log_format = log_format;
- parse_chunk(chunk, start);
- }
-
- public void update_state(AltosState state) {
- super.update_state(state);
-
- AltosGPS gps;
-
- /* Flush any pending GPS changes */
- if (state.gps_pending) {
- switch (cmd) {
- case AltosLib.AO_LOG_GPS_LAT:
- case AltosLib.AO_LOG_GPS_LON:
- case AltosLib.AO_LOG_GPS_ALT:
- case AltosLib.AO_LOG_GPS_SAT:
- case AltosLib.AO_LOG_GPS_DATE:
- break;
- default:
- state.set_temp_gps();
- break;
- }
- }
-
- switch (cmd) {
- case AltosLib.AO_LOG_FLIGHT:
- state.set_boost_tick(tick);
- state.set_flight(flight());
- state.set_ground_accel(ground_accel());
- state.set_ground_pressure(ground_pres());
- state.set_accel_ground(ground_accel_along(),
- ground_accel_across(),
- ground_accel_through());
- state.set_gyro_zero(ground_roll() / 512.0,
- ground_pitch() / 512.0,
- ground_yaw() / 512.0);
- break;
- case AltosLib.AO_LOG_STATE:
- state.set_tick(tick);
- state.set_state(state());
- break;
- case AltosLib.AO_LOG_SENSOR:
- state.set_tick(tick);
- state.set_ms5607(pres(), temp());
-
- AltosIMU imu = new AltosIMU(accel_y(), /* along */
- accel_x(), /* across */
- accel_z(), /* through */
- gyro_y(), /* roll */
- gyro_x(), /* pitch */
- gyro_z()); /* yaw */
-
- if (log_format == AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD)
- state.check_imu_wrap(imu);
-
- state.set_imu(imu);
-
- state.set_mag(new AltosMag(mag_x(),
- mag_y(),
- mag_z()));
-
- state.set_accel(accel());
-
- break;
- case AltosLib.AO_LOG_TEMP_VOLT:
- state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
- state.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pbatt()));
-
- int nsense = nsense();
-
- state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-2)));
- state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-1)));
-
- double voltages[] = new double[nsense-2];
- for (int i = 0; i < nsense-2; i++)
- voltages[i] = AltosConvert.mega_pyro_voltage(sense(i));
-
- state.set_ignitor_voltage(voltages);
- state.set_pyro_fired(pyro());
- break;
- case AltosLib.AO_LOG_GPS_TIME:
- state.set_tick(tick);
- gps = state.make_temp_gps(false);
- gps.lat = latitude() / 1e7;
- gps.lon = longitude() / 1e7;
-
- if (state.altitude_32())
- gps.alt = (altitude_low() & 0xffff) | (altitude_high() << 16);
- else
- gps.alt = altitude_low();
-
- gps.hour = hour();
- gps.minute = minute();
- gps.second = second();
-
- int flags = flags();
-
- gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0;
- gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0;
- gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >>
- AltosLib.AO_GPS_NUM_SAT_SHIFT;
-
- gps.year = 2000 + year();
- gps.month = month();
- gps.day = day();
- gps.ground_speed = ground_speed() * 1.0e-2;
- gps.course = course() * 2;
- gps.climb_rate = climb_rate() * 1.0e-2;
- if (state.compare_version("1.4.9") >= 0) {
- gps.pdop = pdop() / 10.0;
- gps.hdop = hdop() / 10.0;
- gps.vdop = vdop() / 10.0;
- } else {
- gps.pdop = pdop() / 100.0;
- if (gps.pdop < 0.8)
- gps.pdop += 2.56;
- gps.hdop = hdop() / 100.0;
- if (gps.hdop < 0.8)
- gps.hdop += 2.56;
- gps.vdop = vdop() / 100.0;
- if (gps.vdop < 0.8)
- gps.vdop += 2.56;
- }
- break;
- case AltosLib.AO_LOG_GPS_SAT:
- state.set_tick(tick);
- gps = state.make_temp_gps(true);
-
- int n = nsat();
- if (n > max_sat)
- n = max_sat;
- for (int i = 0; i < n; i++)
- gps.add_sat(svid(i), c_n(i));
- break;
- }
- }
-
- public AltosEepromMega (String line, int log_format) {
- this.log_format = log_format;
- parse_string(line);
- }
-
- static public LinkedList<AltosEeprom> read(FileInputStream input, int log_format) {
- LinkedList<AltosEeprom> megas = new LinkedList<AltosEeprom>();
-
- for (;;) {
- try {
- String line = AltosLib.gets(input);
- if (line == null)
- break;
- try {
- AltosEepromMega mega = new AltosEepromMega(line, log_format);
- if (mega.cmd != AltosLib.AO_LOG_INVALID)
- megas.add(mega);
- } catch (Exception e) {
- System.out.printf ("exception\n");
- }
- } catch (IOException ie) {
- break;
- }
- }
-
- return megas;
- }
-}
diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java
deleted file mode 100644
index 04155071..00000000
--- a/altoslib/AltosEepromMini.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright © 2011 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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_11;
-
-import java.io.*;
-import java.util.*;
-import java.text.*;
-
-public class AltosEepromMini extends AltosEeprom {
- public static final int record_length = 16;
-
- public int record_length() { return record_length; }
-
- /* AO_LOG_FLIGHT elements */
- public int flight() { return data16(0); }
- public int ground_pres() { return data32(4); }
-
- /* AO_LOG_STATE elements */
- public int state() { return data16(0); }
- public int reason() { return data16(2); }
-
- /* AO_LOG_SENSOR elements */
- public int pres() { return data24(0); }
- public int temp() { return data24(3); }
- public int sense_a() { return data16(6); }
- public int sense_m() { return data16(8); }
- public int v_batt() { return data16(10); }
-
- private double battery_voltage(AltosState state, int sensor) {
- if (state.log_format == AltosLib.AO_LOG_FORMAT_EASYMINI)
- return AltosConvert.easy_mini_voltage(sensor, state.serial);
- if (state.log_format == AltosLib.AO_LOG_FORMAT_TELEMINI2)
- return AltosConvert.tele_mini_2_voltage(sensor);
- if (state.log_format == AltosLib.AO_LOG_FORMAT_TELEMINI3)
- return AltosConvert.tele_mini_3_battery_voltage(sensor);
- return -1;
- }
-
- private double pyro_voltage(AltosState state, int sensor) {
- if (state.log_format == AltosLib.AO_LOG_FORMAT_EASYMINI)
- return AltosConvert.easy_mini_voltage(sensor, state.serial);
- if (state.log_format == AltosLib.AO_LOG_FORMAT_TELEMINI2)
- return AltosConvert.tele_mini_2_voltage(sensor);
- if (state.log_format == AltosLib.AO_LOG_FORMAT_TELEMINI3)
- return AltosConvert.tele_mini_3_pyro_voltage(sensor);
- return -1;
- }
-
- public void update_state(AltosState state) {
- super.update_state(state);
-
- switch (cmd) {
- case AltosLib.AO_LOG_FLIGHT:
- state.set_flight(flight());
- state.set_ground_pressure(ground_pres());
- break;
- case AltosLib.AO_LOG_STATE:
- state.set_state(state());
- break;
- case AltosLib.AO_LOG_SENSOR:
- state.set_ms5607(pres(), temp());
- state.set_apogee_voltage(pyro_voltage(state, sense_a()));
- state.set_main_voltage(pyro_voltage(state, sense_m()));
- state.set_battery_voltage(battery_voltage(state, v_batt()));
- break;
- }
- }
-
- public AltosEepromMini (AltosEepromChunk chunk, int start) throws ParseException {
- parse_chunk(chunk, start);
- }
-
- public AltosEepromMini (String line) {
- parse_string(line);
- }
-
- public AltosEepromMini(int in_cmd, int in_tick) {
- cmd = in_cmd;
- tick = in_tick;
- valid = true;
- }
-
- static public LinkedList<AltosEeprom> read(FileInputStream input) {
- LinkedList<AltosEeprom> minis = new LinkedList<AltosEeprom>();
-
- for (;;) {
- try {
- String line = AltosLib.gets(input);
- if (line == null)
- break;
- AltosEepromMini mini = new AltosEepromMini(line);
- minis.add(mini);
- } catch (IOException ie) {
- break;
- }
- }
-
- return minis;
- }
-}
diff --git a/altoslib/AltosEepromMonitor.java b/altoslib/AltosEepromMonitor.java
index 792fde27..a99ec687 100644
--- a/altoslib/AltosEepromMonitor.java
+++ b/altoslib/AltosEepromMonitor.java
@@ -16,13 +16,13 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosEepromMonitor {
- public void set_states(int min_state, int max_state);
+ public void set_block(int in_block);
- public void set_value(String in_state_name, int in_state, int in_state_block, int in_block);
+ public void set_max(int in_max);
public void set_serial(int in_serial);
diff --git a/altoslib/AltosEepromRecord.java b/altoslib/AltosEepromRecord.java
new file mode 100644
index 00000000..094584fe
--- /dev/null
+++ b/altoslib/AltosEepromRecord.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public abstract class AltosEepromRecord implements Comparable<AltosEepromRecord> {
+
+ AltosEeprom eeprom;
+
+ int wide_tick;
+
+ final int start;
+ final int length;
+
+ public final static int header_length = 4;
+
+ public int cmd() {
+ return eeprom.data8(start);
+ }
+
+ public int tick() {
+ return eeprom.data16(start+2);
+ }
+
+ public int data8(int i) {
+ i += start + header_length;
+ return eeprom.data8(i);
+ }
+
+ public int data16(int i) {
+ return ((data8(i) | (data8(i+1) << 8)) << 16) >> 16;
+ }
+
+ public int data24(int i) {
+ return data8(i) | (data8(i+1) << 8) | (data8(i+2) << 16);
+ }
+
+ public int data32(int i) {
+ return data8(i) | (data8(i+1) << 8) | (data8(i+2) << 16) | (data8(i+3) << 24);
+ }
+
+ public boolean valid(int s) {
+ return AltosConvert.checksum(eeprom.data, s, length) == 0;
+ }
+
+ public boolean valid() {
+ return valid(start);
+ }
+
+ private int cmdi() {
+ if (cmd() == AltosLib.AO_LOG_FLIGHT)
+ return 0;
+ return 1;
+ }
+
+ public AltosConfigData config_data() {
+ return eeprom.config_data();
+ }
+
+ public int compareTo(AltosEepromRecord o) {
+ int cmd_diff = cmdi() - o.cmdi();
+
+ if (cmd_diff != 0)
+ return cmd_diff;
+
+ int tick_diff = wide_tick - o.wide_tick;
+
+ if (tick_diff != 0)
+ return tick_diff;
+ return start - o.start;
+ }
+
+ /* AltosDataProvider */
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ cal_data.set_tick(tick());
+ if (cmd() == AltosLib.AO_LOG_FLIGHT)
+ cal_data.set_boost_tick();
+ listener.set_time(cal_data.time());
+
+ /* Flush any pending GPS changes */
+ if (!AltosLib.is_gps_cmd(cmd())) {
+ AltosGPS gps = cal_data.temp_gps();
+ if (gps != null) {
+ listener.set_gps(gps);
+ cal_data.reset_temp_gps();
+ }
+ }
+ }
+
+ public int next_start() {
+ int s = start + length;
+
+ while (s + length <= eeprom.data.size()) {
+ if (valid(s))
+ return s;
+ s += length;
+ }
+ return -1;
+ }
+
+ public boolean hasNext() {
+ return next_start() >= 0;
+ }
+
+ public abstract AltosEepromRecord next();
+
+ public AltosEepromRecord(AltosEeprom eeprom, int start, int length) {
+ this.eeprom = eeprom;
+ this.start = start;
+ this.length = length;
+
+ while (start + length < eeprom.data.size() && !valid())
+ start += length;
+ }
+}
diff --git a/altoslib/AltosEepromFireTwo.java b/altoslib/AltosEepromRecordFireTwo.java
index dd510280..d6b74d1b 100644
--- a/altoslib/AltosEepromFireTwo.java
+++ b/altoslib/AltosEepromRecordFireTwo.java
@@ -16,21 +16,17 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
import java.text.*;
-public class AltosEepromFireTwo extends AltosEeprom {
+public class AltosEepromRecordFireTwo extends AltosEepromRecord {
public static final int record_length = 32;
- public int record_length() { return record_length; }
-
/* AO_LOG_FLIGHT elements */
public int flight() { return data16(0); }
- public int idle_pres() { return data16(2); }
- public int idle_thrust() { return data16(4); }
/* AO_LOG_STATE elements */
public int state() { return data16(0); }
@@ -41,21 +37,15 @@ public class AltosEepromFireTwo extends AltosEeprom {
public int thrust() { return data16(2); }
public int temp(int i) { return data16(4+i*2); }
- public AltosEepromFireTwo (AltosEepromChunk chunk, int start) throws ParseException {
- parse_chunk(chunk, start);
- }
-
private static final double r_above = 5600.0;
private static final double r_below = 10000.0;
private static final double v_adc = 3.3;
- private static double
- firetwo_adc(int raw) {
+ private static double firetwo_adc(int raw) {
return raw / 4095.0;
}
- private static double
- adc_to_pa(int adc) {
+ public static double adc_to_pa(int adc) {
/* raw adc to processor voltage, then back through the
* voltage divider to the sensor voltage
@@ -67,52 +57,46 @@ public class AltosEepromFireTwo extends AltosEeprom {
if (v < 0.5) v = 0.5;
if (v > 4.5) v = 4.5;
- double psi = (v - 0.5) / 4.0 * 1600.0;
+ double psi = (v - 0.5) / 4.0 * 2500.0;
return AltosConvert.psi_to_pa(psi);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public static double adc_to_n(int adc) {
+ double v = firetwo_adc(adc);
+
+ /* this is a total guess */
+ return AltosConvert.lb_to_n(v * 298 * 9.807);
+ }
+
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
- switch (cmd) {
+ switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- state.set_flight(flight());
- state.set_ground_pressure(adc_to_pa(idle_pres()));
+ cal_data.set_flight(flight());
break;
case AltosLib.AO_LOG_STATE:
- state.set_state(state());
+ listener.set_state(state());
break;
case AltosLib.AO_LOG_SENSOR:
- state.set_pressure(adc_to_pa(pres()));
+ listener.set_pressure(adc_to_pa(pres()));
+ listener.set_thrust(adc_to_n(thrust()));
break;
}
}
- public AltosEepromFireTwo (String line) {
- parse_string(line);
+ public AltosEepromRecord next() {
+ int s = next_start();
+ if (s < 0)
+ return null;
+ return new AltosEepromRecordFireTwo(eeprom, s);
}
- static public LinkedList<AltosEeprom> read(FileInputStream input) {
- LinkedList<AltosEeprom> firetwos = new LinkedList<AltosEeprom>();
-
- for (;;) {
- try {
- String line = AltosLib.gets(input);
- if (line == null)
- break;
- try {
- AltosEepromFireTwo firetwo = new AltosEepromFireTwo(line);
-
- if (firetwo.cmd != AltosLib.AO_LOG_INVALID)
- firetwos.add(firetwo);
- } catch (Exception e) {
- System.out.printf ("exception\n");
- }
- } catch (IOException ie) {
- break;
- }
- }
+ public AltosEepromRecordFireTwo(AltosEeprom eeprom, int start) {
+ super(eeprom, start, record_length);
+ }
- return firetwos;
+ public AltosEepromRecordFireTwo(AltosEeprom eeprom) {
+ this(eeprom, 0);
}
}
diff --git a/altoslib/AltosEepromRecordFull.java b/altoslib/AltosEepromRecordFull.java
new file mode 100644
index 00000000..85709f73
--- /dev/null
+++ b/altoslib/AltosEepromRecordFull.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosEepromRecordFull extends AltosEepromRecord {
+ public static final int record_length = 8;
+
+ public static final int max_sat = 12;
+
+ public static final int two_g_default = 16294 - 15758;
+
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+
+ super.provide_data(listener, cal_data);
+ AltosGPS gps;
+
+ switch (cmd()) {
+ case AltosLib.AO_LOG_FLIGHT:
+ listener.set_state(AltosLib.ao_flight_pad);
+ cal_data.set_ground_accel(data16(0));
+ cal_data.set_flight(data16(2));
+ if (cal_data.accel_plus_g == AltosLib.MISSING)
+ cal_data.set_accel_plus_minus(data16(0), data16(0) + two_g_default);
+ break;
+ case AltosLib.AO_LOG_SENSOR:
+ listener.set_acceleration(cal_data.acceleration(data16(0)));
+ listener.set_pressure(AltosConvert.barometer_to_pressure(data16(2)));
+ break;
+ case AltosLib.AO_LOG_PRESSURE:
+ listener.set_pressure(AltosConvert.barometer_to_pressure(data16(2)));
+ break;
+ case AltosLib.AO_LOG_TEMP_VOLT:
+ listener.set_temperature(AltosConvert.thermometer_to_temperature(data16(0)));
+ listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(data16(2)));
+ break;
+ case AltosLib.AO_LOG_DEPLOY:
+ listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(data16(0)));
+ listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(data16(2)));
+ break;
+ case AltosLib.AO_LOG_STATE:
+ listener.set_state(data16(0));
+ break;
+ case AltosLib.AO_LOG_GPS_TIME:
+ gps = cal_data.make_temp_gps(tick(),false);
+
+ gps.hour = data8(0);
+ gps.minute = data8(1);
+ gps.second = data8(2);
+
+ int flags = data8(3);
+
+ gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0;
+ gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0;
+ gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >>
+ AltosLib.AO_GPS_NUM_SAT_SHIFT;
+ break;
+ case AltosLib.AO_LOG_GPS_LAT:
+ gps = cal_data.make_temp_gps(tick(),false);
+
+ int lat32 = data32(0);
+ gps.lat = (double) lat32 / 1e7;
+ break;
+ case AltosLib.AO_LOG_GPS_LON:
+ gps = cal_data.make_temp_gps(tick(),false);
+
+ int lon32 = data32(0);
+ gps.lon = (double) lon32 / 1e7;
+ break;
+ case AltosLib.AO_LOG_GPS_ALT:
+ gps = cal_data.make_temp_gps(tick(),false);
+ gps.alt = data16(0);
+ break;
+ case AltosLib.AO_LOG_GPS_SAT:
+ gps = cal_data.make_temp_gps(tick(),true);
+ int svid = data16(0);
+ int c_n0 = data16(3);
+ gps.add_sat(svid, c_n0);
+ break;
+ case AltosLib.AO_LOG_GPS_DATE:
+ gps = cal_data.make_temp_gps(tick(),false);
+ gps.year = data8(0) + 2000;
+ gps.month = data8(1);
+ gps.day = data8(2);
+ break;
+ }
+ }
+
+ public AltosEepromRecord next() {
+ int s = next_start();
+ if (s < 0)
+ return null;
+ return new AltosEepromRecordFull(eeprom, s);
+ }
+
+ public AltosEepromRecordFull(AltosEeprom eeprom, int start) {
+ super(eeprom, start, record_length);
+ }
+
+ public AltosEepromRecordFull(AltosEeprom eeprom) {
+ this(eeprom, 0);
+ }
+}
diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromRecordGps.java
index e76b36dd..5cf5db39 100644
--- a/altoslib/AltosEepromGPS.java
+++ b/altoslib/AltosEepromRecordGps.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2014 Keith Packard <keithp@keithp.com>
+ * Copyright © 2017 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
@@ -16,19 +16,15 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
import java.text.*;
-public class AltosEepromGPS extends AltosEeprom {
+public class AltosEepromRecordGps extends AltosEepromRecord {
public static final int record_length = 32;
- public static final int max_sat = 12;
-
- public int record_length() { return record_length; }
-
/* AO_LOG_FLIGHT elements */
public int flight() { return data16(0); }
public int start_altitude() { return data16(2); }
@@ -55,10 +51,8 @@ public class AltosEepromGPS extends AltosEeprom {
public int mode() { return data8(25); }
public int altitude_high() { return data16(26); }
- public boolean has_seconds() { return cmd == AltosLib.AO_LOG_GPS_TIME; }
-
- public int seconds() {
- switch (cmd) {
+ private int seconds() {
+ switch (cmd()) {
case AltosLib.AO_LOG_GPS_TIME:
return second() + 60 * (minute() + 60 * (hour() + 24 * (day() + 31 * month())));
default:
@@ -66,44 +60,33 @@ public class AltosEepromGPS extends AltosEeprom {
}
}
- public AltosEepromGPS (AltosEepromChunk chunk, int start) throws ParseException {
- parse_chunk(chunk, start);
+ public int compareTo(AltosEepromRecord o) {
+ AltosEepromRecordGps og = (AltosEepromRecordGps) o;
+
+ int seconds_diff = seconds() - og.seconds();
+
+ if (seconds_diff != 0)
+ return seconds_diff;
+
+ return start - o.start;
}
- public void update_state(AltosState state) {
- super.update_state(state);
-
- AltosGPS gps;
-
- /* Flush any pending GPS changes */
- if (state.gps_pending) {
- switch (cmd) {
- case AltosLib.AO_LOG_GPS_LAT:
- case AltosLib.AO_LOG_GPS_LON:
- case AltosLib.AO_LOG_GPS_ALT:
- case AltosLib.AO_LOG_GPS_SAT:
- case AltosLib.AO_LOG_GPS_DATE:
- break;
- default:
- state.set_temp_gps();
- break;
- }
- }
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
- switch (cmd) {
+ switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- if (state.flight == AltosLib.MISSING) {
- state.set_boost_tick(tick);
- state.set_flight(flight());
+ if (cal_data.flight == AltosLib.MISSING) {
+ cal_data.set_boost_tick();
+ cal_data.set_flight(flight());
}
/* no place to log start lat/lon yet */
break;
case AltosLib.AO_LOG_GPS_TIME:
- state.set_tick(tick);
- gps = state.make_temp_gps(false);
+ AltosGPS gps = new AltosGPS();
gps.lat = latitude() / 1e7;
gps.lon = longitude() / 1e7;
- if (state.altitude_32())
+ if (eeprom.config_data().altitude_32 == 1)
gps.alt = (altitude_low() & 0xffff) | (altitude_high() << 16);
else
gps.alt = altitude_low();
@@ -125,7 +108,7 @@ public class AltosEepromGPS extends AltosEeprom {
gps.ground_speed = ground_speed() * 1.0e-2;
gps.course = course() * 2;
gps.climb_rate = climb_rate() * 1.0e-2;
- if (state.compare_version("1.4.9") >= 0) {
+ if (eeprom.config_data().compare_version("1.4.9") >= 0) {
gps.pdop = pdop() / 10.0;
gps.hdop = hdop() / 10.0;
gps.vdop = vdop() / 10.0;
@@ -140,34 +123,23 @@ public class AltosEepromGPS extends AltosEeprom {
if (gps.vdop < 0.8)
gps.vdop += 2.56;
}
+ listener.set_gps(gps);
break;
}
}
- public AltosEepromGPS (String line) {
- parse_string(line);
+ public AltosEepromRecord next() {
+ int s = next_start();
+ if (s < 0)
+ return null;
+ return new AltosEepromRecordGps(eeprom, s);
}
- static public LinkedList<AltosEeprom> read(FileInputStream input) {
- LinkedList<AltosEeprom> tgpss = new LinkedList<AltosEeprom>();
-
- for (;;) {
- try {
- String line = AltosLib.gets(input);
- if (line == null)
- break;
- try {
- AltosEepromGPS tgps = new AltosEepromGPS(line);
- if (tgps.cmd != AltosLib.AO_LOG_INVALID)
- tgpss.add(tgps);
- } catch (Exception e) {
- System.out.printf ("exception\n");
- }
- } catch (IOException ie) {
- break;
- }
- }
+ public AltosEepromRecordGps(AltosEeprom eeprom, int start) {
+ super(eeprom, start, record_length);
+ }
- return tgpss;
+ public AltosEepromRecordGps(AltosEeprom eeprom) {
+ this(eeprom, 0);
}
}
diff --git a/altoslib/AltosEepromRecordMega.java b/altoslib/AltosEepromRecordMega.java
new file mode 100644
index 00000000..ad3e23fd
--- /dev/null
+++ b/altoslib/AltosEepromRecordMega.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosEepromRecordMega extends AltosEepromRecord {
+ public static final int record_length = 32;
+
+ public static final int max_sat = 12;
+
+ private int log_format;
+
+ /* AO_LOG_FLIGHT elements */
+ private int flight() { return data16(0); }
+ private int ground_accel() { return data16(2); }
+ private int ground_pres() { return data32(4); }
+ private int ground_accel_along() { return data16(8); }
+ private int ground_accel_across() { return data16(10); }
+ private int ground_accel_through() { return data16(12); }
+ private int ground_roll() {
+ switch (log_format) {
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA:
+ return data32(16);
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
+ return data16(14);
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+ private int ground_pitch() {
+ switch (log_format) {
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA:
+ return data32(20);
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
+ return data16(16);
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+ private int ground_yaw() {
+ switch (log_format) {
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA:
+ return data32(24);
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
+ return data16(18);
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
+ /* AO_LOG_STATE elements */
+ private int state() { return data16(0); }
+ private int reason() { return data16(2); }
+
+ /* AO_LOG_SENSOR elements */
+ private int pres() { return data32(0); }
+ private int temp() { return data32(4); }
+ private int accel_x() { return data16(8); }
+ private int accel_y() { return data16(10); }
+ private int accel_z() { return data16(12); }
+ private int gyro_x() { return data16(14); }
+ private int gyro_y() { return data16(16); }
+ private int gyro_z() { return data16(18); }
+ private int mag_x() { return data16(20); }
+ private int mag_z() { return data16(22); }
+ private int mag_y() { return data16(24); }
+ private int accel() { return data16(26); }
+
+ /* AO_LOG_TEMP_VOLT elements */
+ private int v_batt() { return data16(0); }
+ private int v_pbatt() { return data16(2); }
+ private int nsense() { return data16(4); }
+ private int sense(int i) { return data16(6 + i * 2); }
+ private int pyro() { return data16(26); }
+
+ /* AO_LOG_GPS_TIME elements */
+ private int latitude() { return data32(0); }
+ private int longitude() { return data32(4); }
+ private int altitude_low() { return data16(8); }
+ private int hour() { return data8(10); }
+ private int minute() { return data8(11); }
+ private int second() { return data8(12); }
+ private int flags() { return data8(13); }
+ private int year() { return data8(14); }
+ private int month() { return data8(15); }
+ private int day() { return data8(16); }
+ private int course() { return data8(17); }
+ private int ground_speed() { return data16(18); }
+ private int climb_rate() { return data16(20); }
+ private int pdop() { return data8(22); }
+ private int hdop() { return data8(23); }
+ private int vdop() { return data8(24); }
+ private int mode() { return data8(25); }
+ private int altitude_high() { return data16(26); }
+
+ /* AO_LOG_GPS_SAT elements */
+ private int nsat() { return data16(0); }
+ private int svid(int n) { return data8(2 + n * 2); }
+ private int c_n(int n) { return data8(2 + n * 2 + 1); }
+
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
+
+ AltosGPS gps;
+
+ switch (cmd()) {
+ case AltosLib.AO_LOG_FLIGHT:
+ cal_data.set_flight(flight());
+ cal_data.set_ground_accel(ground_accel());
+ cal_data.set_ground_pressure(ground_pres());
+ listener.set_accel_ground(ground_accel_along(),
+ ground_accel_across(),
+ ground_accel_through());
+ cal_data.set_gyro_zero(ground_roll() / 512.0,
+ ground_pitch() / 512.0,
+ ground_yaw() / 512.0);
+ break;
+ case AltosLib.AO_LOG_STATE:
+ listener.set_state(state());
+ break;
+ case AltosLib.AO_LOG_SENSOR:
+ AltosConfigData config_data = eeprom.config_data();
+ AltosPresTemp pt = config_data.ms5607().pres_temp(pres(), temp());;
+ listener.set_pressure(pt.pres);
+ listener.set_temperature(pt.temp);
+
+ int accel_along = accel_y();
+ int accel_across = accel_x();
+ int accel_through = accel_z();
+ int gyro_roll = gyro_y();
+ int gyro_pitch = gyro_x();
+ int gyro_yaw = gyro_z();
+
+ int mag_along = mag_y();
+ int mag_across = mag_x();
+ int mag_through = mag_z();
+
+ if (log_format == AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD)
+ cal_data.check_imu_wrap(gyro_roll, gyro_pitch, gyro_yaw);
+
+ listener.set_accel(cal_data.accel_along(accel_along),
+ cal_data.accel_across(accel_across),
+ cal_data.accel_through(accel_through));
+ listener.set_gyro(cal_data.gyro_roll(gyro_roll),
+ cal_data.gyro_pitch(gyro_pitch),
+ cal_data.gyro_yaw(gyro_yaw));
+
+ listener.set_mag(cal_data.mag_along(mag_along),
+ cal_data.mag_across(mag_across),
+ cal_data.mag_through(mag_through));
+
+
+ final double lsb_per_g = 1920.0/105.5;
+
+ double acceleration = AltosConvert.acceleration_from_sensor(
+ accel(),
+ cal_data.ground_accel,
+ cal_data.ground_accel + 2 * lsb_per_g,
+ cal_data.ground_accel);
+
+ listener.set_acceleration(acceleration);
+ break;
+ case AltosLib.AO_LOG_TEMP_VOLT:
+ listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
+ listener.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pbatt()));
+
+ int nsense = nsense();
+
+ listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-2)));
+ listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-1)));
+
+ double voltages[] = new double[nsense-2];
+ for (int i = 0; i < nsense-2; i++)
+ voltages[i] = AltosConvert.mega_pyro_voltage(sense(i));
+
+ listener.set_igniter_voltage(voltages);
+ listener.set_pyro_fired(pyro());
+ break;
+ case AltosLib.AO_LOG_GPS_TIME:
+ gps = cal_data.make_temp_gps(tick(), false);
+ gps.lat = latitude() / 1e7;
+ gps.lon = longitude() / 1e7;
+
+ if (config_data().altitude_32())
+ gps.alt = (altitude_low() & 0xffff) | (altitude_high() << 16);
+ else
+ gps.alt = altitude_low();
+
+ gps.hour = hour();
+ gps.minute = minute();
+ gps.second = second();
+
+ int flags = flags();
+
+ gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0;
+ gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0;
+ gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >>
+ AltosLib.AO_GPS_NUM_SAT_SHIFT;
+
+ gps.year = 2000 + year();
+ gps.month = month();
+ gps.day = day();
+ gps.ground_speed = ground_speed() * 1.0e-2;
+ gps.course = course() * 2;
+ gps.climb_rate = climb_rate() * 1.0e-2;
+ if (config_data().compare_version("1.4.9") >= 0) {
+ gps.pdop = pdop() / 10.0;
+ gps.hdop = hdop() / 10.0;
+ gps.vdop = vdop() / 10.0;
+ } else {
+ gps.pdop = pdop() / 100.0;
+ if (gps.pdop < 0.8)
+ gps.pdop += 2.56;
+ gps.hdop = hdop() / 100.0;
+ if (gps.hdop < 0.8)
+ gps.hdop += 2.56;
+ gps.vdop = vdop() / 100.0;
+ if (gps.vdop < 0.8)
+ gps.vdop += 2.56;
+ }
+ break;
+ case AltosLib.AO_LOG_GPS_SAT:
+ gps = cal_data.make_temp_gps(tick(), true);
+
+ int n = nsat();
+ if (n > max_sat)
+ n = max_sat;
+ for (int i = 0; i < n; i++)
+ gps.add_sat(svid(i), c_n(i));
+ break;
+ }
+ }
+
+ public AltosEepromRecord next() {
+ int s = next_start();
+ if (s < 0)
+ return null;
+ return new AltosEepromRecordMega(eeprom, s);
+ }
+
+ public AltosEepromRecordMega(AltosEeprom eeprom, int start) {
+ super(eeprom, start, record_length);
+ log_format = eeprom.config_data().log_format;
+ }
+
+ public AltosEepromRecordMega(AltosEeprom eeprom) {
+ this(eeprom, 0);
+ }
+}
diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromRecordMetrum.java
index f685b3ce..3da50544 100644
--- a/altoslib/AltosEepromMetrum2.java
+++ b/altoslib/AltosEepromRecordMetrum.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ * Copyright © 2017 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
@@ -16,13 +16,9 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
-import java.io.*;
-import java.util.*;
-import java.text.*;
-
-public class AltosEepromMetrum2 extends AltosEeprom {
+public class AltosEepromRecordMetrum extends AltosEepromRecord {
public static final int record_length = 16;
public int record_length() { return record_length; }
@@ -69,64 +65,42 @@ public class AltosEepromMetrum2 extends AltosEeprom {
public int svid(int n) { return data8(2 + n * 2); }
public int c_n(int n) { return data8(2 + n * 2 + 1); }
- public AltosEepromMetrum2 (AltosEepromChunk chunk, int start) throws ParseException {
- parse_chunk(chunk, start);
- }
-
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
AltosGPS gps;
- /* Flush any pending GPS changes */
- if (state.gps_pending) {
- switch (cmd) {
- case AltosLib.AO_LOG_GPS_POS:
- case AltosLib.AO_LOG_GPS_LAT:
- case AltosLib.AO_LOG_GPS_LON:
- case AltosLib.AO_LOG_GPS_ALT:
- case AltosLib.AO_LOG_GPS_SAT:
- case AltosLib.AO_LOG_GPS_DATE:
- break;
- default:
- state.set_temp_gps();
- break;
- }
- }
-
- switch (cmd) {
+ switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- state.set_flight(flight());
- state.set_ground_accel(ground_accel());
- state.set_ground_pressure(ground_pres());
-// state.set_temperature(ground_temp() / 100.0);
+ cal_data.set_flight(flight());
+ cal_data.set_ground_accel(ground_accel());
+ cal_data.set_ground_pressure(ground_pres());
break;
case AltosLib.AO_LOG_STATE:
- state.set_state(state());
+ listener.set_state(state());
break;
case AltosLib.AO_LOG_SENSOR:
- state.set_ms5607(pres(), temp());
- state.set_accel(accel());
-
+ AltosPresTemp pt = eeprom.config_data().ms5607().pres_temp(pres(), temp());
+ listener.set_pressure(pt.pres);
+ listener.set_temperature(pt.temp);
+ listener.set_acceleration(cal_data.acceleration(accel()));
break;
case AltosLib.AO_LOG_TEMP_VOLT:
- state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
-
- state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a()));
- state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m()));
-
+ listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
+ listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a()));
+ listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m()));
break;
case AltosLib.AO_LOG_GPS_POS:
- gps = state.make_temp_gps(false);
+ gps = cal_data.make_temp_gps(tick(), false);
gps.lat = latitude() / 1e7;
gps.lon = longitude() / 1e7;
- if (state.altitude_32())
+ if (config_data().altitude_32())
gps.alt = (altitude_low() & 0xffff) | (altitude_high() << 16);
else
gps.alt = altitude_low();
break;
case AltosLib.AO_LOG_GPS_TIME:
- gps = state.make_temp_gps(false);
+ gps = cal_data.make_temp_gps(tick(), false);
gps.hour = hour();
gps.minute = minute();
@@ -145,7 +119,7 @@ public class AltosEepromMetrum2 extends AltosEeprom {
gps.pdop = pdop() / 10.0;
break;
case AltosLib.AO_LOG_GPS_SAT:
- gps = state.make_temp_gps(true);
+ gps = cal_data.make_temp_gps(tick(), true);
int n = nsat();
for (int i = 0; i < n; i++)
@@ -154,31 +128,18 @@ public class AltosEepromMetrum2 extends AltosEeprom {
}
}
- public AltosEepromMetrum2 (String line) {
- parse_string(line);
+ public AltosEepromRecord next() {
+ int s = next_start();
+ if (s < 0)
+ return null;
+ return new AltosEepromRecordMetrum(eeprom, s);
}
- static public LinkedList<AltosEeprom> read(FileInputStream input) {
- LinkedList<AltosEeprom> metrums = new LinkedList<AltosEeprom>();
-
- for (;;) {
- try {
- String line = AltosLib.gets(input);
- if (line == null)
- break;
- try {
- AltosEepromMetrum2 metrum = new AltosEepromMetrum2(line);
-
- if (metrum.cmd != AltosLib.AO_LOG_INVALID)
- metrums.add(metrum);
- } catch (Exception e) {
- System.out.printf ("exception\n");
- }
- } catch (IOException ie) {
- break;
- }
- }
+ public AltosEepromRecordMetrum(AltosEeprom eeprom, int start) {
+ super(eeprom, start, record_length);
+ }
- return metrums;
+ public AltosEepromRecordMetrum(AltosEeprom eeprom) {
+ this(eeprom, 0);
}
}
diff --git a/altoslib/AltosEepromRecordMini.java b/altoslib/AltosEepromRecordMini.java
new file mode 100644
index 00000000..55696693
--- /dev/null
+++ b/altoslib/AltosEepromRecordMini.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright © 2017 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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_12;
+
+public class AltosEepromRecordMini extends AltosEepromRecord {
+ public static final int record_length = 16;
+
+ /* AO_LOG_FLIGHT elements */
+ public int flight() { return data16(0); }
+ public int ground_pres() { return data32(4); }
+
+ /* AO_LOG_STATE elements */
+ public int state() { return data16(0); }
+ public int reason() { return data16(2); }
+
+ /* AO_LOG_SENSOR elements */
+ public int pres() { return data24(0); }
+ public int temp() { return data24(3); }
+ public int sense_a() { return data16(6); }
+ public int sense_m() { return data16(8); }
+ public int v_batt() { return data16(10); }
+
+ private int log_format() {
+ return eeprom.config_data().log_format;
+ }
+
+ private double battery_voltage(int sensor) {
+ int log_format = log_format();
+ if (log_format == AltosLib.AO_LOG_FORMAT_EASYMINI1)
+ return AltosConvert.easy_mini_1_voltage(sensor, eeprom.config_data().serial);
+ if (log_format == AltosLib.AO_LOG_FORMAT_EASYMINI2)
+ return AltosConvert.easy_mini_2_voltage(sensor);
+ if (log_format == AltosLib.AO_LOG_FORMAT_TELEMINI2)
+ return AltosConvert.tele_mini_2_voltage(sensor);
+ if (log_format == AltosLib.AO_LOG_FORMAT_TELEMINI3)
+ return AltosConvert.tele_mini_3_battery_voltage(sensor);
+ return -1;
+ }
+
+ private double pyro_voltage(int sensor) {
+ int log_format = log_format();
+ if (log_format == AltosLib.AO_LOG_FORMAT_EASYMINI1)
+ return AltosConvert.easy_mini_1_voltage(sensor, eeprom.config_data().serial);
+ if (log_format == AltosLib.AO_LOG_FORMAT_EASYMINI2)
+ return AltosConvert.easy_mini_2_voltage(sensor);
+ if (log_format == AltosLib.AO_LOG_FORMAT_TELEMINI2)
+ return AltosConvert.tele_mini_2_voltage(sensor);
+ if (log_format == AltosLib.AO_LOG_FORMAT_TELEMINI3)
+ return AltosConvert.tele_mini_3_pyro_voltage(sensor);
+ return -1;
+ }
+
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
+
+ switch (cmd()) {
+ case AltosLib.AO_LOG_FLIGHT:
+ cal_data.set_flight(flight());
+ cal_data.set_ground_pressure(ground_pres());
+ break;
+ case AltosLib.AO_LOG_STATE:
+ listener.set_state(state());
+ break;
+ case AltosLib.AO_LOG_SENSOR:
+ AltosPresTemp pt = eeprom.config_data().ms5607().pres_temp(pres(), temp());
+ listener.set_pressure(pt.pres);
+ listener.set_temperature(pt.temp);
+ listener.set_apogee_voltage(pyro_voltage(sense_a()));
+ listener.set_main_voltage(pyro_voltage(sense_m()));
+ listener.set_battery_voltage(battery_voltage(v_batt()));
+ break;
+ }
+ }
+
+ public AltosEepromRecord next() {
+ int s = next_start();
+ if (s < 0)
+ return null;
+ return new AltosEepromRecordMini(eeprom, s);
+ }
+
+ public AltosEepromRecordMini(AltosEeprom eeprom, int start) {
+ super(eeprom, start, record_length);
+ }
+
+ public AltosEepromRecordMini(AltosEeprom eeprom) {
+ this(eeprom, 0);
+ }
+}
diff --git a/altoslib/AltosEepromRecordSet.java b/altoslib/AltosEepromRecordSet.java
new file mode 100644
index 00000000..48e90c05
--- /dev/null
+++ b/altoslib/AltosEepromRecordSet.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+import java.io.*;
+import java.util.*;
+
+public class AltosEepromRecordSet implements AltosRecordSet {
+ AltosEeprom eeprom;
+ TreeSet<AltosEepromRecord> ordered;
+ AltosCalData cal_data;
+
+ public AltosConfigData config_data() {
+ return eeprom.config_data();
+ }
+
+ public AltosCalData cal_data() {
+ if (cal_data == null) {
+ cal_data = new AltosCalData(config_data());
+ for (AltosEepromRecord record : ordered) {
+ if (record.cmd() == AltosLib.AO_LOG_FLIGHT) {
+ cal_data.set_tick(record.tick());
+ cal_data.set_boost_tick();
+ break;
+ }
+ }
+ }
+ return cal_data;
+ }
+
+ public void capture_series(AltosDataListener listener) {
+ AltosCalData cal_data = cal_data();
+
+ cal_data.reset();
+ for (AltosEepromRecord record : ordered) {
+ record.provide_data(listener, cal_data);
+ }
+ listener.finish();
+ }
+
+ public AltosEepromRecordSet(AltosEeprom eeprom) {
+ this.eeprom = eeprom;
+
+ AltosConfigData config_data = eeprom.config_data();
+
+ AltosEepromRecord record = null;
+
+ switch (config_data.log_format) {
+ case AltosLib.AO_LOG_FORMAT_FULL:
+ record = new AltosEepromRecordFull(eeprom);
+ break;
+ case AltosLib.AO_LOG_FORMAT_TINY:
+ record = new AltosEepromRecordTiny(eeprom);
+ break;
+ case AltosLib.AO_LOG_FORMAT_TELEMETRY:
+ case AltosLib.AO_LOG_FORMAT_TELESCIENCE:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
+ record = new AltosEepromRecordMega(eeprom);
+ break;
+ case AltosLib.AO_LOG_FORMAT_TELEMETRUM:
+ record = new AltosEepromRecordMetrum(eeprom);
+ break;
+ case AltosLib.AO_LOG_FORMAT_TELEMINI2:
+ case AltosLib.AO_LOG_FORMAT_TELEMINI3:
+ case AltosLib.AO_LOG_FORMAT_EASYMINI1:
+ case AltosLib.AO_LOG_FORMAT_EASYMINI2:
+ record = new AltosEepromRecordMini(eeprom);
+ break;
+ case AltosLib.AO_LOG_FORMAT_TELEGPS:
+ record = new AltosEepromRecordGps(eeprom);
+ break;
+ case AltosLib.AO_LOG_FORMAT_TELEFIRETWO:
+ record = new AltosEepromRecordFireTwo(eeprom);
+ break;
+ }
+
+ if (record == null) {
+ System.out.printf("failed to parse log format %d\n", config_data.log_format);
+ return;
+ }
+ ordered = new TreeSet<AltosEepromRecord>();
+ int tick = 0;
+ boolean first = true;
+
+ for (;;) {
+ int t = record.tick();
+
+ if (first) {
+ tick = t;
+ first = false;
+ } else {
+ while (t < tick - 32767)
+ t += 65536;
+ tick = t;
+ }
+ record.wide_tick = tick;
+ ordered.add(record);
+ if (!record.hasNext())
+ break;
+ record = record.next();
+ }
+ }
+
+ public AltosEepromRecordSet(InputStream input) throws IOException {
+ this(new AltosEeprom(input));
+ }
+}
diff --git a/altoslib/AltosEepromRecordTiny.java b/altoslib/AltosEepromRecordTiny.java
new file mode 100644
index 00000000..06ee9d54
--- /dev/null
+++ b/altoslib/AltosEepromRecordTiny.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosEepromRecordTiny extends AltosEepromRecord implements AltosDataProvider {
+ public static final int record_length = 2;
+
+ private int value() {
+ return eeprom.data16(start);
+ }
+
+ public boolean valid(int s) {
+ return eeprom.data16(s) != 0xffff;
+ }
+
+ public int cmd() {
+ if (start == 0)
+ return AltosLib.AO_LOG_FLIGHT;
+ if ((value() & 0x8000) != 0)
+ return AltosLib.AO_LOG_STATE;
+ return AltosLib.AO_LOG_SENSOR;
+ }
+
+ public int tick() {
+ int tick = 0;
+ int step = 10;
+ for (int i = 2; i < start; i += 2)
+ {
+ int v = eeprom.data16(i);
+
+ if ((v & 0x8000) != 0) {
+ if ((v & 0x7fff) >= AltosLib.ao_flight_drogue)
+ step = 100;
+ } else {
+ tick += step;
+ }
+ }
+ return tick;
+ }
+
+ public void provide_data(AltosDataListener listener) {
+ int value = data16(-header_length);
+
+ listener.set_tick(tick());
+ switch (cmd()) {
+ case AltosLib.AO_LOG_FLIGHT:
+ listener.set_state(AltosLib.ao_flight_pad);
+ listener.cal_data().set_flight(value);
+ listener.cal_data().set_boost_tick();
+ break;
+ case AltosLib.AO_LOG_STATE:
+ listener.set_state(value & 0x7fff);
+ break;
+ case AltosLib.AO_LOG_SENSOR:
+ listener.set_pressure(AltosConvert.barometer_to_pressure(value));
+ break;
+ }
+ }
+
+ public AltosEepromRecord next() {
+ int s = next_start();
+ if (s < 0)
+ return null;
+ return new AltosEepromRecordTiny(eeprom, s);
+ }
+
+ public AltosEepromRecordTiny(AltosEeprom eeprom, int start) {
+ super(eeprom, start, record_length);
+ }
+
+ public AltosEepromRecordTiny(AltosEeprom eeprom) {
+ this(eeprom, 0);
+ }
+}
diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java
deleted file mode 100644
index 9a09f926..00000000
--- a/altoslib/AltosEepromTM.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright © 2010 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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_11;
-
-import java.io.*;
-import java.util.*;
-import java.text.*;
-
-public class AltosEepromTM extends AltosEeprom {
- public int a;
- public int b;
-
- public static final int record_length = 8;
-
- public void write(PrintStream out) {
- out.printf("%c %4x %4x %4x\n", cmd, tick, a, b);
- }
-
- public int record_length() { return record_length; }
-
- public String string() {
- return String.format("%c %4x %4x %4x\n", cmd, tick, a, b);
- }
-
- public void update_state(AltosState state) {
- super.update_state(state);
-
- AltosGPS gps;
-
- /* Flush any pending GPS changes */
- if (state.gps_pending) {
- switch (cmd) {
- case AltosLib.AO_LOG_GPS_LAT:
- case AltosLib.AO_LOG_GPS_LON:
- case AltosLib.AO_LOG_GPS_ALT:
- case AltosLib.AO_LOG_GPS_SAT:
- case AltosLib.AO_LOG_GPS_DATE:
- break;
- default:
- state.set_temp_gps();
- break;
- }
- }
-
- switch (cmd) {
- case AltosLib.AO_LOG_FLIGHT:
- state.set_state(AltosLib.ao_flight_pad);
- state.set_ground_accel(a);
- state.set_flight(b);
- state.set_boost_tick(tick);
- break;
- case AltosLib.AO_LOG_SENSOR:
- state.set_accel(a);
- state.set_pressure(AltosConvert.barometer_to_pressure(b));
- break;
- case AltosLib.AO_LOG_PRESSURE:
- state.set_pressure(AltosConvert.barometer_to_pressure(b));
- break;
- case AltosLib.AO_LOG_TEMP_VOLT:
- state.set_temperature(AltosConvert.thermometer_to_temperature(a));
- state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(b));
- break;
- case AltosLib.AO_LOG_DEPLOY:
- state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(a));
- state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(b));
- break;
- case AltosLib.AO_LOG_STATE:
- state.set_state(a);
- break;
- case AltosLib.AO_LOG_GPS_TIME:
- gps = state.make_temp_gps(false);
-
- gps.hour = (a & 0xff);
- gps.minute = (a >> 8);
- gps.second = (b & 0xff);
-
- int flags = (b >> 8);
-
- gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0;
- gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0;
- gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >>
- AltosLib.AO_GPS_NUM_SAT_SHIFT;
- break;
- case AltosLib.AO_LOG_GPS_LAT:
- gps = state.make_temp_gps(false);
-
- int lat32 = a | (b << 16);
- gps.lat = (double) lat32 / 1e7;
- break;
- case AltosLib.AO_LOG_GPS_LON:
- gps = state.make_temp_gps(false);
-
- int lon32 = a | (b << 16);
- gps.lon = (double) lon32 / 1e7;
- break;
- case AltosLib.AO_LOG_GPS_ALT:
- gps = state.make_temp_gps(false);
- gps.alt = a;
- break;
- case AltosLib.AO_LOG_GPS_SAT:
- gps = state.make_temp_gps(true);
- int svid = a;
- int c_n0 = b >> 8;
- gps.add_sat(svid, c_n0);
- break;
- case AltosLib.AO_LOG_GPS_DATE:
- gps = state.make_temp_gps(false);
- gps.year = (a & 0xff) + 2000;
- gps.month = a >> 8;
- gps.day = b & 0xff;
- break;
- }
- }
-
- public AltosEepromTM (AltosEepromChunk chunk, int start) throws ParseException {
-
- cmd = chunk.data(start);
- valid = true;
-
- valid = !chunk.erased(start, record_length);
- if (valid) {
- if (AltosConvert.checksum(chunk.data, start, record_length) != 0)
- throw new ParseException(String.format("invalid checksum at 0x%x",
- chunk.address + start), 0);
- } else {
- cmd = AltosLib.AO_LOG_INVALID;
- }
-
- tick = chunk.data16(start + 2);
- a = chunk.data16(start + 4);
- b = chunk.data16(start + 6);
- }
-
- public AltosEepromTM (String line) {
- valid = false;
- tick = 0;
- a = 0;
- b = 0;
- if (line == null) {
- cmd = AltosLib.AO_LOG_INVALID;
- } else {
- try {
- String[] tokens = line.split("\\s+");
-
- if (tokens[0].length() == 1) {
- if (tokens.length != 4) {
- cmd = AltosLib.AO_LOG_INVALID;
- } else {
- cmd = tokens[0].codePointAt(0);
- tick = Integer.parseInt(tokens[1],16);
- valid = true;
- a = Integer.parseInt(tokens[2],16);
- b = Integer.parseInt(tokens[3],16);
- }
- } else {
- cmd = AltosLib.AO_LOG_INVALID;
- }
- } catch (NumberFormatException ne) {
- cmd = AltosLib.AO_LOG_INVALID;
- }
- }
- }
-
- public AltosEepromTM(int in_cmd, int in_tick, int in_a, int in_b) {
- valid = true;
- cmd = in_cmd;
- tick = in_tick;
- a = in_a;
- b = in_b;
- }
-
- static public LinkedList<AltosEeprom> read(FileInputStream input) {
- LinkedList<AltosEeprom> tms = new LinkedList<AltosEeprom>();
-
- for (;;) {
- try {
- String line = AltosLib.gets(input);
- if (line == null)
- break;
- AltosEepromTM tm = new AltosEepromTM(line);
- tms.add(tm);
- } catch (IOException ie) {
- break;
- }
- }
-
- return tms;
- }
-
-}
diff --git a/altoslib/AltosEepromTMini.java b/altoslib/AltosEepromTMini.java
deleted file mode 100644
index 2557f431..00000000
--- a/altoslib/AltosEepromTMini.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright © 2010 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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_11;
-
-import java.io.*;
-import java.util.*;
-import java.text.*;
-
-public class AltosEepromTMini extends AltosEeprom {
- public int i;
- public int a;
- public int b;
-
- public static final int record_length = 2;
-
- public void write(PrintStream out) {
- out.printf("%c %4x %4x %4x\n", cmd, tick, a, b);
- }
-
- public int record_length() { return record_length; }
-
- public String string() {
- return String.format("%c %4x %4x %4x\n", cmd, tick, a, b);
- }
-
- public void update_state(AltosState state) {
- super.update_state(state);
-
- switch (cmd) {
- case AltosLib.AO_LOG_FLIGHT:
- state.set_state(AltosLib.ao_flight_boost);
- state.set_flight(b);
- break;
- case AltosLib.AO_LOG_PRESSURE:
- if (tick == 0)
- state.set_ground_pressure(AltosConvert.barometer_to_pressure(b));
- else
- state.set_pressure(AltosConvert.barometer_to_pressure(b));
- break;
- case AltosLib.AO_LOG_STATE:
- state.set_state(a);
- break;
- }
- }
-
- public AltosEepromTMini (AltosEepromChunk chunk, int start, AltosState state) throws ParseException {
- int value = chunk.data16(start);
-
- int i = (chunk.address + start) / record_length;
-
- cmd = chunk.data(start);
- valid = true;
-
- valid = !chunk.erased(start, record_length);
-
- switch (i) {
- case 0:
- cmd = AltosLib.AO_LOG_FLIGHT;
- tick = 0;
- a = 0;
- b = value;
- break;
- case 1:
- cmd = AltosLib.AO_LOG_PRESSURE;
- tick = 0;
- a = 0;
- b = value;
- break;
- default:
- if ((value & 0x8000) != 0) {
- cmd = AltosLib.AO_LOG_STATE;
- tick = state.tick;
- a = value & 0x7fff;
- b = 0;
- } else {
- if (state.ascent)
- tick = state.tick + 10;
- else
- tick = state.tick + 100;
- cmd = AltosLib.AO_LOG_PRESSURE;
- a = 0;
- b = value;
- }
- break;
- }
- }
-
- public AltosEepromTMini (String line) {
- valid = false;
- tick = 0;
- a = 0;
- b = 0;
- if (line == null) {
- cmd = AltosLib.AO_LOG_INVALID;
- } else {
- try {
- String[] tokens = line.split("\\s+");
-
- if (tokens[0].length() == 1) {
- if (tokens.length != 4) {
- cmd = AltosLib.AO_LOG_INVALID;
- } else {
- cmd = tokens[0].codePointAt(0);
- tick = Integer.parseInt(tokens[1],16);
- valid = true;
- a = Integer.parseInt(tokens[2],16);
- b = Integer.parseInt(tokens[3],16);
- }
- } else {
- cmd = AltosLib.AO_LOG_INVALID;
- }
- } catch (NumberFormatException ne) {
- cmd = AltosLib.AO_LOG_INVALID;
- }
- }
- }
-
- public AltosEepromTMini(int in_cmd, int in_tick, int in_a, int in_b) {
- valid = true;
- cmd = in_cmd;
- tick = in_tick;
- a = in_a;
- b = in_b;
- }
-
- static public LinkedList<AltosEeprom> read(FileInputStream input) {
- LinkedList<AltosEeprom> tms = new LinkedList<AltosEeprom>();
-
- for (;;) {
- try {
- String line = AltosLib.gets(input);
- if (line == null)
- break;
- AltosEepromTMini tm = new AltosEepromTMini(line);
- tms.add(tm);
- } catch (IOException ie) {
- break;
- }
- }
-
- return tms;
- }
-
-}
diff --git a/altoslib/AltosFile.java b/altoslib/AltosFile.java
index ef75762a..69f779c1 100644
--- a/altoslib/AltosFile.java
+++ b/altoslib/AltosFile.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.File;
import java.util.*;
@@ -66,7 +66,7 @@ public class AltosFile extends File {
extension);
}
- public AltosFile(AltosState state) {
- this(state.serial, state.flight, state.receiver_serial, "telem");
+ public AltosFile(AltosCalData cal_data) {
+ this(cal_data.serial, cal_data.flight, cal_data.receiver_serial, "telem");
}
}
diff --git a/altoslib/AltosFlash.java b/altoslib/AltosFlash.java
index ad573305..c8db1f77 100644
--- a/altoslib/AltosFlash.java
+++ b/altoslib/AltosFlash.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
diff --git a/altoslib/AltosFlashListener.java b/altoslib/AltosFlashListener.java
index e15d7ac3..60052133 100644
--- a/altoslib/AltosFlashListener.java
+++ b/altoslib/AltosFlashListener.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosFlashListener {
public void position(String label, int percent);
diff --git a/altoslib/AltosFlightDisplay.java b/altoslib/AltosFlightDisplay.java
index c395dc45..8fe33c5e 100644
--- a/altoslib/AltosFlightDisplay.java
+++ b/altoslib/AltosFlightDisplay.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosFlightDisplay extends AltosUnitsListener, AltosFontListener {
void reset();
diff --git a/altoslib/AltosFlightListener.java b/altoslib/AltosFlightListener.java
new file mode 100644
index 00000000..d61831a9
--- /dev/null
+++ b/altoslib/AltosFlightListener.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public abstract class AltosFlightListener {
+
+ public int flight;
+ public int serial;
+ public int tick;
+ public int boost_tick;
+ public int state;
+
+ public double accel_plus_g;
+ public double accel_minus_g;
+ public double accel;
+
+ public double ground_pressure;
+ public double ground_altitude;
+
+ AltosGPS temp_gps;
+ int temp_gps_sat_tick;
+ int gps_sequence;
+
+ /* AltosEepromRecord */
+ public void set_boost_tick(int boost_tick) {
+ if (boost_tick != AltosLib.MISSING)
+ this.boost_tick = boost_tick;
+ }
+
+ public void set_tick(int tick) {
+ if (tick != AltosLib.MISSING)
+ this.tick = tick;
+ }
+
+ public double time() {
+ if (tick == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ if (boost_tick != AltosLib.MISSING)
+ return (tick - boost_tick) / 100.0;
+ else
+ return tick / 100.0;
+ }
+
+ public double boost_time() {
+ if (boost_tick == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return boost_tick / 100.0;
+ }
+
+ public abstract void set_rssi(int rssi, int status);
+ public abstract void set_received_time(long received_time);
+
+ /* AltosEepromRecordFull */
+
+ public void set_serial(int serial) {
+ if (serial != AltosLib.MISSING)
+ this.serial = serial;
+ }
+
+ public void set_state(int state) {
+ if (state != AltosLib.MISSING)
+ this.state = state;
+ }
+
+ public int state() { return state; }
+
+ public abstract void set_ground_accel(double ground_accel);
+ public void set_flight(int flight) {
+ if (flight != AltosLib.MISSING)
+ this.flight = flight;
+ }
+ public int flight() {
+ return flight;
+ }
+
+ public abstract void set_accel(double accel);
+ public abstract void set_acceleration(double accel);
+ public abstract void set_accel_g(double accel_plus_g, double accel_minus_g);
+ public abstract void set_pressure(double pa);
+ public abstract void set_thrust(double N);
+
+ public abstract void set_temperature(double deg_c);
+ public abstract void set_battery_voltage(double volts);
+
+ public abstract void set_apogee_voltage(double volts);
+ public abstract void set_main_voltage(double volts);
+
+ public void set_temp_gps() {
+ temp_gps = null;
+ }
+
+ public boolean gps_pending() {
+ return temp_gps != null;
+ }
+
+ public AltosGPS make_temp_gps(boolean sats) {
+ if (temp_gps == null) {
+ temp_gps = new AltosGPS();
+ }
+ if (sats) {
+ if (tick != temp_gps_sat_tick)
+ temp_gps.cc_gps_sat = null;
+ temp_gps_sat_tick = tick;
+ }
+ return temp_gps;
+ }
+
+ public void set_ground_pressure(double ground_pressure) {
+ if (ground_pressure != AltosLib.MISSING) {
+ this.ground_pressure = ground_pressure;
+ this.ground_altitude = AltosConvert.pressure_to_altitude(ground_pressure);
+ }
+ }
+
+ public abstract void set_accel_ground(double along, double across, double through);
+ public abstract void set_gyro_zero(double roll, double pitch, double yaw);
+ public abstract void check_imu_wrap(AltosIMU imu);
+ public abstract void set_imu(AltosIMU imu);
+ public abstract void set_mag(AltosMag mag);
+ public abstract void set_pyro_voltage(double volts);
+ public abstract void set_igniter_voltage(double[] voltage);
+ public abstract void set_pyro_fired(int pyro_mask);
+
+ public void copy(AltosFlightListener old) {
+ flight = old.flight;
+ serial = old.serial;
+ tick = old.tick;
+ boost_tick = old.boost_tick;
+ accel_plus_g = old.accel_plus_g;
+ accel_minus_g = old.accel_minus_g;
+ ground_pressure = old.ground_pressure;
+ ground_altitude = old.ground_altitude;
+ temp_gps = old.temp_gps;
+ temp_gps_sat_tick = old.temp_gps_sat_tick;
+ }
+
+ public void init() {
+ flight = AltosLib.MISSING;
+ serial = AltosLib.MISSING;
+ tick = AltosLib.MISSING;
+ boost_tick = AltosLib.MISSING;
+ accel_plus_g = AltosLib.MISSING;
+ accel_minus_g = AltosLib.MISSING;
+ accel = AltosLib.MISSING;
+ ground_pressure = AltosLib.MISSING;
+ ground_altitude = AltosLib.MISSING;
+ temp_gps = null;
+ temp_gps_sat_tick = AltosLib.MISSING;
+ }
+}
diff --git a/altoslib/AltosFlightReader.java b/altoslib/AltosFlightReader.java
index 250e2236..671bf638 100644
--- a/altoslib/AltosFlightReader.java
+++ b/altoslib/AltosFlightReader.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.io.*;
@@ -31,6 +31,8 @@ public abstract class AltosFlightReader {
public abstract AltosState read() throws InterruptedException, ParseException, AltosCRCException, IOException;
+ public abstract AltosCalData cal_data();
+
public abstract void close(boolean interrupted);
public void set_frequency(double frequency) throws InterruptedException, TimeoutException { }
@@ -45,8 +47,6 @@ public abstract class AltosFlightReader {
public void save_telemetry_rate() { }
- public void update(AltosState state) throws InterruptedException { }
-
public boolean supports_telemetry(int telemetry) { return false; }
public boolean supports_telemetry_rate(int telemetry_rate) { return false; }
diff --git a/altoslib/AltosFlightSeries.java b/altoslib/AltosFlightSeries.java
new file mode 100644
index 00000000..57f1a491
--- /dev/null
+++ b/altoslib/AltosFlightSeries.java
@@ -0,0 +1,697 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+import java.util.*;
+
+public class AltosFlightSeries extends AltosDataListener {
+
+ public ArrayList<AltosTimeSeries> series = new ArrayList<AltosTimeSeries>();
+
+ public double speed_filter_width = 4.0;
+ public double accel_filter_width = 4.0;
+
+ public int[] indices() {
+ int[] indices = new int[series.size()];
+ for (int i = 0; i < indices.length; i++)
+ indices[i] = -1;
+ step_indices(indices);
+ return indices;
+ }
+
+ private double time(int id, int index) {
+ AltosTimeSeries s = series.get(id);
+
+ if (index < 0)
+ return Double.NEGATIVE_INFINITY;
+
+ if (index < s.values.size())
+ return s.values.get(index).time;
+ return Double.POSITIVE_INFINITY;
+ }
+
+ public boolean step_indices(int[] indices) {
+ double min_next = time(0, indices[0]+1);
+
+ for (int i = 1; i < indices.length; i++) {
+ double next = time(i, indices[i]+1);
+ if (next < min_next)
+ min_next = next;
+ }
+
+ if (min_next == Double.POSITIVE_INFINITY)
+ return false;
+
+ for (int i = 0; i < indices.length; i++) {
+ double t = time(i, indices[i] + 1);
+
+ if (t <= min_next)
+ indices[i]++;
+ }
+ return true;
+ }
+
+ public double time(int[] indices) {
+ double max = time(0, indices[0]);
+
+ for (int i = 1; i < indices.length; i++) {
+ double t = time(i, indices[i]);
+ if (t >= max)
+ max = t;
+ }
+ return max;
+ }
+
+ public double value(String name, int[] indices) {
+ for (int i = 0; i < indices.length; i++) {
+ AltosTimeSeries s = series.get(i);
+ if (s.label.equals(name)) {
+ int index = indices[i];
+ if (index < 0)
+ index = 0;
+ if (index >= s.values.size())
+ index = s.values.size() - 1;
+ return s.values.get(index).value;
+ }
+ }
+ return AltosLib.MISSING;
+ }
+
+ public double value(String name, double time) {
+ for (AltosTimeSeries s : series) {
+ if (s.label.equals(name))
+ return s.value(time);
+ }
+ return AltosLib.MISSING;
+ }
+
+ public double value_before(String name, double time) {
+ for (AltosTimeSeries s : series) {
+ if (s.label.equals(name))
+ return s.value_before(time);
+ }
+ return AltosLib.MISSING;
+ }
+
+ public double value_after(String name, double time) {
+ for (AltosTimeSeries s : series) {
+ if (s.label.equals(name))
+ return s.value_after(time);
+ }
+ return AltosLib.MISSING;
+ }
+
+ public AltosTimeSeries make_series(String label, AltosUnits units) {
+ return new AltosTimeSeries(label, units);
+ }
+
+ public void add_series(AltosTimeSeries s) {
+ for (int e = 0; e < series.size(); e++) {
+ if (s.compareTo(series.get(e)) < 0){
+ series.add(e, s);
+ return;
+ }
+ }
+ series.add(s);
+ }
+
+ public AltosTimeSeries add_series(String label, AltosUnits units) {
+ AltosTimeSeries s = make_series(label, units);
+ add_series(s);
+ return s;
+ }
+
+ public void remove_series(AltosTimeSeries s) {
+ series.remove(s);
+ }
+
+ public boolean has_series(String label) {
+ for (AltosTimeSeries s : series)
+ if (s.label.equals(label))
+ return true;
+ return false;
+ }
+
+ public AltosTimeSeries state_series;
+
+ public static final String state_name = "State";
+
+ public void set_state(int state) {
+
+ if (state == AltosLib.ao_flight_pad)
+ return;
+
+ if (state_series == null)
+ state_series = add_series(state_name, AltosConvert.state_name);
+ else if (this.state == state)
+ return;
+ this.state = state;
+ state_series.add(time(), state);
+ }
+
+ public AltosTimeSeries accel_series;
+
+ public static final String accel_name = "Accel";
+
+ public AltosTimeSeries vert_accel_series;
+
+ public static final String vert_accel_name = "Vertical Accel";
+
+ public void set_acceleration(double acceleration) {
+ if (acceleration == AltosLib.MISSING)
+ return;
+ if (accel_series == null)
+ accel_series = add_series(accel_name, AltosConvert.accel);
+
+ accel_series.add(time(), acceleration);
+ }
+
+ private void compute_accel() {
+ if (accel_series != null)
+ return;
+
+ if (speed_series != null) {
+ AltosTimeSeries temp_series = make_series(speed_name, AltosConvert.speed);
+ speed_series.filter(temp_series, accel_filter_width);
+ accel_series = add_series(accel_name, AltosConvert.accel);
+ temp_series.differentiate(accel_series);
+ }
+ }
+
+ public void set_received_time(long received_time) {
+ }
+
+ public AltosTimeSeries rssi_series;
+
+ public static final String rssi_name = "RSSI";
+
+ public AltosTimeSeries status_series;
+
+ public static final String status_name = "Radio Status";
+
+ public void set_rssi(int rssi, int status) {
+ if (rssi_series == null) {
+ rssi_series = add_series(rssi_name, null);
+ status_series = add_series(status_name, null);
+ }
+ rssi_series.add(time(), rssi);
+ status_series.add(time(), status);
+ }
+
+ public AltosTimeSeries pressure_series;
+
+ public static final String pressure_name = "Pressure";
+
+ public AltosTimeSeries altitude_series;
+
+ public static final String altitude_name = "Altitude";
+
+ public AltosTimeSeries height_series;
+
+ public static final String height_name = "Height";
+
+ public void set_pressure(double pa) {
+ if (pa == AltosLib.MISSING)
+ return;
+
+ if (pressure_series == null)
+ pressure_series = add_series(pressure_name, AltosConvert.pressure);
+ pressure_series.add(time(), pa);
+ if (altitude_series == null)
+ altitude_series = add_series(altitude_name, AltosConvert.height);
+
+ if (cal_data().ground_pressure == AltosLib.MISSING)
+ cal_data().set_ground_pressure(pa);
+
+ double altitude = AltosConvert.pressure_to_altitude(pa);
+ altitude_series.add(time(), altitude);
+ }
+
+ private void compute_height() {
+ double ground_altitude = cal_data().ground_altitude;
+ if (height_series == null && ground_altitude != AltosLib.MISSING && altitude_series != null) {
+ height_series = add_series(height_name, AltosConvert.height);
+ for (AltosTimeValue alt : altitude_series)
+ height_series.add(alt.time, alt.value - ground_altitude);
+ }
+
+ if (gps_height == null && cal_data().gps_pad != null && cal_data().gps_pad.alt != AltosLib.MISSING && gps_altitude != null) {
+ double gps_ground_altitude = cal_data().gps_pad.alt;
+ gps_height = add_series(gps_height_name, AltosConvert.height);
+ for (AltosTimeValue gps_alt : gps_altitude)
+ gps_height.add(gps_alt.time, gps_alt.value - gps_ground_altitude);
+ }
+ }
+
+ public AltosTimeSeries speed_series;
+
+ public static final String speed_name = "Speed";
+
+ private void compute_speed() {
+ if (speed_series != null)
+ return;
+
+ AltosTimeSeries alt_speed_series = null;
+ AltosTimeSeries accel_speed_series = null;
+
+ if (altitude_series != null) {
+ AltosTimeSeries temp_series = make_series(altitude_name, AltosConvert.height);
+ altitude_series.filter(temp_series, speed_filter_width);
+
+ alt_speed_series = make_series(speed_name, AltosConvert.speed);
+ temp_series.differentiate(alt_speed_series);
+ }
+ if (accel_series != null) {
+
+ if (orient_series != null) {
+ vert_accel_series = add_series(vert_accel_name, AltosConvert.accel);
+
+ for (AltosTimeValue a : accel_series) {
+ double orient = orient_series.value(a.time);
+ double a_abs = a.value + AltosConvert.gravity;
+ double v_a = a_abs * Math.cos(AltosConvert.degrees_to_radians(orient)) - AltosConvert.gravity;
+
+ vert_accel_series.add(a.time, v_a);
+ }
+ }
+
+ AltosTimeSeries temp_series = make_series(speed_name, AltosConvert.speed);
+
+ if (vert_accel_series != null)
+ vert_accel_series.integrate(temp_series);
+ else
+ accel_series.integrate(temp_series);
+
+ accel_speed_series = make_series(speed_name, AltosConvert.speed);
+ temp_series.filter(accel_speed_series, 0.1);
+ }
+
+ if (alt_speed_series != null && accel_speed_series != null) {
+ double apogee_time = AltosLib.MISSING;
+ if (state_series != null) {
+ for (AltosTimeValue d : state_series) {
+ if (d.value >= AltosLib.ao_flight_drogue){
+ apogee_time = d.time;
+ break;
+ }
+ }
+ }
+ if (apogee_time == AltosLib.MISSING) {
+ speed_series = alt_speed_series;
+ } else {
+ speed_series = make_series(speed_name, AltosConvert.speed);
+ for (AltosTimeValue d : accel_speed_series) {
+ if (d.time <= apogee_time)
+ speed_series.add(d);
+ }
+ for (AltosTimeValue d : alt_speed_series) {
+ if (d.time > apogee_time)
+ speed_series.add(d);
+ }
+
+ }
+ } else if (alt_speed_series != null) {
+ speed_series = alt_speed_series;
+ } else if (accel_speed_series != null) {
+ speed_series = accel_speed_series;
+ }
+ if (speed_series != null)
+ add_series(speed_series);
+ }
+
+ public AltosTimeSeries orient_series;
+
+ public static final String orient_name = "Tilt Angle";
+
+ private void compute_orient() {
+
+ if (orient_series != null)
+ return;
+
+ if (accel_ground_across == AltosLib.MISSING)
+ return;
+
+ if (cal_data().pad_orientation == AltosLib.MISSING)
+ return;
+
+ if (cal_data().accel_zero_across == AltosLib.MISSING)
+ return;
+
+ AltosRotation rotation = new AltosRotation(AltosIMU.convert_accel(accel_ground_across - cal_data().accel_zero_across),
+ AltosIMU.convert_accel(accel_ground_through - cal_data().accel_zero_through),
+ AltosIMU.convert_accel(accel_ground_along - cal_data().accel_zero_along),
+ cal_data().pad_orientation);
+ double prev_time = ground_time;
+
+ orient_series = add_series(orient_name, AltosConvert.orient);
+ orient_series.add(ground_time, rotation.tilt());
+
+ for (AltosTimeValue roll_v : gyro_roll) {
+ double time = roll_v.time;
+ double dt = time - prev_time;
+
+ if (dt > 0) {
+ double roll = AltosConvert.degrees_to_radians(roll_v.value) * dt;
+ double pitch = AltosConvert.degrees_to_radians(gyro_pitch.value(time)) * dt;
+ double yaw = AltosConvert.degrees_to_radians(gyro_yaw.value(time)) * dt;
+
+ rotation.rotate(pitch, yaw, roll);
+ orient_series.add(time, rotation.tilt());
+ }
+ prev_time = time;
+ }
+ }
+
+ public AltosTimeSeries kalman_height_series, kalman_speed_series, kalman_accel_series;
+
+ public static final String kalman_height_name = "Kalman Height";
+ public static final String kalman_speed_name = "Kalman Speed";
+ public static final String kalman_accel_name = "Kalman Accel";
+
+ public void set_kalman(double height, double speed, double acceleration) {
+ if (kalman_height_series == null) {
+ kalman_height_series = add_series(kalman_height_name, AltosConvert.height);
+ kalman_speed_series = add_series(kalman_speed_name, AltosConvert.speed);
+ kalman_accel_series = add_series(kalman_accel_name, AltosConvert.accel);
+ }
+ kalman_height_series.add(time(), height);
+ kalman_speed_series.add(time(), speed);
+ kalman_accel_series.add(time(), acceleration);
+ }
+
+ public AltosTimeSeries thrust_series;
+
+ public static final String thrust_name = "Thrust";
+
+ public void set_thrust(double N) {
+ if (thrust_series == null)
+ thrust_series = add_series(thrust_name, AltosConvert.force);
+ thrust_series.add(time(), N);
+ }
+
+ public AltosTimeSeries temperature_series;
+
+ public static final String temperature_name = "Temperature";
+
+ public void set_temperature(double deg_c) {
+ if (temperature_series == null)
+ temperature_series = add_series(temperature_name, AltosConvert.temperature);
+ temperature_series.add(time(), deg_c);
+ }
+
+ public AltosTimeSeries battery_voltage_series;
+
+ public static final String battery_voltage_name = "Battery Voltage";
+
+ public void set_battery_voltage(double volts) {
+ if (volts == AltosLib.MISSING)
+ return;
+ if (battery_voltage_series == null)
+ battery_voltage_series = add_series(battery_voltage_name, AltosConvert.voltage);
+ battery_voltage_series.add(time(), volts);
+ }
+
+ public AltosTimeSeries apogee_voltage_series;
+
+ public static final String apogee_voltage_name = "Apogee Voltage";
+
+ public void set_apogee_voltage(double volts) {
+ if (volts == AltosLib.MISSING)
+ return;
+ if (apogee_voltage_series == null)
+ apogee_voltage_series = add_series(apogee_voltage_name, AltosConvert.voltage);
+ apogee_voltage_series.add(time(), volts);
+ }
+
+ public AltosTimeSeries main_voltage_series;
+
+ public static final String main_voltage_name = "Main Voltage";
+
+ public void set_main_voltage(double volts) {
+ if (volts == AltosLib.MISSING)
+ return;
+ if (main_voltage_series == null)
+ main_voltage_series = add_series(main_voltage_name, AltosConvert.voltage);
+ main_voltage_series.add(time(), volts);
+ }
+
+ public ArrayList<AltosGPSTimeValue> gps_series;
+
+ public AltosGPS gps_before(double time) {
+ AltosGPS gps = null;
+ for (AltosGPSTimeValue gtv : gps_series)
+ if (gtv.time <= time)
+ gps = gtv.gps;
+ else
+ break;
+ return gps;
+ }
+
+ public AltosTimeSeries sats_in_view;
+ public AltosTimeSeries sats_in_soln;
+ public AltosTimeSeries gps_altitude;
+ public AltosTimeSeries gps_height;
+ public AltosTimeSeries gps_ground_speed;
+ public AltosTimeSeries gps_ascent_rate;
+ public AltosTimeSeries gps_course;
+ public AltosTimeSeries gps_speed;
+ public AltosTimeSeries gps_pdop, gps_vdop, gps_hdop;
+
+ public static final String sats_in_view_name = "Satellites in view";
+ public static final String sats_in_soln_name = "Satellites in solution";
+ public static final String gps_altitude_name = "GPS Altitude";
+ public static final String gps_height_name = "GPS Height";
+ public static final String gps_ground_speed_name = "GPS Ground Speed";
+ public static final String gps_ascent_rate_name = "GPS Ascent Rate";
+ public static final String gps_course_name = "GPS Course";
+ public static final String gps_speed_name = "GPS Speed";
+ public static final String gps_pdop_name = "GPS Dilution of Precision";
+ public static final String gps_vdop_name = "GPS Vertical Dilution of Precision";
+ public static final String gps_hdop_name = "GPS Horizontal Dilution of Precision";
+
+ public void set_gps(AltosGPS gps) {
+ if (gps_series == null)
+ gps_series = new ArrayList<AltosGPSTimeValue>();
+ gps_series.add(new AltosGPSTimeValue(time(), gps));
+
+ if (sats_in_soln == null) {
+ sats_in_soln = add_series(sats_in_soln_name, null);
+ }
+ sats_in_soln.add(time(), gps.nsat);
+ if (gps.pdop != AltosLib.MISSING) {
+ if (gps_pdop == null)
+ gps_pdop = add_series(gps_pdop_name, null);
+ gps_pdop.add(time(), gps.pdop);
+ }
+ if (gps.hdop != AltosLib.MISSING) {
+ if (gps_hdop == null)
+ gps_hdop = add_series(gps_hdop_name, null);
+ gps_hdop.add(time(), gps.hdop);
+ }
+ if (gps.vdop != AltosLib.MISSING) {
+ if (gps_vdop == null)
+ gps_vdop = add_series(gps_vdop_name, null);
+ gps_vdop.add(time(), gps.vdop);
+ }
+ if (gps.locked) {
+ if (gps.alt != AltosLib.MISSING) {
+ if (gps_altitude == null)
+ gps_altitude = add_series(gps_altitude_name, AltosConvert.height);
+ gps_altitude.add(time(), gps.alt);
+ }
+ if (gps.ground_speed != AltosLib.MISSING) {
+ if (gps_ground_speed == null)
+ gps_ground_speed = add_series(gps_ground_speed_name, AltosConvert.speed);
+ gps_ground_speed.add(time(), gps.ground_speed);
+ }
+ if (gps.climb_rate != AltosLib.MISSING) {
+ if (gps_ascent_rate == null)
+ gps_ascent_rate = add_series(gps_ascent_rate_name, AltosConvert.speed);
+ gps_ascent_rate.add(time(), gps.climb_rate);
+ }
+ if (gps.course != AltosLib.MISSING) {
+ if (gps_course == null)
+ gps_course = add_series(gps_course_name, null);
+ gps_course.add(time(), gps.course);
+ }
+ if (gps.ground_speed != AltosLib.MISSING && gps.climb_rate != AltosLib.MISSING) {
+ if (gps_speed == null)
+ gps_speed = add_series(gps_speed_name, null);
+ gps_speed.add(time(), Math.sqrt(gps.ground_speed * gps.ground_speed +
+ gps.climb_rate * gps.climb_rate));
+ }
+ }
+ if (gps.cc_gps_sat != null) {
+ if (sats_in_view == null)
+ sats_in_view = add_series(sats_in_view_name, null);
+ sats_in_view.add(time(), gps.cc_gps_sat.length);
+ }
+ }
+
+ public static final String accel_along_name = "Accel Along";
+ public static final String accel_across_name = "Accel Across";
+ public static final String accel_through_name = "Accel Through";
+
+ public AltosTimeSeries accel_along, accel_across, accel_through;
+
+ public static final String gyro_roll_name = "Roll Rate";
+ public static final String gyro_pitch_name = "Pitch Rate";
+ public static final String gyro_yaw_name = "Yaw Rate";
+
+ public AltosTimeSeries gyro_roll, gyro_pitch, gyro_yaw;
+
+ public static final String mag_along_name = "Magnetic Field Along";
+ public static final String mag_across_name = "Magnetic Field Across";
+ public static final String mag_through_name = "Magnetic Field Through";
+
+ public AltosTimeSeries mag_along, mag_across, mag_through;
+
+ public void set_accel(double along, double across, double through) {
+ if (accel_along == null) {
+ accel_along = add_series(accel_along_name, AltosConvert.accel);
+ accel_across = add_series(accel_across_name, AltosConvert.accel);
+ accel_through = add_series(accel_through_name, AltosConvert.accel);
+ }
+ accel_along.add(time(), along);
+ accel_across.add(time(), across);
+ accel_through.add(time(), through);
+ }
+
+ private double accel_ground_along = AltosLib.MISSING;
+ private double accel_ground_across = AltosLib.MISSING;
+ private double accel_ground_through = AltosLib.MISSING;
+
+ private double ground_time;
+
+ public void set_accel_ground(double along, double across, double through) {
+ accel_ground_along = along;
+ accel_ground_across = across;
+ accel_ground_through = through;
+ ground_time = time();
+ }
+
+ public void set_gyro(double roll, double pitch, double yaw) {
+ if (gyro_roll == null) {
+ gyro_roll = add_series(gyro_roll_name, AltosConvert.rotation_rate);
+ gyro_pitch = add_series(gyro_pitch_name, AltosConvert.rotation_rate);
+ gyro_yaw = add_series(gyro_yaw_name, AltosConvert.rotation_rate);
+ }
+ gyro_roll.add(time(), roll);
+ gyro_pitch.add(time(), pitch);
+ gyro_yaw.add(time(), yaw);
+ }
+
+ public void set_mag(double along, double across, double through) {
+ if (mag_along == null) {
+ mag_along = add_series(mag_along_name, AltosConvert.magnetic_field);
+ mag_across = add_series(mag_across_name, AltosConvert.magnetic_field);
+ mag_through = add_series(mag_through_name, AltosConvert.magnetic_field);
+ }
+ mag_along.add(time(), along);
+ mag_across.add(time(), across);
+ mag_through.add(time(), through);
+ }
+
+ public void set_orient(double orient) {
+ if (orient_series == null)
+ orient_series = add_series(orient_name, AltosConvert.orient);
+ orient_series.add(time(), orient);
+ }
+
+ public static final String pyro_voltage_name = "Pyro Voltage";
+
+ public AltosTimeSeries pyro_voltage;
+
+ public void set_pyro_voltage(double volts) {
+ if (pyro_voltage == null)
+ pyro_voltage = add_series(pyro_voltage_name, AltosConvert.voltage);
+ pyro_voltage.add(time(), volts);
+ }
+
+ private static String[] igniter_voltage_names;
+
+ public String igniter_voltage_name(int channel) {
+ if (igniter_voltage_names == null || igniter_voltage_names.length <= channel) {
+ String[] new_igniter_voltage_names = new String[channel + 1];
+ int i = 0;
+
+ if (igniter_voltage_names != null) {
+ for (; i < igniter_voltage_names.length; i++)
+ new_igniter_voltage_names[i] = igniter_voltage_names[i];
+ }
+ for (; i < channel+1; i++)
+ new_igniter_voltage_names[i] = AltosLib.igniter_name(i);
+ igniter_voltage_names = new_igniter_voltage_names;
+ }
+ return igniter_voltage_names[channel];
+ }
+
+ public AltosTimeSeries[] igniter_voltage;
+
+ public void set_igniter_voltage(double[] voltage) {
+ int channels = voltage.length;
+ if (igniter_voltage == null || igniter_voltage.length <= channels) {
+ AltosTimeSeries[] new_igniter_voltage = new AltosTimeSeries[channels + 1];
+ int i = 0;
+
+ if (igniter_voltage != null) {
+ for (; i < igniter_voltage.length; i++)
+ new_igniter_voltage[i] = igniter_voltage[i];
+ }
+ for (; i < channels; i++)
+ new_igniter_voltage[i] = add_series(igniter_voltage_name(i), AltosConvert.voltage);
+ igniter_voltage = new_igniter_voltage;
+ }
+ for (int channel = 0; channel < voltage.length; channel++)
+ igniter_voltage[channel].add(time(), voltage[channel]);
+ }
+
+ public static final String pyro_fired_name = "Pyro Channel State";
+
+ public AltosTimeSeries pyro_fired_series;
+
+ int last_pyro_mask;
+
+ public void set_pyro_fired(int pyro_mask) {
+ if (pyro_fired_series == null)
+ pyro_fired_series = add_series(pyro_fired_name, AltosConvert.pyro_name);
+ for (int channel = 0; channel < 32; channel++) {
+ if ((last_pyro_mask & (1 << channel)) == 0 &&
+ (pyro_mask & (1 << channel)) != 0) {
+ pyro_fired_series.add(time(), channel);
+ }
+ }
+ last_pyro_mask = pyro_mask;
+ }
+
+ public void set_companion(AltosCompanion companion) {
+ }
+
+ public void finish() {
+ compute_orient();
+ compute_speed();
+ compute_accel();
+ compute_height();
+ }
+
+ public AltosTimeSeries[] series() {
+ finish();
+ return series.toArray(new AltosTimeSeries[0]);
+ }
+
+ public AltosFlightSeries(AltosCalData cal_data) {
+ super(cal_data);
+ }
+}
diff --git a/altoslib/AltosFlightStats.java b/altoslib/AltosFlightStats.java
index 98f13dac..6f8732cf 100644
--- a/altoslib/AltosFlightStats.java
+++ b/altoslib/AltosFlightStats.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
@@ -25,15 +25,17 @@ public class AltosFlightStats {
public double max_gps_height;
public double max_speed;
public double max_acceleration;
- public double[] state_speed = new double[AltosLib.ao_flight_invalid + 1];
- public double[] state_accel = new double[AltosLib.ao_flight_invalid + 1];
- public int[] state_count = new int[AltosLib.ao_flight_invalid + 1];
- public double[] state_start = new double[AltosLib.ao_flight_invalid + 1];
- public double[] state_end = new double[AltosLib.ao_flight_invalid + 1];
+ public double[] state_speed = new double[AltosLib.ao_flight_invalid + 1];
+ public double[] state_accel = new double[AltosLib.ao_flight_invalid + 1];
+ public double[] state_time = new double[AltosLib.ao_flight_invalid + 1];
+ public String product;
+ public String firmware_version;
public int serial;
public int flight;
public int year, month, day;
public int hour, minute, second;
+ public double boost_time;
+ public double landed_time;
public double lat, lon;
public double pad_lat, pad_lon;
public boolean has_flight_data;
@@ -46,65 +48,133 @@ public class AltosFlightStats {
public boolean has_imu;
public boolean has_mag;
public boolean has_orient;
- public int num_ignitor;
+ public int num_igniter;
- double landed_time(AltosStateIterable states) {
- AltosState state = null;
+ double landed_time(AltosFlightSeries series) {
+ double landed_state_time = AltosLib.MISSING;
- for (AltosState s : states) {
- state = s;
- if (state.state() == AltosLib.ao_flight_landed)
- break;
+ double prev_state_time = AltosLib.MISSING;
+ if (series.state_series != null) {
+ for (AltosTimeValue state : series.state_series) {
+ if (state.value == AltosLib.ao_flight_landed) {
+ landed_state_time = state.time;
+ break;
+ } else {
+ prev_state_time = state.time;
+ }
+ }
}
- if (state == null)
- return AltosLib.MISSING;
+ if (landed_state_time == AltosLib.MISSING && series.height_series != null)
+ landed_state_time = series.height_series.get(series.height_series.size()-1).time;
- double landed_height = state.height();
+ double landed_height = AltosLib.MISSING;
+
+ if (series.height_series != null) {
+ for (AltosTimeValue height : series.height_series) {
+ landed_height = height.value;
+ if (height.time >= landed_state_time)
+ break;
+ }
+ }
- state = null;
+ if (landed_height == AltosLib.MISSING)
+ return AltosLib.MISSING;
boolean above = true;
double landed_time = AltosLib.MISSING;
- for (AltosState s : states) {
- state = s;
-
- if (state.height() > landed_height + 10) {
- above = true;
- } else {
- if (above && Math.abs(state.height() - landed_height) < 2) {
- above = false;
- landed_time = state.time;
+ if (series.height_series != null) {
+ for (AltosTimeValue height : series.height_series) {
+ if (height.value > landed_height + 10) {
+ above = true;
+ } else {
+ if (above && Math.abs(height.value - landed_height) < 2) {
+ above = false;
+ landed_time = height.time;
+ }
}
}
}
+
+ if (landed_time == AltosLib.MISSING || (prev_state_time != AltosLib.MISSING && landed_time < prev_state_time))
+ landed_time = landed_state_time;
return landed_time;
}
- double boost_time(AltosStateIterable states) {
- double boost_time = AltosLib.MISSING;
- AltosState state = null;
+ double boost_time(AltosFlightSeries series) {
+ double boost_time = AltosLib.MISSING;
+ double boost_state_time = AltosLib.MISSING;
- for (AltosState s : states) {
- state = s;
- if (state.acceleration() < 1)
- boost_time = state.time;
- if (state.state() >= AltosLib.ao_flight_boost && state.state() <= AltosLib.ao_flight_landed)
- break;
+ if (series.state_series != null) {
+ for (AltosTimeValue state : series.state_series) {
+ if (state.value >= AltosLib.ao_flight_boost && state.value <= AltosLib.ao_flight_landed) {
+ boost_state_time = state.time;
+ break;
+ }
+ }
}
- if (state == null)
- return AltosLib.MISSING;
-
+ if (series.accel_series != null) {
+ for (AltosTimeValue accel : series.accel_series) {
+ if (accel.value < 1)
+ boost_time = accel.time;
+ if (boost_state_time != AltosLib.MISSING && accel.time >= boost_state_time)
+ break;
+ }
+ }
+ if (boost_time == AltosLib.MISSING)
+ boost_time = boost_state_time;
return boost_time;
}
+ private void add_times(AltosFlightSeries series, int state, double start_time, double end_time) {
+ double delta_time = end_time - start_time;
+ if (0 <= state && state <= AltosLib.ao_flight_invalid && delta_time > 0) {
+ speeds[state].value += series.speed_series.average(start_time, end_time) * delta_time;
+ speeds[state].time += delta_time;
+ accels[state].value += series.accel_series.average(start_time, end_time) * delta_time;
+ accels[state].time += delta_time;
+ state_time[state] += delta_time;
+
+ if (state == AltosLib.ao_flight_boost) {
+ AltosTimeValue tv_speed = series.speed_series.max(start_time, end_time);
+ if (tv_speed != null && (max_speed == AltosLib.MISSING || tv_speed.value > max_speed))
+ max_speed = tv_speed.value;
+ AltosTimeValue tv_accel = series.accel_series.max(start_time, end_time);
+ if (tv_accel != null && (max_acceleration == AltosLib.MISSING || tv_accel.value > max_acceleration))
+ max_acceleration = tv_accel.value;
+ }
+ }
+ }
+
+ AltosTimeValue[] speeds = new AltosTimeValue[AltosLib.ao_flight_invalid + 1];
+ AltosTimeValue[] accels = new AltosTimeValue[AltosLib.ao_flight_invalid + 1];
- public AltosFlightStats(AltosStateIterable states) throws InterruptedException, IOException {
- double boost_time = boost_time(states);
- double end_time = 0;
- double landed_time = landed_time(states);
+ public AltosFlightStats(AltosFlightSeries series) {
+ AltosCalData cal_data = series.cal_data();
+
+ series.finish();
+
+ boost_time = boost_time(series);
+ landed_time = landed_time(series);
+
+ if (series.state_series != null){
+ boolean fixed_boost = false;
+ boolean fixed_landed = false;
+ for (AltosTimeValue state : series.state_series) {
+ if ((int) state.value == AltosLib.ao_flight_boost)
+ if (boost_time != AltosLib.MISSING && !fixed_boost) {
+ state.time = boost_time;
+ fixed_boost = true;
+ }
+ if ((int) state.value == AltosLib.ao_flight_landed)
+ if (landed_time != AltosLib.MISSING && !fixed_landed) {
+ state.time = landed_time;
+ fixed_landed = true;
+ }
+ }
+ }
year = month = day = AltosLib.MISSING;
hour = minute = second = AltosLib.MISSING;
@@ -120,96 +190,75 @@ public class AltosFlightStats {
has_mag = false;
has_orient = false;
- for (int s = AltosLib.ao_flight_startup; s <= AltosLib.ao_flight_landed; s++) {
- state_count[s] = 0;
- state_speed[s] = 0.0;
- state_accel[s] = 0.0;
+ for (int s = 0; s < AltosLib.ao_flight_invalid + 1; s++) {
+ state_speed[s] = AltosLib.MISSING;
+ state_accel[s] = AltosLib.MISSING;
+ state_time[s] = 0;
+ speeds[s] = new AltosTimeValue(0, 0);
+ accels[s] = new AltosTimeValue(0, 0);
}
- for (AltosState state : states) {
- if (serial == AltosLib.MISSING && state.serial != AltosLib.MISSING)
- serial = state.serial;
- if (flight == AltosLib.MISSING && state.flight != AltosLib.MISSING)
- flight = state.flight;
- if (state.battery_voltage != AltosLib.MISSING)
- has_battery = true;
- if (state.main_voltage != AltosLib.MISSING)
- has_flight_adc = true;
- if (state.rssi != AltosLib.MISSING)
- has_rssi = true;
- end_time = state.time;
-
- if (state.pressure() != AltosLib.MISSING)
- has_flight_data = true;
-
- int state_id = state.state();
- if (boost_time != AltosLib.MISSING && state.time >= boost_time && state_id < AltosLib.ao_flight_boost) {
- state_id = AltosLib.ao_flight_boost;
- }
- if (landed_time != AltosLib.MISSING && state.time >= landed_time && state_id < AltosLib.ao_flight_landed) {
- state_id = AltosLib.ao_flight_landed;
- }
+ max_speed = AltosLib.MISSING;
+ max_acceleration = AltosLib.MISSING;
- if (state.gps != null && state.gps.locked) {
- year = state.gps.year;
- month = state.gps.month;
- day = state.gps.day;
- hour = state.gps.hour;
- minute = state.gps.minute;
- second = state.gps.second;
+ if (series.state_series != null) {
+ AltosTimeValue prev = null;
+ for (AltosTimeValue state : series.state_series) {
+ if (prev != null)
+ add_times(series, (int) prev.value, prev.time, state.time);
+ prev = state;
}
- max_height = state.max_height();
- max_speed = state.max_speed();
- max_acceleration = state.max_acceleration();
- max_gps_height = state.max_gps_height();
-
- if (0 <= state_id && state_id < AltosLib.ao_flight_invalid) {
- double acceleration = state.acceleration();
- double speed = state.speed();
- if (acceleration != AltosLib.MISSING && speed != AltosLib.MISSING) {
- state_accel[state_id] += acceleration;
- state_speed[state_id] += speed;
- state_count[state_id]++;
+ if (prev != null)
+ add_times(series, (int) prev.value, prev.time, series.accel_series.last().time);
+ }
+
+ for (int s = 0; s <= AltosLib.ao_flight_invalid; s++) {
+ if (speeds[s].time > 0)
+ state_speed[s] = speeds[s].value / speeds[s].time;
+ if (accels[s].time > 0)
+ state_accel[s] = accels[s].value / accels[s].time;
+ }
+
+ product = cal_data.product;
+ firmware_version = cal_data.firmware_version;
+ serial = cal_data.serial;
+ flight = cal_data.flight;
+
+ has_battery = series.battery_voltage_series != null;
+ has_flight_adc = series.main_voltage_series != null;
+ has_rssi = series.rssi_series != null;
+ has_flight_data = series.pressure_series != null;
+
+ AltosGPS gps = series.cal_data().gps_pad;
+
+ if (gps != null) {
+ year = gps.year;
+ month = gps.month;
+ day = gps.day;
+ hour = gps.hour;
+ minute = gps.minute;
+ second = gps.second;
+ has_gps = true;
+ lat = pad_lat = gps.lat;
+ lon = pad_lon = gps.lon;
+ for (AltosGPSTimeValue gtv : series.gps_series) {
+ gps = gtv.gps;
+ if (gps.locked && gps.nsat >= 4) {
+ lat = gps.lat;
+ lon = gps.lon;
}
- if (state_start[state_id] == 0.0)
- state_start[state_id] = state.time;
- if (state_end[state_id] < state.time)
- state_end[state_id] = state.time;
- }
- if (state.pad_lat != AltosLib.MISSING) {
- pad_lat = state.pad_lat;
- pad_lon = state.pad_lon;
}
- if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) {
- lat = state.gps.lat;
- lon = state.gps.lon;
- has_gps = true;
- if (state.gps.cc_gps_sat != null)
- has_gps_sats = true;
- if (state.gps.course != AltosLib.MISSING)
- has_gps_detail = true;
- }
- if (state.imu != null)
- has_imu = true;
- if (state.mag != null)
- has_mag = true;
- if (state.orient() != AltosLib.MISSING)
- has_orient = true;
- if (state.ignitor_voltage != null && state.ignitor_voltage.length > num_ignitor)
- num_ignitor = state.ignitor_voltage.length;
+
}
- for (int s = AltosLib.ao_flight_startup; s <= AltosLib.ao_flight_landed; s++) {
- if (state_count[s] > 0) {
- state_speed[s] /= state_count[s];
- state_accel[s] /= state_count[s];
- } else {
- state_speed[s] = AltosLib.MISSING;
- state_accel[s] = AltosLib.MISSING;
- }
- if (state_start[s] == 0)
- state_start[s] = end_time;
- if (state_end[s] == 0)
- state_end[s] = end_time;
+
+ max_height = AltosLib.MISSING;
+ if (series.height_series != null)
+ max_height = series.height_series.max().value;
+ max_gps_height = AltosLib.MISSING;
+ if (series.gps_height != null) {
+ AltosTimeValue tv = series.gps_height.max();
+ if (tv != null)
+ max_gps_height = tv.value;
}
}
}
diff --git a/altoslib/AltosFontListener.java b/altoslib/AltosFontListener.java
index c7f339a0..97947d0b 100644
--- a/altoslib/AltosFontListener.java
+++ b/altoslib/AltosFontListener.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosFontListener {
void font_size_changed(int font_size);
diff --git a/altoslib/AltosForce.java b/altoslib/AltosForce.java
new file mode 100644
index 00000000..47fb900c
--- /dev/null
+++ b/altoslib/AltosForce.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2017 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_12;
+
+public class AltosForce extends AltosUnits {
+
+ public double value(double v, boolean imperial_units) {
+ if (imperial_units)
+ return AltosConvert.n_to_lb(v);
+ return v;
+ }
+
+ public double inverse(double v, boolean imperial_units) {
+ if (imperial_units)
+ return AltosConvert.lb_to_n(v);
+ return v;
+ }
+
+ public String show_units(boolean imperial_units) {
+ if (imperial_units)
+ return "lbs";
+ return "N";
+ }
+
+ public String say_units(boolean imperial_units) {
+ if (imperial_units)
+ return "pounds";
+ return "newtons";
+ }
+
+ public int show_fraction(int width, boolean imperial_units) {
+ return width / 9;
+ }
+}
diff --git a/altoslib/AltosFrequency.java b/altoslib/AltosFrequency.java
index 3b2a445a..6838be8a 100644
--- a/altoslib/AltosFrequency.java
+++ b/altoslib/AltosFrequency.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java
index 0b30ed45..b6ca3576 100644
--- a/altoslib/AltosGPS.java
+++ b/altoslib/AltosGPS.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.util.concurrent.*;
@@ -383,17 +383,13 @@ public class AltosGPS implements Cloneable {
}
}
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
- AltosGPS gps = new AltosGPS(link, config_data);
-
- if (gps != null) {
- state.set_gps(gps, state.gps_sequence++);
- return;
- }
+ AltosGPS gps = new AltosGPS(link, link.config_data());
+ if (gps != null)
+ listener.set_gps(gps);
} catch (TimeoutException te) {
}
- state.set_gps(null, 0);
}
public AltosGPS (AltosLink link, AltosConfigData config_data) throws TimeoutException, InterruptedException {
diff --git a/altoslib/AltosGPSSat.java b/altoslib/AltosGPSSat.java
index e2f0f380..8d3b316a 100644
--- a/altoslib/AltosGPSSat.java
+++ b/altoslib/AltosGPSSat.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.text.*;
diff --git a/altoslib/AltosGPSTimeValue.java b/altoslib/AltosGPSTimeValue.java
new file mode 100644
index 00000000..e15c60e3
--- /dev/null
+++ b/altoslib/AltosGPSTimeValue.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright © 2017 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_12;
+
+public class AltosGPSTimeValue {
+ public double time;
+ public AltosGPS gps;
+
+ public AltosGPSTimeValue(double time, AltosGPS gps) {
+ this.time = time;
+ this.gps = gps;
+ }
+}
diff --git a/altoslib/AltosGreatCircle.java b/altoslib/AltosGreatCircle.java
index 6e5bd362..f1cb1940 100644
--- a/altoslib/AltosGreatCircle.java
+++ b/altoslib/AltosGreatCircle.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.lang.Math;
import java.io.*;
diff --git a/altoslib/AltosHeight.java b/altoslib/AltosHeight.java
index 0cd495fb..668080f1 100644
--- a/altoslib/AltosHeight.java
+++ b/altoslib/AltosHeight.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosHeight extends AltosUnits {
diff --git a/altoslib/AltosHexfile.java b/altoslib/AltosHexfile.java
index e746b649..7ab121ad 100644
--- a/altoslib/AltosHexfile.java
+++ b/altoslib/AltosHexfile.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.LinkedList;
diff --git a/altoslib/AltosHexsym.java b/altoslib/AltosHexsym.java
index 2eb08f75..4f56af9a 100644
--- a/altoslib/AltosHexsym.java
+++ b/altoslib/AltosHexsym.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosHexsym {
String name;
diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java
index f6cadf1d..dee28a92 100644
--- a/altoslib/AltosIMU.java
+++ b/altoslib/AltosIMU.java
@@ -16,30 +16,32 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.*;
import java.io.*;
public class AltosIMU implements Cloneable {
- public int accel_along;
- public int accel_across;
- public int accel_through;
+ public int accel_x;
+ public int accel_y;
+ public int accel_z;
- public int gyro_roll;
- public int gyro_pitch;
- public int gyro_yaw;
+ public int gyro_x;
+ public int gyro_y;
+ public int gyro_z;
public static final double counts_per_g = 2048.0;
public static double convert_accel(double counts) {
- return counts / counts_per_g * (-AltosConvert.GRAVITATIONAL_ACCELERATION);
+ return counts / counts_per_g * AltosConvert.gravity;
}
- public static final double counts_per_degsec = 16.4;
+ /* In radians */
+ public static final double GYRO_FULLSCALE_DEGREES = 2000.0;
+ public static final double GYRO_COUNTS = 32767.0;
- public static double convert_gyro(double counts) {
- return counts / counts_per_degsec;
+ public static double gyro_degrees_per_second(double counts, double cal) {
+ return (counts - cal) * GYRO_FULLSCALE_DEGREES / GYRO_COUNTS;
}
public boolean parse_string(String line) {
@@ -49,12 +51,12 @@ public class AltosIMU implements Cloneable {
String[] items = line.split("\\s+");
if (items.length >= 8) {
- accel_along = Integer.parseInt(items[1]);
- accel_across = Integer.parseInt(items[2]);
- accel_through = Integer.parseInt(items[3]);
- gyro_roll = Integer.parseInt(items[5]);
- gyro_pitch = Integer.parseInt(items[6]);
- gyro_yaw = Integer.parseInt(items[7]);
+ accel_x = Integer.parseInt(items[1]);
+ accel_y = Integer.parseInt(items[2]);
+ accel_z = Integer.parseInt(items[3]);
+ gyro_x = Integer.parseInt(items[5]);
+ gyro_y = Integer.parseInt(items[6]);
+ gyro_z = Integer.parseInt(items[7]);
}
return true;
}
@@ -62,46 +64,41 @@ public class AltosIMU implements Cloneable {
public AltosIMU clone() {
AltosIMU n = new AltosIMU();
- n.accel_along = accel_along;
- n.accel_across = accel_across;
- n.accel_through = accel_through;
+ n.accel_x = accel_x;
+ n.accel_y = accel_y;
+ n.accel_z = accel_z;
- n.gyro_roll = gyro_roll;
- n.gyro_pitch = gyro_pitch;
- n.gyro_yaw = gyro_yaw;
+ n.gyro_x = gyro_x;
+ n.gyro_y = gyro_y;
+ n.gyro_z = gyro_z;
return n;
}
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosIMU imu = new AltosIMU(link);
-
- if (imu != null)
- state.set_imu(imu);
+ AltosCalData cal_data = listener.cal_data();
+
+ if (imu != null) {
+ listener.set_gyro(cal_data.gyro_roll(imu.gyro_y),
+ cal_data.gyro_pitch(imu.gyro_x),
+ cal_data.gyro_yaw(imu.gyro_z));
+ listener.set_accel_ground(cal_data.accel_along(imu.accel_y),
+ cal_data.accel_across(imu.accel_x),
+ cal_data.accel_through(imu.accel_z));
+ }
} catch (TimeoutException te) {
}
}
public AltosIMU() {
- accel_along = AltosLib.MISSING;
- accel_across = AltosLib.MISSING;
- accel_through = AltosLib.MISSING;
-
- gyro_roll = AltosLib.MISSING;
- gyro_pitch = AltosLib.MISSING;
- gyro_yaw = AltosLib.MISSING;
- }
-
- public AltosIMU(int accel_along, int accel_across, int accel_through,
- int gyro_roll, int gyro_pitch, int gyro_yaw) {
-
- this.accel_along = accel_along;
- this.accel_across = accel_across;
- this.accel_through = accel_through;
+ accel_x = AltosLib.MISSING;
+ accel_y = AltosLib.MISSING;
+ accel_z = AltosLib.MISSING;
- this.gyro_roll = gyro_roll;
- this.gyro_pitch = gyro_pitch;
- this.gyro_yaw = gyro_yaw;
+ gyro_x = AltosLib.MISSING;
+ gyro_y = AltosLib.MISSING;
+ gyro_z = AltosLib.MISSING;
}
public AltosIMU(AltosLink link) throws InterruptedException, TimeoutException {
diff --git a/altoslib/AltosIdle.java b/altoslib/AltosIdle.java
index d37af966..b5ee20d0 100644
--- a/altoslib/AltosIdle.java
+++ b/altoslib/AltosIdle.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
diff --git a/altoslib/AltosIdleFetch.java b/altoslib/AltosIdleFetch.java
index 73717e17..058df0a1 100644
--- a/altoslib/AltosIdleFetch.java
+++ b/altoslib/AltosIdleFetch.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
@@ -30,61 +30,62 @@ class AltosIdler {
static final int idle_gps = 0;
static final int idle_imu = 1;
static final int idle_mag = 2;
- static final int idle_ms5607 = 3;
static final int idle_mma655x = 4;
+ static final int idle_ms5607 = 5;
static final int idle_sensor_tm = 10;
static final int idle_sensor_metrum = 11;
static final int idle_sensor_mega = 12;
- static final int idle_sensor_emini = 13;
- static final int idle_sensor_tmini2 = 14;
- static final int idle_sensor_tgps = 15;
- static final int idle_sensor_tmini3 = 16;
+ static final int idle_sensor_emini1 = 13;
+ static final int idle_sensor_emini2 = 14;
+ static final int idle_sensor_tmini2 = 15;
+ static final int idle_sensor_tgps = 16;
+ static final int idle_sensor_tmini3 = 17;
- public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException, TimeoutException, AltosUnknownProduct {
+ public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException, TimeoutException, AltosUnknownProduct {
for (int idler : idlers) {
- AltosIdle idle = null;
switch (idler) {
case idle_gps:
- AltosGPS.update_state(state, link, config_data);
+ AltosGPS.provide_data(listener, link);
break;
case idle_imu:
- AltosIMU.update_state(state, link, config_data);
+ AltosIMU.provide_data(listener, link);
break;
case idle_mag:
- AltosMag.update_state(state, link, config_data);
- break;
- case idle_ms5607:
- AltosMs5607.update_state(state, link, config_data);
+ AltosMag.provide_data(listener, link);
break;
case idle_mma655x:
- AltosMma655x.update_state(state, link, config_data);
+ AltosMma655x.provide_data(listener, link);
+ break;
+ case idle_ms5607:
+ AltosMs5607.provide_data(listener, link);
break;
case idle_sensor_tm:
- AltosSensorTM.update_state(state, link, config_data);
+ AltosSensorTM.provide_data(listener, link);
break;
case idle_sensor_metrum:
- AltosSensorMetrum.update_state(state, link, config_data);
+ AltosSensorMetrum.provide_data(listener, link);
break;
case idle_sensor_mega:
- AltosSensorMega.update_state(state, link, config_data);
+ AltosSensorMega.provide_data(listener, link);
+ break;
+ case idle_sensor_emini1:
+ AltosSensorEMini.provide_data(listener, link, 1);
break;
- case idle_sensor_emini:
- AltosSensorEMini.update_state(state, link, config_data);
+ case idle_sensor_emini2:
+ AltosSensorEMini.provide_data(listener, link, 2);
break;
case idle_sensor_tmini2:
- AltosSensorTMini2.update_state(state, link, config_data);
+ AltosSensorTMini2.provide_data(listener, link);
break;
case idle_sensor_tgps:
- AltosSensorTGPS.update_state(state, link, config_data);
+ AltosSensorTGPS.provide_data(listener, link);
break;
case idle_sensor_tmini3:
- AltosSensorTMini3.update_state(state, link, config_data);
+ AltosSensorTMini3.provide_data(listener, link);
break;
}
- if (idle != null)
- idle.update_state(state);
}
}
@@ -99,13 +100,17 @@ class AltosIdler {
}
-public class AltosIdleFetch implements AltosStateUpdate {
+public class AltosIdleFetch implements AltosDataProvider {
static final AltosIdler[] idlers = {
- new AltosIdler("EasyMini",
+ new AltosIdler("EasyMini-v1",
AltosIdler.idle_ms5607,
- AltosIdler.idle_sensor_emini),
+ AltosIdler.idle_sensor_emini1),
+
+ new AltosIdler("EasyMini-v2",
+ AltosIdler.idle_ms5607,
+ AltosIdler.idle_sensor_emini2),
new AltosIdler("TeleMini-v1",
AltosIdler.idle_sensor_tm),
@@ -124,16 +129,19 @@ public class AltosIdleFetch implements AltosStateUpdate {
new AltosIdler("TeleMetrum-v2",
AltosIdler.idle_gps,
- AltosIdler.idle_ms5607, AltosIdler.idle_mma655x,
+ AltosIdler.idle_mma655x,
+ AltosIdler.idle_ms5607,
AltosIdler.idle_sensor_metrum),
new AltosIdler("TeleMega",
AltosIdler.idle_gps,
- AltosIdler.idle_ms5607, AltosIdler.idle_mma655x,
+ AltosIdler.idle_mma655x,
+ AltosIdler.idle_ms5607,
AltosIdler.idle_imu, AltosIdler.idle_mag,
AltosIdler.idle_sensor_mega),
new AltosIdler("EasyMega",
- AltosIdler.idle_ms5607, AltosIdler.idle_mma655x,
+ AltosIdler.idle_mma655x,
+ AltosIdler.idle_ms5607,
AltosIdler.idle_imu, AltosIdler.idle_mag,
AltosIdler.idle_sensor_mega),
new AltosIdler("TeleGPS",
@@ -143,29 +151,22 @@ public class AltosIdleFetch implements AltosStateUpdate {
AltosLink link;
- public void update_state(AltosState state) throws InterruptedException, AltosUnknownProduct {
+ public void provide_data(AltosDataListener listener) throws InterruptedException, AltosUnknownProduct {
try {
boolean matched = false;
/* Fetch config data from remote */
AltosConfigData config_data = new AltosConfigData(link);
- state.set_state(AltosLib.ao_flight_stateless);
- state.set_serial(config_data.serial);
- state.set_callsign(config_data.callsign);
- state.set_ground_accel(config_data.accel_cal_plus);
- state.set_accel_g(config_data.accel_cal_plus, config_data.accel_cal_minus);
- state.set_product(config_data.product);
- state.set_firmware_version(config_data.version);
- state.set_log_space(config_data.log_space);
+ listener.set_state(AltosLib.ao_flight_stateless);
for (AltosIdler idler : idlers) {
if (idler.matches(config_data)) {
- idler.update_state(state, link, config_data);
+ idler.provide_data(listener, link);
matched = true;
break;
}
}
if (!matched)
throw new AltosUnknownProduct(config_data.product);
- state.set_received_time(System.currentTimeMillis());
+ listener.set_received_time(System.currentTimeMillis());
} catch (TimeoutException te) {
}
diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java
index c374b601..fc5d4cc8 100644
--- a/altoslib/AltosIdleMonitor.java
+++ b/altoslib/AltosIdleMonitor.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.concurrent.*;
@@ -52,20 +52,20 @@ public class AltosIdleMonitor extends Thread {
return link.reply_abort;
}
- boolean update_state(AltosState state) throws InterruptedException, TimeoutException, AltosUnknownProduct {
+ boolean provide_data(AltosDataListener listener) throws InterruptedException, TimeoutException, AltosUnknownProduct {
boolean worked = false;
boolean aborted = false;
try {
start_link();
- fetch.update_state(state);
+ fetch.provide_data(listener);
if (!link.has_error && !link.reply_abort)
worked = true;
} finally {
aborted = stop_link();
if (worked) {
if (remote)
- state.set_rssi(link.rssi(), 0);
+ listener.set_rssi(link.rssi(), 0);
listener_state.battery = link.monitor_battery();
}
}
@@ -92,12 +92,14 @@ public class AltosIdleMonitor extends Thread {
}
public void run() {
- AltosState state = new AltosState();
+ AltosState state = null;
try {
for (;;) {
try {
link.config_data();
- update_state(state);
+ if (state == null)
+ state = new AltosState(new AltosCalData(link.config_data()));
+ provide_data(state);
listener.update(state, listener_state);
} catch (TimeoutException te) {
} catch (AltosUnknownProduct ae) {
diff --git a/altoslib/AltosIdleMonitorListener.java b/altoslib/AltosIdleMonitorListener.java
index 3349e9c4..1ddec09a 100644
--- a/altoslib/AltosIdleMonitorListener.java
+++ b/altoslib/AltosIdleMonitorListener.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosIdleMonitorListener {
public void update(AltosState state, AltosListenerState listener_state);
diff --git a/altoslib/AltosIdleReader.java b/altoslib/AltosIdleReader.java
index 5903c968..d15e2174 100644
--- a/altoslib/AltosIdleReader.java
+++ b/altoslib/AltosIdleReader.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.io.*;
@@ -25,6 +25,7 @@ import java.util.concurrent.*;
public class AltosIdleReader extends AltosFlightReader {
AltosLink link;
boolean remote;
+ AltosCalData cal_data = null;
AltosState state = null;
AltosIdleFetch fetch;
long next_millis;
@@ -44,15 +45,23 @@ public class AltosIdleReader extends AltosFlightReader {
return link.reply_abort;
}
+ public AltosCalData cal_data() {
+ if (cal_data == null) {
+ try {
+ cal_data = new AltosCalData(link.config_data());
+ } catch (InterruptedException ie) {
+ } catch (TimeoutException te) {
+ }
+ if (cal_data == null)
+ cal_data = new AltosCalData();
+ }
+ return cal_data;
+ }
+
public AltosState read() throws InterruptedException, ParseException, AltosCRCException, IOException {
boolean worked = false;
boolean aborted = false;
- if (state == null)
- state = new AltosState();
- else
- state = state.clone();
-
long delay = next_millis - System.currentTimeMillis();
if (delay > 0)
@@ -61,7 +70,9 @@ public class AltosIdleReader extends AltosFlightReader {
try {
try {
start_link();
- fetch.update_state(state);
+ if (state == null)
+ state = new AltosState(cal_data());
+ fetch.provide_data(state);
if (!link.has_error && !link.reply_abort)
worked = true;
} catch (TimeoutException te) {
diff --git a/altoslib/AltosIgnite.java b/altoslib/AltosIgnite.java
index cdc5c614..767c00fb 100644
--- a/altoslib/AltosIgnite.java
+++ b/altoslib/AltosIgnite.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.*;
import java.io.*;
@@ -102,7 +102,7 @@ public class AltosIgnite {
private void get_npyro() throws InterruptedException, TimeoutException {
if (config_data == null)
config_data = new AltosConfigData(link);
- if (config_data != null)
+ if (config_data != null && config_data.npyro != AltosLib.MISSING)
npyro = config_data.npyro;
else
npyro = 0;
@@ -174,6 +174,7 @@ public class AltosIgnite {
try {
start_link();
link.printf("i DoIt %s\n", igniter);
+ link.flush_output();
} catch (TimeoutException te) {
} finally {
stop_link();
diff --git a/altoslib/AltosImage.java b/altoslib/AltosImage.java
index 2e32b720..abe9d56f 100644
--- a/altoslib/AltosImage.java
+++ b/altoslib/AltosImage.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
diff --git a/altoslib/AltosJson.java b/altoslib/AltosJson.java
index 22f81d03..52c9b41e 100644
--- a/altoslib/AltosJson.java
+++ b/altoslib/AltosJson.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
@@ -25,39 +25,39 @@ import java.lang.*;
import java.lang.reflect.*;
class JsonUtil {
- StringBuffer quote(StringBuffer result, String a) {
- result.append("\"");
+ Writer quote(Writer writer, String a) throws IOException {
+ writer.append("\"");
for (int i = 0; i < a.length(); i++) {
char c = a.charAt(i);
switch (c) {
case '"':
case '\\':
- result.append('\\').append(c);
+ writer.append('\\').append(c);
break;
case '\n':
- result.append("\\n");
+ writer.append("\\n");
break;
default:
- result.append(c);
+ writer.append(c);
break;
}
}
- result.append("\"");
- return result;
+ writer.append("\"");
+ return writer;
}
- StringBuffer append(StringBuffer result, AltosJson value, int indent, boolean pretty) {
+ Writer append(Writer result, AltosJson value, int indent, boolean pretty) throws IOException {
value.append(result, indent, pretty);
return result;
}
- StringBuffer append(StringBuffer result, String string) {
+ Writer append(Writer result, String string) throws IOException {
result.append(string);
return result;
}
- StringBuffer indent(StringBuffer result, int indent) {
+ Writer indent(Writer result, int indent) throws IOException {
result.append("\n");
for (int i = 0; i < indent; i++)
result.append("\t");
@@ -80,7 +80,7 @@ class JsonUtil {
class JsonHash extends JsonUtil {
Hashtable<String,AltosJson> hash;
- void append_hash(StringBuffer result, int indent, boolean pretty) {
+ void append_hash(Writer result, int indent, boolean pretty) throws IOException {
boolean first = true;
result.append("{");
@@ -125,7 +125,7 @@ class JsonHash extends JsonUtil {
class JsonArray extends JsonUtil {
ArrayList<AltosJson> array;
- void append_array(StringBuffer result, int indent, boolean pretty) {
+ void append_array(Writer result, int indent, boolean pretty) throws IOException {
boolean first = true;
append(result, "[");
@@ -185,6 +185,7 @@ class JsonToken {
static final int _colon = 9;
static final int _end = 10;
static final int _error = 11;
+ static final int _none = 12;
static String token_name(int token) {
switch (token) {
@@ -245,7 +246,7 @@ class JsonToken {
this.sval = sval;
}
- JsonToken(int token, StringBuffer bval) {
+ JsonToken(int token, Writer bval) {
this(token, bval.toString());
}
}
@@ -254,11 +255,11 @@ class JsonToken {
* Lexer for json
*/
class JsonLexer extends JsonUtil {
- StringReader f;
- int line;
- int ungot = -2;
- StringBuffer pending_token;
- JsonToken token;
+ InputStream f;
+ int line;
+ int ungot = -2;
+ StringBuffer pending_token;
+ private JsonToken token;
static class keyword {
String word;
@@ -382,7 +383,7 @@ class JsonLexer extends JsonUtil {
return new JsonToken(JsonToken._long, lval);
}
case '"':
- StringBuffer bval = new StringBuffer();
+ Writer bval = new StringWriter();
for (;;) {
c = ch();
if (c == '"')
@@ -400,7 +401,7 @@ class JsonLexer extends JsonUtil {
break;
}
}
- bval.appendCodePoint(c);
+ bval.write(c);
}
return new JsonToken(JsonToken._string, bval);
default:
@@ -424,11 +425,17 @@ class JsonLexer extends JsonUtil {
}
void next() {
- token = lex();
+ token = null;
+ }
+
+ JsonToken token() {
+ if (token == null)
+ token = lex();
+ return token;
}
JsonToken expect(int e) {
- JsonToken t = token;
+ JsonToken t = token();
if (t.token != e)
throw new IllegalArgumentException(String.format("got \"%s\" while expecting \"%s\"",
token.token_name(),
@@ -438,7 +445,13 @@ class JsonLexer extends JsonUtil {
}
JsonLexer(String s) {
- f = new StringReader(s);
+ f = new AltosStringInputStream(s);
+ line = 1;
+ token = null;
+ }
+
+ JsonLexer(InputStream f) {
+ this.f = f;
line = 1;
token = null;
}
@@ -464,7 +477,7 @@ class JsonParse {
lexer.next();
for (;;) {
/* Allow for empty hashes */
- if (lexer.token.token == JsonToken._cc) {
+ if (lexer.token().token == JsonToken._cc) {
lexer.next();
return hash;
}
@@ -475,7 +488,7 @@ class JsonParse {
AltosJson value = value();
hash.put(key, value);
- switch (lexer.token.token) {
+ switch (lexer.token().token) {
case JsonToken._comma:
lexer.next();
break;
@@ -483,7 +496,7 @@ class JsonParse {
lexer.next();
return hash;
default:
- parse_error("got %s expect \",\" or \"}\"", lexer.token.token_name());
+ parse_error("got %s expect \",\" or \"}\"", lexer.token().token_name());
return null;
}
}
@@ -496,14 +509,14 @@ class JsonParse {
lexer.next();
for (int i = 0;; i++) {
/* Allow for empty arrays */
- if (lexer.token.token == JsonToken._cs) {
+ if (lexer.token().token == JsonToken._cs) {
lexer.next();
return array;
}
AltosJson value = value();
array.put(i, value);
- switch (lexer.token.token) {
+ switch (lexer.token().token) {
case JsonToken._comma:
lexer.next();
break;
@@ -511,7 +524,7 @@ class JsonParse {
lexer.next();
return array;
default:
- parse_error("got %s expect \",\" or \"]\"", lexer.token.token_name());
+ parse_error("got %s expect \",\" or \"]\"", lexer.token().token_name());
return null;
}
}
@@ -521,29 +534,29 @@ class JsonParse {
* identify the next object in the input
*/
AltosJson value() {
- switch (lexer.token.token) {
+ switch (lexer.token().token) {
case JsonToken._oc:
return new AltosJson(hash());
case JsonToken._os:
return new AltosJson(array());
case JsonToken._double:
- double dval = lexer.token.dval;
+ double dval = lexer.token().dval;
lexer.next();
return new AltosJson(dval);
case JsonToken._long:
- long lval = lexer.token.lval;
+ long lval = lexer.token().lval;
lexer.next();
return new AltosJson(lval);
case JsonToken._string:
- String sval = lexer.token.sval;
+ String sval = lexer.token().sval;
lexer.next();
return new AltosJson(sval);
case JsonToken._boolean:
- boolean bval = lexer.token.bval;
+ boolean bval = lexer.token().bval;
lexer.next();
return new AltosJson(bval);
default:
- parse_error("Unexpected token \"%s\"", lexer.token.token_name());
+ parse_error("Unexpected token \"%s\"", lexer.token().token_name());
}
return null;
}
@@ -556,6 +569,10 @@ class JsonParse {
JsonParse(String s) {
lexer = new JsonLexer(s);
}
+
+ JsonParse(InputStream f) {
+ lexer = new JsonLexer(f);
+ }
}
public class AltosJson extends JsonUtil {
@@ -578,7 +595,7 @@ public class AltosJson extends JsonUtil {
/* Generate string representation of the value
*/
- StringBuffer append(StringBuffer result, int indent, boolean pretty) {
+ Writer append(Writer result, int indent, boolean pretty) throws IOException {
switch (type) {
case type_hash:
hash.append_hash(result, indent, pretty);
@@ -615,9 +632,13 @@ public class AltosJson extends JsonUtil {
}
private String toString(int indent, boolean pretty) {
- StringBuffer result = new StringBuffer();
- append(result, indent, pretty);
- return result.toString();
+ try {
+ Writer result = new StringWriter();
+ append(result, indent, pretty);
+ return result.toString();
+ } catch (Exception e) {
+ return null;
+ }
}
public String toString() {
@@ -628,6 +649,14 @@ public class AltosJson extends JsonUtil {
return toString(0, true);
}
+ public void write(Writer w, int indent, boolean pretty) throws IOException {
+ append(w, indent, pretty);
+ }
+
+ public void write(Writer w) throws IOException {
+ write(w, 0, true);
+ }
+
/* Parse string representation to a value
*/
@@ -641,6 +670,16 @@ public class AltosJson extends JsonUtil {
}
}
+ public static AltosJson fromInputStream(InputStream f) {
+ JsonParse parse = new JsonParse(f);
+ try {
+ return parse.parse();
+ } catch (IllegalArgumentException ie) {
+ System.out.printf("json:\n%s\n", ie.getMessage());
+ return null;
+ }
+ }
+
/* Accessor functions
*/
private boolean assert_type(boolean setting, int type, int other_type, String error) {
@@ -1213,6 +1252,10 @@ public class AltosJson extends JsonUtil {
for (Field field : c.getDeclaredFields()) {
String fieldName = field.getName();
+ /* XXX hack to allow fields to be not converted */
+ if (fieldName.startsWith("__"))
+ continue;
+
/* Skip static fields */
if (Modifier.isStatic(field.getModifiers()))
continue;
diff --git a/altoslib/AltosKML.java b/altoslib/AltosKML.java
index 25108bf9..587b845b 100644
--- a/altoslib/AltosKML.java
+++ b/altoslib/AltosKML.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
@@ -36,8 +36,9 @@ public class AltosKML implements AltosWriter {
File name;
PrintWriter out;
int flight_state = -1;
- AltosState prev = null;
- double gps_start_altitude;
+ AltosGPS prev = null;
+ double gps_start_altitude = AltosLib.MISSING;
+ AltosFlightStats stats;
static final String[] kml_state_colors = {
"FF000000", // startup
@@ -101,42 +102,47 @@ public class AltosKML implements AltosWriter {
"</Document>\n" +
"</kml>\n";
- void start (AltosState record) {
- out.printf(kml_header_start, record.flight, record.serial);
+ void start (AltosCalData cal_data) {
+ AltosGPS gps = cal_data.gps_pad;
+
+ gps_start_altitude = cal_data.gps_pad_altitude;
+ out.printf(kml_header_start, cal_data.flight, cal_data.serial);
out.printf("Date: %04d-%02d-%02d\n",
- record.gps.year, record.gps.month, record.gps.day);
+ gps.year, gps.month, gps.day);
out.printf("Time: %2d:%02d:%02d\n",
- record.gps.hour, record.gps.minute, record.gps.second);
+ gps.hour, gps.minute, gps.second);
out.printf("%s", kml_header_end);
}
boolean started = false;
- void state_start(AltosState state) {
- String state_name = AltosLib.state_name(state.state());
- String state_color = state_color(state.state());
+ void state_start(int state) {
+ String state_name = AltosLib.state_name(state);
+ String state_color = state_color(state);
out.printf(kml_style_start, state_name, state_color);
- out.printf("\tState: %s\n", state_name);
+ out.printf("State: %s\n", state_name);
+ out.printf("Time: %6.2f s\n", stats.state_time[state]);
+ out.printf("Average speed: %s\n", AltosConvert.speed.show(6, stats.state_speed[state]));
+ out.printf("Average accel: %s\n", AltosConvert.accel.show(6, stats.state_accel[state]));
out.printf("%s", kml_style_end);
out.printf(kml_placemark_start, state_name, state_name);
}
- void state_end(AltosState state) {
+ void state_end() {
out.printf("%s", kml_placemark_end);
}
- void coord(AltosState state) {
- AltosGPS gps = state.gps;
+ void coord(double time, AltosGPS gps, int state, double height) {
double altitude;
- if (state.height() != AltosLib.MISSING)
- altitude = state.height() + gps_start_altitude;
+ if (height != AltosLib.MISSING)
+ altitude = height + gps_start_altitude;
else
altitude = gps.alt;
out.printf(kml_coord_fmt,
gps.lon, gps.lat,
altitude, (double) gps.alt,
- state.time, gps.nsat);
+ time, gps.nsat);
}
void end() {
@@ -145,7 +151,7 @@ public class AltosKML implements AltosWriter {
public void close() {
if (prev != null) {
- state_end(prev);
+ state_end();
end();
prev = null;
}
@@ -155,40 +161,37 @@ public class AltosKML implements AltosWriter {
}
}
- public void write(AltosState state) {
- AltosGPS gps = state.gps;
-
- if (gps == null)
- return;
-
+ public void write(AltosGPSTimeValue gtv, AltosCalData cal_data, int state, double height) {
+ AltosGPS gps = gtv.gps;
if (gps.lat == AltosLib.MISSING)
return;
if (gps.lon == AltosLib.MISSING)
return;
- if (!started) {
- start(state);
- started = true;
- gps_start_altitude = gps.alt;
- }
- if (prev != null && prev.gps_sequence == state.gps_sequence)
- return;
- if (state.state() != flight_state) {
- flight_state = state.state();
+ if (state != flight_state) {
+ flight_state = state;
if (prev != null) {
- coord(state);
- state_end(prev);
+ coord(gtv.time, gps, state, height);
+ state_end();
}
state_start(state);
}
- coord(state);
- prev = state;
+ coord(0, gps, state, height);
+ prev = gps;
}
- public void write(AltosStateIterable states) {
- for (AltosState state : states) {
- if ((state.set & AltosState.set_gps) != 0)
- write(state);
- }
+ private int state(AltosFlightSeries series, double time) {
+ return (int) series.value_before(AltosFlightSeries.state_name, time);
+ }
+
+ private double height(AltosFlightSeries series, double time) {
+ return series.value(AltosFlightSeries.height_name, time);
+ }
+
+ public void write(AltosFlightSeries series) {
+ stats = new AltosFlightStats(series);
+ start(series.cal_data());
+ for (AltosGPSTimeValue gtv : series.gps_series)
+ write(gtv, series.cal_data(), state(series, gtv.time), height(series, gtv.time));
}
public AltosKML(File in_name) throws FileNotFoundException {
diff --git a/altoslib/AltosLatLon.java b/altoslib/AltosLatLon.java
index 5865d3cc..6fcc43fe 100644
--- a/altoslib/AltosLatLon.java
+++ b/altoslib/AltosLatLon.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosLatLon {
public double lat;
diff --git a/altoslib/AltosLatitude.java b/altoslib/AltosLatitude.java
index 4663cd09..f43397d0 100644
--- a/altoslib/AltosLatitude.java
+++ b/altoslib/AltosLatitude.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosLatitude extends AltosLocation {
public String pos() { return "N"; }
diff --git a/altoslib/AltosLaunchSite.java b/altoslib/AltosLaunchSite.java
index 8a06cdb2..19fb4858 100644
--- a/altoslib/AltosLaunchSite.java
+++ b/altoslib/AltosLaunchSite.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.*;
diff --git a/altoslib/AltosLaunchSiteListener.java b/altoslib/AltosLaunchSiteListener.java
index d2ee601e..0d926353 100644
--- a/altoslib/AltosLaunchSiteListener.java
+++ b/altoslib/AltosLaunchSiteListener.java
@@ -15,7 +15,7 @@
* 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_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.*;
diff --git a/altoslib/AltosLaunchSites.java b/altoslib/AltosLaunchSites.java
index d5c41c82..365f19e3 100644
--- a/altoslib/AltosLaunchSites.java
+++ b/altoslib/AltosLaunchSites.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.*;
diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java
index a3f164d4..d1063509 100644
--- a/altoslib/AltosLib.java
+++ b/altoslib/AltosLib.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.*;
import java.io.*;
@@ -38,6 +38,20 @@ public class AltosLib {
public static final int AO_LOG_GPS_DATE = 'Y';
public static final int AO_LOG_PRESSURE = 'P';
+ public static boolean is_gps_cmd(int cmd) {
+ switch (cmd) {
+ case AltosLib.AO_LOG_GPS_POS:
+ case AltosLib.AO_LOG_GPS_TIME:
+ case AltosLib.AO_LOG_GPS_LAT:
+ case AltosLib.AO_LOG_GPS_LON:
+ case AltosLib.AO_LOG_GPS_ALT:
+ case AltosLib.AO_LOG_GPS_SAT:
+ case AltosLib.AO_LOG_GPS_DATE:
+ return true;
+ }
+ return false;
+ }
+
/* Added for header fields in eeprom files */
public static final int AO_LOG_CONFIG_VERSION = 1000;
public static final int AO_LOG_MAIN_DEPLOY = 1001;
@@ -162,6 +176,16 @@ public class AltosLib {
return product_any;
}
+ public static boolean has_9dof(int device_type) {
+ return device_type == product_telemega || device_type == product_easymega;
+ }
+
+ public static boolean has_gps(int device_type) {
+ return device_type == product_telemetrum ||
+ device_type == product_telemega ||
+ device_type == product_telegps;
+ }
+
/* Bluetooth "identifier" (bluetooth sucks) */
public final static String bt_product_telebt = "TeleBT";
@@ -330,7 +354,7 @@ public class AltosLib {
public static final int AO_LOG_FORMAT_TELEMETRY = 3;
public static final int AO_LOG_FORMAT_TELESCIENCE = 4;
public static final int AO_LOG_FORMAT_TELEMEGA_OLD = 5;
- public static final int AO_LOG_FORMAT_EASYMINI = 6;
+ public static final int AO_LOG_FORMAT_EASYMINI1 = 6;
public static final int AO_LOG_FORMAT_TELEMETRUM = 7;
public static final int AO_LOG_FORMAT_TELEMINI2 = 8;
public static final int AO_LOG_FORMAT_TELEGPS = 9;
@@ -338,6 +362,7 @@ public class AltosLib {
public static final int AO_LOG_FORMAT_DETHERM = 11;
public static final int AO_LOG_FORMAT_TELEMINI3 = 12;
public static final int AO_LOG_FORMAT_TELEFIRETWO = 13;
+ public static final int AO_LOG_FORMAT_EASYMINI2 = 14;
public static final int AO_LOG_FORMAT_NONE = 127;
public static boolean isspace(int c) {
@@ -561,7 +586,31 @@ public class AltosLib {
}
}
- public static String ignitor_name(int i) {
+ public static String igniter_name(int i) {
return String.format("Ignitor %c", 'A' + i);
}
+
+ public static AltosRecordSet record_set(File file) throws FileNotFoundException, IOException {
+ FileInputStream in;
+ in = new FileInputStream(file);
+ if (file.getName().endsWith("telem")) {
+ return new AltosTelemetryFile(in);
+ } else if (file.getName().endsWith("eeprom")) {
+ return new AltosEepromFile(in);
+ } else {
+ String name = file.getName();
+ int dot = name.lastIndexOf('.');
+ String extension;
+
+ if (dot == -1)
+ throw new IOException(String.format("%s (Missing extension)", file.toString()));
+ else {
+ extension = name.substring(dot);
+ throw new IOException(String.format("%s (Invalid extension '%s')",
+ file.toString(),
+ extension));
+ }
+ }
+ }
+
}
diff --git a/altoslib/AltosLine.java b/altoslib/AltosLine.java
index 952a21e3..b3833f64 100644
--- a/altoslib/AltosLine.java
+++ b/altoslib/AltosLine.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosLine {
public String line;
diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java
index 76a4eb31..5a802ef1 100644
--- a/altoslib/AltosLink.java
+++ b/altoslib/AltosLink.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.concurrent.*;
@@ -556,7 +556,7 @@ public abstract class AltosLink implements Runnable {
return AltosLib.MISSING;
double volts = AltosLib.MISSING;
- if (config_data.product.startsWith("TeleBT-v3")) {
+ if (config_data.product.startsWith("TeleBT-v3") || config_data.product.startsWith("TeleBT-v4")) {
volts = AltosConvert.tele_bt_3_battery(monitor_batt);
} else {
volts = AltosConvert.cc_battery_to_voltage(monitor_batt);
diff --git a/altoslib/AltosListenerState.java b/altoslib/AltosListenerState.java
index 80bc0df2..949d2271 100644
--- a/altoslib/AltosListenerState.java
+++ b/altoslib/AltosListenerState.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
diff --git a/altoslib/AltosLocation.java b/altoslib/AltosLocation.java
index c612caaa..45831004 100644
--- a/altoslib/AltosLocation.java
+++ b/altoslib/AltosLocation.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public abstract class AltosLocation extends AltosUnits {
diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java
index 6d873d78..44bea646 100644
--- a/altoslib/AltosLog.java
+++ b/altoslib/AltosLog.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.text.*;
@@ -61,8 +61,8 @@ public class AltosLog implements Runnable {
return file;
}
- boolean open (AltosState state) throws IOException, InterruptedException {
- AltosFile a = new AltosFile(state);
+ boolean open (AltosCalData cal_data) throws IOException, InterruptedException {
+ AltosFile a = new AltosFile(cal_data);
log_file = new FileWriter(a, true);
if (log_file != null) {
@@ -80,24 +80,31 @@ public class AltosLog implements Runnable {
public void run () {
try {
- AltosState state = new AltosState();
AltosConfigData receiver_config = link.config_data();
- state.set_receiver_serial(receiver_config.serial);
+ AltosCalData cal_data = new AltosCalData();
+ AltosState state = null;
+ cal_data.set_receiver_serial(receiver_config.serial);
for (;;) {
AltosLine line = input_queue.take();
if (line.line == null)
continue;
try {
AltosTelemetry telem = AltosTelemetry.parse(line.line);
- state = state.clone();
- telem.update_state(state);
- if (state.serial != serial || state.flight != flight || log_file == null)
+ if (state == null)
+ state = new AltosState(cal_data);
+ telem.provide_data(state);
+
+ if (cal_data.serial != serial ||
+ cal_data.flight != flight ||
+ log_file == null)
{
close_log_file();
- serial = state.serial;
- flight = state.flight;
- if (state.serial != AltosLib.MISSING && state.flight != AltosLib.MISSING)
- open(state);
+ serial = cal_data.serial;
+ flight = cal_data.flight;
+ state = null;
+ if (cal_data.serial != AltosLib.MISSING &&
+ cal_data.flight != AltosLib.MISSING)
+ open(cal_data);
}
} catch (ParseException pe) {
} catch (AltosCRCException ce) {
diff --git a/altoslib/AltosLongitude.java b/altoslib/AltosLongitude.java
index 4c6d1857..b2134cbb 100644
--- a/altoslib/AltosLongitude.java
+++ b/altoslib/AltosLongitude.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosLongitude extends AltosLocation {
public String pos() { return "E"; }
diff --git a/altoslib/AltosMag.java b/altoslib/AltosMag.java
index e89ec0de..0d8ec69f 100644
--- a/altoslib/AltosMag.java
+++ b/altoslib/AltosMag.java
@@ -16,15 +16,15 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.*;
import java.io.*;
public class AltosMag implements Cloneable {
- public int along;
- public int across;
- public int through;
+ public int x;
+ public int z;
+ public int y;
public static final double counts_per_gauss = 1090;
@@ -33,10 +33,6 @@ public class AltosMag implements Cloneable {
}
public boolean parse_string(String line) {
-// if (line.startsWith("Syntax error")) {
-// along = across = through = 0;
-// return true;
-// }
if (!line.startsWith("X:"))
return false;
@@ -44,9 +40,9 @@ public class AltosMag implements Cloneable {
String[] items = line.split("\\s+");
if (items.length >= 6) {
- along = Integer.parseInt(items[1]);
- across = Integer.parseInt(items[3]);
- through = Integer.parseInt(items[5]);
+ x = Integer.parseInt(items[1]);
+ z = Integer.parseInt(items[3]);
+ y = Integer.parseInt(items[5]);
}
return true;
}
@@ -54,30 +50,27 @@ public class AltosMag implements Cloneable {
public AltosMag clone() {
AltosMag n = new AltosMag();
- n.along = along;
- n.across = across;
- n.through = through;
+ n.x = x;
+ n.z = z;
+ n.y = y;
return n;
}
public AltosMag() {
- along = AltosLib.MISSING;
- across = AltosLib.MISSING;
- through = AltosLib.MISSING;
+ x = AltosLib.MISSING;
+ z = AltosLib.MISSING;
+ y = AltosLib.MISSING;
}
- public AltosMag(int along, int across, int through) {
- this.along = along;
- this.across = across;
- this.through = through;
- }
-
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosMag mag = new AltosMag(link);
+ AltosCalData cal_data = listener.cal_data();
if (mag != null)
- state.set_mag(mag);
+ listener.set_mag(cal_data.mag_along(mag.y),
+ cal_data.mag_across(mag.x),
+ cal_data.mag_through(mag.z));
} catch (TimeoutException te) {
}
}
diff --git a/altoslib/AltosMap.java b/altoslib/AltosMap.java
index e3c4a6a7..286cf1bb 100644
--- a/altoslib/AltosMap.java
+++ b/altoslib/AltosMap.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.*;
@@ -220,11 +220,11 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
return false;
}
- public void show(AltosState state, AltosListenerState listener_state) {
+ public void show(AltosGPS gps, int state) {
- /* If insufficient gps data, nothing to update
+ /*
+ * If insufficient gps data, nothing to update
*/
- AltosGPS gps = state.gps;
if (gps == null)
return;
@@ -232,23 +232,23 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
if (!gps.locked && gps.nsat < 4)
return;
- switch (state.state()) {
+ switch (state) {
case AltosLib.ao_flight_boost:
if (!have_boost) {
- add_mark(gps.lat, gps.lon, state.state());
+ add_mark(gps.lat, gps.lon, state);
have_boost = true;
}
break;
case AltosLib.ao_flight_landed:
if (!have_landed) {
- add_mark(gps.lat, gps.lon, state.state());
+ add_mark(gps.lat, gps.lon, state);
have_landed = true;
}
break;
}
if (path != null) {
- AltosMapRectangle damage = path.add(gps.lat, gps.lon, state.state());
+ AltosMapRectangle damage = path.add(gps.lat, gps.lon, state);
if (damage != null)
repaint(damage, AltosMapPath.stroke_width);
@@ -259,6 +259,10 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
maybe_centre(gps.lat, gps.lon);
}
+ public void show(AltosState state, AltosListenerState listener_state) {
+ show(state.gps, state.state());
+ }
+
public void centre(AltosLatLon lat_lon) {
centre = lat_lon;
set_transform();
@@ -268,10 +272,14 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
centre(new AltosLatLon(lat, lon));
}
- public void centre(AltosState state) {
- if (!state.gps.locked && state.gps.nsat < 4)
+ public void centre(AltosGPS gps) {
+ if (!gps.locked && gps.nsat < 4)
return;
- centre(state.gps.lat, state.gps.lon);
+ centre(gps.lat, gps.lon);
+ }
+
+ public void centre(AltosState state) {
+ centre(state.gps);
}
public void maybe_centre(double lat, double lon) {
diff --git a/altoslib/AltosMapCache.java b/altoslib/AltosMapCache.java
index 4e529177..54d2dbdd 100644
--- a/altoslib/AltosMapCache.java
+++ b/altoslib/AltosMapCache.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.net.*;
diff --git a/altoslib/AltosMapCacheListener.java b/altoslib/AltosMapCacheListener.java
index 057d1c43..8c07e3c1 100644
--- a/altoslib/AltosMapCacheListener.java
+++ b/altoslib/AltosMapCacheListener.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosMapCacheListener {
public void map_cache_changed(int map_cache);
diff --git a/altoslib/AltosMapInterface.java b/altoslib/AltosMapInterface.java
index a2ea81db..5089db64 100644
--- a/altoslib/AltosMapInterface.java
+++ b/altoslib/AltosMapInterface.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.net.*;
diff --git a/altoslib/AltosMapLine.java b/altoslib/AltosMapLine.java
index c475f52d..f2174935 100644
--- a/altoslib/AltosMapLine.java
+++ b/altoslib/AltosMapLine.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.Math;
@@ -44,39 +44,9 @@ public abstract class AltosMapLine {
}
public String line_dist() {
- String format;
AltosGreatCircle g = new AltosGreatCircle(start.lat, start.lon,
end.lat, end.lon);
- double distance = g.distance;
- if (AltosConvert.imperial_units) {
- distance = AltosConvert.meters_to_feet(distance);
- if (distance < 1000) {
- format = "%4.0fft";
- } else {
- distance /= 5280;
- if (distance < 10)
- format = "%5.3fmi";
- else if (distance < 100)
- format = "%5.2fmi";
- else if (distance < 1000)
- format = "%5.1fmi";
- else
- format = "%5.0fmi";
- }
- } else {
- if (distance < 1000) {
- format = "%4.0fm";
- } else {
- distance /= 1000;
- if (distance < 100)
- format = "%5.2fkm";
- else if (distance < 1000)
- format = "%5.1fkm";
- else
- format = "%5.0fkm";
- }
- }
- return String.format(format, distance);
+ return AltosConvert.distance.show(7, g.distance);
}
}
diff --git a/altoslib/AltosMapLoader.java b/altoslib/AltosMapLoader.java
index 17e88bf4..b57591df 100644
--- a/altoslib/AltosMapLoader.java
+++ b/altoslib/AltosMapLoader.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
diff --git a/altoslib/AltosMapLoaderListener.java b/altoslib/AltosMapLoaderListener.java
index 07624f80..7f36c002 100644
--- a/altoslib/AltosMapLoaderListener.java
+++ b/altoslib/AltosMapLoaderListener.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosMapLoaderListener {
public abstract void loader_start(int max);
diff --git a/altoslib/AltosMapMark.java b/altoslib/AltosMapMark.java
index cbe7bebe..4ef179ef 100644
--- a/altoslib/AltosMapMark.java
+++ b/altoslib/AltosMapMark.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.Math;
diff --git a/altoslib/AltosMapPath.java b/altoslib/AltosMapPath.java
index c2335169..1542a4e9 100644
--- a/altoslib/AltosMapPath.java
+++ b/altoslib/AltosMapPath.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.Math;
diff --git a/altoslib/AltosMapPathPoint.java b/altoslib/AltosMapPathPoint.java
index 5182ecfd..409a6a5c 100644
--- a/altoslib/AltosMapPathPoint.java
+++ b/altoslib/AltosMapPathPoint.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.Math;
diff --git a/altoslib/AltosMapRectangle.java b/altoslib/AltosMapRectangle.java
index a2321e19..0751aa33 100644
--- a/altoslib/AltosMapRectangle.java
+++ b/altoslib/AltosMapRectangle.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosMapRectangle {
AltosLatLon ul, lr;
diff --git a/altoslib/AltosMapStore.java b/altoslib/AltosMapStore.java
index 7cce05a5..4eba3a04 100644
--- a/altoslib/AltosMapStore.java
+++ b/altoslib/AltosMapStore.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.net.*;
@@ -91,6 +91,7 @@ public class AltosMapStore {
static Object forbidden_lock = new Object();
static long forbidden_time;
static boolean forbidden_set;
+ public static int forbidden_response;
private int fetch_url() {
URL u;
@@ -116,6 +117,7 @@ public class AltosMapStore {
synchronized (forbidden_lock) {
forbidden_time = System.nanoTime();
forbidden_set = true;
+ forbidden_response = response;
return AltosMapTile.forbidden;
}
}
diff --git a/altoslib/AltosMapStoreListener.java b/altoslib/AltosMapStoreListener.java
index e3935201..1fb7194a 100644
--- a/altoslib/AltosMapStoreListener.java
+++ b/altoslib/AltosMapStoreListener.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosMapStoreListener {
abstract void notify_store(AltosMapStore store, int status);
diff --git a/altoslib/AltosMapTile.java b/altoslib/AltosMapTile.java
index 4d6dc8d1..4b01e437 100644
--- a/altoslib/AltosMapTile.java
+++ b/altoslib/AltosMapTile.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
diff --git a/altoslib/AltosMapTileListener.java b/altoslib/AltosMapTileListener.java
index 219dcd07..3c6275a0 100644
--- a/altoslib/AltosMapTileListener.java
+++ b/altoslib/AltosMapTileListener.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosMapTileListener {
abstract public void notify_tile(AltosMapTile tile, int status);
diff --git a/altoslib/AltosMapTransform.java b/altoslib/AltosMapTransform.java
index 266557b6..b6d4f435 100644
--- a/altoslib/AltosMapTransform.java
+++ b/altoslib/AltosMapTransform.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.Math;
diff --git a/altoslib/AltosMapTypeListener.java b/altoslib/AltosMapTypeListener.java
index 1d5e2b47..94401a00 100644
--- a/altoslib/AltosMapTypeListener.java
+++ b/altoslib/AltosMapTypeListener.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosMapTypeListener {
public void map_type_changed(int map_type);
diff --git a/altoslib/AltosMapZoomListener.java b/altoslib/AltosMapZoomListener.java
index 93c26cbb..c4a0acd6 100644
--- a/altoslib/AltosMapZoomListener.java
+++ b/altoslib/AltosMapZoomListener.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosMapZoomListener {
abstract public void zoom_changed(int zoom);
diff --git a/altoslib/AltosMma655x.java b/altoslib/AltosMma655x.java
index 503eb5fd..0f6022ac 100644
--- a/altoslib/AltosMma655x.java
+++ b/altoslib/AltosMma655x.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.*;
@@ -46,17 +46,18 @@ public class AltosMma655x implements Cloneable {
return n;
}
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException, AltosUnknownProduct {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException, AltosUnknownProduct {
try {
AltosMma655x mma655x = new AltosMma655x(link);
+ AltosCalData cal_data = listener.cal_data();
if (mma655x != null) {
int accel = mma655x.accel;
- if (config_data.mma655x_inverted())
+ if (cal_data.mma655x_inverted)
accel = 4095 - accel;
- if (config_data.pad_orientation == 1)
+ if (cal_data.pad_orientation == 1)
accel = 4095 - accel;
- state.set_accel(accel);
+ listener.set_acceleration(cal_data.acceleration(accel));
}
} catch (TimeoutException te) {
} catch (NumberFormatException ne) {
diff --git a/altoslib/AltosMs5607.java b/altoslib/AltosMs5607.java
index 631bc716..5b3ba65d 100644
--- a/altoslib/AltosMs5607.java
+++ b/altoslib/AltosMs5607.java
@@ -16,34 +16,42 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.*;
import java.io.*;
public class AltosMs5607 {
- public int reserved;
- public int sens;
- public int off;
- public int tcs;
- public int tco;
- public int tref;
- public int tempsens;
- public int crc;
-
- public int raw_pres;
- public int raw_temp;
- public int pa;
- public int cc;
-
- static final boolean ms5611 = false;
-
- void convert() {
+ public int reserved = AltosLib.MISSING;
+ public int sens = AltosLib.MISSING;
+ public int off = AltosLib.MISSING;
+ public int tcs = AltosLib.MISSING;
+ public int tco = AltosLib.MISSING;
+ public int tref = AltosLib.MISSING;
+ public int tempsens = AltosLib.MISSING;
+ public int crc = AltosLib.MISSING;
+ private boolean ms5611 = false;
+
+ public boolean valid_config() {
+ return reserved != AltosLib.MISSING &&
+ sens != AltosLib.MISSING &&
+ off != AltosLib.MISSING &&
+ tcs != AltosLib.MISSING &&
+ tco != AltosLib.MISSING &&
+ tref != AltosLib.MISSING &&
+ tempsens != AltosLib.MISSING &&
+ crc != AltosLib.MISSING;
+ }
+
+ public AltosPresTemp pres_temp(int raw_pres, int raw_temp) {
int dT;
- int TEMP;
- long OFF;
- long SENS;
- //int P;
+ int TEMP;
+ long OFF;
+ long SENS;
+ int P;
+
+ if (raw_pres == AltosLib.MISSING || raw_temp == AltosLib.MISSING)
+ return new AltosPresTemp(AltosLib.MISSING, AltosLib.MISSING);
dT = raw_temp - ((int) tref << 8);
@@ -64,7 +72,7 @@ public class AltosMs5607 {
int TEMPM = TEMP - 2000;
long OFF2 = ((long) 61 * (long) TEMPM * (long) TEMPM) >> 4;
long SENS2 = (long) 2 * (long) TEMPM * (long) TEMPM;
- if (TEMP < 1500) {
+ if (TEMP < -1500) {
int TEMPP = TEMP + 1500;
long TEMPP2 = (long) TEMPP * (long) TEMPP;
OFF2 = OFF2 + 15 * TEMPP2;
@@ -75,96 +83,75 @@ public class AltosMs5607 {
SENS -= SENS2;
}
- pa = (int) (((((long) raw_pres * SENS) >> 21) - OFF) >> 15);
- cc = TEMP;
- }
+ P = (int) (((((long) raw_pres * SENS) >> 21) - OFF) >> 15);
- public int set(int in_pres, int in_temp) {
- raw_pres = in_pres;
- raw_temp = in_temp;
- convert();
- return pa;
+ return new AltosPresTemp(P, TEMP / 100.0);
}
- public boolean parse_line(String line) {
- String[] items = line.split("\\s+");
- if (line.startsWith("Pressure:")) {
- if (items.length >= 2) {
- raw_pres = Integer.parseInt(items[1]);
- }
- } else if (line.startsWith("Temperature:")) {
- if (items.length >= 2)
- raw_temp = Integer.parseInt(items[1]);
- } else if (line.startsWith("ms5607 reserved:")) {
- if (items.length >= 3)
- reserved = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 sens:")) {
- if (items.length >= 3) {
- sens = Integer.parseInt(items[2]);
+ public AltosPresTemp pres_temp(AltosLink link) throws InterruptedException, TimeoutException {
+ int raw_pres = AltosLib.MISSING;
+ int raw_temp = AltosLib.MISSING;
+ boolean done = false;
+
+ link.printf("B\n");
+ while (!done) {
+ String line = link.get_reply_no_dialog(5000);
+ if (line == null)
+ throw new TimeoutException();
+
+ String[] items = line.split("\\s+");
+ if (line.startsWith("Pressure:")) {
+ if (items.length >= 2) {
+ raw_pres = Integer.parseInt(items[1]);
+ }
+ } else if (line.startsWith("Temperature:")) {
+ if (items.length >= 2)
+ raw_temp = Integer.parseInt(items[1]);
+ } else if (line.startsWith("Altitude:")) {
+ done = true;
}
- } else if (line.startsWith("ms5607 off:")) {
- if (items.length >= 3)
- off = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 tcs:")) {
- if (items.length >= 3)
- tcs = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 tco:")) {
- if (items.length >= 3)
- tco = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 tref:")) {
- if (items.length >= 3)
- tref = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 tempsens:")) {
- if (items.length >= 3)
- tempsens = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 crc:")) {
- if (items.length >= 3)
- crc = Integer.parseInt(items[2]);
- } else if (line.startsWith("Altitude:")) {
- return false;
}
- return true;
+ return pres_temp(raw_pres, raw_temp);
+ }
+
+ public AltosMs5607(boolean ms5611) {
+ this.ms5611 = ms5611;
}
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ public AltosMs5607() {
+ this(false);
+ }
+
+ public AltosMs5607(AltosMs5607 old) {
+ reserved = old.reserved;
+ sens = old.sens;
+ off = old.off;
+ tcs = old.tcs;
+ tco = old.tco;
+ tref = old.tref;
+ tempsens = old.tempsens;
+ crc = old.crc;
+ }
+
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
- AltosMs5607 ms5607 = new AltosMs5607(link, config_data);
+ AltosCalData cal_data = listener.cal_data();
+ AltosMs5607 ms5607 = cal_data.ms5607;
if (ms5607 != null) {
- state.set_ms5607(ms5607);
- return;
+ AltosPresTemp pt = ms5607.pres_temp(link);
+ listener.set_temperature(pt.temp);
+ listener.set_pressure(pt.pres);
}
} catch (TimeoutException te) {
}
}
- public AltosMs5607() {
- raw_pres = AltosLib.MISSING;
- raw_temp = AltosLib.MISSING;
- pa = AltosLib.MISSING;
- cc = AltosLib.MISSING;
+ public AltosMs5607(AltosConfigData config_data) {
+ this(config_data.ms5607());
}
public AltosMs5607 (AltosLink link, AltosConfigData config_data) throws InterruptedException, TimeoutException {
- this();
- reserved = config_data.ms5607_reserved;
- sens = config_data.ms5607_sens;
- off = config_data.ms5607_off;
- tcs = config_data.ms5607_tcs;
- tco = config_data.ms5607_tco;
- tref = config_data.ms5607_tref;
- tempsens = config_data.ms5607_tempsens;
- crc = config_data.ms5607_crc;
- link.printf("B\n");
- for (;;) {
- String line = link.get_reply_no_dialog(5000);
- if (line == null) {
- throw new TimeoutException();
- }
- if (!parse_line(line)) {
- break;
- }
- }
- convert();
+ this(config_data);
}
}
diff --git a/altoslib/AltosNoSymbol.java b/altoslib/AltosNoSymbol.java
index 37542cf0..8372d396 100644
--- a/altoslib/AltosNoSymbol.java
+++ b/altoslib/AltosNoSymbol.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosNoSymbol extends Exception {
public AltosNoSymbol(String name) {
diff --git a/altoslib/AltosOrient.java b/altoslib/AltosOrient.java
index 8b3a3541..4546a798 100644
--- a/altoslib/AltosOrient.java
+++ b/altoslib/AltosOrient.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosOrient extends AltosUnits {
diff --git a/altoslib/AltosParse.java b/altoslib/AltosParse.java
index b4b6f875..77cf969d 100644
--- a/altoslib/AltosParse.java
+++ b/altoslib/AltosParse.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.*;
import java.text.*;
diff --git a/altoslib/AltosPointDouble.java b/altoslib/AltosPointDouble.java
index 31b03b1f..301d07b0 100644
--- a/altoslib/AltosPointDouble.java
+++ b/altoslib/AltosPointDouble.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosPointDouble {
public double x, y;
diff --git a/altoslib/AltosPointInt.java b/altoslib/AltosPointInt.java
index 233a8d31..25f5dd2a 100644
--- a/altoslib/AltosPointInt.java
+++ b/altoslib/AltosPointInt.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosPointInt {
public int x, y;
diff --git a/altoslib/AltosPreferences.java b/altoslib/AltosPreferences.java
index 35d44631..0c388f1b 100644
--- a/altoslib/AltosPreferences.java
+++ b/altoslib/AltosPreferences.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
@@ -363,11 +363,11 @@ public class AltosPreferences {
}
}
- public static void set_state(AltosState state) {
+ public static void set_state(AltosState state, int serial) {
synchronized(backend) {
- backend.putJson(String.format(statePreferenceFormat, state.serial), new AltosJson(state));
- backend.putInt(statePreferenceLatest, state.serial);
+ backend.putJson(String.format(statePreferenceFormat, serial), new AltosJson(state));
+ backend.putInt(statePreferenceLatest, serial);
flush_preferences();
}
}
diff --git a/altoslib/AltosPreferencesBackend.java b/altoslib/AltosPreferencesBackend.java
index 327b534c..00fd2c6d 100644
--- a/altoslib/AltosPreferencesBackend.java
+++ b/altoslib/AltosPreferencesBackend.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
diff --git a/altoslib/AltosPresTemp.java b/altoslib/AltosPresTemp.java
new file mode 100644
index 00000000..4cd382c8
--- /dev/null
+++ b/altoslib/AltosPresTemp.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosPresTemp {
+ double pres = AltosLib.MISSING;
+ double temp = AltosLib.MISSING;
+
+ public AltosPresTemp(double pres, double temp) {
+ this.pres = pres;
+ this.temp = temp;
+ }
+}
diff --git a/altoslib/AltosStateIterable.java b/altoslib/AltosPressure.java
index 5332aecd..507a4cee 100644
--- a/altoslib/AltosStateIterable.java
+++ b/altoslib/AltosPressure.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ * Copyright © 2017 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
@@ -16,28 +16,35 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
-import java.io.*;
-import java.util.*;
+public class AltosPressure extends AltosUnits {
-public abstract class AltosStateIterable implements Iterable<AltosState> {
+ public double value(double v, boolean imperial_units) {
+ if (imperial_units)
+ return AltosConvert.pa_to_psi(v);
+ return v;
+ }
+
+ public double inverse(double v, boolean imperial_units) {
+ if (imperial_units)
+ return AltosConvert.psi_to_pa(v);
+ return v;
+ }
- public void write_comments (PrintStream out) {
+ public String show_units(boolean imperial_units) {
+ if (imperial_units)
+ return "psi";
+ return "Pa";
}
- public abstract void write(PrintStream out);
+ public String say_units(boolean imperial_units) {
+ if (imperial_units)
+ return "p s i";
+ return "pascals";
+ }
- public static AltosStateIterable iterable(File file) {
- FileInputStream in;
- try {
- in = new FileInputStream(file);
- } catch (Exception e) {
- return null;
- }
- if (file.getName().endsWith("telem"))
- return new AltosTelemetryFile(in);
- else
- return new AltosEepromFile(in);
+ public int show_fraction(int width, boolean imperial_units) {
+ return width / 9;
}
}
diff --git a/altoslib/AltosProgrammer.java b/altoslib/AltosProgrammer.java
index ba04107b..0a828a32 100644
--- a/altoslib/AltosProgrammer.java
+++ b/altoslib/AltosProgrammer.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
diff --git a/altoslib/AltosPyro.java b/altoslib/AltosPyro.java
index 33d7486c..0ea3bfc1 100644
--- a/altoslib/AltosPyro.java
+++ b/altoslib/AltosPyro.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.*;
import java.text.*;
@@ -290,6 +290,10 @@ public class AltosPyro {
}
}
+ public AltosPyro() {
+ this(0);
+ }
+
public String toString() {
String ret = String.format("%d", channel);
diff --git a/altoslib/AltosPyroName.java b/altoslib/AltosPyroName.java
new file mode 100644
index 00000000..0152e479
--- /dev/null
+++ b/altoslib/AltosPyroName.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosPyroName extends AltosUnits {
+
+ public double value(double v, boolean imperial_units) { return v; }
+
+ public double inverse(double v, boolean imperial_units) { return v; }
+
+ public String string_value(double v, boolean imperial_units) {
+ return AltosLib.igniter_name((int) v);
+ }
+
+ public String show_units(boolean imperial_units) { return "state"; }
+
+ public String say_units(boolean imperial_units) { return "state"; }
+
+ public int show_fraction(int width, boolean imperial_units) { return 0; }
+}
diff --git a/altoslib/AltosQuaternion.java b/altoslib/AltosQuaternion.java
index 40786e32..6d6bc12c 100644
--- a/altoslib/AltosQuaternion.java
+++ b/altoslib/AltosQuaternion.java
@@ -16,12 +16,13 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosQuaternion {
double r; /* real bit */
double x, y, z; /* imaginary bits */
+ /* Multiply by b */
public AltosQuaternion multiply(AltosQuaternion b) {
return new AltosQuaternion(
this.r * b.r - this.x * b.x - this.y * b.y - this.z * b.z,
@@ -31,35 +32,36 @@ public class AltosQuaternion {
}
public AltosQuaternion conjugate() {
- return new AltosQuaternion(
- this.r,
- -this.x,
- -this.y,
- -this.z);
+ return new AltosQuaternion(this.r,
+ -this.x,
+ -this.y,
+ -this.z);
}
public double normal() {
- return (this.r * this.r +
- this.x * this.x +
- this.y * this.y +
- this.z * this.z);
+ return Math.sqrt(this.r * this.r +
+ this.x * this.x +
+ this.y * this.y +
+ this.z * this.z);
}
+ /* Scale by a real value */
public AltosQuaternion scale(double b) {
- return new AltosQuaternion(
- this.r * b,
- this.x * b,
- this.y * b,
- this.z * b);
+ return new AltosQuaternion(this.r * b,
+ this.x * b,
+ this.y * b,
+ this.z * b);
}
+ /* Divide by the length to end up with a quaternion of length 1 */
public AltosQuaternion normalize() {
double n = normal();
if (n <= 0)
return this;
- return scale(1/Math.sqrt(n));
+ return scale(1/n);
}
+ /* dot product */
public double dot(AltosQuaternion b) {
return (this.r * b.r +
this.x * b.x +
@@ -67,10 +69,14 @@ public class AltosQuaternion {
this.z * b.z);
}
+ /* Rotate 'this' by 'b' */
public AltosQuaternion rotate(AltosQuaternion b) {
return (b.multiply(this)).multiply(b.conjugate());
}
+ /* Given two vectors (this and b), compute a quaternion
+ * representing the rotation between them
+ */
public AltosQuaternion vectors_to_rotation(AltosQuaternion b) {
/*
* The cross product will point orthogonally to the two
@@ -145,7 +151,13 @@ public class AltosQuaternion {
return new AltosQuaternion(1, 0, 0, 0);
}
- static public AltosQuaternion half_euler(double x, double y, double z) {
+ static public AltosQuaternion euler(double x, double y, double z) {
+
+ /* Halve the euler angles */
+ x = x / 2.0;
+ y = y / 2.0;
+ z = z / 2.0;
+
double s_x = Math.sin(x), c_x = Math.cos(x);
double s_y = Math.sin(y), c_y = Math.cos(y);
double s_z = Math.sin(z), c_z = Math.cos(z);;
diff --git a/altoslib/AltosRecordSet.java b/altoslib/AltosRecordSet.java
new file mode 100644
index 00000000..91cce624
--- /dev/null
+++ b/altoslib/AltosRecordSet.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+import java.util.*;
+
+public interface AltosRecordSet {
+ public AltosCalData cal_data();
+ public void capture_series(AltosDataListener listener);
+}
diff --git a/altoslib/AltosRectangle.java b/altoslib/AltosRectangle.java
index 50b3caa6..810388ed 100644
--- a/altoslib/AltosRectangle.java
+++ b/altoslib/AltosRectangle.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosRectangle {
public int x, y, width, height;
diff --git a/altoslib/AltosReplayReader.java b/altoslib/AltosReplayReader.java
index 59ade871..24b425b7 100644
--- a/altoslib/AltosReplayReader.java
+++ b/altoslib/AltosReplayReader.java
@@ -16,40 +16,139 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
+import java.util.concurrent.*;
/*
* Open an existing telemetry file and replay it in realtime
*/
+class AltosReplay extends AltosDataListener implements Runnable {
+
+ AltosState state;
+ AltosRecordSet record_set;
+ double last_time = AltosLib.MISSING;
+ Semaphore semaphore = new Semaphore(1);;
+ boolean done = false;
+
+ public void set_time(double time) {
+ if (last_time != AltosLib.MISSING) {
+ semaphore.release();
+ double delay = Math.min(time - last_time,10);
+ if (delay > 0) {
+ try {
+ Thread.sleep((int) (delay * 1000));
+ } catch (InterruptedException ie) {
+ }
+ }
+ }
+ last_time = time;
+ super.set_time(time);
+ state.set_time(time);
+ }
+
+ public void set_state(int state) {
+ super.set_state(state);
+ this.state.set_state(state);
+ }
+
+ public void set_rssi(int rssi, int status) { state.set_rssi(rssi, status); }
+ public void set_received_time(long received_time) { }
+
+ public void set_acceleration(double accel) { state.set_acceleration(accel); }
+ public void set_pressure(double pa) { state.set_pressure(pa); }
+ public void set_thrust(double N) { state.set_thrust(N); }
+
+ public void set_kalman(double height, double speed, double accel) { state.set_kalman(height, speed, accel); }
+
+ public void set_temperature(double deg_c) { state.set_temperature(deg_c); }
+ public void set_battery_voltage(double volts) { state.set_battery_voltage(volts); }
+
+ public void set_apogee_voltage(double volts) { state.set_apogee_voltage(volts); }
+ public void set_main_voltage(double volts) { state.set_main_voltage(volts); }
+
+ public void set_gps(AltosGPS gps) { state.set_gps(gps); }
+
+ public void set_orient(double orient) { state.set_orient(orient); }
+ public void set_gyro(double roll, double pitch, double yaw) { state.set_gyro(roll, pitch, yaw); }
+ public void set_accel_ground(double along, double across, double through) { state.set_accel_ground(along, across, through); }
+ public void set_accel(double along, double across, double through) { state.set_accel(along, across, through); }
+ public void set_mag(double along, double across, double through) { state.set_mag(along, across, through); }
+ public void set_pyro_voltage(double volts) { state.set_pyro_voltage(volts); }
+ public void set_igniter_voltage(double[] voltage) { state.set_igniter_voltage(voltage); }
+ public void set_pyro_fired(int pyro_mask) { state.set_pyro_fired(pyro_mask); }
+ public void set_companion(AltosCompanion companion) { state.set_companion(companion); }
+
+ public void run () {
+ /* Run the flight */
+ record_set.capture_series(this);
+ /* All done, signal that it's over */
+ done = true;
+ semaphore.release();
+ }
+
+ public AltosReplay(AltosRecordSet record_set) {
+ super(record_set.cal_data());
+ state = new AltosState(record_set.cal_data());
+ this.record_set = record_set;
+ try {
+ semaphore.acquire();
+ } catch (InterruptedException ie) {
+ }
+ }
+}
+
public class AltosReplayReader extends AltosFlightReader {
- Iterator<AltosState> iterator;
- File file;
+ File file;
+ AltosReplay replay;
+ Thread t;
+ int reads;
- public AltosState read() {
- if (iterator.hasNext())
- return iterator.next();
- return null;
+ public AltosCalData cal_data() {
+ return replay.state.cal_data();
}
- public void close (boolean interrupted) {
+ public AltosState read() {
+ switch (reads) {
+ case 0:
+ /* Tell the display that we're in pad mode */
+ replay.state.set_state(AltosLib.ao_flight_pad);
+ break;
+ case 1:
+ t = new Thread(replay);
+ t.start();
+ /* fall through */
+ default:
+ /* Wait for something to change */
+ try {
+ replay.semaphore.acquire();
+ } catch (InterruptedException ie) {
+ }
+ break;
+ }
+ reads++;
+
+ /* When done, let the display know */
+ if (replay.done)
+ return null;
+
+ /* Fake out the received time */
+ replay.state.set_received_time(System.currentTimeMillis());
+ return replay.state;
}
- public void update(AltosState state) throws InterruptedException {
- /* Make it run in realtime after the rocket leaves the pad */
- if (state.state() > AltosLib.ao_flight_pad && state.time_change > 0)
- Thread.sleep((int) (Math.min(state.time_change,10) * 1000));
- state.set_received_time(System.currentTimeMillis());
+ public void close (boolean interrupted) {
}
public File backing_file() { return file; }
- public AltosReplayReader(Iterator<AltosState> in_iterator, File in_file) {
- iterator = in_iterator;
+ public AltosReplayReader(AltosRecordSet record_set, File in_file) {
+ reads = 0;
file = in_file;
name = file.getName();
+ replay = new AltosReplay(record_set);
}
}
diff --git a/altoslib/AltosRomconfig.java b/altoslib/AltosRomconfig.java
index dcfbda32..46ee2b6e 100644
--- a/altoslib/AltosRomconfig.java
+++ b/altoslib/AltosRomconfig.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
diff --git a/altoslib/AltosRotation.java b/altoslib/AltosRotation.java
index 1235d86b..eec8c529 100644
--- a/altoslib/AltosRotation.java
+++ b/altoslib/AltosRotation.java
@@ -16,11 +16,33 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosRotation extends AltosQuaternion {
private AltosQuaternion rotation;
+ /* Compute pitch angle from vertical by taking the pad
+ * orientation vector and rotating it by the current total
+ * rotation value. That will be a unit vector pointing along
+ * the airframe axis. The Z value will be the cosine of the
+ * angle from vertical.
+ *
+ * rot = ao_rotation * vertical * ao_rotation°
+ * rot = ao_rotation * (0,0,0,1) * ao_rotation°
+ * = ((a.z, a.y, -a.x, a.r) * (a.r, -a.x, -a.y, -a.z)) .z
+ *
+ * = (-a.z * -a.z) + (a.y * -a.y) - (-a.x * -a.x) + (a.r * a.r)
+ * = a.z² - a.y² - a.x² + a.r²
+ *
+ * rot = ao_rotation * (0, 0, 0, -1) * ao_rotation°
+ * = ((-a.z, -a.y, a.x, -a.r) * (a.r, -a.x, -a.y, -a.z)) .z
+ *
+ * = (a.z * -a.z) + (-a.y * -a.y) - (a.x * -a.x) + (-a.r * a.r)
+ * = -a.z² + a.y² + a.x² - a.r²
+ *
+ * tilt = acos(rot) (in radians)
+ */
+
public double tilt() {
double rotz = rotation.z * rotation.z - rotation.y * rotation.y - rotation.x * rotation.x + rotation.r * rotation.r;
@@ -28,8 +50,11 @@ public class AltosRotation extends AltosQuaternion {
return tilt;
}
- public void rotate(double dt, double x, double y, double z) {
- AltosQuaternion rot = AltosQuaternion.half_euler(x * dt / 2.0, y * dt / 2.0, z * dt / 2.0);
+ /* Given euler rotations in three axes, perform a combined rotation using
+ * quaternions
+ */
+ public void rotate(double x, double y, double z) {
+ AltosQuaternion rot = AltosQuaternion.euler(x, y, z);
rotation = rot.multiply(rotation).normalize();
}
diff --git a/altoslib/AltosRotationRate.java b/altoslib/AltosRotationRate.java
new file mode 100644
index 00000000..492f1217
--- /dev/null
+++ b/altoslib/AltosRotationRate.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosRotationRate extends AltosUnits {
+
+ public double value(double p, boolean imperial_units) {
+ return p;
+ }
+
+ public double inverse(double p, boolean imperial_units) {
+ return p;
+ }
+
+ public String show_units(boolean imperial_units) {
+ return "°/sec";
+ }
+
+ public String say_units(boolean imperial_units) {
+ return "degrees per second";
+ }
+
+ public int show_fraction(int width, boolean imperial_units) {
+ return 1;
+ }
+}
diff --git a/altoslib/AltosSavedState.java b/altoslib/AltosSavedState.java
index 76d12faf..66876864 100644
--- a/altoslib/AltosSavedState.java
+++ b/altoslib/AltosSavedState.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
diff --git a/altoslib/AltosSelfFlash.java b/altoslib/AltosSelfFlash.java
index ae7cd69a..53782172 100644
--- a/altoslib/AltosSelfFlash.java
+++ b/altoslib/AltosSelfFlash.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
diff --git a/altoslib/AltosSensorEMini.java b/altoslib/AltosSensorEMini.java
index 2581685f..1bdbb60c 100644
--- a/altoslib/AltosSensorEMini.java
+++ b/altoslib/AltosSensorEMini.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
@@ -26,15 +26,25 @@ public class AltosSensorEMini {
public int main;
public int batt;
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link, int version) throws InterruptedException {
try {
AltosSensorEMini sensor_emini = new AltosSensorEMini(link);
+ AltosCalData cal_data = listener.cal_data();
if (sensor_emini == null)
return;
- state.set_battery_voltage(AltosConvert.easy_mini_voltage(sensor_emini.batt, config_data.serial));
- state.set_apogee_voltage(AltosConvert.easy_mini_voltage(sensor_emini.apogee, config_data.serial));
- state.set_main_voltage(AltosConvert.easy_mini_voltage(sensor_emini.main, config_data.serial));
+ switch (version) {
+ case 1:
+ listener.set_battery_voltage(AltosConvert.easy_mini_1_voltage(sensor_emini.batt, cal_data.serial));
+ listener.set_apogee_voltage(AltosConvert.easy_mini_1_voltage(sensor_emini.apogee, cal_data.serial));
+ listener.set_main_voltage(AltosConvert.easy_mini_1_voltage(sensor_emini.main, cal_data.serial));
+ break;
+ case 2:
+ listener.set_battery_voltage(AltosConvert.easy_mini_2_voltage(sensor_emini.batt));
+ listener.set_apogee_voltage(AltosConvert.easy_mini_2_voltage(sensor_emini.apogee));
+ listener.set_main_voltage(AltosConvert.easy_mini_2_voltage(sensor_emini.main));
+ break;
+ }
} catch (TimeoutException te) {
}
diff --git a/altoslib/AltosSensorMM.java b/altoslib/AltosSensorMM.java
index d79c0805..00873afe 100644
--- a/altoslib/AltosSensorMM.java
+++ b/altoslib/AltosSensorMM.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
diff --git a/altoslib/AltosSensorMega.java b/altoslib/AltosSensorMega.java
index 63c7a0ce..e58b03a1 100644
--- a/altoslib/AltosSensorMega.java
+++ b/altoslib/AltosSensorMega.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
@@ -89,18 +89,18 @@ class AltosSensorMega {
}
}
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosSensorMega sensor_mega = new AltosSensorMega(link);
- state.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_mega.v_batt));
- state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[4]));
- state.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[5]));
+ listener.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_mega.v_batt));
+ listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[4]));
+ listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[5]));
- double[] ignitor_voltage = new double[4];
+ double[] igniter_voltage = new double[4];
for (int i = 0; i < 4; i++)
- ignitor_voltage[i] = AltosConvert.mega_pyro_voltage(sensor_mega.sense[i]);
- state.set_ignitor_voltage(ignitor_voltage);
+ igniter_voltage[i] = AltosConvert.mega_pyro_voltage(sensor_mega.sense[i]);
+ listener.set_igniter_voltage(igniter_voltage);
} catch (TimeoutException te) {
}
diff --git a/altoslib/AltosSensorMetrum.java b/altoslib/AltosSensorMetrum.java
index cb163911..e01d57cc 100644
--- a/altoslib/AltosSensorMetrum.java
+++ b/altoslib/AltosSensorMetrum.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
@@ -53,12 +53,12 @@ class AltosSensorMetrum {
}
}
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosSensorMetrum sensor_metrum = new AltosSensorMetrum(link);
- state.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_metrum.v_batt));
- state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_a));
- state.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_m));
+ listener.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_metrum.v_batt));
+ listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_a));
+ listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_m));
} catch (TimeoutException te) {
}
}
diff --git a/altoslib/AltosSensorTGPS.java b/altoslib/AltosSensorTGPS.java
index 9c2bcb10..14514413 100644
--- a/altoslib/AltosSensorTGPS.java
+++ b/altoslib/AltosSensorTGPS.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
@@ -24,13 +24,13 @@ public class AltosSensorTGPS {
public int tick;
public int batt;
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosSensorTGPS sensor_tgps = new AltosSensorTGPS(link);
if (sensor_tgps == null)
return;
- state.set_battery_voltage(AltosConvert.tele_gps_voltage(sensor_tgps.batt));
+ listener.set_battery_voltage(AltosConvert.tele_gps_voltage(sensor_tgps.batt));
} catch (TimeoutException te) {
}
diff --git a/altoslib/AltosSensorTM.java b/altoslib/AltosSensorTM.java
index 5d1b1b7f..bdedaa9c 100644
--- a/altoslib/AltosSensorTM.java
+++ b/altoslib/AltosSensorTM.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
@@ -29,18 +29,19 @@ public class AltosSensorTM {
public int drogue;
public int main;
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosSensorTM sensor_tm = new AltosSensorTM(link);
+ AltosCalData cal_data = listener.cal_data();
if (sensor_tm == null)
return;
- state.set_accel(sensor_tm.accel);
- state.set_pressure(AltosConvert.barometer_to_pressure(sensor_tm.pres));
- state.set_temperature(AltosConvert.thermometer_to_temperature(sensor_tm.temp));
- state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(sensor_tm.batt));
- state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sensor_tm.drogue));
- state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sensor_tm.main));
+ listener.set_acceleration(cal_data.acceleration((sensor_tm.accel)));
+ listener.set_pressure(AltosConvert.barometer_to_pressure(sensor_tm.pres));
+ listener.set_temperature(AltosConvert.thermometer_to_temperature(sensor_tm.temp));
+ listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(sensor_tm.batt));
+ listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(sensor_tm.drogue));
+ listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(sensor_tm.main));
} catch (TimeoutException te) {
}
diff --git a/altoslib/AltosSensorTMini2.java b/altoslib/AltosSensorTMini2.java
index 7e00abd0..9b5a1854 100644
--- a/altoslib/AltosSensorTMini2.java
+++ b/altoslib/AltosSensorTMini2.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
@@ -26,15 +26,15 @@ public class AltosSensorTMini2 {
public int main;
public int batt;
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosSensorTMini2 sensor_tmini = new AltosSensorTMini2(link);
if (sensor_tmini == null)
return;
- state.set_battery_voltage(AltosConvert.tele_mini_2_voltage(sensor_tmini.batt));
- state.set_apogee_voltage(AltosConvert.tele_mini_2_voltage(sensor_tmini.apogee));
- state.set_main_voltage(AltosConvert.tele_mini_2_voltage(sensor_tmini.main));
+ listener.set_battery_voltage(AltosConvert.tele_mini_2_voltage(sensor_tmini.batt));
+ listener.set_apogee_voltage(AltosConvert.tele_mini_2_voltage(sensor_tmini.apogee));
+ listener.set_main_voltage(AltosConvert.tele_mini_2_voltage(sensor_tmini.main));
} catch (TimeoutException te) {
}
diff --git a/altoslib/AltosSensorTMini3.java b/altoslib/AltosSensorTMini3.java
index 19d514d7..b92def03 100644
--- a/altoslib/AltosSensorTMini3.java
+++ b/altoslib/AltosSensorTMini3.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
@@ -26,15 +26,15 @@ public class AltosSensorTMini3 {
public int main;
public int batt;
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosSensorTMini3 sensor_tmini = new AltosSensorTMini3(link);
if (sensor_tmini == null)
return;
- state.set_battery_voltage(AltosConvert.tele_mini_3_battery_voltage(sensor_tmini.batt));
- state.set_apogee_voltage(AltosConvert.tele_mini_3_pyro_voltage(sensor_tmini.apogee));
- state.set_main_voltage(AltosConvert.tele_mini_3_pyro_voltage(sensor_tmini.main));
+ listener.set_battery_voltage(AltosConvert.tele_mini_3_battery_voltage(sensor_tmini.batt));
+ listener.set_apogee_voltage(AltosConvert.tele_mini_3_pyro_voltage(sensor_tmini.apogee));
+ listener.set_main_voltage(AltosConvert.tele_mini_3_pyro_voltage(sensor_tmini.main));
} catch (TimeoutException te) {
}
diff --git a/altoslib/AltosSpeed.java b/altoslib/AltosSpeed.java
index 465c190c..2a8ccedc 100644
--- a/altoslib/AltosSpeed.java
+++ b/altoslib/AltosSpeed.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosSpeed extends AltosUnits {
diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java
index fd2684db..9ee3d57d 100644
--- a/altoslib/AltosState.java
+++ b/altoslib/AltosState.java
@@ -20,11 +20,9 @@
* Track flight state from telemetry or eeprom data stream
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
-import java.io.*;
-
-public class AltosState implements Cloneable {
+public class AltosState extends AltosDataListener {
public static final int set_position = 1;
public static final int set_gps = 2;
@@ -40,12 +38,8 @@ public class AltosState implements Cloneable {
public long received_time;
- public double time;
- public double prev_time;
- public double time_change;
- public int tick;
- private int prev_tick;
- public int boost_tick;
+ public int rssi;
+ public int status;
class AltosValue {
double value;
@@ -290,22 +284,9 @@ public class AltosState implements Cloneable {
}
}
- private int state;
- public int flight;
- public int serial;
- public int altitude_32;
- public int receiver_serial;
public boolean landed;
public boolean ascent; /* going up? */
public boolean boost; /* under power */
- public int rssi;
- public int status;
- public int device_type;
- public int config_major;
- public int config_minor;
- public int apogee_delay;
- public int main_deploy;
- public int flight_log_max;
private double pressure_to_altitude(double p) {
if (p == AltosLib.MISSING)
@@ -448,6 +429,11 @@ public class AltosState implements Cloneable {
}
public void set_altitude(double new_altitude) {
+ double old_altitude = altitude.value();
+ if (old_altitude != AltosLib.MISSING) {
+ while (old_altitude - new_altitude > 32000)
+ new_altitude += 65536.0;
+ }
altitude.set_measured(new_altitude, time);
}
@@ -515,6 +501,9 @@ public class AltosState implements Cloneable {
pressure.set(p, time);
}
+ public void set_thrust(double N) {
+ }
+
public double baro_height() {
double a = altitude();
double g = ground_altitude();
@@ -667,6 +656,11 @@ public class AltosState implements Cloneable {
public AltosValue kalman_height, kalman_speed, kalman_acceleration;
public void set_kalman(double height, double speed, double acceleration) {
+ double old_height = kalman_height.value();
+ if (old_height != AltosLib.MISSING) {
+ while (old_height - height > 32000)
+ height += 65536;
+ }
kalman_height.set(height, time);
kalman_speed.set(speed, time);
kalman_acceleration.set(acceleration, time);
@@ -678,16 +672,10 @@ public class AltosState implements Cloneable {
public double apogee_voltage;
public double main_voltage;
- public double ignitor_voltage[];
+ public double igniter_voltage[];
public AltosGPS gps;
- public AltosGPS temp_gps;
- public int temp_gps_sat_tick;
public boolean gps_pending;
- public int gps_sequence;
-
- public AltosIMU imu;
- public AltosMag mag;
public static final int MIN_PAD_SAMPLES = 10;
@@ -699,6 +687,7 @@ public class AltosState implements Cloneable {
public AltosGreatCircle from_pad;
public double elevation; /* from pad */
+ public double distance; /* distance along ground */
public double range; /* total distance */
public double gps_height;
@@ -708,20 +697,7 @@ public class AltosState implements Cloneable {
public int speak_tick;
public double speak_altitude;
- public String callsign;
- public String firmware_version;
-
- public double accel_plus_g;
- public double accel_minus_g;
- public double accel;
public double ground_accel;
- public double ground_accel_avg;
-
- public int log_format;
- public int log_space;
- public String product;
-
- public AltosMs5607 baro;
public AltosCompanion companion;
@@ -740,23 +716,11 @@ public class AltosState implements Cloneable {
received_time = System.currentTimeMillis();
time = AltosLib.MISSING;
- time_change = AltosLib.MISSING;
- prev_time = AltosLib.MISSING;
- tick = AltosLib.MISSING;
- prev_tick = AltosLib.MISSING;
- boost_tick = AltosLib.MISSING;
state = AltosLib.ao_flight_invalid;
- flight = AltosLib.MISSING;
landed = false;
boost = false;
rssi = AltosLib.MISSING;
status = 0;
- device_type = AltosLib.MISSING;
- config_major = AltosLib.MISSING;
- config_minor = AltosLib.MISSING;
- apogee_delay = AltosLib.MISSING;
- main_deploy = AltosLib.MISSING;
- flight_log_max = AltosLib.MISSING;
ground_altitude = new AltosCValue();
ground_pressure = new AltosGroundPressure();
@@ -771,43 +735,40 @@ public class AltosState implements Cloneable {
pyro_voltage = AltosLib.MISSING;
apogee_voltage = AltosLib.MISSING;
main_voltage = AltosLib.MISSING;
- ignitor_voltage = null;
+ igniter_voltage = null;
kalman_height = new AltosValue();
kalman_speed = new AltosValue();
kalman_acceleration = new AltosValue();
gps = null;
- temp_gps = null;
- temp_gps_sat_tick = 0;
- gps_sequence = 0;
gps_pending = false;
- imu = null;
last_imu_time = AltosLib.MISSING;
rotation = null;
- ground_rotation = null;
-
- mag = null;
- accel_zero_along = AltosLib.MISSING;
- accel_zero_across = AltosLib.MISSING;
- accel_zero_through = AltosLib.MISSING;
accel_ground_along = AltosLib.MISSING;
accel_ground_across = AltosLib.MISSING;
accel_ground_through = AltosLib.MISSING;
- pad_orientation = AltosLib.MISSING;
+ accel_along = AltosLib.MISSING;
+ accel_across = AltosLib.MISSING;
+ accel_through = AltosLib.MISSING;
- gyro_zero_roll = AltosLib.MISSING;
- gyro_zero_pitch = AltosLib.MISSING;
- gyro_zero_yaw = AltosLib.MISSING;
+ gyro_roll = AltosLib.MISSING;
+ gyro_pitch = AltosLib.MISSING;
+ gyro_yaw = AltosLib.MISSING;
+
+ mag_along = AltosLib.MISSING;
+ mag_across = AltosLib.MISSING;
+ mag_through = AltosLib.MISSING;
set_npad(0);
ngps = 0;
from_pad = null;
elevation = AltosLib.MISSING;
+ distance = AltosLib.MISSING;
range = AltosLib.MISSING;
gps_height = AltosLib.MISSING;
@@ -825,32 +786,14 @@ public class AltosState implements Cloneable {
speak_tick = AltosLib.MISSING;
speak_altitude = AltosLib.MISSING;
- callsign = null;
- firmware_version = null;
-
- accel_plus_g = AltosLib.MISSING;
- accel_minus_g = AltosLib.MISSING;
- accel = AltosLib.MISSING;
-
ground_accel = AltosLib.MISSING;
- ground_accel_avg = AltosLib.MISSING;
-
- log_format = AltosLib.MISSING;
- log_space = AltosLib.MISSING;
- product = null;
- serial = AltosLib.MISSING;
- receiver_serial = AltosLib.MISSING;
- altitude_32 = AltosLib.MISSING;
- baro = null;
companion = null;
pyro_fired = 0;
}
void finish_update() {
- prev_tick = tick;
-
ground_altitude.finish_update();
altitude.finish_update();
pressure.finish_update();
@@ -863,156 +806,12 @@ public class AltosState implements Cloneable {
kalman_acceleration.finish_update();
}
- void copy(AltosState old) {
-
- if (old == null) {
- init();
- return;
- }
-
- received_time = old.received_time;
- time = old.time;
- time_change = old.time_change;
- prev_time = old.time;
-
- tick = old.tick;
- prev_tick = old.tick;
- boost_tick = old.boost_tick;
-
- state = old.state;
- flight = old.flight;
- landed = old.landed;
- ascent = old.ascent;
- boost = old.boost;
- rssi = old.rssi;
- status = old.status;
- device_type = old.device_type;
- config_major = old.config_major;
- config_minor = old.config_minor;
- apogee_delay = old.apogee_delay;
- main_deploy = old.main_deploy;
- flight_log_max = old.flight_log_max;
-
- set = 0;
-
- ground_pressure.copy(old.ground_pressure);
- ground_altitude.copy(old.ground_altitude);
- altitude.copy(old.altitude);
- pressure.copy(old.pressure);
- speed.copy(old.speed);
- acceleration.copy(old.acceleration);
- orient.copy(old.orient);
-
- battery_voltage = old.battery_voltage;
- pyro_voltage = old.pyro_voltage;
- temperature = old.temperature;
- apogee_voltage = old.apogee_voltage;
- main_voltage = old.main_voltage;
- ignitor_voltage = old.ignitor_voltage;
-
- kalman_height.copy(old.kalman_height);
- kalman_speed.copy(old.kalman_speed);
- kalman_acceleration.copy(old.kalman_acceleration);
-
- if (old.gps != null)
- gps = old.gps.clone();
- else
- gps = null;
- if (old.temp_gps != null)
- temp_gps = old.temp_gps.clone();
- else
- temp_gps = null;
- temp_gps_sat_tick = old.temp_gps_sat_tick;
- gps_sequence = old.gps_sequence;
- gps_pending = old.gps_pending;
-
- if (old.imu != null)
- imu = old.imu.clone();
- else
- imu = null;
- last_imu_time = old.last_imu_time;
-
- if (old.rotation != null)
- rotation = new AltosRotation (old.rotation);
-
- if (old.ground_rotation != null) {
- ground_rotation = new AltosRotation(old.ground_rotation);
- }
-
- accel_zero_along = old.accel_zero_along;
- accel_zero_across = old.accel_zero_across;
- accel_zero_through = old.accel_zero_through;
-
- accel_ground_along = old.accel_ground_along;
- accel_ground_across = old.accel_ground_across;
- accel_ground_through = old.accel_ground_through;
- pad_orientation = old.pad_orientation;
-
- gyro_zero_roll = old.gyro_zero_roll;
- gyro_zero_pitch = old.gyro_zero_pitch;
- gyro_zero_yaw = old.gyro_zero_yaw;
-
- if (old.mag != null)
- mag = old.mag.clone();
- else
- mag = null;
-
- npad = old.npad;
- gps_waiting = old.gps_waiting;
- gps_ready = old.gps_ready;
- ngps = old.ngps;
-
- if (old.from_pad != null)
- from_pad = old.from_pad.clone();
- else
- from_pad = null;
-
- elevation = old.elevation;
- range = old.range;
-
- gps_height = old.gps_height;
-
- gps_altitude.copy(old.gps_altitude);
- gps_ground_altitude.copy(old.gps_ground_altitude);
- gps_ground_speed.copy(old.gps_ground_speed);
- gps_ascent_rate.copy(old.gps_ascent_rate);
- gps_course.copy(old.gps_course);
- gps_speed.copy(old.gps_speed);
-
- pad_lat = old.pad_lat;
- pad_lon = old.pad_lon;
- pad_alt = old.pad_alt;
-
- speak_tick = old.speak_tick;
- speak_altitude = old.speak_altitude;
-
- callsign = old.callsign;
- firmware_version = old.firmware_version;
-
- accel_plus_g = old.accel_plus_g;
- accel_minus_g = old.accel_minus_g;
- accel = old.accel;
- ground_accel = old.ground_accel;
- ground_accel_avg = old.ground_accel_avg;
-
- log_format = old.log_format;
- log_space = old.log_space;
- product = old.product;
- serial = old.serial;
- receiver_serial = old.receiver_serial;
- altitude_32 = old.altitude_32;
-
- baro = old.baro;
- companion = old.companion;
-
- pyro_fired = old.pyro_fired;
- }
-
void update_time() {
}
void update_gps() {
elevation = AltosLib.MISSING;
+ distance = AltosLib.MISSING;
range = AltosLib.MISSING;
if (gps == null)
@@ -1054,36 +853,15 @@ public class AltosState implements Cloneable {
h = 0;
from_pad = new AltosGreatCircle(pad_lat, pad_lon, 0, gps.lat, gps.lon, h);
elevation = from_pad.elevation;
+ distance = from_pad.distance;
range = from_pad.range;
}
}
- public void set_tick(int new_tick) {
- if (new_tick != AltosLib.MISSING) {
- if (prev_tick != AltosLib.MISSING) {
- while (new_tick < prev_tick - 1000) {
- new_tick += 65536;
- }
- }
- tick = new_tick;
- time = tick / 100.0;
- time_change = time - prev_time;
- }
- }
-
- public void set_boost_tick(int boost_tick) {
- if (boost_tick != AltosLib.MISSING)
- this.boost_tick = boost_tick;
- }
-
public String state_name() {
return AltosLib.state_name(state);
}
- public void set_product(String product) {
- this.product = product;
- }
-
public void set_state(int state) {
if (state != AltosLib.ao_flight_invalid) {
this.state = state;
@@ -1097,96 +875,8 @@ public class AltosState implements Cloneable {
return state;
}
- public void set_device_type(int device_type) {
- this.device_type = device_type;
- switch (device_type) {
- case AltosLib.product_telegps:
- this.state = AltosLib.ao_flight_stateless;
- break;
- }
- }
-
- public void set_log_format(int log_format) {
- this.log_format = log_format;
- switch (log_format) {
- case AltosLib.AO_LOG_FORMAT_TELEGPS:
- this.state = AltosLib.ao_flight_stateless;
- break;
- }
- }
-
- public void set_log_space(int log_space) {
- this.log_space = log_space;
- }
-
- public void set_flight_params(int apogee_delay, int main_deploy) {
- this.apogee_delay = apogee_delay;
- this.main_deploy = main_deploy;
- }
-
- public void set_config(int major, int minor, int flight_log_max) {
- config_major = major;
- config_minor = minor;
- this.flight_log_max = flight_log_max;
- }
-
- public void set_callsign(String callsign) {
- this.callsign = callsign;
- }
-
- public void set_firmware_version(String version) {
- firmware_version = version;
- }
-
- public int compare_version(String other_version) {
- if (firmware_version == null)
- return AltosLib.MISSING;
- return AltosLib.compare_version(firmware_version, other_version);
- }
-
private void re_init() {
- int bt = boost_tick;
- int rs = receiver_serial;
init();
- boost_tick = bt;
- receiver_serial = rs;
- }
-
- public void set_flight(int flight) {
-
- /* When the flight changes, reset the state */
- if (flight != AltosLib.MISSING) {
- if (this.flight != AltosLib.MISSING &&
- this.flight != flight) {
- re_init();
- }
- this.flight = flight;
- }
- }
-
- public void set_serial(int serial) {
- /* When the serial changes, reset the state */
- if (serial != AltosLib.MISSING) {
- if (this.serial != AltosLib.MISSING &&
- this.serial != serial) {
- re_init();
- }
- this.serial = serial;
- }
- }
-
- public void set_receiver_serial(int serial) {
- if (serial != AltosLib.MISSING)
- receiver_serial = serial;
- }
-
- public boolean altitude_32() {
- return altitude_32 == 1;
- }
-
- public void set_altitude_32(int altitude_32) {
- if (altitude_32 != AltosLib.MISSING)
- this.altitude_32 = altitude_32;
}
public int rssi() {
@@ -1206,42 +896,24 @@ public class AltosState implements Cloneable {
received_time = ms;
}
- public void set_gps(AltosGPS gps, int sequence) {
+ public void set_gps(AltosGPS gps) {
if (gps != null) {
- this.gps = gps.clone();
- gps_sequence = sequence;
+ this.gps = gps;
update_gps();
set |= set_gps;
}
}
-
- public double accel_zero_along;
- public double accel_zero_across;
- public double accel_zero_through;
-
public AltosRotation rotation;
- public AltosRotation ground_rotation;
-
- public void set_accel_zero(double zero_along, double zero_across, double zero_through) {
- if (zero_along != AltosLib.MISSING) {
- accel_zero_along = zero_along;
- accel_zero_across = zero_across;
- accel_zero_through = zero_through;
- }
- }
-
- public int pad_orientation;
public double accel_ground_along, accel_ground_across, accel_ground_through;
void update_pad_rotation() {
- if (pad_orientation != AltosLib.MISSING && accel_ground_along != AltosLib.MISSING) {
- rotation = new AltosRotation(AltosIMU.convert_accel(accel_ground_across - accel_zero_across),
- AltosIMU.convert_accel(accel_ground_through - accel_zero_through),
- AltosIMU.convert_accel(accel_ground_along - accel_zero_along),
- pad_orientation);
- ground_rotation = rotation;
+ if (cal_data().pad_orientation != AltosLib.MISSING && accel_ground_along != AltosLib.MISSING) {
+ rotation = new AltosRotation(AltosIMU.convert_accel(accel_ground_across - cal_data().accel_zero_across),
+ AltosIMU.convert_accel(accel_ground_through - cal_data().accel_zero_through),
+ AltosIMU.convert_accel(accel_ground_along - cal_data().accel_zero_along),
+ cal_data().pad_orientation);
orient.set_computed(rotation.tilt(), time);
}
}
@@ -1253,197 +925,95 @@ public class AltosState implements Cloneable {
update_pad_rotation();
}
- public void set_pad_orientation(int pad_orientation) {
- this.pad_orientation = pad_orientation;
- update_pad_rotation();
- }
-
- public double gyro_zero_roll;
- public double gyro_zero_pitch;
- public double gyro_zero_yaw;
-
- public void set_gyro_zero(double roll, double pitch, double yaw) {
- if (roll != AltosLib.MISSING) {
- gyro_zero_roll = roll;
- gyro_zero_pitch = pitch;
- gyro_zero_yaw = yaw;
- }
- }
-
public double last_imu_time;
- private double radians(double degrees) {
- if (degrees == AltosLib.MISSING)
- return AltosLib.MISSING;
- return degrees * Math.PI / 180.0;
- }
-
private void update_orient() {
if (last_imu_time != AltosLib.MISSING) {
double t = time - last_imu_time;
- double pitch = radians(gyro_pitch());
- double yaw = radians(gyro_yaw());
- double roll = radians(gyro_roll());
+ if (t > 0 && gyro_pitch != AltosLib.MISSING && rotation != null) {
+ double pitch = AltosConvert.degrees_to_radians(gyro_pitch) * t;
+ double yaw = AltosConvert.degrees_to_radians(gyro_yaw) * t;
+ double roll = AltosConvert.degrees_to_radians(gyro_roll) * t;
- if (t > 0 & pitch != AltosLib.MISSING && rotation != null) {
- rotation.rotate(t, pitch, yaw, roll);
+ rotation.rotate(pitch, yaw, roll);
orient.set_computed(rotation.tilt(), time);
}
}
last_imu_time = time;
}
- public void set_imu(AltosIMU imu) {
- if (imu != null)
- imu = imu.clone();
- this.imu = imu;
+ private double gyro_roll, gyro_pitch, gyro_yaw;
+
+ public void set_gyro(double roll, double pitch, double yaw) {
+ gyro_roll = roll;
+ gyro_pitch = pitch;
+ gyro_yaw = yaw;
update_orient();
}
- private double gyro_zero_overflow(double first) {
- double v = first / 128.0;
- if (v < 0)
- v = Math.ceil(v);
- else
- v = Math.floor(v);
- return v * 128.0;
- }
+ private double accel_along, accel_across, accel_through;
- public void check_imu_wrap(AltosIMU imu) {
- if (this.imu == null) {
- gyro_zero_roll += gyro_zero_overflow(imu.gyro_roll);
- gyro_zero_pitch += gyro_zero_overflow(imu.gyro_pitch);
- gyro_zero_yaw += gyro_zero_overflow(imu.gyro_yaw);
- }
+ public void set_accel(double along, double across, double through) {
+ accel_along = along;
+ accel_across = across;
+ accel_through = through;
+ update_orient();
}
public double accel_along() {
- if (imu != null && accel_zero_along != AltosLib.MISSING)
- return AltosIMU.convert_accel(imu.accel_along - accel_zero_along);
- return AltosLib.MISSING;
+ return accel_along;
}
public double accel_across() {
- if (imu != null && accel_zero_across != AltosLib.MISSING)
- return AltosIMU.convert_accel(imu.accel_across - accel_zero_across);
- return AltosLib.MISSING;
+ return accel_across;
}
public double accel_through() {
- if (imu != null && accel_zero_through != AltosLib.MISSING)
- return AltosIMU.convert_accel(imu.accel_through - accel_zero_through);
- return AltosLib.MISSING;
+ return accel_through;
}
public double gyro_roll() {
- if (imu != null && gyro_zero_roll != AltosLib.MISSING) {
- return AltosIMU.convert_gyro(imu.gyro_roll - gyro_zero_roll);
- }
- return AltosLib.MISSING;
+ return gyro_roll;
}
public double gyro_pitch() {
- if (imu != null && gyro_zero_pitch != AltosLib.MISSING) {
- return AltosIMU.convert_gyro(imu.gyro_pitch - gyro_zero_pitch);
- }
- return AltosLib.MISSING;
+ return gyro_pitch;
}
public double gyro_yaw() {
- if (imu != null && gyro_zero_yaw != AltosLib.MISSING) {
- return AltosIMU.convert_gyro(imu.gyro_yaw - gyro_zero_yaw);
- }
- return AltosLib.MISSING;
+ return gyro_yaw;
}
- public void set_mag(AltosMag mag) {
- this.mag = mag.clone();
+ private double mag_along, mag_across, mag_through;
+
+ public void set_mag(double along, double across, double through) {
+ mag_along = along;
+ mag_across = across;
+ mag_through = through;
}
public double mag_along() {
- if (mag != null)
- return AltosMag.convert_gauss(mag.along);
- return AltosLib.MISSING;
+ return mag_along;
}
public double mag_across() {
- if (mag != null)
- return AltosMag.convert_gauss(mag.across);
- return AltosLib.MISSING;
+ return mag_across;
}
public double mag_through() {
- if (mag != null)
- return AltosMag.convert_gauss(mag.through);
- return AltosLib.MISSING;
- }
-
- public AltosMs5607 make_baro() {
- if (baro == null)
- baro = new AltosMs5607();
- return baro;
- }
-
- public void set_ms5607(AltosMs5607 ms5607) {
- baro = ms5607;
-
- if (baro != null) {
- set_pressure(baro.pa);
- set_temperature(baro.cc / 100.0);
- }
- }
-
- public void set_ms5607(int pres, int temp) {
- if (baro != null) {
- baro.set(pres, temp);
-
- set_pressure(baro.pa);
- set_temperature(baro.cc / 100.0);
- }
+ return mag_through;
}
public void set_companion(AltosCompanion companion) {
this.companion = companion;
}
- void update_accel() {
- if (accel == AltosLib.MISSING)
- return;
- if (accel_plus_g == AltosLib.MISSING)
- return;
- if (accel_minus_g == AltosLib.MISSING)
- return;
-
- double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0;
- double counts_per_mss = counts_per_g / 9.80665;
- acceleration.set_measured((accel_plus_g - accel) / counts_per_mss, time);
- }
-
- public void set_accel_g(double accel_plus_g, double accel_minus_g) {
- if (accel_plus_g != AltosLib.MISSING) {
- this.accel_plus_g = accel_plus_g;
- this.accel_minus_g = accel_minus_g;
- update_accel();
- }
- }
-
- public void set_ground_accel(double ground_accel) {
- if (ground_accel != AltosLib.MISSING)
- this.ground_accel = ground_accel;
- }
-
- public void set_accel(double accel) {
- if (accel != AltosLib.MISSING) {
- this.accel = accel;
- if (state == AltosLib.ao_flight_pad) {
- if (ground_accel_avg == AltosLib.MISSING)
- ground_accel_avg = accel;
- else
- ground_accel_avg = (ground_accel_avg * 7 + accel) / 8;
- }
+ public void set_acceleration(double acceleration) {
+ if (acceleration != AltosLib.MISSING) {
+ this.acceleration.set_measured(acceleration, time);
+ set |= set_data;
}
- update_accel();
}
public void set_temperature(double temperature) {
@@ -1481,78 +1051,21 @@ public class AltosState implements Cloneable {
}
}
- public void set_ignitor_voltage(double[] voltage) {
- this.ignitor_voltage = voltage;
+ public void set_igniter_voltage(double[] voltage) {
+ this.igniter_voltage = voltage;
}
public void set_pyro_fired(int fired) {
this.pyro_fired = fired;
}
- public double time_since_boost() {
- if (tick == AltosLib.MISSING)
- return 0.0;
-
- if (boost_tick == AltosLib.MISSING)
- return tick / 100.0;
- return (tick - boost_tick) / 100.0;
- }
-
- public boolean valid() {
- return tick != AltosLib.MISSING && serial != AltosLib.MISSING;
- }
-
- public AltosGPS make_temp_gps(boolean sats) {
- if (temp_gps == null) {
- temp_gps = new AltosGPS(gps);
- }
- gps_pending = true;
- if (sats) {
- if (tick != temp_gps_sat_tick)
- temp_gps.cc_gps_sat = null;
- temp_gps_sat_tick = tick;
- }
- return temp_gps;
- }
-
- public void set_temp_gps() {
- set_gps(temp_gps, gps_sequence + 1);
- gps_pending = false;
- temp_gps = null;
- }
-
- public AltosState clone() {
- AltosState s = new AltosState();
- s.copy(this);
-
- /* Code to test state save/restore. Enable only for that purpose
- */
- if (false) {
- AltosJson json = new AltosJson(this);
- String onetrip = json.toPrettyString();
- AltosJson back = AltosJson.fromString(onetrip);
- AltosState tripstate = (AltosState) back.make(this.getClass());
- AltosJson tripjson = new AltosJson(tripstate);
- String twotrip = tripjson.toPrettyString();
-
- if (!onetrip.equals(twotrip)) {
- try {
- FileWriter one_file = new FileWriter("one.json", true);
- one_file.write(onetrip);
- one_file.flush();
- FileWriter two_file = new FileWriter("two.json", true);
- two_file.write(twotrip);
- two_file.flush();
- } catch (Exception e) {
- }
- System.out.printf("json error\n");
- System.exit(1);
- }
- }
- return s;
+ public AltosState() {
+ Thread.dumpStack();
+ init();
}
- public AltosState () {
+ public AltosState (AltosCalData cal_data) {
+ super(cal_data);
init();
}
}
diff --git a/altoslib/AltosStateName.java b/altoslib/AltosStateName.java
new file mode 100644
index 00000000..5ba21f27
--- /dev/null
+++ b/altoslib/AltosStateName.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosStateName extends AltosUnits {
+
+ public double value(double v, boolean imperial_units) { return v; }
+
+ public double inverse(double v, boolean imperial_units) { return v; }
+
+ public String string_value(double v, boolean imperial_units) {
+ return AltosLib.state_name((int) v);
+ }
+
+ public String show_units(boolean imperial_units) { return "state"; }
+
+ public String say_units(boolean imperial_units) { return "state"; }
+
+ public int show_fraction(int width, boolean imperial_units) { return 0; }
+}
diff --git a/altoslib/AltosStringInputStream.java b/altoslib/AltosStringInputStream.java
new file mode 100644
index 00000000..48fff3ea
--- /dev/null
+++ b/altoslib/AltosStringInputStream.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+import java.util.*;
+import java.io.*;
+
+public class AltosStringInputStream extends InputStream {
+
+ String s;
+ int at;
+ int mark;
+
+ public int available() {
+ return s.length() - at;
+ }
+
+ public void mark(int read_limit) {
+ mark = at;
+ }
+
+ public boolean markSupported() {
+ return true;
+ }
+
+ public int read() {
+ if (at == s.length())
+ return -1;
+ return (int) s.charAt(at++);
+ }
+
+ public void reset() {
+ at = mark;
+ }
+
+ public long skip(long n) throws IOException {
+ if (n < 0) n = 0;
+
+ if (at + n > s.length())
+ n = s.length() - at;
+ at += n;
+ return n;
+ }
+
+ public AltosStringInputStream(String s) {
+ this.s = s;
+ this.at = 0;
+ }
+}
diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java
index f830bf35..7d576942 100644
--- a/altoslib/AltosTelemetry.java
+++ b/altoslib/AltosTelemetry.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
@@ -24,13 +24,16 @@ import java.text.*;
* Telemetry data contents
*/
-public abstract class AltosTelemetry implements AltosStateUpdate {
+public abstract class AltosTelemetry implements AltosDataProvider {
+ int[] bytes;
/* All telemetry packets have these fields */
- public int tick;
- public int serial;
- public int rssi;
- public int status;
+ public int rssi() { return AltosConvert.telem_to_rssi(AltosLib.int8(bytes, bytes.length - 3)); }
+ public int status() { return AltosLib.uint8(bytes, bytes.length - 2); }
+
+ /* All telemetry packets report these fields in some form */
+ public abstract int serial();
+ public abstract int tick();
/* Mark when we received the packet */
long received_time;
@@ -43,13 +46,13 @@ public abstract class AltosTelemetry implements AltosStateUpdate {
return sum == bytes[bytes.length - 1];
}
- public void update_state(AltosState state) {
- state.set_serial(serial);
- if (state.state() == AltosLib.ao_flight_invalid)
- state.set_state(AltosLib.ao_flight_startup);
- state.set_tick(tick);
- state.set_rssi(rssi, status);
- state.set_received_time(received_time);
+ public void provide_data(AltosDataListener listener) {
+ listener.set_serial(serial());
+ if (listener.state == AltosLib.ao_flight_invalid)
+ listener.set_state(AltosLib.ao_flight_startup);
+ listener.set_tick(tick());
+ listener.set_rssi(rssi(), status());
+ listener.set_received_time(received_time);
}
final static int PKT_APPEND_STATUS_1_CRC_OK = (1 << 7);
@@ -88,12 +91,6 @@ public abstract class AltosTelemetry implements AltosStateUpdate {
if (!cksum(bytes))
throw new ParseException(String.format("invalid line \"%s\"", hex), 0);
- int rssi = AltosLib.int8(bytes, bytes.length - 3) / 2 - 74;
- int status = AltosLib.uint8(bytes, bytes.length - 2);
-
- if ((status & PKT_APPEND_STATUS_1_CRC_OK) == 0)
- throw new AltosCRCException(rssi);
-
/* length, data ..., rssi, status, checksum -- 4 bytes extra */
switch (bytes.length) {
case AltosLib.ao_telemetry_standard_len + 4:
@@ -108,35 +105,18 @@ public abstract class AltosTelemetry implements AltosStateUpdate {
default:
throw new ParseException(String.format("Invalid packet length %d", bytes.length), 0);
}
- if (telem != null) {
- telem.received_time = System.currentTimeMillis();
- telem.rssi = rssi;
- telem.status = status;
- }
return telem;
}
- public static int extend_height(AltosState state, int height_16) {
- double compare_height;
- int height = height_16;
-
- if (state.gps != null && state.gps.alt != AltosLib.MISSING) {
- compare_height = state.gps_height();
- } else {
- compare_height = state.height();
- }
-
- if (compare_height != AltosLib.MISSING) {
- int high_bits = (int) Math.floor (compare_height / 65536.0);
-
- height = (high_bits << 16) | (height_16 & 0xffff);
+ public AltosTelemetry() {
+ this.received_time = System.currentTimeMillis();
+ }
- if (Math.abs(height + 65536 - compare_height) < Math.abs(height - compare_height))
- height += 65536;
- else if (Math.abs(height - 65536 - compare_height) < Math.abs(height - compare_height))
- height -= 65536;
- }
- return height;
+ public AltosTelemetry(int[] bytes) throws AltosCRCException {
+ this();
+ this.bytes = bytes;
+ if ((status() & PKT_APPEND_STATUS_1_CRC_OK) == 0)
+ throw new AltosCRCException(rssi());
}
public static AltosTelemetry parse(String line) throws ParseException, AltosCRCException {
@@ -149,7 +129,7 @@ public abstract class AltosTelemetry implements AltosStateUpdate {
throw new AltosCRCException(AltosParse.parse_int(word[i++]));
}
- AltosTelemetry telem;
+ AltosTelemetry telem = null;
if (word[i].equals("TELEM")) {
telem = parse_hex(word[i+1]);
diff --git a/altoslib/AltosTelemetryCompanion.java b/altoslib/AltosTelemetryCompanion.java
index a97fda2d..c6dfe3eb 100644
--- a/altoslib/AltosTelemetryCompanion.java
+++ b/altoslib/AltosTelemetryCompanion.java
@@ -16,24 +16,19 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryCompanion extends AltosTelemetryStandard {
- AltosCompanion companion;
-
- static final public int max_channels = 12;
-
- public AltosTelemetryCompanion(int[] bytes) {
- super(bytes);
+ AltosCompanion companion() {
int channels = uint8(7);
if (channels > max_channels)
channels = max_channels;
- companion = new AltosCompanion(channels);
+ AltosCompanion companion = new AltosCompanion(channels);
- companion.tick = tick;
+ companion.tick = tick();
companion.board_id = uint8(5);
companion.update_period = uint8(6);
@@ -45,11 +40,17 @@ public class AltosTelemetryCompanion extends AltosTelemetryStandard {
for (int i = 0; i < channels; i++)
companion.companion_data[i] = uint16(8 + i * 2);
}
+ return companion;
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ static final public int max_channels = 12;
+
+ public AltosTelemetryCompanion(int[] bytes) throws AltosCRCException {
+ super(bytes);
+ }
- state.set_companion(companion);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
+ listener.set_companion(companion());
}
}
diff --git a/altoslib/AltosTelemetryConfiguration.java b/altoslib/AltosTelemetryConfiguration.java
index 6ded5461..ea307442 100644
--- a/altoslib/AltosTelemetryConfiguration.java
+++ b/altoslib/AltosTelemetryConfiguration.java
@@ -16,47 +16,39 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryConfiguration extends AltosTelemetryStandard {
- int device_type;
- int flight;
- int config_major;
- int config_minor;
- int apogee_delay;
- int main_deploy;
- int v_batt;
- int flight_log_max;
- String callsign;
- String version;
-
- public AltosTelemetryConfiguration(int[] bytes) {
- super(bytes);
+ int device_type() { return uint8(5); }
+ int flight() { return uint16(6); }
+ int config_major() { return uint8(8); }
+ int config_minor() { return uint8(9); }
+ int apogee_delay() { return uint16(10); }
+ int main_deploy() { return uint16(12); }
+ int v_batt() { return uint16(10); }
+ int flight_log_max() { return uint16(14); }
+ String callsign() { return string(16, 8); }
+ String version() { return string(24, 8); }
- device_type = uint8(5);
- flight = uint16(6);
- config_major = uint8(8);
- config_minor = uint8(9);
- v_batt = uint16(10);
- apogee_delay = uint16(10);
- main_deploy = uint16(12);
- flight_log_max = uint16(14);
- callsign = string(16, 8);
- version = string(24, 8);
+ public AltosTelemetryConfiguration(int[] bytes) throws AltosCRCException {
+ super(bytes);
}
- public void update_state(AltosState state) {
- super.update_state(state);
- state.set_device_type(device_type);
- state.set_flight(flight);
- state.set_config(config_major, config_minor, flight_log_max);
- if (device_type == AltosLib.product_telegps)
- state.set_battery_voltage(AltosConvert.tele_gps_voltage(v_batt));
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
+
+ AltosCalData cal_data = listener.cal_data();
+
+ cal_data.set_device_type(device_type());
+ cal_data.set_flight(flight());
+ cal_data.set_config(config_major(), config_minor(), flight_log_max());
+ if (device_type() == AltosLib.product_telegps)
+ listener.set_battery_voltage(AltosConvert.tele_gps_voltage(v_batt()));
else
- state.set_flight_params(apogee_delay, main_deploy);
+ cal_data.set_flight_params(apogee_delay() / 100.0, main_deploy());
- state.set_callsign(callsign);
- state.set_firmware_version(version);
+ cal_data.set_callsign(callsign());
+ cal_data.set_firmware_version(version());
}
}
diff --git a/altoslib/AltosTelemetryFile.java b/altoslib/AltosTelemetryFile.java
index 9c5f8dae..135b0284 100644
--- a/altoslib/AltosTelemetryFile.java
+++ b/altoslib/AltosTelemetryFile.java
@@ -16,82 +16,125 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
import java.text.*;
-class AltosTelemetryIterator implements Iterator<AltosState> {
- AltosState state;
- Iterator<AltosTelemetry> telems;
- AltosTelemetry next;
- boolean seen;
-
- public boolean hasNext() {
- return !seen || telems.hasNext();
- }
-
- public AltosState next() {
- if (seen) {
- AltosState n = state.clone();
- AltosTelemetry t = telems.next();
-
- t.update_state(n);
- state = n;
- }
- seen = true;
- return state;
+class AltosTelemetryNullListener extends AltosDataListener {
+ public void set_rssi(int rssi, int status) { }
+ public void set_received_time(long received_time) { }
+
+ public void set_acceleration(double accel) { }
+ public void set_pressure(double pa) { }
+ public void set_thrust(double N) { }
+
+ public void set_kalman(double height, double speed, double accel) { }
+
+ public void set_temperature(double deg_c) { }
+ public void set_battery_voltage(double volts) { }
+
+ public void set_apogee_voltage(double volts) { }
+ public void set_main_voltage(double volts) { }
+
+ public void set_gps(AltosGPS gps) { }
+
+ public void set_orient(double orient) { }
+ public void set_gyro(double roll, double pitch, double yaw) { }
+ public void set_accel_ground(double along, double across, double through) { }
+ public void set_accel(double along, double across, double through) { }
+ public void set_mag(double along, double across, double through) { }
+ public void set_pyro_voltage(double volts) { }
+ public void set_igniter_voltage(double[] voltage) { }
+ public void set_pyro_fired(int pyro_mask) { }
+ public void set_companion(AltosCompanion companion) { }
+
+ public boolean cal_data_complete() {
+ /* All telemetry packets */
+ AltosCalData cal_data = cal_data();
+
+ if (cal_data.serial == AltosLib.MISSING)
+ return false;
+
+ if (cal_data.boost_tick == AltosLib.MISSING)
+ return false;
+
+ /*
+ * TelemetryConfiguration:
+ *
+ * device_type, flight, config version, log max,
+ * flight params, callsign and version
+ */
+ if (cal_data.device_type == AltosLib.MISSING)
+ return false;
+
+ /*
+ * TelemetrySensor or TelemetryMegaData:
+ *
+ * ground_accel, accel+/-, ground pressure
+ */
+ if (cal_data.ground_pressure == AltosLib.MISSING)
+ return false;
+
+ /*
+ * TelemetryLocation
+ */
+ if (AltosLib.has_gps(cal_data.device_type) && cal_data.gps_pad == null)
+ return false;
+
+ return true;
}
- public void remove () {
- }
-
- public AltosTelemetryIterator(AltosState start, Iterator<AltosTelemetry> telems) {
- this.state = start;
- this.telems = telems;
- this.seen = false;
+ public AltosTelemetryNullListener(AltosCalData cal_data) {
+ super(cal_data);
}
}
-public class AltosTelemetryFile extends AltosStateIterable {
+public class AltosTelemetryFile implements AltosRecordSet {
AltosTelemetryIterable telems;
- AltosState start;
+ AltosCalData cal_data;
public void write_comments(PrintStream out) {
}
public void write(PrintStream out) {
-
}
- public AltosTelemetryFile(FileInputStream input) {
- telems = new AltosTelemetryIterable(input);
- start = new AltosState();
-
- /* Find boost tick */
- AltosState state = start.clone();
+ /* Construct cal data by walking through the telemetry data until we've found everything available */
+ public AltosCalData cal_data() {
+ if (cal_data == null) {
+ cal_data = new AltosCalData();
+ AltosTelemetryNullListener l = new AltosTelemetryNullListener(cal_data);
- for (AltosTelemetry telem : telems) {
- telem.update_state(state);
- state.finish_update();
- if (state.state() != AltosLib.ao_flight_invalid && state.state() >= AltosLib.ao_flight_boost) {
- start.set_boost_tick(state.tick);
- break;
+ for (AltosTelemetry telem : telems) {
+ telem.provide_data(l);
+ if (l.cal_data_complete())
+ break;
}
}
+ return cal_data;
}
- public Iterator<AltosState> iterator() {
- AltosState state = start.clone();
- Iterator<AltosTelemetry> i = telems.iterator();
+ public void capture_series(AltosDataListener listener) {
+ AltosCalData cal_data = cal_data();
+
+ cal_data.reset();
+ for (AltosTelemetry telem : telems) {
+ int tick = telem.tick();
+ cal_data.set_tick(tick);
- while (i.hasNext() && !state.valid()) {
- AltosTelemetry t = i.next();
- t.update_state(state);
- state.finish_update();
+ /* Try to pick up at least one pre-boost value */
+ if (cal_data.time() >= -2)
+ telem.provide_data(listener);
+ if (listener.state == AltosLib.ao_flight_landed)
+ break;
}
- return new AltosTelemetryIterator(state, i);
+ listener.finish();
+ }
+
+ public AltosTelemetryFile(FileInputStream input) throws IOException {
+ telems = new AltosTelemetryIterable(input);
}
}
diff --git a/altoslib/AltosTelemetryIterable.java b/altoslib/AltosTelemetryIterable.java
index 0cba86a3..d3e4ce67 100644
--- a/altoslib/AltosTelemetryIterable.java
+++ b/altoslib/AltosTelemetryIterable.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
@@ -67,7 +67,7 @@ public class AltosTelemetryIterable implements Iterable<AltosTelemetry> {
int index;
public void add (AltosTelemetry telem) {
- int t = telem.tick;
+ int t = telem.tick();
if (!telems.isEmpty()) {
while (t < tick - 1000)
t += 65536;
@@ -80,29 +80,25 @@ public class AltosTelemetryIterable implements Iterable<AltosTelemetry> {
return new AltosTelemetryOrderedIterator(telems);
}
- public AltosTelemetryIterable (FileInputStream input) {
+ public AltosTelemetryIterable (FileInputStream input) throws IOException {
telems = new TreeSet<AltosTelemetryOrdered> ();
tick = 0;
index = 0;
- try {
- for (;;) {
- String line = AltosLib.gets(input);
- if (line == null) {
+ for (;;) {
+ String line = AltosLib.gets(input);
+ if (line == null) {
+ break;
+ }
+ try {
+ AltosTelemetry telem = AltosTelemetry.parse(line);
+ if (telem == null)
break;
- }
- try {
- AltosTelemetry telem = AltosTelemetry.parse(line);
- if (telem == null)
- break;
- add(telem);
- } catch (ParseException pe) {
- System.out.printf("parse exception %s\n", pe.getMessage());
- } catch (AltosCRCException ce) {
- }
+ add(telem);
+ } catch (ParseException pe) {
+ System.out.printf("parse exception %s\n", pe.getMessage());
+ } catch (AltosCRCException ce) {
}
- } catch (IOException io) {
- System.out.printf("io exception\n");
}
}
}
diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java
index 08c52986..027f601e 100644
--- a/altoslib/AltosTelemetryLegacy.java
+++ b/altoslib/AltosTelemetryLegacy.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
@@ -233,6 +233,17 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
final static String AO_TELEM_SAT_SVID = "s_v";
final static String AO_TELEM_SAT_C_N_0 = "s_c";
+ public int tick;
+ public int serial;
+ public int rssi;
+ public int status;
+
+ public int tick() { return tick; }
+ public int serial() { return serial; }
+
+ public int rssi() { return rssi; }
+ public int status() { return status; }
+
public int version;
public String callsign;
public int flight;
@@ -271,7 +282,6 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
flight = map.get_int(AO_TELEM_FLIGHT, AltosLib.MISSING);
rssi = map.get_int(AO_TELEM_RSSI, AltosLib.MISSING);
state = AltosLib.state(map.get_string(AO_TELEM_STATE, "invalid"));
- tick = map.get_int(AO_TELEM_TICK, 0);
/* raw sensor values */
accel = map.get_int(AO_TELEM_RAW_ACCEL, AltosLib.MISSING);
@@ -420,7 +430,6 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
* Given a hex dump of a legacy telemetry line, construct an AltosRecordTM from that
*/
- int[] bytes;
int adjust;
/*
@@ -452,8 +461,9 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
static final int AO_GPS_DATE_VALID = (1 << 6);
static final int AO_GPS_COURSE_VALID = (1 << 7);
- public AltosTelemetryLegacy(int[] in_bytes) {
- bytes = in_bytes;
+ public AltosTelemetryLegacy(int[] in_bytes) throws AltosCRCException {
+ super(in_bytes);
+
version = 4;
adjust = 0;
@@ -463,6 +473,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
} else
serial = uint16(0);
+ rssi = super.rssi();
callsign = string(62, 8);
flight = uint16(2);
state = uint8(4);
@@ -537,23 +548,26 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
}
}
- public void update_state(AltosState state) {
- state.set_tick(tick);
- state.set_state(this.state);
- state.set_flight(flight);
- state.set_serial(serial);
- state.set_rssi(rssi, status);
+ public void provide_data(AltosDataListener listener) {
+ listener.set_serial(serial);
+ listener.set_tick(tick);
+ listener.set_state(this.state);
+ listener.set_flight(flight);
+ listener.set_rssi(rssi, status);
+
+ listener.set_pressure(AltosConvert.barometer_to_pressure(pres));
+
+ AltosCalData cal_data = listener.cal_data();
- state.set_pressure(AltosConvert.barometer_to_pressure(pres));
- state.set_accel_g(accel_plus_g, accel_minus_g);
- state.set_accel(accel);
+ cal_data.set_accel_plus_minus(accel_plus_g, accel_minus_g);
+ listener.set_acceleration(cal_data.acceleration(accel));
if (kalman_height != AltosLib.MISSING)
- state.set_kalman(kalman_height, kalman_speed, kalman_acceleration);
- state.set_temperature(AltosConvert.thermometer_to_temperature(temp));
- state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(batt));
- state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(apogee));
- state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(main));
+ listener.set_kalman(kalman_height, kalman_speed, kalman_acceleration);
+ listener.set_temperature(AltosConvert.thermometer_to_temperature(temp));
+ listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(batt));
+ listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(apogee));
+ listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(main));
if (gps != null)
- state.set_gps(gps, gps_sequence);
+ listener.set_gps(gps);
}
}
diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java
index 11995640..f4366e33 100644
--- a/altoslib/AltosTelemetryLocation.java
+++ b/altoslib/AltosTelemetryLocation.java
@@ -16,81 +16,73 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryLocation extends AltosTelemetryStandard {
- int flags;
- int altitude;
- int latitude;
- int longitude;
- int year;
- int month;
- int day;
- int hour;
- int minute;
- int second;
- int pdop;
- int hdop;
- int vdop;
- int mode;
- int ground_speed;
- int climb_rate;
- int course;
+ int flags() { return uint8(5); }
+ int altitude() {
+ if ((mode() & AO_GPS_MODE_ALTITUDE_24) != 0)
+ return (int8(31) << 16) | uint16(6);
+ else
+ return int16(6);
+ }
+ int latitude() { return uint32(8); }
+ int longitude() { return uint32(12); }
+ int year() { return uint8(16); }
+ int month() { return uint8(17); }
+ int day() { return uint8(18); }
+ int hour() { return uint8(19); }
+ int minute() { return uint8(20); }
+ int second() { return uint8(21); }
+ int pdop() { return uint8(22); }
+ int hdop() { return uint8(23); }
+ int vdop() { return uint8(24); }
+ int mode() { return uint8(25); }
+ int ground_speed() { return uint16(26); }
+ int climb_rate() { return int16(28); }
+ int course() { return uint8(30); }
public static final int AO_GPS_MODE_ALTITUDE_24 = (1 << 0); /* Reports 24-bits of altitude */
- public AltosTelemetryLocation(int[] bytes) {
+ public AltosTelemetryLocation(int[] bytes) throws AltosCRCException {
super(bytes);
+ }
- flags = uint8(5);
- latitude = uint32(8);
- longitude = uint32(12);
- year = uint8(16);
- month = uint8(17);
- day = uint8(18);
- hour = uint8(19);
- minute = uint8(20);
- second = uint8(21);
- pdop = uint8(22);
- hdop = uint8(23);
- vdop = uint8(24);
- mode = uint8(25);
- ground_speed = uint16(26);
- climb_rate = int16(28);
- course = uint8(30);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
- if ((mode & AO_GPS_MODE_ALTITUDE_24) != 0) {
- altitude = (int8(31) << 16) | uint16(6);
- } else
- altitude = int16(6);
- }
+ AltosCalData cal_data = listener.cal_data();
- public void update_state(AltosState state) {
- super.update_state(state);
- AltosGPS gps = state.make_temp_gps(false);
+ AltosGPS gps = cal_data.make_temp_gps(tick(), false);
+ int flags = flags();
gps.nsat = flags & 0xf;
gps.locked = (flags & (1 << 4)) != 0;
gps.connected = (flags & (1 << 5)) != 0;
+ gps.pdop = pdop() / 10.0;
+ gps.hdop = hdop() / 10.0;
+ gps.vdop = vdop() / 10.0;
if (gps.locked) {
- gps.lat = latitude * 1.0e-7;
- gps.lon = longitude * 1.0e-7;
- gps.alt = altitude;
- gps.year = 2000 + year;
- gps.month = month;
- gps.day = day;
- gps.hour = hour;
- gps.minute = minute;
- gps.second = second;
- gps.ground_speed = ground_speed * 1.0e-2;
- gps.course = course * 2;
- gps.climb_rate = climb_rate * 1.0e-2;
- gps.pdop = pdop / 10.0;
- gps.hdop = hdop / 10.0;
- gps.vdop = vdop / 10.0;
+ gps.lat = latitude() * 1.0e-7;
+ gps.lon = longitude() * 1.0e-7;
+ gps.alt = altitude();
+ gps.year = 2000 + year();
+ gps.month = month();
+ gps.day = day();
+ gps.hour = hour();
+ gps.minute = minute();
+ gps.second = second();
+ gps.ground_speed = ground_speed() * 1.0e-2;
+ gps.course = course() * 2;
+ gps.climb_rate = climb_rate() * 1.0e-2;
+
+ if (gps.nsat >= 4)
+ cal_data.set_gps(gps);
}
- state.set_temp_gps();
+ listener.set_gps(gps);
+ cal_data.set_gps(gps);
+ cal_data.reset_temp_gps();
}
}
diff --git a/altoslib/AltosTelemetryMap.java b/altoslib/AltosTelemetryMap.java
index c8185434..a7ddc684 100644
--- a/altoslib/AltosTelemetryMap.java
+++ b/altoslib/AltosTelemetryMap.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.util.HashMap;
diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java
index 6ea5ec89..7ef9c637 100644
--- a/altoslib/AltosTelemetryMegaData.java
+++ b/altoslib/AltosTelemetryMegaData.java
@@ -16,78 +16,58 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryMegaData extends AltosTelemetryStandard {
- int state;
- int v_batt;
- int v_pyro;
- int sense[];
+ int state() { return uint8(5); }
- int ground_pres;
- int ground_accel;
- int accel_plus_g;
- int accel_minus_g;
+ int v_batt() { return int16(6); }
+ int v_pyro() { return int16(8); }
+ int sense(int i) { int v = uint8(10+i); return v << 4 | v >> 8; }
- int acceleration;
- int speed;
- int height_16;
+ int ground_pres() { return int32(16); }
+ int ground_accel() { return int16(20); }
+ int accel_plus_g() { return int16(22); }
+ int accel_minus_g() { return int16(24);}
- public AltosTelemetryMegaData(int[] bytes) {
- super(bytes);
-
- state = uint8(5);
-
- v_batt = int16(6);
- v_pyro = int16(8);
-
- sense = new int[6];
-
- for (int i = 0; i < 6; i++) {
- sense[i] = uint8(10 + i) << 4;
- sense[i] |= sense[i] >> 8;
- }
+ int acceleration() { return int16(26); }
+ int speed() { return int16(28); }
+ int height_16() { return int16(30); }
- ground_pres = int32(16);
- ground_accel = int16(20);
- accel_plus_g = int16(22);
- accel_minus_g = int16(24);
-
- acceleration = int16(26);
- speed = int16(28);
-
- height_16 = int16(30);
+ public AltosTelemetryMegaData(int[] bytes) throws AltosCRCException {
+ super(bytes);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
- state.set_state(this.state);
+ listener.set_state(state());
- state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt));
- state.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pyro));
+ listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
+ listener.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pyro()));
- state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense[4]));
- state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense[5]));
+ listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense(4)));
+ listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense(5)));
double voltages[] = new double[4];
for (int i = 0; i < 4; i++)
- voltages[i] = AltosConvert.mega_pyro_voltage(sense[i]);
+ voltages[i] = AltosConvert.mega_pyro_voltage(sense(i));
+
+ listener.set_igniter_voltage(voltages);
- state.set_ignitor_voltage(voltages);
+ AltosCalData cal_data = listener.cal_data();
- state.set_ground_accel(ground_accel);
- state.set_ground_pressure(ground_pres);
- state.set_accel_g(accel_plus_g, accel_minus_g);
+ cal_data.set_ground_accel(ground_accel());
+ cal_data.set_ground_pressure(ground_pres());
+ cal_data.set_accel_plus_minus(accel_plus_g(), accel_minus_g());
/* Fill in the high bits of height from recent GPS
* data if available, otherwise guess using the
* previous kalman height
*/
- state.set_kalman(extend_height(state, height_16),
- speed/16.0, acceleration / 16.0);
+ listener.set_kalman(height_16(), speed()/16.0, acceleration() / 16.0);
}
}
diff --git a/altoslib/AltosTelemetryMegaSensor.java b/altoslib/AltosTelemetryMegaSensor.java
index 2dfc455a..4c64b554 100644
--- a/altoslib/AltosTelemetryMegaSensor.java
+++ b/altoslib/AltosTelemetryMegaSensor.java
@@ -16,64 +16,68 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryMegaSensor extends AltosTelemetryStandard {
- int accel;
- int pres;
- int temp;
+ int orient() { return int8(5); }
- int accel_x;
- int accel_y;
- int accel_z;
+ int accel() { return int16(6); }
+ int pres() { return int32(8); }
+ int temp() { return int16(12); }
- int gyro_x;
- int gyro_y;
- int gyro_z;
+ int accel_x() { return int16(14); }
+ int accel_y() { return int16(16); }
+ int accel_z() { return int16(18); }
- int mag_x;
- int mag_y;
- int mag_z;
+ int gyro_x() { return int16(20); }
+ int gyro_y() { return int16(22); }
+ int gyro_z() { return int16(24); }
- int orient;
+ int mag_x() { return int16(26); }
+ int mag_z() { return int16(28); }
+ int mag_y() { return int16(30); }
- public AltosTelemetryMegaSensor(int[] bytes) {
+ public AltosTelemetryMegaSensor(int[] bytes) throws AltosCRCException {
super(bytes);
+ }
- orient = int8(5);
- accel = int16(6);
- pres = int32(8);
- temp = int16(12);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
- accel_x = int16(14);
- accel_y = int16(16);
- accel_z = int16(18);
+ AltosCalData cal_data = listener.cal_data();
- gyro_x = int16(20);
- gyro_y = int16(22);
- gyro_z = int16(24);
+ listener.set_acceleration(cal_data.acceleration(accel()));
+ listener.set_pressure(pres());
+ listener.set_temperature(temp() / 100.0);
- mag_x = int16(26);
- mag_y = int16(28);
- mag_z = int16(30);
- }
+ listener.set_orient(orient());
- public void update_state(AltosState state) {
- super.update_state(state);
+ /* XXX we have no calibration data for these values */
- state.set_accel(accel);
- state.set_pressure(pres);
- state.set_temperature(temp / 100.0);
+ if (cal_data.accel_zero_along == AltosLib.MISSING)
+ cal_data.set_accel_zero(0, 0, 0);
+ if (cal_data.gyro_zero_roll == AltosLib.MISSING)
+ cal_data.set_gyro_zero(0, 0, 0);
- state.set_orient(orient);
+ int accel_along = accel_y();
+ int accel_across = accel_x();
+ int accel_through = accel_z();
+ int gyro_roll = gyro_y();
+ int gyro_pitch = gyro_x();
+ int gyro_yaw = gyro_z();
- state.set_imu(new AltosIMU(accel_y, /* along */
- accel_x, /* across */
- accel_z, /* through */
- gyro_y, /* along */
- gyro_x, /* across */
- gyro_z)); /* through */
+ int mag_along = mag_y();
+ int mag_across = mag_x();
+ int mag_through = mag_z();
- state.set_mag(new AltosMag(mag_x, mag_y, mag_z));
+ listener.set_accel(cal_data.accel_along(accel_along),
+ cal_data.accel_across(accel_across),
+ cal_data.accel_through(accel_through));
+ listener.set_gyro(cal_data.gyro_roll(gyro_roll),
+ cal_data.gyro_pitch(gyro_pitch),
+ cal_data.gyro_yaw(gyro_yaw));
+ listener.set_mag(cal_data.mag_along(mag_along),
+ cal_data.mag_across(mag_across),
+ cal_data.mag_through(mag_through));
}
}
diff --git a/altoslib/AltosTelemetryMetrumData.java b/altoslib/AltosTelemetryMetrumData.java
index 53a10cc4..8cd09b41 100644
--- a/altoslib/AltosTelemetryMetrumData.java
+++ b/altoslib/AltosTelemetryMetrumData.java
@@ -16,28 +16,23 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryMetrumData extends AltosTelemetryStandard {
- int ground_pres;
- int ground_accel;
- int accel_plus_g;
- int accel_minus_g;
+ int ground_pres() { return int32(8); }
+ int ground_accel() { return int16(12); }
+ int accel_plus_g() { return int16(14); }
+ int accel_minus_g() { return int16(16); }
- public AltosTelemetryMetrumData(int[] bytes) {
+ public AltosTelemetryMetrumData(int[] bytes) throws AltosCRCException {
super(bytes);
-
- ground_pres = int32(8);
- ground_accel = int16(12);
- accel_plus_g = int16(14);
- accel_minus_g = int16(16);
}
- public void update_state(AltosState state) {
- state.set_ground_accel(ground_accel);
- state.set_accel_g(accel_plus_g, accel_minus_g);
- state.set_ground_pressure(ground_pres);
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ cal_data.set_ground_accel(ground_accel());
+ cal_data.set_accel_plus_minus(accel_plus_g(), accel_minus_g());
+ cal_data.set_ground_pressure(ground_pres());
}
}
diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java
index e15043b4..79d3a499 100644
--- a/altoslib/AltosTelemetryMetrumSensor.java
+++ b/altoslib/AltosTelemetryMetrumSensor.java
@@ -16,56 +16,42 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {
- int state;
+ int state() { return uint8(5); }
- int accel;
- int pres;
- int temp;
+ int accel() { return int16(6); }
+ int pres() { return int32(8); }
+ int temp() { return int16(12); }
- int acceleration;
- int speed;
- int height_16;
+ int acceleration() { return int16(14); }
+ int speed() { return int16(16); }
+ int height_16() { return int16(18); }
- int v_batt;
- int sense_a;
- int sense_m;
+ int v_batt() { return int16(20); }
+ int sense_a() { return int16(22); }
+ int sense_m() { return int16(24); }
- public AltosTelemetryMetrumSensor(int[] bytes) {
+ public AltosTelemetryMetrumSensor(int[] bytes) throws AltosCRCException {
super(bytes);
-
- state = int8(5);
- accel = int16(6);
- pres = int32(8);
- temp = int16(12);
-
- acceleration = int16(14);
- speed = int16(16);
- height_16 = int16(18);
-
- v_batt = int16(20);
- sense_a = int16(22);
- sense_m = int16(24);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
- state.set_state(this.state);
+ listener.set_state(state());
- state.set_accel(accel);
- state.set_pressure(pres);
- state.set_temperature(temp/100.0);
+ listener.set_acceleration(listener.cal_data().acceleration(accel()));
+ listener.set_pressure(pres());
+ listener.set_temperature(temp()/100.0);
- state.set_kalman(extend_height(state, height_16),
- speed/16.0, acceleration/16.0);
+ listener.set_kalman(height_16(), speed()/16.0, acceleration()/16.0);
- state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt));
+ listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
- state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a));
- state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m));
+ listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a()));
+ listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m()));
}
}
diff --git a/altoslib/AltosTelemetryMini2.java b/altoslib/AltosTelemetryMini2.java
index 50ec504d..3ea287ac 100644
--- a/altoslib/AltosTelemetryMini2.java
+++ b/altoslib/AltosTelemetryMini2.java
@@ -16,58 +16,46 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryMini2 extends AltosTelemetryStandard {
- int state;
- int v_batt;
- int sense_a;
- int sense_m;
+ int state() { return uint8(5); }
- int pres;
- int temp;
+ int v_batt() { return int16(6); }
+ int sense_a() { return int16(8); }
+ int sense_m() { return int16(10); }
- int acceleration;
- int speed;
- int height;
+ int pres() { return int32(12); }
+ int temp() { return int16(16); }
- int ground_pres;
+ int acceleration() { return int16(18); }
+ int speed() { return int16(20); }
+ int height() { return int16(22); }
- public AltosTelemetryMini2(int[] bytes) {
- super(bytes);
-
- state = int8(5);
-
- v_batt = int16(6);
- sense_a = int16(8);
- sense_m = int16(10);
-
- pres = int32(12);
- temp = int16(16);
+ int ground_pres() { return int32(24); }
- acceleration = int16(18);
- speed = int16(20);
- height = int16(22);
-
- ground_pres = int32(24);
+ public AltosTelemetryMini2(int[] bytes) throws AltosCRCException {
+ super(bytes);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
+
+ listener.set_state(state());
- state.set_state(this.state);
+ listener.set_battery_voltage(AltosConvert.tele_mini_2_voltage(v_batt()));
+ listener.set_apogee_voltage(AltosConvert.tele_mini_2_voltage(sense_a()));
+ listener.set_main_voltage(AltosConvert.tele_mini_2_voltage(sense_m()));
- state.set_battery_voltage(AltosConvert.tele_mini_2_voltage(v_batt));
- state.set_apogee_voltage(AltosConvert.tele_mini_2_voltage(sense_a));
- state.set_main_voltage(AltosConvert.tele_mini_2_voltage(sense_m));
+ AltosCalData cal_data = listener.cal_data();
- state.set_ground_pressure(ground_pres);
+ cal_data.set_ground_pressure(ground_pres());
- state.set_pressure(pres);
- state.set_temperature(temp/100.0);
+ listener.set_pressure(pres());
+ listener.set_temperature(temp()/100.0);
- state.set_kalman(height, speed/16.0, acceleration/16.0);
+ listener.set_kalman(height(), speed()/16.0, acceleration()/16.0);
}
}
diff --git a/altoslib/AltosTelemetryMini3.java b/altoslib/AltosTelemetryMini3.java
index 21f8c485..c66f8e61 100644
--- a/altoslib/AltosTelemetryMini3.java
+++ b/altoslib/AltosTelemetryMini3.java
@@ -16,61 +16,45 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryMini3 extends AltosTelemetryStandard {
- int state;
+ int state() { return uint8(5); }
- int v_batt;
- int sense_a;
- int sense_m;
+ int v_batt() { return int16(6); }
+ int sense_a() { return int16(8); }
+ int sense_m() { return int16(10); }
- int pres;
- int temp;
+ int pres() { return int32(12); }
+ int temp() { return int16(16); }
- int acceleration;
- int speed;
- int height_16;
+ int acceleration() { return int16(18); }
+ int speed() { return int16(20); }
+ int height_16() { return int16(22); }
- int ground_pres;
+ int ground_pres() { return int32(24); }
- public AltosTelemetryMini3(int[] bytes) {
+ public AltosTelemetryMini3(int[] bytes) throws AltosCRCException {
super(bytes);
-
- state = int8(5);
-
- v_batt = int16(6);
- sense_a = int16(8);
- sense_m = int16(10);
-
- pres = int32(12);
- temp = int16(16);
-
- acceleration = int16(18);
- speed = int16(20);
- height_16 = int16(22);
-
- ground_pres = int32(24);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
- state.set_state(this.state);
+ listener.set_state(state());
- state.set_battery_voltage(AltosConvert.tele_mini_3_battery_voltage(v_batt));
+ listener.set_battery_voltage(AltosConvert.tele_mini_3_battery_voltage(v_batt()));
- state.set_apogee_voltage(AltosConvert.tele_mini_3_pyro_voltage(sense_a));
- state.set_main_voltage(AltosConvert.tele_mini_3_pyro_voltage(sense_m));
+ listener.set_apogee_voltage(AltosConvert.tele_mini_3_pyro_voltage(sense_a()));
+ listener.set_main_voltage(AltosConvert.tele_mini_3_pyro_voltage(sense_m()));
- state.set_pressure(pres);
- state.set_temperature(temp/100.0);
+ listener.cal_data().set_ground_pressure(ground_pres());
- state.set_kalman(extend_height(state, height_16),
- speed/16.0, acceleration/16.0);
+ listener.set_pressure(pres());
+ listener.set_temperature(temp()/100.0);
- state.set_ground_pressure(ground_pres);
+ listener.set_kalman(height_16(), speed()/16.0, acceleration()/16.0);
}
}
diff --git a/altoslib/AltosTelemetryRaw.java b/altoslib/AltosTelemetryRaw.java
index 339043a6..f2108d68 100644
--- a/altoslib/AltosTelemetryRaw.java
+++ b/altoslib/AltosTelemetryRaw.java
@@ -16,14 +16,14 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryRaw extends AltosTelemetryStandard {
- public AltosTelemetryRaw(int[] bytes) {
+ public AltosTelemetryRaw(int[] bytes) throws AltosCRCException {
super(bytes);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
}
}
diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java
index 6a93c2c3..26fe4f26 100644
--- a/altoslib/AltosTelemetryReader.java
+++ b/altoslib/AltosTelemetryReader.java
@@ -16,19 +16,20 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.io.*;
import java.util.concurrent.*;
public class AltosTelemetryReader extends AltosFlightReader {
- AltosLink link;
- AltosLog log;
- double frequency;
- int telemetry;
- int telemetry_rate;
- AltosState state = null;
+ AltosLink link;
+ AltosLog log;
+ double frequency;
+ int telemetry;
+ int telemetry_rate;
+ private AltosState state = null;
+ private AltosCalData cal_data = null;
LinkedBlockingQueue<AltosLine> telem;
@@ -40,14 +41,22 @@ public class AltosTelemetryReader extends AltosFlightReader {
throw new IOException("IO error");
} while (!link.get_monitor());
AltosTelemetry telem = AltosTelemetry.parse(l.line);
- if (state == null)
- state = new AltosState();
- else
- state = state.clone();
- telem.update_state(state);
+ if (state == null) {
+ System.out.printf("Make state\n");
+ state = new AltosState(cal_data());
+ }
+ telem.provide_data(state);
return state;
}
+ public AltosCalData cal_data() {
+ if (cal_data == null) {
+ System.out.printf("Make cal data\n");
+ cal_data = new AltosCalData();
+ }
+ return cal_data;
+ }
+
public void flush() {
telem.clear();
}
@@ -55,6 +64,7 @@ public class AltosTelemetryReader extends AltosFlightReader {
public void reset() {
flush();
state = null;
+ cal_data = null;
}
public void close(boolean interrupted) {
diff --git a/altoslib/AltosTelemetrySatellite.java b/altoslib/AltosTelemetrySatellite.java
index 6897f0e6..60bc4a51 100644
--- a/altoslib/AltosTelemetrySatellite.java
+++ b/altoslib/AltosTelemetrySatellite.java
@@ -16,16 +16,15 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetrySatellite extends AltosTelemetryStandard {
- int channels;
- AltosGPSSat[] sats;
+ int channels() { return uint8(5); }
- public AltosTelemetrySatellite(int[] bytes) {
- super(bytes);
+ AltosGPSSat[] sats() {
+ int channels = channels();
+ AltosGPSSat[] sats = null;
- channels = uint8(5);
if (channels > 12)
channels = 12;
if (channels == 0)
@@ -38,14 +37,22 @@ public class AltosTelemetrySatellite extends AltosTelemetryStandard {
sats[i] = new AltosGPSSat(svid, c_n_1);
}
}
+ return sats;
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public AltosTelemetrySatellite(int[] bytes) throws AltosCRCException {
+ super(bytes);
+ }
+
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
+
+ AltosCalData cal_data = listener.cal_data();
- AltosGPS gps = state.make_temp_gps(true);
+ AltosGPS gps = cal_data.make_temp_gps(tick(), true);
- gps.cc_gps_sat = sats;
- state.set_temp_gps();
+ gps.cc_gps_sat = sats();
+ listener.set_gps(gps);
+ cal_data.reset_temp_gps();
}
}
diff --git a/altoslib/AltosTelemetrySensor.java b/altoslib/AltosTelemetrySensor.java
index 3c3e6a01..dc8efa9b 100644
--- a/altoslib/AltosTelemetrySensor.java
+++ b/altoslib/AltosTelemetrySensor.java
@@ -16,66 +16,52 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetrySensor extends AltosTelemetryStandard {
- int state;
- int accel;
- int pres;
- int temp;
- int v_batt;
- int sense_d;
- int sense_m;
+ int state() { return uint8(5); }
+ int accel() { return int16(6); }
+ int pres() { return int16(8); }
+ int temp() { return int16(10); }
+ int v_batt() { return int16(12); }
+ int sense_d() { return int16(14); }
+ int sense_m() { return int16(16); }
- int acceleration;
- int speed;
- int height;
+ int acceleration() { return int16(18); }
+ int speed() { return int16(20); }
+ int height_16() { return int16(22); }
- int ground_accel;
- int ground_pres;
- int accel_plus_g;
- int accel_minus_g;
+ int ground_accel() { return int16(24); }
+ int ground_pres() { return int16(26); }
+ int accel_plus_g() { return int16(28); }
+ int accel_minus_g() { return int16(30); }
- public AltosTelemetrySensor(int[] bytes) {
+ public AltosTelemetrySensor(int[] bytes) throws AltosCRCException {
super(bytes);
- state = uint8(5);
-
- accel = int16(6);
- pres = int16(8);
- temp = int16(10);
- v_batt = int16(12);
- sense_d = int16(14);
- sense_m = int16(16);
+ }
- acceleration = int16(18);
- speed = int16(20);
- height = int16(22);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
- ground_pres = int16(24);
- ground_accel = int16(26);
- accel_plus_g = int16(28);
- accel_minus_g = int16(30);
- }
+ listener.set_state(state());
- public void update_state(AltosState state) {
- super.update_state(state);
+ AltosCalData cal_data = listener.cal_data();
- state.set_state(this.state);
- if (type == packet_type_TM_sensor) {
- state.set_ground_accel(ground_accel);
- state.set_accel_g(accel_plus_g, accel_minus_g);
- state.set_accel(accel);
+ if (type() == packet_type_TM_sensor) {
+ cal_data.set_ground_accel(ground_accel());
+ cal_data.set_accel_plus_minus(accel_plus_g(), accel_minus_g());
+ listener.set_acceleration(cal_data.acceleration(accel()));
}
- state.set_ground_pressure(AltosConvert.barometer_to_pressure(ground_pres));
- state.set_pressure(AltosConvert.barometer_to_pressure(pres));
- state.set_temperature(AltosConvert.thermometer_to_temperature(temp));
- state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(v_batt));
- if (type == packet_type_TM_sensor || type == packet_type_Tm_sensor) {
- state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sense_d));
- state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sense_m));
+ cal_data.set_ground_pressure(AltosConvert.barometer_to_pressure(ground_pres()));
+ listener.set_pressure(AltosConvert.barometer_to_pressure(pres()));
+ listener.set_temperature(AltosConvert.thermometer_to_temperature(temp()));
+ listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(v_batt()));
+ if (type() == packet_type_TM_sensor || type() == packet_type_Tm_sensor) {
+ listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(sense_d()));
+ listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(sense_m()));
}
- state.set_kalman(height, speed/16.0, acceleration / 16.0);
+ listener.set_kalman(height_16(), speed()/16.0, acceleration()/16.0);
}
}
diff --git a/altoslib/AltosTelemetryStandard.java b/altoslib/AltosTelemetryStandard.java
index 35d315c7..2a1c9365 100644
--- a/altoslib/AltosTelemetryStandard.java
+++ b/altoslib/AltosTelemetryStandard.java
@@ -16,12 +16,9 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public abstract class AltosTelemetryStandard extends AltosTelemetry {
- int[] bytes;
- int type;
-
public int int8(int off) {
return AltosLib.int8(bytes, off + 1);
}
@@ -50,10 +47,16 @@ public abstract class AltosTelemetryStandard extends AltosTelemetry {
return AltosLib.string(bytes, off + 1, l);
}
- public static AltosTelemetry parse_hex(int[] bytes) {
- int type = AltosLib.uint8(bytes, 4 + 1);
+ public int type() { return uint8(4); }
+
+ public int serial() { return uint16(0); }
+
+ public int tick() { return uint16(2); }
+ public static AltosTelemetry parse_hex(int[] bytes) throws AltosCRCException {
AltosTelemetry telem;
+
+ int type = AltosLib.uint8(bytes, 4+1);
switch (type) {
case packet_type_TM_sensor:
case packet_type_Tm_sensor:
@@ -97,15 +100,11 @@ public abstract class AltosTelemetryStandard extends AltosTelemetry {
return telem;
}
- public AltosTelemetryStandard(int[] bytes) {
- this.bytes = bytes;
-
- serial = uint16(0);
- tick = uint16(2);
- type = uint8(4);
+ public AltosTelemetryStandard(int[] bytes) throws AltosCRCException {
+ super(bytes);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
}
}
diff --git a/altoslib/AltosTemperature.java b/altoslib/AltosTemperature.java
index d63e81d1..efc6d5e1 100644
--- a/altoslib/AltosTemperature.java
+++ b/altoslib/AltosTemperature.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTemperature extends AltosUnits {
diff --git a/altoslib/AltosTime.java b/altoslib/AltosTime.java
new file mode 100644
index 00000000..5c6ab037
--- /dev/null
+++ b/altoslib/AltosTime.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosTime extends AltosUnits {
+ public double value(double v, boolean imperial_units) { return v; }
+
+ public double inverse(double v, boolean imperial_unis) { return v; }
+
+ public String show_units(boolean imperial_units) { return "s"; }
+
+ public String say_units(boolean imperial_units) { return "seconds"; }
+
+ public int show_fraction(int width, boolean imperial_units) {
+ if (width < 5)
+ return 0;
+ return width - 5;
+ }
+
+ public int say_fraction(boolean imperial_units) { return 0; }
+}
diff --git a/altoslib/AltosTimeSeries.java b/altoslib/AltosTimeSeries.java
new file mode 100644
index 00000000..b3c432fc
--- /dev/null
+++ b/altoslib/AltosTimeSeries.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright © 2017 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+import java.util.*;
+
+public class AltosTimeSeries implements Iterable<AltosTimeValue>, Comparable<AltosTimeSeries> {
+ public String label;
+ public AltosUnits units;
+ ArrayList<AltosTimeValue> values;
+
+ public int compareTo(AltosTimeSeries other) {
+ return label.compareTo(other.label);
+ }
+
+ public void add(AltosTimeValue tv) {
+ values.add(tv);
+ }
+
+ public void add(double time, double value) {
+ add(new AltosTimeValue(time, value));
+ }
+
+ public AltosTimeValue get(int i) {
+ return values.get(i);
+ }
+
+ private double lerp(AltosTimeValue v0, AltosTimeValue v1, double t) {
+ /* degenerate case */
+ if (v0.time == v1.time)
+ return (v0.value + v1.value) / 2;
+
+ return (v0.value * (v1.time - t) + v1.value * (t - v0.time)) / (v1.time - v0.time);
+ }
+
+ private int after_index(double time) {
+ int lo = 0;
+ int hi = values.size() - 1;
+
+ while (lo <= hi) {
+ int mid = (lo + hi) / 2;
+
+ if (values.get(mid).time < time)
+ lo = mid + 1;
+ else
+ hi = mid - 1;
+ }
+ return lo;
+ }
+
+ /* Compute a value for an arbitrary time */
+ public double value(double time) {
+ int after = after_index(time);
+ double ret;
+
+ if (after == 0)
+ ret = values.get(0).value;
+ else if (after == values.size())
+ ret = values.get(after - 1).value;
+ else {
+ AltosTimeValue b = values.get(after-1);
+ AltosTimeValue a = values.get(after);
+ ret = lerp(b, a, time);
+ }
+ return ret;
+ }
+
+ /* Find the value just before an arbitrary time */
+ public double value_before(double time) {
+ int after = after_index(time);
+
+ if (after == 0)
+ return values.get(0).value;
+ return values.get(after-1).value;
+ }
+
+ /* Find the value just after an arbitrary time */
+ public double value_after(double time) {
+ int after = after_index(time);
+
+ if (after == values.size())
+ return values.get(after-1).value;
+ return values.get(after).value;
+ }
+
+ public double time_of(double value) {
+ double last = AltosLib.MISSING;
+ for (AltosTimeValue v : values) {
+ if (v.value >= value)
+ return v.time;
+ last = v.time;
+ }
+ return last;
+ }
+
+ public int size() {
+ return values.size();
+ }
+
+ public Iterator<AltosTimeValue> iterator() {
+ return values.iterator();
+ }
+
+ public AltosTimeValue max() {
+ AltosTimeValue max = null;
+ for (AltosTimeValue tv : values)
+ if (max == null || tv.value > max.value)
+ max = tv;
+ return max;
+ }
+
+ public AltosTimeValue max(double start_time, double end_time) {
+ AltosTimeValue max = null;
+ for (AltosTimeValue tv : values) {
+ if (start_time <= tv.time && tv.time <= end_time)
+ if (max == null || tv.value > max.value)
+ max = tv;
+ }
+ return max;
+ }
+
+ public AltosTimeValue min() {
+ AltosTimeValue min = null;
+ for (AltosTimeValue tv : values) {
+ if (min == null || tv.value < min.value)
+ min = tv;
+ }
+ return min;
+ }
+
+ public AltosTimeValue min(double start_time, double end_time) {
+ AltosTimeValue min = null;
+ for (AltosTimeValue tv : values) {
+ if (start_time <= tv.time && tv.time <= end_time)
+ if (min == null || tv.value < min.value)
+ min = tv;
+ }
+ return min;
+ }
+
+ public AltosTimeValue first() {
+ return values.get(0);
+ }
+
+ public AltosTimeValue last() {
+ return values.get(values.size() - 1);
+ }
+
+ public double average() {
+ double total_value = 0;
+ double total_time = 0;
+ AltosTimeValue prev = null;
+ for (AltosTimeValue tv : values) {
+ if (prev != null) {
+ total_value += (tv.value + prev.value) / 2 * (tv.time - prev.time);
+ total_time += (tv.time - prev.time);
+ }
+ prev = tv;
+ }
+ if (total_time == 0)
+ return AltosLib.MISSING;
+ return total_value / total_time;
+ }
+
+ public double average(double start_time, double end_time) {
+ double total_value = 0;
+ double total_time = 0;
+ AltosTimeValue prev = null;
+ for (AltosTimeValue tv : values) {
+ if (start_time <= tv.time && tv.time <= end_time) {
+ if (prev != null) {
+ total_value += (tv.value + prev.value) / 2 * (tv.time - start_time);
+ total_time += (tv.time - start_time);
+ }
+ start_time = tv.time;
+ }
+ prev = tv;
+ }
+ if (total_time == 0)
+ return AltosLib.MISSING;
+ return total_value / total_time;
+ }
+
+ public AltosTimeSeries integrate(AltosTimeSeries integral) {
+ double value = 0.0;
+ double pvalue = 0.0;
+ double time = 0.0;
+ boolean start = true;
+
+ for (AltosTimeValue v : values) {
+ if (start) {
+ value = 0.0;
+ start = false;
+ } else {
+ value += (pvalue + v.value) / 2.0 * (v.time - time);
+ }
+ pvalue = v.value;
+ time = v.time;
+ integral.add(time, value);
+
+ }
+ return integral;
+ }
+
+ public AltosTimeSeries differentiate(AltosTimeSeries diff) {
+ double value = 0.0;
+ double time = 0.0;
+ boolean start = true;
+
+ for (AltosTimeValue v: values) {
+ if (start) {
+ value = v.value;
+ time = v.time;
+ start = false;
+ } else {
+ double dx = v.time - time;
+ double dy = v.value - value;
+
+ if (dx != 0)
+ diff.add(time, dy/dx);
+
+ time = v.time;
+ value = v.value;
+ }
+ }
+ return diff;
+ }
+
+ private int find_left(int i, double dt) {
+ int j;
+ double t = values.get(i).time - dt;
+ for (j = i; j >= 0; j--) {
+ if (values.get(j).time < t)
+ break;
+ }
+ return j + 1;
+
+ }
+
+ private int find_right(int i, double dt) {
+ int j;
+ double t = values.get(i).time + dt;
+ for (j = i; j < values.size(); j++) {
+ if (values.get(j).time > t)
+ break;
+ }
+ return j - 1;
+
+ }
+
+ private double filter_coeff(double dist, double width) {
+ double ratio = dist / (width / 2);
+
+ return Math.cos(ratio * Math.PI / 2);
+ }
+
+ public AltosTimeSeries filter(AltosTimeSeries f, double width) {
+ double half_width = width/2;
+ for (int i = 0; i < values.size(); i++) {
+ double center_time = values.get(i).time;
+ double left_time = center_time - half_width;
+ double right_time = center_time + half_width;
+ double total_coeff = 0.0;
+ double total_value = 0.0;
+
+ int left = find_left(i, half_width);
+ int right = find_right(i, half_width);
+
+ for (int j = left; j <= right; j++) {
+ double j_time = values.get(j).time;
+
+ if (left_time <= j_time && j_time <= right_time) {
+ double j_left = j == left ? left_time : values.get(j-1).time;
+ double j_right = j == right ? right_time : values.get(j+1).time;
+ double interval = (j_right - j_left) / 2.0;
+ double coeff = filter_coeff(j_time - center_time, width) * interval;
+ double value = values.get(j).value;
+ double partial = value * coeff;
+
+ total_coeff += coeff;
+ total_value += partial;
+ }
+ }
+ if (total_coeff != 0.0)
+ f.add(center_time, total_value / total_coeff);
+ }
+ return f;
+ }
+
+ public AltosTimeSeries(String label, AltosUnits units) {
+ this.label = label;
+ this.units = units;
+ this.values = new ArrayList<AltosTimeValue>();
+ }
+}
diff --git a/altoslib/AltosTimeValue.java b/altoslib/AltosTimeValue.java
new file mode 100644
index 00000000..298ac7f0
--- /dev/null
+++ b/altoslib/AltosTimeValue.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright © 2017 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_12;
+
+public class AltosTimeValue {
+ public double time;
+ public double value;
+
+ public AltosTimeValue(double time, double value) {
+ this.time = time;
+ this.value = value;
+ }
+}
diff --git a/altoslib/AltosUnits.java b/altoslib/AltosUnits.java
index 717a106a..e1194487 100644
--- a/altoslib/AltosUnits.java
+++ b/altoslib/AltosUnits.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
@@ -41,6 +41,10 @@ public abstract class AltosUnits {
public abstract double inverse(double v, boolean imperial_units);
+ public String string_value(double v, boolean imperial_units) {
+ return new Double(value(v, imperial_units)).toString();
+ }
+
public abstract String show_units(boolean imperial_units);
public abstract String say_units(boolean imperial_units);
@@ -113,6 +117,10 @@ public abstract class AltosUnits {
return say_units(v, AltosConvert.imperial_units);
}
+ public String string_value(double v) {
+ return string_value(v, AltosConvert.imperial_units);
+ }
+
/* Parsing functions. Use the first range of the type */
public String parse_units(boolean imperial_units) {
return first_range(imperial_units).show_units;
diff --git a/altoslib/AltosUnitsListener.java b/altoslib/AltosUnitsListener.java
index e094810c..1f06afbf 100644
--- a/altoslib/AltosUnitsListener.java
+++ b/altoslib/AltosUnitsListener.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosUnitsListener {
public void units_changed(boolean imperial_units);
diff --git a/altoslib/AltosUnitsRange.java b/altoslib/AltosUnitsRange.java
index 9f56001d..6bf0d91f 100644
--- a/altoslib/AltosUnitsRange.java
+++ b/altoslib/AltosUnitsRange.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
diff --git a/altoslib/AltosUnknownProduct.java b/altoslib/AltosUnknownProduct.java
index 114abc76..e4bebcd4 100644
--- a/altoslib/AltosUnknownProduct.java
+++ b/altoslib/AltosUnknownProduct.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosUnknownProduct extends Exception {
public String product;
diff --git a/altoslib/AltosVersion.java.in b/altoslib/AltosVersion.java.in
index a48c532b..c8399f2e 100644
--- a/altoslib/AltosVersion.java.in
+++ b/altoslib/AltosVersion.java.in
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosVersion {
public final static String version = "@VERSION@";
diff --git a/altoslib/AltosVoltage.java b/altoslib/AltosVoltage.java
index 8031c805..ef53ac11 100644
--- a/altoslib/AltosVoltage.java
+++ b/altoslib/AltosVoltage.java
@@ -16,7 +16,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosVoltage extends AltosUnits {
diff --git a/altoslib/AltosWriter.java b/altoslib/AltosWriter.java
index 691dc4de..c77e48b0 100644
--- a/altoslib/AltosWriter.java
+++ b/altoslib/AltosWriter.java
@@ -16,11 +16,11 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosWriter {
- public void write(AltosStateIterable states);
+ public void write(AltosFlightSeries series);
public void close();
}
diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am
index 26159421..11b5d562 100644
--- a/altoslib/Makefile.am
+++ b/altoslib/Makefile.am
@@ -26,6 +26,7 @@ record_files = \
altoslib_JAVA = \
AltosLib.java \
+ AltosCalData.java \
AltosCompanion.java \
AltosConfigData.java \
AltosConfigDataException.java \
@@ -35,28 +36,34 @@ altoslib_JAVA = \
AltosCSV.java \
AltosDebug.java \
AltosEeprom.java \
+ AltosRecordSet.java \
+ AltosEepromRecord.java \
+ AltosEepromRecordFull.java \
+ AltosEepromRecordTiny.java \
+ AltosEepromRecordMega.java \
+ AltosEepromRecordMetrum.java \
+ AltosEepromRecordMini.java \
+ AltosEepromRecordGps.java \
+ AltosEepromRecordFireTwo.java \
+ AltosEepromRecordSet.java \
AltosEepromChunk.java \
AltosEepromDownload.java \
+ AltosEepromMonitor.java \
AltosEepromFile.java \
- AltosEepromTM.java \
- AltosEepromTMini.java \
- AltosEepromHeader.java \
- AltosEepromIterable.java \
AltosEepromList.java \
AltosEepromLog.java \
- AltosEepromMega.java \
- AltosEepromMetrum2.java \
- AltosEepromMini.java \
- AltosEepromGPS.java \
- AltosEepromMonitor.java \
- AltosEepromFireTwo.java \
AltosFile.java \
AltosFlash.java \
AltosFlashListener.java \
+ AltosDataListener.java \
+ AltosDataProvider.java \
+ AltosFlightSeries.java \
AltosFlightReader.java \
AltosFlightStats.java \
+ AltosForce.java \
AltosFrequency.java \
AltosGPS.java \
+ AltosGPSTimeValue.java \
AltosGPSSat.java \
AltosGreatCircle.java \
AltosHexfile.java \
@@ -79,9 +86,12 @@ altoslib_JAVA = \
AltosNoSymbol.java \
AltosOrient.java \
AltosParse.java \
+ AltosPressure.java \
+ AltosPresTemp.java \
AltosPreferences.java \
AltosPreferencesBackend.java \
AltosProgrammer.java \
+ AltosPyroName.java \
AltosReplayReader.java \
AltosRomconfig.java \
AltosSavedState.java \
@@ -95,8 +105,8 @@ altoslib_JAVA = \
AltosSensorMetrum.java \
AltosSensorTGPS.java \
AltosState.java \
- AltosStateIterable.java \
- AltosStateUpdate.java \
+ AltosStateName.java \
+ AltosStringInputStream.java \
AltosTelemetry.java \
AltosTelemetryConfiguration.java \
AltosTelemetryCompanion.java \
@@ -116,6 +126,9 @@ altoslib_JAVA = \
AltosTelemetrySensor.java \
AltosTelemetrySatellite.java \
AltosTelemetryStandard.java \
+ AltosTime.java \
+ AltosTimeSeries.java \
+ AltosTimeValue.java \
AltosUnitsListener.java \
AltosUnknownProduct.java \
AltosMs5607.java \
@@ -132,6 +145,7 @@ altoslib_JAVA = \
AltosLocation.java \
AltosLatitude.java \
AltosLongitude.java \
+ AltosRotationRate.java \
AltosPyro.java \
AltosWriter.java \
AltosQuaternion.java \