u-blox / ubxlib

Portable C libraries which provide APIs to build applications with u-blox products and services. Delivered as add-on to existing microcontroller and RTOS SDKs.
Apache License 2.0
302 stars 90 forks source link

Geofencing Support #135

Closed michaelboeding closed 10 months ago

michaelboeding commented 1 year ago

This isn't exactly an issue but I was wondering if there would be Geofencing support for the MAXM10S modules soon? Or if that is even in the pipeline, I know the data sheet says a code change is required for it to be supported. Thanks

RobMeades commented 1 year ago

I'll check: I'm not aware of there being a FW version for MAXM10S that supports geofencing yet. Were you told which version it would appear in?

michaelboeding commented 1 year ago

Nope - wasn't told by anyone but it just says "Code change required" in the data sheet. So I was hoping with any luck support has been added by now, its not critical for me but it would be really nice to have. Thanks for checking

RobMeades commented 1 year ago

I've checked internally and it seems that the feedback we get from customers is that they would prefer to do the geofencing on the MCU-side rather than have it done in the GNSS chip, so I'm going to have a look at what we might do in ubxlib to make that easy.

I've tagged this as a feature request and will update when we have something; might be a month or two, can't be certain just yet.

RobMeades commented 1 year ago

We've been thinking about the shape the geofence API might take and have posted it to a preview branch here:

https://github.com/u-blox/ubxlib/blob/4b15b5724428af9770c66613a5044b2980f4a326/gnss/api/u_gnss_fence.h#L31-L491

We'd be interested in any comments you may have, if you have time of course. The feature is in active development, so subject to wild changes depending on how things go with the implementation, no promises and all that, but your feedback would be very much valued.

cturvey commented 1 year ago

I've checked internally and it seems that the feedback we get from customers is that they would prefer to do the geofencing on the MCU-side rather than have it done in the GNSS chip, so I'm going to have a look at what we might do in ubxlib to make that easy.

Ok, so I'm lurking here. I think the value of doing it within the receiver comes down to low-power or more autonomous behaviour, reducing the number of MCU required in a system, or that need to be powered/involved at a given instant.

I don't think having the GEOFENCE functionality as it was is overly burdensome from a receiver perspective. I built something very similar for prior generations.

Yes, it's a bit limited and crude, but if customers want to define complex bounding polygons that's really an application side decision. I'm not sure why them complaining it didn't suit their specific needs means it needs to be deprecated entirely for every one.

Now even with complex bounding polygons you can compute a circle that contains them, this can be very helpful for sieving large numbers of fences, can be done with integers, and without square roots, so can be very computationally efficient. ie course filtering. You can then check a decimated list of more complex fences. Perhaps caching a list you're within proximity of if they are geographically dispersed, and moving at less than Mach 3. I was dropping circles over traffic intersections I was interested in knowing when a vehicle traversed..

The API looks good, will review as it develops.

cturvey commented 1 year ago

We'd be interested in any comments you may have, if you have time of course. The feature is in active development, so subject to wild changes depending on how things go with the implementation, no promises and all that, but your feedback would be very much valued.

Thoughts here, make sure it scales well. That dealing with very large lists is considered from the outset. People are going to want/expect to dump the whole task on you, and not actively manage and cull the lists themselves.

RobMeades commented 1 year ago

I don't think having the GEOFENCE functionality as it was is overly burdensome from a receiver perspective. I built something very similar for prior generations.

Understood: it surprised me also as I thought this was a neat feature but it was a product management decision. My guess [I'm not close to this, I'm actually in the cellular side of the business] is that resources in the chip are tight.

make sure it scales well

Also understood: the lists will scale provided the heap implementation of the platform is good. That or we move to fixed arrays and the overhead/compile-time-limitations they bring. Since I've not yet come across a problem I could blame on heap fragmentation on the platforms we support, I think that pure linked lists should be good enough.

Anyway, thanks for the feedback, will update the preview branch in a moment with the latest.

michaelboeding commented 1 year ago

Yes I think some other people pointed out exactly why it would be nice to run on the module - it's low power and you wouldn't have to poll the gps constantly. That being said I would prefer a concave/convex polygon that could be loaded into the module and then alerted on changes but also distance from the nearest point on the polygon. So that's a big ask if we are extremely research constrained - but I have written code to do this on the MCU that might be useful? I'll take a look at the new branch.

And when I say distance from I only mean within a certain tolerance of the boundary of the fence. So basically two polygons where the tolerance one is slightly larger and if it's inside that then computes the distance.

Again this is a lot to ask if we are constrained on the device and maybe someone has a more efficient way of doing this - but that's just off the top of my head.

RobMeades commented 1 year ago

I would prefer a concave/convex polygon

It's possible this is the other issue: every application has its own needs and so the relatively limited facilities a module can provide end up being unused in most cases.

Anyway, your feedback would be appreciated.

RobMeades commented 1 year ago

One thing: the implementation I have in mind is currently flat; if you have a simple way of taking the curvature of the earth into account when calculating the intersection of two lines then that would be interesting.

cturvey commented 1 year ago

One thing: the implementation I have in mind is currently flat

That would be my expectation, that you're perhaps dealing with a few hundred meters, rather than multiple km, but I suppose if boundary is of a large field, airfield, test-range or military-industrial complex, these could get quite large in terms of boundaries.

Close-in, I'd opt for flat/simple model.

