Skip to content

Commit

Permalink
Update to #71 - Better support for NMEA DOP parsing
Browse files Browse the repository at this point in the history
* See #71 (comment) for details
* Add support for $GPGSA NMEA sentences
* Support parsing VDOP when the checksum appears next to that value without a comma separator
* Catch NumberFormatException and output error message to console in case there are other issues parsing DOP from NMEA
* Add more tests parsing DOP from GSA sentences
  • Loading branch information
barbeau committed Nov 28, 2016
1 parent 92bc2bb commit 2528122
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ public void onNmeaMessage(String message, long timestamp) {
mAltitudeMslView.setText(getString(R.string.gps_altitude_msl_value, altitudeMsl));
}
}
if (message.startsWith("$GNGSA")) {
if (message.startsWith("$GNGSA") || message.startsWith("$GPGSA")) {
DilutionOfPrecision dop = GpsTestUtil.getDop(message);
if (dop != null && mNavigating) {
showDopViews();
Expand Down
32 changes: 23 additions & 9 deletions GPSTest/src/main/java/com/android/gpstest/util/GpsTestUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -223,16 +223,17 @@ public static Double getAltitudeMeanSeaLevel(String nmeaSentence) {
}

/**
* Given a $GPGSA NMEA sentence, return the dilution of precision, or null if dilution of
* Given a $GNGSA or $GPGSA NMEA sentence, return the dilution of precision, or null if dilution of
* precision can't be parsed.
*
* Example inputs are:
* $GNGSA,A,2,67,68,69,79,84,,,,,,,,1.3,1.0,0.8,2*3A
* $GPGSA,A,3,03,14,16,22,23,26,,,,,,,3.6,1.8,3.1*38
* $GNGSA,A,3,03,14,16,22,23,26,,,,,,,3.6,1.8,3.1,1*3B
*
* Example outputs would be:
* PDOP is 1.3, HDOP is 1.0, and VDOP is 0.8
* Example output is:
* PDOP is 3.6, HDOP is 1.8, and VDOP is 3.1
*
* @param nmeaSentence a $GNGSA NMEA sentence
* @param nmeaSentence a $GNGSA or $GPGSA NMEA sentence
* @return the dilution of precision, or null if dilution of precision can't be parsed
*/
public static DilutionOfPrecision getDop(String nmeaSentence) {
Expand All @@ -241,15 +242,28 @@ public static DilutionOfPrecision getDop(String nmeaSentence) {
final int VDOP_INDEX = 17;
String[] tokens = nmeaSentence.split(",");

if (nmeaSentence.startsWith("$GNGSA")) {
if (nmeaSentence.startsWith("$GNGSA") || nmeaSentence.startsWith("$GPGSA")) {
String pdop = tokens[PDOP_INDEX];
String hdop = tokens[HDOP_INDEX];
String vdop = tokens[VDOP_INDEX];

// See https://github.com/barbeau/gpstest/issues/71#issuecomment-263169174
if (vdop.contains("*")) {
vdop = vdop.split("\\*")[0];
}

if (!TextUtils.isEmpty(pdop) && !TextUtils.isEmpty(hdop) && !TextUtils.isEmpty(vdop)) {
return new DilutionOfPrecision(Double.valueOf(pdop), Double.valueOf(hdop),
Double.valueOf(vdop));
DilutionOfPrecision dop = null;
try {
dop = new DilutionOfPrecision(Double.valueOf(pdop), Double.valueOf(hdop),
Double.valueOf(vdop));
} catch (NumberFormatException e) {
// See https://github.com/barbeau/gpstest/issues/71#issuecomment-263169174
Log.e(TAG, "Invalid DOP values in NMEA: " + nmeaSentence);
}
return dop;
} else {
Log.w(TAG, "Couldn't parse DOP from NMEA: " + nmeaSentence);
Log.w(TAG, "Empty DOP values in NMEA: " + nmeaSentence);
return null;
}
} else {
Expand Down
47 changes: 45 additions & 2 deletions GPSTest/src/test/java/com/android/gpstest/GpsTestUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,55 @@ public void testGetAltitudeFromNmea() {
@Test
public void testGetDopFromNmea() {
DilutionOfPrecision dop;
final String sentence = "$GNGSA,A,2,67,68,69,79,84,,,,,,,,1.3,1.0,0.8,2*3A";

dop = GpsTestUtil.getDop(sentence);
// LG G5 w/ Android 6.0.1
final String s1 = "$GNGSA,A,2,67,68,69,79,84,,,,,,,,1.3,1.0,0.8,2*3A";

// LG G5 w/ Android 7.0
final String s2 = "$GPGSA,A,3,03,14,16,22,23,26,,,,,,,3.6,1.8,3.1*38";
final String s3 = "$GNGSA,A,3,03,14,16,22,23,26,,,,,,,3.6,1.8,3.1,1*3B";

// From http://aprs.gids.nl/nmea/#gsa
final String s4 = "$GPGSA,A,3,,,,,,16,18,,22,24,,,3.6,2.1,2.2*3C";
final String s5 = "$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*35";

// From http://www.gpsinformation.org/dale/nmea.htm#GSA
final String s6 = "$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39";

dop = GpsTestUtil.getDop(s1);

assertEquals(1.3d, dop.getPositionDop());
assertEquals(1.0d, dop.getHorizontalDop());
assertEquals(0.8d, dop.getVerticalDop());

dop = GpsTestUtil.getDop(s2);

assertEquals(3.6d, dop.getPositionDop());
assertEquals(1.8d, dop.getHorizontalDop());
assertEquals(3.1d, dop.getVerticalDop());

dop = GpsTestUtil.getDop(s3);

assertEquals(3.6d, dop.getPositionDop());
assertEquals(1.8d, dop.getHorizontalDop());
assertEquals(3.1d, dop.getVerticalDop());

dop = GpsTestUtil.getDop(s4);

assertEquals(3.6d, dop.getPositionDop());
assertEquals(2.1d, dop.getHorizontalDop());
assertEquals(2.2d, dop.getVerticalDop());

dop = GpsTestUtil.getDop(s5);

assertEquals(1.7d, dop.getPositionDop());
assertEquals(1.0d, dop.getHorizontalDop());
assertEquals(1.3d, dop.getVerticalDop());

dop = GpsTestUtil.getDop(s6);

assertEquals(2.5d, dop.getPositionDop());
assertEquals(1.3d, dop.getHorizontalDop());
assertEquals(2.1d, dop.getVerticalDop());
}
}

0 comments on commit 2528122

Please sign in to comment.