Merge "Generate position report NMEAs only on final fix"
This commit is contained in:
commit
db2e850287
3 changed files with 401 additions and 376 deletions
|
@ -1620,7 +1620,10 @@ static void loc_eng_deferred_action_thread(void* arg)
|
||||||
|
|
||||||
if (loc_eng_data_p->generateNmea && rpMsg->location.position_source == ULP_LOCATION_IS_FROM_GNSS)
|
if (loc_eng_data_p->generateNmea && rpMsg->location.position_source == ULP_LOCATION_IS_FROM_GNSS)
|
||||||
{
|
{
|
||||||
loc_eng_nmea_generate_pos(loc_eng_data_p, rpMsg->location, rpMsg->locationExtended);
|
unsigned char generate_nmea = reported && (rpMsg->status != LOC_SESS_FAILURE);
|
||||||
|
loc_eng_nmea_generate_pos(loc_eng_data_p, rpMsg->location,
|
||||||
|
rpMsg->locationExtended,
|
||||||
|
generate_nmea);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the allocated memory for rawData
|
// Free the allocated memory for rawData
|
||||||
|
|
|
@ -110,7 +110,9 @@ SIDE EFFECTS
|
||||||
|
|
||||||
===========================================================================*/
|
===========================================================================*/
|
||||||
void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p,
|
void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p,
|
||||||
const UlpLocation &location, const GpsLocationExtended &locationExtended)
|
const UlpLocation &location,
|
||||||
|
const GpsLocationExtended &locationExtended,
|
||||||
|
unsigned char generate_nmea)
|
||||||
{
|
{
|
||||||
ENTRY_LOG();
|
ENTRY_LOG();
|
||||||
|
|
||||||
|
@ -128,46 +130,32 @@ void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p,
|
||||||
int utcMinutes = pTm->tm_min;
|
int utcMinutes = pTm->tm_min;
|
||||||
int utcSeconds = pTm->tm_sec;
|
int utcSeconds = pTm->tm_sec;
|
||||||
|
|
||||||
// ------------------
|
if (generate_nmea) {
|
||||||
// ------$GPGSA------
|
// ------------------
|
||||||
// ------------------
|
// ------$GPGSA------
|
||||||
|
// ------------------
|
||||||
|
|
||||||
uint32_t svUsedCount = 0;
|
uint32_t svUsedCount = 0;
|
||||||
uint32_t svUsedList[32] = {0};
|
uint32_t svUsedList[32] = {0};
|
||||||
uint32_t mask = loc_eng_data_p->sv_used_mask;
|
uint32_t mask = loc_eng_data_p->sv_used_mask;
|
||||||
for (uint8_t i = 1; mask > 0 && svUsedCount < 32; i++)
|
for (uint8_t i = 1; mask > 0 && svUsedCount < 32; i++)
|
||||||
{
|
{
|
||||||
if (mask & 1)
|
if (mask & 1)
|
||||||
svUsedList[svUsedCount++] = i;
|
svUsedList[svUsedCount++] = i;
|
||||||
mask = mask >> 1;
|
mask = mask >> 1;
|
||||||
}
|
}
|
||||||
// clear the cache so they can't be used again
|
// clear the cache so they can't be used again
|
||||||
loc_eng_data_p->sv_used_mask = 0;
|
loc_eng_data_p->sv_used_mask = 0;
|
||||||
|
|
||||||
char fixType;
|
char fixType;
|
||||||
if (svUsedCount == 0)
|
if (svUsedCount == 0)
|
||||||
fixType = '1'; // no fix
|
fixType = '1'; // no fix
|
||||||
else if (svUsedCount <= 3)
|
else if (svUsedCount <= 3)
|
||||||
fixType = '2'; // 2D fix
|
fixType = '2'; // 2D fix
|
||||||
else
|
|
||||||
fixType = '3'; // 3D fix
|
|
||||||
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "$GPGSA,A,%c,", fixType);
|
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
|
||||||
{
|
|
||||||
LOC_LOGE("NMEA Error in string formatting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pMarker += length;
|
|
||||||
lengthRemaining -= length;
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 12; i++) // only the first 12 sv go in sentence
|
|
||||||
{
|
|
||||||
if (i < svUsedCount)
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%02d,", svUsedList[i]);
|
|
||||||
else
|
else
|
||||||
length = snprintf(pMarker, lengthRemaining, ",");
|
fixType = '3'; // 3D fix
|
||||||
|
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "$GPGSA,A,%c,", fixType);
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
if (length < 0 || length >= lengthRemaining)
|
||||||
{
|
{
|
||||||
|
@ -176,378 +164,412 @@ void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p,
|
||||||
}
|
}
|
||||||
pMarker += length;
|
pMarker += length;
|
||||||
lengthRemaining -= length;
|
lengthRemaining -= length;
|
||||||
}
|
|
||||||
|
|
||||||
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
|
for (uint8_t i = 0; i < 12; i++) // only the first 12 sv go in sentence
|
||||||
{ // dop is in locationExtended, (QMI)
|
{
|
||||||
length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f",
|
if (i < svUsedCount)
|
||||||
locationExtended.pdop,
|
length = snprintf(pMarker, lengthRemaining, "%02d,", svUsedList[i]);
|
||||||
locationExtended.hdop,
|
else
|
||||||
locationExtended.vdop);
|
length = snprintf(pMarker, lengthRemaining, ",");
|
||||||
}
|
|
||||||
else if (loc_eng_data_p->pdop > 0 && loc_eng_data_p->hdop > 0 && loc_eng_data_p->vdop > 0)
|
|
||||||
{ // dop was cached from sv report (RPC)
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f",
|
|
||||||
loc_eng_data_p->pdop,
|
|
||||||
loc_eng_data_p->hdop,
|
|
||||||
loc_eng_data_p->vdop);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // no dop
|
|
||||||
length = snprintf(pMarker, lengthRemaining, ",,");
|
|
||||||
}
|
|
||||||
|
|
||||||
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
|
if (length < 0 || length >= lengthRemaining)
|
||||||
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
|
{
|
||||||
|
LOC_LOGE("NMEA Error in string formatting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pMarker += length;
|
||||||
|
lengthRemaining -= length;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------
|
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
|
||||||
// ------$GPVTG------
|
{ // dop is in locationExtended, (QMI)
|
||||||
// ------------------
|
length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f",
|
||||||
|
locationExtended.pdop,
|
||||||
|
locationExtended.hdop,
|
||||||
|
locationExtended.vdop);
|
||||||
|
}
|
||||||
|
else if (loc_eng_data_p->pdop > 0 && loc_eng_data_p->hdop > 0 && loc_eng_data_p->vdop > 0)
|
||||||
|
{ // dop was cached from sv report (RPC)
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f",
|
||||||
|
loc_eng_data_p->pdop,
|
||||||
|
loc_eng_data_p->hdop,
|
||||||
|
loc_eng_data_p->vdop);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // no dop
|
||||||
|
length = snprintf(pMarker, lengthRemaining, ",,");
|
||||||
|
}
|
||||||
|
|
||||||
pMarker = sentence;
|
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
|
||||||
lengthRemaining = sizeof(sentence);
|
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
|
||||||
|
|
||||||
|
// ------------------
|
||||||
|
// ------$GPVTG------
|
||||||
|
// ------------------
|
||||||
|
|
||||||
|
pMarker = sentence;
|
||||||
|
lengthRemaining = sizeof(sentence);
|
||||||
|
|
||||||
|
if (location.gpsLocation.flags & GPS_LOCATION_HAS_BEARING)
|
||||||
|
{
|
||||||
|
float magTrack = location.gpsLocation.bearing;
|
||||||
|
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV)
|
||||||
|
{
|
||||||
|
float magTrack = location.gpsLocation.bearing - locationExtended.magneticDeviation;
|
||||||
|
if (magTrack < 0.0)
|
||||||
|
magTrack += 360.0;
|
||||||
|
else if (magTrack > 360.0)
|
||||||
|
magTrack -= 360.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "$GPVTG,%.1lf,T,%.1lf,M,", location.gpsLocation.bearing, magTrack);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "$GPVTG,,T,,M,");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length < 0 || length >= lengthRemaining)
|
||||||
|
{
|
||||||
|
LOC_LOGE("NMEA Error in string formatting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pMarker += length;
|
||||||
|
lengthRemaining -= length;
|
||||||
|
|
||||||
|
if (location.gpsLocation.flags & GPS_LOCATION_HAS_SPEED)
|
||||||
|
{
|
||||||
|
float speedKnots = location.gpsLocation.speed * (3600.0/1852.0);
|
||||||
|
float speedKmPerHour = location.gpsLocation.speed * 3.6;
|
||||||
|
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%.1lf,N,%.1lf,K,", speedKnots, speedKmPerHour);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = snprintf(pMarker, lengthRemaining, ",N,,K,");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length < 0 || length >= lengthRemaining)
|
||||||
|
{
|
||||||
|
LOC_LOGE("NMEA Error in string formatting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pMarker += length;
|
||||||
|
lengthRemaining -= length;
|
||||||
|
|
||||||
|
if (!(location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG))
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%c", 'N'); // N means no fix
|
||||||
|
else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->client_handle->getPositionMode().mode)
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%c", 'A'); // A means autonomous
|
||||||
|
else
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%c", 'D'); // D means differential
|
||||||
|
|
||||||
|
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
|
||||||
|
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
|
||||||
|
|
||||||
|
// ------------------
|
||||||
|
// ------$GPRMC------
|
||||||
|
// ------------------
|
||||||
|
|
||||||
|
pMarker = sentence;
|
||||||
|
lengthRemaining = sizeof(sentence);
|
||||||
|
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "$GPRMC,%02d%02d%02d,A," ,
|
||||||
|
utcHours, utcMinutes, utcSeconds);
|
||||||
|
|
||||||
|
if (length < 0 || length >= lengthRemaining)
|
||||||
|
{
|
||||||
|
LOC_LOGE("NMEA Error in string formatting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pMarker += length;
|
||||||
|
lengthRemaining -= length;
|
||||||
|
|
||||||
|
if (location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG)
|
||||||
|
{
|
||||||
|
double latitude = location.gpsLocation.latitude;
|
||||||
|
double longitude = location.gpsLocation.longitude;
|
||||||
|
char latHemisphere;
|
||||||
|
char lonHemisphere;
|
||||||
|
double latMinutes;
|
||||||
|
double lonMinutes;
|
||||||
|
|
||||||
|
if (latitude > 0)
|
||||||
|
{
|
||||||
|
latHemisphere = 'N';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
latHemisphere = 'S';
|
||||||
|
latitude *= -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (longitude < 0)
|
||||||
|
{
|
||||||
|
lonHemisphere = 'W';
|
||||||
|
longitude *= -1.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lonHemisphere = 'E';
|
||||||
|
}
|
||||||
|
|
||||||
|
latMinutes = fmod(latitude * 60.0 , 60.0);
|
||||||
|
lonMinutes = fmod(longitude * 60.0 , 60.0);
|
||||||
|
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,",
|
||||||
|
(uint8_t)floor(latitude), latMinutes, latHemisphere,
|
||||||
|
(uint8_t)floor(longitude),lonMinutes, lonHemisphere);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = snprintf(pMarker, lengthRemaining,",,,,");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length < 0 || length >= lengthRemaining)
|
||||||
|
{
|
||||||
|
LOC_LOGE("NMEA Error in string formatting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pMarker += length;
|
||||||
|
lengthRemaining -= length;
|
||||||
|
|
||||||
|
if (location.gpsLocation.flags & GPS_LOCATION_HAS_SPEED)
|
||||||
|
{
|
||||||
|
float speedKnots = location.gpsLocation.speed * (3600.0/1852.0);
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%.1lf,", speedKnots);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = snprintf(pMarker, lengthRemaining, ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length < 0 || length >= lengthRemaining)
|
||||||
|
{
|
||||||
|
LOC_LOGE("NMEA Error in string formatting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pMarker += length;
|
||||||
|
lengthRemaining -= length;
|
||||||
|
|
||||||
|
if (location.gpsLocation.flags & GPS_LOCATION_HAS_BEARING)
|
||||||
|
{
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%.1lf,", location.gpsLocation.bearing);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = snprintf(pMarker, lengthRemaining, ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length < 0 || length >= lengthRemaining)
|
||||||
|
{
|
||||||
|
LOC_LOGE("NMEA Error in string formatting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pMarker += length;
|
||||||
|
lengthRemaining -= length;
|
||||||
|
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%2.2d%2.2d%2.2d,",
|
||||||
|
utcDay, utcMonth, utcYear);
|
||||||
|
|
||||||
|
if (length < 0 || length >= lengthRemaining)
|
||||||
|
{
|
||||||
|
LOC_LOGE("NMEA Error in string formatting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pMarker += length;
|
||||||
|
lengthRemaining -= length;
|
||||||
|
|
||||||
if (location.gpsLocation.flags & GPS_LOCATION_HAS_BEARING)
|
|
||||||
{
|
|
||||||
float magTrack = location.gpsLocation.bearing;
|
|
||||||
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV)
|
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV)
|
||||||
{
|
{
|
||||||
float magTrack = location.gpsLocation.bearing - locationExtended.magneticDeviation;
|
float magneticVariation = locationExtended.magneticDeviation;
|
||||||
if (magTrack < 0.0)
|
char direction;
|
||||||
magTrack += 360.0;
|
if (magneticVariation < 0.0)
|
||||||
else if (magTrack > 360.0)
|
{
|
||||||
magTrack -= 360.0;
|
direction = 'W';
|
||||||
}
|
magneticVariation *= -1.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
direction = 'E';
|
||||||
|
}
|
||||||
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "$GPVTG,%.1lf,T,%.1lf,M,", location.gpsLocation.bearing, magTrack);
|
length = snprintf(pMarker, lengthRemaining, "%.1lf,%c,",
|
||||||
}
|
magneticVariation, direction);
|
||||||
else
|
|
||||||
{
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "$GPVTG,,T,,M,");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
|
||||||
{
|
|
||||||
LOC_LOGE("NMEA Error in string formatting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pMarker += length;
|
|
||||||
lengthRemaining -= length;
|
|
||||||
|
|
||||||
if (location.gpsLocation.flags & GPS_LOCATION_HAS_SPEED)
|
|
||||||
{
|
|
||||||
float speedKnots = location.gpsLocation.speed * (3600.0/1852.0);
|
|
||||||
float speedKmPerHour = location.gpsLocation.speed * 3.6;
|
|
||||||
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%.1lf,N,%.1lf,K,", speedKnots, speedKmPerHour);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = snprintf(pMarker, lengthRemaining, ",N,,K,");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
|
||||||
{
|
|
||||||
LOC_LOGE("NMEA Error in string formatting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pMarker += length;
|
|
||||||
lengthRemaining -= length;
|
|
||||||
|
|
||||||
if (!(location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG))
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%c", 'N'); // N means no fix
|
|
||||||
else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->client_handle->getPositionMode().mode)
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%c", 'A'); // A means autonomous
|
|
||||||
else
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%c", 'D'); // D means differential
|
|
||||||
|
|
||||||
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
|
|
||||||
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
|
|
||||||
|
|
||||||
// ------------------
|
|
||||||
// ------$GPRMC------
|
|
||||||
// ------------------
|
|
||||||
|
|
||||||
pMarker = sentence;
|
|
||||||
lengthRemaining = sizeof(sentence);
|
|
||||||
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "$GPRMC,%02d%02d%02d,A," ,
|
|
||||||
utcHours, utcMinutes, utcSeconds);
|
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
|
||||||
{
|
|
||||||
LOC_LOGE("NMEA Error in string formatting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pMarker += length;
|
|
||||||
lengthRemaining -= length;
|
|
||||||
|
|
||||||
if (location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG)
|
|
||||||
{
|
|
||||||
double latitude = location.gpsLocation.latitude;
|
|
||||||
double longitude = location.gpsLocation.longitude;
|
|
||||||
char latHemisphere;
|
|
||||||
char lonHemisphere;
|
|
||||||
double latMinutes;
|
|
||||||
double lonMinutes;
|
|
||||||
|
|
||||||
if (latitude > 0)
|
|
||||||
{
|
|
||||||
latHemisphere = 'N';
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
latHemisphere = 'S';
|
length = snprintf(pMarker, lengthRemaining, ",,");
|
||||||
latitude *= -1.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (longitude < 0)
|
if (length < 0 || length >= lengthRemaining)
|
||||||
{
|
{
|
||||||
lonHemisphere = 'W';
|
LOC_LOGE("NMEA Error in string formatting");
|
||||||
longitude *= -1.0;
|
return;
|
||||||
|
}
|
||||||
|
pMarker += length;
|
||||||
|
lengthRemaining -= length;
|
||||||
|
|
||||||
|
if (!(location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG))
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%c", 'N'); // N means no fix
|
||||||
|
else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->client_handle->getPositionMode().mode)
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%c", 'A'); // A means autonomous
|
||||||
|
else
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%c", 'D'); // D means differential
|
||||||
|
|
||||||
|
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
|
||||||
|
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
|
||||||
|
|
||||||
|
// ------------------
|
||||||
|
// ------$GPGGA------
|
||||||
|
// ------------------
|
||||||
|
|
||||||
|
pMarker = sentence;
|
||||||
|
lengthRemaining = sizeof(sentence);
|
||||||
|
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "$GPGGA,%02d%02d%02d," ,
|
||||||
|
utcHours, utcMinutes, utcSeconds);
|
||||||
|
|
||||||
|
if (length < 0 || length >= lengthRemaining)
|
||||||
|
{
|
||||||
|
LOC_LOGE("NMEA Error in string formatting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pMarker += length;
|
||||||
|
lengthRemaining -= length;
|
||||||
|
|
||||||
|
if (location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG)
|
||||||
|
{
|
||||||
|
double latitude = location.gpsLocation.latitude;
|
||||||
|
double longitude = location.gpsLocation.longitude;
|
||||||
|
char latHemisphere;
|
||||||
|
char lonHemisphere;
|
||||||
|
double latMinutes;
|
||||||
|
double lonMinutes;
|
||||||
|
|
||||||
|
if (latitude > 0)
|
||||||
|
{
|
||||||
|
latHemisphere = 'N';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
latHemisphere = 'S';
|
||||||
|
latitude *= -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (longitude < 0)
|
||||||
|
{
|
||||||
|
lonHemisphere = 'W';
|
||||||
|
longitude *= -1.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lonHemisphere = 'E';
|
||||||
|
}
|
||||||
|
|
||||||
|
latMinutes = fmod(latitude * 60.0 , 60.0);
|
||||||
|
lonMinutes = fmod(longitude * 60.0 , 60.0);
|
||||||
|
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,",
|
||||||
|
(uint8_t)floor(latitude), latMinutes, latHemisphere,
|
||||||
|
(uint8_t)floor(longitude),lonMinutes, lonHemisphere);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lonHemisphere = 'E';
|
length = snprintf(pMarker, lengthRemaining,",,,,");
|
||||||
}
|
}
|
||||||
|
|
||||||
latMinutes = fmod(latitude * 60.0 , 60.0);
|
if (length < 0 || length >= lengthRemaining)
|
||||||
lonMinutes = fmod(longitude * 60.0 , 60.0);
|
|
||||||
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,",
|
|
||||||
(uint8_t)floor(latitude), latMinutes, latHemisphere,
|
|
||||||
(uint8_t)floor(longitude),lonMinutes, lonHemisphere);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = snprintf(pMarker, lengthRemaining,",,,,");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
|
||||||
{
|
|
||||||
LOC_LOGE("NMEA Error in string formatting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pMarker += length;
|
|
||||||
lengthRemaining -= length;
|
|
||||||
|
|
||||||
if (location.gpsLocation.flags & GPS_LOCATION_HAS_SPEED)
|
|
||||||
{
|
|
||||||
float speedKnots = location.gpsLocation.speed * (3600.0/1852.0);
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%.1lf,", speedKnots);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = snprintf(pMarker, lengthRemaining, ",");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
|
||||||
{
|
|
||||||
LOC_LOGE("NMEA Error in string formatting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pMarker += length;
|
|
||||||
lengthRemaining -= length;
|
|
||||||
|
|
||||||
if (location.gpsLocation.flags & GPS_LOCATION_HAS_BEARING)
|
|
||||||
{
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%.1lf,", location.gpsLocation.bearing);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = snprintf(pMarker, lengthRemaining, ",");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
|
||||||
{
|
|
||||||
LOC_LOGE("NMEA Error in string formatting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pMarker += length;
|
|
||||||
lengthRemaining -= length;
|
|
||||||
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%2.2d%2.2d%2.2d,",
|
|
||||||
utcDay, utcMonth, utcYear);
|
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
|
||||||
{
|
|
||||||
LOC_LOGE("NMEA Error in string formatting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pMarker += length;
|
|
||||||
lengthRemaining -= length;
|
|
||||||
|
|
||||||
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV)
|
|
||||||
{
|
|
||||||
float magneticVariation = locationExtended.magneticDeviation;
|
|
||||||
char direction;
|
|
||||||
if (magneticVariation < 0.0)
|
|
||||||
{
|
{
|
||||||
direction = 'W';
|
LOC_LOGE("NMEA Error in string formatting");
|
||||||
magneticVariation *= -1.0;
|
return;
|
||||||
|
}
|
||||||
|
pMarker += length;
|
||||||
|
lengthRemaining -= length;
|
||||||
|
|
||||||
|
char gpsQuality;
|
||||||
|
if (!(location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG))
|
||||||
|
gpsQuality = '0'; // 0 means no fix
|
||||||
|
else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->client_handle->getPositionMode().mode)
|
||||||
|
gpsQuality = '1'; // 1 means GPS fix
|
||||||
|
else
|
||||||
|
gpsQuality = '2'; // 2 means DGPS fix
|
||||||
|
|
||||||
|
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
|
||||||
|
{ // dop is in locationExtended, (QMI)
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%c,%02d,%.1f,",
|
||||||
|
gpsQuality, svUsedCount, locationExtended.hdop);
|
||||||
|
}
|
||||||
|
else if (loc_eng_data_p->pdop > 0 && loc_eng_data_p->hdop > 0 && loc_eng_data_p->vdop > 0)
|
||||||
|
{ // dop was cached from sv report (RPC)
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%c,%02d,%.1f,",
|
||||||
|
gpsQuality, svUsedCount, loc_eng_data_p->hdop);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // no hdop
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%c,%02d,,",
|
||||||
|
gpsQuality, svUsedCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length < 0 || length >= lengthRemaining)
|
||||||
|
{
|
||||||
|
LOC_LOGE("NMEA Error in string formatting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pMarker += length;
|
||||||
|
lengthRemaining -= length;
|
||||||
|
|
||||||
|
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL)
|
||||||
|
{
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%.1lf,M,",
|
||||||
|
locationExtended.altitudeMeanSeaLevel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
direction = 'E';
|
length = snprintf(pMarker, lengthRemaining,",,");
|
||||||
}
|
}
|
||||||
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%.1lf,%c,",
|
if (length < 0 || length >= lengthRemaining)
|
||||||
magneticVariation, direction);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = snprintf(pMarker, lengthRemaining, ",,");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
|
||||||
{
|
|
||||||
LOC_LOGE("NMEA Error in string formatting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pMarker += length;
|
|
||||||
lengthRemaining -= length;
|
|
||||||
|
|
||||||
if (!(location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG))
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%c", 'N'); // N means no fix
|
|
||||||
else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->client_handle->getPositionMode().mode)
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%c", 'A'); // A means autonomous
|
|
||||||
else
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%c", 'D'); // D means differential
|
|
||||||
|
|
||||||
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
|
|
||||||
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
|
|
||||||
|
|
||||||
// ------------------
|
|
||||||
// ------$GPGGA------
|
|
||||||
// ------------------
|
|
||||||
|
|
||||||
pMarker = sentence;
|
|
||||||
lengthRemaining = sizeof(sentence);
|
|
||||||
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "$GPGGA,%02d%02d%02d," ,
|
|
||||||
utcHours, utcMinutes, utcSeconds);
|
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
|
||||||
{
|
|
||||||
LOC_LOGE("NMEA Error in string formatting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pMarker += length;
|
|
||||||
lengthRemaining -= length;
|
|
||||||
|
|
||||||
if (location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG)
|
|
||||||
{
|
|
||||||
double latitude = location.gpsLocation.latitude;
|
|
||||||
double longitude = location.gpsLocation.longitude;
|
|
||||||
char latHemisphere;
|
|
||||||
char lonHemisphere;
|
|
||||||
double latMinutes;
|
|
||||||
double lonMinutes;
|
|
||||||
|
|
||||||
if (latitude > 0)
|
|
||||||
{
|
{
|
||||||
latHemisphere = 'N';
|
LOC_LOGE("NMEA Error in string formatting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pMarker += length;
|
||||||
|
lengthRemaining -= length;
|
||||||
|
|
||||||
|
if ((location.gpsLocation.flags & GPS_LOCATION_HAS_ALTITUDE) &&
|
||||||
|
(locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL))
|
||||||
|
{
|
||||||
|
length = snprintf(pMarker, lengthRemaining, "%.1lf,M,,",
|
||||||
|
location.gpsLocation.altitude - locationExtended.altitudeMeanSeaLevel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
latHemisphere = 'S';
|
length = snprintf(pMarker, lengthRemaining,",,,");
|
||||||
latitude *= -1.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (longitude < 0)
|
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
|
||||||
{
|
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
|
||||||
lonHemisphere = 'W';
|
|
||||||
longitude *= -1.0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lonHemisphere = 'E';
|
|
||||||
}
|
|
||||||
|
|
||||||
latMinutes = fmod(latitude * 60.0 , 60.0);
|
}
|
||||||
lonMinutes = fmod(longitude * 60.0 , 60.0);
|
//Send blank NMEA reports for non-final fixes
|
||||||
|
else {
|
||||||
|
strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
|
||||||
|
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
|
||||||
|
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
|
||||||
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,",
|
strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence));
|
||||||
(uint8_t)floor(latitude), latMinutes, latHemisphere,
|
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
|
||||||
(uint8_t)floor(longitude),lonMinutes, lonHemisphere);
|
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = snprintf(pMarker, lengthRemaining,",,,,");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
strlcpy(sentence, "$GPRMC,,V,,,,,,,,,,N", sizeof(sentence));
|
||||||
{
|
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
|
||||||
LOC_LOGE("NMEA Error in string formatting");
|
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
|
||||||
return;
|
|
||||||
}
|
|
||||||
pMarker += length;
|
|
||||||
lengthRemaining -= length;
|
|
||||||
|
|
||||||
char gpsQuality;
|
strlcpy(sentence, "$GPGGA,,,,,,0,,,,,,,,", sizeof(sentence));
|
||||||
if (!(location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG))
|
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
|
||||||
gpsQuality = '0'; // 0 means no fix
|
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
|
||||||
else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->client_handle->getPositionMode().mode)
|
|
||||||
gpsQuality = '1'; // 1 means GPS fix
|
|
||||||
else
|
|
||||||
gpsQuality = '2'; // 2 means DGPS fix
|
|
||||||
|
|
||||||
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
|
|
||||||
{ // dop is in locationExtended, (QMI)
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%c,%02d,%.1f,",
|
|
||||||
gpsQuality, svUsedCount, locationExtended.hdop);
|
|
||||||
}
|
}
|
||||||
else if (loc_eng_data_p->pdop > 0 && loc_eng_data_p->hdop > 0 && loc_eng_data_p->vdop > 0)
|
|
||||||
{ // dop was cached from sv report (RPC)
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%c,%02d,%.1f,",
|
|
||||||
gpsQuality, svUsedCount, loc_eng_data_p->hdop);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // no hdop
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%c,%02d,,",
|
|
||||||
gpsQuality, svUsedCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
|
||||||
{
|
|
||||||
LOC_LOGE("NMEA Error in string formatting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pMarker += length;
|
|
||||||
lengthRemaining -= length;
|
|
||||||
|
|
||||||
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL)
|
|
||||||
{
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%.1lf,M,",
|
|
||||||
locationExtended.altitudeMeanSeaLevel);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = snprintf(pMarker, lengthRemaining,",,");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length < 0 || length >= lengthRemaining)
|
|
||||||
{
|
|
||||||
LOC_LOGE("NMEA Error in string formatting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pMarker += length;
|
|
||||||
lengthRemaining -= length;
|
|
||||||
|
|
||||||
if ((location.gpsLocation.flags & GPS_LOCATION_HAS_ALTITUDE) &&
|
|
||||||
(locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL))
|
|
||||||
{
|
|
||||||
length = snprintf(pMarker, lengthRemaining, "%.1lf,M,,",
|
|
||||||
location.gpsLocation.altitude - locationExtended.altitudeMeanSeaLevel);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = snprintf(pMarker, lengthRemaining,",,,");
|
|
||||||
}
|
|
||||||
|
|
||||||
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
|
|
||||||
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
|
|
||||||
|
|
||||||
// clear the dop cache so they can't be used again
|
// clear the dop cache so they can't be used again
|
||||||
loc_eng_data_p->pdop = 0;
|
loc_eng_data_p->pdop = 0;
|
||||||
loc_eng_data_p->hdop = 0;
|
loc_eng_data_p->hdop = 0;
|
||||||
|
|
|
@ -37,6 +37,6 @@
|
||||||
void loc_eng_nmea_send(char *pNmea, int length, loc_eng_data_s_type *loc_eng_data_p);
|
void loc_eng_nmea_send(char *pNmea, int length, loc_eng_data_s_type *loc_eng_data_p);
|
||||||
int loc_eng_nmea_put_checksum(char *pNmea, int maxSize);
|
int loc_eng_nmea_put_checksum(char *pNmea, int maxSize);
|
||||||
void loc_eng_nmea_generate_sv(loc_eng_data_s_type *loc_eng_data_p, const GpsSvStatus &svStatus, const GpsLocationExtended &locationExtended);
|
void loc_eng_nmea_generate_sv(loc_eng_data_s_type *loc_eng_data_p, const GpsSvStatus &svStatus, const GpsLocationExtended &locationExtended);
|
||||||
void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p, const UlpLocation &location, const GpsLocationExtended &locationExtended);
|
void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p, const UlpLocation &location, const GpsLocationExtended &locationExtended, unsigned char generate_nmea);
|
||||||
|
|
||||||
#endif // LOC_ENG_NMEA_H
|
#endif // LOC_ENG_NMEA_H
|
||||||
|
|
Loading…
Reference in a new issue