Update ao-view to add GPS satellite tracking data
authorKeith Packard <keithp@keithp.com>
Wed, 19 Aug 2009 06:38:16 +0000 (23:38 -0700)
committerKeith Packard <keithp@keithp.com>
Wed, 19 Aug 2009 06:38:28 +0000 (23:38 -0700)
This adds another column to the display to hold per-satellite GPS
tracking data and a count of the visible and locked sats.

Signed-off-by: Keith Packard <keithp@keithp.com>
ao-view/aoview.glade
ao-view/aoview.h
ao-view/aoview_monitor.c
ao-view/aoview_state.c
ao-view/aoview_table.c
src/ao_gps_print.c

index 3481a7798996367616bb7ad879014b0de0f999e2..9a7461108af227c299ed86860d017ce00521e328 100644 (file)
@@ -3,7 +3,7 @@
   <!-- interface-requires gtk+ 2.16 -->
   <!-- interface-naming-policy project-wide -->
   <widget class="GtkWindow" id="aoview">
-    <property name="width_request">550</property>
+    <property name="width_request">900</property>
     <property name="height_request">700</property>
     <property name="visible">True</property>
     <property name="title" translatable="yes">AltOS View</property>
                 <property name="position">1</property>
               </packing>
             </child>
+            <child>
+              <widget class="GtkTreeView" id="dataview_2">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="show_expanders">False</property>
+                <property name="enable_grid_lines">both</property>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
           </widget>
           <packing>
             <property name="position">2</property>
             <property name="layout_style">end</property>
             <child>
               <widget class="GtkButton" id="cancel_button">
-                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="label">gtk-cancel</property>
                 <property name="response_id">1</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
             </child>
             <child>
               <widget class="GtkButton" id="connect_button">
-                <property name="label" translatable="yes">gtk-connect</property>
+                <property name="label">gtk-connect</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
             <property name="layout_style">end</property>
             <child>
               <widget class="GtkButton" id="file_configure_cancel">
-                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="label">gtk-cancel</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
             </child>
             <child>
               <widget class="GtkButton" id="file_configure_ok">
-                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="label">gtk-ok</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
@@ -693,7 +704,7 @@ You should have received a copy of the GNU General Public License along with AoV
             <property name="layout_style">end</property>
             <child>
               <widget class="GtkButton" id="ao_replay_cancel">
-                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="label">gtk-cancel</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -708,7 +719,7 @@ You should have received a copy of the GNU General Public License along with AoV
             </child>
             <child>
               <widget class="GtkButton" id="ao_replay_ok">
-                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="label">gtk-ok</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
index e8334e5b2693388117036e8ddca79f6f206626ae..9ca65298b7a75839a6c3c2807cb4b1edefe4ad5f 100644 (file)
@@ -75,6 +75,26 @@ struct aogps {
        int     v_error;        /* m */
 };
 
