keplerian::keplerian( const epoch& ref_epoch, const array3D& r0, const array3D& v0, double mu_central_body, double mu_self, double radius, double safe_radius, const std::string &name) : base(mu_central_body, mu_self, radius, safe_radius, name), m_r(r0), m_v(v0), m_ref_mjd2000(ref_epoch.mjd2000()) { // This line is singular (small e and small i) in which case the orbital elements are (simply) not defined ic2par(r0,v0, get_mu_central_body(), m_keplerian_elements); m_keplerian_elements[5] = e2m(m_keplerian_elements[5],m_keplerian_elements[1]); m_mean_motion = sqrt(get_mu_central_body() / pow(m_keplerian_elements[0],3)); }
void keplerian::eph_impl(double mjd2000, array3D &r, array3D &v) const { double dt = (mjd2000 - m_ref_mjd2000) * ASTRO_DAY2SEC; if (m_keplerian_elements[1] > 1e-3 && m_keplerian_elements[2] > 1e-3) { double elements[6]; std::copy(m_keplerian_elements.begin(), m_keplerian_elements.end(), elements); elements[5] += m_mean_motion * dt; elements[5] = m2e(elements[5],elements[1]); par2ic(elements, get_mu_central_body(), r, v); } else { // Small inclinations and eccentricities (including nans), we use lagrangian propagation r = m_r; v = m_v; propagate_lagrangian(r, v, dt, get_mu_central_body()); } }
/// Computes the low-precision ephemerides void jpl_lp::eph_impl(double mjd2000, array3D &r, array3D &v) const { if (mjd2000 <=-73048.0 || mjd2000>=18263.0) { throw_value_error("Ephemeris are out of range [1800-2050]"); } // algorithm from http://ssd.jpl.nasa.gov/txt/p_elem_t1.txt downloded 2013 array6D elements, elements2; double dt = (mjd2000 - ref_mjd2000) / 36525.0; // Number of centuries passed since J2000.0 for(unsigned int i= 0;i<6;++i) { elements[i] = (jpl_elements[i] + jpl_elements_dot[i] * dt); } elements2[0] = elements[0] * ASTRO_AU; elements2[1] = elements[1]; elements2[2] = elements[2] * ASTRO_DEG2RAD; elements2[3] = elements[5] * ASTRO_DEG2RAD; elements2[4] = (elements[4] - elements[5]) * ASTRO_DEG2RAD; elements2[5] = (elements[3] - elements[4]) * ASTRO_DEG2RAD; elements2[5] = m2e(elements2[5],elements2[1]); par2ic(elements2, get_mu_central_body(), r, v); }
/** * Constructs a planet from its elements and its phyisical parameters * \param[in] ref_epoch epoch to which the elements are referred to * \param[in] elem A STL vector containing the keplerian parameters (a,e,i,Om,om,M). (SI units) * \param[in] mu_central_body The gravitational parameter of the attracting body (SI units) * \param[in] mu_self The gravitational parameter of the planet (SI units) * \param[in] radius radius of the planet (SI units) * \param[in] safe_radius mimimual radius that is safe during a fly-by of the planet (SI units) * \param[in] name C++ string containing the planet name. Default value is "Unknown" */ keplerian::keplerian( const epoch& ref_epoch, const array6D& keplerian_elements, double mu_central_body, double mu_self, double radius, double safe_radius, const std::string &name) : base(mu_central_body, mu_self, radius, safe_radius, name), m_keplerian_elements(keplerian_elements), m_ref_mjd2000(ref_epoch.mjd2000()) { if (keplerian_elements[0] <=0) { throw_value_error("The planet semi-major axis needs to a positive number"); } if (keplerian_elements[1] < 0 || keplerian_elements[1] >=1) { throw_value_error("The planet eccentricity needs to be in [0,1)"); } m_mean_motion = sqrt(mu_central_body / pow(keplerian_elements[0],3)); par2ic(m_keplerian_elements, get_mu_central_body(), m_r, m_v); }
/// Sets the keplerian elements (and computes the mean motion) void keplerian::set_elements(const array6D& el) { m_keplerian_elements = el; m_mean_motion = sqrt(get_mu_central_body() / pow(m_keplerian_elements[0],3)); }
double planet::compute_period() const { return 2* boost::math::constants::pi<double>() * std::sqrt(std::pow(get_elements()[0],3) / get_mu_central_body()); }