altos: New telemetry report format (version 4). Supports tiny telemetry.
authorKeith Packard <keithp@keithp.com>
Sun, 20 Mar 2011 06:53:08 +0000 (23:53 -0700)
committerKeith Packard <keithp@keithp.com>
Sun, 20 Mar 2011 06:55:11 +0000 (23:55 -0700)
This completely replaces the version 3 format with a much simpler and
easier to parse scheme. It's described in detail in ao_telem.h, but
the basic idea is that the whole line is split into name/value pairs,
separated by whitespace. Every name is unique, and the values are
either strings or integers. No extraneous formatting or units are
provided.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/ao.h
src/ao_gps_print.c
src/ao_gps_sirf.c
src/ao_gps_test.c
src/ao_gps_test_skytraq.c
src/ao_monitor.c
src/ao_telem.h [new file with mode: 0644]

index 0ba98dbda4fe2ea9c2684fea7e3e3c5f4220c92d..527390b05bc90e87b95d4a128476f29f914c789c 100644 (file)
--- a/src/ao.h
+++ b/src/ao.h
@@ -841,6 +841,7 @@ ao_spi_init(void);
 #define AO_GPS_VALID           (1 << 4)
 #define AO_GPS_RUNNING         (1 << 5)
 #define AO_GPS_DATE_VALID      (1 << 6)
+#define AO_GPS_COURSE_VALID    (1 << 7)
 
 extern __xdata uint16_t ao_gps_tick;
 
@@ -905,8 +906,7 @@ ao_gps_report_init(void);
  * ao_telemetry.c
  */
 
