sidereon_core/inertial/
mod.rs1pub mod config;
8pub mod frames;
9pub mod imu;
10pub mod mechanization;
11pub mod state;
12
13pub use config::{
14 gauss_markov_bias_decay, gauss_markov_bias_variance_increment, ConingCorrection, ImuGrade,
15 ImuSpec, MechanizationConfig,
16};
17pub use frames::{
18 gravity_ecef_mps2, normal_gravity_mps2, WGS84_NORMAL_GRAVITY_EQUATOR_MPS2,
19 WGS84_NORMAL_GRAVITY_POLE_MPS2, WGS84_SOMIGLIANA_K,
20};
21pub use imu::{
22 CorrectedImuIncrement, ImuBias, ImuCalibration, ImuErrorModel, ImuSample, ImuSampleKind,
23};
24pub use mechanization::{mechanize_ecef, rodrigues_delta_dcm, StrapdownMechanizer};
25pub use state::{
26 attitude_yaw_pitch_roll_rad, dcm_to_quaternion, quaternion_to_dcm, reorthonormalize_dcm,
27 AttitudeQuaternion, NavState,
28};
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
32pub enum InertialError {
33 #[error("invalid inertial input {field}: {reason}")]
35 InvalidInput {
36 field: &'static str,
38 reason: &'static str,
40 },
41 #[error("IMU sample time must be strictly increasing")]
43 NonMonotonicSample,
44 #[error("IMU calibration matrix is singular")]
46 SingularCalibration,
47 #[error("attitude matrix is degenerate")]
49 DegenerateAttitude,
50}
51
52pub(crate) const fn invalid_input(field: &'static str, reason: &'static str) -> InertialError {
53 InertialError::InvalidInput { field, reason }
54}
55
56pub(crate) fn validate_finite(value: f64, field: &'static str) -> Result<(), InertialError> {
57 if value.is_finite() {
58 Ok(())
59 } else {
60 Err(invalid_input(field, "must be finite"))
61 }
62}
63
64pub(crate) fn validate_nonnegative(value: f64, field: &'static str) -> Result<(), InertialError> {
65 validate_finite(value, field)?;
66 if value >= 0.0 {
67 Ok(())
68 } else {
69 Err(invalid_input(field, "must be non-negative"))
70 }
71}
72
73pub(crate) fn validate_positive(value: f64, field: &'static str) -> Result<(), InertialError> {
74 validate_finite(value, field)?;
75 if value > 0.0 {
76 Ok(())
77 } else {
78 Err(invalid_input(field, "must be positive"))
79 }
80}
81
82pub(crate) fn validate_vec3(value: [f64; 3], field: &'static str) -> Result<(), InertialError> {
83 for component in value {
84 validate_finite(component, field)?;
85 }
86 Ok(())
87}
88
89pub(crate) fn validate_mat3(
90 value: &[[f64; 3]; 3],
91 field: &'static str,
92) -> Result<(), InertialError> {
93 for row in value {
94 for component in row {
95 validate_finite(*component, field)?;
96 }
97 }
98 Ok(())
99}