Leaps_autopos_start position appears cached, doesn't update after device is moved

We’ve discovered that a device’s absolute position (from leaps_loc_get’s
0x41 block) after leaps_autopos_start appears to be cached from its FIRST
successful trigger, and does not update on subsequent triggers even after
the device is physically moved.

Evidence: device addr=DECA687912909D08 reported position (0,0,0) when
first tested hours ago at one physical location. We then physically moved
this same device to a new location (~2m from another anchor, confirmed via
tape measure) and re-ran leaps_autopos_start (ack=0x00, success) followed
by leaps_loc_get — it still reports the exact same (0,0,0) position as
before the move, not a position reflecting its new physical location.

Separately, we’re also seeing the inter-anchor distance reported via the
0x49 block (now correctly decoded on our end) come back ~23% higher than
the real, tape-measured distance between two anchors (2.46m reported vs
2.00m actual) — is this within expected accuracy for this measurement, or
does it suggest something else is off?

Is there a way to force a genuinely fresh position recalculation on an
already-positioned device, or does autopos_start need to be preceded by
some kind of reset/clear step we’re missing? And is the ~23% distance
discrepancy expected, or a sign of a configuration issue on our end?

One more question, given LEAPS Manager (your own app) clearly achieves
reliable multi-anchor positioning that updates correctly as devices move —
can you describe the actual command sequence your app uses internally to
achieve this? Specifically: does it call autopos_start repeatedly/
periodically per device, or once per session? Does it call any other
command before or after autopos_start that we might be missing (a clear/
reset-position command, a different trigger)? We’re trying to replicate
what your own app does reliably, and having the real sequence would save
a lot of guessing.

Follow-up finding on autopos_start / inter-anchor distances:

We’ve confirmed exactly one device on our network is accepted as the
“real initiator” (ack=0x00 on leaps_autopos_start); every other device
gets ack=0x05 (undocumented status). This appears fixed to one specific
device, not something that migrates or resets via leaps_factory_reset
(tested directly — factory reset on a different device did not make it
eligible).

Using this confirmed initiator, we got ONE successful populated
inter-anchor distance reading via leaps_loc_get’s 0x49 block (real
distance + neighbor position, cross-validated between two devices, matched
each other to the millimeter). However, we have not been able to
reproduce a populated 0x49 block since, despite:

  • Confirming the second device is genuinely in Anchor mode (mode: ani)
  • Physical proximity between devices (few meters, same room)
  • Re-running leaps_autopos_start on the initiator
  • Waiting 30-60+ seconds between checks

Every subsequent leaps_loc_get on the initiator returns an empty 0x49
block (length 0x06, count 0) instead of a populated one.

Questions:

  1. What determines whether two anchors actually range with each other and
    populate this block — is there a specific trigger/condition beyond both
    being in Anchor mode and in range?
  2. Does the “05” status on non-initiator devices mean they cannot
    participate in ranging at all, or only that they can’t themselves call
    autopos_start?
  3. Is there a way to query which specific device is the current
    initiator, or to explicitly assign/reassign that role?

Happy to provide more raw captures if useful.

New, more fundamental question: we’ve discovered LEAPS’ architecture
includes a Gateway/Server layer (leapslabs/leaps_gateway,
leapslabs/leaps_server Docker images) for multi-anchor RTLS. Is this
Gateway/Server layer REQUIRED for reliable multi-anchor positioning (the
kind LEAPS Manager itself demonstrates), or is direct BLE communication
from a mobile app to individual anchors (bypassing Gateway/Server
entirely) a fully supported path for the same use case?

If Gateway/Server is required, could you point us to documentation for
running a minimal Gateway+Server setup, and confirm whether it can run
locally (e.g., on a laptop) rather than requiring cloud infrastructure? Our
use case is a mobile app for individual tradespeople doing on-site
measurements — a full server deployment per user would be a significant
architecture change from what we’ve been building against your BLE API
directly.

Hi @Trevordeanglass

I would like to summarize the information and answer your questions as follows:

The leaps_autopos_start command triggers the ranging/measurement process, but it does not itself recalculate or overwrite the device’s stored absolute position. The distance measurements need to be collected and processed by the application, and the calculated position can then be written back using leaps_pos_set. Therefore, a reset or clear step is not required before calling leaps_autopos_start.

In LEAPS Manager, we call autopos_start only once to collect the required ranging data. We then use our own positioning algorithm to process the collected data and estimate the device’s position. We do not repeatedly call autopos_start for every position update.

The initiator is determined by the device configuration. You can check whether a device has the initiator (ANI) role using leaps_cfg_get. In our workflow, we first identify the device with ANI enabled and use that device to start leaps_autopos_start.

The workflow is as follows:

Step 1: Check the anchor configuration and verify that the initiator (ANI) is enabled using leaps_cfg_get.

Step 2: Enable location data notifications using leaps_ble_evt_cfg_set.

Step 3: Start the auto-positioning procedure using leaps_autopos_start.

Step 4: Wait for the location data change notification from the BLE characteristic.

Step 5: Retrieve the distance measurements from the N nodes using leaps_loc_get.

Step 6: Calculate the device position based on the collected distance measurements.

LEAPS Server and LEAPS Gateway

The LEAPS Server acts as a central data hub for the UWB network. It connects multiple LEAPS Gateway devices to external systems through an MQTT Broker.

The LEAPS Gateway serves as a bridge between the UWB network and the TCP/IP network.

However, neither the LEAPS Gateway nor the LEAPS Server is required for the positioning workflow described above. For more details about the system architecture, please refer to the LEAPS datasheet.

Kind regards,
BXT

Thank you for your help. That makes sense.

1. Does autopos_start produce the full anchor-to-anchor distance matrix, or only initiator-to-anchor ranges? Four anchors give six distances in a full matrix but only three from the initiator alone — and three is not enough to determine the geometry. This is the single most important clarification.

**2.**	After pos_set, does the tag position come back already solved, or does loc_get still return raw ranges that you multilaterate yourself?

Hi @Trevordeanglass

Regarding the anchor-to-anchor distance matrix:

The leaps_autopos_start triggers the auto-positioning/ranging procedure, during which the anchors measure the distances between each other. Therefore, to obtain the complete set of measurements, the ranging data needs to be collected from all participating anchor nodes.

After leaps_pos_set, the tag’s calculated position is stored on the device. When we call leaps_loc_get, it can return the stored position together with the ranging data, depending on the selected output option.

Kind regards,
BXT