I think one of the scalability tricks here is to decimate what you're dealing with, ie the ability to quickly discard geofences that you're clearly way outside, and then drill down in the math and details for those candidates which are more problematic.

The list can also be diminished by understanding how fast the vehicle, or whatever, is moving, and lists of candidates being refreshed periodically to reflect what you might encounter during those intervals, rather than testing every thing, every time, and the receiver can teleport.

Perhaps the FAA, or similar national/international agencies, have some keep-out / no-fly databases one might use to test/validate usability expectations?

cturvey commented 1 year ago

The other consideration is how tightly does any of this need to resolve? With large keep-out zones the idea is to keep you away from a site, not necessarily allow for you to hug the perimeter and tip-toe between in/out of violating the site boundaries.

michaelboeding commented 1 year ago

Here's some of the stuff I used to implement my MCU solution.

https://raw.githubusercontent.com/chrberger/WGS84toCartesian/master/WGS84toCartesian.hpp

And I also used //https://github.com/chrberger/geofence/tree/master

I made some tweaks to these but nothing crazy and pretty application specific.

I think some really good points have come up so it sounds like we would need to define some different use cases and then allow those to be set.

RobMeades commented 1 year ago

Thanks both: having browsed random things on the internet for less than 10 minutes (:-)) I'm going to suggest we stick with the flat.

The issue with WGS84toCartesign, though simple, is that it would bring in floating point types, which we have so far not allowed as they cause clib sizes to balloon and, in order to keep us fleet-on-our-feet, we need to be able to "compile and run/test once", which any largish compile-time options would prevent. Maybe, though we could construct the calculation of the intersection such that WGS84toCartesign could be plugged-in?

The question then becomes, how big can a fence get before it messes up with "flat". I couldn't find a definitive answer to this but it seems like it is in kilometres, rather than metres: @michaelboeding, you plainly felt a need to handle the curvature, what kind of scale were you dealing with?

@cturvey: had anticipated that there are short-cuts to be made in the calculation to drop pointless maths, hadn't thought about keep-out zones though. Can definitely make use of speed.

cturvey commented 1 year ago

The arc-minute, nautical mile, knot stuff relates to the 1852 - 1854m type distances.

For consideration: Range-Safety Track-Limits Property-Boundary Political-Boundary No-Fly / Keep-Out Zones

One of your large customers is DJI, they probably lamented the current GEOFENCE implementation to be inadequate for their use cases. Not familiar exactly with their processes, but imagine pre-flight check/validation, and in-flight enforcement.

michaelboeding commented 1 year ago

Thanks both: having browsed random things on the internet for less than 10 minutes (:-)) I'm going to suggest we stick with the flat.

The issue with WGS84toCartesign, though simple, is that it would bring in floating point types, which we have so far not allowed as they cause clib sizes to balloon and, in order to keep us fleet-on-our-feet, we need to be able to "compile and run/test once", which any largish compile-time options would prevent. Maybe, though we could construct the calculation of the intersection such that WGS84toCartesign could be plugged-in?

The question then becomes, how big can a fence get before it messes up with "flat". I couldn't find a definitive answer to this but it seems like it is in kilometres, rather than metres: @michaelboeding, you plainly felt a need to handle the curvature, what kind of scale were you dealing with?

@cturvey: had anticipated that there are short-cuts to be made in the calculation to drop pointless maths, hadn't thought about keep-out zones though. Can definitely make use of speed.

My scale was variable - user defined. But the main reason I went with that implementation is I have written code before for 3D modeling from drone images and part of the calculation includes that type of conversion for a few projections and other things - so I just wrote the exact math into it for precision. I wasn't really resource constrained for my application.

RobMeades commented 1 year ago

Understood: I've modified the code in the preview branch to split-out the function that is currently "flat" so that an application which has the resources to do so can replace it at link-time with a function which takes the curvature of the earth into account. I've also explained in hopefully relevant places that the default implementation is only good for fences around the 1 km range.

The other API aspect that I am unsure of is whether I need to include a "confidence" factor or not. My current plan is to rely on the horizontal accuracy estimate, as reported by the GNSS device for the fix, and that alone: do you I think I need to allow some sort of multiplier on top of that? Seems a bit odd having an accuracy estimate and then just randomly multiplying it by something. Thoughts?

RobMeades commented 10 months ago

The geofencing API is now implemented and pushed to master, 457b22a57ff580d04e0ef44c87cc960e95b6289a being the last relevant commit.

An example of how to use it with GNSS is included but it can equally be used with cellular (position established through the u-blox CellLocate service) and u-ConnectExpress Wi-Fi (location established through Google, Skyhook or Here). You can also get position any which way you like and throw it at a Geofence with uGeofenceTest().

An overview of the implementation can be found at the top of u_geofence.c.

Gonna close this now, please re-open, or open a new issue, if you have additional comments/suggestions.

michaelboeding commented 10 months ago

Although this may not be the best place to put this, since it would be useful by itself not just with geofencing but the ability to take GPS coordinates and accelerometer readings to create a more accurate fix over time using a Kaman filter could be very useful. Especially for geofencing but as a separate component also for hardware that has access to accelerometer data. It would need to be able to ingest a standard format of data from the accelerometer.

https://robotics.stackexchange.com/questions/11178/kalman-filter-gps-imu

RobMeades commented 10 months ago

I will add this as a separate feature request.