Example #1
0
    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))
Example #2
0
    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))
Example #3
0
 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
Example #4
0
    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
Example #5
0
    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)")
Example #6
0
    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))
Example #7
0
    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
Example #8
0
    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")
Example #9
0
    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)
Example #10
0
    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)