Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers/location: Add location API #46660

Conversation

bjarki-trackunit
Copy link
Collaborator

The rational behind this API and accompanying subsystem
is to define a generic format and API for getting data
from any driver which is capable of supplying such data,
whether it is as a primary or secondary function of the
device the driver is written for.

A device with the primary purpose of providing location
data could be a GPS or GNSS sensor/modem. These devices
should implement the location API as part of their own
API, then register themselves to the location subsystem
as well.

A device with the secondary purpose of providing location
data could be a cellular modem, using triangulation, or
WIFI location. These devices only implement the API in
their drivers, and register to the location subsystem.

The application can then get a list of all registered
location providers and iterate through them, looking for
the best fitting location data. They can also get a ptr
to the underlying device instance to perform other
functions like resume/suspend etc.

The specific data in question is:

The position of the device in latitude and longitude, in
the unit microdegrees, from, -180000000 to 18000000.
A single microdegree is approx. 11 cm along the earths surface.

The bearing of the device movement relative to True North in
millidegrees.

The speed of the device relative to ground in millimeters pr
second

The altitude relative to the mean sea level in millimeters.

The 4 different parameters are all accompanied by the time
the data was created, along with a well defined accuracy
measurement. This allows the application to directly compare
the parameters, even though they may be from different device
types.

The overarching goal of adding this subsystem is to create a
base from which to create an API for GNSS devices, and add
cellular triangulation to existing and future modem drivers.

Signed-off-by: Bjarki AA baa@trackunit.com

@bjarki-trackunit bjarki-trackunit changed the title Add location subsystem and API subsys: Add location subsystem and API Jun 17, 2022
@bjarki-trackunit bjarki-trackunit force-pushed the add_location_subsys branch 2 times, most recently from 14e2086 to 2dcb7c0 Compare June 17, 2022 19:12
@bjarki-trackunit bjarki-trackunit changed the title subsys: Add location subsystem and API location: Add location subsystem and API Jun 17, 2022
@bjarki-trackunit bjarki-trackunit force-pushed the add_location_subsys branch 4 times, most recently from ea3d898 to 1eb210a Compare June 17, 2022 20:54
@stephanosio stephanosio added the area: API Changes to public APIs label Jun 18, 2022
/**
* @brief Location API
*/
__subsystem struct location_provider_api {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this sustainable when we implement more info of the NMEA sentence in the future? Each of the data seems to have its own uptime and accuracy field, I'm wondering if it would be easier if they are in a single struct instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The location API is not tied directly with NMEA frames, the GNSS driver will handle these.

The sustainability of this API/subsystem is a result of the location data only being the essentials provided by any location provider. As long as the earth is spherical, and physics don't change, the API is essentially "future proof".

Technically we can combine the uptime and accuracy into a struct and name it something like metadata. I don't know if it is actually a useful idea though, I personally prefer the verbose nature of having the fields there.

/** Longitudal position in microdegrees (0 to +-180000000) */
int32_t longitude;
/** The uptime when the position was determined */
int64_t uptime;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For NMEA sentences we would be able to get the UTC time, but seems like we have nowhere to store it in this API?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is by design, the real time will get its own API and subsystem, where devices which can provide it will register themselves, as well as timekeepers like RTC clocks. We will create a design proposal for this later.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that we should somehow be able to sync the onboard time with the GNSS time, which should be another proposal. But for this location API, I would also need to know the time of the fix, which doesn't seem possible?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the real time is known by the system, through an RTC for example, the uptime parameter contained with all location data can be used to determine the time since the data was created.

If the real time is not known, the age of the data can be determined like this

struct location_position position;
uint32_t position_age_ms = k_uptime_get() - position.uptime;

If the real time in utc is known, then the time the sample was created can be determined like this

struct location_position position;
uin32_t position_timestamp_utc = rtc_get_timestamp_utc() - (position_age_ms / 1000);

Copy link
Collaborator

@ycsin ycsin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only have experience with GNSS module that outputs NMEA sentences and Quectel cellular location, some initial suggestions that I have, based on my custom location interface in my application:

  1. Sometimes it takes a while for the GNSS to get a fix, so I had a timeout arg for my get_location API call (When the GNSS location provider took too long to get a fix, I will try to get a fix from the cellular location provider)
  2. Probably something to notify the app that a fix is available asynchronously, though callback/signal?

/** The uptime when the position was determined */
int64_t uptime;
/** Accuracy radius in millimeters */
uint32_t accuracy;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering what module provides this data? AFAIK we aren't able to get this from typical NMEA sentences. Also, is this accuracy supposed to be the same for other metrics like speed/bearing?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The accuracy calculation is completely dependent on the technology used to determine the location. For GNSS, it would be based on HDOP or similar. See https://web.archive.org/web/20160310132600/http://edu-observatory.org/gps/gps_accuracy.html for a guide to determining accuracy from this value. Some manufacturers may also provide tables with this data.

@bjarki-trackunit
Copy link
Collaborator Author

bjarki-trackunit commented Jun 20, 2022

I only have experience with GNSS module that outputs NMEA sentences and Quectel cellular location, some initial suggestions that I have, based on my custom location interface in my application:

1. Sometimes it takes a while for the GNSS to get a fix, so I had a timeout arg for my `get_location` API call (When the GNSS location provider took too long to get a fix, I will try to get a fix from the cellular location provider)

2. Probably something to notify the app that a fix is available asynchronously, though callback/signal?

There will definitely be a callback the application can register to, and an event providers can raise to indicate they have data ready. This callback would most likely return a pointer to the location provider with the updated data.

To indicate that the data is not ready, the driver implementing the location API can simply return an error, like -ENODATA, or setting the uptime to 0 or -1, but i prefer the error code :)

