From d7c2d358ed8a1afc9f0ba2bd830b10f6b56dc7b1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 Jul 2009 00:44:42 -0700 Subject: [PATCH] Display last known GPS coord while unlocked Signed-off-by: Keith Packard --- aoview/aoview.h | 47 ++++++++++++++----------- aoview/aoview_monitor.c | 60 ++++++++++++++++---------------- aoview/aoview_state.c | 77 ++++++++++++++++++++++------------------- 3 files changed, 100 insertions(+), 84 deletions(-) diff --git a/aoview/aoview.h b/aoview/aoview.h index 4ed0ffab..62d0640b 100644 --- a/aoview/aoview.h +++ b/aoview/aoview.h @@ -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; diff --git a/aoview/aoview_monitor.c b/aoview/aoview_monitor.c index dd0e6019..9265a199 100644 --- a/aoview/aoview_monitor.c +++ b/aoview/aoview_monitor.c @@ -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; diff --git a/aoview/aoview_state.c b/aoview/aoview_state.c index a0a608e0..9852cabd 100644 --- a/aoview/aoview_state.c +++ b/aoview/aoview_state.c @@ -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); -- 2.30.2