From b7beb48955811513e438b3ddbeb7e5639367afe8 Mon Sep 17 00:00:00 2001 From: Balamurugan Kandan Date: Fri, 11 Dec 2020 01:36:56 +0530 Subject: [PATCH 1/4] getSpeedAccEst, getHeadingAccEst, getInvalidLlh, getHeadVeh, getMagDec and getMagAcc functions implemented. --- keywords.txt | 6 ++ src/SparkFun_Ublox_Arduino_Library.cpp | 76 +++++++++++++++++++++++++- src/SparkFun_Ublox_Arduino_Library.h | 24 ++++++-- 3 files changed, 98 insertions(+), 8 deletions(-) diff --git a/keywords.txt b/keywords.txt index 7c1dbe4..6272770 100644 --- a/keywords.txt +++ b/keywords.txt @@ -58,6 +58,12 @@ getVerticalAccEst KEYWORD2 getNedNorthVel KEYWORD2 getNedEastVel KEYWORD2 getNedDownVel KEYWORD2 +getSpeedAccEst KEYWORD2 +getHeadingAccEst KEYWORD2 +getInvalidLlh KEYWORD2 +getHeadVeh KEYWORD2 +getMagDec KEYWORD2 +getMagAcc KEYWORD2 setPortOutput KEYWORD2 setPortInput KEYWORD2 diff --git a/src/SparkFun_Ublox_Arduino_Library.cpp b/src/SparkFun_Ublox_Arduino_Library.cpp index 06653e9..8b309f6 100644 --- a/src/SparkFun_Ublox_Arduino_Library.cpp +++ b/src/SparkFun_Ublox_Arduino_Library.cpp @@ -1039,10 +1039,15 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg) nedNorthVel = extractSignedLong(48 - startingSpot); nedEastVel = extractSignedLong(52 - startingSpot); nedDownVel = extractSignedLong(56 - startingSpot); - groundSpeed = extractSignedLong(60 - startingSpot); headingOfMotion = extractSignedLong(64 - startingSpot); + speedAccEst = extractLong(68 - startingSpot); + headingAccEst = extractLong(72 - startingSpot); pDOP = extractInt(76 - startingSpot); + invalidLlh = extractByte(78 - startingSpot) & 0x1; + headVeh = extractSignedLong(84 - startingSpot); + magDec = extractSignedInt(88 - startingSpot); + magAcc = extractInt(90 - startingSpot); //Mark all datums as fresh (not read before) moduleQueried.gpsiTOW = true; @@ -1063,19 +1068,23 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg) moduleQueried.latitude = true; moduleQueried.altitude = true; moduleQueried.altitudeMSL = true; - moduleQueried.horizontalAccEst = true; moduleQueried.verticalAccEst = true; moduleQueried.nedNorthVel = true; moduleQueried.nedEastVel = true; moduleQueried.nedDownVel = true; - moduleQueried.SIV = true; moduleQueried.fixType = true; moduleQueried.carrierSolution = true; moduleQueried.groundSpeed = true; moduleQueried.headingOfMotion = true; + moduleQueried.speedAccEst = true; + moduleQueried.headingAccEst = true; moduleQueried.pDOP = true; + moduleQueried.invalidLlh = true; + moduleQueried.headVeh = true; + moduleQueried.magDec = true; + moduleQueried.magAcc = true; } else if (msg->id == UBX_NAV_HPPOSLLH && msg->len == 36) { @@ -3111,6 +3120,19 @@ uint16_t SFE_UBLOX_GPS::extractInt(uint8_t spotToStart) return (val); } +//Just so there is no ambiguity about whether a uint16_t will cast to a int16_t correctly... +int16_t SFE_UBLOX_GPS::extractSignedInt(int8_t spotToStart) +{ + union // Use a union to convert from uint16_t to int16_t + { + uint16_t unsignedInt; + int16_t signedInt; + } stSignedInt; + + stSignedInt.unsignedInt = extractInt(spotToStart); + return (stSignedInt.signedInt); +} + //Given a spot, extract a byte from the payload uint8_t SFE_UBLOX_GPS::extractByte(uint8_t spotToStart) { @@ -3195,6 +3217,54 @@ bool SFE_UBLOX_GPS::getTimeValid(uint16_t maxWait) return (gpsTimeValid); } +uint32_t SFE_UBLOX_GPS::getSpeedAccEst(uint16_t maxWait) +{ + if (moduleQueried.speedAccEst == false) + getPVT(maxWait); + moduleQueried.speedAccEst = false; //Since we are about to give this to user, mark this data as stale + return (speedAccEst); +} + +uint32_t SFE_UBLOX_GPS::getHeadingAccEst(uint16_t maxWait) +{ + if (moduleQueried.headingAccEst == false) + getPVT(maxWait); + moduleQueried.headingAccEst = false; //Since we are about to give this to user, mark this data as stale + return (headingAccEst); +} + +bool SFE_UBLOX_GPS::getInvalidLlh(uint16_t maxWait) +{ + if (moduleQueried.invalidLlh == false) + getPVT(maxWait); + moduleQueried.invalidLlh = false; //Since we are about to give this to user, mark this data as stale + return (invalidLlh); +} + +int32_t SFE_UBLOX_GPS::getHeadVeh(uint16_t maxWait) +{ + if (moduleQueried.headVeh == false) + getPVT(maxWait); + moduleQueried.headVeh = false; //Since we are about to give this to user, mark this data as stale + return (headVeh); +} + +int16_t SFE_UBLOX_GPS::getMagDec(uint16_t maxWait) +{ + if (moduleQueried.magDec == false) + getPVT(maxWait); + moduleQueried.magDec = false; //Since we are about to give this to user, mark this data as stale + return (magDec); +} + +uint16_t SFE_UBLOX_GPS::getMagAcc(uint16_t maxWait) +{ + if (moduleQueried.magAcc == false) + getPVT(maxWait); + moduleQueried.magAcc = false; //Since we are about to give this to user, mark this data as stale + return (magAcc); +} + //Get the current millisecond uint16_t SFE_UBLOX_GPS::getMillisecond(uint16_t maxWait) { diff --git a/src/SparkFun_Ublox_Arduino_Library.h b/src/SparkFun_Ublox_Arduino_Library.h index b437de4..4c10c20 100644 --- a/src/SparkFun_Ublox_Arduino_Library.h +++ b/src/SparkFun_Ublox_Arduino_Library.h @@ -511,13 +511,11 @@ class SFE_UBLOX_GPS int32_t getLongitude(uint16_t maxWait = getPVTmaxWait); //Returns the current longitude in degrees * 10-7. Auto selects between HighPrecision and Regular depending on ability of module. int32_t getAltitude(uint16_t maxWait = getPVTmaxWait); //Returns the current altitude in mm above ellipsoid int32_t getAltitudeMSL(uint16_t maxWait = getPVTmaxWait); //Returns the current altitude in mm above mean sea level - int32_t getHorizontalAccEst(uint16_t maxWait = getPVTmaxWait); int32_t getVerticalAccEst(uint16_t maxWait = getPVTmaxWait); int32_t getNedNorthVel(uint16_t maxWait = getPVTmaxWait); int32_t getNedEastVel(uint16_t maxWait = getPVTmaxWait); int32_t getNedDownVel(uint16_t maxWait = getPVTmaxWait); - uint8_t getSIV(uint16_t maxWait = getPVTmaxWait); //Returns number of sats used in fix uint8_t getFixType(uint16_t maxWait = getPVTmaxWait); //Returns the type of fix: 0=no, 3=3D, 4=GNSS+Deadreckoning uint8_t getCarrierSolutionType(uint16_t maxWait = getPVTmaxWait); //Returns RTK solution: 0=no, 1=float solution, 2=fixed solution @@ -535,6 +533,12 @@ class SFE_UBLOX_GPS uint32_t getTimeOfWeek(uint16_t maxWait = getPVTmaxWait); bool getDateValid(uint16_t maxWait = getPVTmaxWait); bool getTimeValid(uint16_t maxWait = getPVTmaxWait); + uint32_t getSpeedAccEst(uint16_t maxWait = getPVTmaxWait); + uint32_t getHeadingAccEst(uint16_t maxWait = getPVTmaxWait); + bool getInvalidLlh(uint16_t maxWait = getPVTmaxWait); + int32_t getHeadVeh(uint16_t maxWait = getPVTmaxWait); + int16_t getMagDec(uint16_t maxWait = getPVTmaxWait); + uint16_t getMagAcc(uint16_t maxWait = getPVTmaxWait); int32_t getHighResLatitude(uint16_t maxWait = getHPPOSLLHmaxWait); int8_t getHighResLatitudeHp(uint16_t maxWait = getHPPOSLLHmaxWait); @@ -730,7 +734,6 @@ class SFE_UBLOX_GPS bool gpsDateValid; bool gpsTimeValid; - bool gnssFixOk; //valid fix (i.e within DOP & accuracy masks) bool diffSoln; //Differential corrections were applied int32_t latitude; //Degrees * 10^-7 (more accurate than floats) @@ -747,7 +750,13 @@ class SFE_UBLOX_GPS uint8_t carrierSolution; //Tells us when we have an RTK float/fixed solution int32_t groundSpeed; //mm/s int32_t headingOfMotion; //degrees * 10^-5 + uint32_t speedAccEst; + uint32_t headingAccEst; uint16_t pDOP; //Positional dilution of precision * 10^-2 (dimensionless) + bool invalidLlh; + int32_t headVeh; + int16_t magDec; + uint16_t magAcc; uint8_t versionLow; //Loaded from getProtocolVersion(). uint8_t versionHigh; @@ -943,6 +952,7 @@ class SFE_UBLOX_GPS uint32_t extractLong(uint8_t spotToStart); //Combine four bytes from payload into long int32_t extractSignedLong(uint8_t spotToStart); //Combine four bytes from payload into signed long (avoiding any ambiguity caused by casting) uint16_t extractInt(uint8_t spotToStart); //Combine two bytes from payload into int + int16_t extractSignedInt(int8_t spotToStart); uint8_t extractByte(uint8_t spotToStart); //Get byte from payload int8_t extractSignedChar(uint8_t spotToStart); //Get signed 8-bit value from payload void addToChecksum(uint8_t incoming); //Given an incoming byte, adjust rollingChecksumA/B @@ -1026,19 +1036,23 @@ class SFE_UBLOX_GPS uint32_t latitude : 1; uint32_t altitude : 1; uint32_t altitudeMSL : 1; - uint32_t horizontalAccEst : 1; uint32_t verticalAccEst : 1; uint32_t nedNorthVel : 1; uint32_t nedEastVel : 1; uint32_t nedDownVel : 1; - uint32_t SIV : 1; uint32_t fixType : 1; uint32_t carrierSolution : 1; uint32_t groundSpeed : 1; uint32_t headingOfMotion : 1; + uint32_t speedAccEst : 1; + uint32_t headingAccEst : 1; uint32_t pDOP : 1; + uint32_t invalidLlh : 1; + uint32_t headVeh : 1; + uint32_t magDec : 1; + uint32_t magAcc : 1; uint32_t versionNumber : 1; } moduleQueried; From 9479135cebf053f9bbf8f40765cc8304d9387d40 Mon Sep 17 00:00:00 2001 From: Balamurugan Kandan Date: Fri, 11 Dec 2020 02:53:18 +0530 Subject: [PATCH 2/4] getHeadVehValid function added. --- keywords.txt | 1 + src/SparkFun_Ublox_Arduino_Library.cpp | 21 +++++++++++++++++++++ src/SparkFun_Ublox_Arduino_Library.h | 3 +++ 3 files changed, 25 insertions(+) diff --git a/keywords.txt b/keywords.txt index 6272770..99345c1 100644 --- a/keywords.txt +++ b/keywords.txt @@ -64,6 +64,7 @@ getInvalidLlh KEYWORD2 getHeadVeh KEYWORD2 getMagDec KEYWORD2 getMagAcc KEYWORD2 +getHeadVehValid KEYWORD2 setPortOutput KEYWORD2 setPortInput KEYWORD2 diff --git a/src/SparkFun_Ublox_Arduino_Library.cpp b/src/SparkFun_Ublox_Arduino_Library.cpp index 8b309f6..ca1d98b 100644 --- a/src/SparkFun_Ublox_Arduino_Library.cpp +++ b/src/SparkFun_Ublox_Arduino_Library.cpp @@ -1029,6 +1029,7 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg) gnssFixOk = extractByte(21 - startingSpot) & 0x1; //Get the 1st bit diffSoln = extractByte(21 - startingSpot) >> 1 & 0x1; //Get the 2nd bit carrierSolution = extractByte(21 - startingSpot) >> 6; //Get 6th&7th bits of this byte + headVehValid = extractByte(21 - startingSpot) >> 5 & 0x1; // Get the 5th bit SIV = extractByte(23 - startingSpot); longitude = extractSignedLong(24 - startingSpot); latitude = extractSignedLong(28 - startingSpot); @@ -1064,6 +1065,7 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg) moduleQueried.all = true; moduleQueried.gnssFixOk = true; moduleQueried.diffSoln = true; + moduleQueried.headVehValid = true; moduleQueried.longitude = true; moduleQueried.latitude = true; moduleQueried.altitude = true; @@ -3850,6 +3852,18 @@ uint8_t SFE_UBLOX_GPS::getCarrierSolutionType(uint16_t maxWait) return (carrierSolution); } +//Get whether head vehicle valid or not +bool SFE_UBLOX_GPS::getHeadVehValid(uint16_t maxWait) +{ + if (moduleQueried.headVehValid == false) + getPVT(maxWait); + moduleQueried.headVehValid = false; //Since we are about to give this to user, mark this data as stale + moduleQueried.all = false; + + return (headVehValid); +} + + //Get the ground speed in mm/s int32_t SFE_UBLOX_GPS::getGroundSpeed(uint16_t maxWait) { @@ -3971,6 +3985,7 @@ void SFE_UBLOX_GPS::flushPVT() moduleQueried.all = false; moduleQueried.gnssFixOk = false; moduleQueried.diffSoln = false; + moduleQueried.headVehValid = false; moduleQueried.longitude = false; moduleQueried.latitude = false; moduleQueried.altitude = false; @@ -3980,7 +3995,13 @@ void SFE_UBLOX_GPS::flushPVT() moduleQueried.carrierSolution = false; moduleQueried.groundSpeed = false; moduleQueried.headingOfMotion = false; + moduleQueried.speedAccEst = false; + moduleQueried.headingAccEst = false; moduleQueried.pDOP = false; + moduleQueried.invalidLlh = false; + moduleQueried.headVeh = false; + moduleQueried.magDec = false; + moduleQueried.magAcc = false; } //Mark all the HPPOSLLH data as read/stale. This is handy to get data alignment after CRC failure diff --git a/src/SparkFun_Ublox_Arduino_Library.h b/src/SparkFun_Ublox_Arduino_Library.h index 4c10c20..9a3e250 100644 --- a/src/SparkFun_Ublox_Arduino_Library.h +++ b/src/SparkFun_Ublox_Arduino_Library.h @@ -507,6 +507,7 @@ class SFE_UBLOX_GPS bool getGnssFixOk(uint16_t maxWait = getPVTmaxWait); //Get whether we have a valid fix (i.e within DOP & accuracy masks) bool getDiffSoln(uint16_t maxWait = getPVTmaxWait); //Get whether differential corrections were applied + bool getHeadVehValid(uint16_t maxWait = getPVTmaxWait); int32_t getLatitude(uint16_t maxWait = getPVTmaxWait); //Returns the current latitude in degrees * 10^-7. Auto selects between HighPrecision and Regular depending on ability of module. int32_t getLongitude(uint16_t maxWait = getPVTmaxWait); //Returns the current longitude in degrees * 10-7. Auto selects between HighPrecision and Regular depending on ability of module. int32_t getAltitude(uint16_t maxWait = getPVTmaxWait); //Returns the current altitude in mm above ellipsoid @@ -736,6 +737,7 @@ class SFE_UBLOX_GPS bool gnssFixOk; //valid fix (i.e within DOP & accuracy masks) bool diffSoln; //Differential corrections were applied + bool headVehValid; int32_t latitude; //Degrees * 10^-7 (more accurate than floats) int32_t longitude; //Degrees * 10^-7 (more accurate than floats) int32_t altitude; //Number of mm above ellipsoid @@ -1032,6 +1034,7 @@ class SFE_UBLOX_GPS uint32_t all : 1; uint32_t gnssFixOk : 1; uint32_t diffSoln : 1; + uint32_t headVehValid : 1; uint32_t longitude : 1; uint32_t latitude : 1; uint32_t altitude : 1; From 378007abce3679ea8f6bcf158253cc5bdb74281c Mon Sep 17 00:00:00 2001 From: Balamurugan Kandan Date: Fri, 11 Dec 2020 03:32:50 +0530 Subject: [PATCH 3/4] Example1_AutoPVT.ino file is updated for newly added functions. --- .../Example1_AutoPVT/Example1_AutoPVT.ino | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/examples/Example13_PVT/Example1_AutoPVT/Example1_AutoPVT.ino b/examples/Example13_PVT/Example1_AutoPVT/Example1_AutoPVT.ino index b5dd97e..0370e90 100644 --- a/examples/Example13_PVT/Example1_AutoPVT/Example1_AutoPVT.ino +++ b/examples/Example13_PVT/Example1_AutoPVT/Example1_AutoPVT.ino @@ -54,7 +54,8 @@ void setup() void loop() { // Calling getPVT returns true if there actually is a fresh navigation solution available. - if (myGPS.getPVT()) + // Start the reading only when valid LLH is available + if (myGPS.getPVT() && (myGPS.getInvalidLlh() == false)) { Serial.println(); long latitude = myGPS.getLatitude(); @@ -105,6 +106,33 @@ void loop() Serial.print(horizontalAccEst); Serial.print(F(" (mm)")); + int speedAccEst = myGPS.getSpeedAccEst(); + Serial.print(F(" SpeedAccEst: ")); + Serial.print(speedAccEst); + Serial.print(F(" (mm/s)")); + + int headAccEst = myGPS.getHeadingAccEst(); + Serial.print(F(" HeadAccEst: ")); + Serial.print(headAccEst); + Serial.print(F(" (degrees * 10^-5)")); + + if (myGPS.getHeadVehValid() == true) { + int headVeh = myGPS.getHeadVeh(); + Serial.print(F(" HeadVeh: ")); + Serial.print(headVeh); + Serial.print(F(" (degrees * 10^-5)")); + + int magDec = myGPS.getMagDec(); + Serial.print(F(" MagDec: ")); + Serial.print(magDec); + Serial.print(F(" (degrees * 10^-2)")); + + int magAcc = myGPS.getMagAcc(); + Serial.print(F(" MagAcc: ")); + Serial.print(magAcc); + Serial.print(F(" (degrees * 10^-2)")); + } + Serial.println(); } else { Serial.print("."); From 347dc08186a600b2e8b52001a14c7c1f47fc4806 Mon Sep 17 00:00:00 2001 From: Balamurugan Kandan Date: Fri, 11 Dec 2020 09:19:42 +0000 Subject: [PATCH 4/4] Update SparkFun_Ublox_Arduino_Library.cpp Review comment incorporated. --- src/SparkFun_Ublox_Arduino_Library.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SparkFun_Ublox_Arduino_Library.cpp b/src/SparkFun_Ublox_Arduino_Library.cpp index ca1d98b..224305d 100644 --- a/src/SparkFun_Ublox_Arduino_Library.cpp +++ b/src/SparkFun_Ublox_Arduino_Library.cpp @@ -1027,9 +1027,9 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg) fixType = extractByte(20 - startingSpot); gnssFixOk = extractByte(21 - startingSpot) & 0x1; //Get the 1st bit - diffSoln = extractByte(21 - startingSpot) >> 1 & 0x1; //Get the 2nd bit + diffSoln = (extractByte(21 - startingSpot) >> 1) & 0x1; //Get the 2nd bit carrierSolution = extractByte(21 - startingSpot) >> 6; //Get 6th&7th bits of this byte - headVehValid = extractByte(21 - startingSpot) >> 5 & 0x1; // Get the 5th bit + headVehValid = (extractByte(21 - startingSpot) >> 5) & 0x1; // Get the 5th bit SIV = extractByte(23 - startingSpot); longitude = extractSignedLong(24 - startingSpot); latitude = extractSignedLong(28 - startingSpot);