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}