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