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