[SOLVED] Help using GPS in Tracker Edge firmware, how to use the LocationPoint struct?

Hello folks,

I am enjoying the Tracker One!

I apologize for the following generic question. I’m trying to see where in the Tracker Edge Software GPS data is available for reading.

Previously I used the Adafruit_GPS library on with an electron where I could use create an object called “GPS” and then be able to access the values anywhere. I leaned pretty heavily on the Adafruit examples.

(Oversimplification)
Adafruit_GPS GPS(&Serial5);

float GPS_GetLatDeg(void) {
    return GPS.latitudeDegrees;
}

float GPS_GetLongDeg(void) {
    return GPS.longitudeDegrees;
}

I have been poking around with the Tracker One and not able to get a clear sense of how to access the data from GPS.

I would appreciate some recommendations for how to start.

For my application I am looking for a number of GPS stats

Lat, Lng, GPS_speed, Elevation, Bearing, HDOP, and fix_status

Thanks!

@Adam42, take a read of the Tracker Edge Firmware docs starting here:

The function that likely fits what you are looking for is here:

1 Like

Hi @peekay123 Thank you for showing this.

I’ve been trying for the past few hours to understand how to implement the example shown in the docs.

Do you know if there is a free-standing example of reading the location data from the struct LocationPoint as shown in the example?

I’m not really sure why I can’t get this to work.

#include "Particle.h"
#include "tracker_config.h"
#include "tracker.h"
#include "tracker_location.h"
#include "location_service.h"

int getLocation(LocationPoint& point);

static long temp_timer = 0;

void setup()
{
    Tracker::instance().init();
    Serial.begin(115200);
}

void loop()
{
    Tracker::instance().loop();

    if (millis() - temp_timer >= 1000){
        temp_timer = millis();
        Serial.println(LocationPoint.latitude); // This doesn't work, shucks 
    } 
}

You don’t need to copy the forward declaration (aka prototype) of getLocation() you need to call it in your code.
The prototype only tells you how you need to call the function when you want it to do its thing.

    if (millis() - temp_timer >= 1000){
        temp_timer = millis();
        LocationPoint lp;            // declare a variable to hold your data
        getLocationPoint(lp);        // call the function to fill that variable with your desired data
        Serial.println(lp.latitude); // use the requested data now stored in your variable
    } 

This doesn’t work as you intend since LocationPoint is only a struct (like a datatype) but not a variable of that type so it cannot hold any data.
Just like you cannot live in the blueprint of your house :wink:

1 Like

Hi @ScruffR,

I feel like I’m close and I understand your explanation, but I’m not understanding the function you are calling getLocationPoint(lp). I get a compile error that getLocationPoint(lp) function does not exist and I’m not able to find it in the location_service.cpp reference.

Is there really nothing I need to do earlier in my code?

#include "Particle.h"
#include "tracker_config.h"
#include "tracker.h"
#include "Process.h"
#include "tracker_location.h"
#include "location_service.h"


SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(AUTOMATIC);

PRODUCT_ID(secret);
PRODUCT_VERSION(FIRMWARE_VERSION);

SerialLogHandler logHandler(115200, LOG_LEVEL_TRACE, {
    { "app.gps.nmea", LOG_LEVEL_INFO },
    { "app.gps.ubx",  LOG_LEVEL_INFO },
    { "ncp.at", LOG_LEVEL_INFO },
    { "net.ppp.client", LOG_LEVEL_INFO },
});
   
Process Main;

// I want to start something for getLocation, 
// but the spec says it already starts up

static long temp_timer = 0;

void setup()
{
    Tracker::instance().init();
    Serial.begin(115200);
    Main.setup();
}

void loop()
{
    Tracker::instance().loop();
    Main.loop();

    if (millis() - temp_timer >= 1000){
        temp_timer = millis();
        LocationPoint lp;            // declare a variable to hold your data
        getLocationPoint(lp);        // call the function to fill that variable with your desired data
        // Adam-But this function is not anywhere in location_service.cpp ? 
        Serial.println(lp.latitude); // use the requested data now stored in your variable
    } 
}

Compile Error:

main.cpp:59:28: error: 'getLocationPoint' was not declared in this scope

@Adam42, a few points:

  • I would avoid calling any class, structure or variable “Main” simply because ‘C’ uses main() as its primary startup function. Be a little more creative! I also assume the Main class is defined in Process.h?
  • The timer variable temp_timer doesn’t need to be declared static and it should ideally be declared unsigned long or unint32_t since time is not signed.
  • You do not need to have tracker_location.h or location_service.h #includes since these are already included in tracker.h
  • There is no such function as getLocationPoint()!! The correct function is getLocation()

Finally, in the docs, you will see getLocation() - LocationService, indicating that this function is part of the LocationService class. To correctly access this function you need to use the following form:

Tracker::instance().locationService.getLocation(lp);

You code now becomes:

#include "Particle.h"
#include "tracker_config.h"
#include "tracker.h"
#include "Process.h"

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(AUTOMATIC);

PRODUCT_ID(secret);
PRODUCT_VERSION(FIRMWARE_VERSION);

SerialLogHandler logHandler(115200, LOG_LEVEL_TRACE, {
    { "app.gps.nmea", LOG_LEVEL_INFO },
    { "app.gps.ubx",  LOG_LEVEL_INFO },
    { "ncp.at", LOG_LEVEL_INFO },
    { "net.ppp.client", LOG_LEVEL_INFO },
});
   
Process Main;

// I want to start something for getLocation, 
// but the spec says it already starts up

static long temp_timer = 0;

void setup()
{
    Tracker::instance().init();
    Serial.begin(115200);
    Main.setup();
}

void loop()
{
    Tracker::instance().loop();
    Main.loop();

    if (millis() - temp_timer >= 1000){
        temp_timer = millis();
        LocationPoint lp;            // declare a variable to hold your data
        Tracker::instance().locationService.getLocation(lp);        // call the function to fill that variable with your desired data
        // Adam-But this function is not anywhere in location_service.cpp ? 
        Serial.println(lp.latitude); // use the requested data now stored in your variable
    } 
}
2 Likes

I miscopied the function name. It obviously should have been getLocation() instead of getLocationPoint() :blush:

Although that should not have been too hard to deduce from what was said :wink:

2 Likes

haha! Agreed @ScruffR, I should have figured it out.

I will say though, that needing to add the Tracker::instance().locationService. part at the beginning before.getlocation() is what threw me off.

I don’t have a good understanding of what’s happening with this syntax.
However, now that I know it exists I have a pretty clear view of how it will work going forward.

Thank you @peekay123 and @ScruffR for your help!

1 Like