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"
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 {
94  float psd_lp_coeff;
95  uint16_t cfar_guard;
96  uint16_t cfar_win;
103 
104 /**
105  * @brief Surface velocity application context handle
106  */
107 typedef struct
108 {
113  void *buffer;
114  uint32_t buffer_size;
115 
117 
119  float sweep_rate;
120  uint16_t step_length;
121  uint32_t start_point;
123  uint16_t num_distances;
125  uint16_t segment_length;
128  uint16_t middle_index;
129 
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;
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;
150  uint16_t num_peaks;
156 
157 /**
158  * @brief Surface velocity application results container
159  */
160 typedef struct
161 {
162  float estimated_v;
163  float distance_m;
165 
167 
169 
171 
173 
175 
177 
179 
181 
183 
185 
187 
189 
191 
192 static float get_angle_correction(float surface_distance, float distance);
193 
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;
209 
210  printf("Acconeer software version %s\n", acc_version_get());
211 
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 
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 
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 
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 
286  }
287  }
288 
289  cleanup(&handle, &config);
290 
291  printf("Application finished OK\n");
292 
293  return EXIT_SUCCESS;
294 }
295 
297 {
298  for (uint16_t i = 0U; i < handle->segment_length; i++)
299  {
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  {
311  }
312  else
313  {
315  }
316  }
317 }
318 
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 
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 
356 {
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  {
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  {
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  {
413  }
414 
415  if (handle->fft_out != NULL)
416  {
418  }
419 
420  if (handle->psds != NULL)
421  {
423  }
424 
425  if (handle->psd != NULL)
426  {
428  }
429 
430  if (handle->window != NULL)
431  {
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 
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 
466 
467  acc_config_profile_set(config->sensor_config, profile);
468 }
469 
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,
477 }
478 
480 {
481  config->surface_distance = CONFIG_SURFACE_DISTANCE;
482  config->sensor_angle = CONFIG_SENSOR_ANGLE;
483  config->psd_lp_coeff = CONFIG_PSD_LP_COEFF;
485  config->velocity_lp_coeff = CONFIG_VELOCITY_LP_COEFF;
486 
487  acc_config_hwaas_set(config->sensor_config, CONFIG_HWAAS);
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);
504 }
505 
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 
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
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  {
562  }
563  } while (status && !cal_complete);
564  }
565 
566  if (status)
567  {
568  // Reset sensor after calibration by disabling/enabling it
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 
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 
602 
604  if (handle->sensor == NULL)
605  {
606  printf("acc_sensor_create() failed\n");
607  return false;
608  }
609 
611  {
612  printf("do_sensor_calibration_and_prepare() failed\n");
613  acc_sensor_status(handle->sensor);
615  return false;
616  }
617 
618  return true;
619 }
620 
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 
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 
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  */
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 
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 
857 {
858  bool status = false;
859 
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 
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 
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.