Ranging Core

Introduction

The SR1010 and SR1020 ICs have the capability to gather information that can be used to do ranging measurement so that two devices exchanging data can determine the distance between each other. This documentation presents the ranging fundamentals, how this feature works and how to enable it.

Note

A ranging application example is available in the SDK. It is worth mentioning that to keep the ranging example simple, this application is limited to two devices. However, the principle remains the same if there is a need to monitor the distance between an array of devices.

The Fundamentals

Roles

At least two devices are necessary to make ranging possible. The first device’s role is called the Initiator and the other is called the Responder.

The Initiator, as its name suggests, initiates the ranging request and waits for the Responder’s reply. It then calculates the distance between itself and the Responder.

The Responder is always listening and waits for a ranging request from the Initiator. Once it receives the request, it replies with its ranging data. The Responder is unable to determine the distance measurement by itself.

The devices’ roles can be interchangeable during run-time. A device can be an Initiator and then change its role to a Responder. This is left to the user’s application to configure the radios accordingly.

Distance Calculation

The distance between two devices is calculated using time of flight data and phase offset information. The phase offset information is used to compensate for the fact that the two devices are operating in independent clock domains which could be offset with respect to each other. The distance calculation uses values from RX Waited register and the Phase Data registers from both devices as will be explained in detail.

Phase Data

Phase Data is computed automatically each time a new frame is received. The results of the computation are stored in registers. Each device will create Phase Data information. The Initiator computes and stores its Phase Data upon reception of a frame from the Responder and the Responder computes and stores its Phase Data upon reception of a frame from the Initiator. The RX Waited register contains the number of symbol clock periods that the SPARK radio had to wait before receiving a frame.

Data Exchange Sequence

The illustration below shows a simplified data exchange sequence used by the ranging algorithm.

figure not found: Basic Ranging Data Exchange

The content of the payload exchanged has little to do with the ranging operation at its core principle. Although, since the Initiator needs both device phases data for ranging calculation, the Responder must send its data back to the Initiator which it must do by including it in its payload. Once the Initiator has a complete data set, which is formed of both device phases and the RX Waited time of the Initiator, it can then calculate the distance.

Process Time Issue

At its most basic element, a ranging operation could be achieved with a request sent by the Initiator and a reply by the Responder. However, the result will not be accurate if it is done with the previous example. The ranging algorithm interprets the time of flight with the Initiator’s RX Waited time. A portion of this RX Waited time will be the processing time of the Responder. E.g., the time the MCU fetches the Phase Data from the radio and fill the payload with them. This process time completely offsets the results. The time to achieve all these steps cannot be anticipated with extreme precision. The solution for this issue is to set the Responder replies as Auto-Reply to return Phase Data without involving the MCU’s intervention.

Auto-Reply

An Auto-Reply is a feature that sends out a pre-loaded frame as soon as a frame is received. The only time constants left can easily be filtered out, it is the time it takes for a frame to be received or transmitted by the radio modem at the symbol clock frequency. What is left is the time of flight at the speed of light which varies with the distance between both devices. However, the Auto-Reply payload must be preloaded prior receiving a frame. The reception of a frame acts as a send trigger when Auto-Reply is enabled. The radio does not load automatically the Phase Data into the Auto-Reply as it is receiving a frame and needs help from the MCU to do so. One bi-directional exchange cannot provide a full data set using the Auto-Reply feature.

figure not found: Failed Ranging Data Exchange

The illustration above shows the Responder, with the Auto-Reply activated, being requested by the Initiator for a ranging operation. The first frame creates Phase Data into the Responder radio but is not loaded in the Auto-Reply frame that is being sent back. The Responder sends its Auto-Reply frame whether the payload is empty or not. That reply is received by the Initiator as a valid frame, thus creating valid Phase Data in its registers. Those exchanges create every element of the data set, but the Responder Auto-Reply can’t send its Phase Data back to the Initiator. As a result, the Initiator does not have a full data set in its possession. A second exchange is therefore required to send this missing Phase Data.

figure not found: Ranging transaction with Auto-Reply

