Пример #1
0
    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))
Пример #2
0
    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))
Пример #3
0
    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
Пример #4
0
    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
Пример #5
0
    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])
Пример #6
0
    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])
Пример #7
0
    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])
Пример #8
0
    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])
Пример #9
0
    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])
Пример #10
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
Пример #11
0
    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))
Пример #12
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 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
Пример #13
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 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
Пример #14
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")
Пример #15
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")
Пример #16
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
Пример #17
0
    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))