example_processing_subtract_adaptive_bg.c

example_processing_subtract_adaptive_bg.c This program shows how to estimate background reflections by calculating a coherent exponential average over the incomming radar measurements. As we use IQ data and include the phase information when we do the calculations, it is possible to subtract the background that contains all static - or at least almost static - reflections from the signal. What we have left are the reflections from objects in motion.

// Copyright (c) Acconeer AB, 2022-2024
// All rights reserved
// This file is subject to the terms and conditions defined in the file
// 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part
// of this source code package.
/** \example example_processing_subtract_adaptive_bg.c
* @brief example_processing_subtract_adaptive_bg.c
* This program shows how to estimate background reflections by calculating a coherent
* exponential average over the incomming radar measurements. As we use IQ data and
* include the phase information when we do the calculations, it is possible to
* subtract the background that contains all static - or at least almost static -
* reflections from the signal. What we have left are the reflections from objects
* in motion.
*/
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "acc_config.h"
#include "acc_definitions_a121.h"
#include "acc_hal_definitions_a121.h"
#include "acc_hal_integration_a121.h"
#include "acc_integration_log.h"
#include "acc_rss_a121.h"
#include "acc_version.h"
#include "acc_control_helper.h"
#include "acc_processing_helpers.h"
#define SENSOR_ID (1U)
static void update_configuration(acc_config_t *config);
int acconeer_main(int argc, char *argv[]);
int acconeer_main(int argc, char *argv[])
{
(void)argc;
(void)argv;
acc_control_helper_t control_helper_state = {0};
printf("Acconeer software version %s\n", acc_version_get());
const acc_hal_a121_t *hal = acc_hal_rss_integration_get_implementation();
if (!acc_rss_hal_register(hal))
{
return EXIT_FAILURE;
}
bool res = acc_control_helper_create(&control_helper_state, SENSOR_ID);
if (!res)
{
printf("acc_control_helper_create() failed\n");
return EXIT_FAILURE;
}
update_configuration(control_helper_state.config);
res = acc_control_helper_activate(&control_helper_state);
if (!res)
{
printf("acc_control_helper_activate() failed\n");
return EXIT_FAILURE;
}
uint32_t sweep_data_length = control_helper_state.proc_meta.sweep_data_length;
acc_vector_iq_t *current_sweep_iq = acc_vector_iq_alloc(sweep_data_length);
acc_vector_iq_t *adaptive_background_iq = acc_vector_iq_alloc(sweep_data_length);
acc_vector_iq_t *motion_reflections_iq = acc_vector_iq_alloc(sweep_data_length);
acc_vector_float_t *adaptive_background_amplitude = acc_vector_float_alloc(sweep_data_length);
acc_vector_float_t *motion_reflections_amplitude = acc_vector_float_alloc(sweep_data_length);
bool mem_ok = (current_sweep_iq != NULL) && (adaptive_background_iq != NULL) && (motion_reflections_iq != NULL) &&
(adaptive_background_amplitude != NULL) && (motion_reflections_amplitude != NULL);
if (!mem_ok)
{
printf("Memory allocation for vectors failed\n");
goto clean_up;
}
float time_constant_static_background = 5.0f;
float sf_adaptive_background =
acc_processing_helper_tc_to_sf(time_constant_static_background, acc_config_frame_rate_get(control_helper_state.config));
uint32_t iterations = 50U;
for (uint32_t i = 0U; i < iterations; i++)
{
if (!acc_control_helper_get_next(&control_helper_state))
{
printf("acc_control_helper_get_next() failed\n");
break;
}
acc_get_iq_sweep_vector(&control_helper_state, current_sweep_iq);
float sf = acc_processing_helper_dynamic_sf(sf_adaptive_background, i);
acc_vector_iq_update_exponential_average(current_sweep_iq, adaptive_background_iq, sf);
acc_vector_iq_subtract(current_sweep_iq, adaptive_background_iq, motion_reflections_iq);
acc_vector_iq_amplitude(adaptive_background_iq, adaptive_background_amplitude);
acc_vector_iq_amplitude(motion_reflections_iq, motion_reflections_amplitude);
acc_vector_float_print("Background amplitude", adaptive_background_amplitude);
acc_vector_float_print("Motion amplitude", motion_reflections_amplitude);
uint32_t max_peak_index_static = acc_vector_float_argmax(adaptive_background_amplitude);
uint32_t max_peak_index_motion = acc_vector_float_argmax(motion_reflections_amplitude);
printf("Highest background peak index : %" PRIu32 "\n", max_peak_index_static);
printf("Highest motion peak index : %" PRIu32 "\n", max_peak_index_motion);
}
clean_up:
acc_vector_iq_free(current_sweep_iq);
acc_vector_iq_free(adaptive_background_iq);
acc_vector_iq_free(motion_reflections_iq);
acc_vector_float_free(adaptive_background_amplitude);
acc_vector_float_free(motion_reflections_amplitude);
acc_control_helper_destroy(&control_helper_state);
printf("Application finished OK\n");
return EXIT_SUCCESS;
}
static void update_configuration(acc_config_t *config)
{
int32_t start_point = 100; // start at 250 mm
uint16_t step_length = 12;
uint16_t num_points = 16; // range length 16*12*2.5mm = 480 mm
acc_config_start_point_set(config, start_point);
acc_config_num_points_set(config, num_points);
acc_config_step_length_set(config, step_length);
acc_config_profile_set(config, ACC_CONFIG_PROFILE_2);
acc_config_hwaas_set(config, 30);
// The processing in this example assumes that sweeps_per_frame = 1
acc_config_sweeps_per_frame_set(config, 1);
acc_config_frame_rate_set(config, 10);
acc_config_prf_set(config, ACC_CONFIG_PRF_13_0_MHZ);
}
acc_config_start_point_set
void acc_config_start_point_set(acc_config_t *config, int32_t start_point)
Set the starting point of the sweep.
acc_control_helper_create
bool acc_control_helper_create(acc_control_helper_t *radar, acc_sensor_id_t sensor_id)
Create a helper instance.
Definition: acc_control_helper.c:41
acc_rss_a121.h
acc_vector_float_free
void acc_vector_float_free(acc_vector_float_t *vector)
Free storage of data elements in a float vector.
Definition: acc_processing_helpers.c:85
acc_vector_iq_free
void acc_vector_iq_free(acc_vector_iq_t *vector)
Free storage of data elements in an IQ vector.
Definition: acc_processing_helpers.c:73
acc_control_helper_t::config
acc_config_t * config
Definition: acc_control_helper.h:25
acc_version.h
acc_config_profile_set
void acc_config_profile_set(acc_config_t *config, acc_config_profile_t profile)
Set a profile.
SENSOR_ID
#define SENSOR_ID
Definition: example_processing_subtract_adaptive_bg.c:34
acc_config_sweeps_per_frame_set
void acc_config_sweeps_per_frame_set(acc_config_t *config, uint16_t sweeps)
Set sweeps per frame.
acc_processing_helper_dynamic_sf
float acc_processing_helper_dynamic_sf(float static_sf, uint32_t update_count)
Calculate a dynamic smoothing factor.
Definition: acc_processing_helpers.c:110
acc_vector_iq_subtract
void acc_vector_iq_subtract(const acc_vector_iq_t *vector_a, const acc_vector_iq_t *vector_b, acc_vector_iq_t *vector_out)
Subtract two IQ vectors.
Definition: acc_processing_helpers.c:249
acc_control_helper_destroy
void acc_control_helper_destroy(acc_control_helper_t *radar)
Destroy a helper instance.
Definition: acc_control_helper.c:50
config
cargo_config_t config
Definition: i2c_example_cargo.c:34
ACC_CONFIG_PROFILE_2
@ ACC_CONFIG_PROFILE_2
Definition: acc_definitions_a121.h:53
acc_hal_rss_integration_get_implementation
const acc_hal_a121_t * acc_hal_rss_integration_get_implementation(void)
Get hal implementation reference.
Definition: acc_hal_integration_stm32cube_xm.c:152
acc_vector_iq_t
Definition: acc_processing_helpers.h:27
acc_config_frame_rate_set
void acc_config_frame_rate_set(acc_config_t *config, float frame_rate)
Set the frame rate.
acc_hal_a121_t
Definition: acc_hal_definitions_a121.h:82
acc_control_helper_t::proc_meta
acc_processing_metadata_t proc_meta
Definition: acc_control_helper.h:32
acc_rss_hal_register
bool acc_rss_hal_register(const acc_hal_a121_t *hal)
Register an integration.
acc_vector_iq_amplitude
void acc_vector_iq_amplitude(const acc_vector_iq_t *vector_a, acc_vector_float_t *vector_out)
Amplitude of an IQ vector.
Definition: acc_processing_helpers.c:305
acc_config_hwaas_set
void acc_config_hwaas_set(acc_config_t *config, uint16_t hwaas)
Set the hardware accelerated average samples (HWAAS)
acc_processing_metadata_t::sweep_data_length
uint16_t sweep_data_length
Definition: acc_processing.h:41
acc_control_helper.h
acc_hal_integration_a121.h
acc_version_get
const char * acc_version_get(void)
Get the version of the Acconeer software.
acc_config_t
struct acc_config acc_config_t
Definition: acc_config.h:24
printf
#define printf
Definition: printf.h:60
acc_config_frame_rate_get
float acc_config_frame_rate_get(const acc_config_t *config)
Get the frame rate.
acc_config_step_length_set
void acc_config_step_length_set(acc_config_t *config, uint16_t step_length)
Set the step length in a sweep.
acc_config_num_points_set
void acc_config_num_points_set(acc_config_t *config, uint16_t num_points)
Set the number of data points to measure.
acc_hal_definitions_a121.h
acconeer_main
int acconeer_main(int argc, char *argv[])
Assembly test example.
Definition: example_processing_subtract_adaptive_bg.c:40
acc_processing_helpers.h
acc_vector_float_t
Definition: acc_processing_helpers.h:33
acc_integration_log.h
acc_vector_iq_alloc
acc_vector_iq_t * acc_vector_iq_alloc(uint32_t data_length)
Allocate storage for an IQ vector.
Definition: acc_processing_helpers.c:27
acc_vector_float_alloc
acc_vector_float_t * acc_vector_float_alloc(uint32_t data_length)
Allocate storage for a float vector.
Definition: acc_processing_helpers.c:50
acc_vector_float_print
void acc_vector_float_print(const char *label, acc_vector_float_t *vector_a)
Print float vector.
Definition: acc_processing_helpers.c:401
acc_control_helper_t
Definition: acc_control_helper.h:23
acc_control_helper_activate
bool acc_control_helper_activate(acc_control_helper_t *radar)
Activate the sensor.
Definition: acc_control_helper.c:81
acc_config_prf_set
void acc_config_prf_set(acc_config_t *config, acc_config_prf_t prf)
Set Pulse Repetition Frequency.
ACC_CONFIG_PRF_13_0_MHZ
@ ACC_CONFIG_PRF_13_0_MHZ
Definition: acc_definitions_a121.h:118
acc_config.h
acc_control_helper_get_next
bool acc_control_helper_get_next(acc_control_helper_t *radar)
Perform a radar measurement and wait for the result.
Definition: acc_control_helper.c:157
acc_get_iq_sweep_vector
void acc_get_iq_sweep_vector(const acc_control_helper_t *control_helper_state, acc_vector_iq_t *vector_out)
Converts a newly captured IQ frame with one sweep to an IQ vector.
Definition: acc_processing_helpers.c:138
update_configuration
static void update_configuration(acc_config_t *config)
Definition: example_processing_subtract_adaptive_bg.c:137
acc_definitions_a121.h
acc_vector_float_argmax
uint32_t acc_vector_float_argmax(acc_vector_float_t *vector_a)
Index of element with maximum value in a float vector.
Definition: acc_processing_helpers.c:357
acc_vector_iq_update_exponential_average
void acc_vector_iq_update_exponential_average(const acc_vector_iq_t *current, acc_vector_iq_t *averaged_data, float sf)
Update the exponential average of an IQ vector.
Definition: acc_processing_helpers.c:116
acc_processing_helper_tc_to_sf
float acc_processing_helper_tc_to_sf(float time_constant_s, float update_rate_hz)
Convert time constant to smoothing factor.
Definition: acc_processing_helpers.c:97