Astro  0.0.0
A C++ library for space dynamics
Loading...
Searching...
No Matches
Orbit.hxx
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2 * Copyright (c) 2025, Davide Stocco and Enrico Bertolazzi. *
3 * *
4 * The Orbit project is distributed under the GNU GPLv3. *
5 * *
6 * Davide Stocco Enrico Bertolazzi *
7 * University of Trento University of Trento *
8 * e-mail: davide.stocco@unitn.it e-mail: enrico.bertolazzi@unitn.it *
9\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
10
11#pragma once
12
13#ifndef ASTRO_ORBIT_HXX
14#define ASTRO_ORBIT_HXX
15
16namespace Astro
17{
18
19 /*\
20 | ___ _ _ _
21 | / _ \ _ __| |__ (_) |_
22 | | | | | '__| '_ \| | __|
23 | | |_| | | | |_) | | |_
24 | \___/|_| |_.__/|_|\__|
25 |
26 \*/
27
36 class Orbit
37 {
43
44 protected:
50 Type m_type{Type::UNDEFINED};
51 Factor m_factor{Factor::UNDEFINED};
53
54 public:
58 Orbit() {}
59
63 Orbit(Orbit const &) = default;
64
68 Orbit(Orbit &&) = default;
69
73 Orbit & operator=(const Orbit &) = default;
74
78 Orbit & operator=(Orbit &&) = default;
79
84 Cartesian const & cartesian() const {return this->m_cart;}
85
95 void set_cartesian(Real r_x, Real r_y, Real r_z, Real v_x, Real v_y, Real v_z)
96 {
97 this->m_cart.r << r_x, r_y, r_z;
98 this->m_cart.v << v_x, v_y, v_z;
99 OrbitalElements::cartesian_to_keplerian(this->m_cart, this->m_mu, this->m_kepl);
100 OrbitalElements::keplerian_to_equinoctial(this->m_kepl, this->m_factor, this->m_equi);
101 // TODO: OrbitalElements::cartesian_to_quaternionic(this->m_cart, this->m_quat);
102 this->type(this->m_kepl.e);
103 }
104
110 void cartesian(Vector3 const & t_r, Vector3 const & t_v)
111 {
112 this->m_cart.r = t_r;
113 this->m_cart.v = t_v;
114 OrbitalElements::cartesian_to_keplerian(this->m_cart, this->m_mu, this->m_kepl);
115 OrbitalElements::keplerian_to_equinoctial(this->m_kepl, this->m_factor, this->m_equi);
116 // TODO: OrbitalElements::cartesian_to_quaternionic(this->m_cart, this->m_quat);
117 this->type(this->m_kepl.e);
118 }
119
124 void cartesian(Cartesian const & t_cart)
125 {
126 this->m_cart = t_cart;
127 OrbitalElements::cartesian_to_keplerian(this->m_cart, this->m_mu, this->m_kepl);
128 OrbitalElements::keplerian_to_equinoctial(this->m_kepl, this->m_factor, this->m_equi);
129 // TODO: OrbitalElements::cartesian_to_quaternionic(this->m_cart, this->m_quat);
130 this->type(this->m_kepl.e);
131 }
132
137 Keplerian const & keplerian() const {return this->m_kepl;}
138
147 void keplerian(Real t_a, Real t_e, Real t_i, Real t_Omega, Real t_omega)
148 {
149 this->m_kepl.a = t_a;
150 this->m_kepl.e = t_e;
151 this->m_kepl.i = t_i;
152 this->m_kepl.Omega = t_Omega;
153 this->m_kepl.omega = t_omega;
154 OrbitalElements::keplerian_to_cartesian(this->m_kepl, this->m_anom, this->m_mu, this->m_cart);
155 OrbitalElements::keplerian_to_equinoctial(this->m_kepl, this->m_factor, this->m_equi);
156 // TODO: OrbitalElements::keplerian_to_quaternionic(this->m_kepl, this->m_quat);
157 this->type(this->m_kepl.e);
158 }
159
164 void keplerian(Keplerian const & t_kepl)
165 {
166 this->m_kepl = t_kepl;
167 OrbitalElements::keplerian_to_cartesian(this->m_kepl, this->m_anom, this->m_mu, this->m_cart);
168 OrbitalElements::keplerian_to_equinoctial(this->m_kepl, this->m_factor, this->m_equi);
169 // TODO: OrbitalElements::keplerian_to_quaternionic(this->m_kepl, this->m_quat);
170 this->type(this->m_kepl.e);
171 }
172
177 Equinoctial const & equinoctial() const {return this->m_equi;}
178
187 void set_equinoctial(Real t_p, Real t_f, Real t_g, Real t_h, Real t_k)
188 {
189 this->m_equi.p = t_p;
190 this->m_equi.f = t_f;
191 this->m_equi.g = t_g;
192 this->m_equi.h = t_h;
193 this->m_equi.k = t_k;
194 OrbitalElements::equinoctial_to_keplerian(this->m_equi, this->m_kepl);
195 OrbitalElements::equinoctial_to_cartesian(this->m_equi, this->m_anom, this->m_mu, this->m_cart);
196 // TODO: OrbitalElements::equinoctial_to_quaternionic(this->m_equi, this->m_quat);
197 this->type(this->m_kepl.e);
198 }
199
204 void set_equinoctial(Equinoctial const & t_equi)
205 {
206 this->m_equi = t_equi;
207 OrbitalElements::equinoctial_to_keplerian(this->m_equi, this->m_kepl);
208 OrbitalElements::equinoctial_to_cartesian(this->m_equi, this->m_anom, this->m_mu, this->m_cart);
209 // TODO: OrbitalElements::equinoctial_to_quaternionic(this->m_equi, this->m_quat);
210 this->type(this->m_kepl.e);
211 }
212
217 Quaternionic const & quaternionic() const {return this->m_quat;}
218
226 void set_quaternionic(Real t_q_1, Real t_q_2, Real t_q_3, Real t_q_4)
227 {
228 this->m_quat.q.x() = t_q_1;
229 this->m_quat.q.y() = t_q_2;
230 this->m_quat.q.z() = t_q_3;
231 this->m_quat.q.w() = t_q_4;
232 // TODO: OrbitalElements::quaternionic_to_keplerian(this->m_quat, this->m_kepl);
233 // TODO: OrbitalElements::quaternionic_to_equinoctial(this->m_quat, this->m_factor, this->m_equi);
234 // TODO: OrbitalElements::quaternionic_to_cartesian(this->m_quat, this->m_anom, this->m_mu, this->m_cart);
235 this->type(this->m_kepl.e);
236 }
237
242 void set_quaternionic(Quaternion const & t_quat)
243 {
244 this->m_quat.q = t_quat;
245 // TODO: OrbitalElements::quaternionic_to_keplerian(this->m_quat, this->m_kepl);
246 // TODO: OrbitalElements::quaternionic_to_equinoctial(this->m_quat, this->m_factor, this->m_equi);
247 // TODO: OrbitalElements::quaternionic_to_cartesian(this->m_quat, this->m_anom, this->m_mu, this->m_cart);
248 this->type(this->m_kepl.e);
249 }
250
255 Anomaly const & anomaly() const {return this->m_anom;}
256
261 void anomaly(Anomaly const & t_anom)
262 {
263 ASTRO_ASSERT(t_anom.sanity_check(),
264 "Astro::Orbit::anomaly(...): invalid orbital anomalies detected.");
265 this->m_anom = t_anom;
266 }
267
272 Type type() const {return this->m_type;}
273
278 void type(Real e)
279 {
280 if (e > 0.0 && e < 1.0) {
281 this->m_type = Type::ELLIPTIC;
282 } else if (e == 1.0) {
283 this->m_type = Type::PARABOLIC;
284 } else if (e > 1.0) {
285 this->m_type = Type::HYPERBOLIC;
286 } else {
287 ASTRO_ERROR("Astro::Orbit::type(...): invalid eccentricity detected.");
288 }
289 }
290
295 Factor factor() const {return this->m_factor;}
296
301 void factor(Factor t_factor) {this->m_factor = t_factor;}
302
307 Real mu() const {return this->m_mu;}
308
313 void mu(Real t_mu) {this->m_mu = t_mu;}
314
319 std::string info() const {
320 std::ostringstream os;
321 os <<
322 "Cartesian orbit parameters:" << std::endl <<
323 this->m_cart.info() << std::endl <<
324 "Keplerian orbit parameters:" << std::endl <<
325 this->m_kepl.info() << std::endl <<
326 "Equinoctial orbit parameters:" << std::endl <<
327 this->m_equi.info() << std::endl <<
328 "Quaternionic orbit parameters:" << std::endl <<
329 this->m_quat.info() << std::endl <<
330 "Orbital anomalies:" << std::endl <<
331 this->m_anom.info() << std::endl <<
332 "Orbit:" << std::endl <<
333 "µ: grav. const. = " << this->m_mu << " (UA³/day²)" << std::endl <<
334 "type = " << (this->m_type == Type::UNDEFINED ? "undefined" :
335 (this->m_type == Type::ELLIPTIC ? "elliptic" :
336 (this->m_type == Type::PARABOLIC ? "parabolic" :
337 (this->m_type == Type::HYPERBOLIC ? "hyperbolic" : "undefined")))) << std::endl <<
338 "factor = " << (this->m_factor == Factor::UNDEFINED ? "undefined" :
339 (this->m_factor == Factor::POSIGRADE ? "posigrade" :
340 (this->m_factor == Factor::RETROGRADE ? "retrograde" : "undefined"))) << std::endl;
341 return os.str();
342 }
343
348 void info(std::ostream & os) {os << this->info();}
349
353 void reset() {
354 this->m_cart.reset();
355 this->m_kepl.reset();
356 this->m_equi.reset();
357 this->m_quat.reset();
358 this->m_anom.reset();
359 this->m_type = Type::UNDEFINED;
360 this->m_factor = Factor::UNDEFINED;
361 }
362
368 {
369 Real s_Omega{std::sin(this->m_kepl.Omega)};
370 Real c_Omega{std::cos(this->m_kepl.Omega)};
371 Real s_omega{std::sin(this->m_kepl.omega)};
372 Real c_omega{std::cos(this->m_kepl.omega)};
373 Real s_i{std::sin(this->m_kepl.i)};
374 Real c_i{std::cos(this->m_kepl.i)};
375
376 Rotation R;
377 R <<
378 c_Omega*c_omega - s_Omega*s_omega*c_i, -c_Omega*s_omega - s_Omega*c_omega*c_i, s_Omega*s_i,
379 s_Omega*c_omega + c_Omega*s_omega*c_i, -s_Omega*s_omega + c_Omega*c_omega*c_i, -c_Omega*s_i,
380 s_i*s_omega, s_i*c_omega, c_i;
381 return R;
382 }
383
389 {
390 Real h{this->m_equi.h};
391 Real k{this->m_equi.k};
392 Real h2{h*h};
393 Real k2{k*k};
394 Real hk{h*k};
395 Real I{static_cast<Real>(this->m_factor)};
396
397 Rotation R;
398 R <<
399 1.0-h2+k2, 2.0*I*hk, 2.0*h,
400 2.0*hk, I*(1.0+h2-k2), -2.0*k,
401 -2.0*I*h, 2.0*k, I*(1.0-h2-k2);
402 return R / (1.0+h2+k2);
403 }
404
411 {
412 // Initialize the Frenet-Serret frame
413 Rotation rtn;
414
415 // Compute the radial vector
416 rtn.col(0) = this->m_cart.r;
417 rtn.col(0).normalize();
418
419 // Compute the tangential vector
420 rtn.col(1) = rtn.col(0).cross(this->m_cart.v);
421 rtn.col(1).normalize();
422
423 // Compute the binormal vector
424 rtn.col(2) = rtn.col(0).cross(rtn.col(1));
425
426 // Return the Frenet-Serret frame
427 return rtn;
428 }
429
436 {
437 Real h{this->m_equi.h};
438 Real k{this->m_equi.k};
439 Real c_L{std::cos(this->m_anom.L)};
440 Real s_L{std::sin(this->m_anom.L)};
441 Real h2{h*h};
442 Real k2{k*k};
443 Real hk{h*k};
444 Real bf{1.0+h2+k2};
445 Real I{static_cast<Real>(this->m_factor)};
446
447 Rotation R;
448 R <<
449 ((h2-k2+1)*c_L+2.0*I*hk*s_L)/bf, ((k2-h2-1.0)*s_L+2.0*hk*I*c_L)/bf, 2.0*k/bf,
450 (2.0*hk*c_L-I*(h2-k2-1.0)*s_L)/bf, (I*(1.0+k2-h2)*c_L-2.0*hk*s_L)/bf, -2.0*h/bf,
451 (2.0*(h*s_L-c_L*k*I))/bf, (2.0*k*I*s_L+2.0*h*c_L)/bf, I*(1-h2-k2)/bf;
452 return R;
453 }
454
462 {
463 return this->cartesian_to_frenet_rtn() * vec;
464 }
465
473 {
474 return this->equinoctial_to_frenet_rtn() * vec;
475 }
476
484 {
485 return this->cartesian_to_frenet_rtn().transpose() * vec;
486 }
487
495 {
496 return this->equinoctial_to_frenet_rtn().transpose() * vec;
497 }
498
499 }; // class Orbit
500
501} // namespace Astro
502
503#endif // ASTRO_ORBIT_HXX
#define ASTRO_ASSERT(COND, MSG)
Definition Astro.hh:42
#define ASTRO_ERROR(MSG)
Definition Astro.hh:31
Rotation equinoctial_to_reference() const
Definition Orbit.hxx:388
Real m_mu
Definition Orbit.hxx:52
void mu(Real t_mu)
Definition Orbit.hxx:313
OrbitalElements::Keplerian Keplerian
Definition Orbit.hxx:39
OrbitalElements::Equinoctial Equinoctial
Definition Orbit.hxx:40
void cartesian(Vector3 const &t_r, Vector3 const &t_v)
Definition Orbit.hxx:110
Rotation keplerian_to_reference() const
Definition Orbit.hxx:367
void cartesian(Cartesian const &t_cart)
Definition Orbit.hxx:124
OrbitalElements::Cartesian Cartesian
Definition Orbit.hxx:38
Keplerian m_kepl
Definition Orbit.hxx:46
Rotation cartesian_to_frenet_rtn() const
Definition Orbit.hxx:410
Quaternionic const & quaternionic() const
Definition Orbit.hxx:217
void anomaly(Anomaly const &t_anom)
Definition Orbit.hxx:261
Orbit(Orbit const &)=default
Vector3 equinoctial_rtn_to_xyz(Vector3 const &vec) const
Definition Orbit.hxx:472
void keplerian(Keplerian const &t_kepl)
Definition Orbit.hxx:164
void set_equinoctial(Real t_p, Real t_f, Real t_g, Real t_h, Real t_k)
Definition Orbit.hxx:187
void set_quaternionic(Quaternion const &t_quat)
Definition Orbit.hxx:242
Factor m_factor
Definition Orbit.hxx:51
Real mu() const
Definition Orbit.hxx:307
void keplerian(Real t_a, Real t_e, Real t_i, Real t_Omega, Real t_omega)
Definition Orbit.hxx:147
void factor(Factor t_factor)
Definition Orbit.hxx:301
Vector3 cartesian_rtn_to_xyz(Vector3 const &vec) const
Definition Orbit.hxx:461
Keplerian const & keplerian() const
Definition Orbit.hxx:137
Type m_type
Definition Orbit.hxx:50
Anomaly const & anomaly() const
Definition Orbit.hxx:255
void set_quaternionic(Real t_q_1, Real t_q_2, Real t_q_3, Real t_q_4)
Definition Orbit.hxx:226
void info(std::ostream &os)
Definition Orbit.hxx:348
Type type() const
Definition Orbit.hxx:272
Orbit(Orbit &&)=default
void reset()
Definition Orbit.hxx:353
void set_cartesian(Real r_x, Real r_y, Real r_z, Real v_x, Real v_y, Real v_z)
Definition Orbit.hxx:95
Anomaly m_anom
Definition Orbit.hxx:49
Equinoctial m_equi
Definition Orbit.hxx:47
Orbit()
Definition Orbit.hxx:58
OrbitalElements::Anomaly Anomaly
Definition Orbit.hxx:42
Rotation equinoctial_to_frenet_rtn() const
Definition Orbit.hxx:435
Vector3 cartesian_xyz_to_rtn(Vector3 const &vec) const
Definition Orbit.hxx:483
std::string info() const
Definition Orbit.hxx:319
void set_equinoctial(Equinoctial const &t_equi)
Definition Orbit.hxx:204
OrbitalElements::Quaternionic Quaternionic
Definition Orbit.hxx:41
Factor factor() const
Definition Orbit.hxx:295
Quaternionic m_quat
Definition Orbit.hxx:48
Orbit & operator=(const Orbit &)=default
void type(Real e)
Definition Orbit.hxx:278
Equinoctial const & equinoctial() const
Definition Orbit.hxx:177
Cartesian const & cartesian() const
Definition Orbit.hxx:84
Orbit & operator=(Orbit &&)=default
Cartesian m_cart
Definition Orbit.hxx:45
Vector3 equinoctial_xyz_to_rtn(Vector3 const &vec) const
Definition Orbit.hxx:494
void equinoctial_to_cartesian(Equinoctial const &equi, Anomaly const &anom, Real mu, Cartesian &cart)
Definition OrbitalElements.hxx:1305
void keplerian_to_equinoctial(Keplerian const &kepl, Factor I, Equinoctial &equi)
Definition OrbitalElements.hxx:1348
void equinoctial_to_keplerian(Equinoctial const &equi, Keplerian &kepl)
Definition OrbitalElements.hxx:1437
void cartesian_to_keplerian(Cartesian const &cart, Real mu, Keplerian &kepl)
Definition OrbitalElements.hxx:1190
void keplerian_to_cartesian(Keplerian const &kepl, Anomaly const &anom, Real mu, Cartesian &cart)
Definition OrbitalElements.hxx:1253
The namespace for the Astro library.
Definition Astro.hh:72
Eigen::Quaternion< Real > Quaternion
Definition Astro.hh:111
Eigen::Matrix< Real, 3, 3 > Rotation
Definition Astro.hh:110
static Real const QUIET_NAN
Definition Astro.hh:133
enum class Type :Integer { UNDEFINED=0, HYPERBOLIC=1, ELLIPTIC=2, PARABOLIC=3 } Type
Definition OrbitalElements.hxx:24
double Real
Definition Astro.hh:83
enum class Factor :Integer { POSIGRADE=1, UNDEFINED=0, RETROGRADE=-1 } Factor
Definition OrbitalElements.hxx:19
Eigen::Vector< Real, 3 > Vector3
Definition Astro.hh:92
Structure container for the orbital anomalies.
Definition OrbitalElements.hxx:955
std::string info() const
Definition OrbitalElements.hxx:1114
bool sanity_check() const
Definition OrbitalElements.hxx:1149
void reset()
Definition OrbitalElements.hxx:1135
Real L
Definition OrbitalElements.hxx:960
Structure container for the cartesian orbital elements.
Definition OrbitalElements.hxx:56
Vector3 v
Definition OrbitalElements.hxx:58
void reset()
Definition OrbitalElements.hxx:125
Vector3 r
Definition OrbitalElements.hxx:57
std::string info() const
Definition OrbitalElements.hxx:108
Struct container for the (modified) equinoctial orbital elements.
Definition OrbitalElements.hxx:382
Real h
Definition OrbitalElements.hxx:386
Real g
Definition OrbitalElements.hxx:385
Real p
Definition OrbitalElements.hxx:383
Real f
Definition OrbitalElements.hxx:384
std::string info() const
Definition OrbitalElements.hxx:430
void reset()
Definition OrbitalElements.hxx:450
Real k
Definition OrbitalElements.hxx:387
Structure container for the (modified) Keplerian orbital elements.
Definition OrbitalElements.hxx:193
Real i
Definition OrbitalElements.hxx:196
std::string info() const
Definition OrbitalElements.hxx:241
void reset()
Definition OrbitalElements.hxx:261
Real omega
Definition OrbitalElements.hxx:198
Real e
Definition OrbitalElements.hxx:195
Real Omega
Definition OrbitalElements.hxx:197
Real a
Definition OrbitalElements.hxx:194
Structure container for the quaternionic orbital elements.
Definition OrbitalElements.hxx:600
void reset()
Definition OrbitalElements.hxx:683
Quaternion q
Definition OrbitalElements.hxx:601
std::string info() const
Definition OrbitalElements.hxx:664