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/lambert_problem.h>
34 #include "mga_1dsm_alpha.h"
37 namespace pagmo {
namespace problem {
59 const kep_toolbox::epoch t0_l,
const kep_toolbox::epoch t0_u,
60 const double tof_l,
const double tof_u,
61 const double vinf_l,
const double vinf_u,
62 const bool mo,
const bool add_vinf_dep,
const bool add_vinf_arr) :
63 base( 7 + (int)(seq.size()-2) * 4, 0, 1 + (int)mo,0,0,0.0), m_seq(), m_n_legs(seq.size()-1), m_add_vinf_dep(add_vinf_dep), m_add_vinf_arr(add_vinf_arr)
66 std::vector<double> mus(seq.size());
67 for (std::vector<kep_toolbox::planet::planet_ptr>::size_type i = 0; i< seq.size(); ++i) {
68 mus[i] = seq[i]->get_mu_central_body();
70 if ((
unsigned int)std::count(mus.begin(), mus.end(), mus[0]) != mus.size()) {
71 pagmo_throw(value_error,
"The planets do not all have the same mu_central_body");
74 for (std::vector<kep_toolbox::planet::planet_ptr>::size_type i = 0; i < seq.size(); ++i) {
75 m_seq.push_back(seq[i]->
clone());
83 lb[0] = t0_l.mjd2000(); ub[0] = t0_u.mjd2000();
84 lb[1] = tof_l; ub[1] = tof_u;
85 lb[2] = 0; lb[3] = 0; ub[2] = 1; ub[3] = 1;
86 lb[4] = vinf_l * 1000; ub[4] = vinf_u * 1000;
87 lb[5] = 1e-5; ub[5] = 1-1e-5;
88 lb[6] = 1e-5; ub[6] = 1-1e-5;
91 for (std::vector<kep_toolbox::planet::planet_ptr>::size_type i = 0; i < m_n_legs - 1; ++i) {
92 lb[7+4*i] = - 2 * boost::math::constants::pi<double>(); ub[7+4*i] = 2 * boost::math::constants::pi<double>();
93 lb[8+4*i] = 1.1; ub[8+4*i] = 100;
94 lb[9+4*i] = 1e-5; ub[9+4*i] = 1-1e-5;
95 lb[10+4*i] = 1e-5; ub[10+4*i] = 1-1e-5;
99 for (std::vector<kep_toolbox::planet::planet_ptr>::size_type i = 1; i < m_n_legs; ++i) {
100 lb[4 + 4*i] = m_seq[i]->get_safe_radius() / m_seq[i]->get_radius();
108 for (std::vector<kep_toolbox::planet::planet_ptr>::size_type i = 0; i < p.m_seq.size();++i) {
109 m_seq.push_back(p.m_seq[i]->clone());
124 double common_mu = m_seq[0]->get_mu_central_body();
126 std::vector<double> T(m_n_legs,0.0);
127 double alpha_sum = 0;
129 for (
size_t i = 0; i < m_n_legs; ++i) {
130 double tmp = -log(x[6+4*i]);
134 for (
size_t i = 0; i < m_n_legs; ++i) {
139 std::vector<kep_toolbox::epoch> t_P(m_n_legs + 1);
140 std::vector<kep_toolbox::array3D> r_P(m_n_legs + 1);
141 std::vector<kep_toolbox::array3D> v_P(m_n_legs + 1);
142 std::vector<double> DV(m_n_legs + 1);
143 for (
size_t i = 0; i<(m_n_legs + 1); ++i) {
144 t_P[i] = kep_toolbox::epoch(x[0] + std::accumulate(T.begin(), T.begin()+i, 0.0));
145 m_seq[i]->eph(t_P[i], r_P[i], v_P[i]);
149 double theta = 2*boost::math::constants::pi<double>()*x[2];
150 double phi = acos(2*x[3]-1)-boost::math::constants::pi<double>() / 2;
152 kep_toolbox::array3D Vinf = { {x[4]*cos(phi)*cos(theta), x[4]*cos(phi)*sin(theta), x[4]*sin(phi)} };
153 kep_toolbox::array3D v0;
154 kep_toolbox::sum(v0, v_P[0], Vinf);
155 kep_toolbox::array3D r(r_P[0]), v(v0);
156 kep_toolbox::propagate_lagrangian(r,v,x[5]*T[0]*ASTRO_DAY2SEC,common_mu);
159 double dt = (1-x[5])*T[0]*ASTRO_DAY2SEC;
160 kep_toolbox::lambert_problem l(r,r_P[1],dt,common_mu);
161 kep_toolbox::array3D v_end_l = l.get_v2()[0];
162 kep_toolbox::array3D v_beg_l = l.get_v1()[0];
165 kep_toolbox::diff(v, v_beg_l, v);
166 DV[0] = kep_toolbox::norm(v);
169 kep_toolbox::array3D v_out;
170 for (
size_t i = 1; i<m_n_legs; ++i) {
172 kep_toolbox::fb_prop(v_out, v_end_l, v_P[i], x[8+(i-1)*4] * m_seq[i]->get_radius(), x[7+(i-1)*4], m_seq[i]->get_mu_self());
176 kep_toolbox::propagate_lagrangian(r,v,x[9+(i-1)*4]*T[i]*ASTRO_DAY2SEC,common_mu);
179 dt = (1-x[9+(i-1)*4])*T[i]*ASTRO_DAY2SEC;
180 kep_toolbox::lambert_problem l2(r,r_P[i+1],dt,common_mu);
181 v_end_l = l2.get_v2()[0];
182 v_beg_l = l2.get_v1()[0];
185 kep_toolbox::diff(v, v_beg_l, v);
186 DV[i] = kep_toolbox::norm(v);
190 kep_toolbox::diff(v, v_end_l, v_P[m_n_legs]);
191 DV[m_n_legs] = kep_toolbox::norm(v);
195 f[0] = std::accumulate(DV.begin(),DV.end()-1,0.0);
196 if (m_add_vinf_dep) {
199 if (m_add_vinf_arr) {
200 f[0] += DV[DV.size()-1];
203 f[1] = std::accumulate(T.begin(),T.end(),0.0);
207 f[0] = boost::numeric::bounds<double>::highest();
209 f[1] = boost::numeric::bounds<double>::highest();
227 double common_mu = m_seq[0]->get_mu_central_body();
229 std::ostringstream s;
231 s << std::scientific;
234 std::vector<double> T(m_n_legs,0.0);
235 double alpha_sum = 0;
237 for (
size_t i = 0; i < m_n_legs; ++i) {
238 double tmp = -log(x[6+4*i]);
242 for (
size_t i = 0; i < m_n_legs; ++i) {
247 std::vector<kep_toolbox::epoch> t_P(m_n_legs + 1);
248 std::vector<kep_toolbox::array3D> r_P(m_n_legs + 1);
249 std::vector<kep_toolbox::array3D> v_P(m_n_legs + 1);
250 std::vector<double> DV(m_n_legs + 1);
251 for (
size_t i = 0; i<(m_n_legs + 1); ++i) {
252 t_P[i] = kep_toolbox::epoch(x[0] + std::accumulate(T.begin(), T.begin()+i, 0.0));
253 m_seq[i]->eph(t_P[i], r_P[i], v_P[i]);
257 s <<
"First Leg: " << m_seq[0]->get_name() <<
" to " << m_seq[1]->get_name() << std::endl;
258 s <<
"Departure: " << t_P[0] <<
" (" << t_P[0].mjd2000() <<
" mjd2000)" << std::endl;
259 s <<
"Duration: " << T[0] <<
" days" << std::endl;
260 s <<
"VINF: " << x[4] / 1000 <<
" km/sec" << std::endl;
261 s <<
"DSM after " << x[5]*T[0] <<
" days" << std::endl;
262 double theta = 2*boost::math::constants::pi<double>()*x[2];
263 double phi = acos(2*x[3]-1)-boost::math::constants::pi<double>() / 2;
265 kep_toolbox::array3D Vinf = { {x[4]*cos(phi)*cos(theta), x[4]*cos(phi)*sin(theta), x[4]*sin(phi)} };
267 kep_toolbox::array3D v0;
268 kep_toolbox::sum(v0, v_P[0], Vinf);
269 kep_toolbox::array3D r(r_P[0]), v(v0);
270 kep_toolbox::propagate_lagrangian(r,v,x[5]*T[0]*ASTRO_DAY2SEC,common_mu);
273 double dt = (1-x[5])*T[0]*ASTRO_DAY2SEC;
274 kep_toolbox::lambert_problem l(r,r_P[1],dt,common_mu);
275 kep_toolbox::array3D v_end_l = l.get_v2()[0];
276 kep_toolbox::array3D v_beg_l = l.get_v1()[0];
279 kep_toolbox::diff(v, v_beg_l, v);
280 DV[0] = kep_toolbox::norm(v);
281 s <<
"DSM magnitude: " << DV[0] <<
" m/s" << std::endl;
284 kep_toolbox::array3D v_out;
285 for (
size_t i = 1; i<m_n_legs; ++i) {
286 s <<
"\nleg no: " << i+1 <<
": " << m_seq[i]->get_name() <<
" to " << m_seq[i+1]->get_name() << std::endl;
287 s <<
"Duration: " << T[i] <<
" days" << std::endl;
288 s <<
"Fly-by epoch: " << t_P[i] <<
" (" << t_P[i].mjd2000() <<
" mjd2000) " << std::endl;
289 s <<
"Fly-by radius: " << x[8+(i-1)*4] <<
" planetary radii" << std::endl;
290 s <<
"DSM after " << x[9+(i-1)*4]*T[i] <<
" days" << std::endl;
292 kep_toolbox::fb_prop(v_out, v_end_l, v_P[i], x[8+(i-1)*4] * m_seq[i]->get_radius(), x[7+(i-1)*4], m_seq[i]->get_mu_self());
296 kep_toolbox::propagate_lagrangian(r,v,x[9+(i-1)*4]*T[i]*ASTRO_DAY2SEC,common_mu);
299 dt = (1-x[9+(i-1)*4])*T[i]*ASTRO_DAY2SEC;
300 kep_toolbox::lambert_problem l2(r,r_P[i+1],dt,common_mu);
301 v_end_l = l2.get_v2()[0];
302 v_beg_l = l2.get_v1()[0];
305 kep_toolbox::diff(v, v_beg_l, v);
306 DV[i] = kep_toolbox::norm(v);
307 s <<
"DSM magnitude: " << DV[i] <<
"m/s" << std::endl;
311 kep_toolbox::diff(v, v_end_l, v_P[m_n_legs]);
312 DV[m_n_legs] = kep_toolbox::norm(v);
313 s <<
"\nArrival at " << m_seq[m_n_legs]->get_name() << std::endl;
314 s <<
"Arrival epoch: " << t_P[m_n_legs] <<
" (" << t_P[m_n_legs].mjd2000() <<
" mjd2000) " << std::endl;
315 s <<
"Arrival Vinf: " << DV[m_n_legs] <<
"m/s" << std::endl;
316 s <<
"Total mission time: " << std::accumulate(T.begin(),T.end(),0.0)/365.25 <<
" years" << std::endl;
321 return "MGA-1DSM (alpha-encoding)";
361 std::vector<double> retval;
364 retval.push_back(lb[1]);
365 retval.push_back(ub[1]);
385 std::ostringstream oss;
386 oss <<
"\n\tSequence: ";
387 for (
size_t i = 0; i<m_seq.size() ;++i) {
388 oss << m_seq[i]->get_name() <<
" ";
390 oss <<
"\n\tAdd launcher vinf to the objective?: " << (m_add_vinf_dep?
" True":
" False") << std::endl;
391 oss <<
"\n\tAdd arrival vinf to the objective?: " << (m_add_vinf_arr?
" True":
" False") << std::endl;
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base problem.
std::vector< double > decision_vector
Decision vector type.
void set_launch_window(const kep_toolbox::epoch &, const kep_toolbox::epoch &)
Sets the mission launch window.
void set_tof(const double, const double)
Sets the mission time of flight.
void objfun_impl(fitness_vector &, const decision_vector &) const
Implementation of the objective function.
std::string pretty(const std::vector< double > &x) const
Outputs a stream with the trajectory data.
base_ptr clone() const
Clone method.
A generic MGA-1DSM Problem.
std::string get_name() const
Get problem's name.
void set_ub(const decision_vector &)
Set upper bounds from pagmo::decision_vector.
std::vector< double > fitness_vector
Fitness vector type.
const decision_vector & get_ub() const
Upper bounds getter.
mga_1dsm_alpha(const std::vector< kep_toolbox::planet::planet_ptr >=construct_default_sequence(), const kep_toolbox::epoch t0_l=kep_toolbox::epoch(0), const kep_toolbox::epoch t0_r=kep_toolbox::epoch(1000), const double tof_l=1.0 *365.25, const double tof_u=5.0 *365.25, const double vinf_l=0.5, const double vinf_u=2.5, const bool mo=false, const bool add_vinf_dep=false, const bool add_vinf_arr=true)
Constructor.
std::vector< double > get_tof() const
Gets the sequence of time of flights for the mga-1dsm mission.
f_size_type get_f_dimension() const
Return fitness dimension.
std::vector< kep_toolbox::planet::planet_ptr > get_sequence() const
Gets the planetary sequence defining the interplanetary mga-1dsm mission.
const decision_vector & get_lb() const
Lower bounds getter.
std::string human_readable_extra() const
Extra human readable info for the problem.
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.
void set_vinf(const double)
Sets the launch hyperbolic velocity.