26 #include "Astro_Functions.h"
29 #include "propagateKEP.h"
30 #include "time2distance.h"
35 const double MU[9] = {
49 const double RPL[6] = {
59 void vector_normalize(
const double in[3],
double out[3])
61 double norm = norm2(in);
62 for(
int i = 0; i < 3; i++) {
63 out[i] = in[i] / norm;
76 void get_celobj_r_and_v(
const mgadsmproblem& problem,
const double T,
const int i_count,
double* r,
double* v)
78 if (problem.sequence[i_count] < 10) {
79 Planet_Ephemerides_Analytical (T, problem.sequence[i_count],
82 Custom_Eph(T + 2451544.5, problem.asteroid.epoch, problem.asteroid.keplerian,
95 void precalculate_ers_and_vees(
const vector<double>& t,
const mgadsmproblem& problem, std::vector<double*>& r, std::vector<double*>& v)
99 for(
unsigned int i_count = 0; i_count < problem.sequence.size(); i_count++) {
100 get_celobj_r_and_v(problem, T, i_count, r[i_count], v[i_count]);
111 double get_celobj_mu(
const mgadsmproblem& problem,
const int i_count)
113 if (problem.sequence[i_count] < 10) {
114 return MU[problem.sequence[i_count]];
116 return problem.asteroid.mu;
129 void first_block(
const vector<double>& t,
const mgadsmproblem& problem,
const std::vector<double*>& r, std::vector<double*>& v, std::vector<double>& DV,
double v_sc_nextpl_in[3])
132 const int n = problem.sequence.size();
133 const double VINF = t[1];
134 const double udir = t[2];
135 const double vdir = t[3];
137 const double *tof = &t[4];
138 const double *alpha = &t[n+3];
144 cross(r[0], v[0], vtemp);
147 vector_normalize(vtemp, zP1);
150 vector_normalize(v[0], iP1);
153 cross(zP1, iP1, jP1);
156 theta = 2 * M_PI * udir;
157 phi = acos(2 * vdir - 1) - M_PI / 2;
160 for (i = 0; i < 3; i++)
161 vinf[i] = VINF * (cos(theta) * cos(phi) * iP1[i] + sin(theta) * cos(phi) * jP1[i] + sin(phi) * zP1[i]);
164 double v_sc_pl_out[3];
166 for (i = 0; i < 3; i++)
169 v_sc_pl_out[i] = v[0][i] + vinf[i];
173 double rd[3], v_sc_dsm_in[3];
175 propagateKEP(r[0], v_sc_pl_out, alpha[0] * tof[0] * 86400, MU[0],
180 vett(rd, r[1], Dum_Vec);
182 int lw = (Dum_Vec[2] > 0) ? 0 : 1;
186 double v_sc_dsm_out[3];
188 LambertI(rd, r[1], tof[0] * (1 - alpha[0]) * 86400, MU[0], lw,
189 v_sc_dsm_out, v_sc_nextpl_in, a, p, theta2, iter_unused);
192 for (i = 0; i < 3; i++)
194 Dum_Vec[i] = v_sc_dsm_out[i] - v_sc_dsm_in[i];
197 DV[0] = norm2(Dum_Vec);
203 double intermediate_block(
const vector<double>& t,
const mgadsmproblem& problem,
const std::vector<double*>& r,
const std::vector<double*>& v,
int i_count,
const double v_sc_pl_in[], std::vector<double>& DV,
double* v_sc_nextpl_in)
206 const int n = problem.sequence.size();
208 const double *tof = &t[4];
209 const double *alpha = &t[n+3];
210 const double *rp_non_dim = &t[2*n+2];
211 const double *gamma = &t[3*n];
212 const vector<int>& sequence = problem.sequence;
220 for (i = 0; i < 3; i++)
222 v_rel_in[i] = v_sc_pl_in[i] - v[i_count+1][i];
223 vrelin += v_rel_in[i] * v_rel_in[i];
227 double hopobj_mu = get_celobj_mu(problem, i_count + 1);
229 double e = 1.0 + rp_non_dim[i_count] * RPL[sequence[i_count + 1] - 1] * vrelin / hopobj_mu;
231 double beta_rot = 2 * asin(1 / e);
234 vector_normalize(v_rel_in, ix);
237 vector_normalize(v[i_count+1], vpervnorm);
240 vett(ix, vpervnorm, iy);
241 vector_normalize(iy, iy);
246 double v_rel_in_norm = norm2(v_rel_in);
248 double v_sc_pl_out[3];
250 for (i = 0; i < 3; i++)
252 double iVout = cos(beta_rot) * ix[i] + cos(gamma[i_count]) * sin(beta_rot) * iy[i] + sin(gamma[i_count]) * sin(beta_rot) * iz[i];
253 double v_rel_out = v_rel_in_norm * iVout;
254 v_sc_pl_out[i] = v[i_count + 1][i] + v_rel_out;
258 double rd[3], v_sc_dsm_in[3];
260 propagateKEP(r[i_count + 1], v_sc_pl_out, alpha[i_count+1] * tof[i_count+1] * 86400, MU[0],
265 vett(rd, r[i_count + 2], Dum_Vec);
267 int lw = (Dum_Vec[2] > 0) ? 0 : 1;
271 double v_sc_dsm_out[3];
273 LambertI(rd, r[i_count + 2], tof[i_count + 1] * (1 - alpha[i_count + 1]) * 86400, MU[0], lw,
274 v_sc_dsm_out, v_sc_nextpl_in, a, p, theta, iter_unused);
277 for (i = 0; i < 3; i++) {
278 Dum_Vec[i] = v_sc_dsm_out[i] - v_sc_dsm_in[i];
281 DV[i_count + 1] = norm2(Dum_Vec);
288 void final_block(
const mgadsmproblem& problem,
const std::vector<double*>& ,
const std::vector<double*>& v,
const double v_sc_pl_in[], std::vector<double>& DV)
291 const int n = problem.sequence.size();
292 const double rp_target = problem.rp;
293 const double e_target = problem.e;
294 const vector<int>& sequence = problem.sequence;
300 for (i = 0; i < 3; i++) {
301 Dum_Vec[i] = v[n-1][i] - v_sc_pl_in[i];
305 DVrel = norm2(Dum_Vec);
307 if ((problem.type == orbit_insertion) || (problem.type == total_DV_orbit_insertion)) {
308 double DVper = sqrt(DVrel * DVrel + 2 * MU[sequence[n - 1]] / rp_target);
309 double DVper2 = sqrt(2 * MU[sequence[n - 1]] / rp_target - MU[sequence[n - 1]] / rp_target * (1 - e_target));
310 DVarr = fabs(DVper - DVper2);
311 }
else if (problem.type == rndv){
313 }
else if (problem.type == total_DV_rndv){
325 const vector<double> &t,
326 const mgadsmproblem& problem,
333 const int n = problem.sequence.size();
338 std::vector<double*>& r = problem.r;
339 std::vector<double*>& v = problem.v;
341 std::vector<double>& DV = problem.DV;
343 precalculate_ers_and_vees(t, problem, r, v);
345 double inter_pl_in_v[3], inter_pl_out_v[3];
348 first_block(t, problem, r, v,
353 for (
int i_count=0; i_count < n - 2; i_count++) {
355 inter_pl_in_v[0] = inter_pl_out_v[0]; inter_pl_in_v[1] = inter_pl_out_v[1]; inter_pl_in_v[2] = inter_pl_out_v[2];
357 problem.vrelin_vec[i_count] = intermediate_block(t, problem, r, v, i_count, inter_pl_in_v,DV, inter_pl_out_v);
361 inter_pl_in_v[0] = inter_pl_out_v[0]; inter_pl_in_v[1] = inter_pl_out_v[1]; inter_pl_in_v[2] = inter_pl_out_v[2];
363 final_block(problem, r, v, inter_pl_in_v,
371 for (i = 0; i < n; i++) {
378 const double& VINF = t[1];
380 for (i = n; i > 0; i--) {
388 if (problem.type == orbit_insertion) {
390 }
else if (problem.type == total_DV_orbit_insertion) {
392 }
else if (problem.type == rndv) {
394 }
else if (problem.type == total_DV_rndv) {
396 }
else if (problem.type == time2AUs) {
398 const vector<int>& sequence = problem.sequence;
399 const double *rp_non_dim = &t[2*n+2];
400 const double *gamma = &t[3*n];
401 const double AUdist = problem.AUdist;
402 const double DVtotal = problem.DVtotal;
403 const double DVonboard = problem.DVonboard;
404 const double *tof = &t[4];
407 const double AU = 149597870.66;
408 const double V = sqrt(MU[0] / AU);
409 const double T = AU / V;
416 v_rel_in[i] = inter_pl_in_v[i] - v[n-1][i];
417 vrelin += v_rel_in[i] * v_rel_in[i];
420 double e = 1.0 + rp_non_dim[n - 2] * RPL[sequence[n - 2 + 1] - 1] * vrelin / get_celobj_mu(problem, n - 1);
422 double beta_rot=2*asin(1/e);
424 double vrelinn = norm2(v_rel_in);
427 ix[i] = v_rel_in[i]/vrelinn;
431 double vnorm = norm2(v[n-1]);
435 vtemp[i] = v[n-1][i]/vnorm;
440 double iynorm = norm2(iy);
442 iy[i] = iy[i]/iynorm;
446 double v_rel_in_norm = norm2(v_rel_in);
448 double v_sc_pl_out[3];
449 for (i = 0; i < 3; i++)
451 double iVout = cos(beta_rot) * ix[i] + cos(gamma[n - 2]) * sin(beta_rot) * iy[i] + sin(gamma[n - 2]) * sin(beta_rot) * iz[i];
452 double v_rel_out = v_rel_in_norm * iVout;
453 v_sc_pl_out[i] = v[n - 1][i] + v_rel_out;
457 double v_sc_pl_out_per_V[3];
458 for (i = 0; i < 3; i++)
460 r_per_AU[i] = r[n - 1][i] / AU;
461 v_sc_pl_out_per_V[i] = v_sc_pl_out[i] / V;
464 double time = time2distance(r_per_AU, v_sc_pl_out_per_V, AUdist);
472 for (i=0; i<n+1; i++)
476 DVpen += DVpen+(sum-DVtotal);
479 for (i=1; i<n+1; i++)
483 DVpen = DVpen + (sum - DVonboard);
486 for (i=0; i<n-1; i++)
489 J= (time*T/60/60/24 + sum)/365.25 + DVpen*100;