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}