summaryrefslogtreecommitdiff
path: root/gnss-service
diff options
context:
space:
mode:
authorHelmut Schmidt <Helmut.3.Schmidt@continental-corporation.com>2016-09-16 15:12:27 +0200
committerHelmut Schmidt <Helmut.3.Schmidt@continental-corporation.com>2016-09-16 15:12:27 +0200
commitcca2e8710939fbe58fda48079efa325968de700e (patch)
tree9914a5c274abc54feddd506924a5a5a02d95f29c /gnss-service
parentf341b4a2cb216d6204136794d33076170ab1bf80 (diff)
downloadpositioning-cca2e8710939fbe58fda48079efa325968de700e.tar.gz
Positioning Poc: Multiconstellation NMEA support
Diffstat (limited to 'gnss-service')
-rw-r--r--gnss-service/src/gnss-use-nmea.cpp129
-rw-r--r--gnss-service/src/hnmea.cpp302
-rw-r--r--gnss-service/src/hnmea.h65
3 files changed, 278 insertions, 218 deletions
diff --git a/gnss-service/src/gnss-use-nmea.cpp b/gnss-service/src/gnss-use-nmea.cpp
index 6286a6c..5ee9b02 100644
--- a/gnss-service/src/gnss-use-nmea.cpp
+++ b/gnss-service/src/gnss-use-nmea.cpp
@@ -124,32 +124,32 @@ void setGNSSStatus(EGNSSStatus newStatus)
}
/**
- * Convert GPS data from NMEA parser to TGNSSPosition struct
- * @param gps_data [IN] GPS data decoded from NMEA parser
+ * Convert GNSS data from NMEA parser to TGNSSPosition struct
+ * @param gns_data [IN] GNSS data decoded from NMEA parser
* @param timestamp [IN] timestamp in milliseconds
- * @param gnss_pos [OUT] TGNSSPosition struct which will be filled with gps_data and timestamp
+ * @param gnss_pos [OUT] TGNSSPosition struct which will be filled with gns_data and timestamp
* @return conversion has been successful
*/
-bool extractPosition(const GPS_DATA& gps_data, uint64_t timestamp, TGNSSPosition& gnss_pos)
+bool extractPosition(const GNS_DATA& gns_data, uint64_t timestamp, TGNSSPosition& gnss_pos)
{
gnss_pos.validityBits = 0;
gnss_pos.timestamp = timestamp;
- if (gps_data.valid & GPS_DATA_LAT)
+ if (gns_data.valid & GNS_DATA_LAT)
{
- gnss_pos.latitude = gps_data.lat;
+ gnss_pos.latitude = gns_data.lat;
gnss_pos.validityBits |= GNSS_POSITION_LATITUDE_VALID;
}
- if (gps_data.valid & GPS_DATA_LON)
+ if (gns_data.valid & GNS_DATA_LON)
{
- gnss_pos.longitude = gps_data.lon;
+ gnss_pos.longitude = gns_data.lon;
gnss_pos.validityBits |= GNSS_POSITION_LONGITUDE_VALID;
}
- if (gps_data.valid & GPS_DATA_ALT)
+ if (gns_data.valid & GNS_DATA_ALT)
{
- gnss_pos.altitudeMSL = gps_data.alt;
+ gnss_pos.altitudeMSL = gns_data.alt;
gnss_pos.validityBits |= GNSS_POSITION_ALTITUDEMSL_VALID;
- if (gps_data.valid & GPS_DATA_GEOID)
+ if (gns_data.valid & GNS_DATA_GEOID)
{
//Geoid separation terminology might be difficult to understand
//You can cross check your NMEA output and calculation results
@@ -157,51 +157,51 @@ bool extractPosition(const GPS_DATA& gps_data, uint64_t timestamp, TGNSSPosition
// http://www.unavco.org/software/geodetic-utilities/geoid-height-calculator/geoid-height-calculator.html
// http://earth-info.nga.mil/GandG/wgs84/gravitymod/wgs84_180/intptWhel.html
// http://geographiclib.sourceforge.net/cgi-bin/GeoidEval
- gnss_pos.altitudeEll = gps_data.alt+gps_data.geoid;
+ gnss_pos.altitudeEll = gns_data.alt+gns_data.geoid;
gnss_pos.validityBits |= GNSS_POSITION_ALTITUDEELL_VALID;
}
}
- if (gps_data.valid & GPS_DATA_SPEED)
+ if (gns_data.valid & GNS_DATA_SPEED)
{
- gnss_pos.hSpeed = gps_data.speed;
+ gnss_pos.hSpeed = gns_data.speed;
gnss_pos.validityBits |= GNSS_POSITION_HSPEED_VALID;
}
gnss_pos.vSpeed = 9999; //not available
- if (gps_data.valid & GPS_DATA_SPEED)
+ if (gns_data.valid & GNS_DATA_COURSE)
{
- gnss_pos.heading = gps_data.course;
- gnss_pos.validityBits |= GPS_DATA_COURSE;
+ gnss_pos.heading = gns_data.course;
+ gnss_pos.validityBits |= GNSS_POSITION_HEADING_VALID;
}
- if (gps_data.valid & GPS_DATA_PDOP)
+ if (gns_data.valid & GNS_DATA_PDOP)
{
- gnss_pos.pdop = gps_data.pdop;
+ gnss_pos.pdop = gns_data.pdop;
gnss_pos.validityBits |= GNSS_POSITION_PDOP_VALID;
}
- if (gps_data.valid & GPS_DATA_HDOP)
+ if (gns_data.valid & GNS_DATA_HDOP)
{
- gnss_pos.hdop = gps_data.hdop;
+ gnss_pos.hdop = gns_data.hdop;
gnss_pos.validityBits |= GNSS_POSITION_HDOP_VALID;
}
- if (gps_data.valid & GPS_DATA_VDOP)
+ if (gns_data.valid & GNS_DATA_VDOP)
{
- gnss_pos.vdop = gps_data.vdop;
+ gnss_pos.vdop = gns_data.vdop;
gnss_pos.validityBits |= GNSS_POSITION_VDOP_VALID;
}
- if (gps_data.valid & GPS_DATA_USAT)
+ if (gns_data.valid & GNS_DATA_USAT)
{
- gnss_pos.usedSatellites = gps_data.usat;
+ gnss_pos.usedSatellites = gns_data.usat;
gnss_pos.validityBits |= GNSS_POSITION_USAT_VALID;
}
gnss_pos.trackedSatellites = 9999; //not available
gnss_pos.visibleSatellites = 9999; //not available
- if (gps_data.valid & GPS_DATA_HACC)
+ if (gns_data.valid & GNS_DATA_HACC)
{
- gnss_pos.sigmaHPosition = gps_data.hacc;
+ gnss_pos.sigmaHPosition = gns_data.hacc;
gnss_pos.validityBits |= GNSS_POSITION_SHPOS_VALID;
}
- if (gps_data.valid & GPS_DATA_HACC)
+ if (gns_data.valid & GNS_DATA_VACC)
{
- gnss_pos.sigmaAltitude = gps_data.vacc;
+ gnss_pos.sigmaAltitude = gns_data.vacc;
gnss_pos.validityBits |= GNSS_POSITION_SALT_VALID;
}
@@ -211,14 +211,14 @@ bool extractPosition(const GPS_DATA& gps_data, uint64_t timestamp, TGNSSPosition
gnss_pos.validityBits |= GNSS_POSITION_STAT_VALID; //always valid
gnss_pos.fixStatus = GNSS_FIX_STATUS_NO;
- if (gps_data.valid & GPS_DATA_FIX2D)
+ if (gns_data.valid & GNS_DATA_FIX2D)
{
- if (gps_data.fix2d)
+ if (gns_data.fix2d)
{
gnss_pos.fixStatus = GNSS_FIX_STATUS_2D;
}
}
- if ( (gps_data.valid & GPS_DATA_FIX3D) && (gps_data.fix3d) )
+ if ( (gns_data.valid & GNS_DATA_FIX3D) && (gns_data.fix3d) )
{
gnss_pos.fixStatus = GNSS_FIX_STATUS_3D;
}
@@ -230,36 +230,44 @@ bool extractPosition(const GPS_DATA& gps_data, uint64_t timestamp, TGNSSPosition
gnss_pos.validityBits |= GNSS_POSITION_ASYS_VALID;
gnss_pos.usedSystems = GNSS_SYSTEM_GPS;
gnss_pos.validityBits |= GNSS_POSITION_USYS_VALID;
-
+ //check whether GLONASS is active in addition to GPS
+ //TODO check explicitly for GPS to cover GLONASS only
+ if ( (gns_data.valid_ext & GNS_DATA_USAT_GLO) && (gns_data.usat_glo > 0) )
+ {
+ gnss_pos.activatedSystems |= GNSS_SYSTEM_GLONASS;
+ gnss_pos.usedSystems |= GNSS_SYSTEM_GLONASS;
+ gnss_pos.fixTypeBits |= GNSS_FIX_TYPE_MULTI_CONSTELLATION;
+ }
+
return true;
}
/**
- * Convert GPS data from NMEA parser to TGNSSTime struct
- * @param gps_data [IN] GPS data decoded from NMEA parser
+ * Convert GNSS data from NMEA parser to TGNSSTime struct
+ * @param gns_data [IN] GNSS data decoded from NMEA parser
* @param timestamp [IN] timestamp in milliseconds
- * @param gnss_time [OUT] TGNSSTime struct which will be filled with gps_data and timestamp
+ * @param gnss_time [OUT] TGNSSTime struct which will be filled with gns_data and timestamp
* @return conversion has been successful
*/
-bool extractTime(const GPS_DATA& gps_data, uint64_t timestamp, TGNSSTime& gnss_time)
+bool extractTime(const GNS_DATA& gns_data, uint64_t timestamp, TGNSSTime& gnss_time)
{
gnss_time.validityBits = 0;
gnss_time.timestamp = timestamp;
- if (gps_data.valid & GPS_DATA_TIME)
+ if (gns_data.valid & GNS_DATA_TIME)
{
- gnss_time.hour = gps_data.time_hh;
- gnss_time.minute = gps_data.time_mm;
- gnss_time.second = gps_data.time_ss;
- gnss_time.ms = gps_data.time_ms;
+ gnss_time.hour = gns_data.time_hh;
+ gnss_time.minute = gns_data.time_mm;
+ gnss_time.second = gns_data.time_ss;
+ gnss_time.ms = gns_data.time_ms;
gnss_time.validityBits |= GNSS_TIME_TIME_VALID;
}
- if (gps_data.valid & GPS_DATA_DATE)
+ if (gns_data.valid & GNS_DATA_DATE)
{
- gnss_time.year = gps_data.date_yyyy;
- gnss_time.month = gps_data.date_mm-1;
- gnss_time.day = gps_data.date_dd;
+ gnss_time.year = gns_data.date_yyyy;
+ gnss_time.month = gns_data.date_mm-1;
+ gnss_time.day = gns_data.date_dd;
gnss_time.validityBits |= GNSS_TIME_DATE_VALID;
}
@@ -353,6 +361,13 @@ int open_GNSS_NMEA_device(const char* gps_device, unsigned int baudrate)
/*
Done
*/
+#ifdef NMEA_PRINT_RAW
+ //http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_12.html#SEC237
+ //http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_27.html#SEC465
+ //http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_27.html#SEC468
+ //printf("MAX_CANON: %d\n", fpathconf(fd, _PC_MAX_CANON));
+ //printf("MAX_INPUT: %d\n", fpathconf(fd, _PC_MAX_INPUT));
+#endif
//LOG_DEBUG(gContext, "OPEN successful %d\n", fd);
return fd;
}
@@ -372,10 +387,10 @@ void* loop_GNSS_NMEA_device(void* dev)
//read failure - used to trigger restart
bool read_failure = false;
//trigger message
- NMEA_RESULT trigger = NMEA_GPRMC;
- //gps data as returned by NMEA parser
- GPS_DATA gps_data;
- HNMEA_Init_GPS_DATA(&gps_data);
+ NMEA_RESULT trigger = NMEA_RMC;
+ //gnss data as returned by NMEA parser
+ GNS_DATA gns_data;
+ HNMEA_Init_GNS_DATA(&gns_data);
/* loop until we have a terminating condition */
//LOG_DEBUG(gContext, "entering NMEA reading loop %d\n", fd);
@@ -413,18 +428,18 @@ void* loop_GNSS_NMEA_device(void* dev)
printf("%"PRIu64",0,%s",gnss_get_timestamp(), buf);
fflush(stdout);
#endif
- NMEA_RESULT nmea_res = HNMEA_Parse(buf, &gps_data);
+ NMEA_RESULT nmea_res = HNMEA_Parse(buf, &gns_data);
//most receivers sent GPRMC as last, but u-blox send as first: use other trigger
//determine most suitable trigger on actually received messages
#ifdef GNSS_CHIPSET_UBLOX
- if (nmea_res == NMEA_GPGST) //highest precedence
+ if (nmea_res == NMEA_GST) //highest precedence
{
- trigger = NMEA_GPGST;
+ trigger = NMEA_GST;
}
- if ((nmea_res == NMEA_GPGSA) && (trigger == NMEA_GPRMC)) //GSA better than RMC
+ if ((nmea_res == NMEA_GSA) && (trigger == NMEA_RMC)) //GSA better than RMC
{
- trigger = NMEA_GPGSA;
+ trigger = NMEA_GSA;
}
#endif
if (nmea_res == trigger)
@@ -433,7 +448,7 @@ void* loop_GNSS_NMEA_device(void* dev)
uint64_t timestamp = gnss_get_timestamp() - GNSS_DELAY;
TGNSSTime gnss_time = { 0 };
TGNSSPosition gnss_pos = { 0 };
- if (extractTime(gps_data, timestamp, gnss_time))
+ if (extractTime(gns_data, timestamp, gnss_time))
{
updateGNSSTime(&gnss_time, 1);
@@ -453,7 +468,7 @@ void* loop_GNSS_NMEA_device(void* dev)
fflush(stdout);
#endif
}
- if (extractPosition(gps_data, timestamp, gnss_pos))
+ if (extractPosition(gns_data, timestamp, gnss_pos))
{
updateGNSSPosition(&gnss_pos,1 );
}
diff --git a/gnss-service/src/hnmea.cpp b/gnss-service/src/hnmea.cpp
index d176c9e..a7ec73d 100644
--- a/gnss-service/src/hnmea.cpp
+++ b/gnss-service/src/hnmea.cpp
@@ -34,32 +34,35 @@ char test_gpgs3[] = "$GPGSV,3,3,12,09,08,259,29,26,65,304,45,24,02,263,,17,08,13
-void HNMEA_Init_GPS_DATA(GPS_DATA* gps_data)
+void HNMEA_Init_GNS_DATA(GNS_DATA* gns_data)
{
- gps_data->valid = 0;
- gps_data->valid_new = 0;
- gps_data->lat = 999.99;
- gps_data->lon = 999.99;
- gps_data->alt = -1000.0;
- gps_data->geoid = -1000.0;
- gps_data->date_yyyy = -1;
- gps_data->date_mm = -1;
- gps_data->date_dd = -1;
- gps_data->time_hh = -1;
- gps_data->time_mm = -1;
- gps_data->time_ss = -1;
- gps_data->time_ms = -1;
- gps_data->course = -999.99;
- gps_data->speed = -999.99;
- gps_data->hdop = -999.99;
- gps_data->vdop = -999.99;
- gps_data->pdop = -999.99;
- gps_data->usat = -99;
- gps_data->fix2d = -1;
- gps_data->fix3d = -1;
- gps_data->hacc = 999.9;
- gps_data->vacc = 999.9;
-
+ gns_data->valid = 0;
+ gns_data->valid_new = 0;
+ gns_data->valid_ext = 0;
+ gns_data->valid_ext_new = 0;
+ gns_data->lat = 999.99;
+ gns_data->lon = 999.99;
+ gns_data->alt = -1000.0;
+ gns_data->geoid = -1000.0;
+ gns_data->date_yyyy = -1;
+ gns_data->date_mm = -1;
+ gns_data->date_dd = -1;
+ gns_data->time_hh = -1;
+ gns_data->time_mm = -1;
+ gns_data->time_ss = -1;
+ gns_data->time_ms = -1;
+ gns_data->course = -999.99;
+ gns_data->speed = -999.99;
+ gns_data->hdop = -999.99;
+ gns_data->vdop = -999.99;
+ gns_data->pdop = -999.99;
+ gns_data->usat = -99;
+ gns_data->fix2d = -1;
+ gns_data->fix3d = -1;
+ gns_data->hacc = 999.9;
+ gns_data->vacc = 999.9;
+ gns_data->usat_gps = -99;
+ gns_data->usat_glo = -99;
}
@@ -113,7 +116,7 @@ int HNMEA_Checksum_Valid(char* line)
return ret;
}
-void HNMEA_Parse_GPRMC(char* line, GPS_DATA* gps_data)
+void HNMEA_Parse_RMC(char* line, GNS_DATA* gns_data)
{
enum { MAX_FIELD_LEN = 128};
char field[MAX_FIELD_LEN];
@@ -123,7 +126,8 @@ void HNMEA_Parse_GPRMC(char* line, GPS_DATA* gps_data)
int stop = 0; // stop flag
int len = strlen(line);
- gps_data->valid_new = 0;
+ gns_data->valid_new = 0;
+ gns_data->valid_ext_new = 0;
//outer loop - stop at line end
while ( (l < len ) && (stop == 0) )
@@ -139,10 +143,10 @@ void HNMEA_Parse_GPRMC(char* line, GPS_DATA* gps_data)
switch (i)
{
- case 0: //$GPRMC
+ case 0: //$GPRMC or $GNRMC
{
//cross-check for sentence name
- if (strncmp (field, "$GPRMC", 6) != 0)
+ if ((strncmp (field, "$GPRMC", 6) != 0) && (strncmp (field, "$GNRMC", 6) != 0))
{
// force termination of loop
stop = 1;
@@ -154,13 +158,13 @@ void HNMEA_Parse_GPRMC(char* line, GPS_DATA* gps_data)
//length check
if (strlen (field) >=6)
{
- gps_data->time_ss = atoi(field+4);
- gps_data->time_ms = (atof(field+4)-gps_data->time_ss)*1000;
+ gns_data->time_ss = atoi(field+4);
+ gns_data->time_ms = (atof(field+4)-gns_data->time_ss)*1000;
field[4] = '\0';
- gps_data->time_mm = atoi(field+2);
+ gns_data->time_mm = atoi(field+2);
field[2] = '\0';
- gps_data->time_hh = atoi(field);
- gps_data->valid_new |= GPS_DATA_TIME;
+ gns_data->time_hh = atoi(field);
+ gns_data->valid_new |= GNS_DATA_TIME;
}
break;
}
@@ -171,20 +175,20 @@ void HNMEA_Parse_GPRMC(char* line, GPS_DATA* gps_data)
{
if (field[0] == 'A')
{
- gps_data->fix2d = 1;
+ gns_data->fix2d = 1;
}
else
{
- gps_data->fix2d = 0;
+ gns_data->fix2d = 0;
}
- gps_data->valid_new |= GPS_DATA_FIX2D;
+ gns_data->valid_new |= GNS_DATA_FIX2D;
}
break;
}
case 3: //latitude - absolute value
{
//check for minimum length + evaluate only if status ok
- if ( ((gps_data->valid_new & GPS_DATA_FIX2D)!=0) && (gps_data->fix2d) && (strlen (field) >=2) )
+ if ( ((gns_data->valid_new & GNS_DATA_FIX2D)!=0) && (gns_data->fix2d) && (strlen (field) >=2) )
{
double fraction = 0.0;
if (strlen (field) >=3)
@@ -192,8 +196,8 @@ void HNMEA_Parse_GPRMC(char* line, GPS_DATA* gps_data)
fraction = atof(field+2)/60.0;
}
field[2]=0;
- gps_data->lat = atoi(field) + fraction;
- gps_data->valid_new |= GPS_DATA_LAT;
+ gns_data->lat = atoi(field) + fraction;
+ gns_data->valid_new |= GNS_DATA_LAT;
}
break;
}
@@ -204,7 +208,7 @@ void HNMEA_Parse_GPRMC(char* line, GPS_DATA* gps_data)
{
if ((field[0] == 'S') || (field[0] == 's'))
{
- gps_data->lat = - gps_data->lat;
+ gns_data->lat = - gns_data->lat;
}
}
break;
@@ -212,7 +216,7 @@ void HNMEA_Parse_GPRMC(char* line, GPS_DATA* gps_data)
case 5: //longitude - absolute value
{
//check for minimum length + evaluate only if status ok
- if ( ((gps_data->valid_new & GPS_DATA_FIX2D)!=0) && (gps_data->fix2d) && (strlen (field) >=3) )
+ if ( ((gns_data->valid_new & GNS_DATA_FIX2D)!=0) && (gns_data->fix2d) && (strlen (field) >=3) )
{
double fraction = 0.0;
if (strlen (field) >=4)
@@ -220,8 +224,8 @@ void HNMEA_Parse_GPRMC(char* line, GPS_DATA* gps_data)
fraction = atof(field+3)/60.0;
}
field[3]=0;
- gps_data->lon = atoi(field) + fraction;
- gps_data->valid_new |= GPS_DATA_LON;
+ gns_data->lon = atoi(field) + fraction;
+ gns_data->valid_new |= GNS_DATA_LON;
}
break;
}
@@ -232,7 +236,7 @@ void HNMEA_Parse_GPRMC(char* line, GPS_DATA* gps_data)
{
if ((field[0] == 'W') || (field[0] == 'w'))
{
- gps_data->lon = - gps_data->lon;
+ gns_data->lon = - gns_data->lon;
}
}
break;
@@ -240,20 +244,20 @@ void HNMEA_Parse_GPRMC(char* line, GPS_DATA* gps_data)
case 7: //speed - knots
{
//length check + evaluate only if status ok
- if (((gps_data->valid_new & GPS_DATA_FIX2D)!=0) && (gps_data->fix2d) && (strlen (field) >=1) )
+ if (((gns_data->valid_new & GNS_DATA_FIX2D)!=0) && (gns_data->fix2d) && (strlen (field) >=1) )
{
- gps_data->speed = atof(field)*1.852/3.6;
- gps_data->valid_new |= GPS_DATA_SPEED;
+ gns_data->speed = atof(field)*1.852/3.6;
+ gns_data->valid_new |= GNS_DATA_SPEED;
}
break;
}
case 8: //course - degrees
{
//length check + evaluate only if status ok
- if (((gps_data->valid_new & GPS_DATA_FIX2D)!=0) && (gps_data->fix2d) && (strlen (field) >=1) )
+ if (((gns_data->valid_new & GNS_DATA_FIX2D)!=0) && (gns_data->fix2d) && (strlen (field) >=1) )
{
- gps_data->course = atof(field);
- gps_data->valid_new |= GPS_DATA_COURSE;
+ gns_data->course = atof(field);
+ gns_data->valid_new |= GNS_DATA_COURSE;
}
break;
}
@@ -262,12 +266,12 @@ void HNMEA_Parse_GPRMC(char* line, GPS_DATA* gps_data)
//length check
if (strlen (field) >=6)
{
- gps_data->date_yyyy = 2000 + atoi(field+4);
+ gns_data->date_yyyy = 2000 + atoi(field+4);
field[4] = '\0';
- gps_data->date_mm = atoi(field+2);
+ gns_data->date_mm = atoi(field+2);
field[2] = '\0';
- gps_data->date_dd = atoi(field);
- gps_data->valid_new |= GPS_DATA_DATE;
+ gns_data->date_dd = atoi(field);
+ gns_data->valid_new |= GNS_DATA_DATE;
}
stop = 1; //ignore all other fields
break;
@@ -297,10 +301,11 @@ void HNMEA_Parse_GPRMC(char* line, GPS_DATA* gps_data)
}
//update validity mask with new data
- gps_data->valid |= gps_data->valid_new;
+ gns_data->valid |= gns_data->valid_new;
+ gns_data->valid_ext |= gns_data->valid_ext_new;
}
-void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
+void HNMEA_Parse_GGA(char* line, GNS_DATA* gns_data)
{
enum { MAX_FIELD_LEN = 128};
char field[MAX_FIELD_LEN];
@@ -317,7 +322,8 @@ void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
double alt = 0.0;
double geoid = 0.0;
- gps_data->valid_new = 0;
+ gns_data->valid_new = 0;
+ gns_data->valid_ext_new = 0;
//outer loop - stop at line end
while ( (l < len ) && (stop == 0) )
@@ -333,10 +339,10 @@ void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
switch (i)
{
- case 0: //$GPGGA
+ case 0: //$GPGGA or $GNGGA
{
//cross-check for sentence name
- if (strncmp (field, "$GPGGA", 6) != 0)
+ if ((strncmp (field, "$GPGGA", 6) != 0) && (strncmp (field, "$GNGGA", 6) != 0))
{
// force termination of loop
stop = 1;
@@ -348,13 +354,13 @@ void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
//length check
if (strlen (field) >=6)
{
- gps_data->time_ss = atoi(field+4);
- gps_data->time_ms = (atof(field+4)-gps_data->time_ss)*1000;
+ gns_data->time_ss = atoi(field+4);
+ gns_data->time_ms = (atof(field+4)-gns_data->time_ss)*1000;
field[4] = '\0';
- gps_data->time_mm = atoi(field+2);
+ gns_data->time_mm = atoi(field+2);
field[2] = '\0';
- gps_data->time_hh = atoi(field);
- gps_data->valid_new |= GPS_DATA_TIME;
+ gns_data->time_hh = atoi(field);
+ gns_data->valid_new |= GNS_DATA_TIME;
}
break;
}
@@ -370,7 +376,7 @@ void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
}
field[2]=0;
lat = atoi(field) + fraction;
- gps_data->valid_new |= GPS_DATA_LAT;
+ gns_data->valid_new |= GNS_DATA_LAT;
}
break;
}
@@ -398,7 +404,7 @@ void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
}
field[3]=0;
lon = atoi(field) + fraction;
- gps_data->valid_new |= GPS_DATA_LON;
+ gns_data->valid_new |= GNS_DATA_LON;
}
break;
}
@@ -421,16 +427,16 @@ void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
{
if ( (field[0] == '1') || (field[0] == '2') || (field[0] == '6') )
{
- gps_data->fix2d = 1;
- gps_data->lat = lat;
- gps_data->lon = lon;
+ gns_data->fix2d = 1;
+ gns_data->lat = lat;
+ gns_data->lon = lon;
}
else
{
- gps_data->fix2d = 0;
- gps_data->valid_new &= ~(GPS_DATA_LAT | GPS_DATA_LON);
+ gns_data->fix2d = 0;
+ gns_data->valid_new &= ~(GNS_DATA_LAT | GNS_DATA_LON);
}
- gps_data->valid_new |= GPS_DATA_FIX2D;
+ gns_data->valid_new |= GNS_DATA_FIX2D;
}
break;
}
@@ -439,8 +445,8 @@ void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
//length check
if (strlen (field) >=1)
{
- gps_data->usat = atoi(field);
- gps_data->valid_new |= GPS_DATA_USAT;
+ gns_data->usat = atoi(field);
+ gns_data->valid_new |= GNS_DATA_USAT;
}
break;
}
@@ -449,8 +455,8 @@ void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
//length check
if (strlen (field) >=1)
{
- gps_data->hdop = atof(field);
- gps_data->valid_new |= GPS_DATA_HDOP;
+ gns_data->hdop = atof(field);
+ gns_data->valid_new |= GNS_DATA_HDOP;
}
break;
}
@@ -460,7 +466,7 @@ void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
if (strlen (field) >=1)
{
alt = atof(field);
- gps_data->valid_new |= GPS_DATA_ALT;
+ gns_data->valid_new |= GNS_DATA_ALT;
}
break;
}
@@ -469,13 +475,13 @@ void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
//length check
if (strlen (field) >=1)
{
- if ( (field[0] == 'M') && (gps_data->fix2d) )
+ if ( (field[0] == 'M') && (gns_data->fix2d) )
{
- gps_data->alt = alt;
+ gns_data->alt = alt;
}
else
{
- gps_data->valid_new &= ~(GPS_DATA_ALT);
+ gns_data->valid_new &= ~(GNS_DATA_ALT);
}
}
break;
@@ -486,7 +492,7 @@ void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
if (strlen (field) >=1)
{
geoid = atof(field);
- gps_data->valid_new |= GPS_DATA_GEOID;
+ gns_data->valid_new |= GNS_DATA_GEOID;
}
break;
}
@@ -497,11 +503,11 @@ void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
{
if (field[0] == 'M')
{
- gps_data->geoid = geoid;
+ gns_data->geoid = geoid;
}
else
{
- gps_data->valid_new &= ~(GPS_DATA_GEOID);
+ gns_data->valid_new &= ~(GNS_DATA_GEOID);
}
}
stop = 1; //ignore all other fields
@@ -532,11 +538,12 @@ void HNMEA_Parse_GPGGA(char* line, GPS_DATA* gps_data)
}
//update validity mask with valid_new data
- gps_data->valid |= gps_data->valid_new;
+ gns_data->valid |= gns_data->valid_new;
+ gns_data->valid_ext |= gns_data->valid_ext_new;
}
-void HNMEA_Parse_GPGSA(char* line, GPS_DATA* gps_data)
+void HNMEA_Parse_GSA(char* line, GNS_DATA* gns_data)
{
enum { MAX_FIELD_LEN = 128};
char field[MAX_FIELD_LEN];
@@ -547,8 +554,12 @@ void HNMEA_Parse_GPGSA(char* line, GPS_DATA* gps_data)
int len = strlen(line);
int usat = 0; //counter for used satellites
+ //NMEA 4.1: GSA has additional field systemId after VDOP
+ //1=GPS 2=GLONASS 3=Galileo 4=BeiDou
+ int systemId = 0;
- gps_data->valid_new = 0;
+ gns_data->valid_new = 0;
+ gns_data->valid_ext_new = 0;
//outer loop - stop at line end
while ( (l < len ) && (stop == 0) )
@@ -564,10 +575,10 @@ void HNMEA_Parse_GPGSA(char* line, GPS_DATA* gps_data)
switch (i)
{
- case 0: //$GPGSA
+ case 0: //$GPGSA or $GNGSA
{
//cross-check for sentence name
- if (strncmp (field, "$GPGSA", 6) != 0)
+ if ((strncmp (field, "$GPGSA", 6) != 0) && (strncmp (field, "$GNGSA", 6) != 0))
{
// force termination of loop
stop = 1;
@@ -585,21 +596,21 @@ void HNMEA_Parse_GPGSA(char* line, GPS_DATA* gps_data)
{
if (field[0] == '2')
{
- gps_data->fix2d = 1;
- gps_data->fix3d = 0;
+ gns_data->fix2d = 1;
+ gns_data->fix3d = 0;
}
else if (field[0] == '3')
{
- gps_data->fix2d = 1;
- gps_data->fix3d = 1;
+ gns_data->fix2d = 1;
+ gns_data->fix3d = 1;
}
else
{
- gps_data->fix2d = 0;
- gps_data->fix3d = 0;
+ gns_data->fix2d = 0;
+ gns_data->fix3d = 0;
}
- gps_data->valid_new |= GPS_DATA_FIX2D;
- gps_data->valid_new |= GPS_DATA_FIX3D;
+ gns_data->valid_new |= GNS_DATA_FIX2D;
+ gns_data->valid_new |= GNS_DATA_FIX3D;
}
break;
}
@@ -627,8 +638,8 @@ void HNMEA_Parse_GPGSA(char* line, GPS_DATA* gps_data)
//length check
if (strlen (field) >=1)
{
- gps_data->pdop = atof(field);
- gps_data->valid_new |= GPS_DATA_PDOP;
+ gns_data->pdop = atof(field);
+ gns_data->valid_new |= GNS_DATA_PDOP;
}
break;
}
@@ -637,8 +648,8 @@ void HNMEA_Parse_GPGSA(char* line, GPS_DATA* gps_data)
//length check
if (strlen (field) >=1)
{
- gps_data->hdop = atof(field);
- gps_data->valid_new |= GPS_DATA_HDOP;
+ gns_data->hdop = atof(field);
+ gns_data->valid_new |= GNS_DATA_HDOP;
}
break;
}
@@ -647,12 +658,21 @@ void HNMEA_Parse_GPGSA(char* line, GPS_DATA* gps_data)
//length check
if (strlen (field) >=1)
{
- gps_data->vdop = atof(field);
- gps_data->valid_new |= GPS_DATA_VDOP;
+ gns_data->vdop = atof(field);
+ gns_data->valid_new |= GNS_DATA_VDOP;
}
- stop = 1; //ignore all other fields
break;
}
+ case 18: //NMEA 4.1 systemId
+ {
+ //length check
+ if (strlen (field) >=1)
+ {
+ systemId = atoi(field);
+ }
+ stop = 1; //ignore all other fields
+ break;
+ }
default:
{
stop = 1;
@@ -679,15 +699,29 @@ void HNMEA_Parse_GPGSA(char* line, GPS_DATA* gps_data)
if (usat > 0)
{
- gps_data->usat = usat;
- gps_data->valid_new |= GPS_DATA_USAT;
+ if (systemId == 0) //unspecified
+ {
+ gns_data->usat = usat;
+ gns_data->valid_new |= GNS_DATA_USAT;
+ }
+ else if (systemId == 1) //GPS
+ {
+ gns_data->usat_gps = usat;
+ gns_data->valid_ext_new |= GNS_DATA_USAT_GPS;
+ }
+ else if (systemId == 2) //GLONASS
+ {
+ gns_data->usat_glo = usat;
+ gns_data->valid_ext_new |= GNS_DATA_USAT_GLO;
+ }
}
//update validity mask with new data
- gps_data->valid |= gps_data->valid_new;
+ gns_data->valid |= gns_data->valid_new;
+ gns_data->valid_ext |= gns_data->valid_ext_new;
}
-void HNMEA_Parse_GPGST(char* line, GPS_DATA* gps_data)
+void HNMEA_Parse_GST(char* line, GNS_DATA* gns_data)
{
enum { MAX_FIELD_LEN = 128};
char field[MAX_FIELD_LEN];
@@ -703,7 +737,8 @@ void HNMEA_Parse_GPGST(char* line, GPS_DATA* gps_data)
float lon_std = 0.0;
float alt_std = 0.0;
- gps_data->valid_new = 0;
+ gns_data->valid_new = 0;
+ gns_data->valid_ext_new = 0;
//outer loop - stop at line end
while ( (l < len ) && (stop == 0) )
@@ -722,7 +757,7 @@ void HNMEA_Parse_GPGST(char* line, GPS_DATA* gps_data)
case 0: //$GPGST
{
//cross-check for sentence name
- if (strncmp (field, "$GPGST", 6) != 0)
+ if ((strncmp (field, "$GPGST", 6) != 0) && (strncmp (field, "$GNGST", 6) != 0))
{
// force termination of loop
stop = 1;
@@ -734,13 +769,13 @@ void HNMEA_Parse_GPGST(char* line, GPS_DATA* gps_data)
//length check
if (strlen (field) >=6)
{
- gps_data->time_ss = atoi(field+4);
- gps_data->time_ms = (atof(field+4)-gps_data->time_ss)*1000;
+ gns_data->time_ss = atoi(field+4);
+ gns_data->time_ms = (atof(field+4)-gns_data->time_ss)*1000;
field[4] = '\0';
- gps_data->time_mm = atoi(field+2);
+ gns_data->time_mm = atoi(field+2);
field[2] = '\0';
- gps_data->time_hh = atoi(field);
- gps_data->valid_new |= GPS_DATA_TIME;
+ gns_data->time_hh = atoi(field);
+ gns_data->valid_new |= GNS_DATA_TIME;
}
break;
}
@@ -780,8 +815,8 @@ void HNMEA_Parse_GPGST(char* line, GPS_DATA* gps_data)
if ((strlen (field) >=1) && (lat_std_valid))
{
lon_std = atof(field);
- gps_data->hacc = sqrt(lat_std*lat_std + lon_std*lon_std);
- gps_data->valid_new |= GPS_DATA_HACC;
+ gns_data->hacc = sqrt(lat_std*lat_std + lon_std*lon_std);
+ gns_data->valid_new |= GNS_DATA_HACC;
}
break;
}
@@ -791,8 +826,8 @@ void HNMEA_Parse_GPGST(char* line, GPS_DATA* gps_data)
if (strlen (field) >=1)
{
alt_std = atof(field);
- gps_data->vacc = alt_std;
- gps_data->valid_new |= GPS_DATA_VACC;
+ gns_data->vacc = alt_std;
+ gns_data->valid_new |= GNS_DATA_VACC;
}
break;
}
@@ -821,56 +856,57 @@ void HNMEA_Parse_GPGST(char* line, GPS_DATA* gps_data)
}
//update validity mask with new data
- gps_data->valid |= gps_data->valid_new;
+ gns_data->valid |= gns_data->valid_new;
+ gns_data->valid_ext |= gns_data->valid_ext_new;
}
-NMEA_RESULT HNMEA_Parse(char* line, GPS_DATA* gps_data)
+NMEA_RESULT HNMEA_Parse(char* line, GNS_DATA* gns_data)
{
NMEA_RESULT ret = NMEA_UKNOWN;
- if (strncmp (line, "$GPRMC", 6) == 0)
+ if ((strncmp (line, "$GPRMC", 6) == 0) || (strncmp (line, "$GNRMC", 6) == 0))
{
if (HNMEA_Checksum_Valid(line))
{
- HNMEA_Parse_GPRMC(line, gps_data);
- ret = NMEA_GPRMC;
+ HNMEA_Parse_RMC(line, gns_data);
+ ret = NMEA_RMC;
}
else
{
ret = NMEA_BAD_CHKSUM;
}
}
- if (strncmp (line, "$GPGGA", 6) == 0)
+ else if ((strncmp (line, "$GPGGA", 6) == 0) || (strncmp (line, "$GNGGA", 6) == 0))
{
if (HNMEA_Checksum_Valid(line))
{
- HNMEA_Parse_GPGGA(line, gps_data);
- ret = NMEA_GPGGA;
+ HNMEA_Parse_GGA(line, gns_data);
+ ret = NMEA_GGA;
}
else
{
ret = NMEA_BAD_CHKSUM;
}
}
- if (strncmp (line, "$GPGSA", 6) == 0)
+ else if ((strncmp (line, "$GPGSA", 6) == 0) || (strncmp (line, "$GNGSA", 6) == 0))
{
if (HNMEA_Checksum_Valid(line))
{
- HNMEA_Parse_GPGSA(line, gps_data);
- ret = NMEA_GPGSA;
+ HNMEA_Parse_GSA(line, gns_data);
+ ret = NMEA_GSA;
}
else
{
ret = NMEA_BAD_CHKSUM;
}
}
- if (strncmp (line, "$GPGST", 6) == 0)
+ else if ((strncmp (line, "$GPGST", 6) == 0) || (strncmp (line, "$GNGST", 6) == 0))
{
if (HNMEA_Checksum_Valid(line))
{
- HNMEA_Parse_GPGST(line, gps_data);
- ret = NMEA_GPGST;
+ HNMEA_Parse_GST(line, gns_data);
+ ret = NMEA_GST;
}
else
{
diff --git a/gnss-service/src/hnmea.h b/gnss-service/src/hnmea.h
index 2e9a489..a73aefd 100644
--- a/gnss-service/src/hnmea.h
+++ b/gnss-service/src/hnmea.h
@@ -29,36 +29,43 @@ typedef enum {
NMEA_INIT, //initial value - will never be returned by the parser
NMEA_UKNOWN, //unknown content
NMEA_BAD_CHKSUM, //BAD NMEA Checksum
- NMEA_GPRMC, //GPRMC Sentence
- NMEA_GPGGA, //GPGGA Sentence
- NMEA_GPGSA, //GPGSA Sentence
- NMEA_GPGSV, //GPGSV Sentence
- NMEA_GPGST //GPGST Sentence
+ NMEA_RMC, //GxRMC Sentence
+ NMEA_GGA, //GxGGA Sentence
+ NMEA_GSA, //GxGSA Sentence
+ NMEA_GSV, //GxGSV Sentence
+ NMEA_GST //GxGST Sentence
} NMEA_RESULT;
-//bitmap for GPS data
+//bitmaps for GNSS data
typedef enum {
- GPS_DATA_LAT = 0x0001, //latitude
- GPS_DATA_LON = 0x0002, //longitude
- GPS_DATA_ALT = 0x0004, //altitude
- GPS_DATA_GEOID = 0x0008, //geoid separation
- GPS_DATA_DATE = 0x0010, //date
- GPS_DATA_TIME = 0x0020, //time
- GPS_DATA_COURSE = 0x0040, //course (heading)
- GPS_DATA_SPEED = 0x0080, //speed
- GPS_DATA_HDOP = 0x0100, //HDOP
- GPS_DATA_VDOP = 0x0200, //VDOP
- GPS_DATA_PDOP = 0x0400, //PDOP
- GPS_DATA_USAT = 0x0800, //number of used satellites
- GPS_DATA_FIX2D = 0x1000, //at least 2D Fix
- GPS_DATA_FIX3D = 0x2000, //3D Fix (GPS_DATA_FIX2D will be set also)
- GPS_DATA_HACC = 0x4000, //horizontal accuracy
- GPS_DATA_VACC = 0x8000 //vertical accuracy
-} GPS_DATA_TYPE;
+ GNS_DATA_LAT = 0x0001, //latitude
+ GNS_DATA_LON = 0x0002, //longitude
+ GNS_DATA_ALT = 0x0004, //altitude
+ GNS_DATA_GEOID = 0x0008, //geoid separation
+ GNS_DATA_DATE = 0x0010, //date
+ GNS_DATA_TIME = 0x0020, //time
+ GNS_DATA_COURSE = 0x0040, //course (heading)
+ GNS_DATA_SPEED = 0x0080, //speed
+ GNS_DATA_HDOP = 0x0100, //HDOP
+ GNS_DATA_VDOP = 0x0200, //VDOP
+ GNS_DATA_PDOP = 0x0400, //PDOP
+ GNS_DATA_USAT = 0x0800, //number of used satellites
+ GNS_DATA_FIX2D = 0x1000, //at least 2D Fix
+ GNS_DATA_FIX3D = 0x2000, //3D Fix (GPS_DATA_FIX2D will be set also)
+ GNS_DATA_HACC = 0x4000, //horizontal accuracy
+ GNS_DATA_VACC = 0x8000 //vertical accuracy
+} GNS_DATA_TYPE;
+
+typedef enum {
+ GNS_DATA_USAT_GPS = 0x0001, //number of used GPS satellites
+ GNS_DATA_USAT_GLO = 0x0002 //number of used GLONASS satellites
+} GNS_DATA_EXT_TYPE;
typedef struct {
- int valid; //bitmask of GPS_DATA_TYPE for cumulative valid fields
- int valid_new; //bitmask of GPS_DATA_TYPE for new valid fields
+ int valid; //bitmask of GNS_DATA_TYPE for cumulative valid fields
+ int valid_new; //bitmask of GNS_DATA_TYPE for new valid fields
+ int valid_ext; //bitmask of GNS_DATA_EXT_TYPE for cumulative valid fields
+ int valid_ext_new; //bitmask of GNS_DATA_EXT_TYPE for new valid fields
double lat; //latitude in degrees - negative values are south of equator
double lon; //longitude in degrees - negative values are west of Greenwich
double alt; //altitude in meter above sea level
@@ -80,11 +87,13 @@ typedef struct {
int fix3d; //GPS status: 3D Fix - fix2d will be set also
float hacc; //horizontal accuracy in m
float vacc; //vertical accuracy in m
-} GPS_DATA;
+ int usat_gps; //number of GPS satellites
+ int usat_glo; //number of GLONASS satellites
+} GNS_DATA;
-void HNMEA_Init_GPS_DATA(GPS_DATA* gps_data);
+void HNMEA_Init_GNS_DATA(GNS_DATA* gns_data);
-NMEA_RESULT HNMEA_Parse(char* line, GPS_DATA* gps_data);
+NMEA_RESULT HNMEA_Parse(char* line, GNS_DATA* gns_data);
#endif //_HNMEA_H