Exemple #1
0
    def __init__(self, multi_objective, tof_encoding, tof):
        """
        Args:
            - multi_objective (``bool``): when True the problem fitness will return also the time of flight as an added objective
            - tof_encoding (``str``): one of 'direct', 'eta' or 'alpha'. Selects the encoding for the time of flights
            - tof (``list`` or ``list`` of ``list``): time of flight bounds. As documented in ``pykep.mga_1dsm``

        """
        # Redefining the planets as to change their safe radius
        earth = jpl_lp('earth')
        earth.safe_radius = 1.05
        # We need the Earth eph in the fitnes
        venus = jpl_lp('venus')
        venus.safe_radius = 1.05
        mars = jpl_lp('mars')
        mars.safe_radius = 1.05
        jupiter = jpl_lp('jupiter')

        super().__init__(
            seq=[earth, earth, venus, earth, mars, earth, jupiter],
            t0=[8000, 8400],
            tof=tof,
            vinf=[1., 4.],
            add_vinf_dep=False,
            add_vinf_arr=True,
            tof_encoding=tof_encoding,
            multi_objective=multi_objective,
            orbit_insertion=True,
            e_target=0.98531407996358,
            rp_target=1070400000,
            eta_lb=0.01,
            eta_ub=0.99,
            rp_ub=10)
