pros_devices/smart/
distance.rs

1//! Distance sensor device.
2//!
3//! Pretty much one to one with the PROS C and CPP API, except Result is used instead of ERRNO values.
4
5use core::ffi::c_double;
6
7use pros_core::{bail_on, error::PortError};
8use pros_sys::PROS_ERR;
9
10use super::{SmartDevice, SmartDeviceType, SmartPort};
11
12/// A physical distance sensor plugged into a port.
13/// Distance sensors can only keep track of one object at a time.
14#[derive(Debug, Eq, PartialEq)]
15pub struct DistanceSensor {
16    port: SmartPort,
17}
18
19impl DistanceSensor {
20    /// Create a new distance sensor from a smart port index.
21    pub const fn new(port: SmartPort) -> Self {
22        Self { port }
23    }
24
25    /// Returns the distance to the object the sensor detects in millimeters.
26    pub fn distance(&self) -> Result<u32, PortError> {
27        Ok(bail_on!(PROS_ERR, unsafe {
28            pros_sys::distance_get(self.port.index())
29        }) as u32)
30    }
31
32    /// Returns the velocity of the object the sensor detects in m/s
33    pub fn velocity(&self) -> Result<f64, PortError> {
34        // All VEX Distance Sensor functions return PROS_ERR on failure even though
35        // some return floating point values (not PROS_ERR_F)
36        Ok(bail_on!(PROS_ERR as c_double, unsafe {
37            pros_sys::distance_get_object_velocity(self.port.index())
38        }))
39    }
40
41    /// Get the current guess at relative "object size".
42    ///
43    /// This is a value that has a range of 0 to 400. A 18" x 30" grey card will return
44    /// a value of approximately 75 in typical room lighting.
45    ///
46    /// This sensor reading is unusual, as it is entirely unitless with the seemingly arbitrary
47    /// range of 0-400 existing due to VEXCode's [`vex::sizeType`] enum having four variants. It's
48    /// unknown what the sensor is *actually* measuring here either, so use this data with a grain
49    /// of salt.
50    ///
51    /// [`vex::sizeType`]: https://api.vexcode.cloud/v5/search/sizeType/sizeType/enum
52    pub fn relative_size(&self) -> Result<u32, PortError> {
53        Ok(bail_on!(PROS_ERR, unsafe {
54            pros_sys::distance_get_object_size(self.port.index())
55        }) as u32)
56    }
57
58    /// Returns the confidence in the distance measurement from 0.0 to 1.0.
59    pub fn distance_confidence(&self) -> Result<f64, PortError> {
60        // 0 -> 63
61        let confidence = bail_on!(PROS_ERR, unsafe {
62            pros_sys::distance_get_confidence(self.port.index())
63        }) as f64;
64
65        Ok(confidence / 63.0)
66    }
67}
68
69impl SmartDevice for DistanceSensor {
70    fn port_index(&self) -> u8 {
71        self.port.index()
72    }
73
74    fn device_type(&self) -> SmartDeviceType {
75        SmartDeviceType::Distance
76    }
77}