X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=altoslib%2FAltosKML.java;h=4738ac9104925fab8af6eefb57f5a7a214dd600a;hp=587b845bb7ac68cef04bd1c7b024e2ef63a22486;hb=730ee7bf91f607ece42c010a10c53d0013492b96;hpb=98dc29a7a964f8d653b73989c6751695d168844c diff --git a/altoslib/AltosKML.java b/altoslib/AltosKML.java index 587b845b..4738ac91 100644 --- a/altoslib/AltosKML.java +++ b/altoslib/AltosKML.java @@ -38,16 +38,18 @@ public class AltosKML implements AltosWriter { int flight_state = -1; AltosGPS prev = null; 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 @@ -60,85 +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_placemark_end = - " \n" + - " \n" + - " \n"; + static final String kml_path_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 (AltosCalData cal_data) { + 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("Date: %04d-%02d-%02d\n", + 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", + 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 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("State: %s\n", state_name); - out.printf("Time: %6.2f s\n", stats.state_time[state]); - out.printf("Average speed: %s\n", AltosConvert.speed.show(6, stats.state_speed[state])); - out.printf("Average accel: %s\n", AltosConvert.accel.show(6, stats.state_accel[state])); - out.printf("%s", kml_style_end); - out.printf(kml_placemark_start, state_name, state_name); + void folder_end() { + out.printf(kml_folder_end); } - void state_end() { - out.printf("%s", kml_placemark_end); + void path_style_start(String style, String color) { + out.printf(kml_path_style_start, style, color); } - void coord(double time, AltosGPS gps, int state, double height) { - double altitude; + 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); + } - if (height != AltosLib.MISSING) - altitude = height + gps_start_altitude; - else - altitude = gps.alt; + void path_start(String name, String style) { + out.printf(kml_path_start, name, style); + } + + void path_end() { + out.printf(kml_path_end); + } + + void point_start(String name, String style) { + out.printf(kml_point_start, name, style); + } + + void point_end() { + out.printf(kml_point_end); + } + + 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; + + 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, @@ -150,48 +236,103 @@ 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(AltosGPSTimeValue gtv, AltosCalData cal_data, int state, double height) { - AltosGPS gps = gtv.gps; + public void write(AltosGPS gps, double alt) + { if (gps.lat == AltosLib.MISSING) return; if (gps.lon == AltosLib.MISSING) return; - if (state != flight_state) { - flight_state = state; - if (prev != null) { - coord(gtv.time, 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) { - return (int) series.value_before(AltosFlightSeries.state_name, time); - } + 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) { - return series.value(AltosFlightSeries.height_name, time); + 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; + } + 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) { + this.series = series; + series.finish(); stats = new AltosFlightStats(series); - start(series.cal_data()); + cal_data = series.cal_data(); + start(); + 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, series.cal_data(), state(series, gtv.time), height(series, gtv.time)); + write(gtv.gps, baro_altitude(series, gtv.time)); + path_end(); + 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(); + for (AltosTimeValue tv : series.state_series) { + write_point(tv, true); + } + folder_end(); + end(); } public AltosKML(File in_name) throws FileNotFoundException {