Skip to main content

ev3dev_rs/pupdevices/
gyro_sensor.rs

1use crate::{
2    attribute::AttributeName,
3    error::Ev3Result,
4    parameters::SensorPort,
5    sensor_driver::{SensorDriver, SensorMode::*, SensorType},
6};
7
8/// Stock EV3 Gyro Sensor
9///
10/// # Examples
11/// ``` no_run
12/// use ev3dev_rs::pupdevices::GyroSensor;
13/// use ev3dev_rs::parameters::SensorPort;
14///
15/// let gyro_sensor = GyroSensor::new(SensorPort::In1)?;
16///
17/// println!("Heading: {}", gyro_sensor.heading().await?);
18/// println!("Velocity: {}", gyro_sensor.rate().await?);
19/// println!("Tilt: {}", gyro_sensor.tilt().await?);
20/// println!("Tilt Velocity: {}", gyro_sensor.tilt_velocity().await?);
21///
22/// ```
23pub struct GyroSensor {
24    driver: SensorDriver,
25}
26
27impl GyroSensor {
28    /// Find a `GyroSensor` on the given port.
29    ///
30    /// Will return `SensorNotFound` if no sensor is found
31    /// or `IncorrectSensorType` if the found sensor is not a `GyroSensor`.
32    pub fn new(port: SensorPort) -> Ev3Result<Self> {
33        let driver = SensorDriver::new(SensorType::Gyro, port)?;
34        Ok(Self { driver })
35    }
36
37    /// Get the current heading of the sensor in degrees (-32768 to 32,767).
38    pub async fn heading(&self) -> Ev3Result<i16> {
39        self.driver.set_mode(GyroAngleAndRate).await?;
40        Ok(self.driver.read_attribute(AttributeName::Value0).await?.parse()?)
41    }
42
43    /// Get the current angular velocity of the sensor in degrees per second (-440 to 440).
44    pub async fn angular_velocity(&self) -> Ev3Result<i16> {
45        self.driver.set_mode(GyroAngleAndRate).await?;
46
47        Ok(self.driver.read_attribute(AttributeName::Value1).await?.parse()?)
48
49    }
50
51    /// Get the current heading and angular velocity of the sensor.
52    ///
53    /// This does the same job as calling both `heading()` and `angular_velocity()`,
54    /// but it is more efficient because it reads them simultaneously.
55    ///
56    /// # Examples
57    ///
58    /// ``` no_run
59    /// let (heading, velocity) = sensor.heading_and_velocity()?;
60    /// assert_eq!(heading, sensor.heading().await?);
61    /// assert_eq!(velocity, sensor.angular_velocity().await?);
62    /// ```
63    pub async fn heading_and_velocity(&self) -> Ev3Result<(i16, i16)> {
64        self.driver.set_mode(GyroAngleAndRate).await?;
65
66        let heading = self.driver.read_attribute(AttributeName::Value0).await?.parse()?;
67        let velocity = self.driver.read_attribute(AttributeName::Value1).await?.parse()?;
68
69        Ok((heading, velocity))
70    }
71
72    /// Get the current tilt angle of the sensor in degrees (-32768 to, 32,767).
73    pub async fn tilt(&self) -> Ev3Result<i16> {
74        self.driver.set_mode(GyroTiltAngle).await?;
75
76        Ok(self.driver.read_attribute(AttributeName::Value0).await?.parse()?)
77    }
78
79    /// Get the current tilt velocity of the sensor in degrees per second (-440 to 440).
80    pub async fn tilt_velocity(&self) -> Ev3Result<i16> {
81        self.driver.set_mode(GyroTiltRate).await?;
82
83        Ok(self.driver.read_attribute(AttributeName::Value0).await?.parse()?)
84    }
85}