19#include <Sandals/RungeKutta.hh>
20#include <Sandals/Solution.hh>
67 Body(std::string
const & t_name,
Real const t_mass,
Real const t_radius = 0.0)
98 std::string
name()
const {
return this->m_name;}
104 void name(std::string
const & t_name)
106 #define CMD "Astro::Body::name(...): "
109 this->m_name = t_name;
145 "Astro::Orbit::epoch_anomaly(...): invalid orbital anomalies detected.");
146 this->m_epoch_anom = t_epoch_anomaly;
158 this->m_orbit.compute_lambda(this->m_epoch+t, this->m_epoch_anom), this->m_orbit.
keplerian(), this->m_orbit.factor()
186 #define CMD "Astro::Body::mass(...): "
189 this->m_mass = t_mass;
205 #define CMD "Astro::Body::radius(...): "
208 this->m_radius = t_radius;
221 "Astro::Body::cartesian(...): invalid cartesian state vector detected.");
235 this->m_orbit.compute_lambda(this->m_epoch+t, this->m_epoch_anom), this->m_orbit.
keplerian(), this->m_orbit.factor()
284 "Astro::Body::keplerian(...): invalid keplerian state vector detected.");
316 "Astro::Body::equinoctial(...): invalid equinoctial state vector detected.");
337 Eigen::Matrix<T, 6, 1>
cartesian_eom(Eigen::Matrix<T, 6, 1>
const & x, Eigen::Matrix<T, 3, 1>
const & thrust_rtn)
const
340 Eigen::Matrix<T, 3, 1> thrust_xyz(this->
orbit().cartesian_rtn_to_xyz(thrust_rtn));
341 thrust_xyz /= this->m_mass;
344 T mur3{this->
orbit().
mu()/
Power3(x.template head<3>().norm())};
345 return Eigen::Matrix<T, 6, 1>(
349 thrust_xyz[0] - mur3*x[0],
350 thrust_xyz[1] - mur3*x[1],
351 thrust_xyz[2] - mur3*x[2]
366 Real const & a{x[0]};
367 Real const & e{x[1]};
368 Real const & i{x[2]};
370 Real const & omega{x[4]};
371 Real const & M{x[5]};
374 Real const C_rad{thrust[0]/this->m_mass};
375 Real const C_tan{thrust[1]/this->m_mass};
376 Real const C_nor{thrust[2]/this->m_mass};
379 Real const n{std::sqrt(mu / std::pow(a, 3))};
381 Real const ecc{std::sqrt(1.0 - e2)};
385 Real const cos_E{std::cos(E)};
387 Real const cos_nu{std::cos(nu)};
388 Real const sin_nu{std::sin(nu)};
391 Real const p{a*(1.0 - e2)};
392 Real const r{p / (1.0 + e*cos_nu)};
393 Real const u{omega + nu};
394 Real const h{ecc * std::sqrt(mu*a)};
396 Real const sin_i{std::sin(i)};
397 Real const cos_i{std::cos(i)};
398 Real const sin_u{std::sin(u)};
399 Real const cos_u{std::cos(u)};
403 2.0*a*h/(mu*(1.0 - e2))*(e*sin_nu*C_rad + (1.0 + e*cos_nu)*C_tan),
404 h/mu*(sin_nu*C_rad + (cos_nu + cos_E)*C_tan),
406 sin_u*r*C_nor/(h*sin_i),
407 -h/(mu*e)*(cos_nu*C_rad - (2.0 + e*cos_nu)/(1.0 + e*cos_nu)*sin_nu*C_tan) - cos_i*sin_u*r*C_nor/(h*sin_i),
408 n + h*ecc/(mu*e) * ((cos_nu - 2.0*e*r/p)*C_rad - (1.0 + r/p)*sin_nu*C_tan);
424 Real const & p{x[0]};
425 Real const & f{x[1]};
426 Real const & g{x[2]};
427 Real const & h{x[3]};
428 Real const & k{x[4]};
429 Real const & L{x[5]};
432 Real sin_L{std::sin(L)};
433 Real cos_L{std::cos(L)};
435 Real w{1.0 + (f*cos_L + g*sin_L)};
436 Real s2{1.0 + (h*h + k*k)};
437 Real sqrt_p_mu{std::sqrt(p/mu)};
439 Real C_rad{thrust[0]/this->m_mass};
440 Real C_tan{thrust[1]/this->m_mass};
441 Real C_nor{thrust[2]/this->m_mass};
445 2.0*p*sqrt_p_mu/w*C_tan,
446 sqrt_p_mu*(+C_rad*sin_L + ((w + 1.0)*cos_L + f)*C_tan/w - (h*sin_L - k*cos_L)*g/w*C_nor),
447 sqrt_p_mu*(-C_rad*cos_L + ((w + 1.0)*sin_L + g)*C_tan/w + (h*sin_L - k*cos_L)*g/w*C_nor),
448 sqrt_p_mu*s2*C_nor*cos_L/(2.0*w),
449 sqrt_p_mu*s2*C_nor*sin_L/(2.0*w),
450 std::sqrt(mu*p) *
Power2(w/p) + sqrt_p_mu/w*(h*sin_L - k*cos_L)*C_nor;
484 template <Coordinates IntCoords, Coordinates OutCoords = Coordinates::CARTESIAN, Integer S>
486 Sandals::Solution<Real, 6, 0> & sol,
bool const adaptive =
false)
488 #define CMD "Astro::Body::integrate(...): "
491 if constexpr (IntCoords == Coordinates::CARTESIAN) {
496 }
else if constexpr (IntCoords == Coordinates::KEPLERIAN) {
501 }
else if constexpr (IntCoords == Coordinates::EQUINOCTIAL) {
506 }
else if constexpr (IntCoords == Coordinates::QUATERNIONIC) {
509 ASTRO_ERROR(
CMD "unknown coordinate system for the integration.");
518 if constexpr (IntCoords == Coordinates::CARTESIAN) {
520 }
else if constexpr (IntCoords == Coordinates::KEPLERIAN) {
522 }
else if constexpr (IntCoords == Coordinates::EQUINOCTIAL) {
524 }
else if constexpr (IntCoords == Coordinates::QUATERNIONIC) {
531 if constexpr (IntCoords != OutCoords) {
532 if constexpr (OutCoords == Coordinates::CARTESIAN) {
534 }
else if constexpr (OutCoords == Coordinates::KEPLERIAN) {
536 }
else if constexpr (OutCoords == Coordinates::EQUINOCTIAL) {
538 }
else if constexpr (OutCoords == Coordinates::QUATERNIONIC) {
549 return rk.adaptive_solve(t_mesh, ics, sol);
551 return rk.solve(t_mesh, ics, sol);
#define ASTRO_ASSERT(COND, MSG)
Definition Astro.hh:43
#define ASTRO_ERROR(MSG)
Definition Astro.hh:32
Real m_mass
Definition Body.hh:55
Anomaly const & epoch_anomaly() const
Definition Body.hh:130
void name(std::string const &t_name)
Definition Body.hh:104
Vector6 keplerian_state(Real const t) const
Definition Body.hh:272
Real m_radius
Definition Body.hh:54
Real m_epoch
Definition Body.hh:51
Body & operator=(Body &&)=default
void set_epoch_anomaly(Anomaly const &t_epoch_anomaly)
Definition Body.hh:142
Orbit const & orbit() const
Definition Body.hh:118
Vector6 cartesian_state() const
Definition Body.hh:217
void radius(Real const t_radius)
Definition Body.hh:204
Real epoch() const
Definition Body.hh:167
std::string name() const
Definition Body.hh:98
void set_cartesian_state(Vector6 const &cart)
Definition Body.hh:262
Body()
Definition Body.hh:61
Vector3 cartesian_position(Real const t) const
Definition Body.hh:249
Real mass() const
Definition Body.hh:179
void set_epoch(Real const t_epoch)
Definition Body.hh:173
Vector6 equinoctial_eom(Vector6 const &x, Vector3 const &thrust) const
Definition Body.hh:420
Real radius() const
Definition Body.hh:198
Orbit & set_orbit()
Definition Body.hh:124
Vector6 equinoctial_state(Real const t) const
Definition Body.hh:304
void set_equinoctial_state(Vector6 const &state)
Definition Body.hh:324
Body(Body const &)=default
OrbitalElements::Anomaly Anomaly
Definition Body.hh:47
Anomaly m_epoch_anom
Definition Body.hh:52
Vector6 equinoctial_eom(Vector6 const &x, Real thrust_rad, Real thrust_tan, Real thrust_nor) const
Definition Body.hh:464
bool integrate(Sandals::RungeKutta< Real, S, 6, 0 > &rk, VectorX const &t_mesh, Vector6 const &ics, Sandals::Solution< Real, 6, 0 > &sol, bool const adaptive=false)
Definition Body.hh:485
Anomaly & set_epoch_anomaly()
Definition Body.hh:136
Eigen::Matrix< T, 6, 1 > cartesian_eom(Eigen::Matrix< T, 6, 1 > const &x, Eigen::Matrix< T, 3, 1 > const &thrust_rtn) const
Definition Body.hh:337
Body(std::string const &t_name, Real const t_mass, Real const t_radius=0.0)
Definition Body.hh:67
void mass(Real const t_mass)
Definition Body.hh:185
Vector6 keplerian_eom(Vector6 const &x, Vector3 const &thrust) const
Definition Body.hh:362
std::string m_name
Definition Body.hh:50
Anomaly anomaly(Real const t) const
Definition Body.hh:154
Vector3 cartesian_velocity(Real const t) const
Definition Body.hh:256
Orbit m_orbit
Definition Body.hh:53
Vector6 cartesian_state(Real const t) const
Definition Body.hh:230
Body & operator=(const Body &)=default
void set_keplerian_state(Vector6 const &state)
Definition Body.hh:292
Orbit class container.
Definition Orbit.hh:39
Real mu() const
Definition Orbit.hh:316
Keplerian const & keplerian() const
Definition Orbit.hh:140
void set_equinoctial(Real const t_p, Real const t_f, Real const t_g, Real const t_h, Real const t_k, Real const L)
Definition Orbit.hh:203
void set_cartesian(Real r_x, Real r_y, Real r_z, Real v_x, Real v_y, Real v_z)
Definition Orbit.hh:96
void set_keplerian(Real const t_a, Real const t_e, Real const t_i, Real const t_Omega, Real const t_omega, Real const nu)
Definition Orbit.hh:151
Equinoctial const & equinoctial() const
Definition Orbit.hh:192
Cartesian const & cartesian() const
Definition Orbit.hh:85
Real E_to_nu(Real const E, Real const e)
Definition OrbitalElements.hh:963
Real M_to_E(Real M, Real const e)
Definition OrbitalElements.hh:865
void equinoctial_to_cartesian(Equinoctial const &equi, Real const L, Real const mu, Cartesian &cart)
Definition OrbitalElements.hh:1487
The namespace for the Astro library.
Definition Astro.hh:73
enum class Coordinates :Integer {CARTESIAN=0, KEPLERIAN=1, EQUINOCTIAL=2, QUATERNIONIC=3} Coordinates
Definition Body.hh:26
int Integer
Definition Astro.hh:85
Real Power2(Real x)
Definition Utilities.hh:34
static Real const QUIET_NAN
Definition Astro.hh:134
Real Power3(Real x)
Definition Utilities.hh:42
Eigen::Vector< Real, 6 > Vector6
Definition Astro.hh:99
double Real
Definition Astro.hh:84
Eigen::Matrix< Real, 6, 6 > Matrix6
Definition Astro.hh:100
Eigen::Vector< Real, 3 > Vector3
Definition Astro.hh:93
Eigen::Vector< Real, Eigen::Dynamic > VectorX
Definition Astro.hh:108
static Matrix6 const ZEROS_MAT6
Definition Astro.hh:179
Structure container for the orbital anomalies.
Definition OrbitalElements.hh:1110
bool sanity_check() const
Definition OrbitalElements.hh:1323
void set_lambda(Real t_lambda, Keplerian const &kepl, Factor const I)
Set the mean longitude .
Definition OrbitalElements.hh:1248
Real L
Definition OrbitalElements.hh:1115
Real M
Definition OrbitalElements.hh:1112
Structure container for the cartesian orbital elements.
Definition OrbitalElements.hh:59
Vector6 vector() const
Definition OrbitalElements.hh:118
Real h
Definition OrbitalElements.hh:443
Real g
Definition OrbitalElements.hh:442
Real p
Definition OrbitalElements.hh:440
Real f
Definition OrbitalElements.hh:441
Real k
Definition OrbitalElements.hh:444
Real i
Definition OrbitalElements.hh:233
Real omega
Definition OrbitalElements.hh:235
Real e
Definition OrbitalElements.hh:232
Real Omega
Definition OrbitalElements.hh:234
Real a
Definition OrbitalElements.hh:231