Skip to content
This repository was archived by the owner on Jan 28, 2021. It is now read-only.

Commit d08764d

Browse files
authored
Merge pull request #90 from sparkfun/HPPOSLLH_Corrections
Corrected the high precision functions
2 parents 86e78de + 8f6b2c7 commit d08764d

File tree

5 files changed

+200
-57
lines changed

5 files changed

+200
-57
lines changed

examples/ZED-F9P/Example8_GetHighPrecisionPositionAndAccuracy/Example8_GetHighPrecisionPositionAndAccuracy.ino

+97-19
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
/*
2-
Get the high precision geodetic solution for latituude and longitude
2+
Get the high precision geodetic solution for latitude and longitude
33
By: Nathan Seidle
4-
Modified by: Steven Rowland
4+
Modified by: Steven Rowland and Paul Clark
55
SparkFun Electronics
6-
Date: January 3rd, 2019
6+
Date: April 17th, 2020
77
License: MIT. See license file for more information but you can
88
basically do whatever you want with this code.
99
1010
This example shows how to inspect the accuracy of the high-precision
11-
positional solution.
11+
positional solution. Please see below for information about the units.
1212
1313
Feel like supporting open source hardware?
1414
Buy a board from SparkFun!
@@ -36,22 +36,22 @@ void setup()
3636

3737
Wire.begin();
3838

39-
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
39+
//myGPS.enableDebugging(Serial);
40+
41+
if (myGPS.begin(Wire) == false) //Connect to the Ublox module using Wire port
4042
{
4143
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
4244
while (1);
4345
}
4446

45-
//myGPS.enableDebugging(Serial);
46-
4747
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
4848
myGPS.setNavigationFrequency(20); //Set output to 20 times a second
4949

5050
byte rate = myGPS.getNavigationFrequency(); //Get the update rate of this module
51-
Serial.print("Current update rate:");
51+
Serial.print("Current update rate: ");
5252
Serial.println(rate);
53-
54-
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
53+
54+
//myGPS.saveConfiguration(); //Save the current settings to flash and BBR
5555
}
5656

5757
void loop()
@@ -61,17 +61,95 @@ void loop()
6161
if (millis() - lastTime > 1000)
6262
{
6363
lastTime = millis(); //Update the timer
64-
Serial.print("HP Lat: ");
65-
int32_t latitude = myGPS.getHighResLatitude();
66-
Serial.print(latitude);
67-
Serial.print(", HP Lon: ");
6864

69-
int32_t longitude = myGPS.getHighResLongitude();
70-
Serial.print(longitude);
71-
Serial.print(", Accuracy: ");
65+
// getHighResLatitude: returns the latitude from HPPOSLLH as an int32_t in degrees * 10^-7
66+
// getHighResLatitudeHp: returns the high resolution component of latitude from HPPOSLLH as an int8_t in degrees * 10^-9
67+
// getHighResLongitude: returns the longitude from HPPOSLLH as an int32_t in degrees * 10^-7
68+
// getHighResLongitudeHp: returns the high resolution component of longitude from HPPOSLLH as an int8_t in degrees * 10^-9
69+
// getElipsoid: returns the height above ellipsoid as an int32_t in mm
70+
// getElipsoidHp: returns the high resolution component of the height above ellipsoid as an int8_t in mm * 10^-1
71+
// getMeanSeaLevel: returns the height above mean sea level as an int32_t in mm
72+
// getMeanSeaLevelHp: returns the high resolution component of the height above mean sea level as an int8_t in mm * 10^-1
73+
// getHorizontalAccuracy: returns the horizontal accuracy estimate from HPPOSLLH as an uint32_t in mm * 10^-1
7274

75+
// If you want to use the high precision latitude and longitude with the full 9 decimal places
76+
// you will need to use a 64-bit double - which is not supported on all platforms
77+
78+
// To allow this example to run on standard platforms, we cheat by converting lat and lon to integer and fractional degrees
79+
80+
// The high resolution altitudes can be converted into standard 32-bit float
81+
82+
// First, let's collect the position data
83+
int32_t latitude = myGPS.getHighResLatitude();
84+
int8_t latitudeHp = myGPS.getHighResLatitudeHp();
85+
int32_t longitude = myGPS.getHighResLongitude();
86+
int8_t longitudeHp = myGPS.getHighResLongitudeHp();
87+
int32_t ellipsoid = myGPS.getElipsoid();
88+
int8_t ellipsoidHp = myGPS.getElipsoidHp();
89+
int32_t msl = myGPS.getMeanSeaLevel();
90+
int8_t mslHp = myGPS.getMeanSeaLevelHp();
7391
uint32_t accuracy = myGPS.getHorizontalAccuracy();
74-
Serial.println(accuracy);
75-
}
7692

93+
// Defines storage for the lat and lon units integer and fractional parts
94+
int32_t lat_int; // Integer part of the latitude in degrees
95+
int32_t lat_frac; // Fractional part of the latitude
96+
int32_t lon_int; // Integer part of the longitude in degrees
97+
int32_t lon_frac; // Fractional part of the longitude
98+
99+
// Calculate the latitude and longitude integer and fractional parts
100+
lat_int = latitude / 10000000; // Convert latitude from degrees * 10^-7 to Degrees
101+
lat_frac = latitude - (lat_int * 10000000); // Calculate the fractional part of the latitude
102+
lat_frac = (lat_frac * 100) + latitudeHp; // Now add the high resolution component
103+
if (lat_frac < 0) // If the fractional part is negative, remove the minus sign
104+
{
105+
lat_frac = 0 - lat_frac;
106+
}
107+
lon_int = longitude / 10000000; // Convert latitude from degrees * 10^-7 to Degrees
108+
lon_frac = longitude - (lon_int * 10000000); // Calculate the fractional part of the longitude
109+
lon_frac = (lon_frac * 100) + longitudeHp; // Now add the high resolution component
110+
if (lon_frac < 0) // If the fractional part is negative, remove the minus sign
111+
{
112+
lon_frac = 0 - lon_frac;
113+
}
114+
115+
// Print the lat and lon
116+
Serial.print("Lat (deg): ");
117+
Serial.print(lat_int); // Print the integer part of the latitude
118+
Serial.print(".");
119+
Serial.print(lat_frac); // Print the fractional part of the latitude
120+
Serial.print(", Lon (deg): ");
121+
Serial.print(lon_int); // Print the integer part of the latitude
122+
Serial.print(".");
123+
Serial.println(lon_frac); // Print the fractional part of the latitude
124+
125+
// Now define float storage for the heights and accuracy
126+
float f_ellipsoid;
127+
float f_msl;
128+
float f_accuracy;
129+
130+
// Calculate the height above ellipsoid in mm * 10^-1
131+
f_ellipsoid = (ellipsoid * 10) + ellipsoidHp;
132+
// Now convert to m
133+
f_ellipsoid = f_ellipsoid / 10000.0; // Convert from mm * 10^-1 to m
134+
135+
// Calculate the height above mean sea level in mm * 10^-1
136+
f_msl = (msl * 10) + mslHp;
137+
// Now convert to m
138+
f_msl = f_msl / 10000.0; // Convert from mm * 10^-1 to m
139+
140+
// Convert the horizontal accuracy (mm * 10^-1) to a float
141+
f_accuracy = accuracy;
142+
// Now convert to m
143+
f_accuracy = f_accuracy / 10000.0; // Convert from mm * 10^-1 to m
144+
145+
// Finally, do the printing
146+
Serial.print("Ellipsoid (m): ");
147+
Serial.print(f_ellipsoid, 4); // Print the ellipsoid with 4 decimal places
148+
149+
Serial.print(", Mean Sea Level(m): ");
150+
Serial.print(f_msl, 4); // Print the mean sea level with 4 decimal places
151+
152+
Serial.print(", Accuracy (m): ");
153+
Serial.println(f_accuracy, 4); // Print the accuracy with 4 decimal places
154+
}
77155
}

examples/ZED-F9P/Example9_GetHighPrecisionGeodeticPacket/Example9_GetHighPrecisionGeodeticPacket.ino

+16-22
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/*
22
Get the high precision geodetic solution
33
By: Nathan Seidle
4-
Modified by: Steven Rowland
4+
Modified by: Steven Rowland and Paul Clark
55
SparkFun Electronics
6-
Date: January 3rd, 2019
6+
Date: April 17th, 2020
77
License: MIT. See license file for more information but you can
88
basically do whatever you want with this code.
99
@@ -50,8 +50,8 @@ void setup()
5050
byte rate = myGPS.getNavigationFrequency(); //Get the update rate of this module
5151
Serial.print("Current update rate:");
5252
Serial.println(rate);
53-
54-
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
53+
54+
//myGPS.saveConfiguration(); //Save the current settings to flash and BBR
5555
}
5656

5757
void loop()
@@ -64,36 +64,30 @@ void loop()
6464
Serial.print("HP Lat: ");
6565
int32_t latitude = myGPS.getHighResLatitude();
6666
Serial.print(latitude);
67-
Serial.print(", HP Lon: ");
6867

68+
Serial.print(", HP Lon: ");
6969
int32_t longitude = myGPS.getHighResLongitude();
7070
Serial.print(longitude);
71-
Serial.print(", 2D Accuracy(MM): ");
7271

72+
Serial.print(", Horizontal Accuracy(0.1mm): ");
7373
uint32_t accuracy = myGPS.getHorizontalAccuracy();
74-
Serial.println(accuracy);
75-
Serial.print(", Vertical Accuracy(MM): ");
74+
Serial.print(accuracy);
7675

76+
Serial.print(", Vertical Accuracy(0.1mm): ");
7777
uint32_t verticalAccuracy = myGPS.getVerticalAccuracy();
7878
Serial.println(verticalAccuracy);
79-
Serial.print(", Elipsoid(MM): ");
80-
79+
80+
Serial.print("Elipsoid(mm): ");
8181
int32_t elipsoid = myGPS.getElipsoid();
82-
Serial.println(elipsoid);
83-
Serial.print(", Mean Sea Level(MM): ");
84-
82+
Serial.print(elipsoid);
83+
84+
Serial.print(", Mean Sea Level(mm): ");
8585
int32_t meanSeaLevel = myGPS.getMeanSeaLevel();
86-
Serial.println(meanSeaLevel);
87-
Serial.print(", Geoid Separation(MM): ");
88-
89-
int32_t geoidSeparation = myGPS.getGeoidSeparation();
90-
Serial.println(geoidSeparation);
91-
Serial.print(", Time of Week(Millis): ");
92-
86+
Serial.print(meanSeaLevel);
87+
88+
Serial.print(", Time of Week(millis): ");
9389
uint32_t timeOfWeek = myGPS.getTimeOfWeek();
9490
Serial.println(timeOfWeek);
95-
Serial.print(",");
96-
9791
}
9892

9993
}

keywords.txt

+4
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,13 @@ getNanosecond KEYWORD2
118118
getHPPOSLLH KEYWORD2
119119
getTimeOfWeek KEYWORD2
120120
getHighResLatitude KEYWORD2
121+
getHighResLatitudeHp KEYWORD2
121122
getHighResLongitude KEYWORD2
123+
getHighResLongitudeHp KEYWORD2
122124
getElipsoid KEYWORD2
125+
getElipsoidHp KEYWORD2
123126
getMeanSeaLevel KEYWORD2
127+
getMeanSeaLevelHp KEYWORD2
124128
getGeoidSeparation KEYWORD2
125129
getHorizontalAccuracy KEYWORD2
126130
getVerticalAccuracy KEYWORD2

src/SparkFun_Ublox_Arduino_Library.cpp

+61-7
Original file line numberDiff line numberDiff line change
@@ -785,15 +785,22 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
785785
highResLatitude = extractLong(12);
786786
elipsoid = extractLong(16);
787787
meanSeaLevel = extractLong(20);
788-
geoidSeparation = extractLong(24);
788+
highResLongitudeHp = extractSignedChar(24);
789+
highResLatitudeHp = extractSignedChar(25);
790+
elipsoidHp = extractSignedChar(26);
791+
meanSeaLevelHp = extractSignedChar(27);
789792
horizontalAccuracy = extractLong(28);
790793
verticalAccuracy = extractLong(32);
791794

792795
highResModuleQueried.all = true;
793796
highResModuleQueried.highResLatitude = true;
797+
highResModuleQueried.highResLatitudeHp = true;
794798
highResModuleQueried.highResLongitude = true;
799+
highResModuleQueried.highResLongitudeHp = true;
795800
highResModuleQueried.elipsoid = true;
801+
highResModuleQueried.elipsoidHp = true;
796802
highResModuleQueried.meanSeaLevel = true;
803+
highResModuleQueried.meanSeaLevelHp = true;
797804
highResModuleQueried.geoidSeparation = true;
798805
highResModuleQueried.horizontalAccuracy = true;
799806
highResModuleQueried.verticalAccuracy = true;
@@ -816,15 +823,23 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
816823
_debugSerial->print(F("MSL M: "));
817824
_debugSerial->print(((float)(int32_t)extractLong(20)) / 1000.0f);
818825
_debugSerial->print(F(" "));
819-
_debugSerial->print(F("GEO: "));
820-
_debugSerial->print(((float)(int32_t)extractLong(24)) / 1000.0f);
826+
_debugSerial->print(F("LON HP: "));
827+
_debugSerial->print(extractSignedChar(24));
828+
_debugSerial->print(F(" "));
829+
_debugSerial->print(F("LAT HP: "));
830+
_debugSerial->print(extractSignedChar(25));
831+
_debugSerial->print(F(" "));
832+
_debugSerial->print(F("ELI HP: "));
833+
_debugSerial->print(extractSignedChar(26));
834+
_debugSerial->print(F(" "));
835+
_debugSerial->print(F("MSL HP: "));
836+
_debugSerial->print(extractSignedChar(27));
821837
_debugSerial->print(F(" "));
822838
_debugSerial->print(F("HA 2D M: "));
823-
_debugSerial->print(((float)extractLong(28)) / 1000.0f);
839+
_debugSerial->print(((float)(int32_t)extractLong(28)) / 10000.0f);
824840
_debugSerial->print(F(" "));
825841
_debugSerial->print(F("VERT M: "));
826-
_debugSerial->print(((float)extractLong(32)) / 1000.0f);
827-
_debugSerial->print(F(" "));
842+
_debugSerial->println(((float)(int32_t)extractLong(32)) / 10000.0f);
828843
}
829844
}
830845
break;
@@ -2287,12 +2302,18 @@ uint16_t SFE_UBLOX_GPS::extractInt(uint8_t spotToStart)
22872302
return (val);
22882303
}
22892304

2290-
//Given a spot, extract byte the payload
2305+
//Given a spot, extract a byte from the payload
22912306
uint8_t SFE_UBLOX_GPS::extractByte(uint8_t spotToStart)
22922307
{
22932308
return (payloadCfg[spotToStart]);
22942309
}
22952310

2311+
//Given a spot, extract a signed 8-bit value from the payload
2312+
int8_t SFE_UBLOX_GPS::extractSignedChar(uint8_t spotToStart)
2313+
{
2314+
return ((int8_t)payloadCfg[spotToStart]);
2315+
}
2316+
22962317
//Get the current year
22972318
uint16_t SFE_UBLOX_GPS::getYear(uint16_t maxWait)
22982319
{
@@ -2431,6 +2452,14 @@ int32_t SFE_UBLOX_GPS::getHighResLatitude(uint16_t maxWait /* = 250*/)
24312452
return (highResLatitude);
24322453
}
24332454