Between the two exchanges, the Responder has the time to extract the Phase Data and load it in the Auto-Reply payload. This payload is sent as soon as the second frame is received from the Initiator. The second exchange creates new Phase Data in both devices but is irrelevant to the first data set. With this second exchange all the ranging information needed to calculate a distance is present on the Initiator.

Improving Accuracy

In most situations, a single data set will provide more or less accurate measurements for a variety of reasons. It could be affected by a slight offset in the phases value in relation to the truth or caused by multipath. The solution for this inaccuracy is to gather multiple ranging data sets or samples and calculate an average. It is possible to optimize the operation by chaining each exchange. The sequence is as shown in the two figures below:

figure not found: Ranging sequence, a succession of exchanges

In addition, the table below illustrates in an alternate way to describe how the elements containing a data set is spread over sequence of exchanges. It represents the sequence for the Initiator to gather the data set elements and calculate a single distance measurement.

figure not found: Ranging Alternate Sequence

The bigger the size of the samples are, the better the precision is going to be. The SR10x0 series can be affected by multipath in certain environments. These measurements easily stand out and filters can be used to remove them.

figure not found: Average Size vs Standard Deviation

The illustration above shows the relation between the average size and the standard deviation. The standard deviation units are in meters. The more samples are used, the better the accuracy.

Note

The Initiator cannot broadcast a ranging request to multiple Responders. This is to prevent every Responder answering back at the same time when using the Auto-Reply feature. Ranging requests needs to be done with each Responder one at the time.

Working with the Ranging Core

The ranging core needs few user’s parameters that are initialized with the function: ranging_algorithm_init(). Those parameters values are defined in the user’s application. These parameters are the following:

  • Averaging sample size

  • Algorithm type

  • Algorithm fixed-point precision

  • Ranging offset

The function from the SR1000 Transceiver API, uwb_get_phases_info() is used to fetch Phase Data from the radio registers.

The function ranging_algorithm_append() from the Ranging API, which needs to be called every time there is a new frame, concatenates all the data set into an array.

The function ranging_algorithm_calculate_float() or ranging_algorithm_calculate_qnum(), from the Ranging API, needs to be called once all the samples have been gathered. It outputs the distance between the two devices.

Parameters

Descriptions

Average sample size

The averaging size represents the number of samples or data sets to be collected. With these data sets,
the algorithm will calculate an average and this value corresponds to the distance measurement. As
previously shown, 17 exchanges are needed if an average size of 16 have been defined. It is recommended
to use a multiple of 8 for the average size.

Algorithm type

Raw data

This algorithm returns the average value in floating point.

Data corrected

This algorithm returns a filtered average in floating point. Every data point that exceeds a low/high limit,
of the calculated moving average is then removed from the final average calculation.

Raw data fixed point precision

Same as raw data but does calculate the ranging with fixed point. Returns a q_num_t value.

Corrected fixed point precision

Same as data corrected but does calculate the ranging with fixed point. Returns q_num_t value.

Algorithm fixed-point precision

The algorithm fixed-point precision is the number of bits representing the scaling factor when using fixed-point based algorithm.

Ranging Offset

A ranging offset, caused by radio intrinsic delays, can be determined via calibration. View annexes for calibration procedure.

Additional Information

When working with ranging on the SR1000 series, users should be aware of the following information:

  • The ranging distances need to be calculated by the MCU. The radio IC does not output it directly.

  • The phases data and RX Waited time are overwritten once a new frame is received regardless of if it was rejected by address filtering.

  • The phases data needs to be transferred from their register and written back to the TX FIFO by the MCU for the next Auto-Reply

  • The registers that hold the Phase Data and RX Waited are not buffered.

  • The MCU SPI speed will limit the sample rate at which a ranging operation sequence runs.

Ranging API

The Ranging API is the set of public functions the application can use to access the Ranging Core functionalities.

sdk_spark_vx.y.z/
└── core/
    └── ranging/
        ├── ranging_algorithm.h
        ├── ranging_base_fixed_point.h
        ├── ranging_algorithm_private.h
        └── ranging_base.h

Ranging Core Changelog

v0.3.0 - 2021-12-13

Changed
  • Update deprecated terms in documentation.

v0.2.0 - 2021-11-09

Added
  • Changelog.

v0.1.0 - 2021-09-30

Initial release.