Exemple #2
0
def run_example5():
    import pygmo as pg
    from pykep import epoch
    from pykep.planet import jpl_lp
    from pykep.trajopt import mga_1dsm

    # We define an Earth-Venus-Earth problem (single-objective)
    seq = [jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')]
    udp = mga_1dsm(
        seq=seq,
        t0=[epoch(5844), epoch(6209)],
        tof=[0.7 * 365.25, 3 * 365.25],
        vinf=[0.5, 2.5],
        add_vinf_dep=False,
        add_vinf_arr=True,
        multi_objective=False
    )

    pg.problem(udp)
    # We solve it!!
    uda = pg.sade(gen=100)
    archi = pg.archipelago(algo=uda, prob=udp, n=8, pop_size=20)
    print(
        "Running a Self-Adaptive Differential Evolution Algorithm .... on 8 parallel islands")
    archi.evolve(10)
    archi.wait()
    sols = archi.get_champions_f()
    idx = sols.index(min(sols))
    print("Done!! Solutions found are: ", archi.get_champions_f())
    udp.pretty(archi.get_champions_x()[idx])
    udp.plot(archi.get_champions_x()[idx])
def goto_mars():
    # We define an Earth-Mars problem (single-objective)
    seq = [jpl_lp('earth'), jpl_lp('mars')]
    udp = mga_1dsm(seq=seq,
                   t0=[epoch(18 * 365.25 + 1),
                       epoch(25 * 365.25 + 1)],
                   tof=[0.7 * 365.25, 7 * 365.25],
                   vinf=[0.5, 5],
                   add_vinf_dep=False,
                   add_vinf_arr=True,
                   multi_objective=False)

    pg.problem(udp)
    # We solve it!!
    uda = pg.sade(gen=200)
    archi = pg.archipelago(algo=uda, prob=udp, n=8, pop_size=30)
    print(
        "Running a Self-Adaptive Differential Evolution Algorithm .... on 8 parallel islands"
    )
    archi.evolve(10)
    archi.wait()
    sols = archi.get_champions_f()
    idx = sols.index(min(sols))
    print("Done!! Solutions found are: ", archi.get_champions_f())
    print(f"\nThe best solution with Dv = {min(sols)[0]}:\n")
    udp.pretty(archi.get_champions_x()[idx])
    udp.plot(archi.get_champions_x()[idx], savepath="plot.png")
Exemple #4
0
def run_example2():
    import matplotlib as mpl
    from mpl_toolkits.mplot3d import Axes3D

    import matplotlib.pyplot as plt
    from pykep import epoch, DAY2SEC, AU, MU_SUN, lambert_problem
    from pykep.planet import jpl_lp
    from pykep.orbit_plots import plot_planet, plot_lambert

    mpl.rcParams['legend.fontsize'] = 10

    fig = plt.figure()
    axis = fig.gca(projection='3d')

    t1 = epoch(0)
    t2 = epoch(640)
    dt = (t2.mjd2000 - t1.mjd2000) * DAY2SEC

    axis.scatter([0], [0], [0], color='y')

    pl = jpl_lp('earth')
    plot_planet(pl, t0=t1, color=(0.8, 0.8, 1), legend=True, units=AU, ax=axis)
    rE, vE = pl.eph(t1)

    pl = jpl_lp('mars')
    plot_planet(pl, t0=t2, color=(0.8, 0.8, 1), legend=True, units=AU, ax=axis)
    rM, vM = pl.eph(t2)

    l = lambert_problem(rE, rM, dt, MU_SUN)
    plot_lambert(l, color='b', legend=True, units=AU, ax=axis)
    plot_lambert(l, sol=1, color='g', legend=True, units=AU, ax=axis)
    plot_lambert(l, sol=2, color='g', legend=True, units=AU, ax=axis)

    plt.show()
Exemple #5
0
def run_example5():
    import pygmo as pg
    from pykep import epoch
    from pykep.planet import jpl_lp
    from pykep.trajopt import mga_1dsm

    # We define an Earth-Venus-Earth problem (single-objective)
    seq = [jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')]
    udp = mga_1dsm(seq=seq,
                   t0=[epoch(5844), epoch(6209)],
                   tof=[0.7 * 365.25, 3 * 365.25],
                   vinf=[0.5, 2.5],
                   add_vinf_dep=False,
                   add_vinf_arr=True,
                   multi_objective=False)

    pg.problem(udp)
    # We solve it!!
    uda = pg.sade(gen=100)
    archi = pg.archipelago(algo=uda, prob=udp, n=8, pop_size=20)
    print(
        "Running a Self-Adaptive Differential Evolution Algorithm .... on 8 parallel islands"
    )
    archi.evolve(10)
    archi.wait()
    sols = archi.get_champions_f()
    idx = sols.index(min(sols))
    print("Done!! Solutions found are: ", archi.get_champions_f())
    udp.pretty(archi.get_champions_x()[idx])
    udp.plot(archi.get_champions_x()[idx])
Exemple #6
0
 def __init__(self, N=3):
     super(_emNimp_udp, self).__init__(start=planet.jpl_lp('earth'),
                                       target=planet.jpl_lp('mars'),
                                       N_max=N,
                                       tof=[200., 700.],
                                       vinf=[0., 4.],
                                       phase_free=False,
                                       multi_objective=False,
                                       t0=[10000, 11000])
     self.N = N
Exemple #7
0
 def __init__(self, N = 3):
     super(_emNimp_udp, self).__init__(
             start=planet.jpl_lp('earth'),
             target=planet.jpl_lp('mars'),
             N_max=N,
             tof=[200., 700.],
             vinf=[0., 4.],
             phase_free=False,
             multi_objective=False,
             t0=[10000, 11000]
             )
     self.N = N
    def __init__(
        self,
        t0_limits=[7000, 8000],
        tof_limits=[[50, 420], [50, 400], [50, 400]],
        max_revs: int=2,
        resonances=
            [[[1, 1], [5, 4], [4, 3]],
            [[1, 1], [5, 4], [4, 3]],
            [[1, 1], [5, 4], [4, 3]],
            [[4, 3], [3, 2], [5, 3]],
            [[4, 3], [3, 2], [5, 3]],
            [[4, 3], [3, 2], [5, 3]]],
        safe_distance=350000,
        max_mission_time=11.0 * 365.25,
        max_dv0=5600,
    ):
        """
        Args:
            - t0_limits (``list`` of ``float``): start time bounds. 
            - tof_limits (``list`` of ``list`` of ``float``): time of flight bounds. 
            - max_revs (``int``): maximal number of revolutions for Lambert transfer.
            - resonances (``list`` of ``list`` of ``int``): resonance options. 
            - safe_distance: (``float``): safe distance from planet at GA maneuver in m.
            - max_mission_time: (``float``): max mission time in days.
            - max_dv0: (``float``): max delta velocity at start.
        """
        
        self._safe_distance = safe_distance
        self._max_mission_time = max_mission_time
        self._max_dv0 = max_dv0
        self._min_beta = -math.pi
        self._max_beta = math.pi
        
        self._earth = jpl_lp("earth")
        self._venus = jpl_lp("venus")
        self._seq = [self._earth, self._venus, self._venus, self._earth, self._venus,
                     self._venus, self._venus, self._venus, self._venus, self._venus]
        
        assert len(self._seq) - 4 == len(resonances) # one resonance option selection for each VV sequence

        self._resonances = resonances
        self._t0 = t0_limits
        self._tof = tof_limits
        self._max_revs = max_revs       

        self._n_legs = len(self._seq) - 1
 
        # initialize data to compute heliolatitude
        t_plane_crossing = epoch(7645)
        rotation_axis = self._seq[0].eph(t_plane_crossing)[0]
        self._rotation_axis = rotation_axis / np.linalg.norm(rotation_axis)
        self._theta = -7.25 * DEG2RAD  # fixed direction of the rotation
Exemple #9
0
    def __init__(self,
                 seq=[jpl_lp('earth'),
                      jpl_lp('venus'),
                      jpl_lp('mercury')],
                 n_seg=[5, 20],
                 t0=[3000, 4000],
                 tof=[[100, 1000], [200, 2000]],
                 vinf_dep=3,
                 vinf_arr=2,
                 mass=[1200., 2000.0],
                 Tmax=0.5,
                 Isp=3500.0,
                 fb_rel_vel=6,
                 multi_objective=False,
                 high_fidelity=False):
        """
        Args:
            - seq (```list of pykep.planet```): defines the encounter sequence for the trajectory (including the initial planet).
            - n_seg (```list``` of ```int```): the number of segments to be used for each leg.
            - t0 (```list``` of ```floats```): the launch window (in mjd2000).
            - tof (```list``` of ```2D-list```): minimum and maximum time of each leg (days).
            - vinf_dep (```float```): maximum launch hyperbolic velocity allowed (in km/sec).
            - vinf_arr (```float```): maximum arrival hyperbolic velocity allowed (in km/sec).
            - mass (```float```): spacecraft starting mass. (in kg).
            - Tmax (```float```): maximum thrust (in N).
            - Isp (```float```):: engine specific impulse (in s).
.           - fb_rel_vel (```float```): determines the bounds on the maximum allowed relative velocity at all fly-bys (in km/sec).
            - multi-objective (```bool```): when True defines the problem as a multi-objective problem, returning total DV and time of flight.
            - high_fidelity (```bool```):makes the trajectory computations slower, but actually dynamically feasible.
        """
        # We define some data members (we use the double underscore to
        # indicate they are private)
        self._seq = seq
        self._n_seg = n_seg
        self._t0 = t0
        self._tof = tof
        self._vinf_dep = vinf_dep * 1000
        self._vinf_arr = vinf_arr * 1000
        self._mass = mass
        self._Tmax = Tmax
        self._fb_rel_vel = fb_rel_vel
        self._multiobjective = multi_objective
        self._high_fidelity = high_fidelity

        self._n_legs = len(seq) - 1
        self._sc = spacecraft(mass[1], Tmax, Isp)
        self._leg = leg()
        self._leg.set_mu(MU_SUN)
        self._leg.set_spacecraft(self._sc)
Exemple #10
0
 def __init__(self, N=3):
     """
     Write Me
     """
     super().__init__(
         start=jpl_lp('earth'),
         target=jpl_lp('mars'),
         N_max=N,
         tof=[200., 700.],
         vinf=[0., 4.],
         phase_free=False,
         multi_objective=False,
         t0=[10000, 11000]
     )
     self.N = N
Exemple #11
0
 def __init__(self,
              tof_encoding='direct',
              t0=[epoch(0), epoch(3000)],
              tof=[[10, 500], [10, 500]]):
     """
     Write Me
     """
     super().__init__(
         seq=[jpl_lp('earth'),
              jpl_lp('venus'),
              jpl_lp('earth')],
         t0=t0,
         tof=tof,
         vinf=[0.5, 2.5],
         add_vinf_dep=False,
         add_vinf_arr=True,
         tof_encoding=tof_encoding,
         multi_objective=False)
Exemple #12
0
    def __init__(self,
                 seq=[jpl_lp('earth'),
                      jpl_lp('venus'),
                      jpl_lp('earth')],
                 t0=[epoch(0), epoch(1000)],
                 tof=[1.0, 5.0],
                 vinf=[0.5, 2.5],
                 add_vinf_dep=False,
                 add_vinf_arr=True,
                 multi_objective=False):
        """
        pykep.trajopt.mga_1dsm(seq = [jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], t0 = [epoch(0),epoch(1000)], tof = [1.0,5.0], vinf = [0.5, 2.5], multi_objective = False, add_vinf_dep = False, add_vinf_arr=True)

        - seq: list of pykep planets defining the encounter sequence (including the starting launch)
        - t0: list of two epochs defining the launch window
        - tof: list of two floats defining the minimum and maximum allowed mission lenght (days)
        - vinf: list of two floats defining the minimum and maximum allowed initial hyperbolic velocity (at launch), in km/sec
        - multi_objective: when True constructs a multiobjective problem (dv, T)
        - add_vinf_dep: when True the computed Dv includes the initial hyperbolic velocity (at launch)
        - add_vinf_arr: when True the computed Dv includes the final hyperbolic velocity (at the last planet)
        """

        # Sanity checks ...... all planets need to have the same
        # mu_central_body
        if ([r.mu_central_body
             for r in seq].count(seq[0].mu_central_body) != len(seq)):
            raise ValueError(
                'All planets in the sequence need to have exactly the same mu_central_body'
            )
        self.__add_vinf_dep = add_vinf_dep
        self.__add_vinf_arr = add_vinf_arr
        self.__n_legs = len(seq) - 1
        self._t0 = t0
        self._tof = tof
        self._vinf = vinf
        self._obj_dim = multi_objective + 1

        # We then define all planets in the sequence  and the common central
        # body gravity as data members
        self.seq = seq
        self.common_mu = seq[0].mu_central_body
Exemple #13
0
    def __init__(self,
                 seq=[jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')],
                 t0=[epoch(0), epoch(1000)],
                 tof=[1.0, 5.0],
                 vinf=[0.5, 2.5],
                 add_vinf_dep=False,
                 add_vinf_arr=True,
                 multi_objective=False):
        """
        pykep.trajopt.mga_1dsm(seq = [jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], t0 = [epoch(0),epoch(1000)], tof = [1.0,5.0], vinf = [0.5, 2.5], multi_objective = False, add_vinf_dep = False, add_vinf_arr=True)

        - seq: list of pykep planets defining the encounter sequence (including the starting launch)
        - t0: list of two epochs defining the launch window
        - tof: list of two floats defining the minimum and maximum allowed mission lenght (days)
        - vinf: list of two floats defining the minimum and maximum allowed initial hyperbolic velocity (at launch), in km/sec
        - multi_objective: when True constructs a multiobjective problem (dv, T)
        - add_vinf_dep: when True the computed Dv includes the initial hyperbolic velocity (at launch)
        - add_vinf_arr: when True the computed Dv includes the final hyperbolic velocity (at the last planet)
        """

        # Sanity checks ...... all planets need to have the same
        # mu_central_body
        if ([r.mu_central_body for r in seq].count(seq[0].mu_central_body) != len(seq)):
            raise ValueError(
                'All planets in the sequence need to have exactly the same mu_central_body')
        self.__add_vinf_dep = add_vinf_dep
        self.__add_vinf_arr = add_vinf_arr
        self.__n_legs = len(seq) - 1
        self._t0 = t0
        self._tof = tof
        self._vinf = vinf
        self._obj_dim = multi_objective + 1

        # We then define all planets in the sequence  and the common central
        # body gravity as data members
        self.seq = seq
        self.common_mu = seq[0].mu_central_body
Exemple #14
0
from pykep.trajopt import mga
from pykep.planet import jpl_lp
from pykep import AU, DEG2RAD, MU_SUN, epoch

# CASSINI1
_seq_cassini1 = [
    jpl_lp('earth'),
    jpl_lp('venus'),
    jpl_lp('venus'),
    jpl_lp('earth'),
    jpl_lp('jupiter'),
    jpl_lp('saturn')
]


class _cassini1_udp(mga):
    """
    Write Me
    """
    def __init__(self):
        """
        Write Me
        """
        super().__init__(seq=_seq_cassini1,
                         t0=[-1000., 0.],
                         tof=[[30, 400], [100, 470], [30, 400], [400, 2000],
                              [1000, 6000]],
                         vinf=3.,
                         tof_encoding='direct',
                         orbit_insertion=True,
                         e_target=0.98,
Exemple #15
0
from pykep.trajopt import mga_1dsm
from pykep.planet import jpl_lp, keplerian
from pykep import AU, DEG2RAD, MU_SUN, epoch

# MESSENGER (FULL) (we need to modify the safe radius of the planets to match the wanted problem)
_earth = jpl_lp('earth')
_venus = jpl_lp('venus')
_venus.safe_radius = 1.1
_mercury = jpl_lp('mercury')
_mercury.safe_radius = 1.05
_seq_messenger = [
    _earth, _venus, _venus, _mercury, _mercury, _mercury, _mercury
]


class _messenger_udp(mga_1dsm):
    """
    This class represents a rendezvous mission to Mercury modelled as an MGA-1DSM transfer. The selected fly-by sequence,
    E-VVMeMeMe-Me, and other parameters are inspired to the Messenger mission. We have only omitted the first Earth fly-by that
    was used to correct for launcher performances, since we here do not make use of a luncher model.
    As far as chemical propelled interplanetary trajectories go, this particular one is particularly complex and difficult
    to design. The time of flights among successive Mercury fly-bys allow for multiple rvolutions and resonances, making
    optimization techniques struggle to find the correct combination.
    The amount of specialistic knowledge that needs to be used to obtain a successfull design is significant.
    Finding a global optimization approach able to find a good trajectory in complete autonomy without making
    use of additional problem knowledge is possible, but limiting the number of fitness call is difficult.

    .. note::

       A significantly similar version of this problem was part of the no longer maintained GTOP database, 
       https://www.esa.int/gsp/ACT/projects/gtop/gtop.html. The exact definition is, though, different and results
Exemple #16
0
from pykep.trajopt import mga_1dsm
from pykep.planet import jpl_lp, keplerian
from pykep import AU, DEG2RAD, MU_SUN, epoch

# ROSETTA (we need to modify the safe radius of the planets to match the wanted problem)
_churyumov = keplerian(epoch(52504.23754000012, "mjd"),
                                 [3.50294972836275 * AU,
                                  0.6319356,
                                  7.12723 * DEG2RAD,
                                  50.92302 * DEG2RAD,
                                  11.36788 * DEG2RAD,
                                  0. * DEG2RAD],
                                 MU_SUN, 0., 0., 0., "Churyumov-Gerasimenko")

_mars_rosetta = jpl_lp('mars')
_mars_rosetta.safe_radius = 1.05
_seq_rosetta = [jpl_lp('earth'), 
                jpl_lp('earth'), 
                _mars_rosetta, 
                jpl_lp('earth'), 
                jpl_lp('earth'), 
                _churyumov]

class _rosetta_udp(mga_1dsm):
    """
    This class represents a rendezvous mission to the comet 67P/Churyumov-Gerasimenko modelled as an MGA-1DSM transfer.
    The fly-by sequence selected (i.e. E-EMEE-C) is similar to the one planned for the spacecraft Rosetta. 
    The objective function considered is the total mission delta V. No launcher model is employed and a final rendezvous
    with the comet is included in the delta V computations.

    .. note::
Exemple #17
0
from pykep.trajopt import mga_1dsm
from pykep.planet import jpl_lp, keplerian
from pykep import AU, DEG2RAD, MU_SUN, epoch

# CASSINI2 (we need to modify the safe radius of the planets to match the wanted problem)
_earth_cassini2 = jpl_lp('earth')
_earth_cassini2.safe_radius = 1.15
_venus_cassini2 = jpl_lp('venus')
_venus_cassini2.safe_radius = 1.05
_jupiter_cassini2 = jpl_lp('jupiter')
_jupiter_cassini2.safe_radius = 1.7
_seq_cassini2 = [
    _earth_cassini2, _venus_cassini2, _venus_cassini2, _earth_cassini2,
    _jupiter_cassini2,
    jpl_lp('saturn')
]


class _cassini2_udp(mga_1dsm):
    """
    Write Me
    """
    def __init__(self):
        """
        Write Me
        """
        super().__init__(seq=_seq_cassini2,
                         t0=[-1000, 0],
                         tof=[[100, 400], [100, 500], [30, 300], [400, 1600],
                              [800, 2200]],
                         vinf=[3., 5.],
Exemple #18
0
    def __init__(self,
                 seq=[jpl_lp('earth'),
                      jpl_lp('venus'),
                      jpl_lp('earth')],
                 t0=[epoch(0), epoch(1000)],
                 tof=[[10, 300], [10, 300]],
                 vinf=[0.5, 2.5],
                 add_vinf_dep=False,
                 add_vinf_arr=True,
                 tof_encoding='direct',
                 multi_objective=False,
                 orbit_insertion=False,
                 e_target=None,
                 rp_target=None,
                 eta_lb=0.1,
                 eta_ub=0.9,
                 rp_ub=30):
        """
        pykep.trajopt.mga_1dsm(seq = [jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], t0 = [epoch(0),epoch(1000)], tof = [1.0,5.0], vinf = [0.5, 2.5], multi_objective = False, add_vinf_dep = False, add_vinf_arr=True)

        - seq (``list`` of ``pykep.planet``): the encounter sequence (including the starting launch)
        - t0 (``list`` of ``pykep.epoch`` or ``floats``): the launch window (in mjd2000 if floats)
        - tof (``list`` or ``float``): bounds on the time of flight (days). If *tof_encoding* is 'direct', this contains a list
            of 2D lists defining the upper and lower bounds on each leg. If *tof_encoding* is 'alpha',
            this contains a list of two floats containing the lower and upper bounds on the time-of-flight. If *tof_encoding*
            is 'eta' tof is a float defining the upper bound on the time-of-flight
        - vinf (``list``): the minimum and maximum allowed initial hyperbolic velocity (at launch), in km/sec
        - add_vinf_dep (``bool``): when True the computed Dv includes the initial hyperbolic velocity (at launch)
        - add_vinf_arr (``bool``): when True the computed Dv includes the final hyperbolic velocity (at the last planet)
        - tof_encoding (``str``): one of 'direct', 'alpha' or 'eta'. Selects the encoding for the time of flights
        - multi_objective (``bool``): when True constructs a multiobjective problem (dv, T)
        - orbit_insertion (``bool``): when True the arrival dv is computed as that required to acquire a target orbit defined by e_target and rp_target
        - e_target (``float``): if orbit_insertion is True this defines the target orbit eccentricity around the final planet
        - rp_target (``float``): if orbit_insertion is True this defines the target orbit pericenter around the final planet (in m)
        """

        # Sanity checks
        # 1 - Planets need to have the same mu_central_body
        if ([r.mu_central_body
             for r in seq].count(seq[0].mu_central_body) != len(seq)):
            raise ValueError(
                'All planets in the sequence need to have identical mu_central_body'
            )
        # 2 - tof encoding needs to be one of 'alpha', 'eta', 'direct'
        if tof_encoding not in ['alpha', 'eta', 'direct']:
            raise TypeError(
                'tof encoding must be one of \'alpha\', \'eta\', \'direct\'')
        # 3 - tof is expected to have different content depending on the tof_encoding
        if tof_encoding == 'direct':
            if np.shape(np.array(tof)) != (len(seq) - 1, 2):
                raise TypeError(
                    'tof_encoding is ' + tof_encoding +
                    ' and tof must be a list of two dimensional lists and with length equal to the number of legs'
                )
        if tof_encoding == 'alpha':
            if np.shape(np.array(tof)) != (2, ):
                raise TypeError('tof_encoding is ' + tof_encoding +
                                ' and tof must be a list of two floats')
        if tof_encoding == 'eta':
            if np.shape(np.array(tof)) != ():
                raise TypeError('tof_encoding is ' + tof_encoding +
                                ' and tof must be a float')
        # 4 - Check launch window t0. If defined in terms of floats transform into epochs
        if len(t0) != 2:
            raise TypeError('t0 is ' + t0 +
                            ' while should be a list of two floats or epochs')
        if type(t0[0]) is not epoch:
            t0[0] = epoch(t0[0])
        if type(t0[1]) is not epoch:
            t0[1] = epoch(t0[1])
        # 5 - Check that if orbit insertion is selected e_target and r_p are
        # defined
        if orbit_insertion:
            if rp_target is None:
                raise ValueError(
                    'The rp_target needs to be specified when orbit insertion is selected'
                )
            if e_target is None:
                raise ValueError(
                    'The e_target needs to be specified when orbit insertion is selected'
                )
            if add_vinf_arr is False:
                raise ValueError(
                    'When orbit insertion is selected, the add_vinf_arr must be True'
                )

        self._seq = seq
        self._t0 = t0
        self._tof = tof
        self._vinf = vinf
        self._add_vinf_dep = add_vinf_dep
        self._add_vinf_arr = add_vinf_arr
        self._tof_encoding = tof_encoding
        self._multi_objective = multi_objective
        self._orbit_insertion = orbit_insertion
        self._e_target = e_target
        self._rp_target = rp_target
        self._eta_lb = eta_lb
        self._eta_ub = eta_ub
        self._rp_ub = rp_ub

        self.n_legs = len(seq) - 1
        self.common_mu = seq[0].mu_central_body
Exemple #19
0
    def __init__(self,
                 start=jpl_lp('earth'),
                 target=jpl_lp('venus'),
                 N_max=3,
                 tof=[20., 400.],
                 vinf=[0., 4.],
                 phase_free=True,
                 multi_objective=False,
                 t0=None
                 ):
        """
        prob = pykep.trajopt.pl2pl_N_impulses(start=jpl_lp('earth'), target=jpl_lp('venus'), N_max=3, tof=[20., 400.], vinf=[0., 4.], phase_free=True, multi_objective=False, t0=None)

        Args: 
            - start (``pykep.planet``): the starting planet
            - target (``pykep.planet``): the target planet
            - N_max (``int``): maximum number of impulses
            - tof (``list``): the box bounds [lower,upper] for the time of flight (days)
            - vinf (``list``): the box bounds [lower,upper] for each DV magnitude (km/sec)
            - phase_free (``bool``): when True, no randezvous condition are enforced and start and arrival anomalies will be free
            - multi_objective (``bool``):  when True, a multi-objective problem is constructed with DV and time of flight as objectives
            - t0 (``list``):  the box bounds on the launch window containing two pykep.epoch. This is not needed if phase_free is True.
        """

        # Sanity checks
        # 1) all planets need to have the same mu_central_body
        if (start.mu_central_body != target.mu_central_body):
            raise ValueError(
                'Starting and ending pykep.planet must have the same mu_central_body')
        # 2) Number of impulses must be at least 2
        if N_max < 2:
            raise ValueError('Number of impulses N is less than 2')
        # 3) If phase_free is True, t0 does not make sense
        if (t0 is None and not phase_free):
            t0 = [epoch(0), epoch(1000)]
        if (t0 is not None and phase_free):
            raise ValueError('When phase_free is True no t0 can be specified')
        if (type(t0[0]) != type(epoch(0))):
            t0[0] = epoch(t0[0])
        if (type(t0[1]) != type(epoch(0))):
            t0[1] = epoch(t0[1])

        self.obj_dim = multi_objective + 1
        # We then define all class data members
        self.start = start
        self.target = target
        self.N_max = N_max
        self.phase_free = phase_free
        self.multi_objective = multi_objective
        self.vinf = [s * 1000 for s in vinf]

        self.__common_mu = start.mu_central_body

        # And we compute the bounds
        if phase_free:
            self._lb = [0, tof[0]] + [1e-3, 0.0, 0.0,
                                      vinf[0] * 1000] * (N_max - 2) + [1e-3] + [0]
            self._ub = [2 * start.compute_period(epoch(0)) * SEC2DAY, tof[1]] + [1.0-1e-3, 1.0, 1.0, vinf[
                1] * 1000] * (N_max - 2) + [1.0-1e-3] + [2 * target.compute_period(epoch(0)) * SEC2DAY]
        else:
            self._lb = [t0[0].mjd2000, tof[0]] + \
                [1e-3, 0.0, 0.0, vinf[0] * 1000] * (N_max - 2) + [1e-3]
            self._ub = [t0[1].mjd2000, tof[1]] + \
                [1.0-1e-3, 1.0, 1.0, vinf[1] * 1000] * (N_max - 2) + [1.0-1e-3]
def main():

    print('\nInteplanetary porkchop plot using PyKEP\n')
    #Pykep makes use of lambert transfers to study interplanetary trajectories by producing Pork-Chop plots

    # Define the start and end planets of the inteplanetary trajectory

    while True:
        start_planet_input = input('Enter initial planet: ').lower()
        end_planet_input = input('Enter destination planet: ').lower()

        if (start_planet_input == end_planet_input):
            print(
                'Incorrect input. Initial and destination planets cannot be the same.\n'
            )
        elif (start_planet_input
              or end_planet_input) not in ('mercury', 'venus', 'earth', 'mars',
                                           'jupiter', 'saturn', 'uranus',
                                           'neptune', 'pluto'):
            print('Unknown planet name.\n')
        else:
            break

    start_planet = jpl_lp(start_planet_input)
    end_planet = jpl_lp(end_planet_input)

    # Set departure epochs and transfer time

    while True:
        try:
            input_eph1 = float(
                input('\nEnter first departure epoch in MJD2000: '))
            input_eph2 = float(
                input('Enter latest departure epoch in MJD2000: '))
        except ValueError:
            print('Invalid input.\n')
            continue
        else:
            print(
                f'\nDepature window is from {input_eph1} to {input_eph2} (MJD2000)\n'
            )
            break

    while True:
        try:
            input_flt1 = float(input('Enter minimum flight time in days: '))
            input_flt2 = float(input('Enter maximum flight time in days: '))
        except ValueError:
            print('Invalid input.\n')
            continue
        else:
            print(
                f'\nTotal mission duration is from {input_flt1} to {input_flt2} (days)'
            )
            break

    # Sample departure epochs and transfer times every 15 days and solve the lambert problem in a large defined grid

    plotContours(start_planet, end_planet, input_eph1, input_eph2, input_flt1,
                 input_flt2, 15.0)

    while True:
        zoom = input(
            '\nWould you like to sample with a finer resolution? (Y/N)\n')
        if zoom[0].upper() == 'Y':
            pass
            while True:
                try:
                    input_new_eph1 = float(
                        input(
                            '\nEnter the updated first departure epoch in MJD2000: '
                        ))
                    input_new_eph2 = float(
                        input(
                            'Enter the updated latest departure epoch in MJD2000: '
                        ))
                except ValueError:
                    print('Invalid input.\n')
                    continue
                else:
                    print(
                        f'\nDepature window is from {input_new_eph1} to {input_new_eph2} (MJD2000)\n'
                    )
                    break

            while True:
                try:
                    input_new_flt1 = float(
                        input(
                            'Enter the updated minimum flight time in days: '))
                    input_new_flt2 = float(
                        input('Enter updated maximum flight time in days: '))
                except ValueError:
                    print('Invalid input.\n')
                    continue
                else:
                    print(
                        f'\nTotal mission duration is from {input_new_flt1} to {input_new_flt2} (days)'
                    )
                    break

            plotContours(start_planet, end_planet, input_new_eph1,
                         input_new_eph2, input_new_flt1, input_new_flt2, 1.0)

        else:
            print('Program ended.\n')
            break
mpl.rcParams['legend.fontsize'] = 10

# asteroid @ Epoch 2014-Dec-09 (JD 2,457,000.5)
ast_time = epoch_from_string('2014-12-09 00:00:00.000')  #epoch(6800,"mjd2000")
ast_orbel = (2.77 * AU, 0.075, 9.65 * DEG2RAD, 80.33 * DEG2RAD,
             72.52 * DEG2RAD, 95.99 * DEG2RAD)  # a,e,i,W,w,M (SI and RAD)
ast_mu = 6e10
ast_radius = 1e5
ast_name = 'asteroid'
asteroid = keplerian(ast_time, ast_orbel, MU_SUN, ast_mu, ast_radius,
                     ast_radius * 1.1, ast_name)
rA, vA = asteroid.eph(ast_time)

#earth
pl = jpl_lp('earth')
rE, vE = pl.eph(ast_time)

# plot
fig = plt.figure()
axis = fig.gca(projection='3d')
axis.scatter([0], [0], [0], color='y')  #sun
plot_planet(asteroid,
            t0=ast_time,
            color=(1, 0.4, 0),
            legend=True,
            units=AU,
            ax=axis)  #asteroid
plot_planet(pl,
            t0=ast_time,
            color=(0.8, 0.8, 1),
Exemple #22
0
    def __init__(self,
                 seq=[jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')],
                 n_seg=[10] * 2,
                 t0=[epoch(0), epoch(1000)],
                 tof=[[200, 500], [200, 500]],
                 vinf_dep=2.5,
                 vinf_arr=2.0,
                 mass=4000.0,
                 Tmax=1.0,
                 Isp=2000.0,
                 fb_rel_vel=6,
                 multi_objective=False,
                 high_fidelity=False):
        """
        prob = mga_lt_nep(seq = [jpl_lp('earth'),jpl_lp('venus'),jpl_lp('earth')], n_seg = [10]*2,
        t0 = [epoch(0),epoch(1000)], tof = [[200,500],[200,500]], vinf_dep=2.5, vinf_arr=2.0, mass=4000.0, Tmax=1.0, Isp=2000.0,
        multi_objective = False, fb_rel_vel = 6, high_fidelity=False)

        - seq: list of pykep.planet defining the encounter sequence for the trajectoty (including the initial planet)
        - n_seg: list of integers containing the number of segments to be used for each leg (len(n_seg) = len(seq)-1)
        - t0: list of pykep epochs defining the launch window
        - tof: minimum and maximum time of each leg (days)
        - vinf_dep: maximum launch hyperbolic velocity allowed (in km/sec)
        - vinf_arr: maximum arrival hyperbolic velocity allowed (in km/sec)
        - mass: spacecraft starting mass
        - Tmax: maximum thrust
        - Isp: engine specific impulse
        - fb_rel_vel = determines the bounds on the maximum allowed relative velocity at all fly-bys (in km/sec)
        - multi-objective: when True defines the problem as a multi-objective problem, returning total DV and time of flight
        - high_fidelity = makes the trajectory computations slower, but actually dynamically feasible.
        """

        # 1) We compute the problem dimensions .... and call the base problem
        # constructor
        self.__n_legs = len(seq) - 1
        n_fb = self.__n_legs - 1
        # 1a) The decision vector length
        dim = 1 + self.__n_legs * 8 + sum(n_seg) * 3
        # 1b) The total number of constraints (mismatch + fly-by + boundary +
        # throttles
        c_dim = self.__n_legs * 7 + n_fb * 2 + 2 + sum(n_seg)
        # 1c) The number of inequality constraints (boundary + fly-by angle +
        # throttles)
        c_ineq_dim = 2 + n_fb + sum(n_seg)
        # 1d) the number of objectives
        f_dim = multi_objective + 1
        # First we call the constructor for the base pygmo problem
        # As our problem is n dimensional, box-bounded (may be multi-objective), we write
        # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation)
        super(mga_lt_nep, self).__init__(
            dim, 0, f_dim, c_dim, c_ineq_dim, 1e-4)

        # 2) We then define some class data members
        # public:
        self.seq = seq
        # private:
        self.__n_seg = n_seg
        self.__vinf_dep = vinf_dep * 1000
        self.__vinf_arr = vinf_arr * 1000
        self.__sc = spacecraft(mass, Tmax, Isp)
        self.__leg = leg()
        self.__leg.set_mu(MU_SUN)
        self.__leg.set_spacecraft(self.__sc)
        self.__leg.high_fidelity = high_fidelity
        fb_rel_vel *= 1000
        # 3) We compute the bounds
        lb = [t0[0].mjd2000] + [0, mass / 2, -fb_rel_vel, -fb_rel_vel, -fb_rel_vel, -
                                fb_rel_vel, -fb_rel_vel, -fb_rel_vel] * self.__n_legs + [-1, -1, -1] * sum(self.__n_seg)
        ub = [t0[1].mjd2000] + [1, mass, fb_rel_vel, fb_rel_vel, fb_rel_vel, fb_rel_vel,
                                fb_rel_vel, fb_rel_vel] * self.__n_legs + [1, 1, 1] * sum(self.__n_seg)
        # 3a ... and account for the bounds on the vinfs......
        lb[3:6] = [-self.__vinf_dep] * 3
        ub[3:6] = [self.__vinf_dep] * 3
        lb[-sum(self.__n_seg) * 3 - 3:-sum(self.__n_seg)
           * 3] = [-self.__vinf_arr] * 3
        ub[-sum(self.__n_seg) * 3 - 3:-sum(self.__n_seg)
           * 3] = [self.__vinf_arr] * 3
        # 3b... and for the time of flight
        lb[1:1 + 8 * self.__n_legs:8] = [el[0] for el in tof]
        ub[1:1 + 8 * self.__n_legs:8] = [el[1] for el in tof]

        # 4) And we set the bounds
        self.set_bounds(lb, ub)
Exemple #23
0
from pykep.trajopt import mga, pl2pl_N_impulses
from pykep import planet

# Some hidden variables
_seq_cassini = [planet.jpl_lp('earth'), planet.jpl_lp('venus'), planet.jpl_lp(
'venus'), planet.jpl_lp('earth'), planet.jpl_lp('jupiter'), planet.jpl_lp('saturn')]
class _cassini1_udp(mga):
    def __init__(self):
        super(_cassini1_udp, self).__init__(
            seq=_seq_cassini, 
            t0=[-1000., 0.], 
            tof=[[30,400], [100,470], [30, 400], [400, 2000], [1000, 6000]], 
            vinf=3., 
            tof_encoding='direct',
            orbit_insertion=True,
            e_target = 0.98,
            rp_target = 108950000) 
    def get_name(self):
        return "Cassini MGA direct tof encoding (Trajectory Optimisation Gym P1)"
    def get_extra_info(self):
        retval = "\tTrajectory Optimisation Gym problem (P1): Cassini MGA, single objective, direct encoding\n"
        retval+= "\tPlanetary sequence" + str([pl.name for pl in _seq_cassini])
        return retval
    def __repr__(self):
        return self.get_name()

class _cassini1a_udp(mga):
    def __init__(self):
        super(_cassini1a_udp, self).__init__(
            seq=_seq_cassini,
            t0=[-1000., 0.],
Exemple #24
0
from pykep.trajopt import mga, pl2pl_N_impulses
from pykep import planet

# Some hidden variables
_seq_cassini = [
    planet.jpl_lp('earth'),
    planet.jpl_lp('venus'),
    planet.jpl_lp('venus'),
    planet.jpl_lp('earth'),
    planet.jpl_lp('jupiter'),
    planet.jpl_lp('saturn')
]


class _cassini1_udp(mga):
    def __init__(self):
        super(_cassini1_udp, self).__init__(seq=_seq_cassini,
                                            t0=[-1000., 0.],
                                            tof=[[30, 400], [100, 470],
                                                 [30, 400], [400, 2000],
                                                 [1000, 6000]],
                                            vinf=3.,
                                            tof_encoding='direct',
                                            orbit_insertion=True,
                                            e_target=0.98,
                                            rp_target=108950000)

    def get_name(self):
        return "Cassini MGA direct tof encoding (Trajectory Optimisation Gym P1)"

    def get_extra_info(self):
    def __init__(self,
                 start=jpl_lp('earth'),
                 target=jpl_lp('venus'),
                 N_max=3,
                 tof=[20., 400.],
                 vinf=[0., 4.],
                 phase_free=True,
                 multi_objective=False,
                 t0=None):
        """
        prob = pykep.trajopt.pl2pl_N_impulses(start=jpl_lp('earth'), target=jpl_lp('venus'), N_max=3, tof=[20., 400.], vinf=[0., 4.], phase_free=True, multi_objective=False, t0=None)

        Args: 
            - start (``pykep.planet``): the starting planet
            - target (``pykep.planet``): the target planet
            - N_max (``int``): maximum number of impulses
            - tof (``list``): the box bounds [lower,upper] for the time of flight (days)
            - vinf (``list``): the box bounds [lower,upper] for each DV magnitude (km/sec)
            - phase_free (``bool``): when True, no randezvous condition are enforced and start and arrival anomalies will be free
            - multi_objective (``bool``):  when True, a multi-objective problem is constructed with DV and time of flight as objectives
            - t0 (``list``):  the box bounds on the launch window containing two pykep.epoch. This is not needed if phase_free is True.
        """

        # Sanity checks
        # 1) all planets need to have the same mu_central_body
        if (start.mu_central_body != target.mu_central_body):
            raise ValueError(
                'Starting and ending pykep.planet must have the same mu_central_body'
            )
        # 2) Number of impulses must be at least 2
        if N_max < 2:
            raise ValueError('Number of impulses N is less than 2')
        # 3) If phase_free is True, t0 does not make sense
        if (t0 is None and not phase_free):
            t0 = [epoch(0), epoch(1000)]
        if (t0 is not None and phase_free):
            raise ValueError('When phase_free is True no t0 can be specified')
        if (type(t0[0]) != type(epoch(0))):
            t0[0] = epoch(t0[0])
        if (type(t0[1]) != type(epoch(0))):
            t0[1] = epoch(t0[1])

        self.obj_dim = multi_objective + 1
        # We then define all class data members
        self.start = start
        self.target = target
        self.N_max = N_max
        self.phase_free = phase_free
        self.multi_objective = multi_objective
        self.vinf = [s * 1000 for s in vinf]

        self.__common_mu = start.mu_central_body

        # And we compute the bounds
        if phase_free:
            self._lb = [
                0, tof[0]
            ] + [1e-3, 0.0, 0.0, vinf[0] * 1000] * (N_max - 2) + [1e-3] + [0]
            self._ub = [
                2 * start.compute_period(epoch(0)) * SEC2DAY, tof[1]
            ] + [1.0 - 1e-3, 1.0, 1.0, vinf[1] * 1000] * (N_max - 2) + [
                1.0 - 1e-3
            ] + [2 * target.compute_period(epoch(0)) * SEC2DAY]
        else:
            self._lb = [t0[0].mjd2000, tof[0]] + \
                [1e-3, 0.0, 0.0, vinf[0] * 1000] * (N_max - 2) + [1e-3]
            self._ub = [t0[1].mjd2000, tof[1]] + \
                [1.0-1e-3, 1.0, 1.0, vinf[1] * 1000] * (N_max - 2) + [1.0-1e-3]
Exemple #26
0
    def __init__(self,
                 seq=[jpl_lp('earth'),
                      jpl_lp('venus'),
                      jpl_lp('earth')],
                 t0=[0, 1000],
                 tof=[[30, 200], [200, 300]],
                 vinf=2.5,
                 multi_objective=False,
                 tof_encoding='direct',
                 orbit_insertion=False,
                 e_target=None,
                 rp_target=None,
                 max_revs=0):
        """mga(seq=[pk.planet.jpl_lp('earth'), pk.planet.jpl_lp('venus'), pk.planet.jpl_lp('earth')], t0=[0, 1000], tof=[100, 500], vinf=2.5, multi_objective=False, alpha_encoding=False, orbit_insertion=False, e_target=None, rp_target=None)

        Args:
            - seq (``list of pk.planet``): sequence of body encounters including the starting object
            - t0 (``list of pk.epoch``): the launch window
            - tof (``list`` or ``float``): bounds on the time of flight. If *tof_encoding* is 'direct', this contains a list
              of 2D lists defining the upper and lower bounds on each leg. If *tof_encoding* is 'alpha',
              this contains a 2D list with the lower and upper bounds on the time-of-flight. If *tof_encoding*
              is 'eta' tof is a float defining the upper bound on the time-of-flight
            - vinf (``float``): the vinf provided at launch for free
            - multi_objective (``bool``): when True constructs a multiobjective problem (dv, T). In this case, 'alpha' or `eta` encodings are recommended
            - tof_encoding (``str``): one of 'direct', 'alpha' or 'eta'. Selects the encoding for the time of flights
            - orbit_insertion (``bool``): when True the arrival dv is computed as that required to acquire a target orbit defined by e_target and rp_target
            - e_target (``float``): if orbit_insertion is True this defines the target orbit eccentricity around the final planet
            - rp_target (``float``): if orbit_insertion is True this defines the target orbit pericenter around the final planet (in m)
            - max_revs (``int``): maximal number of revolutions for lambert transfer

        Raises:
            - ValueError: if *planets* do not share the same central body (checked on the mu_central_body attribute)
            - ValueError: if *t0* does not contain objects able to construct a epoch (e.g. pk. epoch or floats)
            - ValueError: if *tof* is badly defined
            - ValueError: it the target orbit is not defined and *orbit_insertion* is True
        """

        # Sanity checks
        # 1 - All planets need to have the same mu_central_body
        if ([r.mu_central_body
             for r in seq].count(seq[0].mu_central_body) != len(seq)):
            raise ValueError(
                'All planets in the sequence need to have exactly the same mu_central_body'
            )
        # 2 - We try to build epochs out of the t0 list (mjd2000 by default)
        for i in range(len(t0)):
            if (type(t0[i]) != type(epoch(0))):
                t0[i] = epoch(t0[i])
        # 3 - Check the tof bounds
        if tof_encoding == 'alpha':
            if len(tof) != 2:
                raise ValueError(
                    r'When the tof_encoding is \'alpha\', tof is expected to be something like [lb, ub]'
                )
        elif tof_encoding == 'direct':
            if len(tof) != (len(seq) - 1):
                raise ValueError(
                    'When tof_encoding is direct, the tof must be a float (upper bound on the time of flight)'
                    + str(len(seq) - 1))
        elif tof_encoding == 'eta':
            try:
                float(tof)
            except TypeError:
                raise ValueError('The tof needs to be have len equal to  ' +
                                 str(len(seq) - 1))
        if not tof_encoding in ['alpha', 'eta', 'direct']:
            raise ValueError(
                "tof_encoding must be one of 'alpha', 'eta', 'direct'")

        # 4 - Check that if orbit insertion is selected e_target and r_p are
        # defined
        if orbit_insertion:
            if rp_target is None:
                raise ValueError(
                    'The rp_target needs to be specified when orbit insertion is selected'
                )
            if e_target is None:
                raise ValueError(
                    'The e_target needs to be specified when orbit insertion is selected'
                )

        # Public data members
        self.seq = seq
        self.t0 = t0
        self.tof = tof
        self.vinf = vinf * 1000
        self.multi_objective = multi_objective
        self.tof_encoding = tof_encoding
        self.orbit_insertion = orbit_insertion
        self.e_target = e_target
        self.rp_target = rp_target

        # Private data members
        self._n_legs = len(seq) - 1
        self._common_mu = seq[0].mu_central_body
        self.max_revs = max_revs
Exemple #27
0
    def __init__(self, prob_id=1, constrained=True):
        """ 
        The TandEM problem of the trajectory gym consists in 48 different instances varying in fly-by sequence and
        the presence of a time constraint.

        Args:
            - prob_id (``int``): The problem id defines the fly-by sequence.
            - constrained (``bool``): Activates the constraint on the time of flight 
              (fitness will thus return two numbers, the objectove function and the inequality constraint violation)
        """
        # Redefining the planets as to change their safe radius
        earth = jpl_lp('earth')
        earth.safe_radius = 1.05
        # We need the Earth eph in the fitnes
        venus = jpl_lp('venus')
        venus.safe_radius = 1.05
        mars = jpl_lp('mars')
        mars.safe_radius = 1.05
        jupiter = jpl_lp('jupiter')
        jupiter.safe_radius = 1.7
        saturn = jpl_lp('saturn')

        # Defining the different sequences
        seq_tandem = []
        seq_tandem.append([earth, venus, venus, venus, saturn])
        seq_tandem.append([earth, venus, venus, earth, saturn])
        seq_tandem.append([earth, venus, venus, mars, saturn])
        seq_tandem.append([earth, venus, venus, jupiter, saturn])

        seq_tandem.append([earth, venus, earth, venus, saturn])
        seq_tandem.append([earth, venus, earth, earth, saturn])
        seq_tandem.append([earth, venus, earth, mars, saturn])
        seq_tandem.append([earth, venus, earth, jupiter, saturn])

        seq_tandem.append([earth, venus, mars, venus, saturn])
        seq_tandem.append([earth, venus, mars, earth, saturn])
        seq_tandem.append([earth, venus, mars, mars, saturn])
        seq_tandem.append([earth, venus, mars, jupiter, saturn])

        seq_tandem.append([earth, earth, venus, venus, saturn])
        seq_tandem.append([earth, earth, venus, earth, saturn])
        seq_tandem.append([earth, earth, venus, mars, saturn])
        seq_tandem.append([earth, earth, venus, jupiter, saturn])

        seq_tandem.append([earth, earth, earth, venus, saturn])
        seq_tandem.append([earth, earth, earth, earth, saturn])
        seq_tandem.append([earth, earth, earth, mars, saturn])
        seq_tandem.append([earth, earth, earth, jupiter, saturn])

        seq_tandem.append([earth, earth, mars, venus, saturn])
        seq_tandem.append([earth, earth, mars, earth, saturn])
        seq_tandem.append([earth, earth, mars, mars, saturn])
        seq_tandem.append([earth, earth, mars, jupiter, saturn])

        if prob_id > 24 or type(prob_id) != int or prob_id < 1:
            raise ValueError("TandEM problem id must be an integer in [1, 24]")

        super().__init__(seq=seq_tandem[prob_id - 1],
                         t0=[5475, 9132],
                         tof=[[20, 2500], [20, 2500], [20, 2500], [20, 2500]],
                         vinf=[2.5, 4.9],
                         add_vinf_dep=False,
                         add_vinf_arr=True,
                         tof_encoding='direct',
                         multi_objective=False,
                         orbit_insertion=True,
                         e_target=0.98531407996358,
                         rp_target=80330000,
                         eta_lb=0.01,
                         eta_ub=0.99,
                         rp_ub=10)

        self.prob_id = prob_id
        self.constrained = constrained
Exemple #28
0
from pykep.trajopt import mga_1dsm
from pykep.planet import jpl_lp, keplerian
from pykep import AU, DEG2RAD, MU_SUN, epoch

# ROSETTA (we need to modify the safe radius of the planets to match the wanted problem)
_churyumov = keplerian(epoch(52504.23754000012, "mjd"), [
    3.50294972836275 * AU, 0.6319356, 7.12723 * DEG2RAD, 50.92302 * DEG2RAD,
    11.36788 * DEG2RAD, 0. * DEG2RAD
], MU_SUN, 0., 0., 0., "Churyumov-Gerasimenko")

_mars_rosetta = jpl_lp('mars')
_mars_rosetta.safe_radius = 1.05
_seq_rosetta = [
    jpl_lp('earth'),
    jpl_lp('earth'), _mars_rosetta,
    jpl_lp('earth'),
    jpl_lp('earth'), _churyumov
]


class _rosetta_udp(mga_1dsm):
    """
    This class represents a rendezvous mission to the comet 67P/Churyumov-Gerasimenko modelled as an MGA-1DSM transfer.
    The fly-by sequence selected (i.e. E-EMEE-C) is similar to the one planned for the spacecraft Rosetta. 
    The objective function considered is the total mission delta V. No launcher model is employed and a final randezvous
    with the comet is included in the delta V computations.

    .. note::

       A significantly similar version of this problem was part of the no longer maintained GTOP database, 
       https://www.esa.int/gsp/ACT/projects/gtop/gtop.html. The exact definition is, though, different and results
Exemple #29
0
    def __init__(self,
                 seq=[jpl_lp('earth'),
                      jpl_lp('venus'),
                      jpl_lp('earth')],
                 n_seg=[10] * 2,
                 t0=[epoch(0), epoch(1000)],
                 tof=[[200, 500], [200, 500]],
                 vinf_dep=2.5,
                 vinf_arr=2.0,
                 mass=4000.0,
                 Tmax=1.0,
                 Isp=2000.0,
                 fb_rel_vel=6,
                 multi_objective=False,
                 high_fidelity=False):
        """
        prob = mga_lt_nep(seq = [jpl_lp('earth'),jpl_lp('venus'),jpl_lp('earth')], n_seg = [10]*2,
        t0 = [epoch(0),epoch(1000)], tof = [[200,500],[200,500]], vinf_dep=2.5, vinf_arr=2.0, mass=4000.0, Tmax=1.0, Isp=2000.0,
        multi_objective = False, fb_rel_vel = 6, high_fidelity=False)

        - seq: list of pykep.planet defining the encounter sequence for the trajectoty (including the initial planet)
        - n_seg: list of integers containing the number of segments to be used for each leg (len(n_seg) = len(seq)-1)
        - t0: list of pykep epochs defining the launch window
        - tof: minimum and maximum time of each leg (days)
        - vinf_dep: maximum launch hyperbolic velocity allowed (in km/sec)
        - vinf_arr: maximum arrival hyperbolic velocity allowed (in km/sec)
        - mass: spacecraft starting mass
        - Tmax: maximum thrust
        - Isp: engine specific impulse
        - fb_rel_vel = determines the bounds on the maximum allowed relative velocity at all fly-bys (in km/sec)
        - multi-objective: when True defines the problem as a multi-objective problem, returning total DV and time of flight
        - high_fidelity = makes the trajectory computations slower, but actually dynamically feasible.
        """

        # 1) We compute the problem dimensions .... and call the base problem
        # constructor
        self.__n_legs = len(seq) - 1
        n_fb = self.__n_legs - 1
        # 1a) The decision vector length
        dim = 1 + self.__n_legs * 8 + sum(n_seg) * 3
        # 1b) The total number of constraints (mismatch + fly-by + boundary +
        # throttles
        c_dim = self.__n_legs * 7 + n_fb * 2 + 2 + sum(n_seg)
        # 1c) The number of inequality constraints (boundary + fly-by angle +
        # throttles)
        c_ineq_dim = 2 + n_fb + sum(n_seg)
        # 1d) the number of objectives
        f_dim = multi_objective + 1
        # First we call the constructor for the base pygmo problem
        # As our problem is n dimensional, box-bounded (may be multi-objective), we write
        # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation)
        super(mga_lt_nep, self).__init__(dim, 0, f_dim, c_dim, c_ineq_dim,
                                         1e-4)

        # 2) We then define some class data members
        # public:
        self.seq = seq
        # private:
        self.__n_seg = n_seg
        self.__vinf_dep = vinf_dep * 1000
        self.__vinf_arr = vinf_arr * 1000
        self.__sc = spacecraft(mass, Tmax, Isp)
        self.__leg = leg()
        self.__leg.set_mu(MU_SUN)
        self.__leg.set_spacecraft(self.__sc)
        self.__leg.high_fidelity = high_fidelity
        fb_rel_vel *= 1000
        # 3) We compute the bounds
        lb = [t0[0].mjd2000] + [
            0, mass / 2, -fb_rel_vel, -fb_rel_vel, -fb_rel_vel, -fb_rel_vel,
            -fb_rel_vel, -fb_rel_vel
        ] * self.__n_legs + [-1, -1, -1] * sum(self.__n_seg)
        ub = [t0[1].mjd2000] + [
            1, mass, fb_rel_vel, fb_rel_vel, fb_rel_vel, fb_rel_vel,
            fb_rel_vel, fb_rel_vel
        ] * self.__n_legs + [1, 1, 1] * sum(self.__n_seg)
        # 3a ... and account for the bounds on the vinfs......
        lb[3:6] = [-self.__vinf_dep] * 3
        ub[3:6] = [self.__vinf_dep] * 3
        lb[-sum(self.__n_seg) * 3 - 3:-sum(self.__n_seg) *
           3] = [-self.__vinf_arr] * 3
        ub[-sum(self.__n_seg) * 3 - 3:-sum(self.__n_seg) *
           3] = [self.__vinf_arr] * 3
        # 3b... and for the time of flight
        lb[1:1 + 8 * self.__n_legs:8] = [el[0] for el in tof]
        ub[1:1 + 8 * self.__n_legs:8] = [el[1] for el in tof]

        # 4) And we set the bounds
        self.set_bounds(lb, ub)