ref_app_breathing.c
Go to the documentation of this file.
1 // Copyright (c) Acconeer AB, 2023-2024
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 <stdio.h>
10 #include <string.h>
11 
12 #include "acc_alg_basic_utils.h"
13 #include "acc_algorithm.h"
14 #include "acc_detector_presence.h"
15 #include "acc_integration.h"
16 #include "ref_app_breathing.h"
17 
18 #define B_STATIC_LENGTH (3U)
19 #define A_STATIC_LENGTH (2U)
20 #define B_ANGLE_LENGTH (5U)
21 #define A_ANGLE_LENGTH (4U)
22 
24 {
26 
27  float start_m;
29  int32_t start_point;
32  uint16_t end_point;
33  float frame_rate;
34  float lowest_freq;
35  float highest_freq;
42  uint16_t num_points;
43  uint16_t sweeps_per_frame;
45 
48 
49  float presence_sf;
50  float breathing_sf;
51 
56 
57  float complex *mean_sweep;
58  float complex *sparse_iq_buffer;
59  float complex *filt_sparse_iq_buffer;
60  float complex *filt_sparse_iq;
61  float *angle;
62  float *prev_angle;
63  float *lp_filt_ampl;
65  float *angle_buffer;
70  float complex *rfft_output;
72  float *weighted_psd;
73  float freq_delta;
74 
81  bool first;
82  uint16_t init_count;
83  uint16_t count;
85  uint16_t count_limit;
86 };
87 
89 
91 
93 
94 static bool reinit_breathing(ref_app_breathing_handle_t *handle, uint16_t start_point, uint16_t end_point);
95 
97 
99 
101 {
103 
104  if (config != NULL)
105  {
106  config->presence_config = acc_detector_presence_config_create();
107 
108  if (config->presence_config == NULL)
109  {
111  return NULL;
112  }
113 
114  config->time_series_length_s = 20U;
115  config->lowest_breathing_rate = 6U;
116  config->highest_breathing_rate = 60U;
117  config->num_dists_to_analyze = 3U;
118  config->use_presence_processor = true;
119  config->distance_determination_duration_s = 5U;
120 
121  acc_detector_presence_config_t *presence_config = config->presence_config;
122 
123  acc_detector_presence_config_start_set(presence_config, 0.3f);
124  acc_detector_presence_config_end_set(presence_config, 1.5f);
125  acc_detector_presence_config_hwaas_set(presence_config, 32U);
126  acc_detector_presence_config_frame_rate_set(presence_config, 10.0f);
128  acc_detector_presence_config_auto_profile_set(presence_config, false);
131  acc_detector_presence_config_step_length_set(presence_config, 24U);
138  }
139 
140  return config;
141 }
142 
144 {
145  if (config != NULL)
146  {
147  if (config->presence_config != NULL)
148  {
150  }
151 
153  }
154 }
155 
157 {
158  if (!validate_config(config))
159  {
160  return NULL;
161  }
162 
164 
165  if (handle != NULL)
166  {
167  handle->frame_rate = acc_detector_presence_config_frame_rate_get(config->presence_config);
168  handle->sweeps_per_frame = acc_detector_presence_config_sweeps_per_frame_get(config->presence_config);
169  handle->intra_detection_threshold = acc_detector_presence_config_intra_detection_threshold_get(config->presence_config);
170 
171  acc_detector_presence_metadata_t presence_metadata;
172 
173  handle->presence_handle = acc_detector_presence_create(config->presence_config, &presence_metadata);
174 
175  if (handle->presence_handle == NULL)
176  {
178  return NULL;
179  }
180 
181  handle->start_m = presence_metadata.start_m;
182  handle->step_length_m = presence_metadata.step_length_m;
183  handle->num_points = presence_metadata.num_points;
184 
185  handle->lowest_freq = (float)config->lowest_breathing_rate / 60.0f;
186  handle->highest_freq = (float)config->highest_breathing_rate / 60.0f;
187  handle->use_presence_processor = config->use_presence_processor;
188  handle->time_series_length_s = config->time_series_length_s;
189  handle->distance_determination_count = config->distance_determination_duration_s * handle->frame_rate;
190  handle->num_points_to_analyze_half_width = config->num_dists_to_analyze / 2U;
191  handle->num_points_to_analyze = config->use_presence_processor ? handle->num_points_to_analyze_half_width * 2U + 1U : handle->num_points;
192 
193  handle->time_series_length = handle->time_series_length_s * handle->frame_rate;
194  handle->padded_time_series_length_shift = 0U;
195  handle->padded_time_series_length = 1U << handle->padded_time_series_length_shift;
196 
197  while (handle->padded_time_series_length < handle->time_series_length)
198  {
199  handle->padded_time_series_length_shift++;
200  handle->padded_time_series_length = 1U << handle->padded_time_series_length_shift;
201  }
202 
203  handle->rfft_output_length = (handle->padded_time_series_length / 2U) + 1U;
204  handle->distance_determination_counter = 0U;
205  handle->presence_init = false;
206  handle->presence_distance = 0.0f;
207  handle->base_presence_dist = false;
208  handle->base_presence_distance = 0.0f;
209  handle->presence_distance_threshold = acc_algorithm_get_fwhm(acc_detector_presence_config_profile_get(config->presence_config)) * 2.0f;
210  handle->first = true;
211  handle->init_count = 0U;
212  handle->count = 0U;
213  handle->initialized = false;
214  handle->presence_sf = acc_algorithm_exp_smoothing_coefficient(handle->frame_rate, (float)config->distance_determination_duration_s / 4.0f);
215  handle->breathing_sf = acc_algorithm_exp_smoothing_coefficient(handle->frame_rate, handle->time_series_length_s / 2.0f);
216 
218  handle->prev_app_state = REF_APP_BREATHING_APP_STATE_INIT;
219 
220  handle->count_limit = handle->time_series_length / 2U;
221 
222  acc_algorithm_butter_lowpass(handle->lowest_freq, handle->frame_rate, handle->b_static, handle->a_static);
223  acc_algorithm_butter_bandpass(handle->lowest_freq, handle->highest_freq, handle->frame_rate, handle->b_angle, handle->a_angle);
224 
225  handle->mean_sweep = acc_integration_mem_alloc(handle->num_points_to_analyze * sizeof(*handle->mean_sweep));
226  handle->filt_sparse_iq = acc_integration_mem_alloc(handle->num_points_to_analyze * sizeof(*handle->filt_sparse_iq));
227  handle->sparse_iq_buffer = acc_integration_mem_alloc(B_STATIC_LENGTH * handle->num_points_to_analyze * sizeof(*handle->sparse_iq_buffer));
228  handle->filt_sparse_iq_buffer =
229  acc_integration_mem_alloc(A_STATIC_LENGTH * handle->num_points_to_analyze * sizeof(*handle->filt_sparse_iq_buffer));
230  handle->angle = acc_integration_mem_alloc(handle->num_points_to_analyze * sizeof(*handle->angle));
231  handle->prev_angle = acc_integration_mem_alloc(handle->num_points_to_analyze * sizeof(*handle->prev_angle));
232  handle->lp_filt_ampl = acc_integration_mem_alloc(handle->num_points_to_analyze * sizeof(*handle->lp_filt_ampl));
233  handle->unwrapped_angle = acc_integration_mem_alloc(handle->num_points_to_analyze * sizeof(*handle->unwrapped_angle));
234  handle->angle_buffer = acc_integration_mem_alloc(B_ANGLE_LENGTH * handle->num_points_to_analyze * sizeof(*handle->angle_buffer));
235  handle->filt_angle_buffer = acc_integration_mem_alloc(A_ANGLE_LENGTH * handle->num_points_to_analyze * sizeof(*handle->filt_angle_buffer));
236  handle->breathing_motion_buffer =
237  acc_integration_mem_alloc(handle->time_series_length * handle->num_points_to_analyze * sizeof(*handle->breathing_motion_buffer));
238  handle->hamming_window = acc_integration_mem_alloc(handle->time_series_length * sizeof(*handle->hamming_window));
239  handle->windowed_breathing_motion_buffer =
240  acc_integration_mem_alloc(handle->time_series_length * handle->num_points_to_analyze * sizeof(*handle->windowed_breathing_motion_buffer));
241  handle->rfft_output = acc_integration_mem_alloc(handle->rfft_output_length * handle->num_points_to_analyze * sizeof(*handle->rfft_output));
242  handle->weighted_psd = acc_integration_mem_alloc(handle->rfft_output_length * sizeof(*handle->weighted_psd));
243 
244  bool status = handle->mean_sweep != NULL && handle->filt_sparse_iq != NULL && handle->sparse_iq_buffer != NULL &&
245  handle->filt_sparse_iq_buffer != NULL && handle->angle != NULL && handle->prev_angle != NULL && handle->lp_filt_ampl != NULL &&
246  handle->unwrapped_angle != NULL && handle->angle_buffer != NULL && handle->filt_angle_buffer != NULL &&
247  handle->breathing_motion_buffer != NULL && handle->hamming_window != NULL && handle->windowed_breathing_motion_buffer != NULL &&
248  handle->rfft_output != NULL && handle->weighted_psd != NULL;
249 
250  if (status)
251  {
252  handle->freq_delta = acc_algorithm_fftfreq_delta(handle->padded_time_series_length, 1.0f / handle->frame_rate);
253  acc_algorithm_hamming(handle->time_series_length, handle->hamming_window);
254  }
255  else
256  {
258  return NULL;
259  }
260  }
261 
262  return handle;
263 }
264 
266 {
267  if (handle != NULL)
268  {
269  if (handle->presence_handle != NULL)
270  {
272  }
273 
274  if (handle->mean_sweep != NULL)
275  {
276  acc_integration_mem_free(handle->mean_sweep);
277  }
278 
279  if (handle->filt_sparse_iq != NULL)
280  {
281  acc_integration_mem_free(handle->filt_sparse_iq);
282  }
283 
284  if (handle->sparse_iq_buffer != NULL)
285  {
286  acc_integration_mem_free(handle->sparse_iq_buffer);
287  }
288 
289  if (handle->filt_sparse_iq_buffer != NULL)
290  {
291  acc_integration_mem_free(handle->filt_sparse_iq_buffer);
292  }
293 
294  if (handle->angle != NULL)
295  {
297  }
298 
299  if (handle->prev_angle != NULL)
300  {
301  acc_integration_mem_free(handle->prev_angle);
302  }
303 
304  if (handle->lp_filt_ampl != NULL)
305  {
306  acc_integration_mem_free(handle->lp_filt_ampl);
307  }
308 
309  if (handle->unwrapped_angle != NULL)
310  {
311  acc_integration_mem_free(handle->unwrapped_angle);
312  }
313 
314  if (handle->angle_buffer != NULL)
315  {
316  acc_integration_mem_free(handle->angle_buffer);
317  }
318 
319  if (handle->filt_angle_buffer != NULL)
320  {
321  acc_integration_mem_free(handle->filt_angle_buffer);
322  }
323 
324  if (handle->breathing_motion_buffer != NULL)
325  {
326  acc_integration_mem_free(handle->breathing_motion_buffer);
327  }
328 
329  if (handle->hamming_window != NULL)
330  {
331  acc_integration_mem_free(handle->hamming_window);
332  }
333 
334  if (handle->windowed_breathing_motion_buffer != NULL)
335  {
336  acc_integration_mem_free(handle->windowed_breathing_motion_buffer);
337  }
338 
339  if (handle->rfft_output != NULL)
340  {
341  acc_integration_mem_free(handle->rfft_output);
342  }
343 
344  if (handle->weighted_psd != NULL)
345  {
346  acc_integration_mem_free(handle->weighted_psd);
347  }
348 
350  }
351 }
352 
354 {
356 }
357 
362  void *buffer,
363  uint32_t buffer_size)
364 {
366 }
367 
369 {
370  bool status = acc_detector_presence_process(handle->presence_handle, buffer, &result->presence_result);
371 
372  if (status)
373  {
374  if (result->presence_result.processing_result.calibration_needed)
375  {
376  handle->base_presence_dist = false;
377  handle->base_presence_distance = 0.0f;
378  }
379  else
380  {
381  determine_state(handle, &result->presence_result);
382 
383  update_presence_distance(handle, result->presence_result.presence_distance);
384 
385  status = perform_action_based_on_state(handle, result->presence_result.processing_result.frame, result);
386  }
387  }
388 
389  if (status)
390  {
391  result->app_state = handle->app_state;
392 
393  handle->prev_app_state = handle->app_state;
394  }
395 
396  return status;
397 }
398 
400 {
401  float frame_rate = acc_detector_presence_config_frame_rate_get(config->presence_config);
402 
403  bool status = true;
404 
405  if (frame_rate == 0.0f)
406  {
407  printf("Frame rate must be set, i.e. > 0.0\n");
408  status = false;
409  }
410 
411  if (config->lowest_breathing_rate >= config->highest_breathing_rate)
412  {
413  printf("Lowest breathing rate must be lower than highest breathing rate\n");
414  status = false;
415  }
416 
417  if (config->num_dists_to_analyze < 1U)
418  {
419  printf("Number of distances to analyze must be higher than 1");
420  status = false;
421  }
422 
423  return status;
424 }
425 
427 {
428  if (!presence_result->presence_detected)
429  {
431  }
432  else if (handle->intra_detection_threshold < presence_result->intra_presence_score)
433  {
435  }
436  else if (!handle->base_presence_dist && handle->use_presence_processor)
437  {
439  }
440  else if (!handle->use_presence_processor || handle->distance_determination_count <= handle->distance_determination_counter)
441  {
443  }
444  else
445  {
446  // Do nothing
447  }
448 }
449 
451 {
452  if (!handle->presence_init)
453  {
454  handle->presence_init = true;
455  handle->presence_distance = presence_distance;
456  }
457 
458  handle->presence_distance = handle->presence_distance * handle->presence_sf + presence_distance * (1.0f - handle->presence_sf);
459 
460  if (handle->base_presence_dist && handle->presence_distance_threshold < fabsf(handle->base_presence_distance - handle->presence_distance))
461  {
462  handle->base_presence_dist = false;
463  handle->base_presence_distance = 0.0f;
464  }
465 }
466 
467 static bool reinit_breathing(ref_app_breathing_handle_t *handle, uint16_t start_point, uint16_t end_point)
468 {
469  handle->start_point = start_point;
470  handle->end_point = end_point;
471  handle->num_points_to_analyze = end_point - start_point;
472 
473  handle->first = true;
474  handle->init_count = 0U;
475  handle->count = 0U;
476  handle->initialized = false;
477 
478  memset(handle->sparse_iq_buffer, 0, B_STATIC_LENGTH * handle->num_points_to_analyze * sizeof(*handle->sparse_iq_buffer));
479  memset(handle->filt_sparse_iq_buffer, 0, A_STATIC_LENGTH * handle->num_points_to_analyze * sizeof(*handle->filt_sparse_iq_buffer));
480  memset(handle->prev_angle, 0, handle->num_points_to_analyze * sizeof(*handle->prev_angle));
481  memset(handle->lp_filt_ampl, 0, handle->num_points_to_analyze * sizeof(*handle->lp_filt_ampl));
482  memset(handle->unwrapped_angle, 0, handle->num_points_to_analyze * sizeof(*handle->unwrapped_angle));
483  memset(handle->angle_buffer, 0, B_ANGLE_LENGTH * handle->num_points_to_analyze * sizeof(*handle->angle_buffer));
484  memset(handle->filt_angle_buffer, 0, A_ANGLE_LENGTH * handle->num_points_to_analyze * sizeof(*handle->filt_angle_buffer));
485  memset(handle->breathing_motion_buffer, 0, handle->time_series_length * handle->num_points_to_analyze * sizeof(*handle->breathing_motion_buffer));
486 
487  return true;
488 }
489 
491 {
492  bool status = true;
493 
494  result->result_ready = false;
495 
496  switch (handle->app_state)
497  {
499  // Do nothing
500  break;
501  // No presence and intra presence require the same action
504  handle->base_presence_dist = false;
505  handle->base_presence_distance = 0.0f;
506  break;
508  if (handle->app_state != handle->prev_app_state)
509  {
510  handle->distance_determination_counter = 0U;
511  }
512  else
513  {
514  handle->distance_determination_counter++;
515  handle->base_presence_dist = true;
516  handle->base_presence_distance = handle->presence_distance;
517  }
518 
519  break;
521  if (handle->app_state != handle->prev_app_state)
522  {
523  uint16_t start_p;
524  uint16_t end_p;
525 
526  if (handle->use_presence_processor)
527  {
528  uint16_t center_idx = (uint16_t)(((handle->base_presence_distance - handle->start_m) / handle->step_length_m) + 0.5f);
529  start_p = center_idx >= handle->num_points_to_analyze_half_width
530  ? (uint16_t)(center_idx - handle->num_points_to_analyze_half_width)
531  : 0U;
532  end_p = (center_idx + handle->num_points_to_analyze_half_width + 1U) <= handle->num_points
533  ? (center_idx + handle->num_points_to_analyze_half_width + 1U)
534  : handle->num_points;
535  }
536  else
537  {
538  start_p = 0U;
539  end_p = handle->num_points;
540  }
541 
542  reinit_breathing(handle, start_p, end_p);
543  }
544 
545  status = process_breathing(handle, frame, result);
546  break;
547  default:
548  // Should never happen
549  break;
550  }
551 
552  return status;
553 }
554 
556 {
557  acc_algorithm_mean_sweep(frame, handle->num_points, handle->sweeps_per_frame, handle->start_point, handle->end_point, handle->mean_sweep);
558 
561  handle->num_points_to_analyze,
562  handle->mean_sweep,
563  true);
564 
566  handle->filt_sparse_iq_buffer,
568  handle->num_points_to_analyze,
569  handle->b_static,
570  handle->sparse_iq_buffer,
572  handle->num_points_to_analyze,
573  handle->filt_sparse_iq,
574  handle->num_points_to_analyze);
575 
578  handle->num_points_to_analyze,
579  handle->filt_sparse_iq,
580  true);
581 
582  for (uint16_t i = 0U; i < handle->num_points_to_analyze; i++)
583  {
584  handle->mean_sweep[i] = handle->mean_sweep[i] - handle->filt_sparse_iq[i];
585  handle->angle[i] = cargf(handle->mean_sweep[i]);
586  }
587 
588  if (handle->first)
589  {
590  for (uint16_t i = 0U; i < handle->num_points_to_analyze; i++)
591  {
592  handle->prev_angle[i] = handle->angle[i];
593  handle->lp_filt_ampl[i] = cabsf(handle->mean_sweep[i]);
594  }
595 
596  handle->first = false;
597  }
598 
599  for (uint16_t i = 0U; i < handle->num_points_to_analyze; i++)
600  {
601  handle->lp_filt_ampl[i] = handle->breathing_sf * handle->lp_filt_ampl[i] + (1.0f - handle->breathing_sf) * cabsf(handle->mean_sweep[i]);
602  }
603 
604  for (uint16_t i = 0U; i < handle->num_points_to_analyze; i++)
605  {
606  float angle_diff = handle->angle[i] - handle->prev_angle[i];
607  handle->prev_angle[i] = handle->angle[i];
608 
609  if ((float)M_PI < angle_diff)
610  {
611  angle_diff -= 2.0f * (float)M_PI;
612  }
613  else if (angle_diff < -(float)M_PI)
614  {
615  angle_diff += 2.0f * (float)M_PI;
616  }
617 
618  handle->unwrapped_angle[i] += angle_diff;
619  }
620 
621  acc_algorithm_roll_and_push_matrix_f32(handle->angle_buffer, B_ANGLE_LENGTH, handle->num_points_to_analyze, handle->unwrapped_angle, true);
622 
624  handle->filt_angle_buffer,
626  handle->num_points_to_analyze,
627  handle->b_angle,
628  handle->angle_buffer,
630  handle->num_points_to_analyze,
631  handle->angle,
632  handle->num_points_to_analyze);
633 
634  acc_algorithm_roll_and_push_matrix_f32(handle->filt_angle_buffer, A_ANGLE_LENGTH, handle->num_points_to_analyze, handle->angle, true);
635 
636  acc_algorithm_roll_and_push_matrix_f32(handle->breathing_motion_buffer,
637  handle->time_series_length,
638  handle->num_points_to_analyze,
639  handle->angle,
640  false);
641 
642  if (handle->init_count > handle->time_series_length)
643  {
644  handle->initialized = true;
645  }
646  else
647  {
648  handle->init_count++;
649  }
650 
651  if (handle->time_series_length - handle->count_limit <= handle->count)
652  {
653  handle->count = 0;
654 
655  if (handle->initialized)
656  {
657  float lp_filt_ampl_sum = 0U;
658 
659  for (uint16_t r = 0U; r < handle->time_series_length; r++)
660  {
661  for (uint16_t c = 0U; c < handle->num_points_to_analyze; c++)
662  {
663  handle->windowed_breathing_motion_buffer[r * handle->num_points_to_analyze + c] =
664  handle->breathing_motion_buffer[r * handle->num_points_to_analyze + c] * handle->hamming_window[r];
665  lp_filt_ampl_sum += handle->lp_filt_ampl[c];
666  }
667  }
668 
669  acc_algorithm_rfft_matrix(handle->windowed_breathing_motion_buffer,
670  handle->time_series_length,
671  handle->num_points_to_analyze,
672  handle->padded_time_series_length_shift,
673  handle->rfft_output,
674  0U);
675 
676  for (uint16_t r = 0U; r < handle->rfft_output_length; r++)
677  {
678  float sum_psd = 0U;
679 
680  for (uint16_t c = 0U; c < handle->num_points_to_analyze; c++)
681  {
682  sum_psd += cabsf(handle->rfft_output[r * handle->num_points_to_analyze + c]) * handle->lp_filt_ampl[c];
683  }
684 
685  handle->weighted_psd[r] = sum_psd / lp_filt_ampl_sum;
686  }
687 
688  uint16_t peak_loc = acc_algorithm_argmax(handle->weighted_psd, handle->rfft_output_length);
689 
690  if (peak_loc > 0U)
691  {
692  float freq = acc_algorithm_interpolate_peaks_equidistant(handle->weighted_psd, 0.0f, handle->freq_delta, peak_loc);
693  result->result_ready = true;
694  result->breathing_rate = freq * 60.0f;
695  }
696  }
697  }
698  else
699  {
700  handle->count++;
701  }
702 
703  return true;
704 }
ref_app_breathing_handle::init_count
uint16_t init_count
Definition: ref_app_breathing.c:82
REF_APP_BREATHING_APP_STATE_ESTIMATE_BREATHING_RATE
@ REF_APP_BREATHING_APP_STATE_ESTIMATE_BREATHING_RATE
Definition: ref_app_breathing.h:66
acc_integration_mem_calloc
void * acc_integration_mem_calloc(size_t nmemb, size_t size)
Allocate dynamic memory.
Definition: acc_integration_stm32.c:597
acc_algorithm_apply_filter_f32
void acc_algorithm_apply_filter_f32(const float *a, const float *filt_data, uint16_t filt_rows, uint16_t filt_cols, const float *b, const float *data, uint16_t data_rows, uint16_t data_cols, float *output, uint16_t output_length)
Apply filter coefficients to filtered data matrix and data matrix.
Definition: acc_algorithm.c:464
acc_detector_presence_config_sweeps_per_frame_set
void acc_detector_presence_config_sweeps_per_frame_set(acc_detector_presence_config_t *presence_config, uint16_t sweeps_per_frame)
Set the number of sweeps per frame.
acc_algorithm_exp_smoothing_coefficient
float acc_algorithm_exp_smoothing_coefficient(float fs, float tc)
Calculate exponential smoothing coefficient.
Definition: acc_algorithm.c:694
ref_app_breathing_handle::breathing_sf
float breathing_sf
Definition: ref_app_breathing.c:50
cargo_result_t::calibration_needed
bool calibration_needed
Definition: example_cargo.h:112
process_breathing
static bool process_breathing(ref_app_breathing_handle_t *handle, acc_int16_complex_t *frame, ref_app_breathing_result_t *result)
Definition: ref_app_breathing.c:555
ref_app_breathing_handle::step_length_m
float step_length_m
Definition: ref_app_breathing.c:28
REF_APP_BREATHING_APP_STATE_INIT
@ REF_APP_BREATHING_APP_STATE_INIT
Definition: ref_app_breathing.h:62
acc_detector_presence_destroy
void acc_detector_presence_destroy(acc_detector_presence_handle_t *presence_handle)
Destroy a presence detector identified with the provided handle.
ref_app_breathing_handle::presence_distance
float presence_distance
Definition: ref_app_breathing.c:77
acc_detector_presence_config_hwaas_set
void acc_detector_presence_config_hwaas_set(acc_detector_presence_config_t *presence_config, uint16_t hwaas)
Set the hardware accelerated average samples (HWAAS)
reinit_breathing
static bool reinit_breathing(ref_app_breathing_handle_t *handle, uint16_t start_point, uint16_t end_point)
Definition: ref_app_breathing.c:467
ref_app_breathing_handle::angle
float * angle
Definition: ref_app_breathing.c:61
ref_app_breathing_handle::count
uint16_t count
Definition: ref_app_breathing.c:83
ref_app_breathing_handle::angle_buffer
float * angle_buffer
Definition: ref_app_breathing.c:65
buffer
void * buffer
Definition: i2c_example_cargo.c:40
acc_detector_presence_metadata_t::step_length_m
float step_length_m
Definition: acc_detector_presence.h:108
sensor_cal_result
acc_cal_result_t sensor_cal_result
Definition: i2c_example_cargo.c:36
ref_app_breathing_handle::filt_sparse_iq_buffer
float complex * filt_sparse_iq_buffer
Definition: ref_app_breathing.c:59
ref_app_breathing_handle::app_state
ref_app_breathing_app_state_t app_state
Definition: ref_app_breathing.c:46
ref_app_breathing_config_create
ref_app_breathing_config_t * ref_app_breathing_config_create(void)
Create a configuration for the ref app breathing.
Definition: ref_app_breathing.c:100
acc_detector_presence_config_auto_profile_set
void acc_detector_presence_config_auto_profile_set(acc_detector_presence_config_t *presence_config, bool enable)
Enable automatic selection of profile based on start point of measurement.
presence_distance
static float presence_distance
Definition: i2c_presence_detector.c:49
acc_alg_basic_utils.h
acc_int16_complex_t
Data type for interger-based representation of complex numbers.
Definition: acc_definitions_common.h:40
ref_app_breathing_handle::padded_time_series_length
uint16_t padded_time_series_length
Definition: ref_app_breathing.c:41
acc_algorithm_interpolate_peaks_equidistant
float acc_algorithm_interpolate_peaks_equidistant(const float *y, float x_start, float x_delta, uint16_t peak_idx)
Interpolate equidistant peaks.
Definition: acc_algorithm.c:330
acc_algorithm_roll_and_push_matrix_f32
void acc_algorithm_roll_and_push_matrix_f32(float *data, uint16_t rows, uint16_t cols, const float *column, bool pos_shift)
Roll row elements and push a new column.
Definition: acc_algorithm.c:169
acc_cal_result_t
The result from a completed calibration.
Definition: acc_definitions_a121.h:30
acc_detector_presence_config_frame_rate_set
void acc_detector_presence_config_frame_rate_set(acc_detector_presence_config_t *presence_config, float frame_rate)
Set the frame rate.
acc_detector_presence_metadata_t::start_m
float start_m
Definition: acc_detector_presence.h:95
ref_app_breathing.h
update_presence_distance
static void update_presence_distance(ref_app_breathing_handle_t *handle, float presence_distance)
Definition: ref_app_breathing.c:450
ref_app_breathing_result_t
Breathing application results container.
Definition: ref_app_breathing.h:72
ref_app_breathing_handle::windowed_breathing_motion_buffer
float * windowed_breathing_motion_buffer
Definition: ref_app_breathing.c:69
ref_app_breathing_handle::sparse_iq_buffer
float complex * sparse_iq_buffer
Definition: ref_app_breathing.c:58
ref_app_breathing_handle::presence_handle
acc_detector_presence_handle_t * presence_handle
Definition: ref_app_breathing.c:25
ref_app_breathing_prepare
bool ref_app_breathing_prepare(ref_app_breathing_handle_t *handle, ref_app_breathing_config_t *config, acc_sensor_t *sensor, const acc_cal_result_t *sensor_cal_result, void *buffer, uint32_t buffer_size)
Prepare the application to do a measurement.
Definition: ref_app_breathing.c:358
ref_app_breathing_handle::distance_determination_count
uint16_t distance_determination_count
Definition: ref_app_breathing.c:37
acc_integration.h
acc_detector_presence_get_buffer_size
bool acc_detector_presence_get_buffer_size(const acc_detector_presence_handle_t *presence_handle, uint32_t *buffer_size)
Get the buffer size needed for the provided presence detector handle.
ref_app_breathing_handle::end_point
uint16_t end_point
Definition: ref_app_breathing.c:32
ref_app_breathing_handle::rfft_output_length
uint16_t rfft_output_length
Definition: ref_app_breathing.c:71
ref_app_breathing_handle::intra_detection_threshold
float intra_detection_threshold
Definition: ref_app_breathing.c:44
config
cargo_config_t config
Definition: i2c_example_cargo.c:34
acc_detector_presence_result_t::presence_detected
bool presence_detected
Definition: acc_detector_presence.h:51
ref_app_breathing_handle::frame_rate
float frame_rate
Definition: ref_app_breathing.c:33
ref_app_breathing_handle::presence_distance_threshold
float presence_distance_threshold
Definition: ref_app_breathing.c:80
REF_APP_BREATHING_APP_STATE_INTRA_PRESENCE
@ REF_APP_BREATHING_APP_STATE_INTRA_PRESENCE
Definition: ref_app_breathing.h:64
ref_app_breathing_handle::distance_determination_counter
uint16_t distance_determination_counter
Definition: ref_app_breathing.c:75
acc_detector_presence_config_intra_detection_threshold_set
void acc_detector_presence_config_intra_detection_threshold_set(acc_detector_presence_config_t *presence_config, float intra_detection_threshold)
Set the detection threshold for the intra-frame presence detection.
determine_state
static void determine_state(ref_app_breathing_handle_t *handle, acc_detector_presence_result_t *presence_result)
Definition: ref_app_breathing.c:426
acc_integration_mem_alloc
void * acc_integration_mem_alloc(size_t size)
Allocate dynamic memory.
Definition: acc_integration_stm32.c:592
ref_app_breathing_handle::time_series_length
uint16_t time_series_length
Definition: ref_app_breathing.c:39
ref_app_breathing_handle::sweeps_per_frame
uint16_t sweeps_per_frame
Definition: ref_app_breathing.c:43
ref_app_breathing_handle::lp_filt_ampl
float * lp_filt_ampl
Definition: ref_app_breathing.c:63
ref_app_breathing_handle::prev_angle
float * prev_angle
Definition: ref_app_breathing.c:62
ref_app_breathing_handle::hamming_window
float * hamming_window
Definition: ref_app_breathing.c:68
ref_app_breathing_handle::a_angle
float a_angle[(4U)]
Definition: ref_app_breathing.c:55
acc_detector_presence_result_t
Presence detector results container.
Definition: acc_detector_presence.h:46
buffer_size
uint32_t buffer_size
Definition: i2c_example_cargo.c:41
ref_app_breathing_handle::start_point
int32_t start_point
Definition: ref_app_breathing.c:29
acc_detector_presence_config_inter_frame_presence_timeout_set
void acc_detector_presence_config_inter_frame_presence_timeout_set(acc_detector_presence_config_t *presence_config, uint16_t inter_frame_presence_timeout)
Set the inter-frame presence timeout in seconds.
acc_algorithm_butter_lowpass
void acc_algorithm_butter_lowpass(float freq, float fs, float *b, float *a)
Design a 2nd order digital Butterworth lowpass filter.
Definition: acc_algorithm.c:337
ref_app_breathing_handle::breathing_motion_buffer
float * breathing_motion_buffer
Definition: ref_app_breathing.c:67
sensor
acc_sensor_t * sensor
Definition: i2c_example_cargo.c:33
acc_detector_presence_metadata_t::num_points
uint16_t num_points
Definition: acc_detector_presence.h:115
acc_algorithm_argmax
uint16_t acc_algorithm_argmax(const float *data, uint16_t data_length)
Find index of largest element in the array.
Definition: acc_algorithm.c:305
ref_app_breathing_handle::filt_angle_buffer
float * filt_angle_buffer
Definition: ref_app_breathing.c:66
ref_app_breathing_handle::start_m
float start_m
Definition: ref_app_breathing.c:27
ref_app_breathing_handle::time_series_length_s
uint16_t time_series_length_s
Definition: ref_app_breathing.c:38
ref_app_breathing_handle::highest_freq
float highest_freq
Definition: ref_app_breathing.c:35
acc_detector_presence_config_destroy
void acc_detector_presence_config_destroy(acc_detector_presence_config_t *presence_config)
Destroy a presence detector configuration.
acc_detector_presence_metadata_t
Definition: acc_detector_presence.h:88
ref_app_breathing_handle::rfft_output
float complex * rfft_output
Definition: ref_app_breathing.c:70
ref_app_breathing_handle::a_static
float a_static[(2U)]
Definition: ref_app_breathing.c:53
acc_algorithm_rfft_matrix
void acc_algorithm_rfft_matrix(const float *data, uint16_t rows, uint16_t cols, uint16_t length_shift, float complex *output, uint16_t axis)
1D Fast Fourier Transform for real input matrix
Definition: acc_algorithm.c:597
acc_detector_presence_config_end_set
void acc_detector_presence_config_end_set(acc_detector_presence_config_t *presence_config, float end)
Set the end point of measurement interval in meters.
acc_detector_presence_config_intra_output_time_const_set
void acc_detector_presence_config_intra_output_time_const_set(acc_detector_presence_config_t *presence_config, float intra_output_time_const)
Set the time constant for the output in the intra-frame part.
handle
cargo_handle_t * handle
Definition: i2c_example_cargo.c:35
ref_app_breathing_handle::base_presence_distance
float base_presence_distance
Definition: ref_app_breathing.c:79
result
cargo_result_t result
Definition: i2c_example_cargo.c:43
A_ANGLE_LENGTH
#define A_ANGLE_LENGTH
Definition: ref_app_breathing.c:21
printf
#define printf
Definition: printf.h:60
ref_app_breathing_handle::base_presence_dist
bool base_presence_dist
Definition: ref_app_breathing.c:78
ref_app_breathing_handle::initialized
bool initialized
Definition: ref_app_breathing.c:84
acc_detector_presence_result_t::intra_presence_score
float intra_presence_score
Definition: acc_detector_presence.h:55
validate_config
static bool validate_config(ref_app_breathing_config_t *config)
Definition: ref_app_breathing.c:399
REF_APP_BREATHING_APP_STATE_NO_PRESENCE
@ REF_APP_BREATHING_APP_STATE_NO_PRESENCE
Definition: ref_app_breathing.h:63
M_PI
#define M_PI
Definition: acc_alg_basic_utils.h:14
ref_app_breathing_handle::presence_sf
float presence_sf
Definition: ref_app_breathing.c:49
acc_detector_presence_process
bool acc_detector_presence_process(acc_detector_presence_handle_t *presence_handle, void *buffer, acc_detector_presence_result_t *result)
Process the data according to the configuration used in acc_detector_presence_config_create.
acc_detector_presence_config_inter_output_time_const_set
void acc_detector_presence_config_inter_output_time_const_set(acc_detector_presence_config_t *presence_config, float inter_output_time_const)
Set the time constant for the output in the inter-frame part.
ref_app_breathing_get_buffer_size
bool ref_app_breathing_get_buffer_size(ref_app_breathing_handle_t *handle, uint32_t *buffer_size)
Get the buffer size needed for the provided ref app breathing handle.
Definition: ref_app_breathing.c:353
cargo_handle::presence_handle
acc_detector_presence_handle_t * presence_handle
Definition: example_cargo.c:33
B_ANGLE_LENGTH
#define B_ANGLE_LENGTH
Definition: ref_app_breathing.c:20
ref_app_breathing_handle::weighted_psd
float * weighted_psd
Definition: ref_app_breathing.c:72
acc_algorithm_mean_sweep
void acc_algorithm_mean_sweep(const acc_int16_complex_t *frame, uint16_t num_points, uint16_t sweeps_per_frame, uint16_t start_point, uint16_t end_point, float complex *sweep)
Calculate mean sweep of a frame from start_point to end_point.
Definition: acc_algorithm.c:523
ref_app_breathing_handle::num_points
uint16_t num_points
Definition: ref_app_breathing.c:42
ref_app_breathing_handle::unwrapped_angle
float * unwrapped_angle
Definition: ref_app_breathing.c:64
ref_app_breathing_handle::lowest_freq
float lowest_freq
Definition: ref_app_breathing.c:34
acc_detector_presence_prepare
bool acc_detector_presence_prepare(const acc_detector_presence_handle_t *presence_handle, acc_detector_presence_config_t *presence_config, acc_sensor_t *sensor, const acc_cal_result_t *cal_result, void *buffer, uint32_t buffer_size)
Prepare the detector to do a measurement.
ref_app_breathing_handle::mean_sweep
float complex * mean_sweep
Definition: ref_app_breathing.c:57
acc_algorithm_fftfreq_delta
float acc_algorithm_fftfreq_delta(uint16_t n, float d)
Calculate delta between frequency bins in rfft.
Definition: acc_algorithm.c:652
ref_app_breathing_destroy
void ref_app_breathing_destroy(ref_app_breathing_handle_t *handle)
Destroy a handle for the ref app breathing.
Definition: ref_app_breathing.c:265
B_STATIC_LENGTH
#define B_STATIC_LENGTH
Definition: ref_app_breathing.c:18
perform_action_based_on_state
static bool perform_action_based_on_state(ref_app_breathing_handle_t *handle, acc_int16_complex_t *frame, ref_app_breathing_result_t *result)
Definition: ref_app_breathing.c:490
acc_detector_presence_config_t
struct acc_detector_presence_config acc_detector_presence_config_t
Definition: acc_detector_presence.h:41
acc_detector_presence_config_sweeps_per_frame_get
uint16_t acc_detector_presence_config_sweeps_per_frame_get(const acc_detector_presence_config_t *presence_config)
Get the number of sweeps per frame.
REF_APP_BREATHING_APP_STATE_DETERMINE_DISTANCE
@ REF_APP_BREATHING_APP_STATE_DETERMINE_DISTANCE
Definition: ref_app_breathing.h:65
ref_app_breathing_handle::num_points_to_analyze_half_width
uint16_t num_points_to_analyze_half_width
Definition: ref_app_breathing.c:30
ref_app_breathing_handle::prev_app_state
ref_app_breathing_app_state_t prev_app_state
Definition: ref_app_breathing.c:47
acc_algorithm.h
acc_detector_presence_config_frame_rate_get
float acc_detector_presence_config_frame_rate_get(const acc_detector_presence_config_t *presence_config)
Get the frame rate.
acc_detector_presence_config_profile_set
void acc_detector_presence_config_profile_set(acc_detector_presence_config_t *presence_config, acc_config_profile_t profile)
Set a profile.
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_algorithm_get_fwhm
float acc_algorithm_get_fwhm(acc_config_profile_t profile)
Get the envelope Full Width Half Maximum in meters given a profile.
Definition: acc_algorithm.c:745
acc_integration_mem_free
void acc_integration_mem_free(void *ptr)
Free dynamic memory.
Definition: acc_integration_stm32.c:602
ref_app_breathing_config_destroy
void ref_app_breathing_config_destroy(ref_app_breathing_config_t *config)
Destory a configuration for the ref app breathing.
Definition: ref_app_breathing.c:143
ref_app_breathing_create
ref_app_breathing_handle_t * ref_app_breathing_create(ref_app_breathing_config_t *config)
Create a handle for the ref app breathing.
Definition: ref_app_breathing.c:156
ref_app_breathing_handle::num_points_to_analyze
uint16_t num_points_to_analyze
Definition: ref_app_breathing.c:31
acc_detector_presence_create
acc_detector_presence_handle_t * acc_detector_presence_create(acc_detector_presence_config_t *presence_config, acc_detector_presence_metadata_t *metadata)
Create a presence detector with the provided configuration.
ref_app_breathing_handle
Definition: ref_app_breathing.c:23
acc_detector_presence_config_intra_detection_threshold_get
float acc_detector_presence_config_intra_detection_threshold_get(const acc_detector_presence_config_t *presence_config)
Get the detection threshold for the intra-frame presence detection.
acc_detector_presence_config_profile_get
acc_config_profile_t acc_detector_presence_config_profile_get(const acc_detector_presence_config_t *presence_config)
Get the currently set profile.
acc_algorithm_butter_bandpass
void acc_algorithm_butter_bandpass(float min_freq, float max_freq, float fs, float *b, float *a)
Design a 2nd order digital Butterworth bandpass filter.
Definition: acc_algorithm.c:379
acc_detector_presence_handle_t
struct acc_detector_presence_handle acc_detector_presence_handle_t
Definition: acc_detector_presence.h:34
acc_detector_presence_config_create
acc_detector_presence_config_t * acc_detector_presence_config_create(void)
Create a configuration for a presence detector.
ref_app_breathing_config_t
Breathing application config container.
Definition: ref_app_breathing.h:25
ref_app_breathing_handle::use_presence_processor
uint16_t use_presence_processor
Definition: ref_app_breathing.c:36
ref_app_breathing_handle::b_static
float b_static[(3U)]
Definition: ref_app_breathing.c:52
ref_app_breathing_handle::count_limit
uint16_t count_limit
Definition: ref_app_breathing.c:85
ref_app_breathing_process
bool ref_app_breathing_process(ref_app_breathing_handle_t *handle, void *buffer, ref_app_breathing_result_t *result)
Process the data.
Definition: ref_app_breathing.c:368
ref_app_breathing_handle::first
bool first
Definition: ref_app_breathing.c:81
acc_detector_presence_config_start_set
void acc_detector_presence_config_start_set(acc_detector_presence_config_t *presence_config, float start)
Set the start point of measurement interval in meters.
ref_app_breathing_handle::padded_time_series_length_shift
uint16_t padded_time_series_length_shift
Definition: ref_app_breathing.c:40
ref_app_breathing_handle::filt_sparse_iq
float complex * filt_sparse_iq
Definition: ref_app_breathing.c:60
acc_detector_presence.h
acc_algorithm_apply_filter_f32_complex
void acc_algorithm_apply_filter_f32_complex(const float *a, const float complex *filt_data, uint16_t filt_rows, uint16_t filt_cols, const float *b, const float complex *data, uint16_t data_rows, uint16_t data_cols, float complex *output, uint16_t output_length)
Apply filter coefficients to filtered data matrix and data matrix.
Definition: acc_algorithm.c:491
acc_detector_presence_config_auto_step_length_set
void acc_detector_presence_config_auto_step_length_set(acc_detector_presence_config_t *presence_config, bool enable)
Enable automatic selection of step length based on the profile.
ref_app_breathing_handle::presence_init
bool presence_init
Definition: ref_app_breathing.c:76
acc_algorithm_hamming
void acc_algorithm_hamming(uint16_t n, float *window)
Calculate hamming window for a specified number of points.
Definition: acc_algorithm.c:721
acc_sensor_t
struct acc_sensor acc_sensor_t
Definition: acc_sensor.h:31
ref_app_breathing_handle::b_angle
float b_angle[(5U)]
Definition: ref_app_breathing.c:54
acc_detector_presence_config_step_length_set
void acc_detector_presence_config_step_length_set(acc_detector_presence_config_t *presence_config, uint16_t step_length)
Set the step length in points.
ACC_CONFIG_PROFILE_3
@ ACC_CONFIG_PROFILE_3
Definition: acc_definitions_a121.h:54
acc_detector_presence_config_automatic_subsweeps_set
void acc_detector_presence_config_automatic_subsweeps_set(acc_detector_presence_config_t *presence_config, bool automatic_subsweeps)
Set if automatic subsweeps should be used.
ref_app_breathing_app_state_t
ref_app_breathing_app_state_t
State of the application.
Definition: ref_app_breathing.h:60
ref_app_breathing_handle::freq_delta
float freq_delta
Definition: ref_app_breathing.c:73
A_STATIC_LENGTH
#define A_STATIC_LENGTH
Definition: ref_app_breathing.c:19
acc_detector_presence_config_inter_frame_fast_cutoff_set
void acc_detector_presence_config_inter_frame_fast_cutoff_set(acc_detector_presence_config_t *presence_config, float inter_frame_fast_cutoff)
Set the cutoff frequency of the low pass filter for the fast filtered absolute sweep mean.