Skip to main content

fusion_nav/
frames.rs

1//! Reference frames as compile-time markers.
2//!
3//! A frame is a zero-sized type parameter on a quantity, so that a
4//! [`Position<Enu>`](crate::Position) cannot be passed where a `Position<Ned>` is expected.
5//! Frames carry no data and cost nothing at runtime.
6
7mod sealed {
8    pub trait Sealed {}
9}
10
11/// A reference frame a quantity can be expressed in.
12///
13/// Sealed: frames are a closed set, because the filter's Jacobians depend on the
14/// conventions of [`Ned`] and [`Body`] specifically.
15pub trait Frame: sealed::Sealed + Copy + core::fmt::Debug {
16    /// Short label used in `Debug` output, such as `"NED"`.
17    const NAME: &'static str;
18}
19
20macro_rules! frame {
21    ($(#[$meta:meta])* $name:ident, $label:literal) => {
22        $(#[$meta])*
23        #[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
24        pub struct $name;
25
26        impl sealed::Sealed for $name {}
27
28        impl Frame for $name {
29            const NAME: &'static str = $label;
30        }
31    };
32}
33
34frame!(
35    /// Local tangent navigation frame: North, East, Down.
36    ///
37    /// Down-positive, so gravity has a positive `z` component. This is the frame the
38    /// filter navigates in.
39    Ned,
40    "NED"
41);
42
43frame!(
44    /// Local tangent frame: East, North, Up.
45    ///
46    /// Not used by the filter. It exists so that an ENU quantity is a compile error at the
47    /// boundary rather than a sign error in flight.
48    Enu,
49    "ENU"
50);
51
52frame!(
53    /// Vehicle body frame: x forward, y right, z down.
54    ///
55    /// IMU and magnetometer measurements and the IMU biases live here.
56    Body,
57    "body"
58);