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: {}
135 left: `{:?}`,
136 right: `{:?}`"#,
137 msg, left, right
138 )
139 }
140}
141
142#[derive(Debug, PartialEq, Snafu)]
143#[snafu(visibility(pub(crate)))]
144pub enum AstroError {
145 #[snafu(display("B Plane jacobian invariant must be either VX, VY or VZ"))]
146 BPlaneInvariant,
147 #[snafu(display("operation requires a local frame"))]
148 NotLocalFrame,
149 #[snafu(display("partial derivatives not defined for this parameter"))]
150 PartialsUndefined,
151 #[snafu(display("Orbit is not hyperbolic so there is no hyperbolic anomaly."))]
152 NotHyperbolic,
153 #[snafu(display("physics error occured during astro computation: {source}"))]
154 AstroPhysics { source: PhysicsError },
155 #[snafu(display("ANISE Almanac error occured during astro computation: {source}"))]
156 AstroAlmanac {
157 #[snafu(source(from(AlmanacError, Box::new)))]
158 source: Box<AlmanacError>,
159 },
160}
161
162mod orbitdual;
164pub use self::orbitdual::*;
165
166mod bplane;
168pub use self::bplane::*;
169
170mod spacecraft;
172pub use self::spacecraft::*;
173
174pub mod eclipse;
176
177pub const SPEED_OF_LIGHT_M_S: f64 = SPEED_OF_LIGHT_KM_S * 1e3;
179pub use anise::constants::SPEED_OF_LIGHT_KM_S;
180
181pub const AU: f64 = 149_597_870.700;
183
184pub const STD_GRAVITY: f64 = 9.80665;