Skip to content

Commit 449f25a

Browse files
committed
Create higher precision GST sentence
Work around for issue #513
1 parent 6f62d33 commit 449f25a

File tree

4 files changed

+138
-1
lines changed

4 files changed

+138
-1
lines changed

Firmware/RTK_Everywhere/Developer.ino

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ void pointperfectPrintKeyInformation() {systemPrintln("**PPL Not Compiled**");}
277277
#ifndef COMPILE_LG290P
278278

279279
void lg290pHandler(uint8_t * buffer, int length) {}
280+
void lg290pModifyGst(char *nmeaSentence, uint16_t *sentenceLength) {}
280281

281282
#endif // COMPILE_LG290P
282283

Firmware/RTK_Everywhere/GNSS_LG290P.ino

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,6 @@ uint8_t GNSS_LG290P::getFixType()
10801080
//----------------------------------------
10811081
float GNSS_LG290P::getHorizontalAccuracy()
10821082
{
1083-
// Coming soon from EPE
10841083
if (online.gnss)
10851084
return (_lg290p->get2DError());
10861085
return 0;
@@ -2217,4 +2216,134 @@ bool lg290pMessageEnabled(char *nmeaSentence, int sentenceLength)
22172216

22182217
// If we can't ID this message, allow it by default. The device configuration should control most message flow.
22192218
return (true);
2219+
}
2220+
2221+
// Re-create the GST sentence to increase the horizontal and vertical precision number of decimals
2222+
// ie, 0.0 becomes 0.009
2223+
// See issue: https://github.com/sparkfun/SparkFun_RTK_Everywhere_Firmware/issues/513
2224+
// $GNGST,223954.500,1.7,1.5,1.0,109.3,1.412,1.055,2.4*7E
2225+
// Modifies the sentence length with new length
2226+
void lg290pModifyGst(char *nmeaSentence, uint16_t *sentenceLength)
2227+
{
2228+
// This issue currently only applies to LG290P firmware version 4
2229+
// Version 3 does not support GST messages. Version 5 should fix the issue.
2230+
if (lg290pFirmwareVersion != 4)
2231+
return;
2232+
2233+
if (online.gnss == false)
2234+
return;
2235+
2236+
GNSS_LG290P *lg290p = (GNSS_LG290P *)gnss;
2237+
2238+
// Identify sentence type
2239+
char sentenceType[strlen("GST") + 1] = {0};
2240+
strncpy(sentenceType, &nmeaSentence[3],
2241+
3); // Copy three letters, starting in spot 3. Null terminated from array initializer.
2242+
2243+
// We only care about GST sentences
2244+
if (strncmp(sentenceType, "GST", sizeof(sentenceType)) != 0)
2245+
return;
2246+
2247+
const int latitudeErrorComma = 6;
2248+
const int longitudeErrorComma = 7;
2249+
const int altitudeErrorComma = 8;
2250+
2251+
uint8_t latitudeStart = 0;
2252+
uint8_t latitudeStop = 0;
2253+
uint8_t longitudeStart = 0;
2254+
uint8_t longitudeStop = 0;
2255+
uint8_t altitudeStart = 0;
2256+
uint8_t checksumStart = 0;
2257+
2258+
if (settings.enableImuCompensationDebug == true && !inMainMenu)
2259+
systemPrintf("Original GNGST:\r\n%s\r\n", nmeaSentence);
2260+
2261+
int commaCount = 0;
2262+
for (int x = 0; x < strnlen(nmeaSentence, *sentenceLength); x++) // Assumes sentence is null terminated
2263+
{
2264+
if (nmeaSentence[x] == ',')
2265+
{
2266+
commaCount++;
2267+
if (commaCount == latitudeErrorComma)
2268+
latitudeStart = x + 1;
2269+
if (commaCount == latitudeErrorComma + 1)
2270+
latitudeStop = x;
2271+
if (commaCount == longitudeErrorComma)
2272+
longitudeStart = x + 1;
2273+
if (commaCount == longitudeErrorComma + 1)
2274+
longitudeStop = x;
2275+
if (commaCount == altitudeErrorComma)
2276+
altitudeStart = x + 1;
2277+
}
2278+
if (nmeaSentence[x] == '*')
2279+
{
2280+
checksumStart = x;
2281+
break;
2282+
}
2283+
}
2284+
2285+
if (latitudeStart == 0 || latitudeStop == 0 || longitudeStart == 0 || longitudeStop == 0 || altitudeStart == 0 ||
2286+
checksumStart == 0)
2287+
{
2288+
systemPrintln("Delineator not found");
2289+
return;
2290+
}
2291+
2292+
char newSentence[150] = {0};
2293+
2294+
if (sizeof(newSentence) < *sentenceLength)
2295+
{
2296+
systemPrintln("newSentence not big enough!");
2297+
return;
2298+
}
2299+
2300+
char errorString[strlen("0.000") + 1] = {0};
2301+
2302+
// strncat terminates
2303+
2304+
// Add start of message up to latitude
2305+
strncat(newSentence, nmeaSentence, latitudeStart);
2306+
2307+
// Convert error from EPE message to string. We don't have pure lat error, only 2D and 3D.
2308+
snprintf(errorString, sizeof(errorString), "%0.3f", lg290p->getHorizontalAccuracy());
2309+
2310+
// Add latitude error
2311+
strncat(newSentence, errorString, sizeof(newSentence) - 1);
2312+
2313+
// Add interstitial between end of lat and beginning of lon
2314+
strncat(newSentence, nmeaSentence + latitudeStop, longitudeStart - latitudeStop);
2315+
2316+
// Add same error for longitude error
2317+
strncat(newSentence, errorString, sizeof(newSentence) - 1);
2318+
2319+
// Add interstitial between end of lon and beginning of alt
2320+
strncat(newSentence, nmeaSentence + longitudeStop, altitudeStart - longitudeStop);
2321+
2322+
// Convert error from EPE message to string. We don't have pure altitude error, use double 2D error as stand-in.
2323+
snprintf(errorString, sizeof(errorString), "%0.3f", lg290p->getHorizontalAccuracy() * 2);
2324+
2325+
// Add altitude error. We don't really have altitude so use 3D error in its place.
2326+
strncat(newSentence, errorString, sizeof(newSentence) - 1);
2327+
2328+
// From: http://engineeringnotes.blogspot.com/2015/02/generate-crc-for-nmea-strings-arduino.html
2329+
byte CRC = 0; // XOR chars between '$' and '*'
2330+
for (byte x = 1; x < strlen(newSentence); x++)
2331+
CRC = CRC ^ newSentence[x];
2332+
2333+
// Convert CRC to string, add * and CR LF
2334+
snprintf(errorString, sizeof(errorString), "*%02X\r\n", CRC);
2335+
2336+
// Add CRC
2337+
strncat(newSentence, errorString, sizeof(newSentence) - 1);
2338+
2339+
// Increase length of sentence
2340+
*sentenceLength = strlen(newSentence);
2341+
2342+
// Overwrite the original NMEA
2343+
strncpy(nmeaSentence, newSentence, *sentenceLength);
2344+
2345+
nmeaSentence[*sentenceLength] = '\0'; // Terminate string
2346+
2347+
if (settings.enableImuCompensationDebug == true && !inMainMenu)
2348+
systemPrintf("Corrected GNGST:\r\n%s\r\n", nmeaSentence);
22202349
}

Firmware/RTK_Everywhere/GNSS_None.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,10 @@ class GNSS_None : public GNSS
429429
{
430430
}
431431

432+
void modifyGst(char *nmeaSentence, uint16_t *sentenceLength)
433+
{
434+
}
435+
432436
// Print the module type and firmware version
433437
void printModuleInfo()
434438
{

Firmware/RTK_Everywhere/Tasks.ino

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,9 @@ void processUart1Message(SEMP_PARSE_STATE *parse, uint16_t type)
650650
parse->buffer[0] = 0;
651651
parse->length = 0;
652652
}
653+
654+
// Gimme three decimals!
655+
lg290pModifyGst((char *)parse->buffer, &parse->length);
653656
}
654657
}
655658

0 commit comments

Comments
 (0)