summaryrefslogtreecommitdiff
path: root/altoslib
diff options
context:
space:
mode:
Diffstat (limited to 'altoslib')
-rw-r--r--altoslib/AltosCSV.java139
-rw-r--r--altoslib/AltosConfigData.java3
-rw-r--r--altoslib/AltosConfigValues.java2
-rw-r--r--altoslib/AltosEepromGPS.java25
-rw-r--r--altoslib/AltosEepromHeader.java35
-rw-r--r--altoslib/AltosEepromMega.java26
-rw-r--r--altoslib/AltosEepromMetrum2.java10
-rw-r--r--altoslib/AltosGPS.java36
-rw-r--r--altoslib/AltosKML.java30
-rw-r--r--altoslib/AltosLib.java39
-rw-r--r--altoslib/AltosState.java34
-rw-r--r--altoslib/AltosTelemetry.java29
-rw-r--r--altoslib/AltosTelemetryLegacy.java2
-rw-r--r--altoslib/AltosTelemetryLocation.java13
-rw-r--r--altoslib/AltosTelemetryMegaData.java13
-rw-r--r--altoslib/AltosTelemetryMetrumSensor.java7
-rw-r--r--altoslib/AltosWriter.java2
17 files changed, 367 insertions, 78 deletions
diff --git a/altoslib/AltosCSV.java b/altoslib/AltosCSV.java
index 7e3d6d07..4a9278d9 100644
--- a/altoslib/AltosCSV.java
+++ b/altoslib/AltosCSV.java
@@ -29,6 +29,14 @@ public class AltosCSV implements AltosWriter {
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;
+
static final int ALTOS_CSV_VERSION = 5;
/* Version 4 format:
@@ -55,10 +63,12 @@ public class AltosCSV implements AltosWriter {
* accelerometer speed (m/s)
* barometer speed (m/s)
* temp (°C)
- * battery (V)
* drogue (V)
* main (V)
*
+ * Battery
+ * battery (V)
+ *
* Advanced sensors (if available)
* accel_x (m/s²)
* accel_y (m/s²)
@@ -87,7 +97,9 @@ public class AltosCSV implements AltosWriter {
* from_pad_azimuth (deg true)
* from_pad_range (m)
* from_pad_elevation (deg from horizon)
+ * pdop
* hdop
+ * vdop
*
* GPS Sat data
* C/N0 data for all 32 valid SDIDs
@@ -107,7 +119,7 @@ public class AltosCSV implements AltosWriter {
void write_general(AltosState state) {
out.printf("%s, %d, %d, %s, %8.2f, %8.2f, %4d, %3d",
ALTOS_CSV_VERSION, state.serial, state.flight, state.callsign,
- (double) state.time, (double) state.tick / 100.0,
+ (double) state.time_since_boost(), (double) state.tick / 100.0,
state.rssi,
state.status & 0x7f);
}
@@ -121,11 +133,11 @@ public class AltosCSV implements AltosWriter {
}
void write_basic_header() {
- out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,battery_voltage,drogue_voltage,main_voltage");
+ out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,drogue_voltage,main_voltage");
}
void write_basic(AltosState state) {
- out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f,%5.2f",
+ 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(),
@@ -133,11 +145,18 @@ public class AltosCSV implements AltosWriter {
state.speed(),
state.speed(),
state.temperature,
- state.battery_voltage,
state.apogee_voltage,
state.main_voltage);
}
+ void write_battery_header() {
+ out.printf("battery_voltage");
+ }
+
+ void write_battery(AltosState state) {
+ out.printf("%5.2f", state.battery_voltage);
+ }
+
void write_advanced_header() {
out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z");
}
@@ -150,14 +169,14 @@ public class AltosCSV implements AltosWriter {
imu = new AltosIMU();
if (mag == null)
mag = new AltosMag();
- out.printf("%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d",
+ out.printf("%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f",
imu.accel_x, imu.accel_y, imu.accel_z,
imu.gyro_x, imu.gyro_y, imu.gyro_z,
mag.x, mag.y, mag.z);
}
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,hdop");
+ 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) {
@@ -169,7 +188,7 @@ public class AltosCSV implements AltosWriter {
if (from_pad == null)
from_pad = new AltosGreatCircle();
- 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",
+ 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,
gps.nsat,
@@ -186,7 +205,9 @@ public class AltosCSV implements AltosWriter {
state.range,
from_pad.bearing,
state.elevation,
- gps.hdop);
+ gps.pdop,
+ gps.hdop,
+ gps.vdop);
}
void write_gps_sat_header() {
@@ -239,52 +260,83 @@ public class AltosCSV implements AltosWriter {
out.printf(",0");
}
- void write_header(boolean advanced, boolean gps, boolean companion) {
+ void write_header() {
out.printf("#"); write_general_header();
- out.printf(","); write_flight_header();
- out.printf(","); write_basic_header();
- if (advanced)
- out.printf(","); write_advanced_header();
- if (gps) {
- out.printf(","); write_gps_header();
- out.printf(","); write_gps_sat_header();
+ if (has_flight_state) {
+ out.printf(",");
+ write_flight_header();
}
- if (companion) {
- out.printf(","); write_companion_header();
+ if (has_basic) {
+ out.printf(",");
+ write_basic_header();
+ }
+ if (has_battery) {
+ out.printf(",");
+ write_battery_header();
+ }
+ if (has_advanced) {
+ out.printf(",");
+ write_advanced_header();
+ }
+ if (has_gps) {
+ out.printf(",");
+ write_gps_header();
+ }
+ if (has_gps_sat) {
+ out.printf(",");
+ write_gps_sat_header();
+ }
+ if (has_companion) {
+ out.printf(",");
+ write_companion_header();
}
out.printf ("\n");
}
void write_one(AltosState state) {
- write_general(state); out.printf(",");
- write_flight(state); out.printf(",");
- write_basic(state); out.printf(",");
- if (state.imu != null || state.mag != null)
+ write_general(state);
+ if (has_flight_state) {
+ out.printf(",");
+ write_flight(state);
+ }
+ if (has_basic) {
+ out.printf(",");
+ write_basic(state);
+ }
+ if (has_battery) {
+ out.printf(",");
+ write_battery(state);
+ }
+ if (has_advanced) {
+ out.printf(",");
write_advanced(state);
- if (state.gps != null) {
+ }
+ if (has_gps) {
+ out.printf(",");
+ write_gps(state);
+ }
+ if (has_gps_sat) {
out.printf(",");
- write_gps(state); out.printf(",");
write_gps_sat(state);
}
- if (state.companion != null) {
+ if (has_companion) {
out.printf(",");
write_companion(state);
}
out.printf ("\n");
}
- void flush_pad() {
+ private void flush_pad() {
while (!pad_states.isEmpty()) {
write_one (pad_states.remove());
}
}
- public void write(AltosState state) {
+ private void write(AltosState state) {
if (state.state == AltosLib.ao_flight_startup)
return;
if (!header_written) {
- write_header(state.imu != null || state.mag != null,
- state.gps != null, state.companion != null);
+ write_header();
header_written = true;
}
if (!seen_boost) {
@@ -300,7 +352,7 @@ public class AltosCSV implements AltosWriter {
pad_states.add(state);
}
- public PrintStream out() {
+ private PrintStream out() {
return out;
}
@@ -314,6 +366,31 @@ public class AltosCSV implements AltosWriter {
public void write(AltosStateIterable states) {
states.write_comments(out());
+
+ has_flight_state = false;
+ has_basic = false;
+ has_battery = false;
+ has_advanced = false;
+ 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.imu != null || state.mag != null)
+ 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;
+ }
for (AltosState state : states)
write(state);
}
diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java
index 847436cd..134a0ed2 100644
--- a/altoslib/AltosConfigData.java
+++ b/altoslib/AltosConfigData.java
@@ -31,6 +31,7 @@ public class AltosConfigData implements Iterable<String> {
public int log_format;
public int log_space;
public String version;
+ public int altitude_32;
/* Strings returned */
public LinkedList<String> lines;
@@ -274,6 +275,7 @@ public class AltosConfigData implements Iterable<String> {
try { flight = get_int(line, "current-flight"); } catch (Exception e) {}
try { log_format = get_int(line, "log-format"); } catch (Exception e) {}
try { log_space = get_int(line, "log-space"); } catch (Exception e) {}
+ try { altitude_32 = get_int(line, "altitude-32"); } catch (Exception e) {}
try { version = get_string(line, "software-version"); } catch (Exception e) {}
/* Version also contains MS5607 info, which we ignore here */
@@ -484,6 +486,7 @@ public class AltosConfigData implements Iterable<String> {
dest.set_serial(serial);
dest.set_product(product);
dest.set_version(version);
+ dest.set_altitude_32(altitude_32);
dest.set_main_deploy(main_deploy);
dest.set_apogee_delay(apogee_delay);
dest.set_apogee_lockout(apogee_lockout);
diff --git a/altoslib/AltosConfigValues.java b/altoslib/AltosConfigValues.java
index 987da53b..3f0a7075 100644
--- a/altoslib/AltosConfigValues.java
+++ b/altoslib/AltosConfigValues.java
@@ -25,6 +25,8 @@ public interface AltosConfigValues {
public abstract void set_serial(int serial);
+ public abstract void set_altitude_32(int altitude_32);
+
public abstract void set_main_deploy(int new_main_deploy);
public abstract int main_deploy() throws AltosConfigDataException;
diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java
index 2514b4fc..482f0b5f 100644
--- a/altoslib/AltosEepromGPS.java
+++ b/altoslib/AltosEepromGPS.java
@@ -37,7 +37,7 @@ public class AltosEepromGPS extends AltosEeprom {
/* AO_LOG_GPS_TIME elements */
public int latitude() { return data32(0); }
public int longitude() { return data32(4); }
- public int altitude() { return data16(8); }
+ 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); }
@@ -52,6 +52,7 @@ public class AltosEepromGPS extends AltosEeprom {
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); }
public boolean has_seconds() { return cmd == AltosLib.AO_LOG_GPS_TIME; }
@@ -99,7 +100,10 @@ public class AltosEepromGPS extends AltosEeprom {
gps = state.make_temp_gps(false);
gps.lat = latitude() / 1e7;
gps.lon = longitude() / 1e7;
- gps.alt = altitude();
+ if (state.altitude_32())
+ gps.alt = (altitude_low() & 0xffff) | (altitude_high() << 16);
+ else
+ gps.alt = altitude_low();
gps.hour = hour();
gps.minute = minute();
@@ -118,8 +122,21 @@ 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;
- gps.hdop = hdop();
- gps.vdop = vdop();
+ 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;
}
}
diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java
index 47e9eceb..71030655 100644
--- a/altoslib/AltosEepromHeader.java
+++ b/altoslib/AltosEepromHeader.java
@@ -96,6 +96,22 @@ public class AltosEepromHeader extends AltosEeprom {
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:
+ case AltosLib.AO_LOG_PAD_ORIENTATION:
+ 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;
}
}
@@ -161,6 +177,22 @@ public class AltosEepromHeader extends AltosEeprom {
case AltosLib.AO_LOG_BARO_CRC:
out.printf ("# Baro crc: %d\n", config_a);
break;
+ case AltosLib.AO_LOG_FREQUENCY:
+ case AltosLib.AO_LOG_APOGEE_LOCKOUT:
+ case AltosLib.AO_LOG_RADIO_RATE:
+ case AltosLib.AO_LOG_IGNITE_MODE:
+ case AltosLib.AO_LOG_PAD_ORIENTATION:
+ 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;
}
}
@@ -205,6 +237,9 @@ public class AltosEepromHeader extends AltosEeprom {
} 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];
diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java
index 5d5f3fef..adaa7f31 100644
--- a/altoslib/AltosEepromMega.java
+++ b/altoslib/AltosEepromMega.java
@@ -67,7 +67,7 @@ public class AltosEepromMega extends AltosEeprom {
/* AO_LOG_GPS_TIME elements */
public int latitude() { return data32(0); }
public int longitude() { return data32(4); }
- public int altitude() { return data16(8); }
+ 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); }
@@ -82,6 +82,7 @@ public class AltosEepromMega extends AltosEeprom {
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); }
@@ -168,7 +169,11 @@ public class AltosEepromMega extends AltosEeprom {
gps = state.make_temp_gps(false);
gps.lat = latitude() / 1e7;
gps.lon = longitude() / 1e7;
- gps.alt = altitude();
+
+ if (state.altitude_32())
+ gps.alt = (altitude_low() & 0xffff) | (altitude_high() << 16);
+ else
+ gps.alt = altitude_low();
gps.hour = hour();
gps.minute = minute();
@@ -187,8 +192,21 @@ public class AltosEepromMega extends AltosEeprom {
gps.ground_speed = ground_speed() * 1.0e-2;
gps.course = course() * 2;
gps.climb_rate = climb_rate() * 1.0e-2;
- gps.hdop = hdop();
- gps.vdop = vdop();
+ 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);
diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java
index 24277118..d9a65989 100644
--- a/altoslib/AltosEepromMetrum2.java
+++ b/altoslib/AltosEepromMetrum2.java
@@ -49,7 +49,8 @@ public class AltosEepromMetrum2 extends AltosEeprom {
/* AO_LOG_GPS_POS elements */
public int latitude() { return data32(0); }
public int longitude() { return data32(4); }
- public int altitude() { return data16(8); }
+ public int altitude_low() { return data16(8); }
+ public int altitude_high() { return data16(10); }
/* AO_LOG_GPS_TIME elements */
public int hour() { return data8(0); }
@@ -59,6 +60,7 @@ public class AltosEepromMetrum2 extends AltosEeprom {
public int year() { return data8(4); }
public int month() { return data8(5); }
public int day() { return data8(6); }
+ public int pdop() { return data8(7); }
/* AO_LOG_GPS_SAT elements */
public int nsat() { return data8(0); }
@@ -117,7 +119,10 @@ public class AltosEepromMetrum2 extends AltosEeprom {
gps = state.make_temp_gps(false);
gps.lat = latitude() / 1e7;
gps.lon = longitude() / 1e7;
- gps.alt = altitude();
+ if (state.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);
@@ -136,6 +141,7 @@ public class AltosEepromMetrum2 extends AltosEeprom {
gps.year = 2000 + year();
gps.month = month();
gps.day = day();
+ gps.pdop = pdop() / 10.0;
break;
case AltosLib.AO_LOG_GPS_SAT:
gps = state.make_temp_gps(true);
diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java
index aabcfc5b..0154e95d 100644
--- a/altoslib/AltosGPS.java
+++ b/altoslib/AltosGPS.java
@@ -40,10 +40,11 @@ public class AltosGPS implements Cloneable {
public double ground_speed; /* m/s */
public int course; /* degrees */
public double climb_rate; /* m/s */
+ public double pdop; /* unitless */
public double hdop; /* unitless */
public double vdop; /* unitless */
- public int h_error; /* m */
- public int v_error; /* m */
+ public double h_error; /* m */
+ public double v_error; /* m */
public AltosGPSSat[] cc_gps_sat; /* tracking data */
@@ -95,6 +96,7 @@ public class AltosGPS implements Cloneable {
AltosLib.MISSING, 1/100.0);
course = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_COURSE,
AltosLib.MISSING);
+ pdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_PDOP, MISSING, 1.0);
hdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_HDOP, MISSING, 1.0);
vdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_VDOP, MISSING, 1.0);
h_error = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_HERROR, MISSING);
@@ -268,14 +270,26 @@ public class AltosGPS implements Cloneable {
cc_gps_sat[cc_gps_sat.length - 1] = sat;
}
- public AltosGPS() {
+ private void init() {
lat = AltosLib.MISSING;
lon = AltosLib.MISSING;
alt = AltosLib.MISSING;
+ ground_speed = AltosLib.MISSING;
+ course = AltosLib.MISSING;
+ climb_rate = AltosLib.MISSING;
+ pdop = AltosLib.MISSING;
+ hdop = AltosLib.MISSING;
+ vdop = AltosLib.MISSING;
+ h_error = AltosLib.MISSING;
+ v_error = AltosLib.MISSING;
ClearGPSTime();
cc_gps_sat = null;
}
+ public AltosGPS() {
+ init();
+ }
+
public AltosGPS clone() {
AltosGPS g = new AltosGPS();
@@ -295,7 +309,9 @@ public class AltosGPS implements Cloneable {
g.ground_speed = ground_speed; /* m/s */
g.course = course; /* degrees */
g.climb_rate = climb_rate; /* m/s */
- g.hdop = hdop; /* unitless? */
+ g.pdop = pdop; /* unitless */
+ g.hdop = hdop; /* unitless */
+ g.vdop = vdop; /* unitless */
g.h_error = h_error; /* m */
g.v_error = v_error; /* m */
@@ -327,9 +343,11 @@ public class AltosGPS implements Cloneable {
ground_speed = old.ground_speed; /* m/s */
course = old.course; /* degrees */
climb_rate = old.climb_rate; /* m/s */
+ pdop = old.pdop; /* unitless? */
hdop = old.hdop; /* unitless? */
- h_error = old.h_error; /* m */
- v_error = old.v_error; /* m */
+ vdop = old.vdop; /* unitless? */
+ h_error = old.h_error; /* m */
+ v_error = old.v_error; /* m */
if (old.cc_gps_sat != null) {
cc_gps_sat = new AltosGPSSat[old.cc_gps_sat.length];
@@ -340,11 +358,7 @@ public class AltosGPS implements Cloneable {
}
}
} else {
- lat = AltosLib.MISSING;
- lon = AltosLib.MISSING;
- alt = AltosLib.MISSING;
- ClearGPSTime();
- cc_gps_sat = null;
+ init();
}
}
diff --git a/altoslib/AltosKML.java b/altoslib/AltosKML.java
index e31ddfba..e701fda3 100644
--- a/altoslib/AltosKML.java
+++ b/altoslib/AltosKML.java
@@ -28,18 +28,25 @@ public class AltosKML implements AltosWriter {
double gps_start_altitude;
static final String[] kml_state_colors = {
- "FF000000",
- "FF000000",
- "FF000000",
- "FF0000FF",
- "FF4080FF",
- "FF00FFFF",
- "FFFF0000",
- "FF00FF00",
- "FF000000",
- "FFFFFFFF"
+ "FF000000", // startup
+ "FF000000", // idle
+ "FF000000", // pad
+ "FF0000FF", // boost
+ "FF4080FF", // fast
+ "FF00FFFF", // coast
+ "FFFF0000", // drogue
+ "FF00FF00", // main
+ "FF000000", // landed
+ "FFFFFFFF", // invalid
+ "FFFF0000", // stateless
};
+ static String state_color(int state) {
+ if (state < 0 || kml_state_colors.length <= state)
+ return kml_state_colors[AltosLib.ao_flight_invalid];
+ return kml_state_colors[state];
+ }
+
static final String kml_header_start =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n" +
@@ -95,7 +102,8 @@ public class AltosKML implements AltosWriter {
void state_start(AltosState state) {
String state_name = AltosLib.state_name(state.state);
- out.printf(kml_style_start, state_name, kml_state_colors[state.state]);
+ String state_color = state_color(state.state);
+ out.printf(kml_style_start, state_name, state_color);
out.printf("\tState: %s\n", state_name);
out.printf("%s", kml_style_end);
out.printf(kml_placemark_start, state_name, state_name);
diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java
index c2ec0e3b..68bdd17f 100644
--- a/altoslib/AltosLib.java
+++ b/altoslib/AltosLib.java
@@ -51,6 +51,20 @@ public class AltosLib {
public static final int AO_LOG_SERIAL_NUMBER = 2002;
public static final int AO_LOG_LOG_FORMAT = 2003;
+ public static final int AO_LOG_FREQUENCY = 2004;
+ public static final int AO_LOG_APOGEE_LOCKOUT = 2005;
+ public static final int AO_LOG_RADIO_RATE = 2006;
+ public static final int AO_LOG_IGNITE_MODE = 2007;
+ public static final int AO_LOG_PAD_ORIENTATION = 2008;
+ public static final int AO_LOG_RADIO_ENABLE = 2009;
+ public static final int AO_LOG_AES_KEY = 2010;
+ public static final int AO_LOG_APRS = 2011;
+ public static final int AO_LOG_BEEP_SETTING = 2012;
+ public static final int AO_LOG_TRACKER_SETTING = 2013;
+ public static final int AO_LOG_PYRO_TIME = 2014;
+ public static final int AO_LOG_APRS_ID = 2015;
+ public static final int AO_LOG_ALTITUDE_32 = 2016;
+
/* Added for header fields in telemega files */
public static final int AO_LOG_BARO_RESERVED = 3000;
public static final int AO_LOG_BARO_SENS = 3001;
@@ -215,6 +229,31 @@ public class AltosLib {
telemetry));
}
+ private static int[] split_version(String version) {
+ String[] tokens = version.split("\\.");
+ int[] ret = new int[tokens.length];
+ for (int i = 0; i < tokens.length; i++)
+ ret[i] = Integer.parseInt(tokens[i]);
+ return ret;
+ }
+
+ public static int compare_version(String version_a, String version_b) {
+ int[] a = split_version(version_a);
+ int[] b = split_version(version_b);
+
+ for (int i = 0; i < Math.min(a.length, b.length); i++) {
+ if (a[i] < b[i])
+ return -1;
+ if (a[i] > b[i])
+ return 1;
+ }
+ if (a.length < b.length)
+ return -1;
+ if (a.length > b.length)
+ return 1;
+ return 0;
+ }
+
private static String[] state_to_string = {
"startup",
"idle",
diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java
index 5e7908af..5fce15c4 100644
--- a/altoslib/AltosState.java
+++ b/altoslib/AltosState.java
@@ -271,6 +271,7 @@ public class AltosState implements Cloneable {
public int state;
public int flight;
public int serial;
+ public int altitude_32;
public int receiver_serial;
public boolean landed;
public boolean ascent; /* going up? */
@@ -472,15 +473,23 @@ public class AltosState implements Cloneable {
pressure.set(p, time);
}
+ public double baro_height() {
+ double a = altitude();
+ double g = ground_altitude();
+ if (a != AltosLib.MISSING && g != AltosLib.MISSING)
+ return a - g;
+ return AltosLib.MISSING;
+ }
+
public double height() {
double k = kalman_height.value();
if (k != AltosLib.MISSING)
return k;
- double a = altitude();
- double g = ground_altitude();
- if (a != AltosLib.MISSING && g != AltosLib.MISSING)
- return a - g;
+ double b = baro_height();
+ if (b != AltosLib.MISSING)
+ return b;
+
return gps_height();
}
@@ -762,6 +771,7 @@ public class AltosState implements Cloneable {
product = null;
serial = AltosLib.MISSING;
receiver_serial = AltosLib.MISSING;
+ altitude_32 = AltosLib.MISSING;
baro = null;
companion = null;
@@ -899,6 +909,7 @@ public class AltosState implements Cloneable {
product = old.product;
serial = old.serial;
receiver_serial = old.receiver_serial;
+ altitude_32 = old.altitude_32;
baro = old.baro;
companion = old.companion;
@@ -1024,6 +1035,12 @@ public class AltosState implements Cloneable {
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;
@@ -1060,6 +1077,15 @@ public class AltosState implements Cloneable {
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() {
if (rssi == AltosLib.MISSING)
return 0;
diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java
index 4d50a059..2f15cd89 100644
--- a/altoslib/AltosTelemetry.java
+++ b/altoslib/AltosTelemetry.java
@@ -114,6 +114,35 @@ public abstract class AltosTelemetry implements AltosStateUpdate {
return telem;
}
+ public static int extend_height(AltosState state, int height_16) {
+ double compare_height;
+ int height = height_16;
+
+ System.out.printf("state kalman height %g altitude %g ground_altitude %g gps_height %g\n",
+ state.kalman_height.value(), state.altitude(), state.ground_altitude(), state.gps_height());
+ 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);
+
+ 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;
+ if (height != height_16) {
+ System.out.printf("Height adjusted from %d to %d with %g\n",
+ height_16, height, compare_height);
+ }
+ }
+ return height;
+ }
+
public static AltosTelemetry parse(String line) throws ParseException, AltosCRCException {
String[] word = line.split("\\s+");
int i =0;
diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java
index b7aae3c4..72a8bc4a 100644
--- a/altoslib/AltosTelemetryLegacy.java
+++ b/altoslib/AltosTelemetryLegacy.java
@@ -186,6 +186,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
* g_v GPS vertical speed (integer, cm/sec)
* g_s GPS horizontal speed (integer, cm/sec)
* g_c GPS course (integer, 0-359)
+ * g_pd GPS pdop (integer * 10)
* g_hd GPS hdop (integer * 10)
* g_vd GPS vdop (integer * 10)
* g_he GPS h error (integer)
@@ -209,6 +210,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
final static String AO_TELEM_GPS_VERTICAL_SPEED = "g_v";
final static String AO_TELEM_GPS_HORIZONTAL_SPEED = "g_g";
final static String AO_TELEM_GPS_COURSE = "g_c";
+ final static String AO_TELEM_GPS_PDOP = "g_pd";
final static String AO_TELEM_GPS_HDOP = "g_hd";
final static String AO_TELEM_GPS_VDOP = "g_vd";
final static String AO_TELEM_GPS_HERROR = "g_he";
diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java
index 32ca7608..427ae16e 100644
--- a/altoslib/AltosTelemetryLocation.java
+++ b/altoslib/AltosTelemetryLocation.java
@@ -37,11 +37,12 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard {
int climb_rate;
int course;
+ public static final int AO_GPS_MODE_ALTITUDE_24 = (1 << 0); /* Reports 24-bits of altitude */
+
public AltosTelemetryLocation(int[] bytes) {
super(bytes);
flags = uint8(5);
- altitude = int16(6);
latitude = uint32(8);
longitude = uint32(12);
year = uint8(16);
@@ -57,6 +58,11 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard {
ground_speed = uint16(26);
climb_rate = int16(28);
course = uint8(30);
+
+ if ((mode & AO_GPS_MODE_ALTITUDE_24) != 0) {
+ altitude = (int8(31) << 16) | uint16(6);
+ } else
+ altitude = int16(6);
}
public void update_state(AltosState state) {
@@ -80,8 +86,9 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard {
gps.ground_speed = ground_speed * 1.0e-2;
gps.course = course * 2;
gps.climb_rate = climb_rate * 1.0e-2;
- gps.hdop = hdop;
- gps.vdop = vdop;
+ gps.pdop = pdop / 10.0;
+ gps.hdop = hdop / 10.0;
+ gps.vdop = vdop / 10.0;
}
state.set_temp_gps();
}
diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java
index 93610118..8b1869bb 100644
--- a/altoslib/AltosTelemetryMegaData.java
+++ b/altoslib/AltosTelemetryMegaData.java
@@ -31,7 +31,7 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard {
int acceleration;
int speed;
- int height;
+ int height_16;
public AltosTelemetryMegaData(int[] bytes) {
super(bytes);
@@ -55,7 +55,8 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard {
acceleration = int16(26);
speed = int16(28);
- height = int16(30);
+
+ height_16 = int16(30);
}
public void update_state(AltosState state) {
@@ -79,7 +80,13 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard {
state.set_ground_pressure(ground_pres);
state.set_accel_g(accel_plus_g, accel_minus_g);
- state.set_kalman(height, speed/16.0, acceleration / 16.0);
+ /* 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);
}
}
diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java
index 3e0abedc..beab6da9 100644
--- a/altoslib/AltosTelemetryMetrumSensor.java
+++ b/altoslib/AltosTelemetryMetrumSensor.java
@@ -27,7 +27,7 @@ public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {
int acceleration;
int speed;
- int height;
+ int height_16;
int v_batt;
int sense_a;
@@ -43,7 +43,7 @@ public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {
acceleration = int16(14);
speed = int16(16);
- height = int16(18);
+ height_16 = int16(18);
v_batt = int16(20);
sense_a = int16(22);
@@ -59,7 +59,8 @@ public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {
state.set_pressure(pres);
state.set_temperature(temp/100.0);
- state.set_kalman(height, speed/16.0, acceleration/16.0);
+ state.set_kalman(extend_height(state, height_16),
+ speed/16.0, acceleration/16.0);
state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt));
diff --git a/altoslib/AltosWriter.java b/altoslib/AltosWriter.java
index 9df52250..fb208b02 100644
--- a/altoslib/AltosWriter.java
+++ b/altoslib/AltosWriter.java
@@ -19,8 +19,6 @@ package org.altusmetrum.altoslib_5;
public interface AltosWriter {
- public void write(AltosState state);
-
public void write(AltosStateIterable states);
public void close();