1use anise::errors::{AlmanacError, PhysicsError};
20pub use anise::prelude::*;
21
22pub use crate::cosmic::{DragData, GuidanceMode, Mass, SRPData, Spacecraft};
23use crate::dynamics::DynamicsError;
24pub use crate::errors::NyxError;
25use crate::errors::StateError;
26use crate::linalg::allocator::Allocator;
27use crate::linalg::{DefaultAllocator, DimName, OMatrix, OVector};
28use crate::md::StateParameter;
29use snafu::Snafu;
30use std::fmt;
31
32pub trait TimeTagged {
34 fn epoch(&self) -> Epoch;
36 fn set_epoch(&mut self, epoch: Epoch);
38}
39
40pub trait State: Default + Copy + PartialEq + fmt::Display + fmt::LowerExp + Send + Sync
43where
44 Self: Sized,
45 DefaultAllocator:
46 Allocator<Self::Size> + Allocator<Self::Size, Self::Size> + Allocator<Self::VecLength>,
47{
48 type Size: DimName;
50 type VecLength: DimName;
51
52 fn zeros() -> Self {
55 unimplemented!()
56 }
57
58 fn to_vector(&self) -> OVector<f64, Self::VecLength>;
60
61 fn to_state_vector(&self) -> OVector<f64, Self::Size> {
63 OVector::<f64, Self::Size>::from_iterator(
64 self.to_vector().iter().copied().take(Self::Size::USIZE),
65 )
66 }
67
68 fn stm(&self) -> Result<OMatrix<f64, Self::Size, Self::Size>, DynamicsError> {
71 Err(DynamicsError::StateTransitionMatrixUnset)
72 }
73
74 fn with_stm(self) -> Self;
76
77 fn reset_stm(&mut self) {
79 unimplemented!()
80 }
81
82 fn unset_stm(&mut self);
84
85 fn set(&mut self, epoch: Epoch, vector: &OVector<f64, Self::VecLength>);
87
88 fn set_with_delta_seconds(
91 mut self,
92 delta_t_s: f64,
93 vector: &OVector<f64, Self::VecLength>,
94 ) -> Self
95 where
96 DefaultAllocator: Allocator<Self::VecLength>,
97 {
98 self.set(self.epoch() + delta_t_s, vector);
99 self
100 }
101
102 fn epoch(&self) -> Epoch;
104
105 fn set_epoch(&mut self, epoch: Epoch);
107
108 fn add(self, _other: OVector<f64, Self::Size>) -> Self {
110 unimplemented!()
111 }
112
113 fn value(&self, param: StateParameter) -> Result<f64, StateError> {
115 Err(StateError::Unavailable { param })
116 }
117
118 fn set_value(&mut self, param: StateParameter, _val: f64) -> Result<(), StateError> {
121 Err(StateError::Unavailable { param })
122 }
123
124 fn orbit(&self) -> Orbit;
126
127 fn set_orbit(&mut self, _orbit: Orbit) {}
129}
130
131pub fn assert_orbit_eq_or_abs(left: &Orbit, right: &Orbit, epsilon: f64, msg: &str) {
132 if !left.eq_within(right, epsilon, epsilon) {
133 panic!(
134 r#"assertion failed: {msg}
135 left: `{left:?}`,
136 right: `{right:?}`"#
137 )
138 }
139}
140
141#[derive(Debug, PartialEq, Snafu)]
142#[snafu(visibility(pub(crate)))]
143pub enum AstroError {
144 #[snafu(display("B Plane jacobian invariant must be either VX, VY or VZ"))]
145 BPlaneInvariant,
146 #[snafu(display("operation requires a local frame"))]
147 NotLocalFrame,
148 #[snafu(display("partial derivatives not defined for this parameter"))]
149 PartialsUndefined,
150 #[snafu(display("Orbit is not hyperbolic so there is no hyperbolic anomaly."))]
151 NotHyperbolic,
152 #[snafu(display("physics error occured during astro computation: {source}"))]
153 AstroPhysics { source: PhysicsError },
154 #[snafu(display("ANISE Almanac error occured during astro computation: {source}"))]
155 AstroAlmanac {
156 #[snafu(source(from(AlmanacError, Box::new)))]
157 source: Box<AlmanacError>,
158 },
159}
160
161mod orbitdual;
163pub use self::orbitdual::*;
164
165mod bplane;
167pub use self::bplane::*;
168
169mod spacecraft;
171pub use self::spacecraft::*;
172
173pub mod eclipse;
175
176pub const SPEED_OF_LIGHT_M_S: f64 = SPEED_OF_LIGHT_KM_S * 1e3;
178pub use anise::constants::SPEED_OF_LIGHT_KM_S;
179
180pub const AU: f64 = 149_597_870.700;
182
183pub const STD_GRAVITY: f64 = 9.80665;