This is a collection of helper functions for processing of the sparse IQ data that is generated by Acconeer's A121 radar sensor. The functions are used by Acconeer's processing examples to show common processing steps when working on sparse IQ data. The purpose of the helper functions is to increase the readability of the example programs. The helper functions do not provide optimized implementations of the processing steps.
#include <assert.h>
#include <complex.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_DATA_ENTRY_LEN_IQ 87
#define MAX_DATA_ENTRY_LEN_FLOAT 44
{
if (vector_iq == NULL)
{
return NULL;
}
vector_iq->
data = malloc(data_length *
sizeof(
float complex));
if (vector_iq->
data == NULL)
{
free(vector_iq);
return NULL;
}
return vector_iq;
}
{
if (vector_float == NULL)
{
return NULL;
}
vector_float->
data = malloc(data_length *
sizeof(
float));
if (vector_float->
data == NULL)
{
free(vector_float);
return NULL;
}
return vector_float;
}
{
if (vector == NULL)
{
return;
}
free(vector);
}
{
if (vector == NULL)
{
return;
}
free(vector);
}
{
if (time_constant_s <= 0.0f)
{
return 0.0f;
}
else
{
return expf(-1.0f / (time_constant_s * update_rate_hz));
}
}
{
return fminf(static_sf, 1.0f - 1.0f / (1.0f + update_count));
}
{
{
averaged_data->
data[i] = sf * averaged_data->
data[i] + (1.0f - sf) * current->
data[i];
}
}
{
{
averaged_data->
data[i] = sf * averaged_data->
data[i] + (1.0f - sf) * current->
data[i];
}
}
{
for (uint32_t i = 0; i < data_length; i++)
{
}
}
{
assert(point < control_helper_state->proc_meta.sweep_data_length);
{
}
}
{
return (peak_width_points / step_length) | 1;
}
{
assert(data_length % 2 == 1);
uint32_t mid_offset = (data_length + 1) / 2;
float sum = 0.0f;
for (uint32_t i = 0; i < data_length; i++)
{
if (i < mid_offset)
{
vector_out->
data[i] = (float)i + 1;
}
else
{
vector_out->
data[i] = (float)(data_length - i);
}
sum += vector_out->
data[i];
}
for (uint32_t i = 0; i < data_length; i++)
{
vector_out->
data[i] /= sum;
}
}
{
{
vector_out->
data[i] = 0.0f;
for (uint32_t j = 0; j < filter_vector->
data_length; j++)
{
int32_t a_index = i + j - offset;
if (a_index >= 0 && (uint32_t)a_index < vector_a->data_length)
{
vector_out->
data[i] += vector_a->
data[a_index] * filter_vector->
data[j];
}
}
}
}
{
{
vector_out->
data[i] = vector_a->
data[i];
}
}
{
{
vector_out->
data[i] = vector_a->
data[i] + vector_b->
data[i];
}
}
{
{
vector_out->
data[i] = vector_a->
data[i] - vector_b->
data[i];
}
}
{
{
vector_out->
data[i] = vector_a->
data[i] * vector_b->
data[i];
}
}
{
{
vector_out->
data[i] = vector_a->
data[i] * conjf(vector_b->
data[i]);
}
}
{
float complex rotated_unit_vector = cexpf(radians*I);
{
vector_a->
data[i] *= rotated_unit_vector;
}
}
{
{
vector_a->
data[i] = conjf(vector_a->
data[i]);
}
}
{
{
vector_out->
data[i] = cabsf(vector_a->
data[i]);
}
}
{
float complex coherent_mean = 0;
{
coherent_mean += vector_a->
data[i];
}
}
{
float noncoherent_mean_amplitude = 0;
{
noncoherent_mean_amplitude += cabsf(vector_a->
data[i]);
}
return noncoherent_mean_amplitude / vector_a->
data_length;
}
{
{
vector_out->
data[i] = cargf(vector_a->
data[i]);
}
}
{
float max = -INFINITY;
int max_index = -1;
{
if (vector_a->
data[i] > max)
{
max_index = i;
}
}
return max_index;
}
{
float max = -INFINITY;
int max_index = -1;
assert(elemets_to_skip < vector_a->data_length - elemets_to_skip);
for (uint32_t i = elemets_to_skip; i < (vector_a->
data_length - elemets_to_skip); i++)
{
if (vector_a->
data[i] > max)
{
max_index = i;
}
}
return max_index;
}
{
return (y1 - y3) / (2.0f * y1 - 4.0f * y2 + 2.0f * y3);
}
{
printf("%s:\n", label);
{
if ((i > 0) && ((i % 8) == 0))
{
printf("\n");
}
printf("%14s ", buffer);
}
printf("\n");
}
{
printf("%s: ", label);
{
if ((i > 0) && ((i % 8) == 0))
{
printf("\n");
}
printf("%14s ", buffer);
}
printf("\n");
}