2455+
int8_t SFE_UBLOX_GPS::getHighResLatitudeHp(uint16_t maxWait /* = 250*/)
2456+
{
2457+
if (highResModuleQueried.highResLatitudeHp == false)
2458+
getHPPOSLLH(maxWait);
2459+
highResModuleQueried.highResLatitudeHp = false; //Since we are about to give this to user, mark this data as stale
2460+
return (highResLatitudeHp);
2461+
}
2462+
24342463
int32_t SFE_UBLOX_GPS::getHighResLongitude(uint16_t maxWait /* = 250*/)
24352464
{
24362465
if (highResModuleQueried.highResLongitude == false)
@@ -2439,6 +2468,14 @@ int32_t SFE_UBLOX_GPS::getHighResLongitude(uint16_t maxWait /* = 250*/)
24392468
return (highResLongitude);
24402469
}
24412470

2471+
int8_t SFE_UBLOX_GPS::getHighResLongitudeHp(uint16_t maxWait /* = 250*/)
2472+
{
2473+
if (highResModuleQueried.highResLongitudeHp == false)
2474+
getHPPOSLLH(maxWait);
2475+
highResModuleQueried.highResLongitudeHp = false; //Since we are about to give this to user, mark this data as stale
2476+
return (highResLongitudeHp);
2477+
}
2478+
24422479
int32_t SFE_UBLOX_GPS::getElipsoid(uint16_t maxWait /* = 250*/)
24432480
{
24442481
if (highResModuleQueried.elipsoid == false)
@@ -2447,6 +2484,14 @@ int32_t SFE_UBLOX_GPS::getElipsoid(uint16_t maxWait /* = 250*/)
24472484
return (elipsoid);
24482485
}
24492486

