Skip to main content

rust_gnc/units/
spatial.rs

1//! # Spatial Units and Kinematics
2//! 
3//! This module defines the 3D spatial primitives used for navigation.
4//! 
5//! ### Coordinate Convention
6//! We use the **NED (North-East-Down)** convention:
7//! - **X-axis**: Points North.
8//! - **Y-axis**: Points East.
9//! - **Z-axis**: Points Down (aligned with gravity).
10
11use core::ops::{Add, Mul};
12use crate::units::angular::Radians;
13
14/// Represents linear velocity in 3D space.
15/// Units are typically Meters per Second (m/s).
16#[derive(Debug, Clone, Copy, PartialEq, Default)]
17pub struct Velocity {
18    /// Velocity component along the North axis.
19    pub x: f32,
20    /// Velocity component along the East axis.
21    pub y: f32,
22    /// Velocity component along the Down axis (positive is descending).
23    pub z: f32,
24}
25
26impl Mul<f32> for Velocity {
27    type Output = Self;
28
29    /// Scales velocity by a scalar value. 
30    /// Commonly used to calculate displacement (Velocity * dt).
31    fn mul(self, rhs: f32) -> Self::Output {
32        Self {
33            x: self.x * rhs,
34            y: self.y * rhs,
35            z: self.z * rhs,
36        }
37    }
38}
39
40/// Represents a 3D position in the NED frame.
41/// Units are typically Meters (m).
42#[derive(Debug, Clone, Copy, PartialEq, Default)]
43pub struct Position {
44    /// Distance North of the origin.
45    pub x: f32,
46    /// Distance East of the origin.
47    pub y: f32,
48    /// Altitude relative to origin (positive is below the origin/sea level).
49    pub z: f32,
50}
51
52impl Add<Velocity> for Position {
53    type Output = Self;
54
55    /// Adds a velocity vector (scaled by time) to a position.
56    /// Implements the basic kinematic equation: P_new = P_old + V.
57    fn add(self, rhs: Velocity) -> Self::Output {
58        Self {
59            x: self.x + rhs.x,
60            y: self.y + rhs.y,
61            z: self.z + rhs.z,
62        }
63    }
64}
65
66impl Position {
67    /// Performs a first-order Euler integration to predict the next position.
68    /// 
69    /// ### Arguments
70    /// * `velocity` - The current velocity vector.
71    /// * `dt` - The time delta (seconds).
72    pub fn predict_next(&self, velocity: Velocity, dt: f32) -> Self {
73        *self +velocity * dt
74    }
75}
76
77/// Represents the aircraft orientation using Euler angles.
78/// 
79/// Follows the standard Tait-Bryan convention (Z-Y-X).
80#[derive(Debug, Clone, Copy, PartialEq)]
81pub struct Attitude {
82    /// Rotation about the X-axis (longitudinal).
83    pub roll: Radians,
84    /// Rotation about the Y-axis (lateral).
85    pub pitch: Radians,
86    /// Rotation about the Z-axis (vertical/heading).
87    pub yaw: Radians,
88}
89
90impl Default for Attitude {
91    /// Returns a level attitude (zeroed on all axes).
92    fn default() -> Self {
93        Self {
94            roll: Radians(0.0),
95            pitch: Radians(0.0),
96            yaw: Radians(0.0),
97        }
98    }
99}