Handle vageries of .telem files in ao-postflight
authorKeith Packard <keithp@keithp.com>
Sun, 6 Sep 2009 05:45:49 +0000 (22:45 -0700)
committerKeith Packard <keithp@keithp.com>
Sun, 6 Sep 2009 05:45:49 +0000 (22:45 -0700)
Telem files have multiple entries of the same state, and sometimes
long gaps between recordings. Deal with this as best as possible.

Signed-off-by: Keith Packard <keithp@keithp.com>
ao-tools/ao-postflight/ao-postflight.c
ao-tools/lib/cc-analyse.c
ao-tools/lib/cc-logfile.c
ao-tools/lib/cc.h

index f0e2c2ae235ab76697ccc8d9e2a365c5cfe66919..9371f35174ed2c8966ee1dff67439d421246d6a8 100644 (file)
@@ -81,43 +81,57 @@ analyse_flight(struct cc_flightraw *f)
 
        pres_i = cc_timedata_min(&f->pres, f->pres.data[0].time,
                                 f->pres.data[f->pres.num-1].time);
-       min_pres = f->pres.data[pres_i].value;
-       height = cc_barometer_to_altitude(min_pres) -
-               cc_barometer_to_altitude(f->ground_pres);
-       printf ("Max height: %9.2fm    %9.2fft %9.2fs\n",
-               height, height * 100 / 2.54 / 12,
-               (f->pres.data[pres_i].time - boost_start) / 100.0);
+       if (pres_i)
+       {
+               min_pres = f->pres.data[pres_i].value;
+               height = cc_barometer_to_altitude(min_pres) -
+                       cc_barometer_to_altitude(f->ground_pres);
+               printf ("Max height: %9.2fm    %9.2fft %9.2fs\n",
+                       height, height * 100 / 2.54 / 12,
+                       (f->pres.data[pres_i].time - boost_start) / 100.0);
+       }
 
        accel_i = cc_timedata_min(&f->accel, boost_start, boost_stop);
-       accel = cc_accelerometer_to_acceleration(f->accel.data[accel_i].value,
-                                                f->ground_accel);
-       printf ("Max accel:  %9.2fm/s² %9.2fg  %9.2fs\n",
-               accel, accel /  9.80665,
-               (f->accel.data[accel_i].time - boost_start) / 100.0);
+       if (accel_i)
+       {
+               accel = cc_accelerometer_to_acceleration(f->accel.data[accel_i].value,
+                                                        f->ground_accel);
+               printf ("Max accel:  %9.2fm/s² %9.2fg  %9.2fs\n",
+                       accel, accel /  9.80665,
+                       (f->accel.data[accel_i].time - boost_start) / 100.0);
+       }
        for (i = 0; i < f->state.num; i++) {
                state = f->state.data[i].value;
                state_start = f->state.data[i].time;
+               while (i < f->state.num - 1 && f->state.data[i+1].value == state)
+                       i++;
                if (i < f->state.num - 1)
-                       state_stop = f->state.data[i+1].time;
+                       state_stop = f->state.data[i + 1].time;
                else
                        state_stop = f->accel.data[f->accel.num-1].time;
                printf("State: %s\n", state_names[state]);
                printf("\tStart:      %9.2fs\n", (state_start - boost_start) / 100.0);
                printf("\tDuration:   %9.2fs\n", (state_stop - state_start) / 100.0);
                accel_i = cc_timedata_min(&f->accel, state_start, state_stop);
-               accel = cc_accelerometer_to_acceleration(f->accel.data[accel_i].value,
-                                                        f->ground_accel);
-               printf("\tMax accel:  %9.2fm/s² %9.2fg  %9.2fs\n",
-                      accel, accel / 9.80665,
-                      (f->accel.data[accel_i].time - boost_start) / 100.0);
+               if (accel_i >= 0)
+               {
+                       accel = cc_accelerometer_to_acceleration(f->accel.data[accel_i].value,
+                                                                f->ground_accel);
+                       printf("\tMax accel:  %9.2fm/s² %9.2fg  %9.2fs\n",
+                              accel, accel / 9.80665,
+                              (f->accel.data[accel_i].time - boost_start) / 100.0);
+               }
 
                pres_i = cc_timedata_min(&f->pres, state_start, state_stop);
-               min_pres = f->pres.data[pres_i].value;
-               height = cc_barometer_to_altitude(min_pres) -
-                       cc_barometer_to_altitude(f->ground_pres);
-               printf ("\tMax height: %9.2fm    %9.2fft %9.2fs\n",
-                       height, height * 100 / 2.54 / 12,
-                       (f->pres.data[pres_i].time - boost_start) / 100.0);
+               if (pres_i >= 0)
+               {
+                       min_pres = f->pres.data[pres_i].value;
+                       height = cc_barometer_to_altitude(min_pres) -
+                               cc_barometer_to_altitude(f->ground_pres);
+                       printf ("\tMax height: %9.2fm    %9.2fft %9.2fs\n",
+                               height, height * 100 / 2.54 / 12,
+                               (f->pres.data[pres_i].time - boost_start) / 100.0);
+               }
        }
 }
 
