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

Corrected the high precision functions #90

Merged
merged 1 commit into from
Apr 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/*
Get the high precision geodetic solution for latituude and longitude
Get the high precision geodetic solution for latitude and longitude
By: Nathan Seidle
Modified by: Steven Rowland
Modified by: Steven Rowland and Paul Clark
SparkFun Electronics
Date: January 3rd, 2019
Date: April 17th, 2020
License: MIT. See license file for more information but you can
basically do whatever you want with this code.

This example shows how to inspect the accuracy of the high-precision
positional solution.
positional solution. Please see below for information about the units.

Feel like supporting open source hardware?
Buy a board from SparkFun!
Expand Down Expand Up @@ -36,22 +36,22 @@ void setup()

Wire.begin();

if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
//myGPS.enableDebugging(Serial);

if (myGPS.begin(Wire) == false) //Connect to the Ublox module using Wire port
{
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
while (1);
}

//myGPS.enableDebugging(Serial);

myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
myGPS.setNavigationFrequency(20); //Set output to 20 times a second

byte rate = myGPS.getNavigationFrequency(); //Get the update rate of this module
Serial.print("Current update rate:");
Serial.print("Current update rate: ");
Serial.println(rate);
myGPS.saveConfiguration(); //Save the current settings to flash and BBR

//myGPS.saveConfiguration(); //Save the current settings to flash and BBR
}

void loop()
Expand All @@ -61,17 +61,95 @@ void loop()
if (millis() - lastTime > 1000)
{
lastTime = millis(); //Update the timer
Serial.print("HP Lat: ");
int32_t latitude = myGPS.getHighResLatitude();
Serial.print(latitude);
Serial.print(", HP Lon: ");

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

// If you want to use the high precision latitude and longitude with the full 9 decimal places
// you will need to use a 64-bit double - which is not supported on all platforms

// To allow this example to run on standard platforms, we cheat by converting lat and lon to integer and fractional degrees

// The high resolution altitudes can be converted into standard 32-bit float

// First, let's collect the position data
int32_t latitude = myGPS.getHighResLatitude();
int8_t latitudeHp = myGPS.getHighResLatitudeHp();
int32_t longitude = myGPS.getHighResLongitude();
int8_t longitudeHp = myGPS.getHighResLongitudeHp();
int32_t ellipsoid = myGPS.getElipsoid();
int8_t ellipsoidHp = myGPS.getElipsoidHp();
int32_t msl = myGPS.getMeanSeaLevel();
int8_t mslHp = myGPS.getMeanSeaLevelHp();
uint32_t accuracy = myGPS.getHorizontalAccuracy();
Serial.println(accuracy);
}

// Defines storage for the lat and lon units integer and fractional parts
int32_t lat_int; // Integer part of the latitude in degrees
int32_t lat_frac; // Fractional part of the latitude
int32_t lon_int; // Integer part of the longitude in degrees
int32_t lon_frac; // Fractional part of the longitude

// Calculate the latitude and longitude integer and fractional parts
lat_int = latitude / 10000000; // Convert latitude from degrees * 10^-7 to Degrees
lat_frac = latitude - (lat_int * 10000000); // Calculate the fractional part of the latitude
lat_frac = (lat_frac * 100) + latitudeHp; // Now add the high resolution component
if (lat_frac < 0) // If the fractional part is negative, remove the minus sign
{
lat_frac = 0 - lat_frac;
}
lon_int = longitude / 10000000; // Convert latitude from degrees * 10^-7 to Degrees
lon_frac = longitude - (lon_int * 10000000); // Calculate the fractional part of the longitude
lon_frac = (lon_frac * 100) + longitudeHp; // Now add the high resolution component
if (lon_frac < 0) // If the fractional part is negative, remove the minus sign
{
lon_frac = 0 - lon_frac;
}

// Print the lat and lon
Serial.print("Lat (deg): ");
Serial.print(lat_int); // Print the integer part of the latitude
Serial.print(".");
Serial.print(lat_frac); // Print the fractional part of the latitude
Serial.print(", Lon (deg): ");
Serial.print(lon_int); // Print the integer part of the latitude
Serial.print(".");
Serial.println(lon_frac); // Print the fractional part of the latitude

// Now define float storage for the heights and accuracy
float f_ellipsoid;
float f_msl;
float f_accuracy;

// Calculate the height above ellipsoid in mm * 10^-1
f_ellipsoid = (ellipsoid * 10) + ellipsoidHp;
// Now convert to m
f_ellipsoid = f_ellipsoid / 10000.0; // Convert from mm * 10^-1 to m

// Calculate the height above mean sea level in mm * 10^-1
f_msl = (msl * 10) + mslHp;
// Now convert to m
f_msl = f_msl / 10000.0; // Convert from mm * 10^-1 to m

// Convert the horizontal accuracy (mm * 10^-1) to a float
f_accuracy = accuracy;
// Now convert to m
f_accuracy = f_accuracy / 10000.0; // Convert from mm * 10^-1 to m

// Finally, do the printing
Serial.print("Ellipsoid (m): ");
Serial.print(f_ellipsoid, 4); // Print the ellipsoid with 4 decimal places

Serial.print(", Mean Sea Level(m): ");
Serial.print(f_msl, 4); // Print the mean sea level with 4 decimal places

Serial.print(", Accuracy (m): ");
Serial.println(f_accuracy, 4); // Print the accuracy with 4 decimal places
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/*
Get the high precision geodetic solution
By: Nathan Seidle
Modified by: Steven Rowland
Modified by: Steven Rowland and Paul Clark
SparkFun Electronics
Date: January 3rd, 2019
Date: April 17th, 2020
License: MIT. See license file for more information but you can
basically do whatever you want with this code.

Expand Down Expand Up @@ -50,8 +50,8 @@ void setup()
byte rate = myGPS.getNavigationFrequency(); //Get the update rate of this module
Serial.print("Current update rate:");
Serial.println(rate);
myGPS.saveConfiguration(); //Save the current settings to flash and BBR

//myGPS.saveConfiguration(); //Save the current settings to flash and BBR
}

void loop()
Expand All @@ -64,36 +64,30 @@ void loop()
Serial.print("HP Lat: ");
int32_t latitude = myGPS.getHighResLatitude();
Serial.print(latitude);
Serial.print(", HP Lon: ");

Serial.print(", HP Lon: ");
int32_t longitude = myGPS.getHighResLongitude();
Serial.print(longitude);
Serial.print(", 2D Accuracy(MM): ");

Serial.print(", Horizontal Accuracy(0.1mm): ");
uint32_t accuracy = myGPS.getHorizontalAccuracy();
Serial.println(accuracy);
Serial.print(", Vertical Accuracy(MM): ");
Serial.print(accuracy);

Serial.print(", Vertical Accuracy(0.1mm): ");
uint32_t verticalAccuracy = myGPS.getVerticalAccuracy();
Serial.println(verticalAccuracy);
Serial.print(", Elipsoid(MM): ");


Serial.print("Elipsoid(mm): ");
int32_t elipsoid = myGPS.getElipsoid();
Serial.println(elipsoid);
Serial.print(", Mean Sea Level(MM): ");

Serial.print(elipsoid);

Serial.print(", Mean Sea Level(mm): ");
int32_t meanSeaLevel = myGPS.getMeanSeaLevel();
Serial.println(meanSeaLevel);
Serial.print(", Geoid Separation(MM): ");

int32_t geoidSeparation = myGPS.getGeoidSeparation();
Serial.println(geoidSeparation);
Serial.print(", Time of Week(Millis): ");

Serial.print(meanSeaLevel);

Serial.print(", Time of Week(millis): ");
uint32_t timeOfWeek = myGPS.getTimeOfWeek();
Serial.println(timeOfWeek);
Serial.print(",");

}

}
4 changes: 4 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,13 @@ getNanosecond KEYWORD2
getHPPOSLLH KEYWORD2
getTimeOfWeek KEYWORD2
getHighResLatitude KEYWORD2
getHighResLatitudeHp KEYWORD2
getHighResLongitude KEYWORD2
getHighResLongitudeHp KEYWORD2
getElipsoid KEYWORD2
getElipsoidHp KEYWORD2
getMeanSeaLevel KEYWORD2
getMeanSeaLevelHp KEYWORD2
getGeoidSeparation KEYWORD2
getHorizontalAccuracy KEYWORD2
getVerticalAccuracy KEYWORD2
Expand Down
68 changes: 61 additions & 7 deletions src/SparkFun_Ublox_Arduino_Library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -785,15 +785,22 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
highResLatitude = extractLong(12);
elipsoid = extractLong(16);
meanSeaLevel = extractLong(20);
geoidSeparation = extractLong(24);
highResLongitudeHp = extractSignedChar(24);
highResLatitudeHp = extractSignedChar(25);
elipsoidHp = extractSignedChar(26);
meanSeaLevelHp = extractSignedChar(27);
horizontalAccuracy = extractLong(28);
verticalAccuracy = extractLong(32);

highResModuleQueried.all = true;
highResModuleQueried.highResLatitude = true;
highResModuleQueried.highResLatitudeHp = true;
highResModuleQueried.highResLongitude = true;
highResModuleQueried.highResLongitudeHp = true;
highResModuleQueried.elipsoid = true;
highResModuleQueried.elipsoidHp = true;
highResModuleQueried.meanSeaLevel = true;
highResModuleQueried.meanSeaLevelHp = true;
highResModuleQueried.geoidSeparation = true;
highResModuleQueried.horizontalAccuracy = true;
highResModuleQueried.verticalAccuracy = true;
Expand All @@ -816,15 +823,23 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
_debugSerial->print(F("MSL M: "));
_debugSerial->print(((float)(int32_t)extractLong(20)) / 1000.0f);
_debugSerial->print(F(" "));
_debugSerial->print(F("GEO: "));
_debugSerial->print(((float)(int32_t)extractLong(24)) / 1000.0f);
_debugSerial->print(F("LON HP: "));
_debugSerial->print(extractSignedChar(24));
_debugSerial->print(F(" "));
_debugSerial->print(F("LAT HP: "));
_debugSerial->print(extractSignedChar(25));
_debugSerial->print(F(" "));
_debugSerial->print(F("ELI HP: "));
_debugSerial->print(extractSignedChar(26));
_debugSerial->print(F(" "));
_debugSerial->print(F("MSL HP: "));
_debugSerial->print(extractSignedChar(27));
_debugSerial->print(F(" "));
_debugSerial->print(F("HA 2D M: "));
_debugSerial->print(((float)extractLong(28)) / 1000.0f);
_debugSerial->print(((float)(int32_t)extractLong(28)) / 10000.0f);
_debugSerial->print(F(" "));
_debugSerial->print(F("VERT M: "));
_debugSerial->print(((float)extractLong(32)) / 1000.0f);
_debugSerial->print(F(" "));
_debugSerial->println(((float)(int32_t)extractLong(32)) / 10000.0f);
}
}
break;
Expand Down Expand Up @@ -2287,12 +2302,18 @@ uint16_t SFE_UBLOX_GPS::extractInt(uint8_t spotToStart)
return (val);
}

//Given a spot, extract byte the payload
//Given a spot, extract a byte from the payload
uint8_t SFE_UBLOX_GPS::extractByte(uint8_t spotToStart)
{
return (payloadCfg[spotToStart]);
}

//Given a spot, extract a signed 8-bit value from the payload
int8_t SFE_UBLOX_GPS::extractSignedChar(uint8_t spotToStart)
{
return ((int8_t)payloadCfg[spotToStart]);
}

//Get the current year
uint16_t SFE_UBLOX_GPS::getYear(uint16_t maxWait)
{
Expand Down Expand Up @@ -2431,6 +2452,14 @@ int32_t SFE_UBLOX_GPS::getHighResLatitude(uint16_t maxWait /* = 250*/)
return (highResLatitude);
}