2487+
int8_t SFE_UBLOX_GPS::getElipsoidHp(uint16_t maxWait /* = 250*/)
2488+
{
2489+
if (highResModuleQueried.elipsoidHp == false)
2490+
getHPPOSLLH(maxWait);
2491+
highResModuleQueried.elipsoidHp = false; //Since we are about to give this to user, mark this data as stale
2492+
return (elipsoidHp);
2493+
}
2494+
24502495
int32_t SFE_UBLOX_GPS::getMeanSeaLevel(uint16_t maxWait /* = 250*/)
24512496
{
24522497
if (highResModuleQueried.meanSeaLevel == false)
@@ -2455,6 +2500,15 @@ int32_t SFE_UBLOX_GPS::getMeanSeaLevel(uint16_t maxWait /* = 250*/)
24552500
return (meanSeaLevel);
24562501
}
24572502

2503+
int8_t SFE_UBLOX_GPS::getMeanSeaLevelHp(uint16_t maxWait /* = 250*/)
2504+
{
2505+
if (highResModuleQueried.meanSeaLevelHp == false)
2506+
getHPPOSLLH(maxWait);
2507+
highResModuleQueried.meanSeaLevelHp = false; //Since we are about to give this to user, mark this data as stale
2508+
return (meanSeaLevelHp);
2509+
}
2510+
2511+
// getGeoidSeparation is currently redundant. The geoid separation seems to only be provided in NMEA GGA and GNS messages.
24582512
int32_t SFE_UBLOX_GPS::getGeoidSeparation(uint16_t maxWait /* = 250*/)
24592513
{
24602514
if (highResModuleQueried.geoidSeparation == false)

0 commit comments

Comments
 (0)