index 6fd36cdc9007bd50b3e6311c8b52fefc1306de22..fc8a8417bd3d6cba210be05eccea23ac0ede12d9 100644 (file)
@@ -22,11 +22,11 @@ cc_timedata_min(struct cc_timedata *d, double min_time, double max_time)
 {
        int     i;
        int     set = 0;
-       int     min_i;
+       int     min_i = -1;
        double  min;
 
        if (d->num == 0)
-               return 0;
+               return -1;
        for (i = 0; i < d->num; i++)
                if (min_time <= d->data[i].time && d->data[i].time <= max_time)
                        if (!set || d->data[i].value < min) {
@@ -42,11 +42,11 @@ cc_timedata_max(struct cc_timedata *d, double min_time, double max_time)
 {
        int     i;
        double  max;
-       int     max_i;
+       int     max_i = -1;
        int     set = 0;
 
        if (d->num == 0)
-               return 0;
+               return -1;
        for (i = 0; i < d->num; i++)
                if (min_time <= d->data[i].time && d->data[i].time <= max_time)
                        if (!set || d->data[i].value > max) {
index 444ff0892ebd195236dc9719592f8c1575dcc865..4abf7eb6341189263898e488cd399e43835f48ac 100644 (file)
@@ -18,6 +18,7 @@
 #include "cc.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 static int
 timedata_add(struct cc_timedata *data, double time, double value)
@@ -35,8 +36,11 @@ timedata_add(struct cc_timedata *data, double time, double value)
                data->size = newsize;
                data->data = newdata;
        }
-       if (data->num && data->data[data->num-1].time > time)
+       time += data->time_offset;
+       if (data->num && data->data[data->num-1].time > time) {
+               data->time_offset += 65536;
                time += 65536;
+       }
        data->data[data->num].time = time;
        data->data[data->num].value = value;
        data->num++;
@@ -66,6 +70,11 @@ gpsdata_add(struct cc_gpsdata *data, struct cc_gpselt *elt)
                data->size = newsize;
                data->data = newdata;
        }
+       elt->time += data->time_offset;
+       if (data->num && data->data[data->num-1].time > elt->time) {
+               data->time_offset += 65536;
+               elt->time += 65536;
+       }
        data->data[data->num] = *elt;
        data->num++;
        return 1;
@@ -156,6 +165,29 @@ read_eeprom(const char *line, struct cc_flightraw *f, double *ground_pres, int *
        return 1;
 }
 
+static const char *state_names[] = {
+       "startup",
+       "idle",
+       "pad",
+       "boost",
+       "fast",
+       "coast",
+       "drogue",
+       "main",
+       "landed",
+       "invalid"
+};
+
+static enum ao_flight_state
+state_name_to_state(char *state_name)
+{
+       enum ao_flight_state    state;
+       for (state = ao_flight_startup; state < ao_flight_invalid; state++)
+               if (!strcmp(state_names[state], state_name))
+                       return state;
+       return ao_flight_invalid;
+}
+
 static int
 read_telem(const char *line, struct cc_flightraw *f)
 {
@@ -172,6 +204,7 @@ read_telem(const char *line, struct cc_flightraw *f)
        timedata_add(&f->volt, telem.tick, telem.batt);
        timedata_add(&f->drogue, telem.tick, telem.drogue);
        timedata_add(&f->main, telem.tick, telem.main);
+       timedata_add(&f->state, telem.tick, state_name_to_state(telem.state));
        if (telem.gps.gps_locked) {
                gps.time = telem.tick;
                gps.lat = telem.gps.lat;
index 3975cf1b46d8c470cc4debe3670f78bc441278e4..57f80b8d5e938220e709c4eb6026ee4ba9481404 100644 (file)
@@ -75,6 +75,7 @@ struct cc_timedata {
        int                     num;
        int                     size;
        struct cc_timedataelt   *data;
+       double                  time_offset;
 };
 
 
@@ -92,8 +93,8 @@ struct cc_gpselt {
 struct cc_gpsdata {
        int                     num;
        int                     size;
-       double                  time_offset;
        struct cc_gpselt        *data;
+       double                  time_offset;
 };
 
 /*