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.angular_velocity().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
41 .driver
42 .read_attribute(AttributeName::Value0)
43 .await?
44 .parse()?)
45 }
46
47 /// Get the current angular velocity of the sensor in degrees per second (-440 to 440).
48 pub async fn angular_velocity(&self) -> Ev3Result<i16> {
49 self.driver.set_mode(GyroAngleAndRate).await?;
50
51 Ok(self
52 .driver
53 .read_attribute(AttributeName::Value1)
54 .await?
55 .parse()?)
56 }
57
58 /// Get the current heading and angular velocity of the sensor.
59 ///
60 /// This does the same job as calling both `heading()` and `angular_velocity()`,
61 /// but it is more efficient because it reads them simultaneously.
62 ///
63 /// # Examples
64 ///
65 /// ``` no_run
66 /// let (heading, velocity) = sensor.heading_and_velocity()?;
67 /// assert_eq!(heading, sensor.heading().await?);
68 /// assert_eq!(velocity, sensor.angular_velocity().await?);
69 /// ```
70 pub async fn heading_and_velocity(&self) -> Ev3Result<(i16, i16)> {
71 self.driver.set_mode(GyroAngleAndRate).await?;
72
73 let heading = self
74 .driver
75 .read_attribute(AttributeName::Value0)
76 .await?
77 .parse()?;
78 let velocity = self
79 .driver
80 .read_attribute(AttributeName::Value1)
81 .await?
82 .parse()?;
83
84 Ok((heading, velocity))
85 }
86
87 /// Get the current tilt angle of the sensor in degrees (-32768 to, 32,767).
88 pub async fn tilt(&self) -> Ev3Result<i16> {
89 self.driver.set_mode(GyroTiltAngle).await?;
90
91 Ok(self
92 .driver
93 .read_attribute(AttributeName::Value0)
94 .await?
95 .parse()?)
96 }
97
98 /// Get the current tilt velocity of the sensor in degrees per second (-440 to 440).
99 pub async fn tilt_velocity(&self) -> Ev3Result<i16> {
100 self.driver.set_mode(GyroTiltRate).await?;
101
102 Ok(self
103 .driver
104 .read_attribute(AttributeName::Value0)
105 .await?
106 .parse()?)
107 }
108}