ソースを参照

minmea.h, minmea.c: Added support for GLL sentences

Edyta 11 年 前
コミット
3b6ba502bc
5 ファイル変更77 行追加0 行削除
  1. 1 0
      README.md
  2. BIN
      example.c
  3. 26 0
      minmea.c
  4. 20 0
      minmea.h
  5. 30 0
      tests.c

+ 1 - 0
README.md

@@ -19,6 +19,7 @@ systems.
 * ``RMC`` (Recommended Minimum: position, velocity, time)
 * ``GGA`` (Fix Data)
 * ``GSA`` (DOP and active satellites)
+* ``GLL`` (Geographic Position -- Latitude/Longitude)
 
 Adding support for more sentences is trivial; see ``minmea.c`` source.
 

BIN
example.c


+ 26 - 0
minmea.c

@@ -287,6 +287,8 @@ enum minmea_sentence_id minmea_sentence_id(const char *sentence)
         return MINMEA_SENTENCE_GGA;
     if (!strcmp(type+2, "GSA"))
         return MINMEA_SENTENCE_GSA;
+    if (!strcmp(type+2, "GLL"))
+        return MINMEA_SENTENCE_GLL;
 
     return MINMEA_UNKNOWN;
 }
@@ -385,6 +387,30 @@ bool minmea_parse_gsa(struct minmea_sentence_gsa *frame, const char *sentence)
     return true;
 }
 
+bool minmea_parse_gll(struct minmea_sentence_gll *frame, const char *sentence)
+{
+    // $GPGLL,3723.2475,N,12158.3416,W,161229.487,A,A*41$;
+    char type[6];
+    int latitude_direction;
+    int longitude_direction;
+
+    if (!minmea_scan(sentence, "tfdfdTcc",
+            type,
+            &frame->latitude, &frame->latitude_scale, &latitude_direction,
+            &frame->longitude, &frame->longitude_scale, &longitude_direction,
+            &frame->time,
+            &frame->status,
+            &frame->mode))
+        return false;
+    if (strcmp(type+2, "GLL"))
+        return false;
+
+    frame->latitude *= latitude_direction;
+    frame->longitude *= longitude_direction;
+
+    return true;
+}
+
 int minmea_gettimeofday(struct timeval *tv, const struct minmea_date *date, const struct minmea_time *time)
 {
     if (date->year == -1 || time->hours == -1)

+ 20 - 0
minmea.h

@@ -29,6 +29,7 @@ enum minmea_sentence_id {
     MINMEA_SENTENCE_RMC,
     MINMEA_SENTENCE_GGA,
     MINMEA_SENTENCE_GSA,
+    MINMEA_SENTENCE_GLL
 };
 
 struct minmea_date {
@@ -67,6 +68,24 @@ struct minmea_sentence_gga {
     int dgps_age;
 };
 
+enum minmea_gll_status {
+    MINMEA_GLL_STATUS_DATA_VALID     = 'A',
+    MINMEA_GLL_STATUS_DATA_NOT_VALID = 'V'
+};
+
+enum minmea_gll_mode {
+    MINMEA_GLL_MODE_AUTONOMOUS = 'A',
+    MINMEA_GLL_MODE_DPGS       = 'D',
+    MINMEA_GLL_MODE_DR         = 'E' 
+};
+
+struct minmea_sentence_gll {
+    int latitude, latitude_scale;
+    int longitude, longitude_scale;
+    struct minmea_time time;
+    char status;
+    char mode;
+};
 enum minmea_gsa_mode {
     MINMEA_GPGSA_MODE_AUTO = 'A',
     MINMEA_GPGSA_MODE_FORCED = 'M',
@@ -121,6 +140,7 @@ bool minmea_scan(const char *sentence, const char *format, ...);
 bool minmea_parse_rmc(struct minmea_sentence_rmc *frame, const char *sentence);
 bool minmea_parse_gga(struct minmea_sentence_gga *frame, const char *sentence);
 bool minmea_parse_gsa(struct minmea_sentence_gsa *frame, const char *sentence);
+bool minmea_parse_gll(struct minmea_sentence_gll *frame, const char *sentence);
 
 /**
  * Convert GPS UTC date/time representation to a UNIX timestamp.

+ 30 - 0
tests.c

@@ -377,12 +377,36 @@ START_TEST(test_minmea_parse_gsa1)
 }
 END_TEST
 
+START_TEST(test_minmea_parse_gpgll)
+{
+    const char *sentence = "$GPGLL,3723.2475,N,12158.3416,W,161229.487,A,A*41";
+    struct minmea_sentence_gll frame = {};
+    struct minmea_sentence_gll expected = {};
+
+    expected.latitude = 37232475;
+    expected.latitude_scale = 10000;
+    expected.longitude = -121583416;
+    expected.longitude_scale = 10000;
+    expected.time.hours = 16;
+    expected.time.minutes = 12;
+    expected.time.seconds = 29;
+    expected.time.microseconds = 487000;
+    expected.status = MINMEA_GLL_STATUS_DATA_VALID;
+    expected.mode = MINMEA_GLL_MODE_AUTONOMOUS;
+
+    ck_assert(minmea_check(sentence) == true);
+    ck_assert(minmea_parse_gll(&frame, sentence) == true);
+    ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
+}
+END_TEST
+
 START_TEST(test_minmea_usage1)
 {
     const char *sentences[] = {
         "$GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62",
         "$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47",
         "$GNGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1",
+        "$GPGLL,3723.2475,N,12158.3416,W,161229.487,A,A*41",
         NULL,
     };
 
@@ -403,6 +427,11 @@ START_TEST(test_minmea_usage1)
                 ck_assert(minmea_parse_gsa(&frame, *sentence) == true);
             } break;
 
+            case MINMEA_SENTENCE_GLL: {
+                struct minmea_sentence_gll frame;
+                ck_assert(minmea_parse_gll(&frame, *sentence) == true);
+            } break;
+
 
             default: {
             } break;
@@ -495,6 +524,7 @@ Suite *minmea_suite(void)
     tcase_add_test(tc_parse, test_minmea_parse_rmc2);
     tcase_add_test(tc_parse, test_minmea_parse_gga1);
     tcase_add_test(tc_parse, test_minmea_parse_gsa1);
+    tcase_add_test(tc_parse, test_minmea_parse_gpgll);
     suite_add_tcase(s, tc_parse);
 
     TCase *tc_usage = tcase_create("minmea_usage");