Merge pull request #169 from ladyada-eagleclaw/fix-rmb-partial-update

Preserve waypoint data when RMB parsing fails
This commit is contained in:
Limor "Ladyada" Fried authored and GitHub committed 2026-09-14 20:41:13 -04:00
commit 0b98a99a1c
2 files changed
+68 -13

No files matched your search

+49
View File
@@ -0,0 +1,49 @@
#include <Adafruit_GPS.h>
Adafruit_GPS GPS;
bool testsPassed = false;
void setup() {
Serial.begin(115200);
// Wait briefly for the Serial Monitor on native USB boards.
while (!Serial && millis() < 5000) {
delay(10);
}
delay(250);
Serial.println("Adafruit GPS RMB state regression");
char good[] = "$GPRMB,A,0.10,R,DEST,START,4807.038,N,01131.000,E,1.0,84.4,2.5,A*44";
if (!GPS.parse(good)) {
Serial.println("FAIL: valid RMB sentence was rejected");
return;
}
Serial.println("PASS: valid RMB sentence was accepted");
nmea_float_t crossTrackError = GPS.get(NMEA_XTE);
nmea_float_t latitude = GPS.get(NMEA_LATWP);
nmea_float_t longitude = GPS.get(NMEA_LONWP);
// The checksum is valid, but Q is not a longitude direction.
char bad[] = "$GPRMB,A,0.20,L,OTHER,NEW,4907.038,N,01231.000,Q,2.0,90.0,3.0,A*17";
if (GPS.parse(bad)) {
Serial.println("FAIL: invalid RMB sentence was accepted");
return;
}
Serial.println("PASS: invalid RMB sentence was rejected");
if (GPS.get(NMEA_XTE) != crossTrackError ||
GPS.get(NMEA_LATWP) != latitude || GPS.get(NMEA_LONWP) != longitude ||
strcmp(GPS.toID, "DEST") || strcmp(GPS.fromID, "START")) {
Serial.println("FAIL: rejected sentence changed the waypoint data");
return;
}
Serial.println("PASS: previous waypoint data was preserved");
testsPassed = true;
}
void loop() {
if (testsPassed) {
Serial.println("PASS: RMB state regression");
} else {
Serial.println("FAIL: RMB state regression");
}
delay(2000);
}
+19 -13
View File
@@ -378,16 +378,9 @@ bool Adafruit_GPS::parse(char *nmea) {
if (!isEmpty(p))
xteDir = *p;
p = strchr(p, ',') + 1;
if (xte < 10000.0f && xteDir != 'X') {
if (xteDir == 'L')
xte *= -1.0f;
newDataValue(NMEA_XTE, xte);
}
if (!isEmpty(p))
parseStr(toID, p, NMEA_MAX_WP_ID);
char *toIDField = p;
p = strchr(p, ',') + 1;
if (!isEmpty(p))
parseStr(fromID, p, NMEA_MAX_WP_ID);
char *fromIDField = p;
p = strchr(p, ',') + 1;
nmea_float_t latitudeWP = 0;
nmea_float_t longitudeWP = 0;
@@ -404,8 +397,6 @@ bool Adafruit_GPS::parse(char *nmea) {
if (!parseCoord(p, &latitudeDegreesWP, &latitudeWP, &latitude_fixedWP,
&latWP))
return false;
else
newDataValue(NMEA_LATWP, latitudeDegreesWP);
}
p = strchr(p, ',') + 1;
p = strchr(p, ',') + 1;
@@ -415,9 +406,24 @@ bool Adafruit_GPS::parse(char *nmea) {
if (!parseCoord(p, &longitudeDegreesWP, &longitudeWP, &longitude_fixedWP,
&lonWP))
return false;
else
newDataValue(NMEA_LONWP, longitudeDegreesWP);
}
// Any supplied coordinates passed validation. Save the cross-track error,
// waypoint IDs, and coordinates now; a rejected sentence must leave the
// previous data and history intact.
if (xte < 10000.0f && xteDir != 'X') {
if (xteDir == 'L')
xte *= -1.0f;
newDataValue(NMEA_XTE, xte);
}
if (!isEmpty(toIDField))
parseStr(toID, toIDField, NMEA_MAX_WP_ID);
if (!isEmpty(fromIDField))
parseStr(fromID, fromIDField, NMEA_MAX_WP_ID);
if (latWP != 'X')
newDataValue(NMEA_LATWP, latitudeDegreesWP);
if (lonWP != 'X')
newDataValue(NMEA_LONWP, longitudeDegreesWP);
p = strchr(p, ',') + 1;
p = strchr(p, ',') + 1;
if (!isEmpty(p))