example_processing_peak_interpolation.c
Go to the documentation of this file.
1 // Copyright (c) Acconeer AB, 2022-2024
2 // All rights reserved
3 // This file is subject to the terms and conditions defined in the file
4 // 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part
5 // of this source code package.
6
7 #include <assert.h>
8 #include <stdbool.h>
9 #include <stdint.h>
10 #include <stdio.h>
11
12 #include "acc_config.h"
13 #include "acc_definitions_a121.h"
14 #include "acc_hal_definitions_a121.h"
15 #include "acc_hal_integration_a121.h"
16 #include "acc_integration_log.h"
17 #include "acc_rss_a121.h"
18 #include "acc_version.h"
19
20 #include "acc_control_helper.h"
21 #include "acc_processing_helpers.h"
22
23 #define SENSOR_ID (1U)
24
25 static void update_configuration(acc_config_t *config);
26
27 /** \example example_processing_peak_interpolation.c
28 * @brief example_processing_peak_interpolation.c
29 * This program shows how to apply a distance filter and how to interpolate the
30 * position of the peak to improve distance accuracy.
31 *
32 * The distance filter is applied to the IQ data and will reduce noise and smooth out
33 * the the amplitude of the radar eacho peaks. The smoothing is important for the
34 * next step where we estimate the acctual position of the peak, i.e the position
35 * of the peak that we would have gotten if we had used an shorter distance between
36 * the measurement steps.
37 */
38
39 int acconeer_main(int argc, char *argv[]);
40
41 int acconeer_main(int argc, char *argv[])
42 {
43 (void)argc;
44 (void)argv;
45
46 acc_control_helper_t control_helper_state = {0};
47
48 const uint32_t peak_width_points = 104; // Approximate peak width for profile 3
49
50 printf("Acconeer software version %s \n", acc_version_get());
51
52 const acc_hal_a121_t *hal = acc_hal_rss_integration_get_implementation();
53
54 if (!acc_rss_hal_register(hal))
55 {
56 return EXIT_FAILURE;
57 }
58
59 bool status_ok = acc_control_helper_create(&control_helper_state, SENSOR_ID);
60
61 if (!status_ok)
62 {
63 printf("acc_control_helper_create ()failed \n");
64 return EXIT_FAILURE;
65 }
66
67 update_configuration(control_helper_state.config);
68
69 status_ok = acc_control_helper_activate(&control_helper_state);
70
71 if (!status_ok)
72 {
73 printf("acc_control_helper_activate ()failed\n");
74 acc_control_helper_destroy(&control_helper_state);
75 return EXIT_FAILURE;
76 }
77
78 uint32_t sweep_data_length = control_helper_state.proc_meta.sweep_data_length;
79 uint32_t filter_length = acc_processing_helper_get_filter_length(peak_width_points, acc_config_step_length_get(control_helper_state.config));
80
81 acc_vector_iq_t *current_sweep_iq = acc_vector_iq_alloc(sweep_data_length);
82 acc_vector_iq_t *filtered_sweep_iq = acc_vector_iq_alloc(sweep_data_length);
83
84 acc_vector_float_t *filter_vector = acc_vector_float_alloc(filter_length);
85 acc_vector_float_t *filtered_sweep_amplitude = acc_vector_float_alloc(sweep_data_length);
86
87 bool mem_ok = (current_sweep_iq != NULL) && (filtered_sweep_iq != NULL) && (filter_vector != NULL) && (filtered_sweep_amplitude != NULL);
88 if (!mem_ok)
89 {
90 printf("Memory allocation for vectors failed\n");
91 goto clean_up;
92 }
93
94 acc_vector_float_create_depth_filter_vector(filter_vector);
95
96 uint32_t iterations = 50U;
97 for (uint32_t i = 0U; i < iterations; i++)
98 {
99 if (!acc_control_helper_get_next(&control_helper_state))
100 {
101 printf("acc_control_helper_get_next() failed\n");
102 break;
103 }
104
105 acc_get_iq_sweep_vector(&control_helper_state, current_sweep_iq);
106
107 // Apply distance filter to smooth out the amplitude of the radar signal and
108 // reduce noise. Note that phase enhancement should be enabled when applying
109 // the distance filter on an IQ data vector.
110 acc_vector_iq_apply_filter(current_sweep_iq, filter_vector, filtered_sweep_iq);
111
112 // Find the index of the element with the highest amplitude. We skip the first and last
113 // element of the vector in the search as we would make an of bounds read in the next step
114 // if the max value was found in the first or last element.
115 acc_vector_iq_amplitude(filtered_sweep_iq, filtered_sweep_amplitude);
116
117 uint32_t max_peak_index = acc_vector_float_argmax_skip_edges(filtered_sweep_amplitude, 1);
118
119 // We know that the distance between steps is constant, so it is enough to
120 // use only the peak amplitude and the amplitudes before and after the peak to
121 // estimate the location of the peak relative to the location of the max value.
122 float peak_offset = acc_processing_helper_interpolate_peak_position(filtered_sweep_amplitude->data[max_peak_index - 1],
123 filtered_sweep_amplitude->data[max_peak_index],
124 filtered_sweep_amplitude->data[max_peak_index + 1]);
125
126 // Calculate the distance to the start of the measuring range and the distance between
127 // measurement steps.
128 float start = acc_processing_points_to_meter(acc_config_start_point_get(control_helper_state.config));
129 float step_length = acc_processing_points_to_meter(acc_config_step_length_get(control_helper_state.config));
130
131 // Make the final calculation of the distance to the reflecting object using the index of the
132 // value with the higest amplitude and the interpolated peak offset.
133 float distance = start + (max_peak_index + peak_offset) * step_length;
134
135 printf("Interpolated distance: %d mm\n", (int)(distance * 1000 + .5f));
136 }
137
138 clean_up:
139 acc_control_helper_destroy(&control_helper_state);
140
141 acc_vector_iq_free(current_sweep_iq);
142 acc_vector_iq_free(filtered_sweep_iq);
143 acc_vector_float_free(filter_vector);
144 acc_vector_float_free(filtered_sweep_amplitude);
145
146 printf("Application finished OK\n");
147
148 return EXIT_SUCCESS;
149 }
150
151 static void update_configuration(acc_config_t *config)
152 {
153 int32_t start_point = 100; // start at approx 100*2.5 mm ~= 250 mm
154 uint16_t step_length = 8; // 8 * 2.5 mm ~= 20 mm between each step
155 uint16_t num_points = 50; // range length ~= 250 mm + 50*20 mm ~= 1250 mm
156
157 acc_config_start_point_set(config, start_point);
158 acc_config_num_points_set(config, num_points);
159 acc_config_step_length_set(config, step_length);
160 acc_config_profile_set(config, ACC_CONFIG_PROFILE_3);
161 acc_config_hwaas_set(config, 200);
162 // The processing in this example assumes that sweeps_per_frame = 1
163 acc_config_sweeps_per_frame_set(config, 1);
164 acc_config_frame_rate_set(config, 5.0f);
165 acc_config_phase_enhancement_set(config, true);
166 acc_config_prf_set(config, ACC_CONFIG_PRF_13_0_MHZ);
167 }
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.
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_vector_float_argmax_skip_edges
uint32_t acc_vector_float_argmax_skip_edges(acc_vector_float_t *vector_a, uint32_t elements_to_skip)
Index of element with maximum value in a float vector disregarding edge elements.
Definition: acc_processing_helpers.c:375
acc_vector_float_t::data
float * data
Definition: acc_processing_helpers.h:36
acc_processing_helper_get_filter_length
uint32_t acc_processing_helper_get_filter_length(uint32_t peak_width_points, uint32_t step_length)
Calculate filter vector length.
Definition: acc_processing_helpers.c:166
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_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_config_start_point_get
int32_t acc_config_start_point_get(const acc_config_t *config)
Get the starting point of the sweep.
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_apply_filter
void acc_vector_iq_apply_filter(const acc_vector_iq_t *vector_a, acc_vector_float_t *filter_vector, acc_vector_iq_t *vector_out)
Apply a FIR filter to an IQ vector.
Definition: acc_processing_helpers.c:203
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_step_length_get
uint16_t acc_config_step_length_get(const acc_config_t *config)
Get the step length in a sweep.
acc_processing_points_to_meter
float acc_processing_points_to_meter(int32_t points)
Convert a distance or step length in points to meter.
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_peak_interpolation.c:41
SENSOR_ID
#define SENSOR_ID
Definition: example_processing_peak_interpolation.c:23
acc_vector_float_create_depth_filter_vector
void acc_vector_float_create_depth_filter_vector(acc_vector_float_t *vector_out)
Create a distance filter vector.
Definition: acc_processing_helpers.c:172
acc_processing_helpers.h
acc_config_phase_enhancement_set
void acc_config_phase_enhancement_set(acc_config_t *config, bool enable)
Enable or disable phase enhancement.
update_configuration
static void update_configuration(acc_config_t *config)
Definition: example_processing_peak_interpolation.c:151
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_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
ACC_CONFIG_PROFILE_3
@ ACC_CONFIG_PROFILE_3
Definition: acc_definitions_a121.h:54
acc_processing_helper_interpolate_peak_position
float acc_processing_helper_interpolate_peak_position(float y1, float y2, float y3)
Interpolate peak position.
Definition: acc_processing_helpers.c:395
acc_definitions_a121.h