X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=altoslib%2FAltosCSV.java;h=a08db23e5e938f9ebe53d93925300f9cc2c2ebab;hp=b38ed8dad3cdc3cfd1303e1a31347125d653f43c;hb=HEAD;hpb=97adfff4cfb67c17a96f3ff46606b4e439422b01 diff --git a/altoslib/AltosCSV.java b/altoslib/AltosCSV.java index b38ed8da..ffa4e37c 100644 --- a/altoslib/AltosCSV.java +++ b/altoslib/AltosCSV.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_11; +package org.altusmetrum.altoslib_14; import java.io.*; import java.util.*; @@ -26,18 +27,27 @@ public class AltosCSV implements AltosWriter { boolean header_written; boolean seen_boost; int boost_tick; - LinkedList pad_states; - AltosState state; - static boolean has_basic; - static boolean has_battery; - static boolean has_flight_state; - static boolean has_advanced; - static boolean has_gps; - static boolean has_gps_sat; - static boolean has_companion; - - static final int ALTOS_CSV_VERSION = 5; + boolean has_call; + boolean has_basic; + boolean has_accel; + boolean has_baro; + boolean has_pyro; + boolean has_radio; + boolean has_battery; + boolean has_flight_state; + boolean has_3d_accel; + boolean has_imu; + boolean has_igniter; + boolean has_gps; + boolean has_gps_sat; + boolean has_companion; + boolean has_motor_pressure; + + AltosFlightSeries series; + int[] indices; + + static final int ALTOS_CSV_VERSION = 6; /* Version 4 format: * @@ -47,7 +57,8 @@ public class AltosCSV implements AltosWriter { * flight number * callsign * time (seconds since boost) - * clock (tick count / 100) + * + * Radio info (if available) * rssi * link quality * @@ -79,6 +90,14 @@ public class AltosCSV implements AltosWriter { * mag_x (g) * mag_y (g) * mag_z (g) + * tilt (d) + * + * Extra igniter voltages (if available) + * pyro (V) + * igniter_a (V) + * igniter_b (V) + * igniter_c (V) + * igniter_d (V) * * GPS data (if available) * connected (1/0) @@ -113,75 +132,181 @@ public class AltosCSV implements AltosWriter { */ void write_general_header() { - out.printf("version,serial,flight,call,time,clock,rssi,lqi"); + out.printf(Locale.ROOT,"version,serial,flight"); + if (series.cal_data().callsign != null) + out.printf(Locale.ROOT,",call"); + out.printf(Locale.ROOT,",time"); + } + + double time() { + return series.time(indices); + } + + void write_general() { + out.printf(Locale.ROOT,"%s, %d, %d", + ALTOS_CSV_VERSION, + series.cal_data().serial, + series.cal_data().flight); + if (series.cal_data().callsign != null) + out.printf(Locale.ROOT,",%s", series.cal_data().callsign); + out.printf(Locale.ROOT,", %8.2f", time()); + } + + void write_radio_header() { + out.printf(Locale.ROOT,"rssi,lqi"); } - void write_general(AltosState state) { - out.printf("%s, %d, %d, %s, %8.2f, %8.2f, %4d, %3d", - ALTOS_CSV_VERSION, state.serial, state.flight, state.callsign, - (double) state.time_since_boost(), (double) state.tick / 100.0, - state.rssi, - state.status & 0x7f); + int rssi() { + return (int) series.value(AltosFlightSeries.rssi_name, indices); + } + + int status() { + return (int) series.value(AltosFlightSeries.status_name, indices); + } + + void write_radio() { + out.printf(Locale.ROOT,"%4d, %3d", + rssi(), status() & 0x7f); } void write_flight_header() { - out.printf("state,state_name"); + out.printf(Locale.ROOT,"state,state_name"); } - void write_flight(AltosState state) { - out.printf("%d,%8s", state.state(), state.state_name()); + int state() { + return (int) series.value(AltosFlightSeries.state_name, indices); + } + + void write_flight() { + int state = state(); + out.printf(Locale.ROOT,"%2d,%8s", state, AltosLib.state_name(state)); } void write_basic_header() { - out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,drogue_voltage,main_voltage"); + if (has_accel) + out.printf(Locale.ROOT,"acceleration,"); + if (has_baro) + out.printf(Locale.ROOT,"pressure,altitude,"); + out.printf(Locale.ROOT,"height,speed"); + if (has_baro) + out.printf(Locale.ROOT,",temperature"); + if (has_pyro) + out.printf(Locale.ROOT,",drogue_voltage,main_voltage"); } - void write_basic(AltosState state) { - out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f", - state.acceleration(), - state.pressure(), - state.altitude(), - state.height(), - state.speed(), - state.speed(), - state.temperature, - state.apogee_voltage, - state.main_voltage); + double acceleration() { return series.value(AltosFlightSeries.accel_name, indices); } + double pressure() { return series.value(AltosFlightSeries.pressure_name, indices); } + double altitude() { return series.value(AltosFlightSeries.altitude_name, indices); } + double height() { return series.value(AltosFlightSeries.height_name, indices); } + double speed() { return series.value(AltosFlightSeries.speed_name, indices); } + double temperature() { return series.value(AltosFlightSeries.temperature_name, indices); } + double apogee_voltage() { return series.value(AltosFlightSeries.apogee_voltage_name, indices); } + double main_voltage() { return series.value(AltosFlightSeries.main_voltage_name, indices); } + + void write_basic() { + if (has_accel) + out.printf(Locale.ROOT,"%8.2f,", acceleration()); + if (has_baro) + out.printf(Locale.ROOT,"%10.2f,%8.2f,", + pressure(), altitude()); + out.printf(Locale.ROOT,"%8.2f,%8.2f", + height(), speed()); + if (has_baro) + out.printf(Locale.ROOT,",%5.1f", temperature()); + if (has_pyro) + out.printf(Locale.ROOT,",%5.2f,%5.2f", + apogee_voltage(), + main_voltage()); } void write_battery_header() { - out.printf("battery_voltage"); + out.printf(Locale.ROOT,"battery_voltage"); } - void write_battery(AltosState state) { - out.printf("%5.2f", state.battery_voltage); + double battery_voltage() { return series.value(AltosFlightSeries.battery_voltage_name, indices); } + + void write_battery() { + out.printf(Locale.ROOT,"%5.2f", battery_voltage()); } - void write_advanced_header() { - out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z"); + void write_motor_pressure_header() { + out.printf(Locale.ROOT,"motor_pressure"); } - void write_advanced(AltosState state) { - out.printf("%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f", - state.accel_along(), state.accel_across(), state.accel_through(), - state.gyro_roll(), state.gyro_pitch(), state.gyro_yaw(), - state.mag_along(), state.mag_across(), state.mag_through()); + double motor_pressure() { return series.value(AltosFlightSeries.motor_pressure_name, indices); } + + void write_motor_pressure() { + out.printf(Locale.ROOT,"%10.1f", motor_pressure()); + } + + void write_3d_accel_header() { + out.printf(Locale.ROOT,"accel_x,accel_y,accel_z"); + } + + double accel_along() { return series.value(AltosFlightSeries.accel_along_name, indices); } + double accel_across() { return series.value(AltosFlightSeries.accel_across_name, indices); } + double accel_through() { return series.value(AltosFlightSeries.accel_through_name, indices); } + + void write_3d_accel() { + out.printf(Locale.ROOT,"%7.2f,%7.2f,%7.2f", + accel_along(), accel_across(), accel_through()); + } + + void write_imu_header() { + out.printf(Locale.ROOT,"gyro_roll,gyro_pitch,gyro_yaw,mag_x,mag_y,mag_z,tilt"); + } + + double gyro_roll() { return series.value(AltosFlightSeries.gyro_roll_name, indices); } + double gyro_pitch() { return series.value(AltosFlightSeries.gyro_pitch_name, indices); } + double gyro_yaw() { return series.value(AltosFlightSeries.gyro_yaw_name, indices); } + + double mag_along() { return series.value(AltosFlightSeries.mag_along_name, indices); } + double mag_across() { return series.value(AltosFlightSeries.mag_across_name, indices); } + double mag_through() { return series.value(AltosFlightSeries.mag_through_name, indices); } + + double tilt() { return series.value(AltosFlightSeries.orient_name, indices); } + + void write_imu() { + out.printf(Locale.ROOT,"%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f", + gyro_roll(), gyro_pitch(), gyro_yaw(), + mag_along(), mag_across(), mag_through(), + tilt()); + } + + void write_igniter_header() { + out.printf(Locale.ROOT,"pyro"); + for (int i = 0; i < series.igniter_voltage.length; i++) + out.printf(Locale.ROOT,",%s", AltosLib.igniter_short_name(i)); + } + + double pyro() { return series.value(AltosFlightSeries.pyro_voltage_name, indices); } + + double igniter_value(int channel) { return series.value(series.igniter_voltage_name(channel), indices); } + + void write_igniter() { + out.printf(Locale.ROOT,"%5.2f", pyro()); + for (int i = 0; i < series.igniter_voltage.length; i++) + out.printf(Locale.ROOT,",%5.2f", igniter_value(i)); } void write_gps_header() { - out.printf("connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,pdop,hdop,vdop"); + out.printf(Locale.ROOT,"connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,pdop,hdop,vdop"); } - void write_gps(AltosState state) { - AltosGPS gps = state.gps; - if (gps == null) - gps = new AltosGPS(); + void write_gps() { + AltosGPS gps = series.gps_before(series.time(indices)); - AltosGreatCircle from_pad = state.from_pad; - if (from_pad == null) + AltosGreatCircle from_pad; + + if (series.cal_data().gps_pad != null && gps != null) + from_pad = new AltosGreatCircle(series.cal_data().gps_pad, gps); + else from_pad = new AltosGreatCircle(); - out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f,%6.1f,%6.1f", + if (gps == null) + gps = new AltosGPS(); + + out.printf(Locale.ROOT,"%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f,%6.1f,%6.1f", gps.connected?1:0, gps.locked?1:0, gps.nsat, @@ -195,9 +320,9 @@ public class AltosCSV implements AltosWriter { gps.minute, gps.second, from_pad.distance, - state.range, + from_pad.range, from_pad.bearing, - state.elevation, + from_pad.elevation, gps.pdop, gps.hdop, gps.vdop); @@ -205,14 +330,14 @@ public class AltosCSV implements AltosWriter { void write_gps_sat_header() { for(int i = 1; i <= 32; i++) { - out.printf("sat%02d", i); + out.printf(Locale.ROOT,"sat%02d", i); if (i != 32) - out.printf(","); + out.printf(Locale.ROOT,","); } } - void write_gps_sat(AltosState state) { - AltosGPS gps = state.gps; + void write_gps_sat() { + AltosGPS gps = series.gps_before(series.time(indices)); for(int i = 1; i <= 32; i++) { int c_n0 = 0; if (gps != null && gps.cc_gps_sat != null) { @@ -224,125 +349,145 @@ public class AltosCSV implements AltosWriter { } out.printf ("%3d", c_n0); if (i != 32) - out.printf(","); + out.printf(Locale.ROOT,","); } } void write_companion_header() { - out.printf("companion_id,companion_time,companion_update,companion_channels"); +/* + out.printf(Locale.ROOT,"companion_id,companion_time,companion_update,companion_channels"); for (int i = 0; i < 12; i++) - out.printf(",companion_%02d", i); + out.printf(Locale.ROOT,",companion_%02d", i); +*/ } - void write_companion(AltosState state) { + void write_companion() { +/* AltosCompanion companion = state.companion; int channels_written = 0; if (companion == null) { - out.printf("0,0,0,0"); + out.printf(Locale.ROOT,"0,0,0,0"); } else { - out.printf("%3d,%5.2f,%5.2f,%2d", + out.printf(Locale.ROOT,"%3d,%5.2f,%5.2f,%2d", companion.board_id, (companion.tick - boost_tick) / 100.0, companion.update_period / 100.0, companion.channels); for (; channels_written < companion.channels; channels_written++) - out.printf(",%5d", companion.companion_data[channels_written]); + out.printf(Locale.ROOT,",%5d", companion.companion_data[channels_written]); } for (; channels_written < 12; channels_written++) - out.printf(",0"); + out.printf(Locale.ROOT,",0"); +*/ } void write_header() { - out.printf("#"); write_general_header(); + out.printf(Locale.ROOT,"#"); write_general_header(); + if (has_radio) { + out.printf(Locale.ROOT,","); + write_radio_header(); + } if (has_flight_state) { - out.printf(","); + out.printf(Locale.ROOT,","); write_flight_header(); } if (has_basic) { - out.printf(","); + out.printf(Locale.ROOT,","); write_basic_header(); } if (has_battery) { - out.printf(","); + out.printf(Locale.ROOT,","); write_battery_header(); } - if (has_advanced) { - out.printf(","); - write_advanced_header(); + if (has_motor_pressure) { + out.printf(Locale.ROOT,","); + write_motor_pressure_header(); + } + if (has_3d_accel) { + out.printf(Locale.ROOT,","); + write_3d_accel_header(); + } + if (has_imu) { + out.printf(Locale.ROOT,","); + write_imu_header(); + } + if (has_igniter) { + out.printf(Locale.ROOT,","); + write_igniter_header(); } if (has_gps) { - out.printf(","); + out.printf(Locale.ROOT,","); write_gps_header(); } if (has_gps_sat) { - out.printf(","); + out.printf(Locale.ROOT,","); write_gps_sat_header(); } if (has_companion) { - out.printf(","); + out.printf(Locale.ROOT,","); write_companion_header(); } out.printf ("\n"); } - void write_one(AltosState state) { - write_general(state); + void write_one() { + write_general(); + if (has_radio) { + out.printf(Locale.ROOT,","); + write_radio(); + } if (has_flight_state) { - out.printf(","); - write_flight(state); + out.printf(Locale.ROOT,","); + write_flight(); } if (has_basic) { - out.printf(","); - write_basic(state); + out.printf(Locale.ROOT,","); + write_basic(); } if (has_battery) { - out.printf(","); - write_battery(state); + out.printf(Locale.ROOT,","); + write_battery(); } - if (has_advanced) { - out.printf(","); - write_advanced(state); + if (has_motor_pressure) { + out.printf(Locale.ROOT,","); + write_motor_pressure(); + } + if (has_3d_accel) { + out.printf(Locale.ROOT,","); + write_3d_accel(); + } + if (has_imu) { + out.printf(Locale.ROOT,","); + write_imu(); + } + if (has_igniter) { + out.printf(Locale.ROOT,","); + write_igniter(); } if (has_gps) { - out.printf(","); - write_gps(state); + out.printf(Locale.ROOT,","); + write_gps(); } if (has_gps_sat) { - out.printf(","); - write_gps_sat(state); + out.printf(Locale.ROOT,","); + write_gps_sat(); } if (has_companion) { - out.printf(","); - write_companion(state); + out.printf(Locale.ROOT,","); + write_companion(); } out.printf ("\n"); } - private void flush_pad() { - while (!pad_states.isEmpty()) { - write_one (pad_states.remove()); - } - } - - private void write(AltosState state) { - if (state.state() == AltosLib.ao_flight_startup) + private void write() { + if (state() == AltosLib.ao_flight_startup) return; if (!header_written) { write_header(); header_written = true; } - if (!seen_boost) { - if (state.state() >= AltosLib.ao_flight_boost) { - seen_boost = true; - boost_tick = state.tick; - flush_pad(); - } - } - if (seen_boost) - write_one(state); - else - pad_states.add(state); + write_one(); } private PrintStream out() { @@ -350,48 +495,77 @@ public class AltosCSV implements AltosWriter { } public void close() { - if (!pad_states.isEmpty()) { - boost_tick = pad_states.element().tick; - flush_pad(); - } out.close(); } - public void write(AltosStateIterable states) { - states.write_comments(out()); + public void write(AltosFlightSeries series) { +// series.write_comments(out()); + + this.series = series; + + series.finish(); + has_radio = false; has_flight_state = false; has_basic = false; + has_accel = false; + has_baro = false; + has_pyro = false; has_battery = false; - has_advanced = false; + has_motor_pressure = false; + has_3d_accel = false; + has_imu = false; + has_igniter = false; has_gps = false; has_gps_sat = false; has_companion = false; - for (AltosState state : states) { - if (state.state() != AltosLib.ao_flight_stateless && state.state() != AltosLib.ao_flight_invalid && state.state() != AltosLib.ao_flight_startup) - has_flight_state = true; - if (state.acceleration() != AltosLib.MISSING || state.pressure() != AltosLib.MISSING) - has_basic = true; - if (state.battery_voltage != AltosLib.MISSING) - has_battery = true; - if (state.accel_across() != AltosLib.MISSING) - has_advanced = true; - if (state.gps != null) { - has_gps = true; - if (state.gps.cc_gps_sat != null) - has_gps_sat = true; - } - if (state.companion != null) - has_companion = true; + + if (series.has_series(AltosFlightSeries.rssi_name)) + has_radio = true; + if (series.has_series(AltosFlightSeries.state_name)) + has_flight_state = true; + if (series.has_series(AltosFlightSeries.accel_name)) { + has_basic = true; + has_accel = true; + } + if (series.has_series(AltosFlightSeries.pressure_name)) { + has_basic = true; + has_baro = true; + } + if (series.has_series(AltosFlightSeries.apogee_voltage_name)) + has_pyro = true; + if (series.has_series(AltosFlightSeries.battery_voltage_name)) + has_battery = true; + if (series.has_series(AltosFlightSeries.motor_pressure_name)) + has_motor_pressure = true; + if (series.has_series(AltosFlightSeries.accel_across_name)) + has_3d_accel = true; + if (series.has_series(AltosFlightSeries.gyro_roll_name)) + has_imu = true; + if (series.has_series(AltosFlightSeries.pyro_voltage_name)) + has_igniter = true; + + if (series.gps_series != null) + has_gps = true; + if (series.sats_in_view != null) + has_gps_sat = true; + /* + if (state.companion != null) + has_companion = true; + */ + + indices = series.indices(); + + for (;;) { + write(); + if (!series.step_indices(indices)) + break; } - for (AltosState state : states) - write(state); } public AltosCSV(PrintStream in_out, File in_name) { name = in_name; out = in_out; - pad_states = new LinkedList(); } public AltosCSV(File in_name) throws FileNotFoundException {