example_surface_velocity.c
Go to the documentation of this file.
1 // Copyright (c) Acconeer AB, 2023-2025
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 <complex.h>
8 #include <math.h>
9 #include <stdbool.h>
10 #include <stdint.h>
11 #include <stdio.h>
12 #include <string.h>
13
14 #include "acc_alg_basic_utils.h"
15 #include "acc_algorithm.h"
16 #include "acc_config.h"
17 #include "acc_definitions_a121.h"
18 #include "acc_definitions_common.h"
19 #include "acc_hal_definitions_a121.h"
20 #include "acc_hal_integration_a121.h"
21 #include "acc_integration.h"
22 #include "acc_integration_log.h"
23 #include "acc_processing.h"
24 #include "acc_rss_a121.h"
25 #include "acc_sensor.h"
26 #include "acc_version.h"
27
28 /**
29 * [Default app config - can be adapted to reflect the setup]
30 *
31 * Distance to surface in meters.
32 */
33 #define CONFIG_SURFACE_DISTANCE (1.0f)
34
35 /**
36 * [Default app config - can be adapted to reflect the setup]
37 *
38 * Angle of the sensor compared to the surface.
39 */
40 #define CONFIG_SENSOR_ANGLE (45.0f)
41
42 /**
43 * [Default app config - can be adapted to reflect the setup]
44 *
45 * Threshold level sensitivity.
46 */
47 #define CONFIG_THRESHOLD_SENSITIVITY (0.15f)
48
49 /**
50 * [Default app config - can be adapted to reflect the setup]
51 *
52 * Low-pass filtered power spectral density coefficient.
53 *
54 * Affects the stability of the estimate.
55 */
56 #define CONFIG_PSD_LP_COEFF (0.75f)
57
58 /**
59 * [Default app config - can be adapted to reflect the setup]
60 *
61 * Low-pass filtered velocity coefficient.
62 *
63 * Affects the stability of the estimate.
64 */
65 #define CONFIG_VELOCITY_LP_COEFF (0.98f)
66
67 /**
68 * [Default app config - can be adapted to reflect the setup]
69 *
70 * The sweep rate for sweeps in a frame during measurement.
71 */
72 #define CONFIG_SWEEP_RATE (3000U)
73
74 /**
75 * [Default app config - can be adapted to reflect the setup]
76 *
77 * Hardware accelerated average sampling.
78 */
79 #define CONFIG_HWAAS (16U)
80
81 #define SENSOR_ID (1U)
82 #define SENSOR_TIMEOUT_MS (1000U)
83
84 #define MIN_PEAK_VS 0.1f
85
86 /**
87 * @brief Surface velocity application config container
88 */
89 typedef struct
90 {
91 float surface_distance;
92 uint16_t time_series_length;
93 uint16_t slow_zone_half_length;
94 float psd_lp_coeff;
95 uint16_t cfar_guard;
96 uint16_t cfar_win;
97 float threshold_sensitivity;
98 float velocity_lp_coeff;
99 float max_peak_interval_s;
100 float sensor_angle;
101 acc_config_t *sensor_config;
102 } acc_surface_velocity_config_t;
103
104 /**
105 * @brief Surface velocity application context handle
106 */
107 typedef struct
108 {
109 acc_sensor_t *sensor;
110 acc_processing_t *processing;
111 acc_processing_metadata_t proc_meta;
112 acc_processing_result_t proc_result;
113 void *buffer;
114 uint32_t buffer_size;
115
116 acc_surface_velocity_config_t surface_velocity_config;
117
118 float max_peak_interval_n;
119 float sweep_rate;
120 uint16_t step_length;
121 uint32_t start_point;
122 float base_step_length_m;
123 uint16_t num_distances;
124 uint16_t sweeps_per_frame;
125 uint16_t segment_length;
126 uint16_t padded_segment_length;
127 uint16_t padded_segment_length_shift;
128 uint16_t middle_index;
129
130 int32_t *double_buffer_filter_buffer;
131 float complex *frame;
132 float complex *time_series;
133 float complex *time_series_buffer;
134 float complex *fft_out;
135 float *psds;
136 float *lp_psds;
137 float *psd;
138 float *window;
139 uint32_t *threshold_check;
140 float *bin_rad_vs;
141 float *bin_vertical_vs;
142
143 uint16_t update_index;
144 uint16_t wait_n;
145 float lp_velocity;
146 float vertical_v;
147
148 uint16_t *peak_indexes;
149 uint16_t peak_indexes_length;
150 uint16_t num_peaks;
151 float *merged_velocities;
152 float *merged_energies;
153 uint16_t merged_peaks_length;
154 uint16_t num_merged_peaks;
155 } acc_surface_velocity_handle_t;
156
157 /**
158 * @brief Surface velocity application results container
159 */
160 typedef struct
161 {
162 float estimated_v;
163 float distance_m;
164 } acc_surface_velocity_result_t;
165
166 static void cleanup(acc_surface_velocity_handle_t *handle, acc_surface_velocity_config_t *config);
167
168 static void set_config(acc_surface_velocity_config_t *config);
169
170 static void set_prf(acc_surface_velocity_config_t *config);
171
172 static void set_profile(acc_surface_velocity_config_t *config);
173
174 static bool validate_config(acc_surface_velocity_config_t *config);
175
176 static bool do_sensor_calibration_and_prepare(acc_surface_velocity_handle_t *handle, acc_surface_velocity_config_t *config);
177
178 static bool init_handle(acc_surface_velocity_handle_t *handle, acc_surface_velocity_config_t *config);
179
180 static bool init_sensor_resources(acc_surface_velocity_handle_t *handle, acc_surface_velocity_config_t *config);
181
182 static bool measure(acc_surface_velocity_handle_t *handle);
183
184 static bool process(acc_surface_velocity_handle_t *handle, acc_surface_velocity_result_t *result);
185
186 static void print_result(acc_surface_velocity_result_t *result);
187
188 static void update_threshold(acc_surface_velocity_handle_t *handle);
189
190 static bool get_velocity_estimate(acc_surface_velocity_handle_t *handle);
191
192 static float get_angle_correction(float surface_distance, float distance);
193
194 static uint16_t calc_power_spectral_density(acc_surface_velocity_handle_t *handle);
195
196 static float get_perceived_wavelength(void);
197
198 static float calc_dynamic_smoothing_factor(float static_sf, uint32_t update_count);
199
200 int acconeer_main(int argc, char *argv[]);
201
202 int acconeer_main(int argc, char *argv[])
203 {
204 (void)argc;
205 (void)argv;
206 acc_surface_velocity_config_t config = {0};
207 acc_surface_velocity_handle_t handle = {0};
208 acc_surface_velocity_result_t result = {0};
209
210 printf("Acconeer software version %s\n", acc_version_get());
211
212 const acc_hal_a121_t *hal = acc_hal_rss_integration_get_implementation();
213
214 if (!acc_rss_hal_register(hal))
215 {
216 return EXIT_FAILURE;
217 }
218
219 config.sensor_config = acc_config_create();
220 if (config.sensor_config == NULL)
221 {
222 printf("acc_config_create() failed\n");
223 cleanup(&handle, &config);
224 return EXIT_FAILURE;
225 }
226
227 set_config(&config);
228
229 set_profile(&config);
230
231 set_prf(&config);
232
233 if (!validate_config(&config))
234 {
235 printf("Failed to validate config\n");
236 cleanup(&handle, &config);
237 return EXIT_FAILURE;
238 }
239
240 if (!init_handle(&handle, &config))
241 {
242 printf("Failed to initialize handle\n");
243 cleanup(&handle, &config);
244 return EXIT_FAILURE;
245 }
246
247 if (!init_sensor_resources(&handle, &config))
248 {
249 printf("Failed to initialize sensor resources\n");
250 cleanup(&handle, &config);
251 return EXIT_FAILURE;
252 }
253
254 while (true)
255 {
256 if (!measure(&handle))
257 {
258 cleanup(&handle, &config);
259 return EXIT_FAILURE;
260 }
261
262 if (handle.proc_result.calibration_needed)
263 {
264 printf("The current calibration is not valid for the current temperature.\n");
265 printf("The sensor needs to be re-calibrated.\n");
266
267 if (!do_sensor_calibration_and_prepare(&handle, &config))
268 {
269 printf("do_sensor_calibration_and_prepare() failed\n");
270 acc_sensor_status(handle.sensor);
271 cleanup(&handle, &config);
272 return EXIT_FAILURE;
273 }
274
275 printf("The sensor was successfully re-calibrated.\n");
276 }
277 else
278 {
279 if (!process(&handle, &result))
280 {
281 cleanup(&handle, &config);
282 return EXIT_FAILURE;
283 }
284
285 print_result(&result);
286 }
287 }
288
289 cleanup(&handle, &config);
290
291 printf("Application finished OK\n");
292
293 return EXIT_SUCCESS;
294 }
295
296 static void update_threshold(acc_surface_velocity_handle_t *handle)
297 {
298 for (uint16_t i = 0U; i < handle->segment_length; i++)
299 {
300 float threshold = acc_algorithm_calculate_mirrored_one_sided_cfar(handle->psd,
301 handle->segment_length,
302 handle->middle_index,
303 handle->surface_velocity_config.cfar_win,
304 handle->surface_velocity_config.cfar_guard,
305 handle->surface_velocity_config.threshold_sensitivity,
306 i);
307
308 if (handle->psd[i] > threshold)
309 {
310 acc_alg_basic_utils_set_bit_bitarray_uint32(handle->threshold_check, i);
311 }
312 else
313 {
314 acc_alg_basic_utils_clear_bit_bitarray_uint32(handle->threshold_check, i);
315 }
316 }
317 }
318
319 static bool get_velocity_estimate(acc_surface_velocity_handle_t *handle)
320 {
321 memset(handle->merged_velocities, 0, handle->merged_peaks_length * sizeof(*handle->merged_velocities));
322 memset(handle->merged_energies, 0, handle->merged_peaks_length * sizeof(*handle->merged_energies));
323
324 bool status = acc_algorithm_merge_peaks(MIN_PEAK_VS,
325 handle->bin_vertical_vs,
326 handle->psd,
327 handle->peak_indexes,
328 handle->num_peaks,
329 handle->merged_velocities,
330 handle->merged_energies,
331 handle->merged_peaks_length,
332 &(handle->num_merged_peaks));
333
334 if (status)
335 {
336 handle->vertical_v =
337 acc_algorithm_get_peak_velocity(handle->merged_velocities,
338 handle->merged_energies,
339 NULL,
340 handle->num_merged_peaks,
341 handle->bin_vertical_vs[handle->middle_index + handle->surface_velocity_config.slow_zone_half_length]);
342 }
343
344 return status;
345 }
346
347 float get_angle_correction(float surface_distance, float distance)
348 {
349 float insonation_angle = asinf(surface_distance / distance);
350 float angle_correction = 1.0f / cosf(insonation_angle);
351
352 return angle_correction;
353 }
354
355 static void cleanup(acc_surface_velocity_handle_t *handle, acc_surface_velocity_config_t *config)
356 {
357 acc_hal_integration_sensor_disable(SENSOR_ID);
358 acc_hal_integration_sensor_supply_off(SENSOR_ID);
359
360 if (handle->processing != NULL)
361 {
362 acc_processing_destroy(handle->processing);
363 }
364
365 if (config->sensor_config != NULL)
366 {
367 acc_config_destroy(config->sensor_config);
368 }
369
370 if (handle->buffer != NULL)
371 {
372 acc_integration_mem_free(handle->buffer);
373 }
374
375 if (handle->sensor != NULL)
376 {
377 acc_sensor_destroy(handle->sensor);
378 }
379
380 if (handle->double_buffer_filter_buffer != NULL)
381 {
382 acc_integration_mem_free(handle->double_buffer_filter_buffer);
383 }
384
385 if (handle->frame != NULL)
386 {
387 acc_integration_mem_free(handle->frame);
388 }
389
390 if (handle->time_series != NULL)
391 {
392 acc_integration_mem_free(handle->time_series);
393 }
394
395 if (handle->time_series_buffer != NULL)
396 {
397 acc_integration_mem_free(handle->time_series_buffer);
398 }
399
400 if (handle->bin_rad_vs != NULL)
401 {
402 acc_integration_mem_free(handle->bin_rad_vs);
403 }
404
405 if (handle->bin_vertical_vs != NULL)
406 {
407 acc_integration_mem_free(handle->bin_vertical_vs);
408 }
409
410 if (handle->lp_psds != NULL)
411 {
412 acc_integration_mem_free(handle->lp_psds);
413 }
414
415 if (handle->fft_out != NULL)
416 {
417 acc_integration_mem_free(handle->fft_out);
418 }
419
420 if (handle->psds != NULL)
421 {
422 acc_integration_mem_free(handle->psds);
423 }
424
425 if (handle->psd != NULL)
426 {
427 acc_integration_mem_free(handle->psd);
428 }
429
430 if (handle->window != NULL)
431 {
432 acc_integration_mem_free(handle->window);
433 }
434
435 if (handle->threshold_check != NULL)
436 {
437 acc_integration_mem_free(handle->threshold_check);
438 }
439
440 if (handle->merged_velocities != NULL)
441 {
442 acc_integration_mem_free(handle->merged_velocities);
443 }
444
445 if (handle->merged_energies != NULL)
446 {
447 acc_integration_mem_free(handle->merged_energies);
448 }
449
450 if (handle->peak_indexes != NULL)
451 {
452 acc_integration_mem_free(handle->peak_indexes);
453 }
454 }
455
456 static void set_profile(acc_surface_velocity_config_t *config)
457 {
458 float optimal_distance = config->surface_distance / cosf(config->sensor_angle * (((float)M_PI) / 180.0f));
459 uint16_t optimal_point = (int)ceilf(optimal_distance / ACC_APPROX_BASE_STEP_LENGTH_M);
460 int32_t start_point = rint(optimal_point - ((int)floor((acc_config_num_points_get(config->sensor_config) - 1)) / 2) *
461 acc_config_step_length_get(config->sensor_config));
462
463 acc_config_start_point_set(config->sensor_config, start_point);
464
465 acc_config_profile_t profile = acc_algorithm_select_profile(start_point, ACC_APPROX_BASE_STEP_LENGTH_M);
466
467 acc_config_profile_set(config->sensor_config, profile);
468 }
469
470 static void set_prf(acc_surface_velocity_config_t *config)
471 {
472 uint16_t end_point = acc_config_start_point_get(config->sensor_config) +
473 (acc_config_num_points_get(config->sensor_config) - 1U) * acc_config_step_length_get(config->sensor_config);
474
475 acc_config_prf_set(config->sensor_config,
476 acc_algorithm_select_prf(end_point, acc_config_profile_get(config->sensor_config), ACC_APPROX_BASE_STEP_LENGTH_M));
477 }
478
479 static void set_config(acc_surface_velocity_config_t *config)
480 {
481 config->surface_distance = CONFIG_SURFACE_DISTANCE;
482 config->sensor_angle = CONFIG_SENSOR_ANGLE;
483 config->psd_lp_coeff = CONFIG_PSD_LP_COEFF;
484 config->threshold_sensitivity = CONFIG_THRESHOLD_SENSITIVITY;
485 config->velocity_lp_coeff = CONFIG_VELOCITY_LP_COEFF;
486
487 acc_config_hwaas_set(config->sensor_config, CONFIG_HWAAS);
488 acc_config_sweep_rate_set(config->sensor_config, CONFIG_SWEEP_RATE);
489
490 config->time_series_length = 512U;
491 config->slow_zone_half_length = 3U;
492 config->cfar_guard = 6U;
493 config->cfar_win = 6U;
494 config->max_peak_interval_s = 4.0f;
495
496 acc_config_num_points_set(config->sensor_config, 4U);
497 acc_config_step_length_set(config->sensor_config, 12U);
498 acc_config_sweeps_per_frame_set(config->sensor_config, 128U);
499 acc_config_frame_rate_set(config->sensor_config, 0.0f);
500 acc_config_double_buffering_set(config->sensor_config, true);
501 acc_config_continuous_sweep_mode_set(config->sensor_config, true);
502 acc_config_inter_frame_idle_state_set(config->sensor_config, ACC_CONFIG_IDLE_STATE_READY);
503 acc_config_inter_sweep_idle_state_set(config->sensor_config, ACC_CONFIG_IDLE_STATE_READY);
504 }
505
506 static bool validate_config(acc_surface_velocity_config_t *config)
507 {
508 uint16_t num_subsweeps = acc_config_num_subsweeps_get(config->sensor_config);
509 float sweep_rate = acc_config_sweep_rate_get(config->sensor_config);
510 uint16_t start_point = acc_config_start_point_get(config->sensor_config);
511
512 bool status = true;
513
514 if (num_subsweeps != 1U)
515 {
516 printf("Multiple subsweeps are not supported\n");
517 status = false;
518 }
519
520 if (sweep_rate == 0.0f)
521 {
522 printf("Sweep rate must be set\n");
523 status = false;
524 }
525
526 if (start_point * ACC_APPROX_BASE_STEP_LENGTH_M <= config->surface_distance)
527 {
528 printf("Start point must be > surface distance");
529 status = false;
530 }
531
532 if (config->sensor_angle <= 0 || config->sensor_angle >= 90)
533 {
534 printf("Sensor angle must be between 0 and 90 degrees");
535 status = false;
536 }
537
538 return status;
539 }
540
541 static bool do_sensor_calibration_and_prepare(acc_surface_velocity_handle_t *handle, acc_surface_velocity_config_t *config)
542 {
543 bool status = false;
544 bool cal_complete = false;
545 acc_cal_result_t cal_result;
546 const uint16_t calibration_retries = 1U;
547
548 // Random disturbances may cause the calibration to fail. At failure, retry at least once.
549 for (uint16_t i = 0; !status && (i <= calibration_retries); i++)
550 {
551 // Reset sensor before calibration by disabling/enabling it
552 acc_hal_integration_sensor_disable(SENSOR_ID);
553 acc_hal_integration_sensor_enable(SENSOR_ID);
554
555 do
556 {
557 status = acc_sensor_calibrate(handle->sensor, &cal_complete, &cal_result, handle->buffer, handle->buffer_size);
558
559 if (status && !cal_complete)
560 {
561 status = acc_hal_integration_wait_for_sensor_interrupt(SENSOR_ID, SENSOR_TIMEOUT_MS);
562 }
563 } while (status && !cal_complete);
564 }
565
566 if (status)
567 {
568 // Reset sensor after calibration by disabling/enabling it
569 acc_hal_integration_sensor_disable(SENSOR_ID);
570 acc_hal_integration_sensor_enable(SENSOR_ID);
571
572 status = acc_sensor_prepare(handle->sensor, config->sensor_config, &cal_result, handle->buffer, handle->buffer_size);
573 }
574
575 return status;
576 }
577
578 static bool init_sensor_resources(acc_surface_velocity_handle_t *handle, acc_surface_velocity_config_t *config)
579 {
580 handle->processing = acc_processing_create(config->sensor_config, &handle->proc_meta);
581 if (handle->processing == NULL)
582 {
583 printf("acc_processing_create() failed\n");
584 return false;
585 }
586
587 if (!acc_rss_get_buffer_size(config->sensor_config, &handle->buffer_size))
588 {
589 printf("acc_rss_get_buffer_size() failed\n");
590 return false;
591 }
592
593 handle->buffer = acc_integration_mem_alloc(handle->buffer_size);
594 if (handle->buffer == NULL)
595 {
596 printf("buffer allocation failed\n");
597 return false;
598 }
599
600 acc_hal_integration_sensor_supply_on(SENSOR_ID);
601 acc_hal_integration_sensor_enable(SENSOR_ID);
602
603 handle->sensor = acc_sensor_create(SENSOR_ID);
604 if (handle->sensor == NULL)
605 {
606 printf("acc_sensor_create() failed\n");
607 return false;
608 }
609
610 if (!do_sensor_calibration_and_prepare(handle, config))
611 {
612 printf("do_sensor_calibration_and_prepare() failed\n");
613 acc_sensor_status(handle->sensor);
614 cleanup(handle, config);
615 return false;
616 }
617
618 return true;
619 }
620
621 static bool init_handle(acc_surface_velocity_handle_t *handle, acc_surface_velocity_config_t *config)
622 {
623 handle->wait_n = 0U;
624 handle->update_index = 0U;
625 handle->lp_velocity = 0.0f;
626 handle->vertical_v = 0.0f;
627
628 handle->surface_velocity_config.cfar_guard = config->cfar_guard;
629 handle->surface_velocity_config.cfar_win = config->cfar_win;
630 handle->surface_velocity_config.slow_zone_half_length = config->slow_zone_half_length;
631 handle->surface_velocity_config.velocity_lp_coeff = config->velocity_lp_coeff;
632 handle->surface_velocity_config.surface_distance = config->surface_distance;
633 handle->surface_velocity_config.psd_lp_coeff = config->psd_lp_coeff;
634
635 if (config->threshold_sensitivity <= 0.0f)
636 {
637 printf("Invalid CFAR sensitivity config\n");
638 return false;
639 }
640
641 handle->surface_velocity_config.threshold_sensitivity = config->threshold_sensitivity;
642
643 handle->num_distances = acc_config_num_points_get(config->sensor_config);
644 handle->sweep_rate = acc_config_sweep_rate_get(config->sensor_config);
645 handle->start_point = acc_config_start_point_get(config->sensor_config);
646 handle->sweeps_per_frame = acc_config_sweeps_per_frame_get(config->sensor_config);
647 handle->step_length = acc_config_step_length_get(config->sensor_config);
648 handle->base_step_length_m = acc_processing_points_to_meter(1);
649
650 float estimated_frame_rate;
651
652 if (acc_config_frame_rate_get(config->sensor_config) == 0.0f)
653 {
654 estimated_frame_rate = handle->sweep_rate / handle->sweeps_per_frame;
655 }
656 else
657 {
658 estimated_frame_rate = acc_config_frame_rate_get(config->sensor_config);
659 }
660
661 handle->max_peak_interval_n = config->max_peak_interval_s * estimated_frame_rate;
662
663 if (!acc_config_continuous_sweep_mode_get(config->sensor_config))
664 {
665 handle->surface_velocity_config.time_series_length = handle->sweeps_per_frame;
666 }
667 else
668 {
669 if (handle->sweeps_per_frame > config->time_series_length)
670 {
671 printf("Too many sweeps per frame to be handled\n");
672 return false;
673 }
674 else
675 {
676 handle->surface_velocity_config.time_series_length = config->time_series_length;
677 }
678 }
679
680 handle->segment_length = handle->surface_velocity_config.time_series_length / 4U;
681
682 if (handle->segment_length % 2U != 0U)
683 {
684 handle->segment_length += 1U;
685 }
686
687 handle->padded_segment_length_shift = 0U;
688 handle->padded_segment_length = 1U << handle->padded_segment_length_shift;
689
690 while (handle->padded_segment_length < handle->segment_length)
691 {
692 handle->padded_segment_length_shift++;
693 handle->padded_segment_length = 1U << handle->padded_segment_length_shift;
694 }
695
696 handle->middle_index = rintf((float)handle->segment_length / 2.0f);
697
698 handle->double_buffer_filter_buffer = acc_integration_mem_alloc((handle->sweeps_per_frame - 2U) * sizeof(*handle->double_buffer_filter_buffer));
699 handle->time_series =
700 acc_integration_mem_alloc(handle->surface_velocity_config.time_series_length * handle->num_distances * sizeof(*handle->time_series));
701 handle->time_series_buffer = acc_integration_mem_alloc(handle->segment_length * sizeof(*handle->time_series_buffer));
702 handle->frame = acc_integration_mem_alloc(handle->num_distances * handle->sweeps_per_frame * sizeof(*handle->frame));
703 handle->bin_rad_vs = acc_integration_mem_alloc(handle->segment_length * sizeof(*handle->bin_rad_vs));
704 handle->bin_vertical_vs = acc_integration_mem_alloc(handle->segment_length * sizeof(*handle->bin_vertical_vs));
705 handle->lp_psds = acc_integration_mem_alloc(handle->segment_length * handle->num_distances * sizeof(*handle->lp_psds));
706 handle->fft_out = acc_integration_mem_alloc(handle->padded_segment_length * sizeof(*handle->fft_out));
707 handle->psds = acc_integration_mem_alloc(handle->segment_length * handle->num_distances * sizeof(*handle->psds));
708 handle->psd = acc_integration_mem_alloc(handle->segment_length * sizeof(*handle->psd));
709 handle->window = acc_integration_mem_alloc(handle->segment_length * sizeof(*handle->window));
710
711 size_t threshold_check_length = acc_alg_basic_utils_calculate_length_of_bitarray_uint32(handle->segment_length);
712
713 handle->threshold_check = acc_integration_mem_alloc(threshold_check_length * sizeof(*handle->threshold_check));
714
715 handle->merged_peaks_length = handle->segment_length / 2U;
716 handle->merged_velocities = acc_integration_mem_alloc(handle->merged_peaks_length * sizeof(*handle->merged_velocities));
717 handle->merged_energies = acc_integration_mem_alloc(handle->merged_peaks_length * sizeof(*handle->merged_energies));
718 handle->num_merged_peaks = 0U;
719
720 handle->peak_indexes_length = handle->segment_length / 2U;
721 handle->peak_indexes = acc_integration_mem_alloc(handle->peak_indexes_length * sizeof(*handle->peak_indexes));
722 handle->num_peaks = 0U;
723
724 bool alloc_success = handle->double_buffer_filter_buffer && handle->time_series != NULL && handle->time_series_buffer != NULL &&
725 handle->frame != NULL && handle->bin_rad_vs != NULL && handle->bin_vertical_vs != NULL && handle->lp_psds != NULL &&
726 handle->fft_out != NULL && handle->psds != NULL && handle->window != NULL && handle->threshold_check != NULL &&
727 handle->merged_velocities != NULL && handle->merged_energies != NULL && handle->peak_indexes != NULL;
728
729 if (!alloc_success)
730 {
731 printf("Failed to allocate resources for the surface velocity handle\n");
732 return false;
733 }
734
735 memset(handle->time_series, 0, handle->surface_velocity_config.time_series_length * handle->num_distances * sizeof(*handle->time_series));
736 memset(handle->lp_psds, 0, handle->segment_length * handle->num_distances * sizeof(*handle->lp_psds));
737 memset(handle->psds, 0, handle->segment_length * handle->num_distances * sizeof(*handle->psds));
738 memset(handle->merged_velocities, 0, handle->merged_peaks_length * sizeof(*handle->merged_velocities));
739 memset(handle->merged_energies, 0, handle->merged_peaks_length * sizeof(*handle->merged_energies));
740
741 acc_algorithm_hann(handle->segment_length, handle->window);
742
743 acc_algorithm_fftfreq(handle->segment_length, 1.0f / handle->sweep_rate, handle->bin_rad_vs);
744 acc_algorithm_fftshift(handle->bin_rad_vs, handle->segment_length);
745
746 float perceived_wavelength = get_perceived_wavelength();
747
748 for (uint16_t i = 0U; i < handle->segment_length; i++)
749 {
750 handle->bin_rad_vs[i] *= perceived_wavelength;
751 }
752
753 return true;
754 }
755
756 static bool measure(acc_surface_velocity_handle_t *handle)
757 {
758 if (!acc_sensor_measure(handle->sensor))
759 {
760 printf("acc_sensor_measure failed\n");
761 acc_sensor_status(handle->sensor);
762 return false;
763 }
764
765 if (!acc_hal_integration_wait_for_sensor_interrupt(SENSOR_ID, SENSOR_TIMEOUT_MS))
766 {
767 printf("Sensor interrupt timeout\n");
768 acc_sensor_status(handle->sensor);
769 return false;
770 }
771
772 if (!acc_sensor_read(handle->sensor, handle->buffer, handle->buffer_size))
773 {
774 printf("acc_sensor_read failed\n");
775 acc_sensor_status(handle->sensor);
776 return false;
777 }
778
779 acc_processing_execute(handle->processing, handle->buffer, &handle->proc_result);
780
781 return true;
782 }
783
784 /**
785 * @brief Calculate PSD (power spectral density)
786 *
787 * @param handle Surface velocity handle
788 * @return Distance index
789 */
790 static uint16_t calc_power_spectral_density(acc_surface_velocity_handle_t *handle)
791 {
792 for (uint16_t i = 0U; i < handle->sweeps_per_frame; i++)
793 {
794 for (uint16_t j = 0U; j < handle->num_distances; j++)
795 {
796 uint16_t index = i * handle->num_distances + j;
797
798 handle->frame[j] = ((float)handle->proc_result.frame[index].real) + ((float)handle->proc_result.frame[index].imag) * I;
799 }
800
801 acc_algorithm_roll_and_push_matrix_f32_complex(handle->time_series,
802 handle->surface_velocity_config.time_series_length,
803 handle->num_distances,
804 handle->frame,
805 false);
806 }
807
808 acc_algorithm_welch_matrix(handle->time_series,
809 handle->surface_velocity_config.time_series_length,
810 handle->num_distances,
811 handle->segment_length,
812 handle->time_series_buffer,
813 handle->fft_out,
814 handle->psds,
815 handle->window,
816 handle->padded_segment_length_shift,
817 handle->sweep_rate);
818
819 acc_algorithm_fftshift_matrix(handle->psds, handle->segment_length, handle->num_distances);
820
821 if (handle->update_index * handle->sweeps_per_frame < handle->surface_velocity_config.time_series_length)
822 {
823 for (uint16_t i = 0U; i < handle->segment_length; i++)
824 {
825 for (uint16_t j = 0U; j < handle->num_distances; j++)
826 {
827 handle->lp_psds[i * handle->num_distances + j] = handle->psds[i * handle->num_distances + j];
828 }
829 }
830 }
831
832 for (uint16_t i = 0U; i < handle->segment_length; i++)
833 {
834 for (uint16_t j = 0U; j < handle->num_distances; j++)
835 {
836 handle->lp_psds[i * handle->num_distances + j] =
837 handle->lp_psds[i * handle->num_distances + j] * handle->surface_velocity_config.psd_lp_coeff +
838 handle->psds[i * handle->num_distances + j] * (1 - handle->surface_velocity_config.psd_lp_coeff);
839 }
840 }
841
842 uint16_t index = acc_algorithm_get_distance_idx(handle->lp_psds,
843 handle->num_distances,
844 handle->segment_length,
845 handle->middle_index,
846 handle->surface_velocity_config.slow_zone_half_length);
847
848 for (uint16_t i = 0U; i < handle->segment_length; i++)
849 {
850 handle->psd[i] = handle->lp_psds[i * handle->num_distances + index];
851 }
852
853 return index;
854 }
855
856 static bool process(acc_surface_velocity_handle_t *handle, acc_surface_velocity_result_t *result)
857 {
858 bool status = false;
859
860 acc_algorithm_double_buffering_frame_filter(handle->proc_result.frame,
861 handle->sweeps_per_frame,
862 handle->num_distances,
863 handle->double_buffer_filter_buffer);
864
865 uint16_t distance_index = calc_power_spectral_density(handle);
866 float distance = acc_algorithm_get_distance_m(handle->step_length, handle->start_point, handle->base_step_length_m, distance_index);
867 float angle_correction = get_angle_correction(handle->surface_velocity_config.surface_distance, distance);
868
869 for (uint16_t i = 0U; i < handle->segment_length; i++)
870 {
871 handle->bin_vertical_vs[i] = handle->bin_rad_vs[i] * angle_correction;
872 }
873
874 update_threshold(handle);
875 handle->num_peaks = 0U;
876 status = acc_algorithm_find_peaks(handle->psd,
877 handle->segment_length,
878 handle->threshold_check,
879 handle->peak_indexes,
880 handle->peak_indexes_length,
881 &(handle->num_peaks));
882 if (status)
883 {
884 if (handle->num_peaks > 0U)
885 {
886 float max_abs_bin_vertical_v = -INFINITY;
887 for (uint16_t i = 0U; i < handle->num_peaks; i++)
888 {
889 float abs_bin_vertical_v = fabsf(handle->bin_vertical_vs[handle->peak_indexes[i]]);
890
891 max_abs_bin_vertical_v = fmaxf(abs_bin_vertical_v, max_abs_bin_vertical_v);
892 }
893
894 uint16_t velocity_index = handle->middle_index + handle->surface_velocity_config.slow_zone_half_length;
895
896 if (max_abs_bin_vertical_v > handle->bin_vertical_vs[velocity_index])
897 {
898 status = get_velocity_estimate(handle);
899
900 if (!status)
901 {
902 printf("Failed to merge peaks\n");
903 }
904 }
905 else
906 {
907 handle->vertical_v = acc_algorithm_get_peak_velocity(handle->bin_vertical_vs,
908 handle->psd,
909 handle->peak_indexes,
910 handle->num_peaks,
911 handle->bin_vertical_vs[velocity_index]);
912 }
913
914 if (status)
915 {
916 if (fabsf(handle->lp_velocity) > 0.0f && handle->vertical_v / handle->lp_velocity < 0.8f)
917 {
918 if (handle->wait_n < handle->max_peak_interval_n)
919 {
920 handle->vertical_v = handle->lp_velocity;
921 handle->wait_n += 1U;
922 }
923 }
924 else
925 {
926 handle->wait_n = 0U;
927 }
928 }
929 }
930 else
931 {
932 if (handle->wait_n < handle->max_peak_interval_n)
933 {
934 handle->vertical_v = handle->lp_velocity;
935 handle->wait_n += 1U;
936 }
937 else
938 {
939 handle->vertical_v = 0.0f;
940 }
941 }
942
943 if (status)
944 {
945 float sf = calc_dynamic_smoothing_factor(handle->surface_velocity_config.velocity_lp_coeff, handle->update_index);
946
947 if (handle->update_index * handle->sweeps_per_frame > handle->surface_velocity_config.time_series_length)
948 {
949 handle->lp_velocity = sf * handle->lp_velocity + (1.0f - sf) * handle->vertical_v;
950 }
951
952 handle->update_index += 1U;
953
954 result->estimated_v = handle->lp_velocity;
955 result->distance_m = distance;
956 }
957 }
958 else
959 {
960 printf("Failed to detect peaks\n");
961 }
962
963 return status;
964 }
965
966 static void print_result(acc_surface_velocity_result_t *result)
967 {
968 printf("Velocity: %" PRIfloat " m/s, distance: %" PRIfloat " m\n",
969 ACC_LOG_FLOAT_TO_INTEGER(result->estimated_v),
970 ACC_LOG_FLOAT_TO_INTEGER(result->distance_m));
971 }
972
973 static float get_perceived_wavelength(void)
974 {
975 const float speed_of_light = 299792458.0f;
976 const float radio_frequency = 60.5e9f;
977 const float wavelength = speed_of_light / radio_frequency;
978
979 return wavelength / 2.0f;
980 }
981
982 /**
983 * @brief Calculate a dynamic smoothing factor
984 *
985 * @param[in] static_sf The target smoothing factor that will be used after the first sweeps
986 * @param[in] update_count The update count should be 0 for the first sweep and increased by one for each update
987 * @return Dynamic smoothing factor
988 */
989 static float calc_dynamic_smoothing_factor(float static_sf, uint32_t update_count)
990 {
991 return fminf(static_sf, 1.0f - 1.0f / (1.0f + update_count));
992 }
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_surface_velocity_config_t::surface_distance
float surface_distance
Definition: example_surface_velocity.c:91
acc_config_inter_frame_idle_state_set
void acc_config_inter_frame_idle_state_set(acc_config_t *config, acc_config_idle_state_t idle_state)
Set inter frame idle state.
acc_alg_basic_utils_calculate_length_of_bitarray_uint32
static size_t acc_alg_basic_utils_calculate_length_of_bitarray_uint32(size_t number_of_bits)
Calculate length of 32-bit array to contain size number of bits.
Definition: acc_alg_basic_utils.h:38
acc_hal_integration_sensor_supply_off
void acc_hal_integration_sensor_supply_off(acc_sensor_id_t sensor_id)
Power off sensor supply.
Definition: acc_hal_integration_stm32cube_xm.c:104
acc_rss_a121.h
acc_processing_destroy
void acc_processing_destroy(acc_processing_t *handle)
Destroy a processing instance identified with the provided processing handle.
acc_hal_integration_sensor_supply_on
void acc_hal_integration_sensor_supply_on(acc_sensor_id_t sensor_id)
Power on sensor supply.
Definition: acc_hal_integration_stm32cube_xm.c:99
measure
static bool measure(acc_surface_velocity_handle_t *handle)
Definition: example_surface_velocity.c:756
acc_processing_result_t
Result provided by the processing module.
Definition: acc_processing.h:71
acc_config_continuous_sweep_mode_get
bool acc_config_continuous_sweep_mode_get(const acc_config_t *config)
Get continuous sweep mode.
acc_surface_velocity_handle_t::base_step_length_m
float base_step_length_m
Definition: example_surface_velocity.c:122
get_angle_correction
static float get_angle_correction(float surface_distance, float distance)
Definition: example_surface_velocity.c:347
acc_sensor_read
bool acc_sensor_read(const acc_sensor_t *sensor, void *buffer, uint32_t buffer_size)
Read out radar data.
acc_surface_velocity_handle_t::proc_result
acc_processing_result_t proc_result
Definition: example_surface_velocity.c:112
acc_version.h
acc_surface_velocity_config_t::psd_lp_coeff
float psd_lp_coeff
Definition: example_surface_velocity.c:94
acc_surface_velocity_handle_t::double_buffer_filter_buffer
int32_t * double_buffer_filter_buffer
Definition: example_surface_velocity.c:130
acc_rss_get_buffer_size
bool acc_rss_get_buffer_size(const acc_config_t *config, uint32_t *buffer_size)
Get the buffer size needed for the specified config.
acc_config_num_subsweeps_get
uint8_t acc_config_num_subsweeps_get(const acc_config_t *config)
Get the number of subsweeps to use.
acc_algorithm_get_distance_m
float acc_algorithm_get_distance_m(uint16_t step_length, uint16_t start_point, float base_step_length_m, uint16_t idx)
Calculate distance for a point at an index.
Definition: acc_algorithm.c:1118
acc_config_profile_set
void acc_config_profile_set(acc_config_t *config, acc_config_profile_t profile)
Set a profile.
acc_alg_basic_utils.h
acc_surface_velocity_config_t::max_peak_interval_s
float max_peak_interval_s
Definition: example_surface_velocity.c:99
acc_algorithm_double_buffering_frame_filter
void acc_algorithm_double_buffering_frame_filter(acc_int16_complex_t *frame, const uint16_t sweeps_per_frame, const uint16_t num_points, int32_t *work_buffer)
Double buffering frame filter.
Definition: acc_algorithm.c:774
acc_surface_velocity_result_t::distance_m
float distance_m
Definition: example_surface_velocity.c:163
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_config_destroy
void acc_config_destroy(acc_config_t *config)
Destroy a configuration freeing any resources allocated.
process
static bool process(acc_surface_velocity_handle_t *handle, acc_surface_velocity_result_t *result)
Definition: example_surface_velocity.c:856
acc_surface_velocity_handle_t::sensor
acc_sensor_t * sensor
Definition: example_surface_velocity.c:109
acc_cal_result_t
The result from a completed calibration.
Definition: acc_definitions_a121.h:30
CONFIG_SENSOR_ANGLE
#define CONFIG_SENSOR_ANGLE
Definition: example_surface_velocity.c:40
acc_surface_velocity_handle_t::bin_rad_vs
float * bin_rad_vs
Definition: example_surface_velocity.c:140
acc_processing_execute
void acc_processing_execute(acc_processing_t *handle, void *buffer, acc_processing_result_t *result)
Process the data according to the configuration used in create.
acc_algorithm_get_peak_velocity
float acc_algorithm_get_peak_velocity(const float *velocities, const float *energies, const uint16_t *peak_idxs, uint16_t num_peaks, float limit)
Find the velocity of the peak with the largest amplitude, prioritizing peaks with a velocity over the...
Definition: acc_algorithm.c:1009
acc_algorithm_select_profile
acc_config_profile_t acc_algorithm_select_profile(int32_t start_point, float base_step_length)
Select the highest possible profile without interference of direct leakage.
Definition: acc_algorithm.c:1125
acc_config_inter_sweep_idle_state_set
void acc_config_inter_sweep_idle_state_set(acc_config_t *config, acc_config_idle_state_t idle_state)
Set inter sweep idle state.
acc_config_create
acc_config_t * acc_config_create(void)
Create a configuration.
acc_surface_velocity_handle_t::threshold_check
uint32_t * threshold_check
Definition: example_surface_velocity.c:139
acc_surface_velocity_result_t
Surface velocity application results container.
Definition: example_surface_velocity.c:160
acc_surface_velocity_handle_t::update_index
uint16_t update_index
Definition: example_surface_velocity.c:143
set_profile
static void set_profile(acc_surface_velocity_config_t *config)
Definition: example_surface_velocity.c:456
acc_integration.h
acc_algorithm_fftfreq
void acc_algorithm_fftfreq(uint16_t n, float d, float *freqs)
Calculate the Fast Fourier Transform sample frequencies.
Definition: acc_algorithm.c:675
acc_surface_velocity_config_t::velocity_lp_coeff
float velocity_lp_coeff
Definition: example_surface_velocity.c:98
acc_surface_velocity_handle_t::padded_segment_length_shift
uint16_t padded_segment_length_shift
Definition: example_surface_velocity.c:127
acc_algorithm_welch_matrix
void acc_algorithm_welch_matrix(const float complex *data, uint16_t rows, uint16_t cols, uint16_t segment_length, float complex *data_buffer, float complex *fft_out, float *psds, const float *window, uint16_t length_shift, float fs)
Estimate power spectral density (PSD) using Welch’s method along row dimensions.
Definition: acc_algorithm.c:862
config
cargo_config_t config
Definition: i2c_example_cargo.c:34
acc_surface_velocity_config_t::slow_zone_half_length
uint16_t slow_zone_half_length
Definition: example_surface_velocity.c:93
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_surface_velocity_handle_t::num_merged_peaks
uint16_t num_merged_peaks
Definition: example_surface_velocity.c:154
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_integration_mem_alloc
void * acc_integration_mem_alloc(size_t size)
Allocate dynamic memory.
Definition: acc_integration_stm32.c:592
acc_processing_metadata_t
Metadata that will be populated by the processing module during creation.
Definition: acc_processing.h:36
acc_config_profile_get
acc_config_profile_t acc_config_profile_get(const acc_config_t *config)
Get the currently used profile.
acc_surface_velocity_handle_t::num_distances
uint16_t num_distances
Definition: example_surface_velocity.c:123
acc_hal_a121_t
Definition: acc_hal_definitions_a121.h:82
acc_surface_velocity_handle_t::sweep_rate
float sweep_rate
Definition: example_surface_velocity.c:119
cleanup
static void cleanup(acc_surface_velocity_handle_t *handle, acc_surface_velocity_config_t *config)
Definition: example_surface_velocity.c:355
acc_algorithm_fftshift_matrix
void acc_algorithm_fftshift_matrix(float *data, uint16_t rows, uint16_t cols)
Shift the zero-frequency component to the center along row dimensions.
Definition: acc_algorithm.c:849
acc_algorithm_find_peaks
bool acc_algorithm_find_peaks(const float *abs_sweep, const uint16_t data_length, const uint32_t *threshold_check, uint16_t *peak_idxs, uint16_t peak_idxs_length, uint16_t *num_peaks)
Find peaks above threshold.
Definition: acc_algorithm.c:1178
acc_rss_hal_register
bool acc_rss_hal_register(const acc_hal_a121_t *hal)
Register an integration.
acc_surface_velocity_config_t::sensor_angle
float sensor_angle
Definition: example_surface_velocity.c:100
acc_sensor.h
do_sensor_calibration_and_prepare
static bool do_sensor_calibration_and_prepare(acc_surface_velocity_handle_t *handle, acc_surface_velocity_config_t *config)
Definition: example_surface_velocity.c:541
acc_surface_velocity_handle_t::proc_meta
acc_processing_metadata_t proc_meta
Definition: example_surface_velocity.c:111
acc_config_double_buffering_set
void acc_config_double_buffering_set(acc_config_t *config, bool enable)
Enable or disable double buffering.
acc_surface_velocity_config_t
Surface velocity application config container.
Definition: example_surface_velocity.c:89
CONFIG_HWAAS
#define CONFIG_HWAAS
Definition: example_surface_velocity.c:79
acc_config_hwaas_set
void acc_config_hwaas_set(acc_config_t *config, uint16_t hwaas)
Set the hardware accelerated average samples (HWAAS)
acc_config_sweeps_per_frame_get
uint16_t acc_config_sweeps_per_frame_get(const acc_config_t *config)
Get the number of sweeps per frame.
acc_algorithm_hann
void acc_algorithm_hann(uint16_t n, float *window)
Calculate non-symmetrical hann window for a specified number of points.
Definition: acc_algorithm.c:733
acc_algorithm_calculate_mirrored_one_sided_cfar
float acc_algorithm_calculate_mirrored_one_sided_cfar(const float *data, uint16_t data_length, uint16_t middle_idx, uint16_t window_length, uint16_t half_guard_length, float sensitivity, uint16_t idx)
Calculate mirrored one sided CFAR threshold.
Definition: acc_algorithm.c:928
acc_surface_velocity_handle_t::middle_index
uint16_t middle_index
Definition: example_surface_velocity.c:128
acc_hal_integration_wait_for_sensor_interrupt
bool acc_hal_integration_wait_for_sensor_interrupt(acc_sensor_id_t sensor_id, uint32_t timeout_ms)
Wait for a sensor interrupt.
Definition: acc_hal_integration_stm32cube_xm.c:130
CONFIG_SURFACE_DISTANCE
#define CONFIG_SURFACE_DISTANCE
Definition: example_surface_velocity.c:33
acc_hal_integration_a121.h
handle
cargo_handle_t * handle
Definition: i2c_example_cargo.c:35
acc_surface_velocity_handle_t::buffer
void * buffer
Definition: example_surface_velocity.c:113
acc_algorithm_get_distance_idx
uint16_t acc_algorithm_get_distance_idx(const float *data, uint16_t cols, uint16_t rows, uint16_t middle_idx, uint16_t half_slow_zone)
Find the index of the distance column containing the largest amplitude, disregarding amplitudes prese...
Definition: acc_algorithm.c:983
ACC_CONFIG_IDLE_STATE_READY
@ ACC_CONFIG_IDLE_STATE_READY
Definition: acc_definitions_a121.h:76
result
cargo_result_t result
Definition: i2c_example_cargo.c:43
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_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.
CONFIG_VELOCITY_LP_COEFF
#define CONFIG_VELOCITY_LP_COEFF
Definition: example_surface_velocity.c:65
M_PI
#define M_PI
Definition: acc_alg_basic_utils.h:14
SENSOR_ID
#define SENSOR_ID
Definition: example_surface_velocity.c:81
acc_hal_integration_sensor_enable
void acc_hal_integration_sensor_enable(acc_sensor_id_t sensor_id)
Enable sensor.
Definition: acc_hal_integration_stm32cube_xm.c:109
acc_surface_velocity_config_t::sensor_config
acc_config_t * sensor_config
Definition: example_surface_velocity.c:101
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.
CONFIG_PSD_LP_COEFF
#define CONFIG_PSD_LP_COEFF
Definition: example_surface_velocity.c:56
acc_hal_definitions_a121.h
CONFIG_THRESHOLD_SENSITIVITY
#define CONFIG_THRESHOLD_SENSITIVITY
Definition: example_surface_velocity.c:47
acc_config_sweep_rate_set
void acc_config_sweep_rate_set(acc_config_t *config, float sweep_rate)
Set the sweep rate.
acc_surface_velocity_handle_t::start_point
uint32_t start_point
Definition: example_surface_velocity.c:121
acc_surface_velocity_result_t::estimated_v
float estimated_v
Definition: example_surface_velocity.c:162
ACC_APPROX_BASE_STEP_LENGTH_M
#define ACC_APPROX_BASE_STEP_LENGTH_M
Approximate minimum step length for a sensor measurement in meters.
Definition: acc_algorithm.h:19
acc_surface_velocity_handle_t::merged_velocities
float * merged_velocities
Definition: example_surface_velocity.c:151
SENSOR_TIMEOUT_MS
#define SENSOR_TIMEOUT_MS
Definition: example_surface_velocity.c:82
acc_surface_velocity_handle_t::peak_indexes
uint16_t * peak_indexes
Definition: example_surface_velocity.c:148
acc_algorithm_select_prf
acc_config_prf_t acc_algorithm_select_prf(int16_t breakpoint, acc_config_profile_t profile, float base_step_length)
Select a suitable PRF given a breakpoint and profile.
Definition: acc_algorithm.c:1144
acc_surface_velocity_handle_t::lp_psds
float * lp_psds
Definition: example_surface_velocity.c:136
acc_alg_basic_utils_clear_bit_bitarray_uint32
static void acc_alg_basic_utils_clear_bit_bitarray_uint32(uint32_t *bitarray, size_t bit_index)
Clear bit in bit array.
Definition: acc_alg_basic_utils.h:60
MIN_PEAK_VS
#define MIN_PEAK_VS
Definition: example_surface_velocity.c:84
acc_hal_integration_sensor_disable
void acc_hal_integration_sensor_disable(acc_sensor_id_t sensor_id)
Disable sensor.
Definition: acc_hal_integration_stm32cube_xm.c:119
calc_dynamic_smoothing_factor
static float calc_dynamic_smoothing_factor(float static_sf, uint32_t update_count)
Calculate a dynamic smoothing factor.
Definition: example_surface_velocity.c:989
acc_surface_velocity_handle_t::time_series
float complex * time_series
Definition: example_surface_velocity.c:132
acc_surface_velocity_handle_t::psds
float * psds
Definition: example_surface_velocity.c:135
acc_surface_velocity_config_t::cfar_guard
uint16_t cfar_guard
Definition: example_surface_velocity.c:95
acc_surface_velocity_handle_t::frame
float complex * frame
Definition: example_surface_velocity.c:131
acc_surface_velocity_handle_t::merged_peaks_length
uint16_t merged_peaks_length
Definition: example_surface_velocity.c:153
acconeer_main
int acconeer_main(int argc, char *argv[])
Assembly test example.
Definition: example_surface_velocity.c:202
acc_processing_t
struct acc_processing_handle acc_processing_t
Definition: acc_processing.h:30
acc_integration_log.h
acc_surface_velocity_handle_t::peak_indexes_length
uint16_t peak_indexes_length
Definition: example_surface_velocity.c:149
ACC_LOG_FLOAT_TO_INTEGER
#define ACC_LOG_FLOAT_TO_INTEGER(a)
Definition: acc_integration_log.h:26
acc_surface_velocity_handle_t::num_peaks
uint16_t num_peaks
Definition: example_surface_velocity.c:150
acc_surface_velocity_handle_t::window
float * window
Definition: example_surface_velocity.c:138
acc_surface_velocity_handle_t::time_series_buffer
float complex * time_series_buffer
Definition: example_surface_velocity.c:133
acc_surface_velocity_handle_t::lp_velocity
float lp_velocity
Definition: example_surface_velocity.c:145
acc_config_continuous_sweep_mode_set
void acc_config_continuous_sweep_mode_set(acc_config_t *config, bool enabled)
Set continuous sweep mode.
acc_sensor_status
void acc_sensor_status(const acc_sensor_t *sensor)
Check the status of the sensor.
CONFIG_SWEEP_RATE
#define CONFIG_SWEEP_RATE
Definition: example_surface_velocity.c:72
acc_surface_velocity_handle_t::max_peak_interval_n
float max_peak_interval_n
Definition: example_surface_velocity.c:118
acc_surface_velocity_handle_t::buffer_size
uint32_t buffer_size
Definition: example_surface_velocity.c:114
acc_algorithm.h
init_sensor_resources
static bool init_sensor_resources(acc_surface_velocity_handle_t *handle, acc_surface_velocity_config_t *config)
Definition: example_surface_velocity.c:578
acc_surface_velocity_handle_t::processing
acc_processing_t * processing
Definition: example_surface_velocity.c:110
get_velocity_estimate
static bool get_velocity_estimate(acc_surface_velocity_handle_t *handle)
Definition: example_surface_velocity.c:319
acc_algorithm_roll_and_push_matrix_f32_complex
void acc_algorithm_roll_and_push_matrix_f32_complex(float complex *data, uint16_t rows, uint16_t cols, const float complex *column, bool pos_shift)
Roll row elements and push a new column.
Definition: acc_algorithm.c:203
acc_surface_velocity_config_t::cfar_win
uint16_t cfar_win
Definition: example_surface_velocity.c:96
acc_sensor_prepare
bool acc_sensor_prepare(acc_sensor_t *sensor, const acc_config_t *config, const acc_cal_result_t *cal_result, void *buffer, uint32_t buffer_size)
Prepare a sensor to do a measurement.
acc_algorithm_fftshift
void acc_algorithm_fftshift(float *data, uint16_t data_length)
Shift the zero-frequency component to the center.
Definition: acc_algorithm.c:857
acc_integration_mem_free
void acc_integration_mem_free(void *ptr)
Free dynamic memory.
Definition: acc_integration_stm32.c:602
init_handle
static bool init_handle(acc_surface_velocity_handle_t *handle, acc_surface_velocity_config_t *config)
Definition: example_surface_velocity.c:621
acc_config_profile_t
acc_config_profile_t
Profile.
Definition: acc_definitions_a121.h:49
acc_definitions_common.h
update_threshold
static void update_threshold(acc_surface_velocity_handle_t *handle)
Definition: example_surface_velocity.c:296
acc_config_prf_set
void acc_config_prf_set(acc_config_t *config, acc_config_prf_t prf)
Set Pulse Repetition Frequency.
acc_surface_velocity_config_t::time_series_length
uint16_t time_series_length
Definition: example_surface_velocity.c:92
acc_config.h
acc_config_sweep_rate_get
float acc_config_sweep_rate_get(const acc_config_t *config)
Get the sweep rate.
acc_surface_velocity_handle_t::surface_velocity_config
acc_surface_velocity_config_t surface_velocity_config
Definition: example_surface_velocity.c:116
acc_surface_velocity_handle_t::bin_vertical_vs
float * bin_vertical_vs
Definition: example_surface_velocity.c:141
acc_surface_velocity_handle_t::step_length
uint16_t step_length
Definition: example_surface_velocity.c:120
acc_sensor_calibrate
bool acc_sensor_calibrate(acc_sensor_t *sensor, bool *cal_complete, acc_cal_result_t *cal_result, void *buffer, uint32_t buffer_size)
Calibrate a sensor.
acc_config_num_points_get
uint16_t acc_config_num_points_get(const acc_config_t *config)
Get the number of data points to measure.
PRIfloat
#define PRIfloat
Specifier for printing float type using integers.
Definition: acc_integration_log.h:31
acc_surface_velocity_handle_t
Surface velocity application context handle.
Definition: example_surface_velocity.c:107
calc_power_spectral_density
static uint16_t calc_power_spectral_density(acc_surface_velocity_handle_t *handle)
Calculate PSD (power spectral density)
Definition: example_surface_velocity.c:790
acc_alg_basic_utils_set_bit_bitarray_uint32
static void acc_alg_basic_utils_set_bit_bitarray_uint32(uint32_t *bitarray, size_t bit_index)
Set bit in bit array.
Definition: acc_alg_basic_utils.h:49
acc_surface_velocity_handle_t::wait_n
uint16_t wait_n
Definition: example_surface_velocity.c:144
set_prf
static void set_prf(acc_surface_velocity_config_t *config)
Definition: example_surface_velocity.c:470
acc_surface_velocity_handle_t::segment_length
uint16_t segment_length
Definition: example_surface_velocity.c:125
acc_sensor_measure
bool acc_sensor_measure(acc_sensor_t *sensor)
Start a radar measurement with previously prepared configuration.
acc_processing_create
acc_processing_t * acc_processing_create(const acc_config_t *config, acc_processing_metadata_t *processing_metadata)
Create a processing instance with the provided configuration.
acc_surface_velocity_handle_t::merged_energies
float * merged_energies
Definition: example_surface_velocity.c:152
print_result
static void print_result(acc_surface_velocity_result_t *result)
Definition: example_surface_velocity.c:966
acc_processing.h
acc_sensor_t
struct acc_sensor acc_sensor_t
Definition: acc_sensor.h:31
cargo_config_t::threshold_sensitivity
float threshold_sensitivity
Definition: example_cargo.h:65
acc_surface_velocity_handle_t::padded_segment_length
uint16_t padded_segment_length
Definition: example_surface_velocity.c:126
acc_surface_velocity_handle_t::sweeps_per_frame
uint16_t sweeps_per_frame
Definition: example_surface_velocity.c:124
get_perceived_wavelength
static float get_perceived_wavelength(void)
Definition: example_surface_velocity.c:973
acc_surface_velocity_handle_t::vertical_v
float vertical_v
Definition: example_surface_velocity.c:146
acc_sensor_destroy
void acc_sensor_destroy(acc_sensor_t *sensor)
Destroy a sensor instance freeing any resources allocated.
acc_definitions_a121.h
acc_surface_velocity_handle_t::psd
float * psd
Definition: example_surface_velocity.c:137
set_config
static void set_config(acc_surface_velocity_config_t *config)
Definition: example_surface_velocity.c:479
acc_algorithm_merge_peaks
bool acc_algorithm_merge_peaks(float max_peak_separation, const float *velocities, const float *energies, const uint16_t *peak_idxs, uint16_t num_peaks, float *merged_velocities, float *merged_energies, uint16_t merged_peaks_length, uint16_t *num_merged_peaks)
Merges peaks.
Definition: acc_algorithm.c:1044
acc_surface_velocity_config_t::threshold_sensitivity
float threshold_sensitivity
Definition: example_surface_velocity.c:97
acc_surface_velocity_handle_t::fft_out
float complex * fft_out
Definition: example_surface_velocity.c:134
validate_config
static bool validate_config(acc_surface_velocity_config_t *config)
Definition: example_surface_velocity.c:506
acc_sensor_create
acc_sensor_t * acc_sensor_create(acc_sensor_id_t sensor_id)
Create a sensor instance.