@ycsin
Copy link
Collaborator

ycsin commented Jun 20, 2022

There will definitely be a callback the application can register to, and an event providers can call to indicate they have data ready. This callback would most likely return a pointer to the location provider with the updated data.

This sounds good

To indicate that the data is not ready, the driver implementing the location API can simply return an error, like -ENODATA, or setting the uptime to 0 or -1, but i prefer the error code :)

IMO async notification/ get data with timeout is better than polling

@ycsin
Copy link
Collaborator

ycsin commented Jun 20, 2022

@bjarki-trackunit
Copy link
Collaborator Author

bjarki-trackunit commented Jun 20, 2022

There will definitely be a callback the application can register to, and an event providers can call to indicate they have data ready. This callback would most likely return a pointer to the location provider with the updated data.

This sounds good

To indicate that the data is not ready, the driver implementing the location API can simply return an error, like -ENODATA, or setting the uptime to 0 or -1, but i prefer the error code :)

IMO async notification/ get data with timeout is better than polling

I think both direct calls and callbacks should be available. I will begin work on the callback upon new data available from specific provider today, should hopefully only take hours to implement and test. And i will add "return -ENODATA in case data is not available" to the location API descriptions

@bjarki-trackunit
Copy link
Collaborator Author

bjarki-trackunit commented Jun 20, 2022

To be clear This is not the GNSS API :D The location API should be used as a foundation for it. The GNSS driver will provide a lot more data specific to the GNSS itself, alongside the location data, like satelite count etc. and possibly a NMEA passthrough.

An example of the location provider and future real time provider API used as foundation for GNSS API

struct gnss_driver_api {
    struct location_provider_api loc_api;
    struct real_time_provider_api rt_api; (to be designed)
    gnss_satelite_cnt_get_t satelite_cnt_get;
    gnss_nmea_cb_register_t nmea_cb_register;
    ...
}

The GNSS then registeres itself as a location provider during runtime init

init gnss_init(const struct device *dev)
{   
    struct location_provider_api *loc_api = ((struct gnss_driver_api*)dev->api)->loc_api;
    location_provider_register(dev, loc_api);
    ...

Regarding #46447, work on implementing the location_api can start if this pull request is accepted, the driver is then ready for implementing the GNSS API once it is designed and merged as well.

@bjarki-trackunit
Copy link
Collaborator Author

Well, I have made a mistake it seems, closing this pull request and starting fresh... Sorry for the inconvenience

@glarsennordic
Copy link
Contributor

glarsennordic commented Jul 27, 2022

Do you mind putting a link to your next iteration here when it is started? I would like to keep up to date with this

@bjarki-trackunit
Copy link
Collaborator Author

Do you mind putting a link to your next iteration here when it is started? I would like to keep up to date with this

Absolutely :)

@jukkar
Copy link
Member

jukkar commented Aug 1, 2022

There should be no need to create a new PR, just force push you changes to this PR.

@bjarki-trackunit
Copy link
Collaborator Author

Here is a link to the new PR #48536

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: API Changes to public APIs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet