Location options

I was looking at the debug log and started to wonder if there are some easy ways to shave a few bits off location updates.

Now that we are providing some options in the android app and web interface how about we add the following options:

Altitude: toggle on/off (default off)
Precision: drop down list of options 4/5/6 (default to 4)

It looks like there are currently seven decimal places. Do we really need to transmit sub-centimeter resolution (that likely isn’t even accurate) .

I found this:

  • The sign tells us whether we are north or south, east or west on the globe.

  • A nonzero hundreds digit tells us we’re using longitude, not latitude!

  • The tens digit gives a position to about 1,000 kilometers. It gives us useful information about what continent or ocean we are on.

  • The units digit (one decimal degree) gives a position up to 111 kilometers (60 nautical miles, about 69 miles). It can tell us roughly what large state or country we are in.

  • The first decimal place is worth up to 11.1 km: it can distinguish the position of one large city from a neighboring large city.

  • The second decimal place is worth up to 1.1 km: it can separate one village from the next.

  • The third decimal place is worth up to 110 m: it can identify a large agricultural field or institutional campus.

  • The fourth decimal place is worth up to 11 m: it can identify a parcel of land. It is comparable to the typical accuracy of an uncorrected GPS unit with no interference.

  • The fifth decimal place is worth up to 1.1 m: it distinguish trees from each other. Accuracy to this level with commercial GPS units can only be achieved with differential correction.

  • The sixth decimal place is worth up to 0.11 m: you can use this for laying out structures in detail, for designing landscapes, building roads. It should be more than good enough for tracking movements of glaciers and rivers. This can be achieved by taking painstaking measures with GPS, such as differentially corrected GPS.

  • The seventh decimal place is worth up to 11 mm: this is good for much surveying and is near the limit of what GPS-based techniques can achieve.

In the grand scheme of things it likely doesn’t make a huge difference, but it also seems really easy to implement. At least assuming we aren’t stuck with a variable size that takes the same transmit time regardless of its value. My limited understanding of protobuf is that this should make the payload smaller.

While on this subject can someone explain what location acks are used for?

1 Like

We have two options.

To transmit a 16bit signed number or a 32bit signed number.

16bit … -32768 to +32767
32bit … -2147483648 to 2147483647

That number then gets divider to give the decimal equivalent.

That would mean either 11km or 1km (I’m ball parking, feel free to correct me) if we send a 16bit value.

1 Like

I could easily be missing something, and the example I found is using ints, not floats, but I’m not sure a float is actually necessary.

“To understand your simple protocol buffer encoding, you first need to understand varints . Varints are a method of serializing integers using one or more bytes. Smaller numbers take a smaller number of bytes.”

@Spor7biker good point, I also wondered about this. We transmit lat/long as sint32 and we populate 7 decimal places in them, which may take 4 full bytes on the wire, depending where we are in the world (Less if close to lat/long 0/0, I’m using this to lookup how sint32 is encoded, maybe there is a better way to look at encoded values). If we populate only 4 decimal places instead (11 m accuracy, good for most use cases) we will end up with 3 bytes encoded size. So indeed we could have shaved 2 bytes off lat/long. Plus another couple of bytes in not sending the altitude. For the reference, currently the position message packet payload is ~40 bytes. Not sure it is worth it…

1 Like

re: using sint32 for storing lat/lon
Someday I’d really like to fix this slight goof. I should have used fixed32, because the numbers are currently guaranteed to be large. This would save one byte per lat/lon. But I’ve been avoiding it because we’d either need to include a little bits of backwards compatiblity glue, or it would require all nodes to update. Because the wire format is not the same.

re: using floats
I used ints because 32 bit floats don’t have enough bits of mantissa (I forget, they have about 21 bits?).

acks are typically not requested for position packet broadcasts. If want_acks is set on a packet the packet is considered “high value” and it will be retransmitted if we don’t receive an ack packet from at least one recipient. If we run out of # of retransmit attempts we will generate a nak packet and fire it back towards the original sender.

(text messages are an example of a message where want_acks is set)

I totally get that on a packet and device level a few bytes aren’t a big deal.

But… When we start multiplying that savings by a large number of nodes, updating frequently, like people organizing races want to do I think the impact can be fairly big especially with the longer range transmit settings.

In my debug log the location packets that contain alt/lon/lat include: want_responce: true

I was thinking want_responce and retries could be useful when sending location updates rarely. But when sending frequently I’d guess they would just cause congestion and old locations may come through after a more recent. Thinking about it some more unless the GPS is in some kind of power save mode that is too energy expensive to wake it might be better to send an updated location than retransmit the old one.

I see packets that only seem to have data { portnum: POSITION_APP and rx_snr
are those the ack packets?

Oh - that is slightly different than want_ack. And I think you might have discovered a bug added about a month ago when someone ‘cleaned up’ how phones provide locations when the local device doesn’t have a GPS. (I just searched the source for want_response and found this goof)

@Spor7biker What type of meshtastic device was this with? MeshServiceLocationCallback I think is setting that flag to true when it should not.

On the device side we sometimes set this flag, but only in limited cases: the first position (after a cold boot) we broadcast we set it, because we use the replies to learn the members of the mesh. We also set it when the user is viewing a particular node on the oled screen (so we can update that position frequently without requiring expensive broadcasts)

If your reply is what I expect, this will be the fix:

@geeksville I believe it is coming from a Heltec WiFi_LoRa_32_V2 that gets its position data from my phone.

I have a few different devices, most without onboard GPS.

Yes, floats are terrible on the wire. Re fixed vs sint : In some locations close to 0 lat / 0 long sint32 might save some.
However, in terms of optimization for busy network, there are much bigger fishes:

  1. 32 byte preamble - I think the motivation to save power with extra long preamble might not apply in busy network case.
  2. 4 bytes of broadcast destination could be saved by setting proper default.
    In general, though, busy network case might be lower on product priority list…