-#define AO_MAX_CALLSIGN                8
-#define AO_TELEMETRY_VERSION   3
+#define AO_MAX_CALLSIGN                        8
 
 struct ao_telemetry {
        uint16_t                serial;
@@ -1020,6 +1020,10 @@ extern const char const * const ao_state_names[];
 void
 ao_monitor(void);
 
+#define AO_MONITORING_OFF      0
+#define AO_MONITORING_FULL     1
+#define AO_MONITORING_TINY     2
+
 void
 ao_set_monitor(uint8_t monitoring);
 
index 11213174be357b97ac43aa18dbc74489a4fe362f..ca071b42be360f7b21157854eac6c35af8fd76d5 100644 (file)
 #ifndef AO_GPS_TEST
 #include "ao.h"
 #endif
-
-struct ao_gps_split {
-       uint8_t positive;
-       uint8_t degrees;
-       uint8_t minutes;
-       uint16_t minutes_fraction;
-};
-
-static void
-ao_gps_split(int32_t v, __xdata struct ao_gps_split *split) __reentrant
-{
-       uint32_t minutes_e7;
-
-       split->positive = 1;
-       if (v < 0) {
-               v = -v;
-               split->positive = 0;
-       }
-       split->degrees = v / 10000000;
-       minutes_e7 = (v % 10000000) * 60;
-       split->minutes = minutes_e7 / 10000000;
-       split->minutes_fraction = (minutes_e7 % 10000000) / 1000;
-}
+#include "ao_telem.h"
 
 void
 ao_gps_print(__xdata struct ao_gps_data *gps_data) __reentrant
 {
-       printf("GPS %2d sat",
+       char    state;
+
+       if (gps_data->flags & AO_GPS_VALID)
+               state = AO_TELEM_GPS_STATE_LOCKED;
+       else if (gps_data->flags & AO_GPS_RUNNING)
+               state = AO_TELEM_GPS_STATE_UNLOCKED;
+       else
+               state = AO_TELEM_GPS_STATE_ERROR;
+       printf(AO_TELEM_GPS_STATE " %c "
+              AO_TELEM_GPS_NUM_SAT " %d ",
+              state,
               (gps_data->flags & AO_GPS_NUM_SAT_MASK) >> AO_GPS_NUM_SAT_SHIFT);
-       if (gps_data->flags & AO_GPS_VALID) {
-               static __xdata struct ao_gps_split      lat, lon;
-               int16_t climb, climb_int, climb_frac;
+       if (!(gps_data->flags & AO_GPS_VALID))
+               return;
+       printf(AO_TELEM_GPS_LATITUDE " %ld "
+              AO_TELEM_GPS_LONGITUDE " %ld "
+              AO_TELEM_GPS_ALTITUDE " %d ",
+              gps_data->latitude,
+              gps_data->longitude,
+              gps_data->altitude);
 
-               ao_gps_split(gps_data->latitude, &lat);
-               ao_gps_split(gps_data->longitude, &lon);
-               if (gps_data->flags & AO_GPS_DATE_VALID)
-                       printf(" 20%02d-%02d-%02d",
-                              gps_data->year,
-                              gps_data->month,
-                              gps_data->day);
-               else
-                       printf (" 0000-00-00");
-               printf(" %2d:%02d:%02d",
-                      gps_data->hour,
-                      gps_data->minute,
-                      gps_data->second);
-               printf(" %2d°%02d.%04d'%c %2d°%02d.%04d'%c %5dm",
-                      lat.degrees,
-                      lat.minutes,
-                      lat.minutes_fraction,
-                      lat.positive ? 'N' : 'S',
-                      lon.degrees,
-                      lon.minutes,
-                      lon.minutes_fraction,
-                      lon.positive ? 'E' : 'W',
-                      gps_data->altitude);
-               climb = gps_data->climb_rate;
-               if (climb >= 0) {
-                       climb_int = climb / 100;
-                       climb_frac = climb % 100;
-               } else {
-                       climb = -climb;
-                       climb_int = -(climb / 100);
-                       climb_frac = climb % 100;
-               }
-               printf(" %5u.%02dm/s(H) %d° %5d.%02dm/s(V)",
-                      gps_data->ground_speed / 100,
-                      gps_data->ground_speed % 100,
-                      gps_data->course * 2,
-                      climb / 100,
-                      climb % 100);
-               printf(" %d.%d(hdop) %5u(herr) %5u(verr)",
-                      gps_data->hdop / 5,
-                      (gps_data->hdop * 2) % 10,
+       if (gps_data->flags & AO_GPS_DATE_VALID)
+               printf(AO_TELEM_GPS_YEAR " %d "
+                      AO_TELEM_GPS_MONTH " %d "
+                      AO_TELEM_GPS_DAY " %d ",
+                      gps_data->year,
+                      gps_data->month,
+                      gps_data->day);
+
+       printf(AO_TELEM_GPS_HOUR " %d "
+              AO_TELEM_GPS_MINUTE " %d "
+              AO_TELEM_GPS_SECOND " %d ",
+              gps_data->hour,
+              gps_data->minute,
+              gps_data->second);
+
+       printf(AO_TELEM_GPS_HDOP " %d ",
+              gps_data->hdop * 2);
+
+       if (gps_data->flags & AO_GPS_COURSE_VALID) {
+               printf(AO_TELEM_GPS_HERROR " %d "
+                      AO_TELEM_GPS_VERROR " %d "
+                      AO_TELEM_GPS_VERTICAL_SPEED " %d "
+                      AO_TELEM_GPS_HORIZONTAL_SPEED " %d "
+                      AO_TELEM_GPS_COURSE " %d ",
                       gps_data->h_error,
-                      gps_data->v_error);
-       } else if (gps_data->flags & AO_GPS_RUNNING) {
-               printf(" unlocked");
-       } else {
-               printf (" not-connected");
+                      gps_data->v_error,
+                      gps_data->climb_rate,
+                      gps_data->ground_speed,
+                      (int) gps_data->course * 2);
        }
 }
 
@@ -106,12 +81,11 @@ ao_gps_tracking_print(__xdata struct ao_gps_tracking_data *gps_tracking_data) __
 {
        uint8_t c, n, v;
        __xdata struct ao_gps_sat_data  *sat;
-       printf("SAT ");
+
        n = gps_tracking_data->channels;
-       if (n == 0) {
-               printf("not-connected");
+       if (n == 0)
                return;
-       }
+
        sat = gps_tracking_data->sats;
        v = 0;
        for (c = 0; c < n; c++) {
@@ -119,13 +93,20 @@ ao_gps_tracking_print(__xdata struct ao_gps_tracking_data *gps_tracking_data) __
                        v++;
                sat++;
        }
-       printf("%d ", v);
+
+       printf (AO_TELEM_SAT_NUM " %d ",
+               v);
+
        sat = gps_tracking_data->sats;
+       v = 0;
        for (c = 0; c < n; c++) {
-               if (sat->svid)
-                       printf (" %3d %3d",
-                               sat->svid,
-                               sat->c_n_1);
+               if (sat->svid) {
+                       printf (AO_TELEM_SAT_SVID "%d %d "
+                               AO_TELEM_SAT_C_N_0 "%d %d ",
+                               v, sat->svid,
+                               v, sat->c_n_1);
+                       v++;
+               }
                sat++;
        }
 }
index a6167e6b8f21ab1fcabe16d2781129aa9089512a..87b1d69ce2f5ae91c9db2fa217c83239c1ab4883 100644 (file)
@@ -405,6 +405,7 @@ ao_gps(void) __reentrant
                        ao_gps_data.course = ao_sirf_data.course / 200;
                        ao_gps_data.hdop = ao_sirf_data.hdop;
                        ao_gps_data.climb_rate = ao_sirf_data.climb_rate;
+                       ao_gps_data.flags |= AO_GPS_COURSE_VALID;
                        if (ao_sirf_data.h_error > 6553500)
                                ao_gps_data.h_error = 65535;
                        else
index edb513047fda7aea4eeb8db808b4eb03df9ee473..44efb50cf97be50c53a99945de74c674a591dd50 100644 (file)
@@ -28,6 +28,7 @@
 #define AO_GPS_VALID           (1 << 4)
 #define AO_GPS_RUNNING         (1 << 5)
 #define AO_GPS_DATE_VALID      (1 << 6)
+#define AO_GPS_COURSE_VALID    (1 << 7)
 
 struct ao_gps_data {
        uint8_t                 year;
index 4010e09c9e8816db490feab7ab0c6f887ed793b1..b94e9bd28a9806857f0b1b0a7b51d00bfeeb1e93 100644 (file)
@@ -28,6 +28,7 @@
 #define AO_GPS_VALID           (1 << 4)
 #define AO_GPS_RUNNING         (1 << 5)
 #define AO_GPS_DATE_VALID      (1 << 6)
+#define AO_GPS_COURSE_VALID    (1 << 7)
 
 struct ao_gps_data {
        uint8_t                 year;
index 9c4be6fbd2be6a8cdde664d8f39d00adcc2a1b4c..d6fd8305ea4634338e16142301b0771a58cfb40e 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "ao.h"
+#include "ao_telem.h"
 
 __xdata uint8_t ao_monitoring;
 __pdata uint8_t ao_monitor_led;
@@ -23,54 +24,163 @@ __pdata uint8_t ao_monitor_led;
 void
 ao_monitor(void)
 {
-       __xdata struct ao_telemetry_recv recv;
        __xdata char callsign[AO_MAX_CALLSIGN+1];
+       __xdata union {
+               struct ao_telemetry_recv        full;
+               struct ao_telemetry_tiny_recv   tiny;
+       } u;
+
+#define recv           (u.full)
+#define recv_tiny      (u.tiny)
+
        uint8_t state;
        int16_t rssi;
 
        for (;;) {
                __critical while (!ao_monitoring)
                        ao_sleep(&ao_monitoring);
-               if (!ao_radio_recv(&recv, sizeof (recv)))
-                       continue;
-               state = recv.telemetry.flight_state;
-
-               /* Typical RSSI offset for 38.4kBaud at 433 MHz is 74 */
-               rssi = (int16_t) (recv.rssi >> 1) - 74;
-               memcpy(callsign, recv.telemetry.callsign, AO_MAX_CALLSIGN);
-               if (state > ao_flight_invalid)
-                       state = ao_flight_invalid;
-               if (recv.status & PKT_APPEND_STATUS_1_CRC_OK) {
-                       printf("VERSION %d CALL %s SERIAL %d FLIGHT %5u RSSI %4d STATUS %02x STATE %7s ",
-                              AO_TELEMETRY_VERSION,
-                              callsign,
-                              recv.telemetry.serial,
-                              recv.telemetry.flight,
-                              rssi, recv.status,
-                              ao_state_names[state]);
-                       printf("%5u a: %5d p: %5d t: %5d v: %5d d: %5d m: %5d "
-                              "fa: %5d ga: %d fv: %7ld fp: %5d gp: %5d a+: %5d a-: %5d ",
-                              recv.telemetry.adc.tick,
-                              recv.telemetry.adc.accel,
-                              recv.telemetry.adc.pres,
-                              recv.telemetry.adc.temp,
-                              recv.telemetry.adc.v_batt,
-                              recv.telemetry.adc.sense_d,
-                              recv.telemetry.adc.sense_m,
-                              recv.telemetry.flight_accel,
-                              recv.telemetry.ground_accel,
-                              recv.telemetry.flight_vel,
-                              recv.telemetry.flight_pres,
-                              recv.telemetry.ground_pres,
-                              recv.telemetry.accel_plus_g,
-                              recv.telemetry.accel_minus_g);
-                       ao_gps_print(&recv.telemetry.gps);
-                       putchar(' ');
-                       ao_gps_tracking_print(&recv.telemetry.gps_tracking);
-                       putchar('\n');
-                       ao_rssi_set(rssi);
+               if (ao_monitoring == AO_MONITORING_FULL) {
+                       if (!ao_radio_recv(&recv, sizeof (struct ao_telemetry_recv)))
+                               continue;
+
+                       state = recv.telemetry.flight_state;
+
+                       /* Typical RSSI offset for 38.4kBaud at 433 MHz is 74 */
+                       rssi = (int16_t) (recv.rssi >> 1) - 74;
+                       memcpy(callsign, recv.telemetry.callsign, AO_MAX_CALLSIGN);
+                       if (state > ao_flight_invalid)
+                               state = ao_flight_invalid;
+                       if (recv.status & PKT_APPEND_STATUS_1_CRC_OK) {
+
+                               /* General header fields */
+                               printf(AO_TELEM_VERSION " %d "
+                                      AO_TELEM_CALL " %s "
+                                      AO_TELEM_SERIAL " %d "
+                                      AO_TELEM_FLIGHT " %d "
+                                      AO_TELEM_RSSI " %d "
+                                      AO_TELEM_STATE " %s "
+                                      AO_TELEM_TICK " %d ",
+                                      AO_TELEMETRY_VERSION,
+                                      callsign,
+                                      recv.telemetry.serial,
+                                      recv.telemetry.flight,
+                                      rssi,
+                                      ao_state_names[state],
+                                      recv.telemetry.adc.tick);
+
+                               /* Raw sensor values */
+                               printf(AO_TELEM_RAW_ACCEL " %d "
+                                      AO_TELEM_RAW_BARO " %d "
+                                      AO_TELEM_RAW_THERMO " %d "
+                                      AO_TELEM_RAW_BATT " %d "
+                                      AO_TELEM_RAW_DROGUE " %d "
+                                      AO_TELEM_RAW_MAIN " %d ",
+                                      recv.telemetry.adc.accel,
+                                      recv.telemetry.adc.pres,
+                                      recv.telemetry.adc.temp,
+                                      recv.telemetry.adc.v_batt,
+                                      recv.telemetry.adc.sense_d,
+                                      recv.telemetry.adc.sense_m);
+
+                               /* Sensor calibration values */
+                               printf(AO_TELEM_CAL_ACCEL_GROUND " %d "
+                                      AO_TELEM_CAL_BARO_GROUND " %d "
+                                      AO_TELEM_CAL_ACCEL_PLUS " %d "
+                                      AO_TELEM_CAL_ACCEL_MINUS " %d ",
+                                      recv.telemetry.ground_accel,
+                                      recv.telemetry.ground_pres,
+                                      recv.telemetry.accel_plus_g,
+                                      recv.telemetry.accel_minus_g);
+
+#if 0
+                               /* Kalman state values */
+                               printf(AO_TELEM_KALMAN_HEIGHT " %d "
+                                      AO_TELEM_KALMAN_SPEED " %d "
+                                      AO_TELEM_KALMAN_ACCEL " %d ",
+                                      recv.telemetry.height,
+                                      recv.telemetry.speed,
+                                      recv.telemetry.accel);
+#else
+                               /* Ad-hoc flight values */
+                               printf(AO_TELEM_ADHOC_ACCEL " %d "
+                                      AO_TELEM_ADHOC_SPEED " %ld "
+                                      AO_TELEM_ADHOC_BARO " %d ",
+                                      recv.telemetry.flight_accel,
+                                      recv.telemetry.flight_vel,
+                                      recv.telemetry.flight_pres);
+#endif
+                               ao_gps_print(&recv.telemetry.gps);
+                               ao_gps_tracking_print(&recv.telemetry.gps_tracking);
+                               putchar('\n');
+                               ao_rssi_set(rssi);
+                       } else {
+                               printf("CRC INVALID RSSI %3d\n", rssi);
+                       }
                } else {
-                       printf("CRC INVALID RSSI %3d\n", rssi);
+                       if (!ao_radio_recv(&recv_tiny, sizeof (struct ao_telemetry_tiny_recv)))
+                               continue;
+
+                       state = recv_tiny.telemetry_tiny.flight_state;
+
+                       /* Typical RSSI offset for 38.4kBaud at 433 MHz is 74 */
+                       rssi = (int16_t) (recv_tiny.rssi >> 1) - 74;
+                       memcpy(callsign, recv_tiny.telemetry_tiny.callsign, AO_MAX_CALLSIGN);
+                       if (state > ao_flight_invalid)
+                               state = ao_flight_invalid;
+                       if (recv_tiny.status & PKT_APPEND_STATUS_1_CRC_OK) {
+                               /* General header fields */
+                               printf(AO_TELEM_VERSION " %d "
+                                      AO_TELEM_CALL " %s "
+                                      AO_TELEM_SERIAL " %d "
+                                      AO_TELEM_FLIGHT " %d "
+                                      AO_TELEM_RSSI " %d "
+                                      AO_TELEM_STATE " %s "
+                                      AO_TELEM_TICK " %d ",
+                                      AO_TELEMETRY_VERSION,
+                                      callsign,
+                                      recv_tiny.telemetry_tiny.serial,
+                                      recv_tiny.telemetry_tiny.flight,
+                                      rssi,
+                                      ao_state_names[state],
+                                      recv_tiny.telemetry_tiny.adc.tick);
+
+                               /* Raw sensor values */
+                               printf(AO_TELEM_RAW_BARO " %d "
+                                      AO_TELEM_RAW_THERMO " %d "
+                                      AO_TELEM_RAW_BATT " %d "
+                                      AO_TELEM_RAW_DROGUE " %d "
+                                      AO_TELEM_RAW_MAIN " %d ",
+                                      recv_tiny.telemetry_tiny.adc.pres,
+                                      recv_tiny.telemetry_tiny.adc.temp,
+                                      recv_tiny.telemetry_tiny.adc.v_batt,
+                                      recv_tiny.telemetry_tiny.adc.sense_d,
+                                      recv_tiny.telemetry_tiny.adc.sense_m);
+
+                               /* Sensor calibration values */
+                               printf(AO_TELEM_CAL_BARO_GROUND " %d ",
+                                      recv_tiny.telemetry_tiny.ground_pres);
+
+#if 1
+                               /* Kalman state values */
+                               printf(AO_TELEM_KALMAN_HEIGHT " %d "
+                                      AO_TELEM_KALMAN_SPEED " %d "
+                                      AO_TELEM_KALMAN_ACCEL " %d\n",
+                                      recv_tiny.telemetry_tiny.height,
+                                      recv_tiny.telemetry_tiny.speed,
+                                      recv_tiny.telemetry_tiny.accel);
+#else
+                               /* Ad-hoc flight values */
+                               printf(AO_TELEM_ADHOC_ACCEL " %d "
+                                      AO_TELEM_ADHOC_SPEED " %ld "
+                                      AO_TELEM_ADHOC_BARO " %d\n",
+                                      recv_tiny.telemetry_tiny.flight_accel,
+                                      recv_tiny.telemetry_tiny.flight_vel,
+                                      recv_tiny.telemetry_tiny.flight_pres);
+#endif
+                               ao_rssi_set(rssi);
+                       } else {
+                               printf("CRC INVALID RSSI %3d\n", rssi);
+                       }
                }
                ao_usb_flush();
                ao_led_toggle(ao_monitor_led);
@@ -82,21 +192,21 @@ __xdata struct ao_task ao_monitor_task;
 void
 ao_set_monitor(uint8_t monitoring)
 {
+       if (ao_monitoring)
+               ao_radio_recv_abort();
        ao_monitoring = monitoring;
        ao_wakeup(&ao_monitoring);
-       if (!ao_monitoring)
-               ao_radio_recv_abort();
 }
 
 static void
 set_monitor(void)
 {
        ao_cmd_hex();
-       ao_set_monitor(ao_cmd_lex_i != 0);
+       ao_set_monitor(ao_cmd_lex_i);
 }
 
 __code struct ao_cmds ao_monitor_cmds[] = {
-       { set_monitor,  "m <0 off, 1 on>\0Enable/disable radio monitoring" },
+       { set_monitor,  "m <0 off, 1 full, 2 tiny>\0Enable/disable radio monitoring" },
        { 0,    NULL },
 };
 
diff --git a/src/ao_telem.h b/src/ao_telem.h
new file mode 100644 (file)
index 0000000..b1624fe
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_TELEM_H_
+#define _AO_TELEM_H_
+
+#define AO_TELEMETRY_VERSION           4
+
+/*
+ * Telemetry version 4 and higher format:
+ *
+ * General header fields
+ *
+ *     Name            Value
+ *
+ *     VERSION         Telemetry version number (4 or more). Must be first.
+ *     c               Callsign (string, no spaces allowed)
+ *     n               Flight unit serial number (integer)
+ *     f               Flight number (integer)
+ *     r               Packet RSSI value (integer)
+ *     s               Flight computer state (string, no spaces allowed)
+ *     t               Flight computer clock (integer in centiseconds)
+ */
+
+#define AO_TELEM_VERSION       "VERSION"
+#define AO_TELEM_CALL          "c"
+#define AO_TELEM_SERIAL                "n"
+#define AO_TELEM_FLIGHT                "f"
+#define AO_TELEM_RSSI          "r"
+#define AO_TELEM_STATE         "s"
+#define AO_TELEM_TICK          "t"
+
+/*
+ * Raw sensor values
+ *
+ *     Name            Value
+ *     r_a             Accelerometer reading (integer)
+ *     r_b             Barometer reading (integer)
+ *     r_t             Thermometer reading (integer)
+ *     r_v             Battery reading (integer)
+ *     r_d             Drogue continuity (integer)
+ *     r_m             Main continuity (integer)
+ */
+
+#define AO_TELEM_RAW_ACCEL     "r_a"
+#define AO_TELEM_RAW_BARO      "r_b"
+#define AO_TELEM_RAW_THERMO    "r_t"
+#define AO_TELEM_RAW_BATT      "r_v"
+#define AO_TELEM_RAW_DROGUE    "r_d"
+#define AO_TELEM_RAW_MAIN      "r_m"
+
+/*
+ * Sensor calibration values
+ *
+ *     Name            Value
+ *     c_a             Ground accelerometer reading (integer)
+ *     c_b             Ground barometer reading (integer)
+ *     c_p             Accelerometer reading for +1g
+ *     c_m             Accelerometer reading for -1g
+ */
+
+#define AO_TELEM_CAL_ACCEL_GROUND      "c_a"
+#define AO_TELEM_CAL_BARO_GROUND       "c_b"
+#define AO_TELEM_CAL_ACCEL_PLUS                "c_p"
+#define AO_TELEM_CAL_ACCEL_MINUS       "c_m"
+
+/*
+ * Kalman state values
+ *
+ *     Name            Value
+ *     k_h             Height above pad (integer, meters)
+ *     k_s             Vertical speeed (integer, m/s * 16)
+ *     k_a             Vertical acceleration (integer, m/s² * 16)
+ */
+
+#define AO_TELEM_KALMAN_HEIGHT         "k_h"
+#define AO_TELEM_KALMAN_SPEED          "k_s"
+#define AO_TELEM_KALMAN_ACCEL          "k_a"
+
+/*
+ * Ad-hoc flight values
+ *
+ *     Name            Value
+ *     a_a             Acceleration (integer, sensor units)
+ *     a_s             Speed (integer, integrated acceleration value)
+ *     a_b             Barometer reading (integer, sensor units)
+ */
+
+#define AO_TELEM_ADHOC_ACCEL           "a_a"
+#define AO_TELEM_ADHOC_SPEED           "a_s"
+#define AO_TELEM_ADHOC_BARO            "a_b"
+
+/*
+ * GPS values
+ *
+ *     Name            Value
+ *     g_s             GPS state (string):
+ *                             l       locked
+ *                             u       unlocked
+ *                             e       error (missing or broken)
+ *     g_n             Number of sats used in solution
+ *     g_ns            Latitude (degrees * 10e7)
+ *     g_ew            Longitude (degrees * 10e7)
+ *     g_a             Altitude (integer meters)
+ *     g_Y             GPS year (integer)
+ *     g_M             GPS month (integer - 1-12)
+ *     g_D             GPS day (integer - 1-31)
+ *     g_h             GPS hour (integer - 0-23)
+ *     g_m             GPS minute (integer - 0-59)
+ *     g_s             GPS second (integer - 0-59)
+ *     g_v             GPS vertical speed (integer, cm/sec)
+ *     g_s             GPS horizontal speed (integer, cm/sec)
+ *     g_c             GPS course (integer, 0-359)
+ *     g_hd            GPS hdop (integer * 10)
+ *     g_vd            GPS vdop (integer * 10)
+ *     g_he            GPS h error (integer)
+ *     g_ve            GPS v error (integer)
+ */
+
+#define AO_TELEM_GPS_STATE             "g_s"
+#define AO_TELEM_GPS_STATE_LOCKED      'l'
+#define AO_TELEM_GPS_STATE_UNLOCKED    'u'
+#define AO_TELEM_GPS_STATE_ERROR       'e'
+#define AO_TELEM_GPS_NUM_SAT           "g_n"
+#define AO_TELEM_GPS_LATITUDE          "g_ns"
+#define AO_TELEM_GPS_LONGITUDE         "g_ew"
+#define AO_TELEM_GPS_ALTITUDE          "g_a"
+#define AO_TELEM_GPS_YEAR              "g_Y"
+#define AO_TELEM_GPS_MONTH             "g_M"
+#define AO_TELEM_GPS_DAY               "g_D"
+#define AO_TELEM_GPS_HOUR              "g_h"
+#define AO_TELEM_GPS_MINUTE            "g_m"
+#define AO_TELEM_GPS_SECOND            "g_s"
+#define AO_TELEM_GPS_VERTICAL_SPEED    "g_v"
+#define AO_TELEM_GPS_HORIZONTAL_SPEED  "g_s"
+#define AO_TELEM_GPS_COURSE            "g_c"
+#define AO_TELEM_GPS_HDOP              "g_hd"
+#define AO_TELEM_GPS_VDOP              "g_vd"
+#define AO_TELEM_GPS_HERROR            "g_he"
+#define AO_TELEM_GPS_VERROR            "g_ve"
+
+/*
+ * GPS satellite values
+ *
+ *     Name            Value
+ *     s_n             Number of satellites reported (integer)
+ *     s_v0            Space vehicle ID (integer) for report 0
+ *     s_c0            C/N0 number (integer) for report 0
+ *     s_v1            Space vehicle ID (integer) for report 1
+ *     s_c1            C/N0 number (integer) for report 1
+ *     ...
+ */
+
+#define AO_TELEM_SAT_NUM               "s_n"
+#define AO_TELEM_SAT_SVID              "s_v"
+#define AO_TELEM_SAT_C_N_0             "s_c"
+
+#endif /* _AO_TELEM_H_ */