int8_t SFE_UBLOX_GPS::getHighResLatitudeHp(uint16_t maxWait /* = 250*/)
{
if (highResModuleQueried.highResLatitudeHp == false)
getHPPOSLLH(maxWait);
highResModuleQueried.highResLatitudeHp = false; //Since we are about to give this to user, mark this data as stale
return (highResLatitudeHp);
}

int32_t SFE_UBLOX_GPS::getHighResLongitude(uint16_t maxWait /* = 250*/)
{
if (highResModuleQueried.highResLongitude == false)
Expand All @@ -2439,6 +2468,14 @@ int32_t SFE_UBLOX_GPS::getHighResLongitude(uint16_t maxWait /* = 250*/)
return (highResLongitude);
}

int8_t SFE_UBLOX_GPS::getHighResLongitudeHp(uint16_t maxWait /* = 250*/)
{
if (highResModuleQueried.highResLongitudeHp == false)
getHPPOSLLH(maxWait);
highResModuleQueried.highResLongitudeHp = false; //Since we are about to give this to user, mark this data as stale
return (highResLongitudeHp);
}

int32_t SFE_UBLOX_GPS::getElipsoid(uint16_t maxWait /* = 250*/)
{
if (highResModuleQueried.elipsoid == false)
Expand All @@ -2447,6 +2484,14 @@ int32_t SFE_UBLOX_GPS::getElipsoid(uint16_t maxWait /* = 250*/)
return (elipsoid);
}

