def fitness(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._obj_dim == 1: return (sum(DV), ) else: return (sum(DV), sum(T))
def fitness(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._obj_dim == 1: return (sum(DV),) else: return (sum(DV), sum(T))
def select_resonance(self, beta, safe_distance): v_out = fb_prop(self._rvt_in._v, self._rvt_pl._v, self._planet.radius + safe_distance, beta, self._mu) self._rvt_out = rvt(self._rvt_in._r, v_out, self._time, self._rvt_in._mu) period = self._rvt_out.period() self._timing_error = math.inf for resonance in self._resonances: target = self._period * resonance[1] / resonance[0] dt = abs(period - target) if dt < self._timing_error: self._resonance = resonance self._timing_error = dt return self._timing_error, self._resonance
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, axes=axis, N=150) # 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[4] * T[0] * DAY2SEC, self.common_mu) plot_kepler(r_P[0], v0, x[4] * T[0] * DAY2SEC, self.common_mu, N=100, color='b', legend=False, units=AU, axes=axis) # Lambert arc to reach seq[1] dt = (1 - x[4]) * 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, axes=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[7 + (i - 1) * 4] * self._seq[i].radius, x[6 + (i - 1) * 4], self._seq[i].mu_self) # s/c propagation before the DSM r, v = propagate_lagrangian(r_P[i], v_out, x[8 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu) plot_kepler(r_P[i], v_out, x[8 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu, N=100, color='b', legend=False, units=AU, axes=axis) # Lambert arc to reach Earth during (1-nu2)*T2 (second segment) dt = (1 - x[8 + (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, axes=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 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([0.0] * (self.n_legs + 1)) for i in range(len(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[3] / 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[4] * T[0] * DAY2SEC, self.common_mu) print("DSM after " + str(x[4] * T[0]) + " days") # Lambert arc to reach seq[1] dt = (1 - x[4]) * T[0] * DAY2SEC l = lambert_problem(r, r_P[1], dt, self.common_mu, cw=False, max_revs=0) 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[7 + (i - 1) * 4] * self._seq[i].radius, x[6 + (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[7 + (i - 1) * 4]) + " planetary radii") # s/c propagation before the DSM r, v = propagate_lagrangian(r_P[i], v_out, x[8 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu) print("DSM after " + str(x[8 + (i - 1) * 4] * T[i]) + " days") # Lambert arc to reach Earth during (1-nu2)*T2 (second segment) dt = (1 - x[8 + (i - 1) * 4]) * T[i] * DAY2SEC l = lambert_problem(r, r_P[i + 1], dt, self.common_mu, cw=False, max_revs=0) 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") if self._orbit_insertion: # In this case we compute the insertion DV as a single pericenter # burn DVper = np.sqrt(DV[-1] * DV[-1] + 2 * self._seq[-1].mu_self / self._rp_target) DVper2 = np.sqrt(2 * self._seq[-1].mu_self / self._rp_target - self._seq[-1].mu_self / self._rp_target * (1. - self._e_target)) DVinsertion = np.abs(DVper - DVper2) print("Insertion DV: " + str(DVinsertion) + "m/s") print("Total mission time: " + str(sum(T) / 365.25) + " years (" + str(sum(T)) + " days)")
def fitness(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 in range(len(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[4] * T[0] * DAY2SEC, self.common_mu) # Lambert arc to reach seq[1] dt = (1 - x[4]) * T[0] * DAY2SEC l = lambert_problem(r, r_P[1], dt, self.common_mu, cw=False, max_revs=0) 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[7 + (i - 1) * 4] * self._seq[i].radius, x[6 + (i - 1) * 4], self._seq[i].mu_self) # s/c propagation before the DSM r, v = propagate_lagrangian(r_P[i], v_out, x[8 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu) # Lambert arc to reach Earth during (1-nu2)*T2 (second segment) dt = (1 - x[8 + (i - 1) * 4]) * T[i] * DAY2SEC l = lambert_problem(r, r_P[i + 1], dt, self.common_mu, cw=False, max_revs=0) 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._orbit_insertion: # In this case we compute the insertion DV as a single pericenter # burn DVper = np.sqrt(DV[-1] * DV[-1] + 2 * self._seq[-1].mu_self / self._rp_target) DVper2 = np.sqrt(2 * self._seq[-1].mu_self / self._rp_target - self._seq[-1].mu_self / self._rp_target * (1. - self._e_target)) DV[-1] = np.abs(DVper - DVper2) if self._add_vinf_dep: DV[0] += x[3] if not self._multi_objective: return (sum(DV), ) else: return (sum(DV), 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 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 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 _compute_dvs(self, x: List[float]) -> Tuple[ List[float], # DVs List[Any], # Lambert legs List[float], # T List[Tuple[List[float], List[float]]], # ballistic legs List[float], # epochs of ballistic legs ]: # 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 in range(len(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]) ballistic_legs: List[Tuple[List[float], List[float]]] = [] ballistic_ep: List[float] = [] lamberts = [] # 3 - We start with the first leg v0 = [a + b for a, b in zip(v_P[0], [Vinfx, Vinfy, Vinfz])] ballistic_legs.append((r_P[0], v0)) ballistic_ep.append(t_P[0].mjd2000) r, v = propagate_lagrangian(r_P[0], v0, x[4] * T[0] * DAY2SEC, self.common_mu) # Lambert arc to reach seq[1] dt = (1 - x[4]) * T[0] * DAY2SEC l = lambert_problem_multirev( v, lambert_problem(r, r_P[1], dt, self.common_mu, cw=False, max_revs=self.max_revs)) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] lamberts.append(l) ballistic_legs.append((r, v_beg_l)) ballistic_ep.append(t_P[0].mjd2000 + x[4] * T[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[7 + (i - 1) * 4] * self._seq[i].radius, x[6 + (i - 1) * 4], self._seq[i].mu_self) ballistic_legs.append((r_P[i], v_out)) ballistic_ep.append(t_P[i].mjd2000) # s/c propagation before the DSM r, v = propagate_lagrangian(r_P[i], v_out, x[8 + (i - 1) * 4] * T[i] * DAY2SEC, self.common_mu) # Lambert arc to reach Earth during (1-nu2)*T2 (second segment) dt = (1 - x[8 + (i - 1) * 4]) * T[i] * DAY2SEC l = lambert_problem_multirev( v, lambert_problem(r, r_P[i + 1], dt, self.common_mu, cw=False, max_revs=self.max_revs)) v_end_l = l.get_v2()[0] v_beg_l = l.get_v1()[0] lamberts.append(l) # DSM occuring at time nu2*T2 DV[i] = norm([a - b for a, b in zip(v_beg_l, v)]) ballistic_legs.append((r, v_beg_l)) ballistic_ep.append(t_P[i].mjd2000 + x[8 + (i - 1) * 4] * T[i]) # 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._orbit_insertion: # In this case we compute the insertion DV as a single pericenter # burn DVper = np.sqrt(DV[-1] * DV[-1] + 2 * self._seq[-1].mu_self / self._rp_target) DVper2 = np.sqrt(2 * self._seq[-1].mu_self / self._rp_target - self._seq[-1].mu_self / self._rp_target * (1. - self._e_target)) DV[-1] = np.abs(DVper - DVper2) if self._add_vinf_dep: DV[0] += x[3] return (DV, lamberts, T, ballistic_legs, ballistic_ep)
def _fitness_impl(self, decoded_x, logging=False, plotting=False, ax=None): """ Computation of the objective function. """ saturn_distance_violated = 0 # decode x t0, u, v, dep_vinf, etas, T, betas, rps = decoded_x # convert incoming velocity vector theta, phi = 2.0 * pi * u, acos(2.0 * v - 1.0) - pi / 2.0 Vinfx = dep_vinf * cos(phi) * cos(theta) Vinfy = dep_vinf * cos(phi) * sin(theta) Vinfz = dep_vinf * sin(phi) # 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)) lamberts = list([None] * (self._n_legs)) v_outs = list([None] * (self._n_legs)) DV = list([0.0] * (self._n_legs + 1)) for i, planet in enumerate(self.seq): t_P[i] = epoch(t0 + sum(T[0:i])) r_P[i], v_P[i] = self.seq[i].eph(t_P[i]) # first leg v_outs[0] = [Vinfx, Vinfy, Vinfz] # bug fixed # check first leg up to DSM saturn_distance_violated += self.check_distance( r_P[0], v_outs[0], t0, etas[0] * T[0]) r, v = propagate_lagrangian(r_P[0], v_outs[0], etas[0] * T[0] * DAY2SEC, self.common_mu) # Lambert arc to reach seq[1] dt = (1.0 - etas[0]) * T[0] * DAY2SEC lamberts[0] = lambert_problem(r, r_P[1], dt, self.common_mu, self.cw, 0) v_end_l = lamberts[0].get_v2()[0] v_beg_l = lamberts[0].get_v1()[0] # First DSM occuring at time eta0*T0 DV[0] = norm([a - b for a, b in zip(v_beg_l, v)]) # checking first leg after DSM saturn_distance_violated += self.check_distance( r, v_beg_l, etas[0] * T[0], T[0]) # successive legs for i in range(1, self._n_legs): # Fly-by v_outs[i] = fb_prop(v_end_l, v_P[i], rps[i - 1] * self.seq[i].radius, betas[i - 1], self.seq[i].mu_self) # checking next leg up to DSM saturn_distance_violated += self.check_distance( r_P[i], v_outs[i], T[i - 1], etas[i] * T[i]) # s/c propagation before the DSM r, v = propagate_lagrangian(r_P[i], v_outs[i], etas[i] * T[i] * DAY2SEC, self.common_mu) # Lambert arc to reach next body dt = (1 - etas[i]) * T[i] * DAY2SEC lamberts[i] = lambert_problem(r, r_P[i + 1], dt, self.common_mu, self.cw, 0) v_end_l = lamberts[i].get_v2()[0] v_beg_l = lamberts[i].get_v1()[0] # DSM occuring at time eta_i*T_i DV[i] = norm([a - b for a, b in zip(v_beg_l, v)]) # checking next leg after DSM saturn_distance_violated += self.check_distance( r, v_beg_l, etas[i] * T[i], T[i]) # single dv penalty for now if saturn_distance_violated > 0: DV[-1] += DV_PENALTY arr_vinf = norm([a - b for a, b in zip(v_end_l, v_P[-1])]) # last Delta-v if self._add_vinf_arr: DV[-1] = arr_vinf if self._add_vinf_dep: DV[0] += dep_vinf # pretty printing if logging: print("First leg: {} to {}".format(self.seq[0].name, self.seq[1].name)) print("Departure: {0} ({1:0.6f} mjd2000)".format( t_P[0], t_P[0].mjd2000)) print("Duration: {0:0.6f}d".format(T[0])) print("VINF: {0:0.3f}m/s".format(dep_vinf)) print("DSM after {0:0.6f}d".format(etas[0] * T[0])) print("DSM magnitude: {0:0.6f}m/s".format(DV[0])) for i in range(1, self._n_legs): print("\nleg {}: {} to {}".format(i + 1, self.seq[i].name, self.seq[i + 1].name)) print("Duration: {0:0.6f}d".format(T[i])) print("Fly-by epoch: {0} ({1:0.6f} mjd2000)".format( t_P[i], t_P[i].mjd2000)) print("Fly-by radius: {0:0.6f} planetary radii".format(rps[i - 1])) print("DSM after {0:0.6f}d".format(etas[i] * T[i])) print("DSM magnitude: {0:0.6f}m/s".format(DV[i])) print("\nArrival at {}".format(self.seq[-1].name)) print("Arrival epoch: {0} ({1:0.6f} mjd2000)".format( t_P[-1], t_P[-1].mjd2000)) print("Arrival Vinf: {0:0.3f}m/s".format(arr_vinf)) print("Total mission time: {0:0.6f}d ({1:0.3f} years)".format( sum(T), sum(T) / 365.25)) # plotting if plotting: ax.scatter(0, 0, 0, color='chocolate') for i, planet in enumerate(self.seq): plot_planet(planet, t0=t_P[i], color=pl2c[planet.name], legend=True, units=AU, ax=ax) for i in range(0, self._n_legs): plot_kepler(r_P[i], v_outs[i], etas[i] * T[i] * DAY2SEC, self.common_mu, N=100, color='b', legend=False, units=AU, ax=ax) for l in lamberts: plot_lambert(l, sol=0, color='r', legend=False, units=AU, N=1000, ax=ax) # returning building blocks for objectives return (DV, T, arr_vinf, lamberts)