Overview#

This is the API for the Silicon Labs Real-Time Locationing library. It provides an interface for estimating arrival and departure angles of signals and the positions of AoA/AoD signal transmitters. AoA stands for Angle-of-Arrival and AoD for Angle-of-Departure. AoX is used here when referring to both techniques.

Estimators can be created individually for each locator node using the API. Additionally, multiple estimators with different parameters can be created for a single node. An instance of the estimator is created as a libitem and the estimator is initialized. Next, the estimation parameters such as antenna array type, number of antennas, estimation mode, and so on can be set using the function calls described below.

One snapshot is a set of IQ-samples with exactly one sample for each antenna.

Software Example#

Example: Initialize an estimator, set up parameters, create the estimator, and calculate an angle estimate from previously captured I/Q samples. Finally, deinitialize the estimator after returning the angles.

// Estimator instance
sl_rtl_aox_libitem libitem1;

// Initialize the estimator
sl_rtl_aox_init(&libitem1);

// Set number of snapshots to 3
sl_rtl_aox_set_num_snapshots(&libitem1, 3);

// Set array type to SiLabs reference 4x4 Uniform Rectangular Array
sl_rtl_aox_set_array_type(&libitem1, SL_RTL_AOX_ARRAY_TYPE_4x4_URA);

// Set estimator mode to basic mode, which requires 10 estimation rounds
sl_rtl_aox_set_mode(&libitem1, SL_RTL_AOX_MODE_BASIC);

// Enable IQ sample quality analysis processing (optional)
sl_rtl_aox_iq_sample_qa_configure(&libitem1);

// Create the estimator after all of the parameters are set
sl_rtl_aox_create_estimator(&libitem1);

// Set library switch pattern mode and the pattern itself
sl_rtl_aox_set_switch_pattern_mode(&libitem1, SL_RTL_AOX_SWITCH_PATTERN_MODE_EXTERNAL);

const uint32_t number_of_channels = 4*4;
uint32_t switch_pattern[number_of_channels] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
sl_rtl_aox_update_switch_pattern(&libitem1, switch_pattern, 0);

// Configure radio with the same switching pattern
radioConfigureSwitchPattern(switch_pattern, number_of_channels); // Dummy function

// Setup variables
float azimuthOut, elevationOut;
float channelFrequency = 2.46e9f;

float *IReference, *QReference;
float **ISamples, **QSamples;
// Allocate buffers for reference period I/Q data, size 8 samples
allocate1DFloatBuffer(&IReference, 8); // Dummy function
allocate1DFloatBuffer(&QReference, 8); // Dummy function

// Allocate buffers for I/Q data from all antennas, size 3 snapshots x 16 antennas
allocate2DFloatBuffer(&ISamples, 3, 16); // Dummy function
allocate2DFloatBuffer(&QSamples, 3, 16); // Dummy function

sl_rtl_error_code result = SL_RTL_ERROR_ESTIMATION_IN_PROGRESS;

while (result != SL_RTL_ERROR_SUCCESS) {
  // Wait for new I/Q samples from radio
  waitForNewIqSampleReport(); // Dummy function

  int index = 0;
  // Get captured I/Q reference period samples from radio (example)
  for (uint32_t sample = 0; sample < 8; ++sample) {
      IReference[sample] = iq_report.samples.data[index]; // Dummy data
      QReference[sample] = iq_report.samples.data[index + 1]; // Dummy data
      index += 2;
    }
  }

  // Calculate and set phase rotation to compensate for frequency offset and switching
  float phaseRotation;
  sl_rtl_aox_calculate_iq_sample_phase_rotation(&libitem1, 2.0f, IReference, QReference, 8, &phaseRotation);
  sl_rtl_aox_set_iq_sample_phase_rotation(&libitem, phaseRotation);

  // Get captured I/Q samples from all antennas from radio (example)
  int index = 14;
  for (uint32_t snapshot = 0; snapshot < 3; ++snapshot) {
    for (uint32_t antenna = 0; antenna < 16; ++antenna) {
      ISamples[snapshot][antenna] = iq_report.samples.data[index]; // Dummy data
      QSamples[snapshot][antenna] = iq_report.samples.data[index + 1]; // Dummy data
      index += 2;
    }
  }

  // Feed I/Q data to estimator and calculate estimates
  result = sl_rtl_aox_process(&libitem1, ISamples, QSamples,
    channelFrequency, &azimuthOut, &elevationOut);
}

*returnAzimuth = azimuthOut;
*returnElevation = elevationOut;

// get the overall result of the IQ sample quality results
uint32_t sample_qa_results = sl_rtl_aox_get_iq_sample_qa_results(&libitem1);

sl_rtl_clib_iq_sample_qa_dataset_t quality_results;
sl_rtl_clib_iq_sample_qa_antenna_data_t antenna_data[numAntennas];

// get the IQ sample quality results for the latest packet
sl_rtl_aox_iq_sample_qa_get_details(&libitem1, &quality_results, antenna_data);

// get the IQ sample quality results for the latest packet using the certain radio channel
// (which is not necessarily the latest packet received)
sl_rtl_aox_iq_sample_qa_get_channel_details(&libitem1, bt_channel, &quality_results, antenna_data);

sl_rtl_aox_deinit(&libitem1);

License#

Copyright 2019-2020 Silicon Laboratories Inc. www.silabs.com

The licensor of this software is Silicon Laboratories Inc. Your use of this software is governed by the terms of Silicon Labs Master Software License Agreement (MSLA) available at www.silabs.com/about-us/legal/master-software-license-agreement. This software is distributed to you in Source Code format and is governed by the sections of the MSLA applicable to Source Code.

Information on open-source software used with the library can be found in the included license.txt file.