X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=altoslib%2FAltosKML.java;h=131bdf4982584c8240fd6d25fb93e0b7905cf44f;hp=61e83daa97b03466a5639f3221f6f5507bdc8b3a;hb=ec46adee44ea08120b1940ca55a5fbdf56874bb1;hpb=f26cfe417c6977cf1e7e75a4f050e25f64d41859 diff --git a/altoslib/AltosKML.java b/altoslib/AltosKML.java index 61e83daa..131bdf49 100644 --- a/altoslib/AltosKML.java +++ b/altoslib/AltosKML.java @@ -16,7 +16,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_11; +package org.altusmetrum.altoslib_14; import java.io.*; import java.util.*; @@ -37,16 +37,19 @@ public class AltosKML implements AltosWriter { PrintWriter out; int flight_state = -1; AltosGPS prev = null; - double gps_start_altitude; + double gps_start_altitude = AltosLib.MISSING; + AltosFlightSeries series; + AltosFlightStats stats; + AltosCalData cal_data; static final String[] kml_state_colors = { "FF000000", // startup "FF000000", // idle "FF000000", // pad "FF0000FF", // boost + "FF8040FF", // coast "FF4080FF", // fast - "FF00FFFF", // coast - "FFFF0000", // drogue + "FF00FFFF", // drogue "FF00FF00", // main "FF000000", // landed "FFFFFFFF", // invalid @@ -59,81 +62,169 @@ public class AltosKML implements AltosWriter { return kml_state_colors[state]; } + static final String[] kml_style_colors = { + "FF0000FF", // baro + "FFFF0000", // gps + }; + + static String style_color(int style) { + if (style < 0 || kml_style_colors.length <= style) + return kml_style_colors[0]; + return kml_style_colors[style]; + } + static final String kml_header_start = "\n" + "\n" + "\n" + " AO Flight#%d S/N: %03d\n" + - " \n"; + " \n"; + static final String kml_header_end = - " \n" + - " 0\n"; - - static final String kml_style_start = - " \n"; - - static final String kml_placemark_start = - " \n" + - " %s\n" + - " #ao-flightstate-%s\n" + - " \n" + - " 1\n" + - " absolute\n" + - " \n"; + " \n" + + " 1\n"; + + static final String kml_folder_start = + " \n" + + " %s\n"; + + static final String kml_path_style_start = + " \n"; + + static final String kml_point_style_start = + " \n"; + + static final String kml_path_start = + " \n" + + " %s\n" + + " #ao-style-%s\n" + + " \n" + + " 1\n" + + " absolute\n" + + " \n"; static final String kml_coord_fmt = - " %.7f,%.7f,%.7f \n"; + " %.7f,%.7f,%.7f \n"; + + static final String kml_path_end = + " \n" + + " \n" + + " \n"; - static final String kml_placemark_end = - " \n" + - " \n" + - " \n"; + static final String kml_point_start = + " \n" + + " %s\n" + + " #ao-style-%s\n" + + " \n" + + " 1\n" + + " absolute\n" + + " \n"; + + static final String kml_point_end = + " \n" + + " \n" + + " \n"; + + static final String kml_folder_end = + " \n"; static final String kml_footer = "\n" + "\n"; - void start (int state) { -/* - out.printf(kml_header_start, record.flight, record.serial); - out.printf("Date: %04d-%02d-%02d\n", - record.gps.year, record.gps.month, record.gps.day); - out.printf("Time: %2d:%02d:%02d\n", - record.gps.hour, record.gps.minute, record.gps.second); + void start () { + AltosGPS gps = cal_data.gps_pad; + + gps_start_altitude = cal_data.gps_pad_altitude; + out.printf(kml_header_start, cal_data.flight, cal_data.serial); + out.printf("Product: %s\n", stats.product); + out.printf("Firmware: %s\n", stats.firmware_version); + out.printf("Date: %04d-%02d-%02d\n", + gps.year, gps.month, gps.day); + out.printf("Time: %2d:%02d:%02d\n", + gps.hour, gps.minute, gps.second); + if (stats.max_height != AltosLib.MISSING) + out.printf("Max baro height: %s\n", AltosConvert.height.show(6, stats.max_height)); + if (stats.max_gps_height != AltosLib.MISSING) + out.printf("Max GPS Height: %s\n", AltosConvert.height.show(6, stats.max_gps_height)); + if (stats.max_speed != AltosLib.MISSING) + out.printf("Max speed: %s\n", AltosConvert.speed.show(6, stats.max_speed)); + if (stats.max_acceleration != AltosLib.MISSING) + out.printf("Max accel: %s\n", AltosConvert.accel.show(6, stats.max_acceleration)); out.printf("%s", kml_header_end); -*/ } - boolean started = false; + void folder_start(String folder_name) { + out.printf(kml_folder_start, folder_name); + } + + void folder_end() { + out.printf(kml_folder_end); + } + + void path_style_start(String style, String color) { + out.printf(kml_path_style_start, style, color); + } + + void path_style_end() { + out.printf(kml_path_style_end); + } + + void point_style_start(String style, String color) { + out.printf(kml_point_style_start, style, color, color); + } + + void point_style_end() { + out.printf(kml_point_style_end); + } + + void path_start(String name, String style) { + out.printf(kml_path_start, name, style); + } + + void path_end() { + out.printf(kml_path_end); + } - void state_start(int state) { - String state_name = AltosLib.state_name(state); - String state_color = state_color(state); - out.printf(kml_style_start, state_name, state_color); - out.printf("\tState: %s\n", state_name); - out.printf("%s", kml_style_end); - out.printf(kml_placemark_start, state_name, state_name); + void point_start(String name, String style) { + out.printf(kml_point_start, name, style); } - void state_end() { - out.printf("%s", kml_placemark_end); + void point_end() { + out.printf(kml_point_end); } - void coord(double time, AltosGPS gps, int state, double height) { - double altitude; + boolean started = false; + + private double baro_altitude(AltosFlightSeries series, double time) { + double height = series.value(AltosFlightSeries.height_name, time); + + if (height == AltosLib.MISSING) + return AltosLib.MISSING; + if (cal_data.gps_pad_altitude == AltosLib.MISSING) + return AltosLib.MISSING; - if (height != AltosLib.MISSING) - altitude = height + gps_start_altitude; - else - altitude = gps.alt; + return height + cal_data.gps_pad_altitude; + } + + void coord(double time, AltosGPS gps, double altitude) { out.printf(kml_coord_fmt, gps.lon, gps.lat, altitude, (double) gps.alt, @@ -145,63 +236,111 @@ public class AltosKML implements AltosWriter { } public void close() { - if (prev != null) { - state_end(); - end(); - prev = null; - } if (out != null) { out.close(); out = null; } } - public void write(AltosGPS gps, int state, double height) { + public void write(AltosGPS gps, double alt) + { + if (gps == null) + return; if (gps.lat == AltosLib.MISSING) return; if (gps.lon == AltosLib.MISSING) return; - if (!started) { - start(state); - started = true; - gps_start_altitude = gps.alt; - } - if (state != flight_state) { - flight_state = state; - if (prev != null) { -// coord(gps, state, height); - state_end(); - } - state_start(state); + if (alt == AltosLib.MISSING) { + alt = cal_data.gps_pad_altitude; + if (alt == AltosLib.MISSING) + return; } -// coord(0, gps, state, height); + coord(0, gps, alt); prev = gps; } - private int state(AltosFlightSeries series, double time) { - int s = AltosLib.MISSING; - for (AltosTimeValue state : series.state_series) { - if (state.time > time) - break; - s = (int) state.value; - } - return s; - } + public void write_point(AltosTimeValue tv, boolean is_gps) { + int state = (int) tv.value; + String style_prefix = is_gps ? "gps-" : "baro-"; + String state_name = AltosLib.state_name(state); + String state_label = AltosLib.state_name_capital(state); + String style_name = style_prefix + state_name; + String folder_name = is_gps ? "GPS" : "Baro"; + String full_name = state_label + " (" + folder_name + ")"; + AltosGPS gps = series.gps_before(tv.time); + double altitude = is_gps ? gps.alt : baro_altitude(series, tv.time); - private double height(AltosFlightSeries series, double time) { - double h = AltosLib.MISSING; - for (AltosTimeValue height : series.height_series) { - if (height.time > time) - break; - h = height.value; + point_style_start(style_name, state_color(state)); + out.printf("%s\n", full_name); + switch (state) { + case AltosLib.ao_flight_boost: + out.printf("Max accel %s\n", AltosConvert.accel.show(6, stats.max_acceleration)); + out.printf("Max speed %s\n", AltosConvert.speed.show(6, stats.max_speed)); + break; + case AltosLib.ao_flight_coast: + case AltosLib.ao_flight_fast: + out.printf("Entry speed %s\n", AltosConvert.speed.show(6, stats.state_enter_speed[state])); + out.printf("Entry height %s\n", AltosConvert.height.show(6, altitude - cal_data.gps_pad_altitude)); + break; + case AltosLib.ao_flight_drogue: + out.printf("Max height %s\n", AltosConvert.height.show(6, is_gps ? stats.max_gps_height : stats.max_height)); + out.printf("Average descent rate %s\n", AltosConvert.speed.show(6, -stats.state_speed[state])); + break; + case AltosLib.ao_flight_main: + out.printf("Entry speed %s\n", AltosConvert.speed.show(6, -stats.state_enter_speed[state])); + out.printf("Entry height %s\n", AltosConvert.height.show(6, altitude - cal_data.gps_pad_altitude)); + out.printf("Average descent rate %s\n", AltosConvert.speed.show(6, -stats.state_speed[state])); + break; + case AltosLib.ao_flight_landed: + out.printf("Landing speed %s\n", AltosConvert.speed.show(6, -stats.state_enter_speed[state])); + break; } - return h; + point_style_end(); + point_start(full_name, style_name); + gps = series.gps_before(tv.time); + write(gps, altitude); + point_end(); } public void write(AltosFlightSeries series) { - for (AltosGPSTimeValue gps : series.gps_series) { - write(gps.gps, state(series, gps.time), height(series, gps.time)); + this.series = series; + series.finish(); + stats = new AltosFlightStats(series); + cal_data = series.cal_data(); + start(); + if (series.height_series != null) { + folder_start("Barometric Altitude"); + path_style_start("baro", style_color(0)); + out.printf("Barometric Altitude\n"); + out.printf("Max height: %s\n", AltosConvert.height.show(6, stats.max_height)); + path_style_end(); + path_start("Barometric Altitude", "baro"); + for (AltosGPSTimeValue gtv : series.gps_series) + write(gtv.gps, baro_altitude(series, gtv.time)); + path_end(); + if (series.state_series != null) { + for (AltosTimeValue tv : series.state_series) { + write_point(tv, false); + } + } + folder_end(); + } + folder_start("GPS Altitude"); + path_style_start("gps", style_color(1)); + out.printf("GPS Altitude"); + out.printf("Max height: %s\n", AltosConvert.height.show(6, stats.max_gps_height)); + path_style_end(); + path_start("GPS Altitude", "gps"); + for (AltosGPSTimeValue gtv : series.gps_series) + write(gtv.gps, gtv.gps.alt); + path_end(); + if (series.state_series != null) { + for (AltosTimeValue tv : series.state_series) { + write_point(tv, true); + } } + folder_end(); + end(); } public AltosKML(File in_name) throws FileNotFoundException {