first cut at turnon scripts for EasyTimer v2
[fw/altos] / altoslib / AltosCSV.java
index edb23e69f93183eb80f31f7785cb31741d655ff0..ffa4e37c863abc15a3121c81b913ab896994ff7b 100644 (file)
@@ -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_8;
+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<AltosState>  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<AltosState>();
        }
 
        public AltosCSV(File in_name) throws FileNotFoundException {