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"
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 {
97  float psd_lp_coeff;
98  uint16_t cfar_guard;
99  uint16_t cfar_win;
106 
107 
108 /**
109  * @brief Surface velocity application context handle
110  */
111 typedef struct
112 {
117  void *buffer;
118  uint32_t buffer_size;
119 
121 
123  float sweep_rate;
124  uint16_t step_length;
125  uint32_t start_point;
127  uint16_t num_distances;
129  uint16_t segment_length;
132  uint16_t middle_index;
133 
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;
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;
154  uint16_t num_peaks;
160 
161 
162 /**
163  * @brief Surface velocity application results container
164  */
165 typedef struct
166 {
167  float estimated_v;
168  float distance_m;
170 
171 
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 
185 
186 
188 
189 
191 
192 
194 
195 
196 static bool measure(acc_surface_velocity_handle_t *handle);
197 
198 
200 
201 
202 static void print_result(acc_surface_velocity_result_t *result);
203 
204 
206 
207 
209 
210 
211 static float get_angle_correction(float surface_distance, float distance);
212 
213 
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 
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 
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,
329 
330  if (handle->psd[i] > threshold)
331  {
333  }
334  else
335  {
337  }
338  }
339 }
340 
341 
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  {
356  handle->merged_energies, NULL, handle->num_merged_peaks,
357  handle->bin_vertical_vs[handle->middle_index +
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 
375 {
378 
379  if (handle->processing != NULL)
380  {
382  }
383 
384  if (config->sensor_config != NULL)
385  {
387  }
388 
389  if (handle->buffer != NULL)
390  {
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  {
402  }
403 
404  if (handle->frame != NULL)
405  {
407  }
408 
409  if (handle->time_series != NULL)
410  {
412  }
413 
414  if (handle->time_series_buffer != NULL)
415  {
417  }
418 
419  if (handle->bin_rad_vs != NULL)
420  {
422  }
423 
424  if (handle->bin_vertical_vs != NULL)
425  {
427  }
428 
429  if (handle->lp_psds != NULL)
430  {
432  }
433 
434  if (handle->fft_out != NULL)
435  {
437  }
438 
439  if (handle->psds != NULL)
440  {
442  }
443 
444  if (handle->psd != NULL)
445  {
446  acc_integration_mem_free(handle->psd);
447  }
448 
449  if (handle->window != NULL)
450  {
452  }
453 
454  if (handle->threshold_check != NULL)
455  {
457  }
458 
459  if (handle->merged_velocities != NULL)
460  {
462  }
463 
464  if (handle->merged_energies != NULL)
465  {
467  }
468 
469  if (handle->peak_indexes != NULL)
470  {
472  }
473 }
474 
475 
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) *
483 
484  acc_config_start_point_set(config->sensor_config, start_point);
485 
487 
488  acc_config_profile_set(config->sensor_config, profile);
489 }
490 
491 
493 {
494  uint16_t end_point = acc_config_start_point_get(config->sensor_config) + (acc_config_num_points_get(config->sensor_config) - 1U) *
496 
499 }
500 
501 
503 {
509 
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 
527 }
528 
529 
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 
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
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  {
587  }
588  } while (status && !cal_complete);
589  }
590 
591  if (status)
592  {
593  // Reset sensor after calibration by disabling/enabling it
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 
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 
628 
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 
649 {
650  handle->wait_n = 0U;
651  handle->update_index = 0U;
652  handle->lp_velocity = 0.0f;
653  handle->vertical_v = 0.0f;
654 
656  handle->surface_velocity_config.cfar_win = config->cfar_win;
661 
662  if (config->threshold_sensitivity <= 0.0f)
663  {
664  printf("Invalid CFAR sensitivity config\n");
665  return false;
666  }
667 
669 
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 
690  {
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  {
703  }
704  }
705 
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 
726  handle->time_series =
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 =
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;
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 
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 
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  */
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 
838  handle->num_distances,
839  handle->frame,
840  false);
841  }
842 
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 
848 
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] *
866  handle->psds[i * handle->num_distances + j] *
868  }
869  }
870 
871  uint16_t index = acc_algorithm_get_distance_idx(handle->lp_psds, handle->num_distances, handle->segment_length, handle->middle_index,
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 
884 {
885  bool status = false;
886 
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 
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  {
968 
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 
990 {
991  printf("Velocity: %" PRIfloat " m/s, distance: %" PRIfloat " m\n", ACC_LOG_FLOAT_TO_INTEGER(result->estimated_v),
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.