2 * Copyright © 2018 Bdale Garbee <bdale@gag.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 import org.altusmetrum.altoslib_12.*;
24 public class TestStats {
25 public double max_pressure;
26 public double max_thrust;
27 public double max_height;
28 public double max_gps_height;
29 public double max_speed;
30 public double max_acceleration;
31 public double[] state_speed = new double[AltosLib.ao_flight_invalid + 1];
32 public double[] state_enter_speed = new double[AltosLib.ao_flight_invalid + 1];
33 public double[] state_enter_height = new double[AltosLib.ao_flight_invalid + 1];
34 public double[] state_enter_gps_height = new double[AltosLib.ao_flight_invalid + 1];
35 public double[] state_accel = new double[AltosLib.ao_flight_invalid + 1];
36 public double[] state_time = new double[AltosLib.ao_flight_invalid + 1];
37 public String product;
38 public String firmware_version;
41 public int year, month, day;
42 public int hour, minute, second;
43 public double boost_time;
44 public double landed_time;
45 public double lat, lon;
46 public double pad_lat, pad_lon;
47 public boolean has_flight_data;
48 public boolean has_gps;
49 public boolean has_gps_sats;
50 public boolean has_gps_detail;
51 public boolean has_flight_adc;
52 public boolean has_battery;
53 public boolean has_rssi;
54 public boolean has_imu;
55 public boolean has_mag;
56 public boolean has_orient;
57 public int num_igniter;
59 double landed_time(AltosFlightSeries series) {
60 double landed_state_time = AltosLib.MISSING;
62 double prev_state_time = AltosLib.MISSING;
63 if (series.state_series != null) {
64 for (AltosTimeValue state : series.state_series) {
65 if (state.value == AltosLib.ao_flight_landed) {
66 landed_state_time = state.time;
69 prev_state_time = state.time;
74 if (landed_state_time == AltosLib.MISSING && series.height_series != null)
75 landed_state_time = series.height_series.get(series.height_series.size()-1).time;
77 double landed_height = AltosLib.MISSING;
79 if (series.height_series != null) {
80 for (AltosTimeValue height : series.height_series) {
81 landed_height = height.value;
82 if (height.time >= landed_state_time)
87 if (landed_height == AltosLib.MISSING)
88 return AltosLib.MISSING;
92 double landed_time = AltosLib.MISSING;
94 if (series.height_series != null) {
95 for (AltosTimeValue height : series.height_series) {
96 if (height.value > landed_height + 10) {
99 if (above && Math.abs(height.value - landed_height) < 2) {
101 landed_time = height.time;
107 if (landed_time == AltosLib.MISSING || (prev_state_time != AltosLib.MISSING && landed_time < prev_state_time))
108 landed_time = landed_state_time;
112 double boost_time(AltosFlightSeries series) {
113 double boost_time = AltosLib.MISSING;
114 double boost_state_time = AltosLib.MISSING;
116 if (series.state_series != null) {
117 for (AltosTimeValue state : series.state_series) {
118 if (state.value >= AltosLib.ao_flight_boost && state.value <= AltosLib.ao_flight_landed) {
119 boost_state_time = state.time;
124 if (series.accel_series != null) {
125 for (AltosTimeValue accel : series.accel_series) {
127 boost_time = accel.time;
128 if (boost_state_time != AltosLib.MISSING && accel.time >= boost_state_time)
132 if (boost_time == AltosLib.MISSING)
133 boost_time = boost_state_time;
137 private void add_times(AltosFlightSeries series, int state, double start_time, double end_time) {
138 double delta_time = end_time - start_time;
139 if (0 <= state && state <= AltosLib.ao_flight_invalid && delta_time > 0) {
140 if (state_enter_speed[state] == AltosLib.MISSING)
141 state_enter_speed[state] = series.speed_series.value(start_time);
142 if (state_enter_height[state] == AltosLib.MISSING)
143 state_enter_height[state] = series.height_series.value(start_time);
144 if (state_enter_gps_height[state] == AltosLib.MISSING)
145 if (series.gps_height != null)
146 state_enter_gps_height[state] = series.gps_height.value(start_time);
147 speeds[state].value += series.speed_series.average(start_time, end_time) * delta_time;
148 speeds[state].time += delta_time;
149 accels[state].value += series.accel_series.average(start_time, end_time) * delta_time;
150 accels[state].time += delta_time;
151 state_time[state] += delta_time;
153 if (state == AltosLib.ao_flight_boost) {
154 AltosTimeValue tv_speed = series.speed_series.max(start_time, end_time);
155 if (tv_speed != null && (max_speed == AltosLib.MISSING || tv_speed.value > max_speed))
156 max_speed = tv_speed.value;
157 AltosTimeValue tv_accel = series.accel_series.max(start_time, end_time);
158 if (tv_accel != null && (max_acceleration == AltosLib.MISSING || tv_accel.value > max_acceleration))
159 max_acceleration = tv_accel.value;
164 AltosTimeValue[] speeds = new AltosTimeValue[AltosLib.ao_flight_invalid + 1];
165 AltosTimeValue[] accels = new AltosTimeValue[AltosLib.ao_flight_invalid + 1];
167 public TestStats(AltosFlightSeries series) {
168 AltosCalData cal_data = series.cal_data();
172 boost_time = boost_time(series);
173 landed_time = landed_time(series);
175 if (series.state_series != null){
176 boolean fixed_boost = false;
177 boolean fixed_landed = false;
178 for (AltosTimeValue state : series.state_series) {
179 if ((int) state.value == AltosLib.ao_flight_boost)
180 if (boost_time != AltosLib.MISSING && !fixed_boost) {
181 state.time = boost_time;
184 if ((int) state.value == AltosLib.ao_flight_landed)
185 if (landed_time != AltosLib.MISSING && !fixed_landed) {
186 state.time = landed_time;
192 year = month = day = AltosLib.MISSING;
193 hour = minute = second = AltosLib.MISSING;
194 serial = flight = AltosLib.MISSING;
195 lat = lon = AltosLib.MISSING;
196 has_flight_data = false;
198 has_gps_sats = false;
199 has_flight_adc = false;
206 for (int s = 0; s < AltosLib.ao_flight_invalid + 1; s++) {
207 state_speed[s] = AltosLib.MISSING;
208 state_enter_speed[s] = AltosLib.MISSING;
209 state_accel[s] = AltosLib.MISSING;
211 speeds[s] = new AltosTimeValue(0, 0);
212 accels[s] = new AltosTimeValue(0, 0);
215 max_speed = AltosLib.MISSING;
216 max_acceleration = AltosLib.MISSING;
218 if (series.state_series != null) {
219 AltosTimeValue prev = null;
220 for (AltosTimeValue state : series.state_series) {
222 add_times(series, (int) prev.value, prev.time, state.time);
226 AltosTimeValue last_accel = series.accel_series.last();
227 if (last_accel != null)
228 add_times(series, (int) prev.value, prev.time, last_accel.time);
232 for (int s = 0; s <= AltosLib.ao_flight_invalid; s++) {
233 if (speeds[s].time > 0)
234 state_speed[s] = speeds[s].value / speeds[s].time;
235 if (accels[s].time > 0)
236 state_accel[s] = accels[s].value / accels[s].time;
239 product = cal_data.product;
240 firmware_version = cal_data.firmware_version;
241 serial = cal_data.serial;
242 flight = cal_data.flight;
244 has_battery = series.battery_voltage_series != null;
245 has_flight_adc = series.main_voltage_series != null;
246 has_rssi = series.rssi_series != null;
247 has_flight_data = series.pressure_series != null;
249 max_pressure = AltosLib.MISSING;
250 if (series.pressure_series != null)
251 max_pressure = series.pressure_series.max().value;
252 max_thrust = AltosLib.MISSING;
253 if (series.thrust_series != null)
254 max_thrust = series.thrust_series.max().value;