int8_t SFE_UBLOX_GPS::getElipsoidHp(uint16_t maxWait /* = 250*/)
{
if (highResModuleQueried.elipsoidHp == false)
getHPPOSLLH(maxWait);
highResModuleQueried.elipsoidHp = false; //Since we are about to give this to user, mark this data as stale
return (elipsoidHp);
}

int32_t SFE_UBLOX_GPS::getMeanSeaLevel(uint16_t maxWait /* = 250*/)
{
if (highResModuleQueried.meanSeaLevel == false)
Expand All @@ -2455,6 +2500,15 @@ int32_t SFE_UBLOX_GPS::getMeanSeaLevel(uint16_t maxWait /* = 250*/)
return (meanSeaLevel);
}

int8_t SFE_UBLOX_GPS::getMeanSeaLevelHp(uint16_t maxWait /* = 250*/)
{
if (highResModuleQueried.meanSeaLevelHp == false)
getHPPOSLLH(maxWait);
highResModuleQueried.meanSeaLevelHp = false; //Since we are about to give this to user, mark this data as stale
return (meanSeaLevelHp);
}

// getGeoidSeparation is currently redundant. The geoid separation seems to only be provided in NMEA GGA and GNS messages.
int32_t SFE_UBLOX_GPS::getGeoidSeparation(uint16_t maxWait /* = 250*/)
{
if (highResModuleQueried.geoidSeparation == false)
Expand Down
Loading