Branch data Line data Source code
1 : : #pragma once
2 : :
3 : : #include <cmath>
4 : : #include <cstdint>
5 : :
6 : : /**
7 : : * @brief Unified result type for all ultrasonic sensor operations.
8 : : */
9 : : enum class UsResult
10 : : {
11 : : // Success — distance value is valid
12 : : OK, /**< Reliable reading, high ping ratio, low variance. */
13 : : WEAK_SIGNAL, /**< Valid reading but ping ratio is below the ideal threshold. */
14 : :
15 : : // Logical failures — not enough valid data
16 : : TIMEOUT, /**< Sensor did not respond to trigger within timeout_us. */
17 : : OUT_OF_RANGE, /**< Measured distance is outside [min_distance_cm, max_distance_cm]. */
18 : : HIGH_VARIANCE, /**< Standard deviation of valid pings exceeds max_dev_cm. */
19 : : INSUFFICIENT_SAMPLES, /**< Too few valid pings (ratio below minimum threshold). */
20 : :
21 : : // Hardware failures — require application-level action
22 : : ECHO_STUCK, /**< ECHO pin is stuck HIGH. Application should power-cycle the sensor. */
23 : : HW_FAULT, /**< GPIO/HAL operation failed. */
24 : : };
25 : :
26 : : /**
27 : : * @brief Result of a single ping attempt or a full measurement cycle.
28 : : */
29 : : struct Reading
30 : : {
31 : : UsResult result; /**< Result status of the reading. */
32 : : float cm; /**< Distance in centimeters. Only valid if is_success(result). */
33 : :
34 : : /** @internal */
35 : 14 : bool operator==(const Reading &other) const
36 : : {
37 [ + - ]: 14 : return (result == other.result) &&
38 [ + + + - ]: 14 : ((result != UsResult::OK && result != UsResult::WEAK_SIGNAL) || std::abs(cm - other.cm) < 0.001f);
39 : : }
40 : :
41 : : /** @internal */
42 : : bool operator!=(const Reading &other) const { return !(*this == other); }
43 : : };
44 : :
45 : : /**
46 : : * @brief Helper to check if a result represents a valid distance measurement.
47 : : * @param r UsResult to check.
48 : : * @return true if status is OK or WEAK_SIGNAL.
49 : : */
50 : 98 : inline bool is_success(UsResult r)
51 : : {
52 [ + + ]: 98 : return r == UsResult::OK || r == UsResult::WEAK_SIGNAL;
53 : : }
54 : :
55 : : /**
56 : : * @brief Statistical filter algorithm to apply to the collected ping samples.
57 : : */
58 : : enum class Filter
59 : : {
60 : : MEDIAN, /**< Selects the median value from the sorted series. */
61 : : DOMINANT_CLUSTER, /**< Averages the largest cluster of similar measurements. */
62 : : };
63 : :
64 : : /**
65 : : * @brief Configuration for the ultrasonic sensor hardware and processing.
66 : : */
67 : : struct UsConfig
68 : : {
69 : : uint16_t ping_interval_ms = 70; /**< Delay between consecutive pings (ms). */
70 : : uint16_t ping_duration_us = 20; /**< Trigger pulse duration (us). */
71 : : uint32_t timeout_us = 30000; /**< Max wait for echo pulse (us). */
72 : : Filter filter = Filter::MEDIAN; /**< Statistical filter type. */
73 : : float min_distance_cm = 10.0f; /**< Minimum valid distance (cm). */
74 : : float max_distance_cm = 200.0f; /**< Maximum valid distance (cm). */
75 : : float max_dev_cm = 15.0f; /**< Max standard deviation for OK result (cm). */
76 : : uint16_t warmup_time_ms = 600; /**< Time to wait after init before first ping (ms). */
77 : : };
|