safe_vex/imu.rs
1//! # Inertial Sensor API
2
3use crate::{bindings, error::{PROSErr, PROSResult}, port::SmartPort};
4
5/// Calibrate the IMU Sensor
6///
7/// Calibration takes approximately `2` seconds, but this function only blocks until the IMU status flag is set properly to E_IMU_STATUS_CALIBRATING, with a minimum blocking time of 5ms
8///
9/// # Errors
10///
11/// - Returns `PROSErr::NoDev` if the port cannot be configured as a Inertial Sensor
12/// - Returns `PROSErr::Again` if the sensor is already currently calibrating, or time out setting the status flag
13pub fn reset(port: SmartPort) -> Result<(), PROSErr> {
14 unsafe {
15 bindings::imu_reset(port as u8)
16 }.check().map(|_| ())
17}
18
19/// Gets the Inertial Sensor's heading relative to the initial direction of it's x-axis
20///
21/// This value is bounded by `0..=360`///
22///
23/// # Errors
24///
25/// - Returns `PROSErr::NoDev` if the port cannot be configured as a Inertial Sensor
26/// - Returns `PROSErr::Again` if the sensor is still calibrating
27pub fn get_heading(port: SmartPort) -> Result<f64, PROSErr> {
28 unsafe {
29 bindings::imu_get_heading(port as u8)
30 }.check()
31}
32
33/// Gets the Inertial Sensor's heading relative to the initial direction of it's x-axis
34///
35/// This value is bounded by `-180..=180`. Clockwise rotations are represented with positive degree values, while counterclockwise rotations are represented with negative ones
36///
37/// # Errors
38///
39/// - Returns `PROSErr::NoDev` if the port cannot be configured as a Inertial Sensor
40/// - Returns `PROSErr::Again` if the sensor is still calibrating
41pub fn get_yaw(port: SmartPort) -> Result<f64, PROSErr> {
42 unsafe {
43 bindings::imu_get_yaw(port as u8)
44 }.check()
45}
46
47/// Gets the Inertial Sensor's heading relative to the initial direction of it's x-axis
48///
49/// This value is bounded by `-180..=180`. Clockwise rotations are represented with positive degree values, while counterclockwise rotations are represented with negative ones
50///
51/// # Errors
52///
53/// - Returns `PROSErr::NoDev` if the port cannot be configured as a Inertial Sensor
54/// - Returns `PROSErr::Again` if the sensor is still calibrating
55pub fn get_pitch(port: SmartPort) -> Result<f64, PROSErr> {
56 unsafe {
57 bindings::imu_get_pitch(port as u8)
58 }.check()
59}
60
61/// Gets the Inertial Sensor's heading relative to the initial direction of it's x-axis
62///
63/// This value is bounded by `-180..=180`. Clockwise rotations are represented with positive degree values, while counterclockwise rotations are represented with negative ones
64///
65/// # Errors
66///
67/// - Returns `PROSErr::NoDev` if the port cannot be configured as a Inertial Sensor
68/// - Returns `PROSErr::Again` if the sensor is still calibrating
69pub fn get_roll(port: SmartPort) -> Result<f64, PROSErr> {
70 unsafe {
71 bindings::imu_get_roll(port as u8)
72 }.check()
73}
74
75/// Resets all 5 values of the Interial Sensor to 0
76///
77/// # Errors
78///
79/// - Returns `PROSErr::NoDev` if the port cannot be configured as a Inertial Sensor
80/// - Returns `PROSErr::Again` if the sensor is still calibrating
81pub fn tare(port: SmartPort) -> Result<(), PROSErr> {
82 unsafe {
83 bindings::imu_tare(port as u8)
84 }.check().map(|_| ())
85}
86
87/// Sets the Inertial Sensor's refresh interval in milliseconds
88///
89/// # Errors
90///
91/// - Returns `PROSErr::NoDev` if the port cannot be configured as a Inertial Sensor
92/// - Returns `PROSErr::Again` if the sensor is still calibrating
93pub fn set_data_rate(port: SmartPort, rate: u32) -> Result<(), PROSErr> {
94 unsafe {
95 bindings::imu_set_data_rate(port as u8, rate)
96 }.check().map(|_| ())
97}
98
99/// Raw Accelerometer values
100pub struct Acceleration {
101 /// accelleration in the x axis
102 pub x: f64,
103 /// accelleration in the y axis
104 pub y: f64,
105 /// accelleration in the z axis
106 pub z: f64,
107}
108
109/// Gets the Inertial Sensor's raw accelerometer values
110///
111/// # Errors
112///
113/// - Returns `PROSErr::NoDev` if the port cannot be configured as a Inertial Sensor
114/// - Returns `PROSErr::Again` if the sensor is still calibrating
115pub fn get_accel(port: SmartPort) -> Result<Acceleration, PROSErr> {
116 unsafe {
117 let accel = bindings::imu_get_accel(port as u8);
118 accel.x.check()?; // check for errors
119
120 Ok(Acceleration {
121 x: accel.x,
122 y: accel.y,
123 z: accel.z,
124 })
125 }
126}