Display last known GPS coord while unlocked
authorKeith Packard <keithp@keithp.com>
Sat, 18 Jul 2009 07:44:42 +0000 (00:44 -0700)
committerKeith Packard <keithp@keithp.com>
Sat, 18 Jul 2009 07:44:42 +0000 (00:44 -0700)
Signed-off-by: Keith Packard <keithp@keithp.com>
aoview/aoview.h
aoview/aoview_monitor.c
aoview/aoview_state.c

index 4ed0ffaba51804005c83fd05a42ba7419c06f137..62d0640b9a182b42101263cea45ff3a1936729b6 100644 (file)
@@ -51,6 +51,30 @@ struct usbdev {
        int     idVendor;
 };
 
+struct aogps_time {
+       int hour;
+       int minute;
+       int second;
+};
+
+struct aogps {
+       int     nsat;
+       int     gps_locked;
+       int     gps_connected;
+       struct aogps_time gps_time;
+       double  lat;            /* degrees (+N -S) */
+       double  lon;            /* degrees (+E -W) */
+       int     alt;            /* m */
+
+       int     gps_extended;   /* has extra data */
+       double  ground_speed;   /* m/s */
+       int     course;         /* degrees */
+       double  climb_rate;     /* m/s */
+       double  hdop;           /* unitless? */
+       int     h_error;        /* m */
+       int     v_error;        /* m */
+};
+
 struct aodata {
        char    callsign[16];
        int     serial;
@@ -68,23 +92,7 @@ struct aodata {
        int     flight_vel;
        int     flight_pres;
        int     ground_pres;
-       int     nsat;
-       int     gps_locked;
-       int     gps_connected;
-       struct {
-               int hour;
-               int minute;
-               int second;
-       } gps_time;
-       double  lat;            /* degrees (+N -S) */
-       double  lon;            /* degrees (+E -W) */
-       int     alt;            /* m */
-       double  ground_speed;   /* m/s */
-       int     course;         /* degrees */
-       double  climb_rate;     /* m/s */
-       double  hdop;           /* unitless? */
-       int     h_error;        /* m */
-       int     v_error;        /* m */
+       struct aogps    gps;
 };
 
 struct aostate {
@@ -112,10 +120,9 @@ struct aostate {
        double  max_acceleration;
        double  max_speed;
 
-       double  lat;
-       double  lon;
-       int     gps_valid;
+       struct aogps    gps;
 
+       int     gps_valid;
        double  pad_lat;
        double  pad_lon;
        double  pad_alt;
index dd0e60196515924eccc7a65e80859fa6a9a99624..9265a1992ac439294dbec034e1b0b2ca0a204b84 100644 (file)
@@ -105,41 +105,43 @@ aoview_monitor_parse(const char *input_line)
        aoview_parse_int(&data.flight_vel, words[28]);
        aoview_parse_int(&data.flight_pres, words[30]);
        aoview_parse_int(&data.ground_pres, words[32]);
-       aoview_parse_int(&data.nsat, words[34]);
+       aoview_parse_int(&data.gps.nsat, words[34]);
        if (strcmp (words[36], "unlocked") == 0) {
-               data.gps_connected = 1;
-               data.gps_locked = 0;
-               data.gps_time.hour = data.gps_time.minute = data.gps_time.second = 0;
-               data.lat = data.lon = 0;
-               data.alt = 0;
+               data.gps.gps_connected = 1;
+               data.gps.gps_locked = 0;
+               data.gps.gps_time.hour = data.gps.gps_time.minute = data.gps.gps_time.second = 0;
+               data.gps.lat = data.gps.lon = 0;
+               data.gps.alt = 0;
        } else if (nword >= 40) {
-               data.gps_locked = 1;
-               data.gps_connected = 1;
-               sscanf(words[36], "%d:%d:%d", &data.gps_time.hour, &data.gps_time.minute, &data.gps_time.second);
-               aoview_parse_pos(&data.lat, words[37]);
-               aoview_parse_pos(&data.lon, words[38]);
-               sscanf(words[39], "%dm", &data.alt);
+               data.gps.gps_locked = 1;
+               data.gps.gps_connected = 1;
+               sscanf(words[36], "%d:%d:%d", &data.gps.gps_time.hour, &data.gps.gps_time.minute, &data.gps.gps_time.second);
+               aoview_parse_pos(&data.gps.lat, words[37]);
+               aoview_parse_pos(&data.gps.lon, words[38]);
+               sscanf(words[39], "%dm", &data.gps.alt);
        } else {
-               data.gps_connected = 0;
-               data.gps_locked = 0;
-               data.gps_time.hour = data.gps_time.minute = data.gps_time.second = 0;
-               data.lat = data.lon = 0;
-               data.alt = 0;
+               data.gps.gps_connected = 0;
+               data.gps.gps_locked = 0;
+               data.gps.gps_time.hour = data.gps.gps_time.minute = data.gps.gps_time.second = 0;
+               data.gps.lat = data.gps.lon = 0;
+               data.gps.alt = 0;
        }
        if (nword >= 46) {
-               sscanf(words[40], "%lfm/s", &data.ground_speed);
-               sscanf(words[41], "%d", &data.course);
-               sscanf(words[42], "%lfm/s", &data.climb_rate);
-               sscanf(words[43], "%lf", &data.hdop);
-               sscanf(words[44], "%d", &data.h_error);
-               sscanf(words[45], "%d", &data.v_error);
+               data.gps.gps_extended = 1;
+               sscanf(words[40], "%lfm/s", &data.gps.ground_speed);
+               sscanf(words[41], "%d", &data.gps.course);
+               sscanf(words[42], "%lfm/s", &data.gps.climb_rate);
+               sscanf(words[43], "%lf", &data.gps.hdop);
+               sscanf(words[44], "%d", &data.gps.h_error);
+               sscanf(words[45], "%d", &data.gps.v_error);
        } else {
-               data.ground_speed = 0;
-               data.course = 0;
-               data.climb_rate = 0;
-               data.hdop = 0;
-               data.h_error = 0;
-               data.v_error = 0;
+               data.gps.gps_extended = 0;
+               data.gps.ground_speed = 0;
+               data.gps.course = 0;
+               data.gps.climb_rate = 0;
+               data.gps.hdop = 0;
+               data.gps.h_error = 0;
+               data.gps.v_error = 0;
        }
        aoview_state_notify(&data);
        return TRUE;
index a0a608e0b8804851bdf0efa720fabb78ac6eed51..9852cabd257633687bbe691ce2db0a64fcca86ab 100644 (file)
@@ -130,19 +130,19 @@ aoview_state_derive(struct aodata *data, struct aostate *state)
        state->main_sense = data->main / 32767.0 * 15.0;
        state->battery = data->batt / 32767.0 * 5.0;
        if (!strcmp(data->state, "pad")) {
-               if (data->gps_locked && data->nsat >= 4) {
+               if (data->gps.gps_locked && data->gps.nsat >= 4) {
                        state->npad++;
-                       state->pad_lat_total += data->lat;
-                       state->pad_lon_total += data->lon;
-                       state->pad_alt_total += data->alt;
+                       state->pad_lat_total += data->gps.lat;
+                       state->pad_lon_total += data->gps.lon;
+                       state->pad_alt_total += data->gps.alt;
                        if (state->npad > 1) {
-                               state->pad_lat = (state->pad_lat * 31 + data->lat) / 32.0;
-                               state->pad_lon = (state->pad_lon * 31 + data->lon) / 32.0;
-                               state->pad_alt = (state->pad_alt * 31 + data->alt) / 32.0;
+                               state->pad_lat = (state->pad_lat * 31 + data->gps.lat) / 32.0;
+                               state->pad_lon = (state->pad_lon * 31 + data->gps.lon) / 32.0;
+                               state->pad_alt = (state->pad_alt * 31 + data->gps.alt) / 32.0;
                        } else {
-                               state->pad_lat = data->lat;
-                               state->pad_lon = data->lon;
-                               state->pad_alt = data->alt;
+                               state->pad_lat = data->gps.lat;
+                               state->pad_lon = data->gps.lon;
+                               state->pad_alt = data->gps.alt;
                        }
                }
        }
@@ -159,15 +159,17 @@ aoview_state_derive(struct aodata *data, struct aostate *state)
 
        if (state->height > state->max_height)
                state->max_height = state->height;
-       if (data->gps_locked) {
-               state->lat = data->lat;
-               state->lon = data->lon;
-               aoview_great_circle(state->pad_lat, state->pad_lon, data->lat, data->lon,
-                                   &state->distance, &state->bearing);
+       state->gps.gps_locked = data->gps.gps_locked;
+       state->gps.gps_connected = data->gps.gps_connected;
+       if (data->gps.gps_locked) {
+               state->gps = data->gps;
                state->gps_valid = 1;
+               if (state->npad)
+                       aoview_great_circle(state->pad_lat, state->pad_lon, state->gps.lat, state->gps.lon,
+                                           &state->distance, &state->bearing);
        }
        if (state->npad) {
-               state->gps_height = data->alt - state->pad_alt;
+               state->gps_height = state->gps.alt - state->pad_alt;
        } else {
                state->gps_height = 0;
        }
@@ -249,7 +251,7 @@ aoview_state_timeout(gpointer data)
                                aoview_voice_speak("rocket landed safely\n");
                        else
                                aoview_voice_speak("rocket may have crashed\n");
-                       if (aostate.gps_valid) {
+                       if (aostate.gps.gps_connected) {
                                aoview_voice_speak("rocket reported %s of pad distance %d meters\n",
                                                   aoview_compass_point(aostate.bearing),
                                                   (int) aostate.distance);
@@ -295,30 +297,35 @@ aoview_state_notify(struct aodata *data)
        aoview_table_add_row(0, "Drogue", "%5.2fV", state->drogue_sense);
        aoview_table_add_row(0, "Main", "%5.2fV", state->main_sense);
        aoview_table_add_row(0, "Pad altitude", "%dm", state->ground_altitude);
-       aoview_table_add_row(1, "Satellites", "%d", state->data.nsat);
-       if (state->data.gps_locked) {
-               aoview_state_add_deg(1, "Latitude", state->data.lat, 'N', 'S');
-               aoview_state_add_deg(1, "Longitude", state->data.lon, 'E', 'W');
+       aoview_table_add_row(1, "Satellites", "%d", state->gps.nsat);
+       if (state->gps.gps_locked) {
+               aoview_table_add_row(1, "GPS", "locked");
+       } else if (state->gps.gps_connected) {
+               aoview_table_add_row(1, "GPS", "unlocked");
+       } else {
+               aoview_table_add_row(1, "GPS", "not available");
+       }
+       if (state->gps_valid) {
+               aoview_state_add_deg(1, "Latitude", state->gps.lat, 'N', 'S');
+               aoview_state_add_deg(1, "Longitude", state->gps.lon, 'E', 'W');
                aoview_table_add_row(1, "GPS height", "%d", state->gps_height);
                aoview_table_add_row(1, "GPS time", "%02d:%02d:%02d",
-                                    state->data.gps_time.hour,
-                                    state->data.gps_time.minute,
-                                    state->data.gps_time.second);
+                                    state->gps.gps_time.hour,
+                                    state->gps.gps_time.minute,
+                                    state->gps.gps_time.second);
+       }
+       if (state->gps.gps_extended) {
                aoview_table_add_row(1, "GPS ground speed", "%7.1fm/s %d°",
-                                    state->data.ground_speed,
-                                    state->data.course);
+                                    state->gps.ground_speed,
+                                    state->gps.course);
                aoview_table_add_row(1, "GPS climb rate", "%7.1fm/s",
-                                    state->data.climb_rate);
-               aoview_table_add_row(1, "GPS precision", "%f(hdop) %dm(h) %dm(v)\n",
-                                    state->data.hdop, state->data.h_error, state->data.v_error);
-               aoview_table_add_row(1, "Distance from pad", "%5.0fm", state->distance);
-               aoview_table_add_row(1, "Direction from pad", "%4.0f°", state->bearing);
-       } else if (state->data.gps_connected) {
-               aoview_table_add_row(1, "GPS", "unlocked");
-       } else {
-               aoview_table_add_row(1, "GPS", "not available");
+                                    state->gps.climb_rate);
+               aoview_table_add_row(1, "GPS precision", "%4.1f(hdop) %3dm(h) %3dm(v)",
+                                    state->gps.hdop, state->gps.h_error, state->gps.v_error);
        }
        if (state->npad) {
+               aoview_table_add_row(1, "Distance from pad", "%5.0fm", state->distance);
+               aoview_table_add_row(1, "Direction from pad", "%4.0f°", state->bearing);
                aoview_state_add_deg(1, "Pad latitude", state->pad_lat, 'N', 'S');
                aoview_state_add_deg(1, "Pad longitude", state->pad_lon, 'E', 'W');
                aoview_table_add_row(1, "Pad GPS alt", "%gm", state->pad_alt);