26 #include <boost/math/constants/constants.hpp>
30 #include <keplerian_toolbox/core_functions/propagate_lagrangian.h>
31 #include <keplerian_toolbox/core_functions/fb_prop.h>
32 #include <keplerian_toolbox/core_functions/closest_distance.h>
33 #include <keplerian_toolbox/lambert_problem.h>
38 #define ASTRO_JR 71492000.0 //m
40 namespace pagmo {
namespace problem {
57 const std::vector<std::vector<double> > tof,
58 const kep_toolbox::epoch t0,
59 const kep_toolbox::array3D vinf_in
61 base(4*(seq.size()-1)), m_tof(tof), m_t0(t0), m_vinf_in(vinf_in)
64 std::vector<double> mus(seq.size());
65 for (std::vector<kep_toolbox::planet::planet_ptr>::size_type i = 0; i< seq.size(); ++i) {
66 mus[i] = seq[i]->get_mu_central_body();
68 if ((
unsigned int)std::count(mus.begin(), mus.end(), mus[0]) != mus.size()) {
69 pagmo_throw(value_error,
"The planets do not all have the same mu_central_body");
72 if (tof.size() != (seq.size()-1)) {
73 pagmo_throw(value_error,
"The time-of-flight vector (tof) has the wrong length");
75 for (
size_t i = 0; i < tof.size(); ++i) {
76 if (tof[i].size()!=2) pagmo_throw(value_error,
"Each element of the time-of-flight vector (tof) needs to have dimension 2 (lower and upper bound)");
80 pagmo_throw(value_error,
"The sequence must contain at least 2 planets");
84 for (std::vector<kep_toolbox::planet::planet_ptr>::size_type i = 0; i < seq.size(); ++i) {
85 m_seq.push_back(seq[i]->
clone());
94 for (std::vector<kep_toolbox::planet::planet_ptr>::size_type i = 0; i < (m_seq.size() - 1); ++i) {
95 lb[4*i] = - 2 * boost::math::constants::pi<double>(); ub[4*i] = 2 * boost::math::constants::pi<double>();
96 lb[4*i+1] = 1.1; ub[4*i+1] = 30;
97 lb[4*i+2] = 1e-5; ub[4*i+2] = 1-1e-5;
98 lb[4*i+3] = m_tof[i][0]; ub[4*i+3] = m_tof[i][1];
102 for (std::vector<kep_toolbox::planet::planet_ptr>::size_type i = 0; i < (m_seq.size() - 1); ++i) {
103 lb[4*i+1] = m_seq[i]->get_safe_radius() / m_seq[i]->get_radius();
104 ub[4*i+1] = (m_seq[i]->get_radius() + 2000000) / m_seq[i]->get_radius();
112 for (std::vector<kep_toolbox::planet::planet_ptr>::size_type i = 0; i < p.m_seq.size();++i) {
113 m_seq.push_back(p.m_seq[i]->clone());
129 double common_mu = m_seq[0]->get_mu_central_body();
131 std::vector<double> T(m_seq.size()-1,0.0);
133 for (
size_t i = 0; i < (m_seq.size()-1); ++i) {
137 std::vector<kep_toolbox::epoch> t_P(m_seq.size());
138 std::vector<kep_toolbox::array3D> r_P(m_seq.size());
139 std::vector<kep_toolbox::array3D> v_P(m_seq.size());
140 std::vector<double> DV(m_seq.size() - 1);
141 for (
size_t i = 0; i<m_seq.size(); ++i) {
142 t_P[i] = kep_toolbox::epoch(m_t0.mjd2000() + std::accumulate(T.begin(),T.begin()+i,0.0));
143 m_seq[i]->eph(t_P[i], r_P[i], v_P[i]);
147 kep_toolbox::array3D v_out,r,v;
148 kep_toolbox::array3D v_beg_l,v_end_l;
149 kep_toolbox::sum(v_end_l, m_vinf_in, v_P[0]);
150 for (
size_t i = 0; i<(m_seq.size()-1); ++i) {
152 kep_toolbox::fb_prop(v_out, v_end_l, v_P[i], x[4*i+1] * m_seq[i]->get_radius(), x[4*i], m_seq[i]->get_mu_self());
157 kep_toolbox::propagate_lagrangian(r,v,x[4*i+2]*T[i]*ASTRO_DAY2SEC,common_mu);
158 kep_toolbox::closest_distance(d, ra, r_P[i], v_out, r, v, common_mu);
161 double dt = (1-x[4*i+2])*T[i]*ASTRO_DAY2SEC;
162 kep_toolbox::lambert_problem l2(r,r_P[i+1],dt,common_mu,
false,
false);
163 v_end_l = l2.get_v2()[0];
164 v_beg_l = l2.get_v1()[0];
165 kep_toolbox::closest_distance(d2,ra2,r,v_beg_l, r_P[i+1], v_end_l, common_mu);
175 kep_toolbox::diff(v_out, v_beg_l, v);
177 DV[i] = kep_toolbox::norm(v_out) + std::max((2.0-d),0.0) * 1000.0;
180 f[0] = std::accumulate(DV.begin(),DV.end(),0.0);
183 f[0] = boost::numeric::bounds<double>::highest();
200 std::ostringstream s;
202 s << std::scientific;
206 double common_mu = m_seq[0]->get_mu_central_body();
208 std::vector<double> T(m_seq.size()-1,0.0);
210 for (
size_t i = 0; i<m_seq.size()-1; ++i) {
214 std::vector<kep_toolbox::epoch> t_P(m_seq.size());
215 std::vector<kep_toolbox::array3D> r_P(m_seq.size());
216 std::vector<kep_toolbox::array3D> v_P(m_seq.size());
217 std::vector<double> DV(m_seq.size() - 1);
218 for (
size_t i = 0; i<m_seq.size(); ++i) {
219 t_P[i] = kep_toolbox::epoch(m_t0.mjd2000() + std::accumulate(T.begin(),T.begin()+i,0.0));
220 m_seq[i]->eph(t_P[i], r_P[i], v_P[i]);
224 kep_toolbox::array3D v_out,r,v,mem_vin,mem_vout,mem_vP;
225 kep_toolbox::array3D v_beg_l,v_end_l;
226 kep_toolbox::sum(v_end_l, m_vinf_in, v_P[0]);
227 for (
size_t i = 0; i<m_seq.size()-1; ++i) {
229 kep_toolbox::fb_prop(v_out, v_end_l, v_P[i], x[4*i+1] * m_seq[i]->get_radius(), x[4*i], m_seq[i]->get_mu_self());
238 kep_toolbox::propagate_lagrangian(r,v,x[4*i+2]*T[i]*ASTRO_DAY2SEC,common_mu);
239 kep_toolbox::closest_distance(d, ra, r_P[i], v_out, r, v, common_mu);
242 double dt = (1-x[4*i+2])*T[i]*ASTRO_DAY2SEC;
243 kep_toolbox::lambert_problem l2(r,r_P[i+1],dt,common_mu,
false,
false);
244 v_end_l = l2.get_v2()[0];
245 v_beg_l = l2.get_v1()[0];
246 kep_toolbox::closest_distance(d2,ra2,r,v_beg_l, r_P[i+1], v_end_l, common_mu);
258 kep_toolbox::diff(v_out, v_beg_l, v);
259 DV[i] = kep_toolbox::norm(v_out);
260 s <<
"\nleg no. " << i+1 <<
": " << m_seq[i]->get_name() <<
" to " << m_seq[i+1]->get_name() << std::endl;
261 s <<
"\tDuration: (days)" << T[i] << std::endl;
262 s <<
"\tFly-by epoch: " << t_P[i] <<
" (" << t_P[i].mjd2000() <<
" mjd2000) " << std::endl;
263 s <<
"\tFly-by altitude (km): " << (x[4*i+1]*m_seq[i]->get_radius()-m_seq[i]->get_radius())/1000.0 << std::endl;
264 s <<
"\tPlanet position (m): " << r_P[i] << std::endl;
265 s <<
"\tPlanet velocity (m/s): " << mem_vP << std::endl;
266 s <<
"\tV in (m/s): " << mem_vin << std::endl;
267 s <<
"\tV out (m/s): " << mem_vout << std::endl << std::endl;
269 s <<
"\tDSM after (days): " << x[4*i+2]*T[i] << std::endl;
270 s <<
"\tDSM magnitude (m/s): " << DV[i] << std::endl;
271 s <<
"\tClosest distance (JR): " << d << std::endl;
272 s <<
"\tApoapsis at closest distance (JR): " << ra << std::endl;
276 s <<
"\nArrival at " << m_seq[m_seq.size()-1]->get_name() << std::endl;
277 kep_toolbox::diff(v_out, v_end_l, v_P[m_seq.size()-1]);
278 s <<
"Arrival epoch: " << t_P[m_seq.size()-1] <<
" (" << t_P[m_seq.size()-1].mjd2000() <<
" mjd2000) " << std::endl;
279 s <<
"Arrival Vinf (m/s): " << v_out <<
" - " << kep_toolbox::norm(v_out) << std::endl;
280 s <<
"Total mission time (days): " << std::accumulate(T.begin(),T.end(),0.0) << std::endl;
285 return "MGA-PART (a part of the jupiter moon tour)";
295 if (tof.size() != (m_seq.size()-1)) {
296 pagmo_throw(value_error,
"The time-of-flight vector (tof) has the wrong length");
299 for (
size_t i=0; i< (m_seq.size()-1); ++i) {
320 if (betas.size() != (m_seq.size()-1)) {
321 pagmo_throw(value_error,
"The betas vector (betas) has the wrong length");
323 for (
size_t i=0; i< (m_seq.size()-1); ++i) {
324 if (betas[i].size() !=2) {
325 pagmo_throw(value_error,
"Lower and upper bound vector needs to have dimension 2");
336 std::vector<std::vector<double> > retval;
337 std::vector<double> tmp(2);
338 for (
size_t i=0; i< (m_seq.size()-1); ++i) {
341 retval.push_back(tmp);
353 if (rps.size() != (m_seq.size()-1)) {
354 pagmo_throw(value_error,
"The periplanets vector (rps) has the wrong length");
356 for (
size_t i=0; i< (m_seq.size()-1); ++i) {
357 if (rps[i].size() !=2) {
358 pagmo_throw(value_error,
"Lower and upper bound vector needs to have dimension 2");
360 set_bounds(1+4*i,(rps[i][0]*1000+m_seq[i]->get_radius())/m_seq[i]->get_radius(),(rps[i][1]*1000+m_seq[i]->get_radius())/m_seq[i]->get_radius());
369 std::vector<std::vector<double> > retval;
370 std::vector<double> tmp(2);
371 for (
size_t i=0; i< (m_seq.size()-1); ++i) {
372 tmp[0] = ((
get_lb()[4*i+1]*m_seq[i]->get_radius())-m_seq[i]->get_radius())/1000.0;
373 tmp[1] = ((
get_ub()[4*i+1]*m_seq[i]->get_radius())-m_seq[i]->get_radius())/1000.0;
374 retval.push_back(tmp);
431 std::ostringstream oss;
432 oss <<
"\n\tSequence: ";
433 for (
size_t i = 0; i<m_seq.size() ;++i) {
434 oss << m_seq[i]->get_name() <<
" ";
436 oss <<
"\n\tTime of flights: ";
437 for (
size_t i=0; i<(m_seq.size()-1); ++i) {
438 oss << m_tof[i]<<
' ';
440 oss <<
"\n\tStarting epoch: " << m_t0;
441 oss <<
"\n\tStarting Vinf in: " << m_vinf_in << std::endl;
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base problem.
std::vector< double > decision_vector
Decision vector type.
mga_part(const std::vector< kep_toolbox::planet::planet_ptr >=construct_default_sequence(), const std::vector< std::vector< double > > tof=construct_default_tofs(), const kep_toolbox::epoch t0=kep_toolbox::epoch(11000), const kep_toolbox::array3D vinf_in=construct_default_v())
Constructor.
void objfun_impl(fitness_vector &, const decision_vector &) const
Implementation of the objective function.
const kep_toolbox::epoch & get_t0() const
Gets the start epoch.
std::vector< std::vector< double > > get_betas() const
Gets the betas.
base_ptr clone() const
Clone method.
void set_tof(const std::vector< std::vector< double > > &)
Sets the times of flight.
std::string human_readable_extra() const
Extra human readable info for the problem.
A part of the GTOC6 Jupiter Capture Trajectory.
std::string pretty(const std::vector< double > &x) const
Outputs a stream with the trajectory data.
std::string get_name() const
Get problem's name.
std::vector< kep_toolbox::planet::planet_ptr > get_sequence() const
Gets the planetary sequence defining the interplanetary mga-1dsm mission.
void set_t0(const kep_toolbox::epoch &)
Sets the start epoch.
const kep_toolbox::array3D & get_vinf_in() const
Gets the start velocity.
void set_vinf_in(const kep_toolbox::array3D &)
Sets the start velocity.
std::vector< double > fitness_vector
Fitness vector type.
void set_rps(const std::vector< std::vector< double > > &)
Sets the peri-planet bounds.
const decision_vector & get_ub() const
Upper bounds getter.
void set_betas(const std::vector< std::vector< double > > &)
Sets the betas.
const decision_vector & get_lb() const
Lower bounds getter.
void set_bounds(const decision_vector &, const decision_vector &)
Bounds setter from pagmo::decision_vector.
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.
const std::vector< std::vector< double > > & get_tof() const
Gets the times of flight.
std::vector< std::vector< double > > get_rps() const
Gets the peri-planet bounds.