Bump java lib versions to 13
[fw/altos] / micropeak / MicroData.java
index d3c8c43e634cefc0b79105e229a765c73906e5ed..96053ac55ca712c8e8c45f12441eff8ed5779c7d 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
@@ -20,59 +21,36 @@ package org.altusmetrum.micropeak;
 import java.lang.*;
 import java.io.*;
 import java.util.*;
-import org.altusmetrum.AltosLib.*;
-
-class MicroIterator implements Iterator<MicroDataPoint> {
-       int             i;
-       MicroData       data;
-
-       public boolean hasNext() {
-               return i < data.pressures.length;
-       }
-
-       public MicroDataPoint next() {
-               return new MicroDataPoint(data, i++);
-       }
-
-       public MicroIterator (MicroData data) {
-               this.data = data;
-               i = 0;
-       }
-
-       public void remove() {
-       }
-}
-
-class MicroIterable implements Iterable<MicroDataPoint> {
-
-       MicroData       data;
-
-       public Iterator<MicroDataPoint> iterator() {
-               return new MicroIterator(data);
-       }
-
-       public MicroIterable(MicroData data) {
-               this.data = data;
-       }
-}
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
 
 public class MicroData {
        public int              ground_pressure;
        public int              min_pressure;
-       public int[]            pressures;
+
+       AltosUIFlightSeries     flight_series;
+       AltosFlightStats        flight_stats;
+       AltosCalData            cal_data;
+
        private double          time_step;
-       private double          ground_altitude;
        private ArrayList<Integer>      bytes;
+       public int              log_id;
        String                  name;
-       
 
-       class FileEndedException extends Exception {
+       public static final int LOG_ID_MICROPEAK = 0;
+       public static final int LOG_ID_MICROKITE = 1;
+       public static final int LOG_ID_MICROPEAK2 = 2;
+
+       public static final double CLOCK_MP1 = 0.096;
+       public static final double CLOCK_MP2 = 0.1;
+
+       public class FileEndedException extends Exception {
        }
 
-       class NonHexcharException extends Exception {
+       public class NonHexcharException extends Exception {
        }
 
-       class InvalidCrcException extends Exception {
+       public class InvalidCrcException extends Exception {
        }
 
        private int getc(InputStream f) throws IOException, FileEndedException {
@@ -133,16 +111,12 @@ public class MicroData {
                return h;
        }
 
-       private boolean find_header(InputStream f) throws IOException {
-               try {
-                       for (;;) {
-                               if (get_nonwhite(f) == 'M' && get_nonwhite(f) == 'P')
-                                       return true;
-                       }
-               } catch (FileEndedException fe) {
-                       return false;
+       private boolean find_header(InputStream f) throws IOException, FileEndedException {
+               for (;;) {
+                       if (get_nonwhite(f) == 'M' && get_nonwhite(f) == 'P')
+                               return true;
                }
-       } 
+       }
 
        private int get_32(InputStream f)  throws IOException, FileEndedException, NonHexcharException {
                int     v = 0;
@@ -174,83 +148,75 @@ public class MicroData {
                return Math.abs (target - a) < Math.abs(target - b);
        }
 
-       public double altitude(int i) {
-               return AltosConvert.pressure_to_altitude(pressures[i]);
-       }
-
-       public Iterable<MicroDataPoint> points() {
-               return new MicroIterable(this);
+       public double altitude(double time) {
+               if (flight_series.altitude_series == null)
+                       return 0.0;
+               return flight_series.altitude_series.value(time);
        }
 
-       int fact(int n) {
-               if (n == 0)
-                       return 1;
-               return n * fact(n-1);
+       public double altitude(int i) {
+               return altitude(time(i));
        }
 
-       int choose(int n, int k) {
-               return fact(n) / (fact(k) * fact(n-k));
+       public String name() {
+               return name;
        }
 
+       public double pressure(int i) {
+               if (flight_series.pressure_series == null)
+                       return 0.0;
 
-       public double avg_altitude(int center, int dist) {
-               int     start = center - dist;
-               int     stop = center + dist;
-
-               if (start < 0)
-                       start = 0;
-               if (stop >= pressures.length)
-                       stop = pressures.length - 1;
-
-               double  sum = 0;
-               double  div = 0;
-
-               int     n = dist * 2;
-
-               for (int i = start; i <= stop; i++) {
-                       int     k = i - (center - dist);
-                       int     c = choose (n, k);
-
-                       sum += c * pressures[i];
-                       div += c;
-               }
+               return flight_series.pressure_series.value(time(i));
+       }
 
-               double pres = sum / div;
+       public double height(double time) {
+               if (flight_series.height_series == null)
+                       return 0.0;
 
-               double alt = AltosConvert.pressure_to_altitude(pres);
-               return alt;
+               return flight_series.height_series.value(time);
        }
 
-       public double pressure(int i) {
-               return pressures[i];
+       public double height(int i) {
+               return height(time(i));
        }
 
-       public double height(int i) {
-               return altitude(i) - ground_altitude;
+       public int length() {
+               if (flight_series.pressure_series == null)
+                       return 0;
+               return flight_series.pressure_series.size();
        }
 
-       static final int speed_avg = 3;
-       static final int accel_avg = 5;
+       /* Use the recorded apogee pressure for stats so that it agrees with the device */
+       public double apogee_pressure() {
+               return min_pressure;
+       }
 
-       private double avg_speed(int center, int dist) {
-               if (center == 0)
-                       return 0;
+       public double apogee_altitude() {
+               return AltosConvert.pressure_to_altitude(apogee_pressure());
+       }
 
-               double ai = avg_altitude(center, dist);
-               double aj = avg_altitude(center - 1, dist);
-               double s = (ai - aj) / time_step;
+       public double apogee_height() {
+               return apogee_altitude() - cal_data.ground_altitude;
+       }
 
-               return s;
+       public double speed(double time) {
+               if (flight_series.speed_series == null)
+                       return 0.0;
+               return flight_series.speed_series.value(time);
        }
 
        public double speed(int i) {
-               return avg_speed(i, speed_avg);
+               return speed(time(i));
+       }
+
+       public double acceleration(double time) {
+               if (flight_series.accel_series == null)
+                       return 0.0;
+               return flight_series.accel_series.value(time);
        }
 
        public double acceleration(int i) {
-               if (i == 0)
-                       return 0;
-               return (avg_speed(i, accel_avg) - avg_speed(i-1, accel_avg)) / time_step;
+               return acceleration(time(i));
        }
 
        public double time(int i) {
@@ -265,19 +231,25 @@ public class MicroData {
 
        public void export (Writer f) throws IOException {
                PrintWriter     pw = new PrintWriter(f);
-               pw.printf("  Time, Press(Pa), Height(m), Height(f), Speed(m/s), Speed(ft/s), Speed(mach), Accel(m/s²), Accel(ft/s²),  Accel(g)\n");
-               for (MicroDataPoint point : points()) {
-                       pw.printf("%6.3f,%10.0f,%10.1f,%10.1f,%11.2f,%12.2f,%12.4f,%12.2f,%13.2f,%10.4f\n",
-                                 point.time,
-                                 point.pressure,
-                                 point.height,
-                                 AltosConvert.meters_to_feet(point.height),
-                                 point.speed,
-                                 AltosConvert.meters_to_feet(point.speed),
-                                 AltosConvert.meters_to_mach(point.speed),
-                                 point.accel,
-                                 AltosConvert.meters_to_feet(point.accel),
-                                 AltosConvert.meters_to_g(point.accel));
+               pw.printf("  Time, Press(Pa), Height(m), Height(f), Speed(m/s), Speed(mph), Speed(mach), Accel(m/s²), Accel(ft/s²),  Accel(g)\n");
+
+               for (AltosTimeValue ptv : flight_series.pressure_series) {
+
+                       double height = height(ptv.time);
+                       double speed = speed(ptv.time);
+                       double accel = acceleration(ptv.time);
+
+                       pw.printf("%6.3f,%10.0f,%10.1f,%10.1f,%11.2f,%11.2f,%12.4f,%12.2f,%13.2f,%10.4f\n",
+                                 ptv.time,
+                                 ptv.value,
+                                 height,
+                                 AltosConvert.meters_to_feet(height),
+                                 speed,
+                                 AltosConvert.meters_to_mph(speed),
+                                 AltosConvert.meters_to_mach(speed),
+                                 accel,
+                                 AltosConvert.meters_to_feet(accel),
+                                 AltosConvert.meters_to_g(accel));
                }
        }
 
@@ -285,9 +257,20 @@ public class MicroData {
                this.name = name;
        }
 
-       public MicroData (InputStream f, String name) throws IOException, InterruptedException {
+       public MicroData() {
+               ground_pressure = 101000;
+               min_pressure = 101000;
+               cal_data = new AltosCalData();
+               flight_series = new AltosUIFlightSeries(cal_data);
+       }
+
+       public MicroData (InputStream f, String name) throws IOException, InterruptedException, NonHexcharException, FileEndedException {
                this.name = name;
                bytes = new ArrayList<Integer>();
+
+               cal_data = new AltosCalData();
+               flight_series = new AltosUIFlightSeries(cal_data);
+
                if (!find_header(f))
                        throw new IOException("No MicroPeak data header found");
                try {
@@ -295,11 +278,33 @@ public class MicroData {
                        ground_pressure = get_32(f);
                        min_pressure = get_32(f);
                        int nsamples = get_16(f);
-                       pressures = new int[nsamples + 1];
 
-                       ground_altitude = AltosConvert.pressure_to_altitude(ground_pressure);
+                       log_id = nsamples >> 12;
+                       nsamples &= 0xfff;
+
+                       cal_data.set_ground_pressure(ground_pressure);
+
+                       switch (log_id) {
+                       case LOG_ID_MICROPEAK:
+                               time_step = 2 * CLOCK_MP1;
+                               break;
+                       case LOG_ID_MICROKITE:
+                               time_step = 200 * CLOCK_MP1;
+                               break;
+                       case LOG_ID_MICROPEAK2:
+                               time_step = CLOCK_MP2;
+                               break;
+                       default:
+                               throw new IOException(String.format("Unknown device type: %d", log_id));
+                       }
+                       cal_data.set_ticks_per_sec(1/time_step);
+                       cal_data.set_tick(0);
+                       cal_data.set_boost_tick();
+
                        int cur = ground_pressure;
-                       pressures[0] = cur;
+                       cal_data.set_tick(0);
+                       flight_series.set_time(cal_data.time());
+                       flight_series.set_pressure(cur);
                        for (int i = 0; i < nsamples; i++) {
                                int     k = get_16(f);
                                int     same = mix_in(cur, k);
@@ -317,28 +322,43 @@ public class MicroData {
                                        else
                                                cur = down;
                                }
-                               
-                               pressures[i+1] = cur;
+
+                               cal_data.set_tick(i+1);
+                               flight_series.set_time(cal_data.time());
+                               flight_series.set_pressure(cur);
                        }
 
+                       flight_series.finish();
+
+                       /* Build states */
+
+                       flight_series.set_time(0);
+                       flight_series.set_state(AltosLib.ao_flight_boost);
+
+                       flight_series.set_time(flight_series.speed_series.max().time);
+                       flight_series.set_state(AltosLib.ao_flight_coast);
+
+                       flight_series.set_time(flight_series.height_series.max().time);
+                       flight_series.set_state(AltosLib.ao_flight_drogue);
+
+                       cal_data.set_tick(nsamples);
+                       flight_series.set_time(cal_data.time());
+                       flight_series.set_state(AltosLib.ao_flight_landed);
+
+                       flight_series.set_min_pressure(min_pressure);
+
+                       flight_series.finish();
+
+                       flight_stats = new AltosFlightStats(flight_series);
+
                        int current_crc = swap16(~file_crc & 0xffff);
                        int crc = get_16(f);
 
                        crc_valid = crc == current_crc;
 
-                       time_step = 0.192;
                } catch (FileEndedException fe) {
                        throw new IOException("File Ended Unexpectedly");
-               } catch (NonHexcharException ne) {
-                       throw new IOException("Non hexadecimal character found");
                }
        }
 
-       public MicroData() {
-               ground_pressure = 101000;
-               min_pressure = 101000;
-               pressures = new int[1];
-               pressures[0] = 101000;
-       }
-       
 }