From bf684a4c290573a3aa627fd8ddf6f6ebbe5fa057 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 29 May 2014 14:36:14 -0700 Subject: telegps: Add graph display Moved the altosui graph files to altosuilib and fixed things up. Signed-off-by: Keith Packard --- altosuilib/AltosGraph.java | 428 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 428 insertions(+) create mode 100644 altosuilib/AltosGraph.java (limited to 'altosuilib/AltosGraph.java') diff --git a/altosuilib/AltosGraph.java b/altosuilib/AltosGraph.java new file mode 100644 index 00000000..5e5a35cf --- /dev/null +++ b/altosuilib/AltosGraph.java @@ -0,0 +1,428 @@ +/* + * Copyright © 2013 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_2; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_4.*; + +import org.jfree.ui.*; +import org.jfree.chart.*; +import org.jfree.chart.plot.*; +import org.jfree.chart.axis.*; +import org.jfree.chart.renderer.*; +import org.jfree.chart.renderer.xy.*; +import org.jfree.chart.labels.*; +import org.jfree.data.xy.*; +import org.jfree.data.*; + +class AltosVoltage extends AltosUnits { + + public double value(double v, boolean imperial_units) { + return v; + } + + public double inverse(double v, boolean imperial_units) { + return v; + } + + public String show_units(boolean imperial_units) { + return "V"; + } + + public String say_units(boolean imperial_units) { + return "volts"; + } + + public int show_fraction(int width, boolean imperial_units) { + return width / 2; + } +} + +class AltosNsat extends AltosUnits { + + public double value(double v, boolean imperial_units) { + return v; + } + + public double inverse(double v, boolean imperial_units) { + return v; + } + + public String show_units(boolean imperial_units) { + return "Sats"; + } + + public String say_units(boolean imperial_units) { + return "Satellites"; + } + + public int show_fraction(int width, boolean imperial_units) { + return 0; + } +} + +class AltosPressure extends AltosUnits { + + public double value(double p, boolean imperial_units) { + return p; + } + + public double inverse(double p, boolean imperial_units) { + return p; + } + + public String show_units(boolean imperial_units) { + return "Pa"; + } + + public String say_units(boolean imperial_units) { + return "pascals"; + } + + public int show_fraction(int width, boolean imperial_units) { + return 0; + } +} + +class AltosDbm extends AltosUnits { + + public double value(double d, boolean imperial_units) { + return d; + } + + public double inverse(double d, boolean imperial_units) { + return d; + } + + public String show_units(boolean imperial_units) { + return "dBm"; + } + + public String say_units(boolean imperial_units) { + return "D B M"; + } + + public int show_fraction(int width, boolean imperial_units) { + return 0; + } +} + +class AltosGyroUnits extends AltosUnits { + + public double value(double p, boolean imperial_units) { + return p; + } + + public double inverse(double p, boolean imperial_units) { + return p; + } + + public String show_units(boolean imperial_units) { + return "°/sec"; + } + + public String say_units(boolean imperial_units) { + return "degrees per second"; + } + + public int show_fraction(int width, boolean imperial_units) { + return 1; + } +} + +class AltosMagUnits extends AltosUnits { + + public double value(double p, boolean imperial_units) { + return p; + } + + public double inverse(double p, boolean imperial_units) { + return p; + } + + public String show_units(boolean imperial_units) { + return "Ga"; + } + + public String say_units(boolean imperial_units) { + return "gauss"; + } + + public int show_fraction(int width, boolean imperial_units) { + return 2; + } +} + +public class AltosGraph extends AltosUIGraph { + + static final private Color height_color = new Color(194,31,31); + static final private Color gps_height_color = new Color(150,31,31); + static final private Color pressure_color = new Color (225,31,31); + static final private Color range_color = new Color(100, 31, 31); + static final private Color distance_color = new Color(100, 31, 194); + static final private Color speed_color = new Color(31,194,31); + static final private Color accel_color = new Color(31,31,194); + static final private Color voltage_color = new Color(194, 194, 31); + static final private Color battery_voltage_color = new Color(194, 194, 31); + static final private Color drogue_voltage_color = new Color(150, 150, 31); + static final private Color main_voltage_color = new Color(100, 100, 31); + static final private Color gps_nsat_color = new Color (194, 31, 194); + static final private Color gps_nsat_solution_color = new Color (194, 31, 194); + static final private Color gps_nsat_view_color = new Color (150, 31, 150); + static final private Color gps_course_color = new Color (100, 31, 112); + static final private Color gps_ground_speed_color = new Color (31, 112, 100); + static final private Color gps_climb_rate_color = new Color (31, 31, 112); + 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 orient_color = new Color(31, 31, 31); + + static AltosVoltage voltage_units = new AltosVoltage(); + static AltosPressure pressure_units = new AltosPressure(); + static AltosNsat nsat_units = new AltosNsat(); + static AltosDbm dbm_units = new AltosDbm(); + static AltosGyroUnits gyro_units = new AltosGyroUnits(); + static AltosOrient orient_units = new AltosOrient(); + static AltosMagUnits mag_units = new AltosMagUnits(); + + AltosUIAxis height_axis, speed_axis, accel_axis, voltage_axis, temperature_axis, nsat_axis, dbm_axis; + AltosUIAxis distance_axis, pressure_axis; + AltosUIAxis gyro_axis, orient_axis, mag_axis; + AltosUIAxis course_axis; + + public AltosGraph(AltosUIEnable enable, AltosFlightStats stats, AltosGraphDataSet dataSet) { + super(enable); + + height_axis = newAxis("Height", AltosConvert.height, height_color); + pressure_axis = newAxis("Pressure", pressure_units, pressure_color, 0); + speed_axis = newAxis("Speed", AltosConvert.speed, speed_color); + accel_axis = newAxis("Acceleration", AltosConvert.accel, accel_color); + voltage_axis = newAxis("Voltage", voltage_units, voltage_color); + temperature_axis = newAxis("Temperature", AltosConvert.temperature, temperature_color, 0); + nsat_axis = newAxis("Satellites", nsat_units, gps_nsat_color, + AltosUIAxis.axis_include_zero | AltosUIAxis.axis_integer); + dbm_axis = newAxis("Signal Strength", dbm_units, dbm_color, 0); + distance_axis = newAxis("Distance", AltosConvert.distance, range_color); + + gyro_axis = newAxis("Rotation Rate", gyro_units, 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); + + addMarker("State", AltosGraphDataPoint.data_state, state_color); + 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("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) { + addSeries("Range", + AltosGraphDataPoint.data_range, + AltosConvert.distance, + range_color, + false, + distance_axis); + addSeries("Distance", + AltosGraphDataPoint.data_distance, + AltosConvert.distance, + distance_color, + false, + distance_axis); + addSeries("GPS Height", + AltosGraphDataPoint.data_gps_height, + AltosConvert.height, + gps_height_color, + false, + height_axis); + addSeries("GPS Satellites in Solution", + AltosGraphDataPoint.data_gps_nsat_solution, + nsat_units, + gps_nsat_solution_color, + false, + nsat_axis); + addSeries("GPS Satellites in View", + AltosGraphDataPoint.data_gps_nsat_view, + nsat_units, + gps_nsat_view_color, + false, + nsat_axis); + addSeries("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, + false, + speed_axis); + addSeries("GPS Climb Rate", + AltosGraphDataPoint.data_gps_climb_rate, + AltosConvert.speed, + gps_climb_rate_color, + false, + speed_axis); + } + if (stats.has_rssi) + addSeries("Received Signal Strength", + AltosGraphDataPoint.data_rssi, + dbm_units, + dbm_color, + false, + dbm_axis); + if (stats.has_other_adc) { + addSeries("Temperature", + AltosGraphDataPoint.data_temperature, + AltosConvert.temperature, + temperature_color, + false, + temperature_axis); + addSeries("Battery Voltage", + AltosGraphDataPoint.data_battery_voltage, + voltage_units, + battery_voltage_color, + false, + voltage_axis); + addSeries("Drogue Voltage", + AltosGraphDataPoint.data_drogue_voltage, + voltage_units, + drogue_voltage_color, + false, + voltage_axis); + addSeries("Main Voltage", + AltosGraphDataPoint.data_main_voltage, + voltage_units, + main_voltage_color, + false, + voltage_axis); + } + + if (stats.has_imu) { + addSeries("Acceleration X", + AltosGraphDataPoint.data_accel_x, + AltosConvert.accel, + accel_x_color, + false, + accel_axis); + addSeries("Acceleration Y", + AltosGraphDataPoint.data_accel_y, + AltosConvert.accel, + accel_y_color, + false, + accel_axis); + addSeries("Acceleration Z", + AltosGraphDataPoint.data_accel_z, + AltosConvert.accel, + accel_z_color, + false, + accel_axis); + addSeries("Rotation Rate X", + AltosGraphDataPoint.data_gyro_x, + gyro_units, + gyro_x_color, + false, + gyro_axis); + addSeries("Rotation Rate Y", + AltosGraphDataPoint.data_gyro_y, + gyro_units, + gyro_y_color, + false, + gyro_axis); + addSeries("Rotation Rate Z", + AltosGraphDataPoint.data_gyro_z, + gyro_units, + gyro_z_color, + false, + gyro_axis); + } + if (stats.has_mag) { + addSeries("Magnetometer X", + AltosGraphDataPoint.data_mag_x, + mag_units, + mag_x_color, + false, + mag_axis); + addSeries("Magnetometer Y", + AltosGraphDataPoint.data_mag_y, + mag_units, + mag_y_color, + false, + mag_axis); + addSeries("Magnetometer Z", + AltosGraphDataPoint.data_mag_z, + 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); + } + + setDataSet(dataSet); + } +} -- cgit v1.2.3 From 5617919091d4c4a1e627470ddab0b45cf649f7a1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Jun 2014 11:49:14 -0700 Subject: altosuilib: Show GPS instead of (missing) flight data for TeleGPS graphs Signed-off-by: Keith Packard --- altosuilib/AltosGraph.java | 68 ++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 27 deletions(-) (limited to 'altosuilib/AltosGraph.java') diff --git a/altosuilib/AltosGraph.java b/altosuilib/AltosGraph.java index 5e5a35cf..73c53a22 100644 --- a/altosuilib/AltosGraph.java +++ b/altosuilib/AltosGraph.java @@ -238,31 +238,39 @@ public class AltosGraph extends AltosUIGraph { course_axis = newAxis("Course", orient_units, gps_course_color, 0); addMarker("State", AltosGraphDataPoint.data_state, state_color); - 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("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_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("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, @@ -273,12 +281,18 @@ public class AltosGraph extends AltosUIGraph { AltosGraphDataPoint.data_distance, AltosConvert.distance, distance_color, - false, + 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", @@ -303,13 +317,13 @@ public class AltosGraph extends AltosUIGraph { AltosGraphDataPoint.data_gps_ground_speed, AltosConvert.speed, gps_ground_speed_color, - false, + enable_gps, speed_axis); addSeries("GPS Climb Rate", AltosGraphDataPoint.data_gps_climb_rate, AltosConvert.speed, gps_climb_rate_color, - false, + enable_gps, speed_axis); } if (stats.has_rssi) -- cgit v1.2.3 From 6fc58142d2a108c91d257eb0175098bf082834f9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 10 Jun 2014 11:30:36 -0700 Subject: altosuilib: Split battery graph enable out from other adc enables This lets TeleGPS just show the battery voltage values without also adding enable lines for the other flight computer ADC values like ignitor voltages. Signed-off-by: Keith Packard --- altoslib/AltosFlightStats.java | 30 ++++--- altosui/AltosFlightStatsTable.java | 144 ---------------------------------- altosuilib/AltosFlightStatsTable.java | 144 ++++++++++++++++++++++++++++++++++ altosuilib/AltosGraph.java | 17 ++-- 4 files changed, 173 insertions(+), 162 deletions(-) delete mode 100644 altosui/AltosFlightStatsTable.java create mode 100644 altosuilib/AltosFlightStatsTable.java (limited to 'altosuilib/AltosGraph.java') diff --git a/altoslib/AltosFlightStats.java b/altoslib/AltosFlightStats.java index b3305a05..56feb848 100644 --- a/altoslib/AltosFlightStats.java +++ b/altoslib/AltosFlightStats.java @@ -37,7 +37,8 @@ public class AltosFlightStats { public double pad_lat, pad_lon; public boolean has_flight_data; public boolean has_gps; - public boolean has_other_adc; + public boolean has_flight_adc; + public boolean has_battery; public boolean has_rssi; public boolean has_imu; public boolean has_mag; @@ -112,7 +113,8 @@ public class AltosFlightStats { lat = lon = AltosLib.MISSING; has_flight_data = false; has_gps = false; - has_other_adc = false; + has_flight_adc = false; + has_battery = false; has_rssi = false; has_imu = false; has_mag = false; @@ -123,7 +125,9 @@ public class AltosFlightStats { if (flight == AltosLib.MISSING && state.flight != AltosLib.MISSING) flight = state.flight; if (state.battery_voltage != AltosLib.MISSING) - has_other_adc = true; + 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; @@ -144,6 +148,11 @@ public class AltosFlightStats { 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(); @@ -156,16 +165,12 @@ public class AltosFlightStats { state_start[state_id] = state.time; if (state_end[state_id] < state.time) state_end[state_id] = state.time; - max_height = state.max_height(); - max_speed = state.max_speed(); - max_acceleration = state.max_acceleration(); - max_gps_height = state.max_gps_height(); + } + if (state.pad_lat != AltosLib.MISSING) { + pad_lat = state.pad_lat; + pad_lon = state.pad_lon; } if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { - if (state_id <= AltosLib.ao_flight_pad) { - pad_lat = state.gps.lat; - pad_lon = state.gps.lon; - } lat = state.gps.lat; lon = state.gps.lon; has_gps = true; @@ -183,6 +188,9 @@ public class AltosFlightStats { if (state_count[s] > 0) { state_speed[s] /= state_count[s]; state_accel[s] /= state_count[s]; + } else { + state_speed[s] = AltosLib.MISSING; + state_accel[s] = AltosLib.MISSING; } if (state_start[s] == 0) state_start[s] = end_time; diff --git a/altosui/AltosFlightStatsTable.java b/altosui/AltosFlightStatsTable.java deleted file mode 100644 index e7a8e728..00000000 --- a/altosui/AltosFlightStatsTable.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright © 2011 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; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package altosui; - -import java.awt.*; -import javax.swing.*; -import org.altusmetrum.altoslib_4.*; - -public class AltosFlightStatsTable extends JComponent { - GridBagLayout layout; - - class FlightStat { - JLabel label; - JTextField value; - - public FlightStat(GridBagLayout layout, int y, String label_text, String ... values) { - GridBagConstraints c = new GridBagConstraints(); - c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad); - c.weighty = 1; - - label = new JLabel(label_text); - label.setFont(Altos.label_font); - label.setHorizontalAlignment(SwingConstants.LEFT); - c.gridx = 0; c.gridy = y; - c.anchor = GridBagConstraints.WEST; - c.fill = GridBagConstraints.VERTICAL; - c.weightx = 0; - layout.setConstraints(label, c); - add(label); - - for (int j = 0; j < values.length; j++) { - value = new JTextField(values[j]); - value.setFont(Altos.value_font); - value.setHorizontalAlignment(SwingConstants.RIGHT); - c.gridx = j+1; c.gridy = y; - c.anchor = GridBagConstraints.EAST; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - layout.setConstraints(value, c); - add(value); - } - } - - } - - static String pos(double p, String pos, String neg) { - String h = pos; - if (p < 0) { - h = neg; - p = -p; - } - int deg = (int) Math.floor(p); - double min = (p - Math.floor(p)) * 60.0; - return String.format("%s %4d° %9.6f'", h, deg, min); - } - - public AltosFlightStatsTable(AltosFlightStats stats) { - layout = new GridBagLayout(); - - setLayout(layout); - int y = 0; - new FlightStat(layout, y++, "Serial", String.format("%d", stats.serial)); - new FlightStat(layout, y++, "Flight", String.format("%d", stats.flight)); - if (stats.year != AltosLib.MISSING && stats.hour != AltosLib.MISSING) - new FlightStat(layout, y++, "Date/Time", - String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day), - String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); - else { - if (stats.year != AltosLib.MISSING) - new FlightStat(layout, y++, "Date", - String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day)); - if (stats.hour != AltosLib.MISSING) - new FlightStat(layout, y++, "Time", - String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); - } - new FlightStat(layout, y++, "Maximum height", - String.format("%5.0f m", stats.max_height), - String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.max_height))); - if (stats.max_gps_height != AltosLib.MISSING) { - new FlightStat(layout, y++, "Maximum GPS height", - String.format("%5.0f m", stats.max_gps_height), - String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.max_gps_height))); - } - new FlightStat(layout, y++, "Maximum speed", - String.format("%5.0f m/s", stats.max_speed), - String.format("%5.0f mph", AltosConvert.meters_to_mph(stats.max_speed)), - String.format("Mach %4.1f", AltosConvert.meters_to_mach(stats.max_speed))); - if (stats.max_acceleration != AltosLib.MISSING) { - new FlightStat(layout, y++, "Maximum boost acceleration", - String.format("%5.0f m/s²", stats.max_acceleration), - String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.max_acceleration)), - String.format("%5.0f G", AltosConvert.meters_to_g(stats.max_acceleration))); - new FlightStat(layout, y++, "Average boost acceleration", - String.format("%5.0f m/s²", stats.state_accel[Altos.ao_flight_boost]), - String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.state_accel[Altos.ao_flight_boost])), - String.format("%5.0f G", AltosConvert.meters_to_g(stats.state_accel[Altos.ao_flight_boost]))); - } - new FlightStat(layout, y++, "Drogue descent rate", - String.format("%5.0f m/s", stats.state_speed[Altos.ao_flight_drogue]), - String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue]))); - new FlightStat(layout, y++, "Main descent rate", - String.format("%5.0f m/s", stats.state_speed[Altos.ao_flight_main]), - String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main]))); - new FlightStat(layout, y++, "Ascent time", - String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_boost] - stats.state_start[AltosLib.ao_flight_boost], - AltosLib.state_name(Altos.ao_flight_boost)), - String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_fast] - stats.state_start[AltosLib.ao_flight_fast], - AltosLib.state_name(Altos.ao_flight_fast)), - String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_coast] - stats.state_start[AltosLib.ao_flight_coast], - AltosLib.state_name(Altos.ao_flight_coast))); - new FlightStat(layout, y++, "Descent time", - String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_drogue] - stats.state_start[AltosLib.ao_flight_drogue], - AltosLib.state_name(Altos.ao_flight_drogue)), - String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_main] - stats.state_start[AltosLib.ao_flight_main], - AltosLib.state_name(Altos.ao_flight_main))); - new FlightStat(layout, y++, "Flight time", - String.format("%6.1f s", stats.state_end[Altos.ao_flight_main] - - stats.state_start[Altos.ao_flight_boost])); - if (stats.has_gps) { - new FlightStat(layout, y++, "Pad location", - pos(stats.pad_lat,"N","S"), - pos(stats.pad_lon,"E","W")); - new FlightStat(layout, y++, "Last reported location", - pos(stats.lat,"N","S"), - pos(stats.lon,"E","W")); - } - } - -} \ No newline at end of file diff --git a/altosuilib/AltosFlightStatsTable.java b/altosuilib/AltosFlightStatsTable.java new file mode 100644 index 00000000..e7a8e728 --- /dev/null +++ b/altosuilib/AltosFlightStatsTable.java @@ -0,0 +1,144 @@ +/* + * Copyright © 2011 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_4.*; + +public class AltosFlightStatsTable extends JComponent { + GridBagLayout layout; + + class FlightStat { + JLabel label; + JTextField value; + + public FlightStat(GridBagLayout layout, int y, String label_text, String ... values) { + GridBagConstraints c = new GridBagConstraints(); + c.insets = new Insets(Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad, Altos.tab_elt_pad); + c.weighty = 1; + + label = new JLabel(label_text); + label.setFont(Altos.label_font); + label.setHorizontalAlignment(SwingConstants.LEFT); + c.gridx = 0; c.gridy = y; + c.anchor = GridBagConstraints.WEST; + c.fill = GridBagConstraints.VERTICAL; + c.weightx = 0; + layout.setConstraints(label, c); + add(label); + + for (int j = 0; j < values.length; j++) { + value = new JTextField(values[j]); + value.setFont(Altos.value_font); + value.setHorizontalAlignment(SwingConstants.RIGHT); + c.gridx = j+1; c.gridy = y; + c.anchor = GridBagConstraints.EAST; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1; + layout.setConstraints(value, c); + add(value); + } + } + + } + + static String pos(double p, String pos, String neg) { + String h = pos; + if (p < 0) { + h = neg; + p = -p; + } + int deg = (int) Math.floor(p); + double min = (p - Math.floor(p)) * 60.0; + return String.format("%s %4d° %9.6f'", h, deg, min); + } + + public AltosFlightStatsTable(AltosFlightStats stats) { + layout = new GridBagLayout(); + + setLayout(layout); + int y = 0; + new FlightStat(layout, y++, "Serial", String.format("%d", stats.serial)); + new FlightStat(layout, y++, "Flight", String.format("%d", stats.flight)); + if (stats.year != AltosLib.MISSING && stats.hour != AltosLib.MISSING) + new FlightStat(layout, y++, "Date/Time", + String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day), + String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); + else { + if (stats.year != AltosLib.MISSING) + new FlightStat(layout, y++, "Date", + String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day)); + if (stats.hour != AltosLib.MISSING) + new FlightStat(layout, y++, "Time", + String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); + } + new FlightStat(layout, y++, "Maximum height", + String.format("%5.0f m", stats.max_height), + String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.max_height))); + if (stats.max_gps_height != AltosLib.MISSING) { + new FlightStat(layout, y++, "Maximum GPS height", + String.format("%5.0f m", stats.max_gps_height), + String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.max_gps_height))); + } + new FlightStat(layout, y++, "Maximum speed", + String.format("%5.0f m/s", stats.max_speed), + String.format("%5.0f mph", AltosConvert.meters_to_mph(stats.max_speed)), + String.format("Mach %4.1f", AltosConvert.meters_to_mach(stats.max_speed))); + if (stats.max_acceleration != AltosLib.MISSING) { + new FlightStat(layout, y++, "Maximum boost acceleration", + String.format("%5.0f m/s²", stats.max_acceleration), + String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.max_acceleration)), + String.format("%5.0f G", AltosConvert.meters_to_g(stats.max_acceleration))); + new FlightStat(layout, y++, "Average boost acceleration", + String.format("%5.0f m/s²", stats.state_accel[Altos.ao_flight_boost]), + String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.state_accel[Altos.ao_flight_boost])), + String.format("%5.0f G", AltosConvert.meters_to_g(stats.state_accel[Altos.ao_flight_boost]))); + } + new FlightStat(layout, y++, "Drogue descent rate", + String.format("%5.0f m/s", stats.state_speed[Altos.ao_flight_drogue]), + String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue]))); + new FlightStat(layout, y++, "Main descent rate", + String.format("%5.0f m/s", stats.state_speed[Altos.ao_flight_main]), + String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main]))); + new FlightStat(layout, y++, "Ascent time", + String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_boost] - stats.state_start[AltosLib.ao_flight_boost], + AltosLib.state_name(Altos.ao_flight_boost)), + String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_fast] - stats.state_start[AltosLib.ao_flight_fast], + AltosLib.state_name(Altos.ao_flight_fast)), + String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_coast] - stats.state_start[AltosLib.ao_flight_coast], + AltosLib.state_name(Altos.ao_flight_coast))); + new FlightStat(layout, y++, "Descent time", + String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_drogue] - stats.state_start[AltosLib.ao_flight_drogue], + AltosLib.state_name(Altos.ao_flight_drogue)), + String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_main] - stats.state_start[AltosLib.ao_flight_main], + AltosLib.state_name(Altos.ao_flight_main))); + new FlightStat(layout, y++, "Flight time", + String.format("%6.1f s", stats.state_end[Altos.ao_flight_main] - + stats.state_start[Altos.ao_flight_boost])); + if (stats.has_gps) { + new FlightStat(layout, y++, "Pad location", + pos(stats.pad_lat,"N","S"), + pos(stats.pad_lon,"E","W")); + new FlightStat(layout, y++, "Last reported location", + pos(stats.lat,"N","S"), + pos(stats.lon,"E","W")); + } + } + +} \ No newline at end of file diff --git a/altosuilib/AltosGraph.java b/altosuilib/AltosGraph.java index 73c53a22..f8c8b27b 100644 --- a/altosuilib/AltosGraph.java +++ b/altosuilib/AltosGraph.java @@ -333,19 +333,22 @@ public class AltosGraph extends AltosUIGraph { dbm_color, false, dbm_axis); - if (stats.has_other_adc) { - addSeries("Temperature", - AltosGraphDataPoint.data_temperature, - AltosConvert.temperature, - temperature_color, - false, - temperature_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, -- cgit v1.2.3