How to parse RAW Lat and Long TinyGPS++

Hi,

I really wish I had the time to take a course in C++, I am trying and I have had some fantastic assistance from folk on here. I usually try everything I can think of before asking for help as I believe trial and error is the best way to learn. Please forgive my lack of understanding.

I am attempting to increase accuracy of GPS readings using the Ublox Neo-6M and the TinyGPS++ library.
I have been advised to use the RAW lat and long data.
Using three Serial.print commands, it is possible to print the +/-, degs and billionths of a degree as for example, +501234567.
My question is how can I combine these three separate segments of the RAW lat and long into one variable?
Thanks in advance for any help.
Cheers

/*
 *Experimenting in extracting RAW Lat data
 */
 
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

void setup(){
  Serial.begin(115200);
  ss.begin(GPSBaud);
}

void loop(){
  // This displays the RAW latitude every time a new sentence is correctly encoded.
  while (ss.available() > 0){
    gps.encode(ss.read());
    if (gps.location.isUpdated()){
     
      Serial.print(gps.location.rawLat().negative ? "-" : "+");
Serial.print(gps.location.rawLat().deg); // Raw latitude in whole degrees
Serial.println(gps.location.rawLat().billionths);// ... and billionths (u16/u32)
      
 //  Output on serial monitor is +5046738201. But how can I combine these into one variable/string that I can use for some math?
    }
  }
}

It's tricky. If you have an Arduino with actual eight byte doubles (e.g. Due) you could combine the components into one but on most, you only have four byte floats. In that case you're probably better off leaving the data in the struct, which is a compromise to get more precision.

That precision is largely a fantasy though. If somehow you got an super accurate fix you can do a little bit better than using a float but once you're down to a three foot radius circle, the rest of the billionths are just noise - GPS just isn't going to give you more and generally, you won't even get that.

Cannot see what you would acheive by doing this, the fifth decimal place of the float in degrees is (approximatly) counts of 1M distance, and if your real lucky the GPS will be accurate to 3M but 10M is fairly normal. So going beyond 5 decimal places of a float wont acheive a lot.

TinyGPS++ already has a function to give you lat and long as a uint32_t of billonths of a degree anyway, but how knowing the conversion value from degrees and minutes down to fractions of a mm helps I am not sure.

The NMEA sentence data itself goes down to units circa of 1cm I believe, whereas the postiton accuracy it's self is going to be 3m - 10m.

Thanks for your advice.
I totally agree about not bothering with all the extra decimal places.
I am looking at initially letting say 20 sentences go by and then averaging the next 20 to try and get as accurate an initial fix as possible.
Even without averaging, ignoring the first 50 fixes gives quite a good result, so I will continue experimenting using the gps.location.lat(); gps.location.lng(); method.

Out of curiosity though, going back to my initial post, is there any way to 'concatenate' the three values returned from these methods into one usable value?

Serial.print(gps.location.rawLat().negative ? "-" : "+");
Serial.print(gps.location.rawLat().deg); // Raw latitude in whole degrees
Serial.println(gps.location.rawLat().billionths);// ... and billionths (u16/u32)

Thanks

To convert TinyGPS++ raw latitudes and longitudes, as stored in their internal form, to the extremely convenient long integer format in degrees*(ten million), use something like:

long scale=10000000UL;
long lat = gps.location.rawLat().deg*scale+gps.location.rawLat().billionths/100UL;
if(gps.location.rawLat().negative) lat=-lat;
long lon = gps.location.rawLng().deg*scale+gps.location.rawLng().billionths/100UL;
if(gps.location.rawLng().negative) lon=-lon;

With this scale factor, 45.123456 degrees is represented internally by 451234560 and specifies location to +/- 1 cm precision.

Note this assumes that the GPS object is named "gps".

stevetyphoon:
I am looking at initially letting say 20 sentences go by and then averaging the next 20 to try and get as accurate an initial fix as possible.

Averaging in the short term, does not necessarily improve accuracy.

The reported position tend to centre on a spot, say 10M to the North and there is then a variation around this locus. The centre of the locus drifts over the long term, such that it may over minutes\hours move to the West, East or South. At least that is what I have observed.

as I believe trial and error is the best way to learn

Studying the language references and tutorials is a much, much better and faster way to learn.

Example of GPS coordinate drift over 4.5 hours. See point - How much sense does it make to average (lat,lon) samples in order to increase 2D accuracy of a GPS location? - Geographic Information Systems Stack Exchange

I've been experimenting with the U-blox Neo-M8P RTK setup. In order to get a really significant improvement on the location accuracy, a recommendation is to average for 24 to 48 hours. That way a variety of satellite constellations is used for input.

RTK corrections are relative to the base station, so if you are happy with locally accurate, high precision measurements (+/- 10 cm), you can safely assume an approximate base station location to use as the reference and fix up the locations later with corrections from a more accurate reference.

jremington:
See point - How much sense does it make to average (lat,lon) samples in order to increase 2D accuracy of a GPS location? - Geographic Information Systems Stack Exchange

An excellant article.

Gents,

This has turned into something far more involved than I initially thought!
Coding aside, I am a sub-sea construction engineer. Positioning is obviously very important, but GPS is a minor part of the complete system used to put a lump of steel on the seabed! We usually have approx 5cm accuracy and that is at 5000m water depth.
This is really a fascinating subject. I suppose with the next generation of GPS satellites accuracy is going to be orders better....Unfortunately, here in the UK, we opted out of the new EU Galileo system, and it is not certain how we will get onboard with another system.

I have been experimenting all day with different approaches. For me ignoring the first 30 sentences or so and then taking the next lat/long as an initial fix seemed to be a big improvement. The averaging I did was ignore the first 30 sentences then average the next 30. This didn't really make a significant improvement but it had started raining so I had to give up! ( I suppose rain affects accuracy as well!)

taking the next lat/long as an initial fix seemed to be a big improvement.

Perhaps today, but not tomorrow.

Unless you already know the precise, correct location, you are simply driving blind.

Hi JR,

Luckily I am only using GPS to give me a rough idea how far away I have traveled, not for navigation purposes.

It has been a fascinating discussion, thanks again for your knowledgeable input.