예제 #1
0
    def _compute_dvs(self, x: List[float]) -> Tuple[
            float,  # DVlaunch
            List[float],  # DVs
            float,  # DVarrival,
            List[Any],  # Lambert legs
            float,  #DVlaunch_tot
            List[float],  # T
            List[Tuple[List[float], List[float]]],  # ballistic legs
            List[float],  # epochs of ballistic legs
    ]:
        # 1 -  we 'decode' the times of flights and compute epochs (mjd2000)
        T: List[float] = self._decode_tofs(x)  # [T1, T2 ...]
        ep = np.insert(T, 0, x[0])  # [t0, T1, T2 ...]
        ep = np.cumsum(ep)  # [t0, t1, t2, ...]
        # 2 - we compute the ephemerides
        r = [0] * len(self.seq)
        v = [0] * len(self.seq)
        for i in range(len(self.seq)):
            r[i], v[i] = self.seq[i].eph(float(ep[i]))

        l = list()
        ballistic_legs: List[Tuple[List[float], List[float]]] = []
        ballistic_ep: List[float] = []

        # 3 - we solve the lambert problems
        vi = v[0]
        for i in range(self._n_legs):
            lp = lambert_problem_multirev(
                vi,
                lambert_problem(r[i], r[i + 1], T[i] * DAY2SEC,
                                self._common_mu, False, self.max_revs))
            l.append(lp)
            vi = lp.get_v2()[0]
            ballistic_legs.append((r[i], lp.get_v1()[0]))
            ballistic_ep.append(ep[i])
        # 4 - we compute the various dVs needed at fly-bys to match incoming
        # and outcoming
        DVfb = list()
        for i in range(len(l) - 1):
            vin = [a - b for a, b in zip(l[i].get_v2()[0], v[i + 1])]
            vout = [a - b for a, b in zip(l[i + 1].get_v1()[0], v[i + 1])]
            DVfb.append(fb_vel(vin, vout, self.seq[i + 1]))
        # 5 - we add the departure and arrival dVs
        DVlaunch_tot = np.linalg.norm(
            [a - b for a, b in zip(v[0], l[0].get_v1()[0])])
        DVlaunch = max(0, DVlaunch_tot - self.vinf)
        DVarrival = np.linalg.norm(
            [a - b for a, b in zip(v[-1], l[-1].get_v2()[0])])
        if self.orbit_insertion:
            # In this case we compute the insertion DV as a single pericenter
            # burn
            DVper = np.sqrt(DVarrival * DVarrival +
                            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))
            DVarrival = np.abs(DVper - DVper2)
        return (DVlaunch, DVfb, DVarrival, l, DVlaunch_tot, T, ballistic_legs,
                ballistic_ep)
예제 #2
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_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]

        # 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_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]
            # 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)")
예제 #3
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',
                    units=AU,
                    axes=axis)

        # 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))

        plot_lambert(l, sol=0, color='r', 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',
                        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_multirev(
                v,
                lambert_problem(r,
                                r_P[i + 1],
                                dt,
                                self.common_mu,
                                cw=False,
                                max_revs=self.max_revs))

            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
예제 #4
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_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]

        # 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_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]
            # 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))