1pub mod builders;
7mod cartesian;
8pub mod ensemble;
10mod keplerian;
11pub mod sso;
13mod trajectory;
14
15pub use cartesian::StateToDynGroundError;
16pub use ensemble::{DynEnsemble, Ensemble};
17pub use trajectory::{DynTrajectory, Trajectory, TrajectoryError, TrajectoryTransformationError};
18
19use lox_bodies::{DynOrigin, Origin, PointMass, TryPointMass, UndefinedOriginPropertyError};
20use lox_core::{
21 coords::Cartesian,
22 elements::{GravitationalParameter, Keplerian},
23};
24use lox_frames::{DynFrame, ReferenceFrame};
25use lox_time::{
26 Time,
27 time_scales::{DynTimeScale, TimeScale},
28};
29use thiserror::Error;
30
31pub enum OrbitType {
33 Cartesian(Cartesian),
35 Keplerian(Keplerian),
37}
38
39#[derive(Debug, Clone, Copy, PartialEq)]
41#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
42pub struct Orbit<S, T: TimeScale, O: Origin, R: ReferenceFrame> {
43 state: S,
44 time: Time<T>,
45 origin: O,
46 frame: R,
47}
48
49pub type DynOrbit = Orbit<OrbitType, DynTimeScale, DynOrigin, DynFrame>;
51
52impl<S, T, O, R> Orbit<S, T, O, R>
53where
54 T: TimeScale,
55 O: Origin,
56 R: ReferenceFrame,
57{
58 #[inline]
60 pub const fn from_state(state: S, time: Time<T>, origin: O, frame: R) -> Self {
61 Self {
62 state,
63 time,
64 origin,
65 frame,
66 }
67 }
68
69 #[inline]
71 pub fn state(&self) -> S
72 where
73 S: Copy,
74 {
75 self.state
76 }
77
78 #[inline]
80 pub fn time(&self) -> Time<T>
81 where
82 T: Copy,
83 {
84 self.time
85 }
86
87 #[inline]
89 pub fn origin(&self) -> O
90 where
91 O: Copy,
92 {
93 self.origin
94 }
95
96 #[inline]
98 pub fn reference_frame(&self) -> R
99 where
100 R: Copy,
101 {
102 self.frame
103 }
104
105 pub fn try_gravitational_parameter(
107 &self,
108 ) -> Result<GravitationalParameter, UndefinedOriginPropertyError>
109 where
110 O: TryPointMass,
111 {
112 self.origin.try_gravitational_parameter()
113 }
114
115 pub fn gravitational_parameter(&self) -> GravitationalParameter
117 where
118 O: PointMass,
119 {
120 self.origin.gravitational_parameter()
121 }
122}
123
124impl<S, T, O, R> Orbit<S, T, O, R>
125where
126 T: TimeScale + Copy + Into<DynTimeScale>,
127 O: Origin + Copy + Into<DynOrigin>,
128 R: ReferenceFrame + Copy + Into<DynFrame>,
129{
130 pub fn into_dyn(self) -> Orbit<S, DynTimeScale, DynOrigin, DynFrame> {
132 Orbit::from_state(
133 self.state,
134 self.time.into_dyn(),
135 self.origin.into(),
136 self.frame.into(),
137 )
138 }
139}
140
141pub type CartesianOrbit<T, O, R> = Orbit<Cartesian, T, O, R>;
143pub type DynCartesianOrbit = Orbit<Cartesian, DynTimeScale, DynOrigin, DynFrame>;
145
146pub type KeplerianOrbit<T, O, R> = Orbit<Keplerian, T, O, R>;
148pub type DynKeplerianOrbit = Orbit<Keplerian, DynTimeScale, DynOrigin, DynFrame>;
150
151#[derive(Debug, Clone, PartialEq, Error)]
153pub enum TrajectorError {
154 #[error("at least 2 states are required but only {0} were provided")]
156 InsufficientStates(usize),
157}