ev3dev_lang_rust/sensors/
compass_sensor.rs

1//! HiTechnic EV3 / NXT Compass Sensor. (<https://www.generationrobots.com/en/401186-hitechnic-compass-sensor-for-lego-mindstorms-nxt-and-ev3.html>)
2
3use super::{Sensor, SensorPort};
4use crate::{Attribute, Device, Driver, Ev3Error, Ev3Result};
5
6/// HiTechnic EV3 / NXT Compass Sensor.
7#[derive(Debug, Clone, Device, Sensor)]
8pub struct CompassSensor {
9    driver: Driver,
10    origin: i32, // zero point
11}
12
13impl CompassSensor {
14    fn new(driver: Driver) -> Self {
15        Self { driver, origin: 0 }
16    }
17
18    findable!(
19        "lego-sensor",
20        ["ht-nxt-compass"],
21        SensorPort,
22        "Compass",
23        "in"
24    );
25
26    /// Command for starting the calibration
27    pub const COMMAND_START_CALIBRATION: &'static str = "BEGIN-CAL";
28
29    /// Command for stopping the calibration
30    pub const COMMAND_STOP_CALIBRATION: &'static str = "END-CAL";
31
32    // Sensor only have one mode (COMPASS), so setting the mode is not necessary
33
34    /// gets rotation (in degree) from the compass sensor
35    pub fn get_rotation(&self) -> Ev3Result<i32> {
36        self.get_value0()
37    }
38
39    /// sets the origin
40    pub fn set_zero(&mut self) -> Ev3Result<()> {
41        self.origin = self.get_rotation()?;
42        Ok(())
43    }
44
45    /// calculates the rotation to the origin / the zero point
46    pub fn get_relative_rotation(&self) -> Ev3Result<i32> {
47        let pos = self.get_rotation()?;
48        let mut rel_rot = pos - self.origin;
49        if rel_rot < 0 {
50            rel_rot += 360;
51        }
52        Ok(rel_rot)
53    }
54
55    /// calibration:
56    /// start the calibration by start_calibration()
57    /// turn the robot 360 degrees
58    /// end the calibration by stop_calibration()
59    /// attention: if calibration has not finished, the get_rotation method always returns -258
60    ///
61    /// starts the calibration
62    pub fn start_calibration(&self) -> Ev3Result<()> {
63        self.set_command(Self::COMMAND_START_CALIBRATION)
64    }
65
66    /// stops the calibration
67    pub fn stop_calibration(&self) -> Ev3Result<()> {
68        self.set_command(Self::COMMAND_STOP_CALIBRATION)
69    }
70}