From 222158581887b5f9e8b9843d14321c313fa023fa Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 25 May 2017 22:36:05 -0700 Subject: [PATCH] altoslib/altosuilib/altosui: More work towards using AltosFlightSeries for analysis Graphing and CSV seem complete now; stats still missing lots of stuff. Signed-off-by: Keith Packard --- altoslib/AltosCSV.java | 68 ++--- altoslib/AltosCalData.java | 11 +- altoslib/AltosConvert.java | 6 +- altoslib/AltosDataListener.java | 2 +- altoslib/AltosDistance.java | 2 +- altoslib/AltosEepromDownload.java | 2 +- altoslib/AltosEepromNew.java | 3 +- altoslib/AltosEepromRecord.java | 2 +- altoslib/AltosEepromRecordFull.java | 4 +- altoslib/AltosEepromRecordMega.java | 3 +- altoslib/AltosFlightListener.java | 2 +- altoslib/AltosFlightSeries.java | 211 +++++++++++++-- altoslib/AltosFlightStats.java | 6 +- altoslib/AltosLib.java | 2 +- altoslib/AltosMapLine.java | 32 +-- altoslib/AltosPyroName.java | 32 +++ altoslib/AltosSensorMega.java | 6 +- altoslib/AltosSensorTM.java | 4 +- altoslib/AltosState.java | 8 +- altoslib/AltosTelemetryFile.java | 4 +- altoslib/AltosTelemetryLegacy.java | 4 +- altoslib/AltosTelemetryLocation.java | 8 +- altoslib/AltosTelemetryMegaData.java | 2 +- altoslib/AltosTelemetrySensor.java | 4 +- altoslib/AltosTimeSeries.java | 65 ++++- altoslib/Makefile.am | 1 + altosui/AltosFlightUI.java | 22 +- altosui/AltosGraphUI.java | 9 +- altosui/AltosIdleMonitorUI.java | 24 +- altosui/AltosIgnitor.java | 42 +-- altosui/AltosUI.java | 2 +- altosuilib/AltosGraphNew.java | 377 +++++++++------------------ altosuilib/AltosUIFlightSeries.java | 15 +- altosuilib/AltosUITimeSeries.java | 15 +- 34 files changed, 555 insertions(+), 445 deletions(-) create mode 100644 altoslib/AltosPyroName.java diff --git a/altoslib/AltosCSV.java b/altoslib/AltosCSV.java index 0cfe4c94..38afdc64 100644 --- a/altoslib/AltosCSV.java +++ b/altoslib/AltosCSV.java @@ -192,31 +192,42 @@ public class AltosCSV implements AltosWriter { out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z"); } + double accel_along() { return series.value(AltosFlightSeries.accel_along_name, indices); } + double accel_across() { return series.value(AltosFlightSeries.accel_across_name, indices); } + double accel_through() { return series.value(AltosFlightSeries.accel_through_name, indices); } + + double gyro_roll() { return series.value(AltosFlightSeries.gyro_roll_name, indices); } + double gyro_pitch() { return series.value(AltosFlightSeries.gyro_pitch_name, indices); } + double gyro_yaw() { return series.value(AltosFlightSeries.gyro_yaw_name, indices); } + + double mag_along() { return series.value(AltosFlightSeries.mag_along_name, indices); } + double mag_across() { return series.value(AltosFlightSeries.mag_across_name, indices); } + double mag_through() { return series.value(AltosFlightSeries.mag_through_name, indices); } + void write_advanced() { -/* out.printf("%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f", - state.accel_along(), state.accel_across(), state.accel_through(), - state.gyro_roll(), state.gyro_pitch(), state.gyro_yaw(), - state.mag_along(), state.mag_across(), state.mag_through()); -*/ + accel_along(), accel_across(), accel_through(), + gyro_roll(), gyro_pitch(), gyro_yaw(), + mag_along(), mag_across(), mag_through()); } void write_gps_header() { -/* out.printf("connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,pdop,hdop,vdop"); -*/ } void write_gps() { -/* - AltosGPS gps = state.gps; - if (gps == null) - gps = new AltosGPS(); + AltosGPS gps = series.gps_before(series.time(indices)); - AltosGreatCircle from_pad = state.from_pad; - if (from_pad == null) + AltosGreatCircle from_pad; + + if (series.cal_data.gps_pad != null && gps != null) + from_pad = new AltosGreatCircle(series.cal_data.gps_pad, gps); + else from_pad = new AltosGreatCircle(); + if (gps == null) + gps = new AltosGPS(); + out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f,%6.1f,%6.1f", gps.connected?1:0, gps.locked?1:0, @@ -231,13 +242,12 @@ public class AltosCSV implements AltosWriter { gps.minute, gps.second, from_pad.distance, - state.range, + from_pad.range, from_pad.bearing, - state.elevation, + from_pad.elevation, gps.pdop, gps.hdop, gps.vdop); -*/ } void write_gps_sat_header() { @@ -249,8 +259,7 @@ public class AltosCSV implements AltosWriter { } void write_gps_sat() { -/* - AltosGPS gps = state.gps; + AltosGPS gps = series.gps_before(series.time(indices)); for(int i = 1; i <= 32; i++) { int c_n0 = 0; if (gps != null && gps.cc_gps_sat != null) { @@ -264,13 +273,14 @@ public class AltosCSV implements AltosWriter { if (i != 32) out.printf(","); } -*/ } void write_companion_header() { +/* out.printf("companion_id,companion_time,companion_update,companion_channels"); for (int i = 0; i < 12; i++) out.printf(",companion_%02d", i); +*/ } void write_companion() { @@ -401,16 +411,16 @@ public class AltosCSV implements AltosWriter { 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) - has_gps_sat = true; - } - if (state.companion != null) - has_companion = true; - } -*/ + + if (series.gps_series != null) + has_gps = true; + if (series.sats_in_view != null) + has_gps_sat = true; + /* + if (state.companion != null) + has_companion = true; + */ + indices = series.indices(); for (;;) { diff --git a/altoslib/AltosCalData.java b/altoslib/AltosCalData.java index 58d34abe..3da0e400 100644 --- a/altoslib/AltosCalData.java +++ b/altoslib/AltosCalData.java @@ -204,12 +204,11 @@ public class AltosCalData { this.state = state; } - public double gps_ground_altitude = AltosLib.MISSING; + public AltosGPS gps_pad = null; - 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; + public void set_gps(AltosGPS gps) { + if ((state != AltosLib.MISSING && state < AltosLib.ao_flight_boost) || gps_pad == null) + gps_pad = gps; } /* @@ -226,7 +225,7 @@ public class AltosCalData { public void reset_temp_gps() { if (temp_gps != null) { if (temp_gps.locked && temp_gps.nsat >= 4) - set_gps_altitude(temp_gps.alt); + set_gps(temp_gps); } temp_gps = null; } diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index 95c1a99f..5b3ff391 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -191,7 +191,7 @@ public class AltosConvert { } public static double - cc_ignitor_to_voltage(double ignite) + cc_igniter_to_voltage(double ignite) { return ignite / 32767 * 15.0; } @@ -434,6 +434,10 @@ public class AltosConvert { public static AltosStateName state_name = new AltosStateName(); + public static AltosPyroName pyro_name = new AltosPyroName(); + + public static AltosUnits magnetic_field = null; + public static String show_gs(String format, double a) { a = meters_to_g(a); format = format.concat(" g"); diff --git a/altoslib/AltosDataListener.java b/altoslib/AltosDataListener.java index b644e817..4a6fe04d 100644 --- a/altoslib/AltosDataListener.java +++ b/altoslib/AltosDataListener.java @@ -59,7 +59,7 @@ public abstract class AltosDataListener { 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_igniter_voltage(double[] voltage); public abstract void set_pyro_fired(int pyro_mask); public abstract void set_companion(AltosCompanion companion); diff --git a/altoslib/AltosDistance.java b/altoslib/AltosDistance.java index 0239c5ce..5e1b3545 100644 --- a/altoslib/AltosDistance.java +++ b/altoslib/AltosDistance.java @@ -96,7 +96,7 @@ public class AltosDistance extends AltosUnits { } }; - range_imperial[1] = new AltosUnitsRange(AltosConvert.feet_to_meters(1000), + range_imperial[1] = new AltosUnitsRange(AltosConvert.feet_to_meters(5280), "mi", "miles") { double value(double v) { return AltosConvert.meters_to_miles(v); diff --git a/altoslib/AltosEepromDownload.java b/altoslib/AltosEepromDownload.java index 4e641b85..8a2053ec 100644 --- a/altoslib/AltosEepromDownload.java +++ b/altoslib/AltosEepromDownload.java @@ -59,7 +59,7 @@ class AltosEepromNameData extends AltosDataListener { 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_igniter_voltage(double[] voltage) { } public void set_pyro_fired(int pyro_mask) { } public void set_companion(AltosCompanion companion) { } public void set_kalman(double height, double speed, double acceleration) { } diff --git a/altoslib/AltosEepromNew.java b/altoslib/AltosEepromNew.java index 5220f3a0..0da3df71 100644 --- a/altoslib/AltosEepromNew.java +++ b/altoslib/AltosEepromNew.java @@ -165,7 +165,8 @@ public class AltosEepromNew { int start = data.size(); if (config_data().log_format != AltosLib.AO_LOG_FORMAT_TINY) { - data.add((byte) tokens[0].codePointAt(0)); + byte cmd = (byte) tokens[0].codePointAt(0); + data.add(cmd); int time = AltosLib.fromhex(tokens[1]); diff --git a/altoslib/AltosEepromRecord.java b/altoslib/AltosEepromRecord.java index 08f7ebca..7dd37592 100644 --- a/altoslib/AltosEepromRecord.java +++ b/altoslib/AltosEepromRecord.java @@ -92,7 +92,7 @@ public abstract class AltosEepromRecord implements Comparable public int next_start() { int s = start + length; - while (s + length < eeprom.data.size()) { + while (s + length <= eeprom.data.size()) { if (valid(s)) return s; s += length; diff --git a/altoslib/AltosEepromRecordFull.java b/altoslib/AltosEepromRecordFull.java index ea81eb3d..b4968220 100644 --- a/altoslib/AltosEepromRecordFull.java +++ b/altoslib/AltosEepromRecordFull.java @@ -62,8 +62,8 @@ public class AltosEepromRecordFull extends AltosEepromRecord { listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(data16(2))); break; case AltosLib.AO_LOG_DEPLOY: - listener.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(data16(0))); - listener.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(data16(2))); + listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(data16(0))); + listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(data16(2))); break; case AltosLib.AO_LOG_STATE: listener.set_state(data16(0)); diff --git a/altoslib/AltosEepromRecordMega.java b/altoslib/AltosEepromRecordMega.java index 371810ab..d4a5a0b2 100644 --- a/altoslib/AltosEepromRecordMega.java +++ b/altoslib/AltosEepromRecordMega.java @@ -143,6 +143,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord { ground_yaw() / 512.0); break; case AltosLib.AO_LOG_STATE: + System.out.printf("log state %s\n", AltosLib.state_name(state())); listener.set_state(state()); break; case AltosLib.AO_LOG_SENSOR: @@ -198,7 +199,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord { for (int i = 0; i < nsense-2; i++) voltages[i] = AltosConvert.mega_pyro_voltage(sense(i)); - listener.set_ignitor_voltage(voltages); + listener.set_igniter_voltage(voltages); listener.set_pyro_fired(pyro()); break; case AltosLib.AO_LOG_GPS_TIME: diff --git a/altoslib/AltosFlightListener.java b/altoslib/AltosFlightListener.java index 5b478ed0..395d8f3f 100644 --- a/altoslib/AltosFlightListener.java +++ b/altoslib/AltosFlightListener.java @@ -130,7 +130,7 @@ public abstract class AltosFlightListener { public abstract void set_imu(AltosIMU imu); public abstract void set_mag(AltosMag mag); public abstract void set_pyro_voltage(double volts); - public abstract void set_ignitor_voltage(double[] voltage); + public abstract void set_igniter_voltage(double[] voltage); public abstract void set_pyro_fired(int pyro_mask); public void copy(AltosFlightListener old) { diff --git a/altoslib/AltosFlightSeries.java b/altoslib/AltosFlightSeries.java index b7434a5c..0eea34b7 100644 --- a/altoslib/AltosFlightSeries.java +++ b/altoslib/AltosFlightSeries.java @@ -23,12 +23,17 @@ public class AltosFlightSeries extends AltosDataListener { public int[] indices() { int[] indices = new int[series.size()]; for (int i = 0; i < indices.length; i++) - indices[i] = 0; + indices[i] = -1; + step_indices(indices); return indices; } private double time(int id, int index) { AltosTimeSeries s = series.get(id); + + if (index < 0) + return Double.NEGATIVE_INFINITY; + if (index < s.values.size()) return s.values.get(index).time; return Double.POSITIVE_INFINITY; @@ -69,8 +74,30 @@ public class AltosFlightSeries extends AltosDataListener { public double value(String name, int[] indices) { for (int i = 0; i < indices.length; i++) { AltosTimeSeries s = series.get(i); + if (s.label.equals(name)) { + int index = indices[i]; + if (index < 0) + index = 0; + if (index >= s.values.size()) + index = s.values.size() - 1; + return s.values.get(index).value; + } + } + return AltosLib.MISSING; + } + + public double value_before(String name, double time) { + for (AltosTimeSeries s : series) { if (s.label.equals(name)) - return s.values.get(indices[i]).value; + return s.value_before(time); + } + return AltosLib.MISSING; + } + + public double value_after(String name, double time) { + for (AltosTimeSeries s : series) { + if (s.label.equals(name)) + return s.value_after(time); } return AltosLib.MISSING; } @@ -105,11 +132,12 @@ public class AltosFlightSeries extends AltosDataListener { 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, AltosConvert.state_name); - else if ((int) state_series.get(state_series.size()-1).value == state) + else if (this.state == state) return; + System.out.printf("state %s\n", AltosLib.state_name(state)); + this.state = state; state_series.add(time(), state); } @@ -146,14 +174,14 @@ public class AltosFlightSeries extends AltosDataListener { AltosTimeSeries status_series; - public static final String status_name = "Status"; + public static final String status_name = "Radio Status"; public void set_rssi(int rssi, int status) { - if (rssi_series == null) + 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); + } + rssi_series.add(time(), rssi); status_series.add(time(), status); } @@ -329,6 +357,18 @@ public class AltosFlightSeries extends AltosDataListener { main_voltage_series.add(time(), volts); } + public ArrayList gps_series; + + public AltosGPS gps_before(double time) { + AltosGPS gps = null; + for (AltosGPSTimeValue gtv : gps_series) + if (gtv.time <= time) + gps = gtv.gps; + else + break; + return gps; + } + AltosTimeSeries sats_in_view; AltosTimeSeries sats_in_soln; AltosTimeSeries gps_altitude; @@ -337,8 +377,7 @@ public class AltosFlightSeries extends AltosDataListener { AltosTimeSeries gps_ascent_rate; AltosTimeSeries gps_course; AltosTimeSeries gps_speed; - - public ArrayList gps_series; + AltosTimeSeries gps_pdop, gps_vdop, gps_hdop; public static final String sats_in_view_name = "Satellites in view"; public static final String sats_in_soln_name = "Satellites in solution"; @@ -348,30 +387,42 @@ public class AltosFlightSeries extends AltosDataListener { public static final String gps_ascent_rate_name = "GPS Ascent Rate"; public static final String gps_course_name = "GPS Course"; public static final String gps_speed_name = "GPS Speed"; + public static final String gps_pdop_name = "GPS Dilution of Precision"; + public static final String gps_vdop_name = "GPS Vertical Dilution of Precision"; + public static final String gps_hdop_name = "GPS Horizontal Dilution of Precision"; public void set_gps(AltosGPS gps) { if (gps_series == null) gps_series = new ArrayList(); gps_series.add(new AltosGPSTimeValue(time(), gps)); - if (sats_in_view == null) { - sats_in_view = add_series(sats_in_view_name, null); + if (sats_in_soln == 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 (gps.cc_gps_sat != null) - sats_in_view.add(time(), gps.cc_gps_sat.length); + sats_in_soln.add(time(), gps.nsat); + if (gps.pdop != AltosLib.MISSING) { + if (gps_pdop == null) { + gps_pdop = add_series(gps_pdop_name, null); + gps_hdop = add_series(gps_hdop_name, null); + gps_vdop = add_series(gps_vdop_name, null); + } + gps_pdop.add(time(), gps.pdop); + gps_hdop.add(time(), gps.hdop); + gps_vdop.add(time(), gps.vdop); + } if (gps.locked) { - sats_in_soln.add(time(), gps.nsat); + if (gps_altitude == 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 (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 (cal_data.gps_pad != null) + gps_height.add(time(), gps.alt - cal_data.gps_pad.alt); } if (gps.ground_speed != AltosLib.MISSING) gps_ground_speed.add(time(), gps.ground_speed); @@ -383,33 +434,141 @@ public class AltosFlightSeries extends AltosDataListener { gps_speed.add(time(), Math.sqrt(gps.ground_speed * gps.ground_speed + gps.climb_rate * gps.climb_rate)); } + if (gps.cc_gps_sat != null) { + if (sats_in_view == null) + sats_in_view = add_series(sats_in_view_name, null); + sats_in_view.add(time(), gps.cc_gps_sat.length); + } } - public static final String accel_across_name = "Accel Across"; public static final String accel_along_name = "Accel Along"; + public static final String accel_across_name = "Accel Across"; public static final String accel_through_name = "Accel Through"; + AltosTimeSeries accel_along, accel_across, accel_through; + + public static final String gyro_roll_name = "Roll Rate"; + public static final String gyro_pitch_name = "Pitch Rate"; + public static final String gyro_yaw_name = "Yaw Rate"; + + AltosTimeSeries gyro_roll, gyro_pitch, gyro_yaw; + + public static final String mag_along_name = "Magnetic Field Along"; + public static final String mag_across_name = "Magnetic Field Across"; + public static final String mag_through_name = "Magnetic Field Through"; + + AltosTimeSeries mag_along, mag_across, mag_through; + public void set_accel(double along, double across, double through) { + if (accel_along == null) { + accel_along = add_series(accel_along_name, AltosConvert.accel); + accel_across = add_series(accel_across_name, AltosConvert.accel); + accel_through = add_series(accel_through_name, AltosConvert.accel); + } + accel_along.add(time(), along); + accel_across.add(time(), across); + accel_through.add(time(), through); } public void set_accel_ground(double along, double across, double through) { } public void set_gyro(double roll, double pitch, double yaw) { + if (gyro_roll == null) { + gyro_roll = add_series(gyro_roll_name, AltosConvert.rotation_rate); + gyro_pitch = add_series(gyro_pitch_name, AltosConvert.rotation_rate); + gyro_yaw = add_series(gyro_yaw_name, AltosConvert.rotation_rate); + } + gyro_roll.add(time(), roll); + gyro_pitch.add(time(), pitch); + gyro_yaw.add(time(), yaw); } public void set_mag(double along, double across, double through) { + if (mag_along == null) { + mag_along = add_series(mag_along_name, AltosConvert.magnetic_field); + mag_across = add_series(mag_across_name, AltosConvert.magnetic_field); + mag_through = add_series(mag_through_name, AltosConvert.magnetic_field); + } + mag_along.add(time(), along); + mag_across.add(time(), across); + mag_through.add(time(), through); } - public void set_orient(double new_orient) { } + public static final String orient_name = "Tilt Angle"; + + AltosTimeSeries orient_series; + + public void set_orient(double orient) { + if (orient_series == null) + orient_series = add_series(orient_name, AltosConvert.orient); + orient_series.add(time(), orient); + } + + public static final String pyro_voltage_name = "Pyro Voltage"; + + AltosTimeSeries pyro_voltage; public void set_pyro_voltage(double volts) { + if (pyro_voltage == null) + pyro_voltage = add_series(pyro_voltage_name, AltosConvert.voltage); + pyro_voltage.add(time(), volts); } - public void set_ignitor_voltage(double[] voltage) { + private static String[] igniter_voltage_names; + + public String igniter_voltage_name(int channel) { + if (igniter_voltage_names == null || igniter_voltage_names.length <= channel) { + String[] new_igniter_voltage_names = new String[channel + 1]; + int i = 0; + + if (igniter_voltage_names != null) { + for (; i < igniter_voltage_names.length; i++) + new_igniter_voltage_names[i] = igniter_voltage_names[i]; + } + for (; i < channel+1; i++) + new_igniter_voltage_names[i] = AltosLib.igniter_name(i); + igniter_voltage_names = new_igniter_voltage_names; + } + return igniter_voltage_names[channel]; + } + + AltosTimeSeries[] igniter_voltage; + + public void set_igniter_voltage(double[] voltage) { + int channels = voltage.length; + if (igniter_voltage == null || igniter_voltage.length <= channels) { + AltosTimeSeries[] new_igniter_voltage = new AltosTimeSeries[channels + 1]; + int i = 0; + + if (igniter_voltage != null) { + for (; i < igniter_voltage.length; i++) + new_igniter_voltage[i] = igniter_voltage[i]; + } + for (; i < channels; i++) + new_igniter_voltage[i] = add_series(igniter_voltage_name(i), AltosConvert.voltage); + igniter_voltage = new_igniter_voltage; + } + for (int channel = 0; channel < voltage.length; channel++) + igniter_voltage[channel].add(time(), voltage[channel]); } + public static final String pyro_fired_name = "Pyro Channel State"; + + AltosTimeSeries pyro_fired_series; + + int last_pyro_mask; + public void set_pyro_fired(int pyro_mask) { + if (pyro_fired_series == null) + pyro_fired_series = add_series(pyro_fired_name, AltosConvert.pyro_name); + for (int channel = 0; channel < 32; channel++) { + if ((last_pyro_mask & (1 << channel)) == 0 && + (pyro_mask & (1 << channel)) != 0) { + pyro_fired_series.add(time(), channel); + } + } + last_pyro_mask = pyro_mask; } public void set_companion(AltosCompanion companion) { diff --git a/altoslib/AltosFlightStats.java b/altoslib/AltosFlightStats.java index 7179351e..54d0dd63 100644 --- a/altoslib/AltosFlightStats.java +++ b/altoslib/AltosFlightStats.java @@ -46,7 +46,7 @@ public class AltosFlightStats { public boolean has_imu; public boolean has_mag; public boolean has_orient; - public int num_ignitor; + public int num_igniter; double landed_time(AltosFlightSeries series) { double landed_state_time = AltosLib.MISSING; @@ -215,8 +215,8 @@ public class AltosFlightStats { has_mag = true; if (state.orient() != AltosLib.MISSING) has_orient = true; - if (state.ignitor_voltage != null && state.ignitor_voltage.length > num_ignitor) - num_ignitor = state.ignitor_voltage.length; + if (state.igniter_voltage != null && state.igniter_voltage.length > num_igniter) + num_igniter = state.igniter_voltage.length; } */ for (int s = AltosLib.ao_flight_startup; s <= AltosLib.ao_flight_landed; s++) { diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 2137d1d7..fb43ea20 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -571,7 +571,7 @@ public class AltosLib { } } - public static String ignitor_name(int i) { + public static String igniter_name(int i) { return String.format("Ignitor %c", 'A' + i); } } diff --git a/altoslib/AltosMapLine.java b/altoslib/AltosMapLine.java index c475f52d..cf09307e 100644 --- a/altoslib/AltosMapLine.java +++ b/altoslib/AltosMapLine.java @@ -44,39 +44,9 @@ public abstract class AltosMapLine { } public String line_dist() { - String format; AltosGreatCircle g = new AltosGreatCircle(start.lat, start.lon, end.lat, end.lon); - double distance = g.distance; - if (AltosConvert.imperial_units) { - distance = AltosConvert.meters_to_feet(distance); - if (distance < 1000) { - format = "%4.0fft"; - } else { - distance /= 5280; - if (distance < 10) - format = "%5.3fmi"; - else if (distance < 100) - format = "%5.2fmi"; - else if (distance < 1000) - format = "%5.1fmi"; - else - format = "%5.0fmi"; - } - } else { - if (distance < 1000) { - format = "%4.0fm"; - } else { - distance /= 1000; - if (distance < 100) - format = "%5.2fkm"; - else if (distance < 1000) - format = "%5.1fkm"; - else - format = "%5.0fkm"; - } - } - return String.format(format, distance); + return AltosConvert.distance.show(7, g.distance); } } diff --git a/altoslib/AltosPyroName.java b/altoslib/AltosPyroName.java new file mode 100644 index 00000000..18a31dd2 --- /dev/null +++ b/altoslib/AltosPyroName.java @@ -0,0 +1,32 @@ +/* + * Copyright © 2017 Keith Packard + * + * 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 AltosPyroName extends AltosUnits { + + public double value(double v, boolean imperial_units) { return v; } + + public double inverse(double v, boolean imperial_units) { return v; } + + public String string_value(double v, boolean imperial_units) { + return AltosLib.igniter_name((int) v); + } + + public String show_units(boolean imperial_units) { return "state"; } + + public String say_units(boolean imperial_units) { return "state"; } + + public int show_fraction(int width, boolean imperial_units) { return 0; } +} diff --git a/altoslib/AltosSensorMega.java b/altoslib/AltosSensorMega.java index 63c7a0ce..82696038 100644 --- a/altoslib/AltosSensorMega.java +++ b/altoslib/AltosSensorMega.java @@ -97,10 +97,10 @@ class AltosSensorMega { state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[4])); state.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[5])); - double[] ignitor_voltage = new double[4]; + double[] igniter_voltage = new double[4]; for (int i = 0; i < 4; i++) - ignitor_voltage[i] = AltosConvert.mega_pyro_voltage(sensor_mega.sense[i]); - state.set_ignitor_voltage(ignitor_voltage); + igniter_voltage[i] = AltosConvert.mega_pyro_voltage(sensor_mega.sense[i]); + state.set_igniter_voltage(igniter_voltage); } catch (TimeoutException te) { } diff --git a/altoslib/AltosSensorTM.java b/altoslib/AltosSensorTM.java index 7d7becfb..49f3986b 100644 --- a/altoslib/AltosSensorTM.java +++ b/altoslib/AltosSensorTM.java @@ -39,8 +39,8 @@ public class AltosSensorTM { 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)); + listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(sensor_tm.drogue)); + listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(sensor_tm.main)); } catch (TimeoutException te) { } diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index f46b12ea..889aa9a3 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -702,7 +702,7 @@ public class AltosState extends AltosDataListener { public double apogee_voltage; public double main_voltage; - public double ignitor_voltage[]; + public double igniter_voltage[]; public AltosGPS gps; public AltosGPS temp_gps; @@ -786,7 +786,7 @@ public class AltosState extends AltosDataListener { pyro_voltage = AltosLib.MISSING; apogee_voltage = AltosLib.MISSING; main_voltage = AltosLib.MISSING; - ignitor_voltage = null; + igniter_voltage = null; kalman_height = new AltosValue(); kalman_speed = new AltosValue(); @@ -1221,8 +1221,8 @@ public class AltosState extends AltosDataListener { } } - public void set_ignitor_voltage(double[] voltage) { - this.ignitor_voltage = voltage; + public void set_igniter_voltage(double[] voltage) { + this.igniter_voltage = voltage; } public void set_pyro_fired(int fired) { diff --git a/altoslib/AltosTelemetryFile.java b/altoslib/AltosTelemetryFile.java index 0b0e6a48..c6462872 100644 --- a/altoslib/AltosTelemetryFile.java +++ b/altoslib/AltosTelemetryFile.java @@ -46,7 +46,7 @@ class AltosTelemetryNullListener extends AltosDataListener { 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_igniter_voltage(double[] voltage) { } public void set_pyro_fired(int pyro_mask) { } public void set_companion(AltosCompanion companion) { } @@ -78,7 +78,7 @@ class AltosTelemetryNullListener extends AltosDataListener { /* * TelemetryLocation */ - if (AltosLib.has_gps(cal_data.device_type) && cal_data.gps_ground_altitude == AltosLib.MISSING) + if (AltosLib.has_gps(cal_data.device_type) && cal_data.gps_pad == null) return false; return true; diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java index 394d023c..8a86417c 100644 --- a/altoslib/AltosTelemetryLegacy.java +++ b/altoslib/AltosTelemetryLegacy.java @@ -564,8 +564,8 @@ public class AltosTelemetryLegacy extends AltosTelemetry { 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)); + listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(apogee)); + listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(main)); if (gps != null) listener.set_gps(gps); } diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java index 5eb727d6..c7b7fa22 100644 --- a/altoslib/AltosTelemetryLocation.java +++ b/altoslib/AltosTelemetryLocation.java @@ -58,6 +58,9 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard { gps.nsat = flags & 0xf; gps.locked = (flags & (1 << 4)) != 0; gps.connected = (flags & (1 << 5)) != 0; + gps.pdop = pdop() / 10.0; + gps.hdop = hdop() / 10.0; + gps.vdop = vdop() / 10.0; if (gps.locked) { gps.lat = latitude() * 1.0e-7; @@ -72,12 +75,9 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard { gps.ground_speed = ground_speed() * 1.0e-2; gps.course = course() * 2; gps.climb_rate = climb_rate() * 1.0e-2; - gps.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); + cal_data.set_gps(gps); } listener.set_gps(gps); } diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java index c0749e87..b648f300 100644 --- a/altoslib/AltosTelemetryMegaData.java +++ b/altoslib/AltosTelemetryMegaData.java @@ -55,7 +55,7 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard { for (int i = 0; i < 4; i++) voltages[i] = AltosConvert.mega_pyro_voltage(sense(i)); - listener.set_ignitor_voltage(voltages); + listener.set_igniter_voltage(voltages); cal_data.set_ground_accel(ground_accel()); cal_data.set_ground_pressure(ground_pres()); diff --git a/altoslib/AltosTelemetrySensor.java b/altoslib/AltosTelemetrySensor.java index 37589397..da253eea 100644 --- a/altoslib/AltosTelemetrySensor.java +++ b/altoslib/AltosTelemetrySensor.java @@ -57,8 +57,8 @@ public class AltosTelemetrySensor extends AltosTelemetryStandard { listener.set_temperature(AltosConvert.thermometer_to_temperature(temp())); listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(v_batt())); if (type() == packet_type_TM_sensor || type() == packet_type_Tm_sensor) { - listener.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sense_d())); - listener.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sense_m())); + listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(sense_d())); + listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(sense_m())); } listener.set_kalman(height_16(), speed()/16.0, acceleration()/16.0); diff --git a/altoslib/AltosTimeSeries.java b/altoslib/AltosTimeSeries.java index 1d3d9a6c..30b24d82 100644 --- a/altoslib/AltosTimeSeries.java +++ b/altoslib/AltosTimeSeries.java @@ -17,9 +17,9 @@ package org.altusmetrum.altoslib_11; import java.util.*; public class AltosTimeSeries implements Iterable { - public String label; - public AltosUnits units; - List values; + public String label; + public AltosUnits units; + ArrayList values; public void add(AltosTimeValue tv) { values.add(tv); @@ -33,6 +33,58 @@ public class AltosTimeSeries implements Iterable { return values.get(i); } + private double lerp(AltosTimeValue v0, AltosTimeValue v1, double t) { + /* degenerate case */ + if (v0.time == v1.time) + return (v0.value + v1.value) / 2; + + return (v0.value * (v1.time - t) + v1.value * (t - v0.time)) / v1.time - v0.time; + } + + private int after_index(double time) { + int lo = 0; + int hi = values.size() - 1; + + while (lo <= hi) { + int mid = (lo + hi) / 2; + + if (values.get(mid).time < time) + lo = mid + 1; + else + hi = mid - 1; + } + return lo; + } + + /* Compute a value for an arbitrary time */ + public double value(double time) { + int after = after_index(time); + if (after == 0) + return values.get(0).value; + if (after == values.size()) + return values.get(after - 1).value; + + return lerp(values.get(after-1), values.get(after), time); + } + + /* Find the value just before an arbitrary time */ + public double value_before(double time) { + int after = after_index(time); + + if (after == 0) + return values.get(0).value; + return values.get(after-1).value; + } + + /* Find the value just after an arbitrary time */ + public double value_after(double time) { + int after = after_index(time); + + if (after == values.size()) + return values.get(after-1).value; + return values.get(after).value; + } + public int size() { return values.size(); } @@ -144,11 +196,16 @@ public class AltosTimeSeries implements Iterable { 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); + double j_left = j == left ? left_time : values.get(j-1).time; + double j_right = j == right ? right_time : values.get(j+1).time; + double interval = (j_right - j_left) / 2.0; + double coeff = filter_coeff(j_time - center_time, width) * interval; + total_coeff += coeff; total_value += coeff * values.get(j).value; } diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index fa0e8c1b..ffa92783 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -92,6 +92,7 @@ altoslib_JAVA = \ AltosPreferences.java \ AltosPreferencesBackend.java \ AltosProgrammer.java \ + AltosPyroName.java \ AltosReplayReader.java \ AltosRomconfig.java \ AltosSavedState.java \ diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index 3d33b6e5..eaf19256 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -36,7 +36,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay { JTabbedPane pane; AltosPad pad; - AltosIgnitor ignitor; + AltosIgnitor igniter; AltosAscent ascent; AltosDescent descent; AltosLanded landed; @@ -45,7 +45,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay { boolean has_map; boolean has_companion; boolean has_state; - boolean has_ignitor; + boolean has_igniter; private AltosFlightStatus flightStatus; private AltosInfoTable flightInfo; @@ -121,15 +121,15 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay { cur_tab = tab; } - if (ignitor.should_show(state)) { - if (!has_ignitor) { - pane.add("Ignitor", ignitor); - has_ignitor = true; + if (igniter.should_show(state)) { + if (!has_igniter) { + pane.add("Ignitor", igniter); + has_igniter = true; } } else { - if (has_ignitor) { - pane.remove(ignitor); - has_ignitor = false; + if (has_igniter) { + pane.remove(igniter); + has_igniter = false; } } @@ -272,8 +272,8 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay { displays.add(pad); pane.add("Status", pad); - ignitor = new AltosIgnitor(); - displays.add(ignitor); + igniter = new AltosIgnitor(); + displays.add(igniter); ascent = new AltosAscent(); displays.add(ascent); descent = new AltosDescent(); diff --git a/altosui/AltosGraphUI.java b/altosui/AltosGraphUI.java index 5314a3b6..a3107f2b 100644 --- a/altosui/AltosGraphUI.java +++ b/altosui/AltosGraphUI.java @@ -44,19 +44,26 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt void fill_map(AltosFlightSeries flight_series) { boolean any_gps = false; + AltosGPSTimeValue gtv_last = null; for (AltosGPSTimeValue gtv : flight_series.gps_series) { + gtv_last = gtv; AltosGPS gps = gtv.gps; if (gps != null && gps.locked && gps.nsat >= 4) { if (map == null) map = new AltosUIMap(); - map.show(gps, AltosLib.ao_flight_pad); + map.show(gps, (int) flight_series.value_before(AltosFlightSeries.state_name, gtv.time)); this.gps = gps; has_gps = true; } } + if (gtv_last != null) { + int state = (int) flight_series.value_after(AltosFlightSeries.state_name, gtv_last.time); + if (state == AltosLib.ao_flight_landed) + map.show(gtv_last.gps, state); + } } public void font_size_changed(int font_size) { diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index 4d5c3b2d..afa9b944 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -34,12 +34,12 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl AltosPad pad; AltosInfoTable flightInfo; AltosFlightStatus flightStatus; - AltosIgnitor ignitor; + AltosIgnitor igniter; AltosIdleMonitor thread; AltosUIMap sitemap; int serial; boolean remote; - boolean has_ignitor; + boolean has_igniter; boolean has_map; void stop_display() { @@ -75,15 +75,15 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl public void show(AltosState state, AltosListenerState listener_state) { status_update.saved_state = state; - if (ignitor.should_show(state)) { - if (!has_ignitor) { - pane.add("Ignitor", ignitor); - has_ignitor = true; + if (igniter.should_show(state)) { + if (!has_igniter) { + pane.add("Ignitor", igniter); + has_igniter = true; } } else { - if (has_ignitor) { - pane.remove(ignitor); - has_ignitor = false; + if (has_igniter) { + pane.remove(igniter); + has_igniter = false; } } if (state.gps != null && state.gps.connected) { @@ -102,8 +102,8 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl pad.show(state, listener_state); flightStatus.show(state, listener_state); flightInfo.show(state, listener_state); - if (has_ignitor) - ignitor.show(state, listener_state); + if (has_igniter) + igniter.show(state, listener_state); if (has_map) sitemap.show(state, listener_state); // } catch (Exception e) { @@ -274,7 +274,7 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl flightInfo = new AltosInfoTable(); pane.add("Table", new JScrollPane(flightInfo)); - ignitor = new AltosIgnitor(); + igniter = new AltosIgnitor(); sitemap = new AltosUIMap(); diff --git a/altosui/AltosIgnitor.java b/altosui/AltosIgnitor.java index fabf4320..09dcdf93 100644 --- a/altosui/AltosIgnitor.java +++ b/altosui/AltosIgnitor.java @@ -27,59 +27,59 @@ import org.altusmetrum.altosuilib_11.*; public class AltosIgnitor extends AltosUIFlightTab { public class Ignitor extends AltosUIUnitsIndicator { - int ignitor; + int igniter; public double value(AltosState state, int i) { - if (state.ignitor_voltage == null || - state.ignitor_voltage.length < ignitor) + if (state.igniter_voltage == null || + state.igniter_voltage.length < igniter) return AltosLib.MISSING; - return state.ignitor_voltage[ignitor]; + return state.igniter_voltage[igniter]; } public double good() { return AltosLib.ao_igniter_good; } public Ignitor (AltosUIFlightTab container, int y) { - super(container, y, AltosConvert.voltage, String.format ("%s Voltage", AltosLib.ignitor_name(y)), 1, true, 1); - ignitor = y; + super(container, y, AltosConvert.voltage, String.format ("%s Voltage", AltosLib.igniter_name(y)), 1, true, 1); + igniter = y; } } - Ignitor[] ignitors; + Ignitor[] igniters; public void show(AltosState state, AltosListenerState listener_state) { if (isShowing()) - make_ignitors(state); + make_igniters(state); super.show(state, listener_state); } public boolean should_show(AltosState state) { if (state == null) return false; - if (state.ignitor_voltage == null) + if (state.igniter_voltage == null) return false; - return state.ignitor_voltage.length > 0; + return state.igniter_voltage.length > 0; } - void make_ignitors(AltosState state) { - int n = (state == null || state.ignitor_voltage == null) ? 0 : state.ignitor_voltage.length; - int old_n = ignitors == null ? 0 : ignitors.length; + void make_igniters(AltosState state) { + int n = (state == null || state.igniter_voltage == null) ? 0 : state.igniter_voltage.length; + int old_n = igniters == null ? 0 : igniters.length; if (n != old_n) { - if (ignitors != null) { - for (int i = 0; i < ignitors.length; i++) { - remove(ignitors[i]); - ignitors[i].remove(this); - ignitors = null; + if (igniters != null) { + for (int i = 0; i < igniters.length; i++) { + remove(igniters[i]); + igniters[i].remove(this); + igniters = null; } } if (n > 0) { setVisible(true); - ignitors = new Ignitor[n]; + igniters = new Ignitor[n]; for (int i = 0; i < n; i++) { - ignitors[i] = new Ignitor(this, i); - add(ignitors[i]); + igniters[i] = new Ignitor(this, i); + add(igniters[i]); } } else setVisible(false); diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index a6e422e6..b0cff381 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -327,7 +327,7 @@ public class AltosUI extends AltosUIFrame { } private static AltosFlightSeries make_series(AltosRecordSet set) { - AltosFlightSeries series = new AltosFlightSeries(new AltosCalData()); + AltosFlightSeries series = new AltosFlightSeries(set.cal_data()); set.capture_series(series); return series; } diff --git a/altosuilib/AltosGraphNew.java b/altosuilib/AltosGraphNew.java index dc5b7e47..a9393f94 100644 --- a/altosuilib/AltosGraphNew.java +++ b/altosuilib/AltosGraphNew.java @@ -52,6 +52,8 @@ public class AltosGraphNew extends AltosUIGraphNew { static final private Color battery_voltage_color = new Color(194, 194, 31); static final private Color drogue_voltage_color = new Color(150, 150, 31); static final private Color main_voltage_color = new Color(100, 100, 31); + static final private Color igniter_voltage_color = new Color(80, 80, 31); + static final private Color igniter_marker_color = new Color(255, 0, 0); static final private Color gps_nsat_color = new Color (194, 31, 194); static final private Color gps_nsat_solution_color = new Color (194, 31, 194); static final private Color gps_nsat_view_color = new Color (150, 31, 150); @@ -65,25 +67,17 @@ public class AltosGraphNew extends AltosUIGraphNew { static final private Color temperature_color = new Color (31, 194, 194); static final private Color dbm_color = new Color(31, 100, 100); static final private Color state_color = new Color(0,0,0); - static final private Color accel_x_color = new Color(255, 0, 0); - static final private Color accel_y_color = new Color(0, 255, 0); - static final private Color accel_z_color = new Color(0, 0, 255); - static final private Color gyro_x_color = new Color(192, 0, 0); - static final private Color gyro_y_color = new Color(0, 192, 0); - static final private Color gyro_z_color = new Color(0, 0, 192); - static final private Color mag_x_color = new Color(128, 0, 0); - static final private Color mag_y_color = new Color(0, 128, 0); - static final private Color mag_z_color = new Color(0, 0, 128); + static final private Color accel_along_color = new Color(255, 0, 0); + static final private Color accel_across_color = new Color(0, 255, 0); + static final private Color accel_through_color = new Color(0, 0, 255); + static final private Color gyro_roll_color = new Color(192, 0, 0); + static final private Color gyro_pitch_color = new Color(0, 192, 0); + static final private Color gyro_yaw_color = new Color(0, 0, 192); + static final private Color mag_along_color = new Color(128, 0, 0); + static final private Color mag_across_color = new Color(0, 128, 0); + static final private Color mag_through_color = new Color(0, 0, 128); static final private Color orient_color = new Color(31, 31, 31); -// static AltosNsat nsat_units = new AltosNsat(); - static AltosUnits nsat_units = null; -// static AltosDbm dbm_units = new AltosDbm(); - static AltosUnits dbm_units = null; - static AltosOrient orient_units = new AltosOrient(); -// static AltosMagUnits mag_units = new AltosMagUnits(); - static AltosUnits mag_units = null; -// static AltosDopUnits dop_units = new AltosDopUnits(); static AltosUnits dop_units = null; AltosUIFlightSeries flight_series; @@ -102,15 +96,15 @@ public class AltosGraphNew extends AltosUIGraphNew { accel_axis = newAxis("Acceleration", AltosConvert.accel, accel_color); voltage_axis = newAxis("Voltage", AltosConvert.voltage, voltage_color); temperature_axis = newAxis("Temperature", AltosConvert.temperature, temperature_color, 0); - nsat_axis = newAxis("Satellites", nsat_units, gps_nsat_color, + nsat_axis = newAxis("Satellites", null, gps_nsat_color, AltosUIAxis.axis_include_zero | AltosUIAxis.axis_integer); - dbm_axis = newAxis("Signal Strength", dbm_units, dbm_color, 0); + dbm_axis = newAxis("Signal Strength", null, dbm_color, 0); distance_axis = newAxis("Distance", AltosConvert.distance, range_color); - gyro_axis = newAxis("Rotation Rate", AltosConvert.rotation_rate, gyro_z_color, 0); - orient_axis = newAxis("Tilt Angle", orient_units, orient_color, 0); - mag_axis = newAxis("Magnetic Field", mag_units, mag_x_color, 0); - course_axis = newAxis("Course", orient_units, gps_course_color, 0); + gyro_axis = newAxis("Rotation Rate", AltosConvert.rotation_rate, gyro_roll_color, 0); + orient_axis = newAxis("Tilt Angle", AltosConvert.orient, orient_color, 0); + mag_axis = newAxis("Magnetic Field", AltosConvert.magnetic_field, mag_along_color, 0); + course_axis = newAxis("Course", AltosConvert.orient, gps_course_color, 0); dop_axis = newAxis("Dilution of Precision", dop_units, gps_pdop_color, 0); flight_series.register_axis("default", @@ -121,7 +115,14 @@ public class AltosGraphNew extends AltosUIGraphNew { flight_series.register_marker(AltosUIFlightSeries.state_name, state_color, true, - plot); + plot, + true); + + flight_series.register_marker(AltosUIFlightSeries.pyro_fired_name, + igniter_marker_color, + true, + plot, + false); flight_series.register_axis(AltosUIFlightSeries.accel_name, accel_color, @@ -164,17 +165,50 @@ public class AltosGraphNew extends AltosUIGraphNew { height_axis); + flight_series.register_axis(AltosUIFlightSeries.temperature_name, + temperature_color, + false, + temperature_axis); + + flight_series.register_axis(AltosUIFlightSeries.battery_voltage_name, + battery_voltage_color, + false, + voltage_axis); + + flight_series.register_axis(AltosUIFlightSeries.apogee_voltage_name, + drogue_voltage_color, + false, + voltage_axis); + + flight_series.register_axis(AltosUIFlightSeries.main_voltage_name, + main_voltage_color, + false, + voltage_axis); + flight_series.register_axis(AltosUIFlightSeries.sats_in_view_name, gps_nsat_view_color, false, nsat_axis); - flight_series.register_axis(AltosUIFlightSeries.sats_in_soln_name, gps_nsat_solution_color, false, nsat_axis); + flight_series.register_axis(AltosUIFlightSeries.gps_pdop_name, + gps_pdop_color, + false, + dop_axis); + + flight_series.register_axis(AltosUIFlightSeries.gps_hdop_name, + gps_hdop_color, + false, + dop_axis); + + flight_series.register_axis(AltosUIFlightSeries.gps_vdop_name, + gps_vdop_color, + false, + dop_axis); flight_series.register_axis(AltosUIFlightSeries.gps_altitude_name, gps_height_color, @@ -191,13 +225,11 @@ public class AltosGraphNew extends AltosUIGraphNew { false, speed_axis); - flight_series.register_axis(AltosUIFlightSeries.gps_ascent_rate_name, gps_climb_rate_color, false, speed_axis); - flight_series.register_axis(AltosUIFlightSeries.gps_course_name, gps_course_color, false, @@ -208,246 +240,69 @@ public class AltosGraphNew extends AltosUIGraphNew { false, speed_axis); + flight_series.register_axis(AltosUIFlightSeries.accel_along_name, + accel_along_color, + false, + accel_axis); + + flight_series.register_axis(AltosUIFlightSeries.accel_across_name, + accel_across_color, + false, + accel_axis); + + flight_series.register_axis(AltosUIFlightSeries.accel_through_name, + accel_through_color, + false, + accel_axis); + + flight_series.register_axis(AltosUIFlightSeries.gyro_roll_name, + gyro_roll_color, + false, + gyro_axis); + + flight_series.register_axis(AltosUIFlightSeries.gyro_pitch_name, + gyro_pitch_color, + false, + gyro_axis); + + flight_series.register_axis(AltosUIFlightSeries.gyro_yaw_name, + gyro_yaw_color, + false, + gyro_axis); + + flight_series.register_axis(AltosUIFlightSeries.mag_along_name, + mag_along_color, + false, + mag_axis); + + flight_series.register_axis(AltosUIFlightSeries.mag_across_name, + mag_across_color, + false, + mag_axis); + + flight_series.register_axis(AltosUIFlightSeries.mag_through_name, + mag_through_color, + false, + mag_axis); + + flight_series.register_axis(AltosUIFlightSeries.orient_name, + orient_color, + false, + orient_axis); + + for (int channel = 0; channel < 26; channel++) { + flight_series.register_axis(flight_series.igniter_voltage_name(channel), + igniter_voltage_color, + false, + voltage_axis); + } + flight_series.register_axis(AltosUIFlightSeries.thrust_name, thrust_color, true, thrust_axis); -// addMarker("State", AltosGraphDataPoint.data_state, state_color); - return flight_series.series(cal_data); -/* - if (stats.has_flight_data) { - addSeries("Height", - AltosGraphDataPoint.data_height, - AltosConvert.height, - height_color, - true, - height_axis); - addSeries("Pressure", - AltosGraphDataPoint.data_pressure, - pressure_units, - pressure_color, - false, - pressure_axis); - addSeries("Thrust", - AltosGraphDataPoint.data_thrust, - thrust_units, - thrust_color, - false, - thrust_axis); - addSeries("Speed", - AltosGraphDataPoint.data_speed, - AltosConvert.speed, - speed_color, - true, - speed_axis); - addSeries("Acceleration", - AltosGraphDataPoint.data_accel, - AltosConvert.accel, - accel_color, - true, - accel_axis); - } - if (stats.has_gps) { - boolean enable_gps = false; - - if (!stats.has_flight_data) - enable_gps = true; - - addSeries("Range", - AltosGraphDataPoint.data_range, - AltosConvert.distance, - range_color, - false, - distance_axis); - addSeries("Distance", - AltosGraphDataPoint.data_distance, - AltosConvert.distance, - distance_color, - enable_gps, - distance_axis); - addSeries("GPS Height", - AltosGraphDataPoint.data_gps_height, - AltosConvert.height, - gps_height_color, - enable_gps, - height_axis); - addSeries("GPS Altitude", - AltosGraphDataPoint.data_gps_altitude, - AltosConvert.height, - gps_height_color, - false, - height_axis); - addSeries("GPS Satellites in Solution", - AltosGraphDataPoint.data_gps_nsat_solution, - nsat_units, - gps_nsat_solution_color, - false, - nsat_axis); - if (stats.has_gps_sats) { - addSeries("GPS Satellites in View", - AltosGraphDataPoint.data_gps_nsat_view, - nsat_units, - gps_nsat_view_color, - false, - nsat_axis); - } - if (stats.has_gps_detail) { - addSeries("GPS Course", - AltosGraphDataPoint.data_gps_course, - orient_units, - gps_course_color, - false, - course_axis); - addSeries("GPS Ground Speed", - AltosGraphDataPoint.data_gps_ground_speed, - AltosConvert.speed, - gps_ground_speed_color, - enable_gps, - speed_axis); - addSeries("GPS Climb Rate", - AltosGraphDataPoint.data_gps_climb_rate, - AltosConvert.speed, - gps_climb_rate_color, - enable_gps, - speed_axis); - } - addSeries("GPS Position DOP", - AltosGraphDataPoint.data_gps_pdop, - dop_units, - gps_pdop_color, - false, - dop_axis); - if (stats.has_gps_detail) { - addSeries("GPS Horizontal DOP", - AltosGraphDataPoint.data_gps_hdop, - dop_units, - gps_hdop_color, - false, - dop_axis); - addSeries("GPS Vertical DOP", - AltosGraphDataPoint.data_gps_vdop, - dop_units, - gps_vdop_color, - false, - dop_axis); - } - } - if (stats.has_rssi) - addSeries("Received Signal Strength", - AltosGraphDataPoint.data_rssi, - dbm_units, - dbm_color, - false, - dbm_axis); - - if (stats.has_battery) - addSeries("Battery Voltage", - AltosGraphDataPoint.data_battery_voltage, - voltage_units, - battery_voltage_color, - false, - voltage_axis); - - if (stats.has_flight_adc) { - addSeries("Temperature", - AltosGraphDataPoint.data_temperature, - AltosConvert.temperature, - temperature_color, - false, - temperature_axis); - addSeries("Drogue Voltage", - AltosGraphDataPoint.data_drogue_voltage, - voltage_units, - drogue_voltage_color, - false, - voltage_axis); - addSeries("Main Voltage", - AltosGraphDataPoint.data_main_voltage, - voltage_units, - main_voltage_color, - false, - voltage_axis); - } - - if (stats.has_imu) { - addSeries("Acceleration Along", - AltosGraphDataPoint.data_accel_along, - AltosConvert.accel, - accel_x_color, - false, - accel_axis); - addSeries("Acceleration Across", - AltosGraphDataPoint.data_accel_across, - AltosConvert.accel, - accel_y_color, - false, - accel_axis); - addSeries("Acceleration Through", - AltosGraphDataPoint.data_accel_through, - AltosConvert.accel, - accel_z_color, - false, - accel_axis); - addSeries("Roll Rate", - AltosGraphDataPoint.data_gyro_roll, - gyro_units, - gyro_x_color, - false, - gyro_axis); - addSeries("Pitch Rate", - AltosGraphDataPoint.data_gyro_pitch, - gyro_units, - gyro_y_color, - false, - gyro_axis); - addSeries("Yaw Rate", - AltosGraphDataPoint.data_gyro_yaw, - gyro_units, - gyro_z_color, - false, - gyro_axis); - } - if (stats.has_mag) { - addSeries("Magnetometer Along", - AltosGraphDataPoint.data_mag_along, - mag_units, - mag_x_color, - false, - mag_axis); - addSeries("Magnetometer Across", - AltosGraphDataPoint.data_mag_across, - mag_units, - mag_y_color, - false, - mag_axis); - addSeries("Magnetometer Through", - AltosGraphDataPoint.data_mag_through, - mag_units, - mag_z_color, - false, - mag_axis); - } - if (stats.has_orient) - addSeries("Tilt Angle", - AltosGraphDataPoint.data_orient, - orient_units, - orient_color, - false, - orient_axis); - if (stats.num_ignitor > 0) { - for (int i = 0; i < stats.num_ignitor; i++) - addSeries(AltosLib.ignitor_name(i), - AltosGraphDataPoint.data_ignitor_0 + i, - voltage_units, - main_voltage_color, - false, - voltage_axis); - for (int i = 0; i < stats.num_ignitor; i++) - addMarker(AltosLib.ignitor_name(i), AltosGraphDataPoint.data_ignitor_fired_0 + i, state_color); - } -*/ } public AltosGraphNew(AltosUIEnable enable, AltosFlightStats stats, AltosUIFlightSeries flight_series, AltosCalData cal_data) { diff --git a/altosuilib/AltosUIFlightSeries.java b/altosuilib/AltosUIFlightSeries.java index 1840761e..0bcc8a6e 100644 --- a/altosuilib/AltosUIFlightSeries.java +++ b/altosuilib/AltosUIFlightSeries.java @@ -33,15 +33,17 @@ class AltosUITimeSeriesAxis { Color color; boolean enabled; boolean marker; + boolean marker_top; AltosUIAxis axis; XYPlot plot; - public AltosUITimeSeriesAxis(Color color, boolean enabled, AltosUIAxis axis, XYPlot plot, boolean marker) { + public AltosUITimeSeriesAxis(Color color, boolean enabled, AltosUIAxis axis, XYPlot plot, boolean marker, boolean marker_top) { this.color = color; this.enabled = enabled; this.axis = axis; this.plot = plot; this.marker = marker; + this.marker_top = marker_top; } } @@ -57,7 +59,7 @@ public class AltosUIFlightSeries extends AltosFlightSeries { if (label.equals(ts.label) || (label.equals("default") && uts.color == null)) { if (axis.marker) - uts.set_marker(axis.color, axis.enabled, axis.plot); + uts.set_marker(axis.color, axis.enabled, axis.plot, axis.marker_top); else uts.set_axis(axis.color, axis.enabled, axis.axis); } @@ -72,6 +74,7 @@ public class AltosUIFlightSeries extends AltosFlightSeries { enabled, axis, null, + false, false); axes.put(label, tsa); fill_axes(label, tsa); @@ -80,12 +83,14 @@ public class AltosUIFlightSeries extends AltosFlightSeries { public void register_marker(String label, Color color, boolean enabled, - XYPlot plot) { + XYPlot plot, + boolean marker_top) { AltosUITimeSeriesAxis tsa = new AltosUITimeSeriesAxis(color, enabled, null, plot, - true); + true, + marker_top); axes.put(label, tsa); fill_axes(label, tsa); } @@ -100,7 +105,7 @@ public class AltosUIFlightSeries extends AltosFlightSeries { tsa = axes.get("default"); if (tsa != null) { if (tsa.marker) - time_series.set_marker(tsa.color, tsa.enabled, tsa.plot); + time_series.set_marker(tsa.color, tsa.enabled, tsa.plot, tsa.marker_top); else time_series.set_axis(tsa.color, tsa.enabled, tsa.axis); } diff --git a/altosuilib/AltosUITimeSeries.java b/altosuilib/AltosUITimeSeries.java index 0f5e35eb..7c48264e 100644 --- a/altosuilib/AltosUITimeSeries.java +++ b/altosuilib/AltosUITimeSeries.java @@ -47,6 +47,7 @@ public class AltosUITimeSeries extends AltosTimeSeries implements AltosUIGrapher boolean enable; AltosUIAxis axis; boolean marker; + boolean marker_top; XYItemRenderer renderer; XYPlot plot; AltosXYSeries xy_series; @@ -81,8 +82,13 @@ public class AltosUITimeSeries extends AltosTimeSeries implements AltosUIGrapher String s = units.string_value(v.value); ValueMarker marker = new ValueMarker(v.time); marker.setLabel(s); - marker.setLabelAnchor(RectangleAnchor.TOP_RIGHT); - marker.setLabelTextAnchor(TextAnchor.TOP_LEFT); + if (marker_top) { + marker.setLabelAnchor(RectangleAnchor.TOP_RIGHT); + marker.setLabelTextAnchor(TextAnchor.TOP_LEFT); + } else { + marker.setLabelAnchor(RectangleAnchor.BOTTOM_RIGHT); + marker.setLabelTextAnchor(TextAnchor.BOTTOM_LEFT); + } marker.setPaint(color); if (enable) plot.addDomainMarker(marker); @@ -91,12 +97,14 @@ public class AltosUITimeSeries extends AltosTimeSeries implements AltosUIGrapher } else { xy_series.clear(); + xy_series.setNotify(false); for (AltosTimeValue v : this) { double value = v.value; if (units != null) value = units.graph_value(value); xy_series.add(v.time, value); } + xy_series.setNotify(true); } } @@ -153,11 +161,12 @@ public class AltosUITimeSeries extends AltosTimeSeries implements AltosUIGrapher xy_series = new AltosXYSeries(label); } - public void set_marker(Color color, boolean enable, XYPlot plot) { + public void set_marker(Color color, boolean enable, XYPlot plot, boolean marker_top) { this.color = color; this.enable = enable; this.marker = true; this.plot = plot; + this.marker_top = marker_top; } public AltosUITimeSeries(String label, AltosUnits units) { -- 2.30.2