marg_orientation/
accelerometer_reading.rs

1use crate::impl_standard_traits;
2use core::fmt::{Debug, Formatter};
3use core::ops::Mul;
4use uniform_array_derive::UniformArray;
5
6#[derive(UniformArray)]
7#[cfg_attr(test, ensure_uniform_type::ensure_uniform_type)]
8#[repr(C)]
9pub struct AccelerometerReading<T> {
10    /// The acceleration along the x-axis, in meters per second.
11    pub x: T,
12    /// The acceleration along the y-axis, in meters per second.
13    pub y: T,
14    /// The acceleration along the z-axis, in meters per second.
15    pub z: T,
16}
17
18impl<T> AccelerometerReading<T> {
19    /// Initializes a new [`AccelerometerReading`] instance.
20    #[inline(always)]
21    pub const fn new(x: T, y: T, z: T) -> Self {
22        Self { x, y, z }
23    }
24
25    /// Constructs a new [`AccelerometerReading`] instance from a reading in a given coordinate frame.
26    #[cfg(feature = "coordinate-frame")]
27    #[cfg_attr(docsrs, doc(cfg(feature = "coordinate-frame")))]
28    pub fn north_east_down<C>(coordinate: C) -> Self
29    where
30        C: Into<coordinate_frame::NorthEastDown<T>>,
31        T: Clone,
32    {
33        let coordinate = coordinate.into();
34        Self {
35            x: coordinate.x(),
36            y: coordinate.y(),
37            z: coordinate.z(),
38        }
39    }
40}
41
42impl<T> Default for AccelerometerReading<T>
43where
44    T: Default,
45{
46    #[inline]
47    fn default() -> Self {
48        Self::new(Default::default(), Default::default(), Default::default())
49    }
50}
51
52impl<T> Clone for AccelerometerReading<T>
53where
54    T: Clone,
55{
56    fn clone(&self) -> Self {
57        Self {
58            x: self.x.clone(),
59            y: self.y.clone(),
60            z: self.z.clone(),
61        }
62    }
63}
64
65impl<T> Debug for AccelerometerReading<T>
66where
67    T: Debug,
68{
69    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
70        f.debug_tuple("AccelerometerReading")
71            .field(&self.x)
72            .field(&self.y)
73            .field(&self.z)
74            .finish()
75    }
76}
77
78impl<T> Mul<T> for AccelerometerReading<T>
79where
80    T: Mul<T, Output = T> + Clone,
81{
82    type Output = AccelerometerReading<T>;
83
84    fn mul(self, rhs: T) -> Self::Output {
85        Self {
86            x: self.x * rhs.clone(),
87            y: self.y * rhs.clone(),
88            z: self.z * rhs.clone(),
89        }
90    }
91}
92
93#[cfg(feature = "coordinate-frame")]
94#[cfg_attr(docsrs, doc(cfg(feature = "coordinate-frame")))]
95impl<T, C> From<C> for AccelerometerReading<T>
96where
97    C: coordinate_frame::CoordinateFrame<Type = T>,
98    T: Copy + coordinate_frame::SaturatingNeg<Output = T>,
99{
100    fn from(value: C) -> Self {
101        Self::north_east_down(value.to_ned())
102    }
103}
104
105impl_standard_traits!(AccelerometerReading, T);
106
107#[cfg(test)]
108mod test {
109    use super::*;
110
111    #[test]
112    fn test_len() {
113        let reading = AccelerometerReading::<f32>::default();
114        assert_eq!(reading.len(), 3);
115    }
116
117    #[test]
118    fn test_index() {
119        let reading = AccelerometerReading::<f32> {
120            x: 1.0,
121            y: 2.0,
122            z: 3.0,
123        };
124
125        assert_eq!(reading[0], 1.0);
126        assert_eq!(reading[1], 2.0);
127        assert_eq!(reading[2], 3.0);
128    }
129}