25 #define CAL_ITERATIONS (3U)
26 #define MAX_AMPLITUDE (46341.0f) // sqrt((2^15)^2 + (2^15)^2)
154 static void car_signature(
const float *magnitudes,
const float *distances, uint16_t length,
signature_t *signature);
203 parking_config->
preset = preset;
205 switch (parking_config->
preset)
258 handle->parking_config = *parking_config;
259 handle->sensor_id = sensor_id;
262 if (
handle->sensor_config == NULL)
291 if (
handle->sensor != NULL)
296 if (
handle->signature_history_sorted != NULL)
301 if (
handle->signature_history != NULL)
306 if (
handle->magnitudes != NULL)
311 if (
handle->norm_distances != NULL)
316 if (
handle->distances != NULL)
321 if (
handle->obstruction_magnitudes != NULL)
326 if (
handle->obstruction_distances != NULL)
331 if (
handle->noise_magnitudes != NULL)
336 if (
handle->buffer != NULL)
346 if (
handle->sensor_config != NULL)
358 bool cal_complete =
false;
359 const uint16_t calibration_retries = 1U;
360 const uint32_t calibration_step_timeout_ms = 500U;
363 for (uint16_t i = 0; !status && (i <= calibration_retries); i++)
373 if (status && !cal_complete)
377 }
while (status && !cal_complete);
394 uint16_t noise_subsweep_index =
handle->parking_config.car_config.subsweep_index;
402 printf(
"acc_sensor_prepare() failed\n");
407 float noise_level_sum = 0.0f;
409 uint16_t noise_data_offset =
handle->proc_meta.subsweep_data_offset[noise_subsweep_index];
410 uint16_t noise_data_length =
handle->proc_meta.subsweep_data_length[noise_subsweep_index];
420 noise_cal_temps[i] =
handle->proc_result.temperature;
422 noise_level_sum +=
noise_process(&
handle->proc_result.frame[noise_data_offset],
handle->noise_magnitudes, noise_data_length);
431 if (
handle->parking_config.frame_rate_app_driven)
450 uint16_t obs_cal_subsweep_index =
handle->parking_config.obstruction_config.subsweep_index;
451 uint16_t obs_cal_data_offset =
handle->proc_meta.subsweep_data_offset[obs_cal_subsweep_index];
452 uint16_t obs_cal_data_length =
handle->proc_meta.subsweep_data_length[obs_cal_subsweep_index];
459 printf(
"acc_sensor_prepare() failed\n");
464 float noise_level_sum = 0.0f;
476 noise_level_sum += noise_levels[i];
487 printf(
"acc_sensor_prepare() failed\n");
492 float energy_sum = 0.0f;
493 float weighted_distance_sum = 0.0f;
507 handle->obstruction_magnitudes,
508 handle->obstruction_distances,
513 energy_sum += signature.
energy;
520 handle->obstruction_lp_signature =
handle->obstruction_center;
523 if (
handle->parking_config.frame_rate_app_driven)
541 printf(
"acc_sensor_prepare failed\n");
547 printf(
"enter_hibernate failed\n");
560 printf(
"exit_hibernate failed\n");
567 printf(
"acc_sensor_measure failed\n");
573 printf(
"Sensor interrupt timeout\n");
579 printf(
"acc_sensor_read failed\n");
587 printf(
"enter_hibernate failed\n");
601 *data_reliable =
true;
603 if (
handle->proc_result.data_saturated)
605 *data_reliable =
false;
607 printf(
"Data saturated. Try to reduce the sensor gain.\n");
610 if (
handle->proc_result.frame_delayed)
612 printf(
"Frame delayed. Could not read data fast enough.\n");
613 printf(
"Try lowering the frame rate or call 'acc_sensor_read' more frequently.\n");
616 if (
handle->proc_result.calibration_needed)
618 printf(
"The current calibration is not valid for the current temperature.\n");
619 printf(
"Re-calibrating sensor...\n");
623 printf(
"exit_hibernate failed\n");
631 printf(
"ref_app_parking_sensor_calibration() failed\n");
641 printf(
"acc_sensor_prepare() failed\n");
650 printf(
"enter_hibernate failed\n");
655 *data_reliable =
false;
657 printf(
"The sensor was successfully re-calibrated.\n");
671 float signal_adjust_factor;
672 float deviation_adjust_factor;
675 handle->proc_result.temperature,
677 &signal_adjust_factor,
678 &deviation_adjust_factor);
680 float noise_level_adjusted =
handle->obstruction_noise_level * deviation_adjust_factor;
687 for (uint16_t i = 0; i < num_points; i++)
689 subsweep[i].
real = ((float)subsweep[i].real / signal_adjust_factor) + 0.5f;
690 subsweep[i].
imag = ((float)subsweep[i].imag / signal_adjust_factor) + 0.5f;
698 float lp_const =
handle->obstruction_lp_const;
700 lp_signature->
energy = lp_signature->
energy * lp_const + (1.0f - lp_const) * curr_signature.
energy;
704 float energy_diff = fabsf(lp_signature->
energy -
handle->obstruction_center.energy);
705 float weighted_distance_diff = fabsf(lp_signature->
weighted_distance -
handle->obstruction_center.weighted_distance);
707 *obstruction_detected =
708 (energy_diff >
handle->obstruction_energy_threshold) || (weighted_distance_diff >
handle->obstruction_weighted_distance_threshold);
722 float signal_adjust_factor;
723 float deviation_adjust_factor;
726 handle->proc_result.temperature,
728 &signal_adjust_factor,
729 &deviation_adjust_factor);
731 float noise_level_adjusted =
handle->noise_level * deviation_adjust_factor;
733 for (uint16_t i = 0; i < num_points; i++)
735 handle->magnitudes[i] = sqrtf((
float)subsweep[i].real * (
float)subsweep[i].real + (
float)subsweep[i].imag * (
float)subsweep[i].imag);
738 handle->magnitudes[i] /= noise_level_adjusted;
741 handle->magnitudes[i] = (
handle->magnitudes[i] - 1.0f < 0.0f) ? 0.0f :
handle->magnitudes[i] - 1.0f;
749 handle->signature_history[i - 1] =
handle->signature_history[i];
757 *car_detected = obj_present && same_obj;
790 uint16_t step_length = 0U;
794 if (step_length_ideal >= 24)
796 step_length = (step_length_ideal / 24U) * 24U;
800 step_length = step_length_ideal;
801 while (24U % step_length != 0U)
838 printf(
"\nParking config:\n");
840 char *preset_string = NULL;
842 switch (parking_config->
preset)
845 preset_string =
"None";
848 preset_string =
"Ground";
851 preset_string =
"Pole";
858 printf(
"preset: %s\n", preset_string);
862 printf(
"\nCar config:\n");
872 printf(
"\nObstruction config:\n");
879 printf(
"\nSensor config:\n");
900 if (
handle->buffer == NULL)
909 if (
handle->noise_magnitudes == NULL)
915 if (
handle->obstruction_magnitudes == NULL)
921 if (
handle->obstruction_distances == NULL)
927 if (
handle->distances == NULL)
933 if (
handle->norm_distances == NULL)
939 if (
handle->magnitudes == NULL)
947 if (
handle->signature_history == NULL)
953 if (
handle->signature_history_sorted == NULL)
962 if (
handle->sensor == NULL)
988 for (uint16_t i = 0; i < num_points; i++)
990 handle->obstruction_distances[i] = (float)(start_point + i * step_length) * base_step_length;
993 float actual_distance_range =
handle->obstruction_distances[num_points - 1U] -
handle->obstruction_distances[0];
998 handle->obstruction_weighted_distance_threshold = actual_distance_range * obstruction_config->
threshold;
1007 for (uint16_t i = 0; i < num_points; i++)
1009 handle->distances[i] = (float)(start_point + i * step_length) * base_step_length;
1019 return (uint32_t)((1.0f / update_rate_hz) * 1000.0f) + 1000U;
1024 float noise_mean = 0.0f;
1026 for (uint16_t i = 0; i < noise_data_length; i++)
1028 noise_magnitudes[i] = sqrtf((
float)noise_data[i].real * (
float)noise_data[i].real + (
float)noise_data[i].imag * (
float)noise_data[i].imag);
1029 noise_mean += noise_magnitudes[i];
1032 noise_mean /= noise_data_length;
1034 float pow_sum = 0.0f;
1036 for (uint16_t i = 0; i < noise_data_length; i++)
1038 pow_sum += (noise_magnitudes[i] - noise_mean) * (noise_magnitudes[i] - noise_mean);
1041 float noise_std = sqrtf(pow_sum / noise_data_length);
1043 float noise_level = noise_mean + 2.0f * noise_std;
1050 float noise_mean = 0.0f;
1052 for (uint16_t i = 0; i < obs_noise_data_length; i++)
1055 sqrtf((
float)obs_noise_data[i].real * (
float)obs_noise_data[i].real + (
float)obs_noise_data[i].imag * (
float)obs_noise_data[i].imag);
1058 noise_mean /= obs_noise_data_length;
1070 float energy_sum = 0.0f;
1072 for (uint16_t j = 0; j < length; j++)
1074 magnitudes[j] = sqrtf((
float)subsweep[j].real * (
float)subsweep[j].real + (
float)subsweep[j].imag * (
float)subsweep[j].imag);
1075 magnitudes[j] -= noise_level;
1076 energy_sum += magnitudes[j];
1079 signature->
energy = (energy_sum / length);
1091 uint16_t queue_length_n =
handle->parking_config.car_config.queue_length_n;
1092 float amplitude_threshold =
handle->parking_config.car_config.amplitude_threshold;
1093 float signature_similarity_threshold =
handle->parking_config.car_config.signature_similarity_threshold;
1095 uint16_t trig_count = 0;
1097 for (uint16_t i = 0; i < queue_length_n; i++)
1099 if (
handle->signature_history[i].energy > amplitude_threshold)
1105 return (
float)trig_count > (queue_length_n * signature_similarity_threshold);
1110 uint16_t queue_length_n =
handle->parking_config.car_config.queue_length_n;
1111 float amplitude_threshold =
handle->parking_config.car_config.amplitude_threshold;
1112 float weighted_distance_threshold_m =
handle->parking_config.car_config.weighted_distance_threshold_m;
1113 float signature_similarity_threshold =
handle->parking_config.car_config.signature_similarity_threshold;
1115 for (uint16_t i = 0; i < queue_length_n; i++)
1117 handle->signature_history_sorted[i] =
handle->signature_history[i];
1122 uint16_t active_cluster_count = 0;
1123 float active_cluster_ref_dist = 0.0f;
1124 uint16_t largest_cluster_count = 0;
1126 for (uint16_t i = 0; i < queue_length_n; i++)
1128 if (
handle->signature_history_sorted[i].energy > amplitude_threshold)
1131 if (active_cluster_count == 0)
1133 active_cluster_count++;
1134 active_cluster_ref_dist =
handle->signature_history_sorted[i].weighted_distance;
1137 else if (
handle->signature_history_sorted[i].weighted_distance - active_cluster_ref_dist > weighted_distance_threshold_m)
1139 if (active_cluster_count > largest_cluster_count)
1141 largest_cluster_count = active_cluster_count;
1144 active_cluster_count = 0;
1145 active_cluster_ref_dist = 0.0f;
1150 active_cluster_count++;
1156 if (active_cluster_count != 0)
1158 if (active_cluster_count > largest_cluster_count)
1160 largest_cluster_count = active_cluster_count;
1164 return (
float)largest_cluster_count / (float)queue_length_n > signature_similarity_threshold;
1192 printf(
"acc_sensor_hibernate_on failed\n");
1208 printf(
"acc_sensor_hibernate_off failed\n");