Skip to main content

nyx_space/dynamics/sequence/
config.rs

1/*
2    Nyx, blazing fast astrodynamics
3    Copyright (C) 2018-onwards Christopher Rabotin <christopher.rabotin@gmail.com>
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU Affero General Public License as published
7    by the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU Affero General Public License for more details.
14
15    You should have received a copy of the GNU Affero General Public License
16    along with this program.  If not, see <https://www.gnu.org/licenses/>.
17*/
18use anise::frames::FrameUid;
19use serde::{Deserialize, Serialize};
20use serde_dhall::{SimpleType, StaticType};
21use std::collections::HashMap;
22use std::sync::Arc;
23
24use crate::{
25    dynamics::{
26        guidance::{Maneuver, ObjectiveEfficiency, ObjectiveWeight},
27        Drag, PointMasses, SolarPressure,
28    },
29    io::gravity::GravityFieldConfig,
30    propagators::{IntegratorMethod, IntegratorOptions},
31};
32
33use crate::dynamics::sequence::discrete_event::DiscreteEvent;
34
35#[derive(Clone, Debug, Serialize, Deserialize)]
36pub enum Phase {
37    Terminate,
38    Activity {
39        name: String,
40        propagator: String,
41        guidance: Option<Box<GuidanceConfig>>,
42        /// The discrete event will be applied ONCE before the equation of motions are integrated.
43        on_entry: Option<Box<DiscreteEvent>>,
44        /// Allows disabling a phase without removing it
45        disabled: bool,
46    },
47}
48
49impl StaticType for Phase {
50    fn static_type() -> SimpleType {
51        let mut variants = HashMap::new();
52
53        // Handle the Vector(Vector3<f64>) variant
54        // Most math crates serialize Vector3 as a list of 3 doubles
55        variants.insert("Terminate".to_string(), None);
56
57        //  Activity variant (Record variant)
58        let mut activity_fields = HashMap::new();
59
60        activity_fields.insert("name".to_string(), String::static_type());
61        activity_fields.insert("propagator".to_string(), String::static_type());
62
63        // Use the StaticType impl of the boxed inner types
64        activity_fields.insert(
65            "guidance".to_string(),
66            <Option<GuidanceConfig> as StaticType>::static_type(),
67        );
68
69        activity_fields.insert(
70            "on_entry".to_string(),
71            <Option<DiscreteEvent> as StaticType>::static_type(),
72        );
73
74        activity_fields.insert("disabled".to_string(), bool::static_type());
75
76        variants.insert(
77            "Activity".to_string(),
78            Some(SimpleType::Record(activity_fields)),
79        );
80
81        SimpleType::Union(variants)
82    }
83}
84
85/// Propagator config includes the method, options, and all dynamics
86#[derive(Clone, Debug, Serialize, Deserialize, StaticType)]
87pub struct PropagatorConfig {
88    pub method: IntegratorMethod,
89    pub options: IntegratorOptions,
90    pub accel_models: AccelModels,
91    pub force_models: ForceModels,
92}
93
94/// Acceleration models alter the orbital dynamics
95#[derive(Clone, Serialize, Deserialize, Debug)]
96pub struct AccelModels {
97    pub point_masses: Option<Arc<PointMasses>>,
98    pub gravity_field: Option<(GravityFieldConfig, FrameUid)>,
99}
100
101/// Force models alter the spacecraft dynamics (they need a mass).
102#[derive(Clone, Serialize, Deserialize, Debug)]
103pub struct ForceModels {
104    pub solar_pressure: Option<Arc<SolarPressure>>,
105    pub drag: Option<Arc<Drag>>,
106}
107
108#[derive(Clone, Debug, Serialize, Deserialize, StaticType)]
109pub struct GuidanceConfig {
110    pub thruster_model: String,
111    pub disable_prop_mass: bool,
112    pub law: SteeringLaw,
113}
114
115#[derive(Clone, Debug, Serialize, Deserialize, StaticType)]
116pub enum SteeringLaw {
117    FiniteBurn(Maneuver),
118    Kluever {
119        /// Stores the objectives, and their associated weights (set to zero to disable).
120        objectives: Vec<ObjectiveWeight>,
121        /// If defined, coast until vehicle is out of the provided eclipse state.
122        max_eclipse_prct: Option<f64>,
123    },
124    Ruggiero {
125        /// Stores the objectives, and their associated efficiency threshold (set to zero if not minimum efficiency).
126        objectives: Vec<ObjectiveEfficiency>,
127        /// If defined, coast until vehicle is out of the provided eclipse state.
128        max_eclipse_prct: Option<f64>,
129    },
130}
131
132impl StaticType for AccelModels {
133    fn static_type() -> serde_dhall::SimpleType {
134        let mut fields = HashMap::new();
135
136        fields.insert(
137            "point_masses".to_string(),
138            SimpleType::Optional(Box::new(PointMasses::static_type())),
139        );
140
141        #[allow(dead_code)]
142        #[derive(StaticType)]
143        struct GravityFieldDhall(GravityFieldConfig, FrameUid);
144
145        fields.insert(
146            "gravity_field".to_string(),
147            SimpleType::Optional(Box::new(GravityFieldDhall::static_type())),
148        );
149
150        SimpleType::Record(fields)
151    }
152}
153
154impl StaticType for ForceModels {
155    fn static_type() -> serde_dhall::SimpleType {
156        let mut fields = HashMap::new();
157
158        fields.insert(
159            "solar_pressure".to_string(),
160            SimpleType::Optional(Box::new(SolarPressure::static_type())),
161        );
162
163        fields.insert(
164            "drag".to_string(),
165            SimpleType::Optional(Box::new(Drag::static_type())),
166        );
167
168        SimpleType::Record(fields)
169    }
170}