nyx_space/md/opti/multipleshooting/
ctrlnodes.rs1use anise::prelude::Frame;
20
21use crate::md::prelude::{Objective, StateParameter};
22use crate::time::Epoch;
23use crate::NyxError;
24use serde_derive::{Deserialize, Serialize};
25use std::convert::Into;
26use std::str::FromStr;
27
28use super::multishoot::MultishootNode;
29
30#[derive(Serialize, Deserialize, Clone, Debug)]
31pub struct NodesSerde {
32 pub nodes: Vec<NodeSerde>,
33}
34
35impl NodesSerde {
36 pub fn to_node_vec(&self) -> Result<Vec<Node>, NyxError> {
37 let mut rtn = Vec::with_capacity(self.nodes.len());
38 for n in &self.nodes {
39 rtn.push(n.to_node()?)
40 }
41 Ok(rtn)
42 }
43}
44
45#[derive(Serialize, Deserialize, Clone, Debug)]
46pub struct NodeSerde {
47 pub x: f64,
48 pub y: f64,
49 pub z: f64,
50 pub vmag: Option<f64>,
51 pub epoch: String,
52 pub frame: Frame,
53}
54
55impl NodeSerde {
56 pub fn to_node(&self) -> Result<Node, NyxError> {
57 let epoch = Epoch::from_str(&self.epoch).unwrap();
58
59 Ok(Node {
60 x: self.x,
61 y: self.y,
62 z: self.z,
63 vmag: self.vmag.unwrap_or(0.0),
64 frame: self.frame,
65 epoch,
66 })
67 }
68}
69
70#[derive(Copy, Clone, Debug)]
71pub struct Node {
72 pub x: f64,
73 pub y: f64,
74 pub z: f64,
75 pub vmag: f64,
76 pub epoch: Epoch,
77 pub frame: Frame,
78}
79
80impl Node {
81 pub fn rmag(&self) -> f64 {
82 (self.x.powi(2) + self.y.powi(2) + self.z.powi(2)).sqrt()
83 }
84}
85
86impl MultishootNode<3> for Node {
87 fn epoch(&self) -> Epoch {
88 self.epoch
89 }
90
91 fn update_component(&mut self, component: usize, add_val: f64) {
92 match component {
93 0 => self.x += add_val,
94 1 => self.y += add_val,
95 2 => self.z += add_val,
96 3 => self.vmag += add_val,
97 _ => unreachable!(),
98 }
99 }
100}
101
102#[allow(clippy::from_over_into)]
103impl Into<[Objective; 3]> for Node {
104 fn into(self) -> [Objective; 3] {
105 [
106 Objective::new(StateParameter::X, self.x),
107 Objective::new(StateParameter::Y, self.y),
108 Objective::new(StateParameter::Z, self.z),
109 ]
110 }
111}
112
113impl MultishootNode<4> for Node {
114 fn epoch(&self) -> Epoch {
115 self.epoch
116 }
117
118 fn update_component(&mut self, component: usize, add_val: f64) {
119 match component {
120 0 => self.x += add_val,
121 1 => self.y += add_val,
122 2 => self.z += add_val,
123 3 => self.vmag += add_val,
124 _ => unreachable!(),
125 }
126 }
127}
128
129#[allow(clippy::from_over_into)]
130impl Into<[Objective; 4]> for Node {
131 fn into(self) -> [Objective; 4] {
132 [
133 Objective::new(StateParameter::X, self.x),
134 Objective::new(StateParameter::Y, self.y),
135 Objective::new(StateParameter::Z, self.z),
136 Objective::new(StateParameter::Vmag, self.vmag),
137 ]
138 }
139}
140
141#[allow(clippy::from_over_into)]
142impl Into<NodeSerde> for Node {
143 fn into(self) -> NodeSerde {
144 NodeSerde {
145 x: self.x,
146 y: self.y,
147 z: self.z,
148 vmag: Some(self.vmag),
149 frame: self.frame,
150 epoch: self.epoch.to_string(),
151 }
152 }
153}
154
155#[allow(clippy::from_over_into)]
156impl Into<NodeSerde> for &Node {
157 fn into(self) -> NodeSerde {
158 NodeSerde {
159 x: self.x,
160 y: self.y,
161 z: self.z,
162 vmag: Some(self.vmag),
163 frame: self.frame,
164 epoch: self.epoch.to_string(),
165 }
166 }
167}
168
169#[test]
170fn test_nodeserde() {
171 use toml;
172
173 let str_nodes = r#"[[nodes]]
174x = -394.37164017582654
175y = -80.02184491079583
176z = -1702.1160791417442
177vmag = 0.0
178epoch = "2023-11-25T14:11:46.789000034 UTC"
179
180[nodes.frame]
181ephemeris_id = 301
182orientation_id = 1
183
184[[nodes]]
185x = -381.68254116206856
186y = -48.21573534985666
187z = -1705.829637126235
188vmag = 0.0
189epoch = "2023-11-25T14:12:06.789000034 UTC"
190
191[nodes.frame]
192ephemeris_id = 301
193orientation_id = 1
194
195[[nodes]]
196x = -368.8474537620047
197y = -16.401929604226403
198z = -1708.8692139449731
199vmag = 0.0
200epoch = "2023-11-25T14:12:26.789000034 UTC"
201
202[nodes.frame]
203ephemeris_id = 301
204orientation_id = 1
205"#;
206
207 let toml_nodes: NodesSerde = toml::from_str(str_nodes).unwrap();
208
209 let nodes = toml_nodes.to_node_vec().unwrap();
210
211 dbg!(&nodes);
212
213 let v = NodesSerde {
214 nodes: nodes.iter().map(|n| n.into()).collect::<Vec<NodeSerde>>(),
215 };
216 let toml_ser = toml::to_string(&v).unwrap();
217
218 println!("GOT\n{}\n\nWANTED:{}", toml_ser, str_nodes);
219
220 assert_eq!(toml_ser, str_nodes);
221}