diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index bb2d30b5..5b0ad0d7 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -68,6 +68,19 @@ void perhapsSetRTC(struct tm &t) perhapsSetRTC(&tv); } +// Generate a string representation of the DOP +// based on Wikipedia "meaning of DOP values" https://en.wikipedia.org/wiki/Dilution_of_precision_(navigation)#Meaning_of_DOP_Values +const char *getDOPString(uint32_t dop) { + dop = dop / 100; + if(dop <= 1) return "GPS Ideal"; + if(dop <= 2) return "GPS Exc."; + if(dop <= 5) return "GPS Good"; + if(dop <= 10) return "GPS Mod."; + if(dop <= 20) return "GPS Fair"; + if(dop > 0) return "GPS Poor"; + return "invalid dop"; +} + #include uint32_t getTime() diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 3eb97284..b2d1916d 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -8,6 +8,9 @@ void perhapsSetRTC(const struct timeval *tv); void perhapsSetRTC(struct tm &t); +// Generate a string representation of DOP +const char *getDOPString(uint32_t dop); + /// Return time since 1970 in secs. Until we have a GPS lock we will be returning time based at zero uint32_t getTime(); @@ -31,6 +34,8 @@ class GPS : public Observable public: int32_t latitude = 0, longitude = 0; // as an int mult by 1e-7 to get value as double int32_t altitude = 0; + uint32_t dop = 0; // Diminution of position; PDOP where possible (UBlox), HDOP otherwise (TinyGPS) in 10^2 units (needs scaling before use) + bool isConnected = false; // Do we have a GPS we are talking to virtual ~GPS() {} diff --git a/src/gps/NEMAGPS.cpp b/src/gps/NEMAGPS.cpp index 7d19f886..baba0424 100644 --- a/src/gps/NEMAGPS.cpp +++ b/src/gps/NEMAGPS.cpp @@ -53,9 +53,13 @@ void NEMAGPS::loop() latitude = toDegInt(loc.lat); longitude = toDegInt(loc.lng); } + // Diminution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it + if(reader.hdop.isValid()) { + dop = reader.hdop.value(); + } // expect gps pos lat=37.520825, lon=-122.309162, alt=158 - DEBUG_MSG("new NEMA GPS pos lat=%f, lon=%f, alt=%d\n", latitude * 1e-7, longitude * 1e-7, altitude); + DEBUG_MSG("new NEMA GPS pos lat=%f, lon=%f, alt=%d, hdop=%f\n", latitude * 1e-7, longitude * 1e-7, altitude, dop * 1e-2); hasValidLocation = (latitude != 0) || (longitude != 0); // bogus lat lon is reported as 0,0 if (hasValidLocation) diff --git a/src/gps/UBloxGPS.cpp b/src/gps/UBloxGPS.cpp index 1e4bad8b..8427e68b 100644 --- a/src/gps/UBloxGPS.cpp +++ b/src/gps/UBloxGPS.cpp @@ -115,7 +115,8 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s latitude = ublox.getLatitude(); longitude = ublox.getLongitude(); altitude = ublox.getAltitude() / 1000; // in mm convert to meters - DEBUG_MSG("new gps pos lat=%f, lon=%f, alt=%d\n", latitude * 1e-7, longitude * 1e-7, altitude); + dop = ublox.getPDOP(); // PDOP (an accuracy metric) is reported in 10^2 units so we have to scale down when we use it + DEBUG_MSG("new gps pos lat=%f, lon=%f, alt=%d, pdop=%f\n", latitude * 1e-7, longitude * 1e-7, altitude, dop * 1e-2); // bogus lat lon is reported as 0 or 0 (can be bogus just for one) // Also: apparently when the GPS is initially reporting lock it can output a bogus latitude > 90 deg! diff --git a/src/main.cpp b/src/main.cpp index d79f2856..8493aab8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -361,8 +361,7 @@ void loop() screen.debug()->setNodeNumbersStatus(nodeDB.getNumOnlineNodes(), nodeDB.getNumNodes()); screen.debug()->setChannelNameStatus(channelSettings.name); screen.debug()->setPowerStatus(powerStatus); - // TODO(#4): use something based on hdop to show GPS "signal" strength. - screen.debug()->setGPSStatus(gps->isConnected ? (gps->hasLock() ? "GPS ok" : "No Sats") : "No GPS"); + screen.debug()->setGPSStatus(gps->isConnected ? (gps->hasLock() ? getDOPString(gps->dop) : "No Sats") : "No GPS"); // No GPS lock yet, let the OS put the main CPU in low power mode for 100ms (or until another interrupt comes in) // i.e. don't just keep spinning in loop as fast as we can.