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;
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) {
+ 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());
+*/
}
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) {
+ void write_gps() {
+/*
AltosGPS gps = state.gps;
if (gps == null)
gps = new AltosGPS();
gps.pdop,
gps.hdop,
gps.vdop);
+*/
}
void write_gps_sat_header() {
}
}
- void write_gps_sat(AltosState state) {
+ void write_gps_sat() {
+/*
AltosGPS gps = state.gps;
for(int i = 1; i <= 32; i++) {
int c_n0 = 0;
if (i != 32)
out.printf(",");
}
+*/
}
void write_companion_header() {
out.printf(",companion_%02d", i);
}
- void write_companion(AltosState state) {
+ void write_companion() {
+/*
AltosCompanion companion = state.companion;
int channels_written = 0;
}
for (; channels_written < 12; channels_written++)
out.printf(",0");
+*/
}
void write_header() {
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() {
}
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.fill_in();
has_flight_state = false;
has_basic = 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.accel_across() != AltosLib.MISSING)
- has_advanced = 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 (state.gps != null) {
has_gps = true;
if (state.gps.cc_gps_sat != null)
if (state.companion != null)
has_companion = true;
}
- for (AltosState state : states)
- write(state);
+*/
+ indices = series.indices();
+
+ for (;;) {
+ write();
+ if (!series.step_indices(indices))
+ break;
+ }
}
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 {
--- /dev/null
+/*
+ * 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_11;
+
+/*
+ * 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;
+ }
+
+ 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) {
+ 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 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;
+ }
+ }
+ this.tick = tick;
+ }
+ }
+
+ public int boost_tick = AltosLib.MISSING;
+
+ public void set_boost_tick() {
+ boost_tick = tick;
+ }
+
+ public double time() {
+ if (tick == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ if (boost_tick == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return (tick - boost_tick) / 100.0;
+ }
+
+ public double boost_time() {
+ if (boost_tick == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return boost_tick / 100.0;
+ }
+
+ 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 double gps_ground_altitude = AltosLib.MISSING;
+
+ public void set_gps_altitude(double altitude) {
+ if ((state != AltosLib.MISSING && state < AltosLib.ao_flight_boost) ||
+ gps_ground_altitude == AltosLib.MISSING)
+ gps_ground_altitude = altitude;
+ }
+
+ /*
+ * While receiving GPS data, we construct a temporary GPS state
+ * object and then deliver the result atomically to the listener
+ */
+ AltosGPS temp_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_altitude(temp_gps.alt);
+ }
+ temp_gps = null;
+ }
+
+ public boolean gps_pending() {
+ return temp_gps != null;
+ }
+
+ public AltosGPS make_temp_gps(int tick, 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 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;
+ }
+ }
+
+ public double gyro_roll(double counts) {
+ if (gyro_zero_roll == AltosLib.MISSING || counts == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return AltosIMU.convert_gyro(counts - gyro_zero_roll);
+ }
+
+ public double gyro_pitch(double counts) {
+ if (gyro_zero_pitch == AltosLib.MISSING || counts == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return AltosIMU.convert_gyro(counts - gyro_zero_pitch);
+ }
+
+ public double gyro_yaw(double counts) {
+ if (gyro_zero_yaw == AltosLib.MISSING || counts == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return AltosIMU.convert_gyro(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);
+ return v * 128.0;
+ }
+
+ public void check_imu_wrap(double roll, double pitch, double yaw) {
+ gyro_zero_roll += gyro_zero_overflow(roll);
+ gyro_zero_pitch += gyro_zero_overflow(pitch);
+ gyro_zero_yaw += gyro_zero_overflow(yaw);
+ }
+
+ 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_flight(config_data.flight);
+ set_callsign(config_data.callsign);
+ set_accel_plus_minus(config_data.accel_cal_plus, config_data.accel_cal_minus);
+ set_ms5607(config_data.ms5607);
+ try {
+ set_mma655x_inverted(config_data.mma655x_inverted());
+ } catch (AltosUnknownProduct up) {
+ }
+ set_pad_orientation(config_data.pad_orientation);
+ }
+}
import java.text.*;
import java.util.concurrent.*;
-public class AltosConfigData implements Iterable<String> {
+public class AltosConfigData {
/* Version information */
public String manufacturer;
public String version;
public int altitude_32;
- /* Strings returned */
- public LinkedList<String> __lines;
-
/* Config information */
/* HAS_FLIGHT*/
public int main_deploy;
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)) {
throw new ParseException("mismatch", 0);
}
- public Iterator<String> iterator() {
- return __lines.iterator();
- }
-
public int log_space() {
if (log_space > 0)
return log_space;
}
public void reset() {
- __lines = new LinkedList<String>();
-
manufacturer = null;
product = null;
serial = 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) {}
/* 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 */
import java.util.*;
public class AltosConvert {
+
+ public static final double gravity = 9.80665;
+
/*
* Pressure Sensor Model, version 1.1
*
* 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
};
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];
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;
+ return (sensor - ground) / counts_per_mss;
+ }
+
public static boolean imperial_units = false;
public static AltosDistance distance = new AltosDistance();
public static AltosRotationRate rotation_rate = new AltosRotationRate();
+ public static AltosStateName state_name = new AltosStateName();
+
public static String show_gs(String format, double a) {
a = meters_to_g(a);
format = format.concat(" g");
--- /dev/null
+/*
+ * 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_11;
+
+public abstract class AltosDataListener {
+
+ public AltosCalData cal_data;
+
+ public double time = AltosLib.MISSING;
+
+ public void set_time(double time) {
+ if (time != AltosLib.MISSING)
+ this.time = time;
+ }
+
+ public double time() {
+ return time;
+ }
+
+ public int state = AltosLib.MISSING;
+
+ public void set_state(int state) {
+ if (state != AltosLib.MISSING)
+ this.state = state;
+ }
+
+ 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_ignitor_voltage(double[] voltage);
+ public abstract void set_pyro_fired(int pyro_mask);
+ public abstract void set_companion(AltosCompanion companion);
+
+ public AltosDataListener(AltosCalData cal_data) {
+ this.cal_data = cal_data;
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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;
+
+public interface AltosDataProvider {
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) throws InterruptedException, AltosUnknownProduct;
+}
import java.util.*;
import java.text.*;
-public abstract class AltosEeprom implements AltosStateUpdate {
+public abstract class AltosEeprom implements AltosDataProvider {
public int cmd;
public int tick;
public int data8[];
public abstract int record_length();
- public void update_state(AltosState state) {
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ cal_data.set_tick(tick);
if (cmd == AltosLib.AO_LOG_FLIGHT)
- state.set_boost_tick(tick);
- else
- state.set_tick(tick);
+ cal_data.set_boost_tick();
+ listener.set_time(cal_data.time());
}
public void write(PrintStream out) {
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_ignitor_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;
gps.day != AltosLib.MISSING;
}
- private AltosFile MakeFile(int serial, int flight, AltosState state) throws IOException {
+ private AltosFile MakeFile(int serial, int flight, AltosEepromNameData name_data) throws IOException {
AltosFile eeprom_name;
- if (has_gps_date(state)) {
- AltosGPS gps = state.gps;
+ if (name_data.gps != null) {
+ AltosGPS gps = name_data.gps;
eeprom_name = new AltosFile(gps.year, gps.month, gps.day,
serial, flight, "eeprom");
} else
* doesn't need to work; we'll still save the data using
* a less accurate name.
*/
- AltosEepromRecordSet set = new AltosEepromRecordSet(eeprom);
-
- AltosState state = new AltosState();
+ AltosEepromRecordSet set = new AltosEepromRecordSet(eeprom);
+ AltosEepromNameData name_data = new AltosEepromNameData(set.cal_data());
- for (AltosState s : set) {
- state = s;
- if (state.gps != null)
+ 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, state);
+ AltosFile f = MakeFile(flights.config_data.serial, log.flight, name_data);
monitor.set_filename(f.toString());
import java.util.*;
import java.text.*;
-public class AltosEepromFile extends AltosStateIterable implements AltosRecordSet {
+public class AltosEepromFile implements AltosRecordSet {
AltosEepromRecordSet set;
- public AltosConfigData config_data() {
- return set.eeprom.config_data();
- }
-
public void write_comments(PrintStream out) {
}
set = new AltosEepromRecordSet(input);
}
- public Iterator<AltosState> iterator() {
- return set.iterator();
+ public AltosConfigData config_data() {
+ return set.config_data();
+ }
+
+ public AltosCalData cal_data() {
+ return set.cal_data();
}
- public void capture_series(AltosFlightSeries series) {
+ public void capture_series(AltosDataListener series) {
set.capture_series(series);
}
}
return config_data;
}
- public void reset_config_data() {
- config_data = null;
- }
-
private void write_config(Writer w) throws IOException {
config.write(w, 0, true);
w.append('\n');
return start - o.start;
}
- public void update_state(AltosFlightListener listen) {
+ /* AltosDataProvider */
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ cal_data.set_tick(tick());
if (cmd() == AltosLib.AO_LOG_FLIGHT)
- listen.set_boost_tick(tick());
- else
- listen.set_tick(tick());
+ cal_data.set_boost_tick();
+ listener.set_time(cal_data.time());
}
public int next_start() {
return AltosConvert.lb_to_n(v * 298 * 9.807);
}
- public void update_state(AltosFlightListener state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- state.set_flight(flight());
- state.set_ground_pressure(0.0);
- state.set_accel_g(0, -1);
+ 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()));
- state.set_thrust(adc_to_n(thrust()));
+ listener.set_pressure(adc_to_pa(pres()));
+ listener.set_thrust(adc_to_n(thrust()));
break;
}
}
public static final int two_g_default = 16294 - 15758;
- public void update_state(AltosFlightListener state) {
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
- super.update_state(state);
+ super.provide_data(listener, cal_data);
AltosGPS gps;
/* Flush any pending GPS changes */
- if (state.gps_pending()) {
+ if (cal_data.gps_pending()) {
switch (cmd()) {
case AltosLib.AO_LOG_GPS_LAT:
case AltosLib.AO_LOG_GPS_LON:
case AltosLib.AO_LOG_GPS_DATE:
break;
default:
- state.set_temp_gps();
+ listener.set_gps(cal_data.temp_gps());
+ cal_data.reset_temp_gps();
break;
}
}
switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- state.set_state(AltosLib.ao_flight_pad);
- state.set_ground_accel(data16(0));
- state.set_flight(data16(2));
- if (state.accel_plus_g == AltosLib.MISSING)
- state.set_accel_g(data16(0), data16(0) + two_g_default);
+ 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:
- state.set_accel(data16(0));
- state.set_pressure(AltosConvert.barometer_to_pressure(data16(2)));
+ listener.set_acceleration(cal_data.acceleration(data16(0)));
+ listener.set_pressure(AltosConvert.barometer_to_pressure(data16(2)));
break;
case AltosLib.AO_LOG_PRESSURE:
- state.set_pressure(AltosConvert.barometer_to_pressure(data16(2)));
+ listener.set_pressure(AltosConvert.barometer_to_pressure(data16(2)));
break;
case AltosLib.AO_LOG_TEMP_VOLT:
- state.set_temperature(AltosConvert.thermometer_to_temperature(data16(0)));
- state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(data16(2)));
+ 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:
- state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(data16(0)));
- state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(data16(2)));
+ listener.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(data16(0)));
+ listener.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(data16(2)));
break;
case AltosLib.AO_LOG_STATE:
- state.set_state(data16(0));
+ listener.set_state(data16(0));
break;
case AltosLib.AO_LOG_GPS_TIME:
- gps = state.make_temp_gps(false);
+ gps = cal_data.make_temp_gps(tick(),false);
gps.hour = data8(0);
gps.minute = data8(1);
AltosLib.AO_GPS_NUM_SAT_SHIFT;
break;
case AltosLib.AO_LOG_GPS_LAT:
- gps = state.make_temp_gps(false);
+ 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 = state.make_temp_gps(false);
+ 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 = state.make_temp_gps(false);
+ gps = cal_data.make_temp_gps(tick(),false);
gps.alt = data16(0);
break;
case AltosLib.AO_LOG_GPS_SAT:
- gps = state.make_temp_gps(true);
+ 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 = state.make_temp_gps(false);
+ gps = cal_data.make_temp_gps(tick(),false);
gps.year = data8(0) + 2000;
gps.month = data8(1);
gps.day = data8(2);
return start - o.start;
}
- public void update_state(AltosFlightListener state) {
- super.update_state(state);
-
- AltosGPS gps;
-
- /* Flush any pending RecordGps 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()) {
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:
- gps = state.make_temp_gps(false);
+ AltosGPS gps = new AltosGPS();
gps.lat = latitude() / 1e7;
gps.lon = longitude() / 1e7;
if (eeprom.config_data().altitude_32 == 1)
if (gps.vdop < 0.8)
gps.vdop += 2.56;
}
+ listener.set_gps(gps);
break;
}
}
private int svid(int n) { return data8(2 + n * 2); }
private int c_n(int n) { return data8(2 + n * 2 + 1); }
- public void update_state(AltosFlightListener 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()) {
+ if (cal_data.gps_pending()) {
switch (cmd()) {
case AltosLib.AO_LOG_GPS_LAT:
case AltosLib.AO_LOG_GPS_LON:
case AltosLib.AO_LOG_GPS_DATE:
break;
default:
- state.set_temp_gps();
+ listener.set_gps(cal_data.temp_gps());
+ cal_data.reset_temp_gps();
break;
}
}
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_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);
+ 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:
- state.set_state(state());
+ listener.set_state(state());
break;
case AltosLib.AO_LOG_SENSOR:
- 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 */
+ 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_x();
+ int mag_across = mag_y();
+ int mag_through = mag_z();
if (log_format == AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD)
- state.check_imu_wrap(imu);
+ 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));
- state.set_imu(imu);
+ listener.set_mag(cal_data.mag_along(mag_along),
+ cal_data.mag_across(mag_across),
+ cal_data.mag_through(mag_through));
- state.set_mag(new AltosMag(mag_x(),
- mag_y(),
- mag_z()));
- state.set_accel(accel());
+ double acceleration = AltosConvert.acceleration_from_sensor(
+ accel(),
+ config_data.accel_cal_plus,
+ config_data.accel_cal_minus,
+ AltosLib.MISSING);
+ listener.set_acceleration(acceleration);
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()));
+ listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
+ listener.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)));
+ 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));
- state.set_ignitor_voltage(voltages);
- state.set_pyro_fired(pyro());
+ listener.set_ignitor_voltage(voltages);
+ listener.set_pyro_fired(pyro());
break;
case AltosLib.AO_LOG_GPS_TIME:
- gps = state.make_temp_gps(false);
+ gps = cal_data.make_temp_gps(tick(), false);
gps.lat = latitude() / 1e7;
gps.lon = longitude() / 1e7;
}
break;
case AltosLib.AO_LOG_GPS_SAT:
- gps = state.make_temp_gps(true);
+ gps = cal_data.make_temp_gps(tick(), true);
int n = nsat();
if (n > max_sat)
public int svid(int n) { return data8(2 + n * 2); }
public int c_n(int n) { return data8(2 + n * 2 + 1); }
- public void update_state(AltosFlightListener 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()) {
+ if (cal_data.gps_pending()) {
switch (cmd()) {
case AltosLib.AO_LOG_GPS_POS:
case AltosLib.AO_LOG_GPS_LAT:
case AltosLib.AO_LOG_GPS_DATE:
break;
default:
- state.set_temp_gps();
+ listener.set_gps(cal_data.temp_gps());
+ cal_data.reset_temp_gps();
break;
}
}
switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- state.set_flight(flight());
- state.set_ground_accel(ground_accel());
- state.set_ground_pressure(ground_pres());
+ 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 (config_data().altitude_32())
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();
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++)
return -1;
}
- public void update_state(AltosFlightListener state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- state.set_flight(flight());
- state.set_ground_pressure(ground_pres());
+ cal_data.set_flight(flight());
+ 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_apogee_voltage(pyro_voltage(sense_a()));
- state.set_main_voltage(pyro_voltage(sense_m()));
- state.set_battery_voltage(battery_voltage(v_batt()));
+ 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;
}
}
import java.io.*;
import java.util.*;
-public class AltosEepromRecordSet implements Iterable<AltosState>, AltosRecordSet {
+public class AltosEepromRecordSet implements AltosRecordSet {
AltosEepromNew eeprom;
TreeSet<AltosEepromRecord> ordered;
- AltosState start_state;
+ AltosCalData cal_data;
- class RecordIterator implements Iterator<AltosState> {
- Iterator<AltosEepromRecord> riterator;
- AltosState state;
- boolean started;
-
- public boolean hasNext() {
- return state == null || riterator.hasNext();
- }
+ public AltosConfigData config_data() {
+ return eeprom.config_data();
+ }
- public AltosState next() {
- if (state == null)
- state = start_state.clone();
- else {
- state = state.clone();
- AltosEepromRecord r = riterator.next();
- r.update_state(state);
+ 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();
+ }
}
- return state;
- }
-
- public RecordIterator() {
- riterator = ordered.iterator();
- state = null;
}
+ return cal_data;
}
- public Iterator<AltosState> iterator() {
- return new RecordIterator();
- }
-
- public void capture_series(AltosFlightSeries series) {
- series.set_config_data(eeprom.config_data());
+ public void capture_series(AltosDataListener listener) {
+ AltosCalData cal_data = cal_data();
for (AltosEepromRecord record : ordered) {
- record.update_state(series);
+ record.provide_data(listener, cal_data);
}
}
int tick = 0;
boolean first = true;
- start_state = new AltosState();
- start_state.set_config_data(record.eeprom.config_data());
-
for (;;) {
int t = record.tick();
package org.altusmetrum.altoslib_11;
-public class AltosEepromRecordTiny extends AltosEepromRecord {
+public class AltosEepromRecordTiny extends AltosEepromRecord implements AltosDataProvider {
public static final int record_length = 2;
private int value() {
return tick;
}
- public void update_state(AltosFlightListener state) {
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
int value = data16(-header_length);
- state.set_tick(tick());
+ cal_data.set_tick(tick());
switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- state.set_state(AltosLib.ao_flight_pad);
- state.set_flight(value);
- state.set_boost_tick(0);
+ listener.set_state(AltosLib.ao_flight_pad);
+ cal_data.set_flight(value);
+ cal_data.set_boost_tick();
break;
case AltosLib.AO_LOG_STATE:
- state.set_state(value & 0x7fff);
+ listener.set_state(value & 0x7fff);
break;
case AltosLib.AO_LOG_SENSOR:
- state.set_pressure(AltosConvert.barometer_to_pressure(value));
+ listener.set_pressure(AltosConvert.barometer_to_pressure(value));
break;
}
}
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");
}
}
public abstract class AltosFlightListener {
- int flight;
+ public int flight;
+ public int serial;
+ public int tick;
+ public int boost_tick;
+ public int state;
- public int tick;
- int boost_tick;
+ public double accel_plus_g;
+ public double accel_minus_g;
+ public double accel;
- AltosGPS temp_gps;
- int temp_gps_sat_tick;
+ 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) {
public double time() {
if (tick == AltosLib.MISSING)
return AltosLib.MISSING;
- return tick / 100.0;
+ if (boost_tick != AltosLib.MISSING)
+ return (tick - boost_tick) / 100.0;
+ else
+ return tick / 100.0;
}
public double boost_time() {
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 abstract void set_state(int state);
+ 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)
}
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);
return temp_gps;
}
- public abstract void set_ground_pressure(double ground_pressure);
+ 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 set_ms5607(int pres_val, int temp_val);
public abstract void check_imu_wrap(AltosIMU imu);
public abstract void set_imu(AltosIMU imu);
public abstract void set_mag(AltosMag mag);
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;
}
}
import java.util.*;
-public class AltosFlightSeries extends AltosFlightListener {
+public class AltosFlightSeries extends AltosDataListener {
- int flight;
+ public ArrayList<AltosTimeSeries> series;
- int tick;
- int boost_tick;
+ public int[] indices() {
+ int[] indices = new int[series.size()];
+ for (int i = 0; i < indices.length; i++)
+ indices[i] = 0;
+ return indices;
+ }
- AltosGPS temp_gps;
- int temp_gps_sat_tick;
+ private double time(int id, int index) {
+ AltosTimeSeries s = series.get(id);
+ if (index < s.values.size())
+ return s.values.get(index).time;
+ return Double.POSITIVE_INFINITY;
+ }
- AltosMs5607 ms5607;
+ public boolean step_indices(int[] indices) {
+ double min_next = time(0, indices[0]+1);
- public ArrayList<AltosTimeSeries> series;
+ for (int i = 1; i < indices.length; i++) {
+ double next = time(i, indices[i]+1);
+ if (next < min_next)
+ min_next = next;
+ }
- /* AltosEepromRecord */
- public void set_boost_tick(int boost_tick) {
- if (boost_tick != AltosLib.MISSING)
- this.boost_tick = boost_tick;
- }
+ if (min_next == Double.POSITIVE_INFINITY)
+ return false;
- public void set_tick(int tick) {
- if (tick != AltosLib.MISSING)
- this.tick = tick;
+ 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() {
- if (tick == AltosLib.MISSING)
- return AltosLib.MISSING;
- return tick / 100.0;
+ 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 boost_time() {
- if (boost_tick == AltosLib.MISSING)
- return AltosLib.MISSING;
- return boost_tick / 100.0;
+ 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))
+ return s.values.get(indices[i]).value;
+ }
+ return AltosLib.MISSING;
}
public AltosTimeSeries make_series(String label, AltosUnits units) {
return new AltosTimeSeries(label, units);
}
+ public void add_series(AltosTimeSeries s) {
+ series.add(s);
+ }
+
public AltosTimeSeries add_series(String label, AltosUnits units) {
- System.out.printf("add series %s\n", label);
AltosTimeSeries s = make_series(label, units);
- series.add(s);
+ add_series(s);
return s;
}
- /* AltosEepromRecordFull */
+ 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;
+ }
AltosTimeSeries state_series;
public static final String state_name = "State";
public void set_state(int state) {
+ this.state = state;
if (state_series == null)
- state_series = add_series(state_name, null);
+ state_series = add_series(state_name, AltosConvert.state_name);
+ else if ((int) state_series.get(state_series.size()-1).value == state)
+ return;
state_series.add(time(), state);
}
- public void set_flight(int flight) {
- if (flight != AltosLib.MISSING)
- this.flight = flight;
- }
- public int flight() {
- return flight;
- }
-
AltosTimeSeries accel_series;
- double accel_plus_g, accel_minus_g;
-
public static final String accel_name = "Accel";
- public void set_accel(double accel) {
- if (accel_series == null)
+ public void set_acceleration(double acceleration) {
+ if (accel_series == null) {
+ System.out.printf("set acceleration %g\n", acceleration);
accel_series = add_series(accel_name, AltosConvert.accel);
- double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0;
- double counts_per_mss = counts_per_g / 9.80665;
- double mss = (accel_plus_g - accel) / counts_per_mss;
-
- accel_series.add(time(), mss);
+ }
+ accel_series.add(time(), acceleration);
}
+ private void compute_accel() {
+ if (accel_series != null)
+ return;
- public void set_accel_g(double accel_plus_g, double accel_minus_g) {
- this.accel_plus_g = accel_plus_g;
- this.accel_minus_g = accel_minus_g;
+ if (speed_series != null) {
+ AltosTimeSeries temp_series = make_series(accel_name, AltosConvert.accel);
+ speed_series.differentiate(temp_series);
+ accel_series = add_series(accel_name, AltosConvert.accel);
+ temp_series.filter(accel_series, 0.25);
+ }
}
- public void set_config_data(AltosConfigData config_data) {
-// if (config_data.callsign != null)
-// set_callsign(config_data.callsign);
- if (config_data.accel_cal_plus != AltosLib.MISSING &&
- config_data.accel_cal_minus != AltosLib.MISSING)
- set_accel_g(config_data.accel_cal_plus, config_data.accel_cal_minus);
-// if (config_data.product != null)
-// set_product(config_data.product);
-// if (config_data.log_format != AltosLib.MISSING)
-// set_log_format(config_data.log_format);
-// if (config_data.serial != AltosLib.MISSING)
-// set_serial(config_data.serial);
- AltosMs5607 ms5607 = new AltosMs5607(config_data);
- if (ms5607.valid_config())
- this.ms5607 = ms5607;
+ public void set_received_time(long received_time) {
}
- public void set_ground_accel(double ground_accel) {
+ AltosTimeSeries rssi_series;
+
+ public static final String rssi_name = "RSSI";
+
+ AltosTimeSeries status_series;
+
+ public static final String status_name = "Status";
+
+ public void set_rssi(int rssi, int status) {
+ if (rssi_series == null)
+ rssi_series = add_series(rssi_name, null);
+ rssi_series.add(time(), rssi);
+ if (status_series == null)
+ status_series = add_series(status_name, null);
+ status_series.add(time(), status);
}
AltosTimeSeries pressure_series;
public static final String pressure_name = "Pressure";
+ AltosTimeSeries altitude_series;
+
+ public static final String altitude_name = "Altitude";
+
+ AltosTimeSeries height_series;
+
+ public static final String height_name = "Height";
+
public void set_pressure(double pa) {
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);
+
+ double altitude = AltosConvert.pressure_to_altitude(pa);
+ altitude_series.add(time(), altitude);
+ }
+
+ private void compute_height(double ground_altitude) {
+ if (height_series == null) {
+ height_series = add_series(height_name, AltosConvert.height);
+ for (AltosTimeValue alt : altitude_series)
+ height_series.add(alt.time, alt.value - ground_altitude);
+ }
+ }
+
+ AltosTimeSeries speed_series;
+
+ public static final String speed_name = "Speed";
+
+ private void compute_speed() {
+ if (speed_series != null) {
+ System.out.printf("speed series already made\n");
+ return;
+ }
+
+ AltosTimeSeries alt_speed_series = null;
+ AltosTimeSeries accel_speed_series = null;
+
+ if (altitude_series != null) {
+ AltosTimeSeries temp_series = make_series(speed_name, AltosConvert.speed);
+ altitude_series.differentiate(temp_series);
+
+ alt_speed_series = make_series(speed_name, AltosConvert.speed);
+ temp_series.filter(alt_speed_series, 10.0);
+ } else {
+ System.out.printf("no altitude series\n");
+ }
+ if (accel_series != null) {
+ AltosTimeSeries temp_series = make_series(speed_name, AltosConvert.speed);
+ accel_series.integrate(temp_series);
+
+ accel_speed_series = make_series(speed_name, AltosConvert.speed);
+ temp_series.filter(accel_speed_series, 0.1);
+ } else {
+ System.out.printf("no accel series\n");
+ }
+
+ 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);
+ System.out.printf("speed series for %s set to %s\n", this.toString(), speed_series.toString());
+ } else
+ System.out.printf("didn't manage to make speed series\n");
+ }
+
+ 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);
}
AltosTimeSeries thrust_series;
thrust_series.add(time(), N);
}
+ 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 void set_battery_voltage(double volts) {
+ 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 void set_apogee_voltage(double volts) {
+ 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 void set_main_voltage(double volts) {
+ 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);
}
AltosTimeSeries sats_in_view;
AltosTimeSeries sats_in_soln;
AltosTimeSeries gps_altitude;
+ AltosTimeSeries gps_height;
AltosTimeSeries gps_ground_speed;
AltosTimeSeries gps_ascent_rate;
AltosTimeSeries gps_course;
AltosTimeSeries gps_speed;
+ public ArrayList<AltosGPSTimeValue> gps_series;
+
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 void set_temp_gps() {
- if (sats_in_view == null) {
- sats_in_view = add_series("Satellites in view", null);
- sats_in_soln = add_series("Satellites in solution", null);
- gps_altitude = add_series("GPS Altitude", AltosConvert.height);
- gps_ground_speed = add_series("GPS Ground Speed", AltosConvert.speed);
- gps_ascent_rate = add_series("GPS Ascent Rate", AltosConvert.speed);
- gps_course = add_series("GPS Course", null);
- gps_speed = add_series("GPS Speed", null);
- }
-
- /* XXX capture GPS data */
- super.set_temp_gps();
- }
-
- public boolean gps_pending() {
- return temp_gps != null;
- }
+ public void set_gps(AltosGPS gps) {
+ if (gps_series == null)
+ gps_series = new ArrayList<AltosGPSTimeValue>();
+ gps_series.add(new AltosGPSTimeValue(time(), gps));
- public AltosGPS make_temp_gps(boolean sats) {
- if (temp_gps == null) {
- temp_gps = new AltosGPS();
+ if (sats_in_view == null) {
+ sats_in_view = add_series(sats_in_view_name, null);
+ sats_in_soln = add_series(sats_in_soln_name, null);
+ gps_altitude = add_series(gps_altitude_name, AltosConvert.height);
+ gps_height = add_series(gps_height_name, AltosConvert.height);
+ gps_ground_speed = add_series(gps_ground_speed_name, AltosConvert.speed);
+ gps_ascent_rate = add_series(gps_ascent_rate_name, AltosConvert.speed);
+ gps_course = add_series(gps_course_name, null);
+ gps_speed = add_series(gps_speed_name, null);
}
- if (sats) {
- if (tick != temp_gps_sat_tick)
- temp_gps.cc_gps_sat = null;
- temp_gps_sat_tick = tick;
+ if (gps.cc_gps_sat != null)
+ sats_in_view.add(time(), gps.cc_gps_sat.length);
+ if (gps.locked) {
+ sats_in_soln.add(time(), gps.nsat);
+ if (gps.alt != AltosLib.MISSING) {
+ gps_altitude.add(time(), gps.alt);
+ if (cal_data.gps_ground_altitude != AltosLib.MISSING)
+ gps_height.add(time(), gps.alt - cal_data.gps_ground_altitude);
+ }
+ if (gps.ground_speed != AltosLib.MISSING)
+ gps_ground_speed.add(time(), gps.ground_speed);
+ if (gps.climb_rate != AltosLib.MISSING)
+ gps_ascent_rate.add(time(), gps.climb_rate);
+ if (gps.course != AltosLib.MISSING)
+ gps_course.add(time(), gps.course);
+ if (gps.ground_speed != AltosLib.MISSING && gps.climb_rate != AltosLib.MISSING)
+ gps_speed.add(time(), Math.sqrt(gps.ground_speed * gps.ground_speed +
+ gps.climb_rate * gps.climb_rate));
}
- return temp_gps;
}
- public void set_ground_pressure(double ground_pressure) {
+ public static final String accel_across_name = "Accel Across";
+ public static final String accel_along_name = "Accel Along";
+ public static final String accel_through_name = "Accel Through";
+
+ public void set_accel(double along, double across, double through) {
}
public void set_accel_ground(double along, double across, double through) {
}
- public void set_gyro_zero(double roll, double pitch, double yaw) {
+ public void set_gyro(double roll, double pitch, double yaw) {
}
- public void set_ms5607(int pres_val, int temp_val) {
- if (ms5607 != null) {
- ms5607.set(pres_val, temp_val);
-
- set_pressure(ms5607.pa);
- set_temperature(ms5607.cc / 100.0);
- }
+ public void set_mag(double along, double across, double through) {
}
- public void check_imu_wrap(AltosIMU imu) {
- }
+ public void set_orient(double new_orient) { }
- public void set_imu(AltosIMU imu) {
+ public void set_pyro_voltage(double volts) {
}
- public void set_mag(AltosMag mag) {
+ public void set_ignitor_voltage(double[] voltage) {
}
- public void set_pyro_voltage(double volts) {
+ public void set_pyro_fired(int pyro_mask) {
}
- public void set_ignitor_voltage(double[] voltage) {
+ public void set_companion(AltosCompanion companion) {
}
- public void set_pyro_fired(int pyro_mask) {
+ public void fill_in() {
+ System.out.printf("fill in %s\n", this.toString());
+ compute_speed();
+ compute_accel();
+ if (cal_data.ground_altitude != AltosLib.MISSING)
+ compute_height(cal_data.ground_altitude);
}
public void init() {
- flight = AltosLib.MISSING;
- tick = AltosLib.MISSING;
- boost_tick = AltosLib.MISSING;
- temp_gps_sat_tick = AltosLib.MISSING;
+ time = AltosLib.MISSING;
series = new ArrayList<AltosTimeSeries>();
}
- public void copy(AltosFlightSeries old) {
- super.copy(old);
- }
-
public AltosTimeSeries[] series() {
+ fill_in();
return series.toArray(new AltosTimeSeries[0]);
}
- public AltosFlightSeries() {
+ public AltosFlightSeries(AltosCalData cal_data) {
+ super(cal_data);
+ System.out.printf("new flight series %s\n", this.toString());
init();
}
}
public boolean has_orient;
public int num_ignitor;
- 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)
+ for (AltosTimeValue state : series.state_series) {
+ if (state.value == AltosLib.ao_flight_landed) {
+ landed_state_time = state.time;
break;
+ }
}
- if (state == null)
+ if (landed_state_time == AltosLib.MISSING)
return AltosLib.MISSING;
- double landed_height = state.height();
+ double landed_height = AltosLib.MISSING;
+ for (AltosTimeValue height : series.height_series) {
+ if (height.time >= landed_state_time) {
+ landed_height = height.value;
+ 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) {
+ for (AltosTimeValue height : series.height_series) {
+ if (height.value > landed_height + 10) {
above = true;
} else {
- if (above && Math.abs(state.height() - landed_height) < 2) {
+ if (above && Math.abs(height.value - landed_height) < 2) {
above = false;
- landed_time = state.time;
+ landed_time = height.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)
+ 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;
+ }
+ }
+ 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 (state == null)
- return AltosLib.MISSING;
-
return boost_time;
}
- public AltosFlightStats(AltosStateIterable states) throws InterruptedException, IOException {
- double boost_time = boost_time(states);
+ public AltosFlightStats(AltosFlightSeries series) throws InterruptedException, IOException {
+ AltosCalData cal_data = series.cal_data;
+ double boost_time = boost_time(series);
double end_time = 0;
- double landed_time = landed_time(states);
+ double landed_time = landed_time(series);
+
+ System.out.printf("flight stats %s\n", series.toString());
year = month = day = AltosLib.MISSING;
hour = minute = second = AltosLib.MISSING;
state_accel[s] = 0.0;
}
+ 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;
+
+ if (series.gps_series != null) {
+ AltosGPS gps = series.gps_series.get(0).gps;
+
+ year = gps.year;
+ month = gps.month;
+ day = gps.day;
+ hour = gps.hour;
+ minute = gps.minute;
+ second = gps.second;
+ }
+
+ max_height = AltosLib.MISSING;
+ if (series.height_series != null)
+ max_height = series.height_series.max();
+ max_speed = AltosLib.MISSING;
+ if (series.speed_series != null)
+ max_speed = series.speed_series.max();
+ else
+ System.out.printf("missing speed series\n");
+ max_acceleration = AltosLib.MISSING;
+ if (series.accel_series != null)
+ max_acceleration = series.accel_series.max();
+ max_gps_height = AltosLib.MISSING;
+ if (series.gps_height != null)
+ max_gps_height = series.gps_height.max();
+
+/*
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;
state_id = AltosLib.ao_flight_landed;
}
- 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;
- }
- 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 (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];
}
}
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link, AltosCalData cal_data) 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 {
--- /dev/null
+/*
+ * 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_11;
+
+public class AltosGPSTimeValue {
+ public double time;
+ public AltosGPS gps;
+
+ public AltosGPSTimeValue(double time, AltosGPS gps) {
+ this.time = time;
+ this.gps = gps;
+ }
+}
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;
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, AltosCalData cal_data) throws InterruptedException {
try {
AltosIMU imu = new AltosIMU(link);
- if (imu != null)
- state.set_imu(imu);
+ if (imu != null) {
+ listener.set_accel(cal_data.accel_along(imu.accel_along),
+ cal_data.accel_across(imu.accel_across),
+ cal_data.accel_through(imu.accel_through));
+ listener.set_gyro(cal_data.gyro_roll(imu.gyro_roll),
+ cal_data.gyro_pitch(imu.gyro_pitch),
+ cal_data.gyro_yaw(imu.gyro_yaw));
+ }
} catch (TimeoutException te) {
}
}
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_sensor_tgps = 15;
static final int idle_sensor_tmini3 = 16;
- public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException, TimeoutException, AltosUnknownProduct {
+ public void provide_data(AltosDataListener listener, AltosLink link, AltosCalData cal_data) 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, cal_data);
break;
case idle_imu:
- AltosIMU.update_state(state, link, config_data);
+ AltosIMU.provide_data(listener, link, cal_data);
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, cal_data);
break;
case idle_mma655x:
- AltosMma655x.update_state(state, link, config_data);
+ AltosMma655x.provide_data(listener, link, cal_data);
break;
- case idle_sensor_tm:
- AltosSensorTM.update_state(state, link, config_data);
+/* case idle_sensor_tm:
+ AltosSensorTM.provide_data(listener, link, cal_data);
break;
case idle_sensor_metrum:
- AltosSensorMetrum.update_state(state, link, config_data);
+ AltosSensorMetrum.provide_data(listener, link, cal_data);
break;
case idle_sensor_mega:
- AltosSensorMega.update_state(state, link, config_data);
+ AltosSensorMega.provide_data(listener, link, cal_data);
break;
case idle_sensor_emini:
- AltosSensorEMini.update_state(state, link, config_data);
+ AltosSensorEMini.provide_data(listener, link, cal_data);
break;
case idle_sensor_tmini2:
- AltosSensorTMini2.update_state(state, link, config_data);
+ AltosSensorTMini2.provide_data(listener, link, cal_data);
break;
case idle_sensor_tgps:
- AltosSensorTGPS.update_state(state, link, config_data);
+ AltosSensorTGPS.provide_data(listener, link, cal_data);
break;
case idle_sensor_tmini3:
- AltosSensorTMini3.update_state(state, link, config_data);
+ AltosSensorTMini3.provide_data(listener, link, cal_data);
break;
+*/
}
- if (idle != null)
- idle.update_state(state);
}
}
}
-public class AltosIdleFetch implements AltosStateUpdate {
+public class AltosIdleFetch implements AltosDataProvider {
static final AltosIdler[] idlers = {
new AltosIdler("EasyMini",
- AltosIdler.idle_ms5607,
AltosIdler.idle_sensor_emini),
new AltosIdler("TeleMini-v1",
AltosIdler.idle_sensor_tm),
new AltosIdler("TeleMini-v2",
- AltosIdler.idle_ms5607,
AltosIdler.idle_sensor_tmini2),
new AltosIdler("TeleMini-v3",
- AltosIdler.idle_ms5607,
AltosIdler.idle_sensor_tmini3),
new AltosIdler("TeleMetrum-v1",
new AltosIdler("TeleMetrum-v2",
AltosIdler.idle_gps,
- AltosIdler.idle_ms5607, AltosIdler.idle_mma655x,
+ AltosIdler.idle_mma655x,
AltosIdler.idle_sensor_metrum),
new AltosIdler("TeleMega",
AltosIdler.idle_gps,
- AltosIdler.idle_ms5607, AltosIdler.idle_mma655x,
+ AltosIdler.idle_mma655x,
AltosIdler.idle_imu, AltosIdler.idle_mag,
AltosIdler.idle_sensor_mega),
new AltosIdler("EasyMega",
- AltosIdler.idle_ms5607, AltosIdler.idle_mma655x,
+ AltosIdler.idle_mma655x,
AltosIdler.idle_imu, AltosIdler.idle_mag,
AltosIdler.idle_sensor_mega),
new AltosIdler("TeleGPS",
AltosLink link;
- public void update_state(AltosState state) throws InterruptedException, AltosUnknownProduct {
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) 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, cal_data);
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) {
}
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;
+ AltosCalData cal_data = new AltosCalData(link.config_data());
try {
start_link();
- fetch.update_state(state);
+ fetch.provide_data(listener, cal_data);
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();
}
}
}
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) {
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)
try {
try {
start_link();
- fetch.update_state(state);
+ if (state == null)
+ state = new AltosState(new AltosCalData(link.config_data()));
+ fetch.provide_data(state, state.cal_data);
if (!link.has_error && !link.reply_abort)
worked = true;
} catch (TimeoutException te) {
File name;
PrintWriter out;
int flight_state = -1;
- AltosState prev = null;
+ AltosGPS prev = null;
double gps_start_altitude;
static final String[] kml_state_colors = {
"</Document>\n" +
"</kml>\n";
- void start (AltosState record) {
+ void start (int state) {
+/*
out.printf(kml_header_start, record.flight, record.serial);
out.printf("Date: %04d-%02d-%02d\n",
record.gps.year, record.gps.month, record.gps.day);
out.printf("Time: %2d:%02d:%02d\n",
record.gps.hour, record.gps.minute, record.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("%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() {
public void close() {
if (prev != null) {
- state_end(prev);
+ state_end();
end();
prev = null;
}
}
}
- public void write(AltosState state) {
- AltosGPS gps = state.gps;
-
- if (gps == null)
- return;
-
+ public void write(AltosGPS gps, int state, double height) {
if (gps.lat == AltosLib.MISSING)
return;
if (gps.lon == AltosLib.MISSING)
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(gps, state, height);
+ state_end();
}
state_start(state);
}
- coord(state);
- prev = state;
+// coord(0, gps, state, height);
+ prev = gps;
+ }
+
+ private int state(AltosFlightSeries series, double time) {
+ int s = AltosLib.MISSING;
+ for (AltosTimeValue state : series.state_series) {
+ if (state.time > time)
+ break;
+ s = (int) state.value;
+ }
+ return s;
+ }
+
+ private double height(AltosFlightSeries series, double time) {
+ double h = AltosLib.MISSING;
+ for (AltosTimeValue height : series.height_series) {
+ if (height.time > time)
+ break;
+ h = height.value;
+ }
+ return h;
}
- public void write(AltosStateIterable states) {
- for (AltosState state : states) {
- if ((state.set & AltosState.set_gps) != 0)
- write(state);
+ public void write(AltosFlightSeries series) {
+ for (AltosGPSTimeValue gps : series.gps_series) {
+ write(gps.gps, state(series, gps.time), height(series, gps.time));
}
}
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";
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) {
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, cal_data);
+
+ 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) {
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, AltosCalData cal_data) throws InterruptedException {
try {
AltosMag mag = new AltosMag(link);
if (mag != null)
- state.set_mag(mag);
+ listener.set_mag(cal_data.mag_along(mag.along),
+ cal_data.mag_across(mag.across),
+ cal_data.mag_through(mag.through));
} catch (TimeoutException te) {
}
}
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;
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);
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();
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) {
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, AltosCalData cal_data) throws InterruptedException, AltosUnknownProduct {
try {
AltosMma655x mma655x = new AltosMma655x(link);
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) {
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);
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]);
- }
- } 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;
- }
+ public AltosPresTemp pres_temp(AltosLink link) throws InterruptedException, TimeoutException {
+ int raw_pres = AltosLib.MISSING;
+ int raw_temp = AltosLib.MISSING;
+ boolean done = false;
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
- try {
- AltosMs5607 ms5607 = new AltosMs5607(link, config_data);
+ link.printf("B\n");
+ while (!done) {
+ String line = link.get_reply_no_dialog(5000);
+ if (line == null)
+ throw new TimeoutException();
- if (ms5607 != null) {
- state.set_ms5607(ms5607);
- return;
+ 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;
}
- } catch (TimeoutException te) {
}
+ return pres_temp(raw_pres, raw_temp);
}
- 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 AltosMs5607(boolean ms5611) {
+ this.ms5611 = ms5611;
}
public AltosMs5607() {
- raw_pres = AltosLib.MISSING;
- raw_temp = AltosLib.MISSING;
- pa = AltosLib.MISSING;
- cc = AltosLib.MISSING;
+ 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;
}
public AltosMs5607(AltosConfigData config_data) {
- 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;
+ this(config_data.ms5607());
}
public AltosMs5607 (AltosLink link, AltosConfigData config_data) throws InterruptedException, TimeoutException {
this(config_data);
- 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();
}
}
}
}
- 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();
}
}
--- /dev/null
+/*
+ * 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_11;
+
+public class AltosPresTemp {
+ double pres = AltosLib.MISSING;
+ double temp = AltosLib.MISSING;
+
+ public AltosPresTemp(double pres, double temp) {
+ this.pres = pres;
+ this.temp = temp;
+ }
+}
import java.util.*;
public interface AltosRecordSet {
- public void capture_series(AltosFlightSeries series);
+ public AltosCalData cal_data();
+ public void capture_series(AltosDataListener listener);
}
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, AltosCalData cal_data) throws InterruptedException {
try {
AltosSensorTM sensor_tm = new AltosSensorTM(link);
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_ignitor_to_voltage(sensor_tm.drogue));
+ listener.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sensor_tm.main));
} catch (TimeoutException te) {
}
import java.io.*;
-public class AltosState extends AltosFlightListener implements Cloneable {
+public class AltosState extends AltosDataListener {
public static final int set_position = 1;
public static final int set_gps = 2;
public long received_time;
+ public int rssi;
+ public int status;
+
public double time;
public double prev_time;
public double time_change;
- private int prev_tick;
class AltosValue {
double value;
}
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 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);
}
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);
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 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;
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;
gps = null;
temp_gps = null;
temp_gps_sat_tick = 0;
- gps_sequence = 0;
gps_pending = false;
imu = null;
pad_orientation = AltosLib.MISSING;
- gyro_zero_roll = AltosLib.MISSING;
- gyro_zero_pitch = AltosLib.MISSING;
- gyro_zero_yaw = AltosLib.MISSING;
-
set_npad(0);
ngps = 0;
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;
}
void finish_update() {
- prev_tick = tick;
-
ground_altitude.finish_update();
altitude.finish_update();
pressure.finish_update();
kalman_acceleration.finish_update();
}
- void copy(AltosState old) {
-
- if (old == null) {
- init();
- return;
- }
-
- super.copy(old);
-
- 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() {
}
}
}
- 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 String state_name() {
return AltosLib.state_name(state);
}
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) {
}
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 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;
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;
}
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) {
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 = roll;
+ gyro_roll = roll;
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() {
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 && baro.pa != AltosLib.MISSING && baro.cc != AltosLib.MISSING) {
- 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);
- }
- }
-
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) {
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 void set_temp_gps() {
- set_gps(temp_gps, gps_sequence + 1);
- gps_pending = false;
- super.set_temp_gps();
- }
-
- public void set_config_data(AltosConfigData config_data) {
- if (config_data.callsign != null)
- set_callsign(config_data.callsign);
- if (config_data.accel_cal_plus != AltosLib.MISSING &&
- config_data.accel_cal_minus != AltosLib.MISSING)
- set_accel_g(config_data.accel_cal_plus, config_data.accel_cal_minus);
- if (config_data.product != null)
- set_product(config_data.product);
- if (config_data.log_format != AltosLib.MISSING)
- set_log_format(config_data.log_format);
- if (config_data.serial != AltosLib.MISSING)
- set_serial(config_data.serial);
- AltosMs5607 ms5607 = new AltosMs5607(config_data);
- if (ms5607.valid_config())
- set_ms5607(ms5607);
- }
-
- 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 () {
+ public AltosState (AltosCalData cal_data) {
+ super(cal_data);
init();
}
}
--- /dev/null
+/*
+ * 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_11;
+
+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; }
+}
+++ /dev/null
-/*
- * Copyright © 2013 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; 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;
-
-public interface AltosStateUpdate {
- public void update_state(AltosState state) throws InterruptedException, AltosUnknownProduct;
-}
* Telemetry data contents
*/
-public abstract class AltosTelemetry implements AltosStateUpdate {
+public abstract class AltosTelemetry implements AltosDataProvider {
int[] bytes;
/* All telemetry packets have these fields */
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, AltosCalData cal_data) {
+ cal_data.set_serial(serial());
+ if (listener.state == AltosLib.ao_flight_invalid)
+ listener.set_state(AltosLib.ao_flight_startup);
+ cal_data.set_tick(tick());
+ listener.set_time(cal_data.time());
+ listener.set_rssi(rssi(), status());
+ listener.set_received_time(received_time);
}
final static int PKT_APPEND_STATUS_1_CRC_OK = (1 << 7);
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);
-
- 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() {
this.received_time = System.currentTimeMillis();
}
super(bytes);
}
- public void update_state(AltosState state) {
- super.update_state(state);
- state.set_companion(companion());
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
+ listener.set_companion(companion());
}
}
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());
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_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)
- state.set_battery_voltage(AltosConvert.tele_gps_voltage(v_batt()));
+ 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());
}
}
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();
+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_ignitor_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 */
+ 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_ground_altitude == AltosLib.MISSING)
+ return false;
+
+ return true;
}
- public AltosState next() {
- if (seen) {
- AltosState n = state.clone();
- AltosTelemetry t = telems.next();
-
- t.update_state(n);
- state = n;
- }
- seen = true;
- return state;
- }
-
- 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, cal_data);
+ if (l.cal_data_complete())
+ break;
}
+ System.out.printf("Telemetry boost tick %d\n", cal_data.boost_tick);
}
+ 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();
- while (i.hasNext() && !state.valid()) {
- AltosTelemetry t = i.next();
- t.update_state(state);
- state.finish_update();
+ for (AltosTelemetry telem : telems) {
+ int tick = telem.tick();
+ cal_data.set_tick(tick);
+ if (cal_data.time() >= -1)
+ telem.provide_data(listener, cal_data);
}
- return new AltosTelemetryIterator(state, i);
+ }
+
+ public AltosTelemetryFile(FileInputStream input) {
+ telems = new AltosTelemetryIterable(input);
}
}
}
}
- 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);
-
- state.set_pressure(AltosConvert.barometer_to_pressure(pres));
- state.set_accel_g(accel_plus_g, accel_minus_g);
- state.set_accel(accel);
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ cal_data.set_tick(tick);
+ listener.set_time(cal_data.time());
+ listener.set_state(this.state);
+ cal_data.set_state(this.state);
+ cal_data.set_flight(flight);
+ cal_data.set_serial(serial);
+ listener.set_rssi(rssi, status);
+
+ listener.set_pressure(AltosConvert.barometer_to_pressure(pres));
+ 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_ignitor_to_voltage(apogee));
+ listener.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(main));
if (gps != null)
- state.set_gps(gps, gps_sequence);
+ listener.set_gps(gps);
}
}
super(bytes);
}
- public void update_state(AltosState state) {
- super.update_state(state);
- AltosGPS gps = state.make_temp_gps(false);
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
+
+ AltosGPS gps = new AltosGPS();
int flags = flags();
gps.nsat = flags & 0xf;
gps.pdop = pdop() / 10.0;
gps.hdop = hdop() / 10.0;
gps.vdop = vdop() / 10.0;
+
+ if (gps.nsat >= 4)
+ cal_data.set_gps_altitude(gps.alt);
}
- state.set_temp_gps();
+ listener.set_gps(gps);
}
}
super(bytes);
}
- 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);
- state.set_state(state());
+ listener.set_state(state());
+ cal_data.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));
- state.set_ignitor_voltage(voltages);
+ listener.set_ignitor_voltage(voltages);
- 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);
}
}
super(bytes);
}
- 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);
- state.set_accel(accel());
- state.set_pressure(pres());
- state.set_temperature(temp() / 100.0);
+ listener.set_acceleration(cal_data.acceleration(accel()));
+ listener.set_pressure(pres());
+ listener.set_temperature(temp() / 100.0);
- state.set_orient(orient());
+ listener.set_orient(orient());
- state.set_imu(new AltosIMU(accel_y(), /* along */
- accel_x(), /* across */
- accel_z(), /* through */
- gyro_y(), /* along */
- gyro_x(), /* across */
- gyro_z())); /* through */
+ /* XXX we have no calibration data for these values */
- state.set_mag(new AltosMag(mag_x(), mag_y(), mag_z()));
+ 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);
+
+ 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_x();
+ int mag_across = mag_y();
+ int mag_through = 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));
}
}
super(bytes);
}
- 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());
}
}
super(bytes);
}
- 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);
- state.set_state(state());
+ listener.set_state(state());
+ cal_data.set_state(state());
- state.set_accel(accel());
- state.set_pressure(pres());
- state.set_temperature(temp()/100.0);
+ listener.set_acceleration(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()));
}
}
super(bytes);
}
- 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);
- state.set_state(state());
+ listener.set_state(state());
+ cal_data.set_state(state());
- 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()));
+ 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_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);
}
}
super(bytes);
}
- 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);
- state.set_state(state());
+ cal_data.set_ground_pressure(ground_pres());
- state.set_battery_voltage(AltosConvert.tele_mini_3_battery_voltage(v_batt()));
+ listener.set_state(state());
+ cal_data.set_state(state());
- 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_battery_voltage(AltosConvert.tele_mini_3_battery_voltage(v_batt()));
- state.set_pressure(pres());
- state.set_temperature(temp()/100.0);
+ 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_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);
}
}
super(bytes);
}
- 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);
}
}
double frequency;
int telemetry;
int telemetry_rate;
- AltosState state = null;
+ public AltosState state = null;
+ public AltosCalData cal_data = null;
LinkedBlockingQueue<AltosLine> telem;
throw new IOException("IO error");
} while (!link.get_monitor());
AltosTelemetry telem = AltosTelemetry.parse(l.line);
+ if (cal_data == null)
+ cal_data = new AltosCalData();
if (state == null)
- state = new AltosState();
- else
- state = state.clone();
- telem.update_state(state);
+ state = new AltosState(cal_data);
+ telem.provide_data(state, cal_data);
return state;
}
public void reset() {
flush();
state = null;
+ cal_data = null;
}
public void close(boolean interrupted) {
--- /dev/null
+/*
+ * 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_11;
+
+import java.io.*;
+import java.util.*;
+
+public class AltosTelemetryRecordSet implements AltosRecordSet {
+ AltosTelemetry telemetry;
+ TreeSet<AltosTelemetryRecord> ordered;
+
+ public void capture_series(AltosDataListener series) {
+ for (AltosTelemetryRecord record : ordered) {
+ record.update_state(series);
+ }
+ }
+
+ public AltosTelemetryRecordSet(AltosTelemetry telemetry) {
+ this.telemetry = telemetry;
+
+ AltosTelemetryRecord record = null;
+
+ switch (config_data.log_format) {
+ case AltosLib.AO_LOG_FORMAT_FULL:
+ record = new AltosTelemetryRecordFull(eeprom);
+ break;
+ case AltosLib.AO_LOG_FORMAT_TINY:
+ record = new AltosTelemetryRecordTiny(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 AltosTelemetryRecordMega(eeprom);
+ break;
+ case AltosLib.AO_LOG_FORMAT_TELEMETRUM:
+ record = new AltosTelemetryRecordMetrum(eeprom);
+ break;
+ case AltosLib.AO_LOG_FORMAT_TELEMINI2:
+ case AltosLib.AO_LOG_FORMAT_TELEMINI3:
+ case AltosLib.AO_LOG_FORMAT_EASYMINI:
+ record = new AltosTelemetryRecordMini(eeprom);
+ break;
+ case AltosLib.AO_LOG_FORMAT_TELEGPS:
+ record = new AltosTelemetryRecordGps(eeprom);
+ break;
+ case AltosLib.AO_LOG_FORMAT_TELEFIRETWO:
+ record = new AltosTelemetryRecordFireTwo(eeprom);
+ break;
+ }
+
+ if (record == null) {
+ System.out.printf("failed to parse log format %d\n", config_data.log_format);
+ return;
+ }
+ ordered = new TreeSet<AltosTelemetryRecord>();
+ int tick = 0;
+ boolean first = true;
+
+ start_state = new AltosState();
+ start_state.set_config_data(record.eeprom.config_data());
+
+ 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 AltosTelemetryRecordSet(Reader input) throws IOException {
+ this(new AltosTelemetryNew(input));
+ }
+}
super(bytes);
}
- 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 = state.make_temp_gps(true);
+ AltosGPS gps = new AltosGPS();
gps.cc_gps_sat = sats();
- state.set_temp_gps();
+ listener.set_gps(gps);
}
}
super(bytes);
}
- 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);
+
+ listener.set_state(state());
+ cal_data.set_state(state());
- state.set_state(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());
+ 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()));
+ 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) {
- state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sense_d()));
- state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sense_m()));
+ listener.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sense_d()));
+ listener.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sense_m()));
}
- state.set_kalman(height_16(), speed()/16.0, acceleration()/16.0);
+ listener.set_kalman(height_16(), speed()/16.0, acceleration()/16.0);
}
}
super(bytes);
}
- 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);
}
}
public AltosUnits units;
List<AltosTimeValue> values;
- public void add(double x, double y) {
- values.add(new AltosTimeValue(x, y));
+ 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);
+ }
+
+ public int size() {
+ return values.size();
}
public Iterator<AltosTimeValue> iterator() {
return values.iterator();
}
- public void integrate(AltosTimeSeries integral) {
- double y = 0.0;
- double x = 0.0;
+ public double max() {
+ double max = AltosLib.MISSING;
+ for (AltosTimeValue tv : values) {
+ if (max == AltosLib.MISSING || tv.value > max)
+ max = tv.value;
+ }
+ return max;
+ }
+
+ public double min() {
+ double min = AltosLib.MISSING;
+ for (AltosTimeValue tv : values) {
+ if (min == AltosLib.MISSING || tv.value < min)
+ min = tv.value;
+ }
+ return min;
+ }
+
+ 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) {
- y = 0.0;
- x = v.x;
+ value = 0.0;
start = false;
} else {
- y += v.y * (v.x - x);
- x = v.x;
+ value += (pvalue + v.value) / 2.0 * (v.time - time);
}
- integral.add(x, y);
+ pvalue = v.value;
+ time = v.time;
+// System.out.printf("%g %g %g\n", time, v.value, value);
+ integral.add(time, value);
+
}
+ return integral;
}
- public void differentiate(AltosTimeSeries diff) {
- double y = 0.0;
- double x = 0.0;
+ public AltosTimeSeries differentiate(AltosTimeSeries diff) {
+ double value = 0.0;
+ double time = 0.0;
boolean start = true;
for (AltosTimeValue v: values) {
if (start) {
- y = 0.0;
- x = v.x;
+ value = v.value;
+ time = v.time;
start = false;
} else {
- double dx = v.x - x;
- double dy = v.y - y;
+ double dx = v.time - time;
+ double dy = v.value - value;
- x = v.x;
- y = v.y;
if (dx != 0)
- diff.add(x, dy);
+ 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).x - dt;
- for (j = i; j > 0; j--) {
- if (values.get(j).x < t)
+ 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;
+ return j - 1;
}
- public void filter(AltosTimeSeries out, double width) {
+ 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 coeff = filter_coeff(j_time - center_time, width);
+ total_coeff += coeff;
+ total_value += coeff * values.get(j).value;
+ }
+ }
+ if (total_coeff != 0.0)
+ f.add(center_time, total_value / total_coeff);
}
+ return f;
}
public AltosTimeSeries(String label, AltosUnits units) {
package org.altusmetrum.altoslib_11;
public class AltosTimeValue {
- public double x, y;
+ public double time;
+ public double value;
- public AltosTimeValue(double x, double y) {
- this.x = x;
- this.y = y;
+ public AltosTimeValue(double time, double value) {
+ this.time = time;
+ this.value = value;
}
}
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);
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;
public interface AltosWriter {
- public void write(AltosStateIterable states);
+ public void write(AltosFlightSeries series);
public void close();
}
altoslib_JAVA = \
AltosLib.java \
+ AltosCalData.java \
AltosCompanion.java \
AltosConfigData.java \
AltosConfigDataException.java \
AltosFile.java \
AltosFlash.java \
AltosFlashListener.java \
- AltosFlightListener.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 \
AltosOrient.java \
AltosParse.java \
AltosPressure.java \
+ AltosPresTemp.java \
AltosPreferences.java \
AltosPreferencesBackend.java \
AltosProgrammer.java \
AltosSensorMetrum.java \
AltosSensorTGPS.java \
AltosState.java \
- AltosStateIterable.java \
- AltosStateUpdate.java \
+ AltosStateName.java \
AltosTelemetry.java \
AltosTelemetryConfiguration.java \
AltosTelemetryCompanion.java \