def _objfun_impl(self, x): # 1 - we 'decode' the chromosome recording the various times of flight # (days) in the list T and the cartesian components of vinf T, Vinfx, Vinfy, Vinfz = self._decode_times_and_vinf(x) # 2 - We compute the epochs and ephemerides of the planetary encounters t_P = list([None] * (self.__n_legs + 1)) r_P = list([None] * (self.__n_legs + 1)) v_P = list([None] * (self.__n_legs + 1)) DV = list([0.0] * (self.__n_legs + 1)) for i, planet in enumerate(self.seq): t_P[i] = epoch(x[0] + sum(T[0:i])) r_P[i], v_P[i] = self.seq[i].eph(t_P[i]) # 3 - We start with the first leg v0 = [a + b for a, b in zip(v_P[0], [Vinfx, Vinfy, Vinfz])] r, v = propagate_lagrangian(r_P[0], v0, x[5] * T[0] * DAY2SEC, self.common_mu) # Lambert arc to reach seq[1] dt = (1 - x[5]) * T[0] * DAY2SEC l = lambert_problem(r, r_P[1], dt, self.common_mu, False, False) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # First DSM occuring at time nu1*T1 DV[0] = norm([a - b for a, b in zip(v_beg_l, v)]) # 4 - And we proceed with each successive leg for i in range(1, self.__n_legs): # Fly-by v_out = fb_prop(v_end_l, v_P[i], x[8 + (i - 1) * 4] * self.seq[i].radius, x[7 + (i - 1) * 4], self.seq[i].mu_self) # s/c propagation before the DSM r, v = propagate_lagrangian(r_P[i], v_out, x[9 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu) # Lambert arc to reach Earth during (1-nu2)*T2 (second segment) dt = (1 - x[9 + (i - 1) * 4]) * T[i] * DAY2SEC l = lambert_problem(r, r_P[i + 1], dt, self.common_mu, False, False) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # DSM occuring at time nu2*T2 DV[i] = norm([a - b for a, b in zip(v_beg_l, v)]) # Last Delta-v if self.__add_vinf_arr: DV[-1] = norm([a - b for a, b in zip(v_end_l, v_P[-1])]) if self.__add_vinf_dep: DV[0] += x[3] if self.f_dimension == 1: return (sum(DV), ) else: return (sum(DV), sum(T))
def _objfun_impl(self, x): # 1 - we 'decode' the chromosome recording the various times of flight # (days) in the list T and the cartesian components of vinf T, Vinfx, Vinfy, Vinfz = self._decode_times_and_vinf(x) # 2 - We compute the epochs and ephemerides of the planetary encounters t_P = list([None] * (self.__n_legs + 1)) r_P = list([None] * (self.__n_legs + 1)) v_P = list([None] * (self.__n_legs + 1)) DV = list([0.0] * (self.__n_legs + 1)) for i, planet in enumerate(self.seq): t_P[i] = epoch(x[0] + sum(T[0:i])) r_P[i], v_P[i] = self.seq[i].eph(t_P[i]) # 3 - We start with the first leg v0 = [a + b for a, b in zip(v_P[0], [Vinfx, Vinfy, Vinfz])] r, v = propagate_lagrangian(r_P[0], v0, x[5] * T[0] * DAY2SEC, self.common_mu) # Lambert arc to reach seq[1] dt = (1 - x[5]) * T[0] * DAY2SEC l = lambert_problem(r, r_P[1], dt, self.common_mu, False, False) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # First DSM occuring at time nu1*T1 DV[0] = norm([a - b for a, b in zip(v_beg_l, v)]) # 4 - And we proceed with each successive leg for i in range(1, self.__n_legs): # Fly-by v_out = fb_prop(v_end_l, v_P[i], x[8 + (i - 1) * 4] * self.seq[i].radius, x[7 + (i - 1) * 4], self.seq[i].mu_self) # s/c propagation before the DSM r, v = propagate_lagrangian(r_P[i], v_out, x[9 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu) # Lambert arc to reach Earth during (1-nu2)*T2 (second segment) dt = (1 - x[9 + (i - 1) * 4]) * T[i] * DAY2SEC l = lambert_problem(r, r_P[i + 1], dt, self.common_mu, False, False) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # DSM occuring at time nu2*T2 DV[i] = norm([a - b for a, b in zip(v_beg_l, v)]) # Last Delta-v if self.__add_vinf_arr: DV[-1] = norm([a - b for a, b in zip(v_end_l, v_P[-1])]) if self.__add_vinf_dep: DV[0] += x[3] if self.f_dimension == 1: return (sum(DV),) else: return (sum(DV), sum(T))
def plot_orbits(self, pop, ax=None): import matplotlib.pylab as plt from mpl_toolkits.mplot3d import Axes3D A1, A2 = self._ast1, self._ast2 if ax is None: fig = plt.figure() axis = fig.add_subplot(111, projection='3d') else: axis = ax plot_planet(A1, ax=axis, s=10, t0=epoch(self.lb[0])) plot_planet(A2, ax=axis, s=10, t0=epoch(self.ub[0])) for ind in pop: if ind.cur_f[0] == self._UNFEASIBLE: continue dep, arr = ind.cur_x rdep, vdep = A1.eph(epoch(dep)) rarr, varr = A2.eph(epoch(arr)) l = lambert_problem(rdep, rarr, (arr - dep) * DAY2SEC, A1.mu_central_body, False, 1) axis = plot_lambert(l, ax=axis, alpha=0.8, color='k') if ax is None: plt.show() return axis
def _objfun_impl(self, x): from math import sqrt # 1 - We check that the transfer time is positive if x[0] >= x[1]: if self.f_dimension == 1: return (self._UNFEASIBLE, ) else: return (self._UNFEASIBLE, self._UNFEASIBLE) # 2 - We compute the asteroid positions r1, v1 = self._ast1.eph(x[0]) r2, v2 = self._ast2.eph(x[1]) # 3 - We compute Lambert arc l = lambert_problem(r1, r2, (x[1] - x[0]) * DAY2SEC, self._ast1.mu_central_body, False, 0) # 4 - We compute the two impulses v1l = l.get_v1()[0] v2l = l.get_v2()[0] DV1 = [a - b for a, b in zip(v1, v1l)] DV2 = [a - b for a, b in zip(v2, v2l)] a1, a2, tau, dv = damon(DV1, DV2, (x[1] - x[0]) * DAY2SEC) Isp = self._Isp g0 = 9.80665 Tmax = self._Tmax ms = self._ms MIMA = 2 * Tmax / norm(a1) / (1. + exp(-norm(a1) * (x[1] - x[0]) * DAY2SEC / Isp / g0)) DV1 = sum([l * l for l in DV1]) DV2 = sum([l * l for l in DV2]) totDV = sqrt(DV1) + sqrt(DV2) totDT = x[1] - x[0] if ms > MIMA: if self.f_dimension == 1: return (self._UNFEASIBLE, ) else: return (self._UNFEASIBLE, self._UNFEASIBLE) if self.f_dimension == 1: return (totDV, ) else: return (totDV, x[1])
def _objfun_impl(self, x): # 1 - we 'decode' the chromosome recording the various deep space # manouvres timing (days) in the list T T = list([0] * (self.N_max - 1)) for i in range(len(T)): T[i] = log(x[2 + 4 * i]) total = sum(T) T = [x[1] * time / total for time in T] # 2 - We compute the starting and ending position r_start, v_start = self.start.eph(epoch(x[0])) if self.phase_free: r_target, v_target = self.target.eph(epoch(x[-1])) else: r_target, v_target = self.target.eph(epoch(x[0] + x[1])) # 3 - We loop across inner impulses rsc = r_start vsc = v_start for i, time in enumerate(T[:-1]): theta = 2 * pi * x[3 + 4 * i] phi = acos(2 * x[4 + 4 * i] - 1) - pi / 2 Vinfx = x[5 + 4 * i] * cos(phi) * cos(theta) Vinfy = x[5 + 4 * i] * cos(phi) * sin(theta) Vinfz = x[5 + 4 * i] * sin(phi) # We apply the (i+1)-th impulse vsc = [a + b for a, b in zip(vsc, [Vinfx, Vinfy, Vinfz])] rsc, vsc = propagate_lagrangian( rsc, vsc, T[i] * DAY2SEC, self.__common_mu) cw = (ic2par(rsc, vsc, self.start.mu_central_body)[2] > pi / 2) # We now compute the remaining two final impulses # Lambert arc to reach seq[1] dt = T[-1] * DAY2SEC l = lambert_problem(rsc, r_target, dt, self.__common_mu, cw, False) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] DV1 = norm([a - b for a, b in zip(v_beg_l, vsc)]) DV2 = norm([a - b for a, b in zip(v_end_l, v_target)]) DV_others = sum(x[5::4]) if self.f_dimension == 1: return (DV1 + DV2 + DV_others,) else: return (DV1 + DV2 + DV_others, x[1])
def _objfun_impl(self, x): # 1 - we 'decode' the chromosome recording the various deep space # manouvres timing (days) in the list T T = list([0] * (self.N_max - 1)) for i in range(len(T)): T[i] = log(x[2 + 4 * i]) total = sum(T) T = [x[1] * time / total for time in T] # 2 - We compute the starting and ending position r_start, v_start = self.start.eph(epoch(x[0])) if self.phase_free: r_target, v_target = self.target.eph(epoch(x[-1])) else: r_target, v_target = self.target.eph(epoch(x[0] + x[1])) # 3 - We loop across inner impulses rsc = r_start vsc = v_start for i, time in enumerate(T[:-1]): theta = 2 * pi * x[3 + 4 * i] phi = acos(2 * x[4 + 4 * i] - 1) - pi / 2 Vinfx = x[5 + 4 * i] * cos(phi) * cos(theta) Vinfy = x[5 + 4 * i] * cos(phi) * sin(theta) Vinfz = x[5 + 4 * i] * sin(phi) # We apply the (i+1)-th impulse vsc = [a + b for a, b in zip(vsc, [Vinfx, Vinfy, Vinfz])] rsc, vsc = propagate_lagrangian(rsc, vsc, T[i] * DAY2SEC, self.__common_mu) cw = (ic2par(rsc, vsc, self.start.mu_central_body)[2] > pi / 2) # We now compute the remaining two final impulses # Lambert arc to reach seq[1] dt = T[-1] * DAY2SEC l = lambert_problem(rsc, r_target, dt, self.__common_mu, cw, False) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] DV1 = norm([a - b for a, b in zip(v_beg_l, vsc)]) DV2 = norm([a - b for a, b in zip(v_end_l, v_target)]) DV_others = sum(x[5::4]) if self.f_dimension == 1: return (DV1 + DV2 + DV_others, ) else: return (DV1 + DV2 + DV_others, x[1])
def _objfun_impl(self, x): from math import sqrt # 1 - We check that the transfer time is positive if x[0] >= x[1]: if self.f_dimension == 1: return (self._UNFEASIBLE, ) else: return (self._UNFEASIBLE, self._UNFEASIBLE) # 2 - We compute the asteroid positions r1, v1 = self._ast1.eph(x[0]) r2, v2 = self._ast2.eph(x[1]) # 3 - We compute Lambert arc l = lambert_problem(r1, r2, (x[1] - x[0]) * DAY2SEC, self._ast1.mu_central_body, False, 0) # 4 - We compute the two impulses v1l = l.get_v1()[0] v2l = l.get_v2()[0] DV1 = [a - b for a, b in zip(v1, v1l)] DV2 = [a - b for a, b in zip(v2, v2l)] a1, a2, tau, dv = damon(DV1, DV2, (x[1] - x[0]) * DAY2SEC) Isp = self._Isp g0 = 9.80665 Tmax = self._Tmax ms = self._ms MIMA = 2 * Tmax / norm(a1) / (1. + exp(-norm(a1) * (x[1] - x[0]) * DAY2SEC / Isp / g0) ) DV1 = sum([l * l for l in DV1]) DV2 = sum([l * l for l in DV2]) totDV = sqrt(DV1) + sqrt(DV2) totDT = x[1] - x[0] if ms > MIMA: if self.f_dimension == 1: return (self._UNFEASIBLE, ) else: return (self._UNFEASIBLE, self._UNFEASIBLE) if self.f_dimension == 1: return (totDV, ) else: return (totDV, x[1])
def _objfun_impl(self, x): from math import sqrt # 1 - We check that the transfer time is positive if x[0] >= x[1]: if self.f_dimension == 1: return (self._UNFEASIBLE, ) else: return (self._UNFEASIBLE, self._UNFEASIBLE) # 2 - We compute the asteroid positions r1, v1 = self._ast1.eph(x[0]) r2, v2 = self._ast2.eph(x[1]) # 3 - We compute Lambert arc l = lambert_problem(r1, r2, (x[1] - x[0]) * DAY2SEC, self._ast1.mu_central_body, False, 0) # 4 - We compute the two impulses v1l = l.get_v1()[0] v2l = l.get_v2()[0] DV1 = [a - b for a, b in zip(v1, v1l)] DV2 = [a - b for a, b in zip(v2, v2l)] DV1 = sum([l * l for l in DV1]) DV2 = sum([l * l for l in DV2]) totDV = sqrt(DV1) + sqrt(DV2) totDT = x[1] - x[0] if totDV >= self._max_acc * totDT * DAY2SEC: if self.f_dimension == 1: return (self._UNFEASIBLE, ) else: return (self._UNFEASIBLE, self._UNFEASIBLE) if self.f_dimension == 1: return (totDV, ) else: return (totDV, x[1])
def plot(self, x, ax=None): """ ax = prob.plot(x, ax=None) - x: encoded trajectory - ax: matplotlib axis where to plot. If None figure and axis will be created - [out] ax: matplotlib axis where to plot Plots the trajectory represented by a decision vector x on the 3d axis ax Example:: ax = prob.plot(x) """ import matplotlib as mpl from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt from PyKEP.orbit_plots import plot_planet, plot_lambert, plot_kepler if ax is None: mpl.rcParams['legend.fontsize'] = 10 fig = plt.figure() axis = fig.gca(projection='3d') else: axis = ax axis.scatter(0, 0, 0, color='y') # 1 - we 'decode' the chromosome recording the various times of flight # (days) in the list T and the cartesian components of vinf T, Vinfx, Vinfy, Vinfz = self._decode_times_and_vinf(x) # 2 - We compute the epochs and ephemerides of the planetary encounters t_P = list([None] * (self.__n_legs + 1)) r_P = list([None] * (self.__n_legs + 1)) v_P = list([None] * (self.__n_legs + 1)) DV = list([None] * (self.__n_legs + 1)) for i, planet in enumerate(self.seq): t_P[i] = epoch(x[0] + sum(T[0:i])) r_P[i], v_P[i] = planet.eph(t_P[i]) plot_planet(planet, t0=t_P[i], color=(0.8, 0.6, 0.8), legend=True, units = AU, ax=axis) # 3 - We start with the first leg v0 = [a + b for a, b in zip(v_P[0], [Vinfx, Vinfy, Vinfz])] r, v = propagate_lagrangian(r_P[0], v0, x[5] * T[0] * DAY2SEC, self.common_mu) plot_kepler(r_P[0], v0, x[5] * T[0] * DAY2SEC, self.common_mu, N=100, color='b', legend=False, units=AU, ax=axis) # Lambert arc to reach seq[1] dt = (1 - x[5]) * T[0] * DAY2SEC l = lambert_problem(r, r_P[1], dt, self.common_mu, False, False) plot_lambert(l, sol=0, color='r', legend=False, units=AU, ax=axis) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # First DSM occuring at time nu1*T1 DV[0] = norm([a - b for a, b in zip(v_beg_l, v)]) # 4 - And we proceed with each successive leg for i in range(1, self.__n_legs): # Fly-by v_out = fb_prop(v_end_l, v_P[i], x[8 + (i - 1) * 4] * self.seq[i].radius, x[7 + (i - 1) * 4], self.seq[i].mu_self) # s/c propagation before the DSM r, v = propagate_lagrangian(r_P[i], v_out, x[9 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu) plot_kepler(r_P[i], v_out, x[9 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu, N=100, color='b', legend=False, units=AU, ax=axis) # Lambert arc to reach Earth during (1-nu2)*T2 (second segment) dt = (1 - x[9 + (i - 1) * 4]) * T[i] * DAY2SEC l = lambert_problem(r, r_P[i + 1], dt, self.common_mu, False, False) plot_lambert(l, sol=0, color='r', legend=False, units=AU, N=1000, ax=axis) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # DSM occuring at time nu2*T2 DV[i] = norm([a - b for a, b in zip(v_beg_l, v)]) plt.show() return axis
def calc_objective(self, x, should_print=False): # 1 - we 'decode' the chromosome recording the various times of flight # (days) in the list T and the cartesian components of vinf T, Vinfx, Vinfy, Vinfz = self._decode_times_and_vinf(x) Vinf = [Vinfx, Vinfy, Vinfz] # 2 - We compute the epochs and ephemerides of the planetary encounters t_P = list([None] * (self.n_legs + 1)) r_P = list([None] * (self.n_legs + 1)) v_P = list([None] * (self.n_legs + 1)) DV = list([0.0] * (self.n_legs + 1)) for i, planet in enumerate(self.seq): t_P[i] = epoch(x[0] + sum(T[0:i])) r_P[i], v_P[i] = self.seq[i].eph(t_P[i]) if should_print: self.print_time_info(self.seq, t_P) if self.__add_vinf_dep: DV[0] += self.burn_cost(self.seq[0], Vinf) if should_print: self.print_escape(self.seq[0], v_P[0], r_P[0], Vinf, t_P[0].mjd) # 3 - We start with the first leg v0 = [a + b for a, b in zip(v_P[0], Vinf)] r, v = propagate_lagrangian(r_P[0], v0, x[5] * T[0] * DAY2SEC, self.common_mu) # Lambert arc to reach seq[1] dt = (1 - x[5]) * T[0] * DAY2SEC l = lambert_problem(r, r_P[1], dt, self.common_mu, False, False) v_beg_l = l.get_v1()[0] v_end_l = l.get_v2()[0] # First DSM occuring at time nu1*T1 deltaV = [a - b for a, b in zip(v_beg_l, v)] DV[0] += norm(deltaV) if should_print: self.print_dsm(v, r, deltaV, v_beg_l, t_P[0].mjd + dt / DAY2SEC) # 4 - And we proceed with each successive leg for i in range(1, self.n_legs): # Fly-by radius = x[8 + (i - 1) * 4] * self.seq[i].radius beta = x[7 + (i - 1) * 4] v_out = fb_prop(v_end_l, v_P[i], radius, beta, self.seq[i].mu_self) if should_print: v_rel_in = [a - b for a, b in zip(v_end_l, v_P[i])] v_rel_out = [a - b for a, b in zip(v_out, v_P[i])] self.print_flyby(self.seq[i], v_P[i], r_P[i], v_rel_in, v_rel_out, t_P[i].mjd) # s/c propagation before the DSM r, v = propagate_lagrangian(r_P[i], v_out, x[9 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu) # Lambert arc to reach Earth during (1-nu2)*T2 (second segment) dt = (1 - x[9 + (i - 1) * 4]) * T[i] * DAY2SEC l = lambert_problem(r, r_P[i + 1], dt, self.common_mu, False, False) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # DSM occuring at time nu2*T2 deltaV = [a - b for a, b in zip(v_beg_l, v)] DV[i] = norm(deltaV) if should_print: self.print_dsm(v, r, deltaV, v_beg_l, t_P[i].mjd + dt / DAY2SEC) # Last Delta-v if self.__add_vinf_arr: Vexc_arr = [a - b for a, b in zip(v_end_l, v_P[-1])] DV[-1] = self.burn_cost(self.seq[-1], Vexc_arr) if should_print: self.print_arrival(self.seq[-1], Vexc_arr, t_P[-1].mjd) fuelCost = sum(DV) if should_print: print("Total fuel cost: %10.3f m/s" % round(fuelCost, 3)) if self.f_dimension == 1: return (fuelCost, ) else: return (fuelCost, sum(T))
def plot(self, x, ax=None): """ ax = prob.plot(x, ax=None) - x: encoded trajectory - ax: matplotlib axis where to plot. If None figure and axis will be created - [out] ax: matplotlib axis where to plot Plots the trajectory represented by a decision vector x on the 3d axis ax Example:: ax = prob.plot(x) """ import matplotlib as mpl from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt from PyKEP.orbit_plots import plot_planet, plot_lambert, plot_kepler if ax is None: mpl.rcParams['legend.fontsize'] = 10 fig = plt.figure() axis = fig.gca(projection='3d') else: axis = ax axis.scatter(0, 0, 0, color='y') # 1 - we 'decode' the chromosome recording the various deep space # manouvres timing (days) in the list T T = list([0] * (self.N_max - 1)) for i in range(len(T)): T[i] = log(x[2 + 4 * i]) total = sum(T) T = [x[1] * time / total for time in T] # 2 - We compute the starting and ending position r_start, v_start = self.start.eph(epoch(x[0])) if self.phase_free: r_target, v_target = self.target.eph(epoch(x[-1])) else: r_target, v_target = self.target.eph(epoch(x[0] + x[1])) plot_planet(self.start, t0=epoch(x[0]), color=(0.8, 0.6, 0.8), legend=True, units = AU, ax=axis) plot_planet(self.target, t0=epoch(x[0] + x[1]), color=(0.8, 0.6, 0.8), legend=True, units = AU, ax=axis) # 3 - We loop across inner impulses rsc = r_start vsc = v_start for i, time in enumerate(T[:-1]): theta = 2 * pi * x[3 + 4 * i] phi = acos(2 * x[4 + 4 * i] - 1) - pi / 2 Vinfx = x[5 + 4 * i] * cos(phi) * cos(theta) Vinfy = x[5 + 4 * i] * cos(phi) * sin(theta) Vinfz = x[5 + 4 * i] * sin(phi) # We apply the (i+1)-th impulse vsc = [a + b for a, b in zip(vsc, [Vinfx, Vinfy, Vinfz])] plot_kepler(rsc, vsc, T[ i] * DAY2SEC, self.__common_mu, N=200, color='b', legend=False, units=AU, ax=axis) rsc, vsc = propagate_lagrangian( rsc, vsc, T[i] * DAY2SEC, self.__common_mu) cw = (ic2par(rsc, vsc, self.start.mu_central_body)[2] > pi / 2) # We now compute the remaining two final impulses # Lambert arc to reach seq[1] dt = T[-1] * DAY2SEC l = lambert_problem(rsc, r_target, dt, self.__common_mu, cw, False) plot_lambert( l, sol=0, color='r', legend=False, units=AU, ax=axis, N=200) plt.show() return axis
def plot(self, x, ax=None): """ ax = prob.plot(x, ax=None) - x: encoded trajectory - ax: matplotlib axis where to plot. If None figure and axis will be created - [out] ax: matplotlib axis where to plot Plots the trajectory represented by a decision vector x on the 3d axis ax Example:: ax = prob.plot(x) """ import matplotlib as mpl from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt from PyKEP.orbit_plots import plot_planet, plot_lambert, plot_kepler if ax is None: mpl.rcParams['legend.fontsize'] = 10 fig = plt.figure() axis = fig.gca(projection='3d') else: axis = ax axis.scatter(0, 0, 0, color='y') # 1 - we 'decode' the chromosome recording the various deep space # manouvres timing (days) in the list T T = list([0] * (self.N_max - 1)) for i in range(len(T)): T[i] = log(x[2 + 4 * i]) total = sum(T) T = [x[1] * time / total for time in T] # 2 - We compute the starting and ending position r_start, v_start = self.start.eph(epoch(x[0])) if self.phase_free: r_target, v_target = self.target.eph(epoch(x[-1])) else: r_target, v_target = self.target.eph(epoch(x[0] + x[1])) plot_planet(self.start, t0=epoch(x[0]), color=(0.8, 0.6, 0.8), legend=True, units=AU, ax=axis) plot_planet(self.target, t0=epoch(x[0] + x[1]), color=(0.8, 0.6, 0.8), legend=True, units=AU, ax=axis) # 3 - We loop across inner impulses rsc = r_start vsc = v_start for i, time in enumerate(T[:-1]): theta = 2 * pi * x[3 + 4 * i] phi = acos(2 * x[4 + 4 * i] - 1) - pi / 2 Vinfx = x[5 + 4 * i] * cos(phi) * cos(theta) Vinfy = x[5 + 4 * i] * cos(phi) * sin(theta) Vinfz = x[5 + 4 * i] * sin(phi) # We apply the (i+1)-th impulse vsc = [a + b for a, b in zip(vsc, [Vinfx, Vinfy, Vinfz])] plot_kepler(rsc, vsc, T[i] * DAY2SEC, self.__common_mu, N=200, color='b', legend=False, units=AU, ax=axis) rsc, vsc = propagate_lagrangian(rsc, vsc, T[i] * DAY2SEC, self.__common_mu) cw = (ic2par(rsc, vsc, self.start.mu_central_body)[2] > pi / 2) # We now compute the remaining two final impulses # Lambert arc to reach seq[1] dt = T[-1] * DAY2SEC l = lambert_problem(rsc, r_target, dt, self.__common_mu, cw, False) plot_lambert(l, sol=0, color='r', legend=False, units=AU, ax=axis, N=200) plt.show() return axis
def pretty(self, x): """ prob.plot(x) - x: encoded trajectory Prints human readable information on the trajectory represented by the decision vector x Example:: print(prob.pretty(x)) """ # 1 - we 'decode' the chromosome recording the various times of flight # (days) in the list T and the cartesian components of vinf T, Vinfx, Vinfy, Vinfz = self._decode_times_and_vinf(x) # 2 - We compute the epochs and ephemerides of the planetary encounters t_P = list([None] * (self.__n_legs + 1)) r_P = list([None] * (self.__n_legs + 1)) v_P = list([None] * (self.__n_legs + 1)) DV = list([None] * (self.__n_legs + 1)) for i, planet in enumerate(self.seq): t_P[i] = epoch(x[0] + sum(T[0:i])) r_P[i], v_P[i] = self.seq[i].eph(t_P[i]) # 3 - We start with the first leg print("First Leg: " + self.seq[0].name + " to " + self.seq[1].name) print("Departure: " + str(t_P[0]) + " (" + str(t_P[0].mjd2000) + " mjd2000) ") print("Duration: " + str(T[0]) + "days") print("VINF: " + str(x[4] / 1000) + " km/sec") v0 = [a + b for a, b in zip(v_P[0], [Vinfx, Vinfy, Vinfz])] r, v = propagate_lagrangian(r_P[0], v0, x[5] * T[0] * DAY2SEC, self.common_mu) print("DSM after " + str(x[5] * T[0]) + " days") # Lambert arc to reach seq[1] dt = (1 - x[5]) * T[0] * DAY2SEC l = lambert_problem(r, r_P[1], dt, self.common_mu, False, False) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # First DSM occuring at time nu1*T1 DV[0] = norm([a - b for a, b in zip(v_beg_l, v)]) print("DSM magnitude: " + str(DV[0]) + "m/s") # 4 - And we proceed with each successive leg for i in range(1, self.__n_legs): print("\nleg no. " + str(i + 1) + ": " + self.seq[i].name + " to " + self.seq[i + 1].name) print("Duration: " + str(T[i]) + "days") # Fly-by v_out = fb_prop(v_end_l, v_P[i], x[8 + (i - 1) * 4] * self.seq[i].radius, x[7 + (i - 1) * 4], self.seq[i].mu_self) print("Fly-by epoch: " + str(t_P[i]) + " (" + str(t_P[i].mjd2000) + " mjd2000) ") print("Fly-by radius: " + str(x[8 + (i - 1) * 4]) + " planetary radii") # s/c propagation before the DSM r, v = propagate_lagrangian(r_P[i], v_out, x[9 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu) print("DSM after " + str(x[9 + (i - 1) * 4] * T[i]) + " days") # Lambert arc to reach Earth during (1-nu2)*T2 (second segment) dt = (1 - x[9 + (i - 1) * 4]) * T[i] * DAY2SEC l = lambert_problem(r, r_P[i + 1], dt, self.common_mu, False, False) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # DSM occuring at time nu2*T2 DV[i] = norm([a - b for a, b in zip(v_beg_l, v)]) print("DSM magnitude: " + str(DV[i]) + "m/s") # Last Delta-v print("\nArrival at " + self.seq[-1].name) DV[-1] = norm([a - b for a, b in zip(v_end_l, v_P[-1])]) print("Arrival epoch: " + str(t_P[-1]) + " (" + str(t_P[-1].mjd2000) + " mjd2000) ") print("Arrival Vinf: " + str(DV[-1]) + "m/s") print("Total mission time: " + str(sum(T) / 365.25) + " years")
def pretty(self, x): """ prob.plot(x) - x: encoded trajectory Prints human readable information on the trajectory represented by the decision vector x Example:: print(prob.pretty(x)) """ # 1 - we 'decode' the chromosome recording the various times of flight # (days) in the list T and the cartesian components of vinf T, Vinfx, Vinfy, Vinfz = self._decode_times_and_vinf(x) # 2 - We compute the epochs and ephemerides of the planetary encounters t_P = list([None] * (self.__n_legs + 1)) r_P = list([None] * (self.__n_legs + 1)) v_P = list([None] * (self.__n_legs + 1)) DV = list([None] * (self.__n_legs + 1)) for i, planet in enumerate(self.seq): t_P[i] = epoch(x[0] + sum(T[0:i])) r_P[i], v_P[i] = self.seq[i].eph(t_P[i]) # 3 - We start with the first leg print("First Leg: " + self.seq[0].name + " to " + self.seq[1].name) print("Departure: " + str(t_P[0]) + " (" + str(t_P[0].mjd2000) + " mjd2000) ") print("Duration: " + str(T[0]) + "days") print("VINF: " + str(x[4] / 1000) + " km/sec") v0 = [a + b for a, b in zip(v_P[0], [Vinfx, Vinfy, Vinfz])] r, v = propagate_lagrangian(r_P[0], v0, x[5] * T[0] * DAY2SEC, self.common_mu) print("DSM after " + str(x[5] * T[0]) + " days") # Lambert arc to reach seq[1] dt = (1 - x[5]) * T[0] * DAY2SEC l = lambert_problem(r, r_P[1], dt, self.common_mu, False, False) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # First DSM occuring at time nu1*T1 DV[0] = norm([a - b for a, b in zip(v_beg_l, v)]) print("DSM magnitude: " + str(DV[0]) + "m/s") # 4 - And we proceed with each successive leg for i in range(1, self.__n_legs): print("\nleg no. " + str(i + 1) + ": " + self.seq[i].name + " to " + self.seq[i + 1].name) print("Duration: " + str(T[i]) + "days") # Fly-by v_out = fb_prop(v_end_l, v_P[i], x[8 + (i - 1) * 4] * self.seq[i].radius, x[7 + (i - 1) * 4], self.seq[i].mu_self) print( "Fly-by epoch: " + str(t_P[i]) + " (" + str(t_P[i].mjd2000) + " mjd2000) ") print( "Fly-by radius: " + str(x[8 + (i - 1) * 4]) + " planetary radii") # s/c propagation before the DSM r, v = propagate_lagrangian(r_P[i], v_out, x[9 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu) print("DSM after " + str(x[9 + (i - 1) * 4] * T[i]) + " days") # Lambert arc to reach Earth during (1-nu2)*T2 (second segment) dt = (1 - x[9 + (i - 1) * 4]) * T[i] * DAY2SEC l = lambert_problem(r, r_P[i + 1], dt, self.common_mu, False, False) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # DSM occuring at time nu2*T2 DV[i] = norm([a - b for a, b in zip(v_beg_l, v)]) print("DSM magnitude: " + str(DV[i]) + "m/s") # Last Delta-v print("\nArrival at " + self.seq[-1].name) DV[-1] = norm([a - b for a, b in zip(v_end_l, v_P[-1])]) print( "Arrival epoch: " + str(t_P[-1]) + " (" + str(t_P[-1].mjd2000) + " mjd2000) ") print("Arrival Vinf: " + str(DV[-1]) + "m/s") print("Total mission time: " + str(sum(T) / 365.25) + " years")
def plot(self, x, ax=None): """ ax = prob.plot(x, ax=None) - x: encoded trajectory - ax: matplotlib axis where to plot. If None figure and axis will be created - [out] ax: matplotlib axis where to plot Plots the trajectory represented by a decision vector x on the 3d axis ax Example:: ax = prob.plot(x) """ import matplotlib as mpl from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt from PyKEP.orbit_plots import plot_planet, plot_lambert, plot_kepler if ax is None: mpl.rcParams['legend.fontsize'] = 10 fig = plt.figure() axis = fig.gca(projection='3d') else: axis = ax axis.scatter(0, 0, 0, color='y') # 1 - we 'decode' the chromosome recording the various times of flight # (days) in the list T and the cartesian components of vinf T, Vinfx, Vinfy, Vinfz = self._decode_times_and_vinf(x) # 2 - We compute the epochs and ephemerides of the planetary encounters t_P = list([None] * (self.__n_legs + 1)) r_P = list([None] * (self.__n_legs + 1)) v_P = list([None] * (self.__n_legs + 1)) DV = list([None] * (self.__n_legs + 1)) for i, planet in enumerate(self.seq): t_P[i] = epoch(x[0] + sum(T[0:i])) r_P[i], v_P[i] = planet.eph(t_P[i]) plot_planet(planet, t0=t_P[i], color=(0.8, 0.6, 0.8), legend=True, units=AU, ax=axis) # 3 - We start with the first leg v0 = [a + b for a, b in zip(v_P[0], [Vinfx, Vinfy, Vinfz])] r, v = propagate_lagrangian(r_P[0], v0, x[5] * T[0] * DAY2SEC, self.common_mu) plot_kepler(r_P[0], v0, x[5] * T[0] * DAY2SEC, self.common_mu, N=100, color='b', legend=False, units=AU, ax=axis) # Lambert arc to reach seq[1] dt = (1 - x[5]) * T[0] * DAY2SEC l = lambert_problem(r, r_P[1], dt, self.common_mu, False, False) plot_lambert(l, sol=0, color='r', legend=False, units=AU, ax=axis) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # First DSM occuring at time nu1*T1 DV[0] = norm([a - b for a, b in zip(v_beg_l, v)]) # 4 - And we proceed with each successive leg for i in range(1, self.__n_legs): # Fly-by v_out = fb_prop(v_end_l, v_P[i], x[8 + (i - 1) * 4] * self.seq[i].radius, x[7 + (i - 1) * 4], self.seq[i].mu_self) # s/c propagation before the DSM r, v = propagate_lagrangian(r_P[i], v_out, x[9 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu) plot_kepler(r_P[i], v_out, x[9 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu, N=100, color='b', legend=False, units=AU, ax=axis) # Lambert arc to reach Earth during (1-nu2)*T2 (second segment) dt = (1 - x[9 + (i - 1) * 4]) * T[i] * DAY2SEC l = lambert_problem(r, r_P[i + 1], dt, self.common_mu, False, False) plot_lambert(l, sol=0, color='r', legend=False, units=AU, N=1000, ax=axis) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # DSM occuring at time nu2*T2 DV[i] = norm([a - b for a, b in zip(v_beg_l, v)]) plt.show() return axis
def calc_objective(self, x, should_print = False): # 1 - we 'decode' the chromosome recording the various times of flight # (days) in the list T and the cartesian components of vinf T, Vinfx, Vinfy, Vinfz = self._decode_times_and_vinf(x) Vinf = [Vinfx, Vinfy, Vinfz] # 2 - We compute the epochs and ephemerides of the planetary encounters t_P = list([None] * (self.n_legs + 1)) r_P = list([None] * (self.n_legs + 1)) v_P = list([None] * (self.n_legs + 1)) DV = list([0.0] * (self.n_legs + 1)) for i, planet in enumerate(self.seq): t_P[i] = epoch(x[0] + sum(T[0:i])) r_P[i], v_P[i] = self.seq[i].eph(t_P[i]) if should_print: self.print_time_info(self.seq, t_P) if self.__add_vinf_dep: DV[0] += self.burn_cost(self.seq[0], Vinf) if should_print: self.print_escape(self.seq[0], v_P[0], r_P[0], Vinf, t_P[0].mjd) # 3 - We start with the first leg v0 = [a + b for a, b in zip(v_P[0], Vinf)] r, v = propagate_lagrangian(r_P[0], v0, x[5] * T[0] * DAY2SEC, self.common_mu) # Lambert arc to reach seq[1] dt = (1 - x[5]) * T[0] * DAY2SEC l = lambert_problem(r, r_P[1], dt, self.common_mu, False, False) v_beg_l = l.get_v1()[0] v_end_l = l.get_v2()[0] # First DSM occuring at time nu1*T1 deltaV = [a - b for a, b in zip(v_beg_l, v)] DV[0] += norm(deltaV) if should_print: self.print_dsm(v, r, deltaV, v_beg_l, t_P[0].mjd + dt / DAY2SEC) # 4 - And we proceed with each successive leg for i in range(1, self.n_legs): # Fly-by radius = x[8 + (i - 1) * 4] * self.seq[i].radius beta = x[7 + (i - 1) * 4] v_out = fb_prop(v_end_l, v_P[i],radius , beta, self.seq[i].mu_self) if should_print: v_rel_in = [a - b for a,b in zip(v_end_l, v_P[i])] v_rel_out = [a - b for a,b in zip(v_out, v_P[i])] self.print_flyby(self.seq[i], v_P[i], r_P[i], v_rel_in, v_rel_out, t_P[i].mjd) # s/c propagation before the DSM r, v = propagate_lagrangian(r_P[i], v_out, x[9 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu) # Lambert arc to reach Earth during (1-nu2)*T2 (second segment) dt = (1 - x[9 + (i - 1) * 4]) * T[i] * DAY2SEC l = lambert_problem(r, r_P[i + 1], dt, self.common_mu, False, False) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] # DSM occuring at time nu2*T2 deltaV = [a - b for a, b in zip(v_beg_l, v)] DV[i] = norm(deltaV) if should_print: self.print_dsm(v, r, deltaV, v_beg_l, t_P[i].mjd + dt / DAY2SEC) # Last Delta-v if self.__add_vinf_arr: Vexc_arr = [a - b for a, b in zip(v_end_l, v_P[-1])] DV[-1] = self.burn_cost(self.seq[-1], Vexc_arr) if should_print: self.print_arrival(self.seq[-1], Vexc_arr, t_P[-1].mjd) fuelCost = sum(DV) if should_print: print("Total fuel cost: %10.3f m/s" % round(fuelCost, 3)) if self.f_dimension == 1: return (fuelCost,) else: return (fuelCost, sum(T))