+#define SIRF_SAT_STATE_ACQUIRED                        (1 << 0)
+#define SIRF_SAT_STATE_CARRIER_PHASE_VALID     (1 << 1)
+#define SIRF_SAT_BIT_SYNC_COMPLETE             (1 << 2)
+#define SIRF_SAT_SUBFRAME_SYNC_COMPLETE                (1 << 3)
+#define SIRF_SAT_CARRIER_PULLIN_COMPLETE       (1 << 4)
+#define SIRF_SAT_CODE_LOCKED                   (1 << 5)
+#define SIRF_SAT_ACQUISITION_FAILED            (1 << 6)
+#define SIRF_SAT_EPHEMERIS_AVAILABLE           (1 << 7)
+
+struct aogps_sat {
+       int     svid;
+       int     state;
+       int     c_n0;
+};
+
+struct aogps_tracking {
+       int                     channels;
+       struct aogps_sat        sats[12];
+};
+
 struct aodata {
        char    callsign[16];
        int     serial;
@@ -93,6 +113,7 @@ struct aodata {
        int     flight_pres;
        int     ground_pres;
        struct aogps    gps;
+       struct aogps_tracking   gps_tracking;
 };
 
 struct aostate {
@@ -121,6 +142,7 @@ struct aostate {
        double  max_speed;
 
        struct aogps    gps;
+       struct aogps_tracking   gps_tracking;
 
        int     gps_valid;
        double  pad_lat;
index 9265a1992ac439294dbec034e1b0b2ca0a204b84..1f4c8f728100f9627d2ddf735fcc96a1dc81c971 100644 (file)
@@ -47,6 +47,12 @@ aoview_parse_int(int *target, char *source)
        *target = strtol(source, NULL, 0);
 }
 
+static void
+aoview_parse_hex(int *target, char *source)
+{
+       *target = strtol(source, NULL, 16);
+}
+
 static void
 aoview_parse_pos(double *target, char *source)
 {
@@ -65,20 +71,23 @@ aoview_parse_pos(double *target, char *source)
        *target = r;
 }
 
+#define PARSE_MAX_WORDS        256
+
 gboolean
 aoview_monitor_parse(const char *input_line)
 {
        char *saveptr;
-       char *words[64];
+       char *words[PARSE_MAX_WORDS];
        int nword;
        char line_buf[8192], *line;
        struct aodata   data;
+       int     tracking_pos;
 
        /* avoid smashing our input parameter */
        strncpy (line_buf, input_line, sizeof (line_buf)-1);
        line_buf[sizeof(line_buf) - 1] = '\0';
        line = line_buf;
-       for (nword = 0; nword < 64; nword++) {
+       for (nword = 0; nword < PARSE_MAX_WORDS; nword++) {
                words[nword] = strtok_r(line, " \t\n", &saveptr);
                line = NULL;
                if (words[nword] == NULL)
@@ -112,6 +121,7 @@ aoview_monitor_parse(const char *input_line)
                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;
+               tracking_pos = 37;
        } else if (nword >= 40) {
                data.gps.gps_locked = 1;
                data.gps.gps_connected = 1;
@@ -119,6 +129,7 @@ aoview_monitor_parse(const char *input_line)
                aoview_parse_pos(&data.gps.lat, words[37]);
                aoview_parse_pos(&data.gps.lon, words[38]);
                sscanf(words[39], "%dm", &data.gps.alt);
+               tracking_pos = 46;
        } else {
                data.gps.gps_connected = 0;
                data.gps.gps_locked = 0;
@@ -143,6 +154,25 @@ aoview_monitor_parse(const char *input_line)
                data.gps.h_error = 0;
                data.gps.v_error = 0;
        }
+       if (nword >= tracking_pos + 2 && strcmp(words[tracking_pos], "SAT") == 0) {
+               int     c, n, pos;
+               aoview_parse_int(&n, words[tracking_pos + 1]);
+               pos = tracking_pos + 2;
+               if (nword >= pos + n * 3) {
+                       data.gps_tracking.channels = n;
+                       for (c = 0; c < n; c++) {
+                               aoview_parse_int(&data.gps_tracking.sats[c].svid,
+                                                words[pos + 0]);
+                               aoview_parse_hex(&data.gps_tracking.sats[c].state,
+                                                words[pos + 1]);
+                               aoview_parse_int(&data.gps_tracking.sats[c].c_n0,
+                                                words[pos + 2]);
+                               pos += 3;
+                       }
+               } else {
+                       data.gps_tracking.channels = 0;
+               }
+       }
        aoview_state_notify(&data);
        return TRUE;
 }
index 7efd33b0ebf5a62942a00a88e520c96c9b8d18f4..f75066dde24d64b5100f2d7d00481e660d9a4d82 100644 (file)
@@ -168,6 +168,8 @@ aoview_state_derive(struct aodata *data, struct aostate *state)
                        aoview_great_circle(state->pad_lat, state->pad_lon, state->gps.lat, state->gps.lon,
                                            &state->distance, &state->bearing);
        }
+       if (data->gps_tracking.channels)
+               state->gps_tracking = data->gps_tracking;
        if (state->npad) {
                state->gps_height = state->gps.alt - state->pad_alt;
        } else {
@@ -308,6 +310,7 @@ aoview_state_notify(struct aodata *data)
        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 altitude", "%d", state->gps.alt);
                aoview_table_add_row(1, "GPS height", "%d", state->gps_height);
                aoview_table_add_row(1, "GPS time", "%02d:%02d:%02d",
                                     state->gps.gps_time.hour,
@@ -330,6 +333,27 @@ aoview_state_notify(struct aodata *data)
                aoview_state_add_deg(1, "Pad longitude", state->pad_lon, 'E', 'W');
                aoview_table_add_row(1, "Pad GPS alt", "%gm", state->pad_alt);
        }
+       if (state->gps.gps_connected) {
+               int     nsat_vis = 0;
+               int     nsat_locked = 0;
+               int     c;
+
+               for (c = 0; c < state->gps_tracking.channels; c++) {
+                       if ((state->gps_tracking.sats[c].state & 0xff) == 0xbf)
+                               nsat_locked++;
+               }
+               aoview_table_add_row(2, "Satellites Visible", "%d", state->gps_tracking.channels);
+               aoview_table_add_row(2, "Satellites Locked", "%d", nsat_locked);
+               for (c = 0; c < state->gps_tracking.channels; c++) {
+                       aoview_table_add_row(2, "Satellite id,state,C/N0",
+                                            "%3d,%02x,%2d%s",
+                                            state->gps_tracking.sats[c].svid,
+                                            state->gps_tracking.sats[c].state,
+                                            state->gps_tracking.sats[c].c_n0,
+                                            (state->gps_tracking.sats[c].state & 0xff) == 0xbf ?
+                                            " LOCKED" : "");
+               }
+       }
        aoview_table_finish();
        aoview_label_show(state);
        aoview_speak_state(state);
index 931430096590a8d9f8337af717da980a11b5199a..e75ae670c8037c90520b121e8e0fd3d6363f7330 100644 (file)
@@ -17,7 +17,7 @@
 
 #include "aoview.h"
 
-#define NCOL   2
+#define NCOL   3
 
 static GtkTreeView     *dataview[NCOL];
 static GtkListStore    *datalist[NCOL];
index ba0ff68a09c2fb3aa6b317353df26c5c17b62b6c..cc75133728884550d1e092c8992ecfb6527cbb00 100644 (file)
@@ -102,7 +102,7 @@ ao_gps_tracking_print(__xdata struct ao_gps_tracking_data *gps_tracking_data) __
        printf("SAT ");
        n = gps_tracking_data->channels;
        if (n == 0) {
-               printf("not-connected\n");
+               printf("not-connected");
                return;
        }
        sat = gps_tracking_data->sats;
@@ -122,5 +122,4 @@ ao_gps_tracking_print(__xdata struct ao_gps_tracking_data *gps_tracking_data) __
                                sat->c_n_1);
                sat++;
        }
-       printf ("\n");
 }