X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=altoslib%2FAltosKML.java;h=131bdf4982584c8240fd6d25fb93e0b7905cf44f;hp=ac5e0257cec482e7bc9ba2980cbd8dd7ad5d6c6a;hb=ec46adee44ea08120b1940ca55a5fbdf56874bb1;hpb=21d176f161b90f18f236ef887cef9676d712eee3 diff --git a/altoslib/AltosKML.java b/altoslib/AltosKML.java index ac5e0257..131bdf49 100644 --- a/altoslib/AltosKML.java +++ b/altoslib/AltosKML.java @@ -3,7 +3,8 @@ * * 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. + * 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 @@ -15,7 +16,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_10; +package org.altusmetrum.altoslib_14; import java.io.*; import java.util.*; @@ -35,17 +36,20 @@ public class AltosKML implements AltosWriter { File name; PrintWriter out; int flight_state = -1; - AltosState prev = null; - double gps_start_altitude; + 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 @@ -58,84 +62,173 @@ 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 (AltosState record) { - 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 state_start(AltosState state) { - String state_name = AltosLib.state_name(state.state()); - String state_color = state_color(state.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 path_style_end() { + out.printf(kml_path_style_end); } - void state_end(AltosState state) { - out.printf("%s", kml_placemark_end); + void point_style_start(String style, String color) { + out.printf(kml_point_style_start, style, color, color); } - void coord(AltosState state) { - AltosGPS gps = state.gps; - double altitude; + void point_style_end() { + out.printf(kml_point_style_end); + } + + void path_start(String name, String style) { + out.printf(kml_path_start, name, style); + } - if (state.height() != AltosLib.MISSING) - altitude = state.height() + gps_start_altitude; - else - altitude = gps.alt; + 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, - state.time, gps.nsat); + time, gps.nsat); } void end() { @@ -143,51 +236,111 @@ public class AltosKML implements AltosWriter { } public void close() { - if (prev != null) { - state_end(prev); - end(); - prev = null; - } if (out != null) { out.close(); out = null; } } - public void write(AltosState state) { - AltosGPS gps = state.gps; - + 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 (alt == AltosLib.MISSING) { + alt = cal_data.gps_pad_altitude; + if (alt == AltosLib.MISSING) + return; } - if (prev != null && prev.gps_sequence == state.gps_sequence) - return; - if (state.state() != flight_state) { - flight_state = state.state(); - if (prev != null) { - coord(state); - state_end(prev); - } - state_start(state); + coord(0, gps, alt); + prev = gps; + } + + 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); + + 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; } - coord(state); - prev = state; + point_style_end(); + point_start(full_name, style_name); + gps = series.gps_before(tv.time); + write(gps, altitude); + point_end(); } - public void write(AltosStateIterable states) { - for (AltosState state : states) { - if ((state.set & AltosState.set_gps) != 0) - write(state); + public void write(AltosFlightSeries series) { + 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 {