Exemplo n.º 1
0
def plot_taylor(r0,
                v0,
                m0,
                thrust,
                tof,
                mu,
                veff,
                N=60,
                units=1,
                color='b',
                legend=False,
                axes=None):
    """
    ax = plot_taylor(r0, v0, m0, thrust, tof, mu, veff, N=60, units=1, color='b', legend=False, axes=None):

    - axes:	3D axis object created using fig.gca(projection='3d')
    - r0:	initial position (cartesian coordinates)
    - v0:	initial velocity (cartesian coordinates)
    - m0: 	initial mass
    - u:	cartesian components for the constant thrust
    - tof:	propagation time
    - mu:	gravitational parameter
    - veff:	the product Isp * g0
    - N:	number of points to be plotted along one arc
    - units:	the length unit to be used in the plot
    - color:	matplotlib color to use to plot the line
    - legend:	when True it plots also the legend

    Plots the result of a taylor propagation of constant thrust

    Example::

	import pykep as pk
	import matplotlib.pyplot as plt
	pi = 3.14

	fig = plt.figure()
	ax = fig.gca(projection = '3d')
	pk.orbit_plots.plot_taylor([1,0,0],[0,1,0],100,[1,1,0],40, 1, 1, N = 1000, axes = ax)
	plt.show()
    """

    from pykep import propagate_taylor
    import matplotlib.pyplot as plt

    if axes is None:
        fig = plt.figure()
        ax = fig.gca(projection='3d')
    else:
        ax = axes

    # We define the integration time ...
    dt = tof / (N - 1)

    # ... and calcuate the cartesian components for r
    x = [0.0] * N
    y = [0.0] * N
    z = [0.0] * N

    # Replace r0, v0, m0 for r, v, m
    r = r0
    v = v0
    m = m0
    # We calculate the spacecraft position at each dt
    for i in range(N):
        x[i] = r[0] / units
        y[i] = r[1] / units
        z[i] = r[2] / units
        r, v, m = propagate_taylor(r, v, m, thrust, dt, mu, veff, -10, -10)

    # And we plot
    if legend:
        label = 'constant thrust arc'
    else:
        label = None
    ax.plot(x, y, z, c=color, label=label)

    if legend:
        ax.legend()

    if axes is None:  # show only if axis is not set
        plt.show()
    return ax
Exemplo n.º 2
0
def plot_sf_leg(leg,
                N=5,
                units=1,
                color='b',
                legend=False,
                plot_line=True,
                plot_segments=False,
                axes=None):
    """
    ax = plot_sf_leg(leg, N=5, units=1, color='b', legend=False, no_trajectory=False, axes=None):

    - axes:	    3D axis object created using fig.gca(projection='3d')
    - leg:	    a pykep.sims_flanagan.leg
    - N:	    number of points to be plotted along one arc
    - units:	    the length unit to be used in the plot
    - color:	    matplotlib color to use to plot the trajectory and the grid points
    - legend	    when True it plots also the legend
    - plot_line:    when True plots also the trajectory (between mid-points and grid points)

    Plots a Sims-Flanagan leg

    Example::

        from mpl_toolkits.mplot3d import Axes3D
        import matplotlib.pyplot as plt

        fig = plt.figure()
        ax = fig.gca(projection='3d')
        t1 = epoch(0)
        pl = planet_ss('earth')
        rE,vE = pl.eph(t1)
        plot_planet(pl,t0=t1, units=AU, axes=ax)

        t2 = epoch(440)
        pl = planet_ss('mars')
        rM, vM = pl.eph(t2)
        plot_planet(pl,t0=t2, units=AU, axes=ax)

        sc = sims_flanagan.spacecraft(4500,0.5,2500)
        x0 = sims_flanagan.sc_state(rE,vE,sc.mass)
        xe = sims_flanagan.sc_state(rM,vM,sc.mass)
        l = sims_flanagan.leg(t1,x0,[1,0,0]*5,t2,xe,sc,MU_SUN)

        plot_sf_leg(l, units=AU, axes=ax)
    """
    from pykep import propagate_lagrangian, AU, DAY2SEC, G0, propagate_taylor
    import numpy as np
    from scipy.linalg import norm
    from math import exp
    import matplotlib.pylab as plt
    from mpl_toolkits.mplot3d import Axes3D

    if axes is None:
        fig = plt.figure()
        ax = fig.gca(projection='3d')
    else:
        ax = axes

    # We compute the number of segments for forward and backward propagation
    n_seg = len(leg.get_throttles())
    fwd_seg = (n_seg + 1) // 2
    back_seg = n_seg // 2

    # We extract information on the spacecraft
    sc = leg.get_spacecraft()
    isp = sc.isp
    max_thrust = sc.thrust

    # And on the leg
    throttles = leg.get_throttles()
    mu = leg.get_mu()

    # Forward propagation

    # x,y,z contain the cartesian components of all points (grid+midpoints)
    x = [0.0] * (fwd_seg * 2 + 1)
    y = [0.0] * (fwd_seg * 2 + 1)
    z = [0.0] * (fwd_seg * 2 + 1)

    state = leg.get_xi()

    # Initial conditions
    r = state.r
    v = state.v
    m = state.m
    x[0] = r[0] / units
    y[0] = r[1] / units
    z[0] = r[2] / units

    # We compute all points by propagation
    for i, t in enumerate(throttles[:fwd_seg]):
        dt = (t.end.mjd - t.start.mjd) * DAY2SEC
        alpha = min(norm(t.value), 1.0)
        # Keplerian propagation and dV application
        if leg.high_fidelity is False:
            dV = [max_thrust / m * dt * dumb for dumb in t.value]
            if plot_line:
                plot_kepler(r,
                            v,
                            dt / 2,
                            mu,
                            N=N,
                            units=units,
                            color=(alpha, 0, 1 - alpha),
                            axes=ax)
            r, v = propagate_lagrangian(r, v, dt / 2, mu)
            x[2 * i + 1] = r[0] / units
            y[2 * i + 1] = r[1] / units
            z[2 * i + 1] = r[2] / units
            # v= v+dV
            v = [a + b for a, b in zip(v, dV)]
            if plot_line:
                plot_kepler(r,
                            v,
                            dt / 2,
                            mu,
                            N=N,
                            units=units,
                            color=(alpha, 0, 1 - alpha),
                            axes=ax)
            r, v = propagate_lagrangian(r, v, dt / 2, mu)
            x[2 * i + 2] = r[0] / units
            y[2 * i + 2] = r[1] / units
            z[2 * i + 2] = r[2] / units
            m *= exp(-norm(dV) / isp / G0)
        # Taylor propagation of constant thrust u
        else:
            u = [max_thrust * dumb for dumb in t.value]
            if plot_line:
                plot_taylor(r,
                            v,
                            m,
                            u,
                            dt / 2,
                            mu,
                            isp * G0,
                            N=N,
                            units=units,
                            color=(alpha, 0, 1 - alpha),
                            axes=ax)
            r, v, m = propagate_taylor(r, v, m, u, dt / 2, mu, isp * G0, -12,
                                       -12)
            x[2 * i + 1] = r[0] / units
            y[2 * i + 1] = r[1] / units
            z[2 * i + 1] = r[2] / units
            if plot_line:
                plot_taylor(r,
                            v,
                            m,
                            u,
                            dt / 2,
                            mu,
                            isp * G0,
                            N=N,
                            units=units,
                            color=(alpha, 0, 1 - alpha),
                            axes=ax)
            r, v, m = propagate_taylor(r, v, m, u, dt / 2, mu, isp * G0, -12,
                                       -12)
            x[2 * i + 2] = r[0] / units
            y[2 * i + 2] = r[1] / units
            z[2 * i + 2] = r[2] / units

    x_grid = x[::2]
    y_grid = y[::2]
    z_grid = z[::2]
    x_midpoint = x[1::2]
    y_midpoint = y[1::2]
    z_midpoint = z[1::2]
    if plot_segments:
        ax.scatter(x_grid[:-1],
                   y_grid[:-1],
                   z_grid[:-1],
                   label='nodes',
                   marker='o')
        ax.scatter(x_midpoint,
                   y_midpoint,
                   z_midpoint,
                   label='mid-points',
                   marker='x')
        ax.scatter(x_grid[-1],
                   y_grid[-1],
                   z_grid[-1],
                   marker='^',
                   c='y',
                   label='mismatch point')

    # Backward propagation

    # x,y,z will contain the cartesian components of
    x = [0.0] * (back_seg * 2 + 1)
    y = [0.0] * (back_seg * 2 + 1)
    z = [0.0] * (back_seg * 2 + 1)

    state = leg.get_xf()

    # Final conditions
    r = state.r
    v = state.v
    m = state.m
    x[-1] = r[0] / units
    y[-1] = r[1] / units
    z[-1] = r[2] / units

    for i, t in enumerate(throttles[-1:-back_seg - 1:-1]):
        dt = (t.end.mjd - t.start.mjd) * DAY2SEC
        alpha = min(norm(t.value), 1.0)
        if leg.high_fidelity is False:
            dV = [max_thrust / m * dt * dumb for dumb in t.value]
            if plot_line:
                plot_kepler(r,
                            v,
                            -dt / 2,
                            mu,
                            N=N,
                            units=units,
                            color=(alpha, 0, 1 - alpha),
                            axes=ax)
            r, v = propagate_lagrangian(r, v, -dt / 2, mu)
            x[-2 * i - 2] = r[0] / units
            y[-2 * i - 2] = r[1] / units
            z[-2 * i - 2] = r[2] / units
            # v= v+dV
            v = [a - b for a, b in zip(v, dV)]
            if plot_line:
                plot_kepler(r,
                            v,
                            -dt / 2,
                            mu,
                            N=N,
                            units=units,
                            color=(alpha, 0, 1 - alpha),
                            axes=ax)
            r, v = propagate_lagrangian(r, v, -dt / 2, mu)
            x[-2 * i - 3] = r[0] / units
            y[-2 * i - 3] = r[1] / units
            z[-2 * i - 3] = r[2] / units
            m *= exp(norm(dV) / isp / G0)
        else:
            u = [max_thrust * dumb for dumb in t.value]
            if plot_line:
                plot_taylor(r,
                            v,
                            m,
                            u,
                            -dt / 2,
                            mu,
                            isp * G0,
                            N=N,
                            units=units,
                            color=(alpha, 0, 1 - alpha),
                            axes=ax)
            r, v, m = propagate_taylor(r, v, m, u, -dt / 2, mu, isp * G0, -12,
                                       -12)
            x[-2 * i - 2] = r[0] / units
            y[-2 * i - 2] = r[1] / units
            z[-2 * i - 2] = r[2] / units
            if plot_line:
                plot_taylor(r,
                            v,
                            m,
                            u,
                            -dt / 2,
                            mu,
                            isp * G0,
                            N=N,
                            units=units,
                            color=(alpha, 0, 1 - alpha),
                            axes=ax)
            r, v, m = propagate_taylor(r, v, m, u, -dt / 2, mu, isp * G0, -12,
                                       -12)
            x[-2 * i - 3] = r[0] / units
            y[-2 * i - 3] = r[1] / units
            z[-2 * i - 3] = r[2] / units

    x_grid = x[::2]
    y_grid = y[::2]
    z_grid = z[::2]
    x_midpoint = x[1::2]
    y_midpoint = y[1::2]
    z_midpoint = z[1::2]

    if plot_segments:
        ax.scatter(x_grid[1:],
                   y_grid[1:],
                   z_grid[1:],
                   marker='o',
                   label='nodes')
        ax.scatter(x_midpoint,
                   y_midpoint,
                   z_midpoint,
                   marker='x',
                   label='mid-points')
        ax.scatter(x_grid[0],
                   y_grid[0],
                   z_grid[0],
                   marker='^',
                   c='y',
                   label='mismatch point')

    if legend:
        ax.legend()

    if axes is None:  # show only if axis is not set
        plt.show()
    return ax
Exemplo n.º 3
0
def _leg_eph(self, t, debug=False):
    """
    Computes the ephemerides (r, v) along the leg.  Should only be called on high_fidelity legs having
    no state mismatch. Otherwise the values returned will not correspond to physical quantities.

     - t: epoch (either a pykep epoch, or assumes mjd2000). This value must be between self.get_ti() and self.get_tf()
    """
    from pykep import epoch, propagate_taylor, G0, DAY2SEC
    from bisect import bisect

    if isinstance(t, epoch):
        t0 = t.mjd2000
    else:
        t0 = t

    # We extract the leg states
    t_grid, r, v, m = self.get_states()

    # We check that requested epoch is valid
    if (t0 < t_grid[0]) or (t0 > t_grid[-1]):
        raise ValueError("The requested epoch is out of bounds")

    # We check that the leg is high fidelity, otherwise this makes little sense
    if not self.high_fidelity:
        raise ValueError(
            "The eph method works only for high fidelity legs at the moment")

    # Extract some information from the leg
    mu = self.get_mu()
    sc = self.get_spacecraft()
    isp = sc.isp
    max_thrust = sc.thrust
    t_grid, r, v, m = self.get_states()

    # If by chance its in the grid node, we are done
    if t0 in t_grid:
        idx = t_grid.index(t0)
        if debug:
            raise ValueError("DEBUG!!!!")
        return r[idx], v[idx], m[idx]

    # Find the index to start from (need to account for the midpoint
    # repetition)
    idx = bisect(t_grid, t0) - 1

    # We compute the number of segments of forward propagation
    n_seg = len(self.get_throttles())
    fwd_seg = (n_seg + 1) // 2

    # We start with the backward propagation cases
    if idx > 2 * fwd_seg:
        r0 = r[idx + 1]
        v0 = v[idx + 1]
        m0 = m[idx + 1]
        idx_thrust = (idx - 1) / 2
        dt_int = (t_grid[idx + 1] - t0) * DAY2SEC
        th = self.get_throttles()[idx_thrust].value
        if debug:
            raise ValueError("DEBUG!!!!")
        return propagate_taylor(r0, v0, m0, [d * max_thrust for d in th], -dt_int, mu, isp * G0, -12, -12)

    # Find the index to start from
    idx = bisect(t_grid, t0) - 1
    r0 = r[idx]
    v0 = v[idx]
    m0 = m[idx]
    idx_thrust = idx / 2
    dt_int = (t0 - t_grid[idx]) * DAY2SEC
    th = self.get_throttles()[idx_thrust].value
    if debug:
        raise ValueError("DEBUG!!!!")
    return propagate_taylor(r0, v0, m0, [d * max_thrust for d in th], dt_int, mu, isp * G0, -12, -12)
Exemplo n.º 4
0
    def _propagate(self, x):
        # 1 - We decode the chromosome
        t0 = x[0]
        T = x[1]
        m_f = x[2]
        # We extract the number of segments for forward and backward
        # propagation
        n_seg = self.__n_seg
        fwd_seg = self.__fwd_seg
        bwd_seg = self.__bwd_seg
        # We extract information on the spacecraft
        m_i = self.__sc.mass
        max_thrust = self.__sc.thrust
        isp = self.__sc.isp
        veff = isp * pk.G0
        # And on the leg
        throttles = [x[3 + 3 * i: 6 + 3 * i] for i in range(n_seg)]
        # Return lists
        n_points_fwd = fwd_seg + 1
        n_points_bwd = bwd_seg + 1
        rfwd = [[0.0] * 3] * (n_points_fwd)
        vfwd = [[0.0] * 3] * (n_points_fwd)
        mfwd = [0.0] * (n_points_fwd)
        ufwd = [[0.0] * 3] * (fwd_seg)
        dfwd = [[0.0] * 3] * (fwd_seg)  # distances E/S
        rbwd = [[0.0] * 3] * (n_points_bwd)
        vbwd = [[0.0] * 3] * (n_points_bwd)
        mbwd = [0.0] * (n_points_bwd)
        ubwd = [[0.0] * 3] * (bwd_seg)
        dbwd = [[0.0] * 3] * (bwd_seg)

        # 2 - We compute the initial and final epochs and ephemerides
        t_i = pk.epoch(t0)
        r_i, v_i = self.__earth.eph(t_i)
        if self.__start == 'l1':
            r_i = [r * 0.99 for r in r_i]
            v_i = [v * 0.99 for v in v_i]
        elif self.__start == 'l2':
            r_i = [r * 1.01 for r in r_i]
            v_i = [v * 1.01 for v in v_i]
        t_f = pk.epoch(t0 + T)
        r_f, v_f = self.target.eph(t_f)

        # 3 - Forward propagation
        fwd_grid = t0 + T * self.__fwd_grid  # days
        fwd_dt = T * self.__fwd_dt  # seconds
        # Initial conditions
        rfwd[0] = r_i
        vfwd[0] = v_i
        mfwd[0] = m_i
        # Propagate
        for i, t in enumerate(throttles[:fwd_seg]):
            if self.__sep:
                r = math.sqrt(rfwd[i][0]**2 + rfwd[i][1]
                              ** 2 + rfwd[i][2]**2) / pk.AU
                max_thrust, isp = self._sep_model(r)
                veff = isp * pk.G0
            ufwd[i] = [max_thrust * thr for thr in t]
            if self.__earth_gravity:
                r_E, v_E = self.__earth.eph(pk.epoch(fwd_grid[i]))
                dfwd[i] = [a - b for a, b in zip(r_E, rfwd[i])]
                r3 = sum([r**2 for r in dfwd[i]])**(3 / 2)
                disturbance = [mfwd[i] * pk.MU_EARTH /
                               r3 * ri for ri in dfwd[i]]
                rfwd[i + 1], vfwd[i + 1], mfwd[i + 1] = pk.propagate_taylor_disturbance(
                    rfwd[i], vfwd[i], mfwd[i], ufwd[i], disturbance, fwd_dt[i], pk.MU_SUN, veff, -10, -10)
            else:
                rfwd[i + 1], vfwd[i + 1], mfwd[i + 1] = pk.propagate_taylor(
                    rfwd[i], vfwd[i], mfwd[i], ufwd[i], fwd_dt[i], pk.MU_SUN, veff, -10, -10)

        # 4 - Backward propagation
        bwd_grid = t0 + T * self.__bwd_grid  # days
        bwd_dt = T * self.__bwd_dt  # seconds
        # Final conditions
        rbwd[-1] = r_f
        vbwd[-1] = v_f
        mbwd[-1] = m_f
        # Propagate
        for i, t in enumerate(throttles[-1:-bwd_seg - 1:-1]):
            if self.__sep:
                r = math.sqrt(rbwd[-i - 1][0]**2 + rbwd[-i - 1]
                              [1]**2 + rbwd[-i - 1][2]**2) / pk.AU
                max_thrust, isp = self._sep_model(r)
                veff = isp * pk.G0
            ubwd[-i - 1] = [max_thrust * thr for thr in t]
            if self.__earth_gravity:
                r_E, v_E = self.__earth.eph(pk.epoch(bwd_grid[-i - 1]))
                dbwd[-i - 1] = [a - b for a, b in zip(r_E, rbwd[-i - 1])]
                r3 = sum([r**2 for r in dbwd[-i - 1]])**(3 / 2)
                disturbance = [mfwd[i] * pk.MU_EARTH /
                               r3 * ri for ri in dbwd[-i - 1]]
                rbwd[-i - 2], vbwd[-i - 2], mbwd[-i - 2] = pk.propagate_taylor_disturbance(
                    rbwd[-i - 1], vbwd[-i - 1], mbwd[-i - 1], ubwd[-i - 1], disturbance, -bwd_dt[-i - 1], pk.MU_SUN, veff, -10, -10)
            else:
                rbwd[-i - 2], vbwd[-i - 2], mbwd[-i - 2] = pk.propagate_taylor(
                    rbwd[-i - 1], vbwd[-i - 1], mbwd[-i - 1], ubwd[-i - 1], -bwd_dt[-i - 1], pk.MU_SUN, veff, -10, -10)

        return rfwd, rbwd, vfwd, vbwd, mfwd, mbwd, ufwd, ubwd, fwd_dt, bwd_dt, dfwd, dbwd
Exemplo n.º 5
0
def _leg_get_states(self):
    """
    Returns the spacecraft states (t,r,v,m) at the leg grid points

    Examples::

      times,r,v,m = pykep.sims_flanagan.leg.get_states()
    """
    from pykep import propagate_lagrangian, AU, DAY2SEC, G0, propagate_taylor
    import numpy as np
    from scipy.linalg import norm
    from math import exp

    # We compute the number of segments for forward and backward propagation
    n_seg = len(self.get_throttles())
    fwd_seg = (n_seg + 1) // 2
    back_seg = n_seg // 2

    # We extract information on the spacecraft
    sc = self.get_spacecraft()
    isp = sc.isp
    max_thrust = sc.thrust

    # And on the leg
    throttles = self.get_throttles()
    mu = self.get_mu()

    # time grid (the mismatch is repeated twice)
    t_grid = [0.0] * (n_seg * 2 + 2)

    # Forward propagation

    # x,y,z contain the cartesian components of all points (grid+midpints)
    x = [0.0] * (fwd_seg * 2 + 1)
    y = [0.0] * (fwd_seg * 2 + 1)
    z = [0.0] * (fwd_seg * 2 + 1)
    vx = [0.0] * (fwd_seg * 2 + 1)
    vy = [0.0] * (fwd_seg * 2 + 1)
    vz = [0.0] * (fwd_seg * 2 + 1)
    mass = [0.0] * (fwd_seg * 2 + 1)

    state = self.get_xi()

    # Initial conditions
    r = state.r
    v = state.v
    m = state.m
    x[0], y[0], z[0] = r
    vx[0], vy[0], vz[0] = v
    mass[0] = m

    # We compute all points by propagation
    for i, t in enumerate(throttles[:fwd_seg]):
        t_grid[2 * i] = t.start.mjd2000
        t_grid[2 * i + 1] = t.start.mjd2000 + \
            (t.end.mjd2000 - t.start.mjd2000) / 2.
        dt = (t.end.mjd - t.start.mjd) * DAY2SEC
        alpha = min(norm(t.value), 1.0)
        # Keplerian propagation and dV application
        if self.high_fidelity is False:
            dV = [max_thrust / m * dt * dumb for dumb in t.value]

            r, v = propagate_lagrangian(r, v, dt / 2, mu)
            x[2 * i + 1], y[2 * i + 1], z[2 * i + 1] = r
            vx[2 * i + 1], vy[2 * i + 1], vz[2 * i + 1] = v
            mass[2 * i + 1] = m
            # v= v+dV
            v = [a + b for a, b in zip(v, dV)]
            r, v = propagate_lagrangian(r, v, dt / 2, mu)
            m *= exp(-norm(dV) / isp / G0)

            x[2 * i + 2], y[2 * i + 2], z[2 * i + 2] = r
            vx[2 * i + 2], vy[2 * i + 2], vz[2 * i + 2] = v
            mass[2 * i + 2] = m

        # Taylor propagation of constant thrust u
        else:
            u = [max_thrust * dumb for dumb in t.value]

            r, v, m = propagate_taylor(
                r, v, m, u, dt / 2, mu, isp * G0, -12, -12)
            x[2 * i + 1], y[2 * i + 1], z[2 * i + 1] = r
            vx[2 * i + 1], vy[2 * i + 1], vz[2 * i + 1] = v
            mass[2 * i + 1] = m

            r, v, m = propagate_taylor(
                r, v, m, u, dt / 2, mu, isp * G0, -12, -12)
            x[2 * i + 2], y[2 * i + 2], z[2 * i + 2] = r
            vx[2 * i + 2], vy[2 * i + 2], vz[2 * i + 2] = v
            mass[2 * i + 2] = m

    t_grid[2 * i + 2] = t.end.mjd2000

    # Backward propagation

    # x,y,z will contain the cartesian components of
    x_back = [0.123] * (back_seg * 2 + 1)
    y_back = [0.123] * (back_seg * 2 + 1)
    z_back = [0.123] * (back_seg * 2 + 1)
    vx_back = [0.0] * (back_seg * 2 + 1)
    vy_back = [0.0] * (back_seg * 2 + 1)
    vz_back = [0.0] * (back_seg * 2 + 1)
    mass_back = [0.0] * (back_seg * 2 + 1)

    state = self.get_xf()

    # Final conditions
    r = state.r
    v = state.v
    m = state.m
    x_back[-1], y_back[-1], z_back[-1] = r
    vx_back[-1], vy_back[-1], vz_back[-1] = v
    mass_back[-1] = m

    for i, t in enumerate(throttles[-1:-back_seg - 1:-1]):
        t_grid[-2 * i - 2] = t.end.mjd2000 - \
            (t.end  .mjd2000 - t.start.mjd2000) / 2.
        t_grid[-2 * i - 1] = t.end.mjd2000
        dt = (t.end.mjd - t.start.mjd) * DAY2SEC
        alpha = min(norm(t.value), 1.0)
        if self.high_fidelity is False:
            dV = [max_thrust / m * dt * dumb for dumb in t.value]
            r, v = propagate_lagrangian(r, v, -dt / 2, mu)
            x_back[-2 * i - 2], y_back[-2 * i - 2], z_back[-2 * i - 2] = r
            vx_back[-2 * i - 2], vy_back[-2 * i - 2], vz_back[-2 * i - 2] = v
            mass_back[-2 * i - 2] = m
            # v= v+dV
            v = [a - b for a, b in zip(v, dV)]
            r, v = propagate_lagrangian(r, v, -dt / 2, mu)
            m *= exp(norm(dV) / isp / G0)

            x_back[-2 * i - 3], y_back[-2 * i - 3], z_back[-2 * i - 3] = r
            vx_back[-2 * i - 3], vy_back[-2 * i - 3], vz_back[-2 * i - 3] = v
            mass_back[-2 * i - 3] = m

        else:
            u = [max_thrust * dumb for dumb in t.value]
            r, v, m = propagate_taylor(
                r, v, m, u, -dt / 2, mu, isp * G0, -12, -12)
            x_back[-2 * i - 2], y_back[-2 * i - 2], z_back[-2 * i - 2] = r
            vx_back[-2 * i - 2], vy_back[-2 * i - 2], vz_back[-2 * i - 2] = v
            mass_back[-2 * i - 2] = m

            r, v, m = propagate_taylor(
                r, v, m, u, -dt / 2, mu, isp * G0, -12, -12)
            x_back[-2 * i - 3], y_back[-2 * i - 3], z_back[-2 * i - 3] = r
            vx_back[-2 * i - 3], vy_back[-2 * i - 3], vz_back[-2 * i - 3] = v
            mass_back[-2 * i - 3] = m

    t_grid[-2 * i - 3] = t.start.mjd2000
    x = x + x_back
    y = y + y_back
    z = z + z_back
    vx = vx + vx_back
    vy = vy + vy_back
    vz = vz + vz_back
    mass = mass + mass_back

    return t_grid, list(zip(x, y, z)), list(zip(vx, vy, vz)), mass
Exemplo n.º 6
0
def _leg_eph(self, t, debug=False):
    """
    Computes the ephemerides (r, v) along the leg.  Should only be called on high_fidelity legs having
    no state mismatch. Otherwise the values returned will not correspond to physical quantities.

     - t: epoch (either a pykep epoch, or assumes mjd2000). This value must be between self.get_ti() and self.get_tf()
    """
    from pykep import epoch, propagate_taylor, G0, DAY2SEC
    from bisect import bisect

    if isinstance(t, epoch):
        t0 = t.mjd2000
    else:
        t0 = t

    # We extract the leg states
    t_grid, r, v, m = self.get_states()

    # We check that requested epoch is valid
    if (t0 < t_grid[0]) or (t0 > t_grid[-1]):
        raise ValueError("The requested epoch is out of bounds")

    # We check that the leg is high fidelity, otherwise this makes little sense
    if not self.high_fidelity:
        raise ValueError(
            "The eph method works only for high fidelity legs at the moment")

    # Extract some information from the leg
    mu = self.get_mu()
    sc = self.get_spacecraft()
    isp = sc.isp
    max_thrust = sc.thrust
    t_grid, r, v, m = self.get_states()

    # If by chance its in the grid node, we are done
    if t0 in t_grid:
        idx = t_grid.index(t0)
        if debug:
            raise ValueError("DEBUG!!!!")
        return r[idx], v[idx], m[idx]

    # Find the index to start from (need to account for the midpoint
    # repetition)
    idx = bisect(t_grid, t0) - 1

    # We compute the number of segments of forward propagation
    n_seg = len(self.get_throttles())
    fwd_seg = (n_seg + 1) // 2

    # We start with the backward propagation cases
    if idx > 2 * fwd_seg:
        r0 = r[idx + 1]
        v0 = v[idx + 1]
        m0 = m[idx + 1]
        idx_thrust = (idx - 1) / 2
        dt_int = (t_grid[idx + 1] - t0) * DAY2SEC
        th = self.get_throttles()[idx_thrust].value
        if debug:
            raise ValueError("DEBUG!!!!")
        return propagate_taylor(r0, v0, m0, [d * max_thrust for d in th],
                                -dt_int, mu, isp * G0, -12, -12)

    # Find the index to start from
    idx = bisect(t_grid, t0) - 1
    r0 = r[idx]
    v0 = v[idx]
    m0 = m[idx]
    idx_thrust = idx / 2
    dt_int = (t0 - t_grid[idx]) * DAY2SEC
    th = self.get_throttles()[idx_thrust].value
    if debug:
        raise ValueError("DEBUG!!!!")
    return propagate_taylor(r0, v0, m0, [d * max_thrust for d in th], dt_int,
                            mu, isp * G0, -12, -12)
Exemplo n.º 7
0
def _leg_get_states(self):
    """
    Returns the spacecraft states (t,r,v,m) at the leg grid points

    Examples::

      times,r,v,m = pykep.sims_flanagan.leg.get_states()
    """
    from pykep import propagate_lagrangian, AU, DAY2SEC, G0, propagate_taylor
    import numpy as np
    from scipy.linalg import norm
    from math import exp

    # We compute the number of segments for forward and backward propagation
    n_seg = len(self.get_throttles())
    fwd_seg = (n_seg + 1) // 2
    back_seg = n_seg // 2

    # We extract information on the spacecraft
    sc = self.get_spacecraft()
    isp = sc.isp
    max_thrust = sc.thrust

    # And on the leg
    throttles = self.get_throttles()
    mu = self.get_mu()

    # time grid (the mismatch is repeated twice)
    t_grid = [0.0] * (n_seg * 2 + 2)

    # Forward propagation

    # x,y,z contain the cartesian components of all points (grid+midpints)
    x = [0.0] * (fwd_seg * 2 + 1)
    y = [0.0] * (fwd_seg * 2 + 1)
    z = [0.0] * (fwd_seg * 2 + 1)
    vx = [0.0] * (fwd_seg * 2 + 1)
    vy = [0.0] * (fwd_seg * 2 + 1)
    vz = [0.0] * (fwd_seg * 2 + 1)
    mass = [0.0] * (fwd_seg * 2 + 1)

    state = self.get_xi()

    # Initial conditions
    r = state.r
    v = state.v
    m = state.m
    x[0], y[0], z[0] = r
    vx[0], vy[0], vz[0] = v
    mass[0] = m

    # We compute all points by propagation
    for i, t in enumerate(throttles[:fwd_seg]):
        t_grid[2 * i] = t.start.mjd2000
        t_grid[2 * i + 1] = t.start.mjd2000 + \
            (t.end.mjd2000 - t.start.mjd2000) / 2.
        dt = (t.end.mjd - t.start.mjd) * DAY2SEC
        alpha = min(norm(t.value), 1.0)
        # Keplerian propagation and dV application
        if self.high_fidelity is False:
            dV = [max_thrust / m * dt * dumb for dumb in t.value]

            r, v = propagate_lagrangian(r, v, dt / 2, mu)
            x[2 * i + 1], y[2 * i + 1], z[2 * i + 1] = r
            vx[2 * i + 1], vy[2 * i + 1], vz[2 * i + 1] = v
            mass[2 * i + 1] = m
            # v= v+dV
            v = [a + b for a, b in zip(v, dV)]
            r, v = propagate_lagrangian(r, v, dt / 2, mu)
            m *= exp(-norm(dV) / isp / G0)

            x[2 * i + 2], y[2 * i + 2], z[2 * i + 2] = r
            vx[2 * i + 2], vy[2 * i + 2], vz[2 * i + 2] = v
            mass[2 * i + 2] = m

        # Taylor propagation of constant thrust u
        else:
            u = [max_thrust * dumb for dumb in t.value]

            r, v, m = propagate_taylor(r, v, m, u, dt / 2, mu, isp * G0, -12,
                                       -12)
            x[2 * i + 1], y[2 * i + 1], z[2 * i + 1] = r
            vx[2 * i + 1], vy[2 * i + 1], vz[2 * i + 1] = v
            mass[2 * i + 1] = m

            r, v, m = propagate_taylor(r, v, m, u, dt / 2, mu, isp * G0, -12,
                                       -12)
            x[2 * i + 2], y[2 * i + 2], z[2 * i + 2] = r
            vx[2 * i + 2], vy[2 * i + 2], vz[2 * i + 2] = v
            mass[2 * i + 2] = m

    t_grid[2 * i + 2] = t.end.mjd2000

    # Backward propagation

    # x,y,z will contain the cartesian components of
    x_back = [0.123] * (back_seg * 2 + 1)
    y_back = [0.123] * (back_seg * 2 + 1)
    z_back = [0.123] * (back_seg * 2 + 1)
    vx_back = [0.0] * (back_seg * 2 + 1)
    vy_back = [0.0] * (back_seg * 2 + 1)
    vz_back = [0.0] * (back_seg * 2 + 1)
    mass_back = [0.0] * (back_seg * 2 + 1)

    state = self.get_xf()

    # Final conditions
    r = state.r
    v = state.v
    m = state.m
    x_back[-1], y_back[-1], z_back[-1] = r
    vx_back[-1], vy_back[-1], vz_back[-1] = v
    mass_back[-1] = m

    for i, t in enumerate(throttles[-1:-back_seg - 1:-1]):
        t_grid[-2 * i - 2] = t.end.mjd2000 - \
            (t.end  .mjd2000 - t.start.mjd2000) / 2.
        t_grid[-2 * i - 1] = t.end.mjd2000
        dt = (t.end.mjd - t.start.mjd) * DAY2SEC
        alpha = min(norm(t.value), 1.0)
        if self.high_fidelity is False:
            dV = [max_thrust / m * dt * dumb for dumb in t.value]
            r, v = propagate_lagrangian(r, v, -dt / 2, mu)
            x_back[-2 * i - 2], y_back[-2 * i - 2], z_back[-2 * i - 2] = r
            vx_back[-2 * i - 2], vy_back[-2 * i - 2], vz_back[-2 * i - 2] = v
            mass_back[-2 * i - 2] = m
            # v= v+dV
            v = [a - b for a, b in zip(v, dV)]
            r, v = propagate_lagrangian(r, v, -dt / 2, mu)
            m *= exp(norm(dV) / isp / G0)

            x_back[-2 * i - 3], y_back[-2 * i - 3], z_back[-2 * i - 3] = r
            vx_back[-2 * i - 3], vy_back[-2 * i - 3], vz_back[-2 * i - 3] = v
            mass_back[-2 * i - 3] = m

        else:
            u = [max_thrust * dumb for dumb in t.value]
            r, v, m = propagate_taylor(r, v, m, u, -dt / 2, mu, isp * G0, -12,
                                       -12)
            x_back[-2 * i - 2], y_back[-2 * i - 2], z_back[-2 * i - 2] = r
            vx_back[-2 * i - 2], vy_back[-2 * i - 2], vz_back[-2 * i - 2] = v
            mass_back[-2 * i - 2] = m

            r, v, m = propagate_taylor(r, v, m, u, -dt / 2, mu, isp * G0, -12,
                                       -12)
            x_back[-2 * i - 3], y_back[-2 * i - 3], z_back[-2 * i - 3] = r
            vx_back[-2 * i - 3], vy_back[-2 * i - 3], vz_back[-2 * i - 3] = v
            mass_back[-2 * i - 3] = m

    t_grid[-2 * i - 3] = t.start.mjd2000
    x = x + x_back
    y = y + y_back
    z = z + z_back
    vx = vx + vx_back
    vy = vy + vy_back
    vz = vz + vz_back
    mass = mass + mass_back

    return t_grid, list(zip(x, y, z)), list(zip(vx, vy, vz)), mass
Exemplo n.º 8
0
    def _propagate(self, x):
        # 1 - We decode the chromosome
        t0 = x[0]
        T = x[1]
        m_f = x[2]
        # We extract the number of segments for forward and backward
        # propagation
        n_seg = self.__n_seg
        fwd_seg = self.__fwd_seg
        bwd_seg = self.__bwd_seg
        # We extract information on the spacecraft
        m_i = self.__sc.mass
        max_thrust = self.__sc.thrust
        isp = self.__sc.isp
        veff = isp * pk.G0
        # And on the leg
        throttles = [x[3 + 3 * i:6 + 3 * i] for i in range(n_seg)]
        # Return lists
        n_points_fwd = fwd_seg + 1
        n_points_bwd = bwd_seg + 1
        rfwd = [[0.0] * 3] * (n_points_fwd)
        vfwd = [[0.0] * 3] * (n_points_fwd)
        mfwd = [0.0] * (n_points_fwd)
        ufwd = [[0.0] * 3] * (fwd_seg)
        dfwd = [[0.0] * 3] * (fwd_seg)  # distances E/S
        rbwd = [[0.0] * 3] * (n_points_bwd)
        vbwd = [[0.0] * 3] * (n_points_bwd)
        mbwd = [0.0] * (n_points_bwd)
        ubwd = [[0.0] * 3] * (bwd_seg)
        dbwd = [[0.0] * 3] * (bwd_seg)

        # 2 - We compute the initial and final epochs and ephemerides
        t_i = pk.epoch(t0)
        r_i, v_i = self.__earth.eph(t_i)
        if self.__start == 'l1':
            r_i = [r * 0.99 for r in r_i]
            v_i = [v * 0.99 for v in v_i]
        elif self.__start == 'l2':
            r_i = [r * 1.01 for r in r_i]
            v_i = [v * 1.01 for v in v_i]
        t_f = pk.epoch(t0 + T)
        r_f, v_f = self.target.eph(t_f)

        # 3 - Forward propagation
        fwd_grid = t0 + T * self.__fwd_grid  # days
        fwd_dt = T * self.__fwd_dt  # seconds
        # Initial conditions
        rfwd[0] = r_i
        vfwd[0] = v_i
        mfwd[0] = m_i
        # Propagate
        for i, t in enumerate(throttles[:fwd_seg]):
            if self.__sep:
                r = math.sqrt(rfwd[i][0]**2 + rfwd[i][1]**2 +
                              rfwd[i][2]**2) / pk.AU
                max_thrust, isp = self._sep_model(r)
                veff = isp * pk.G0
            ufwd[i] = [max_thrust * thr for thr in t]
            if self.__earth_gravity:
                r_E, v_E = self.__earth.eph(pk.epoch(fwd_grid[i]))
                dfwd[i] = [a - b for a, b in zip(r_E, rfwd[i])]
                r3 = sum([r**2 for r in dfwd[i]])**(3 / 2)
                disturbance = [
                    mfwd[i] * pk.MU_EARTH / r3 * ri for ri in dfwd[i]
                ]
                rfwd[i +
                     1], vfwd[i +
                              1], mfwd[i +
                                       1] = pk.propagate_taylor_disturbance(
                                           rfwd[i], vfwd[i], mfwd[i], ufwd[i],
                                           disturbance, fwd_dt[i], pk.MU_SUN,
                                           veff, -10, -10)
            else:
                rfwd[i + 1], vfwd[i + 1], mfwd[i + 1] = pk.propagate_taylor(
                    rfwd[i], vfwd[i], mfwd[i], ufwd[i], fwd_dt[i], pk.MU_SUN,
                    veff, -10, -10)

        # 4 - Backward propagation
        bwd_grid = t0 + T * self.__bwd_grid  # days
        bwd_dt = T * self.__bwd_dt  # seconds
        # Final conditions
        rbwd[-1] = r_f
        vbwd[-1] = v_f
        mbwd[-1] = m_f
        # Propagate
        for i, t in enumerate(throttles[-1:-bwd_seg - 1:-1]):
            if self.__sep:
                r = math.sqrt(rbwd[-i - 1][0]**2 + rbwd[-i - 1][1]**2 +
                              rbwd[-i - 1][2]**2) / pk.AU
                max_thrust, isp = self._sep_model(r)
                veff = isp * pk.G0
            ubwd[-i - 1] = [max_thrust * thr for thr in t]
            if self.__earth_gravity:
                r_E, v_E = self.__earth.eph(pk.epoch(bwd_grid[-i - 1]))
                dbwd[-i - 1] = [a - b for a, b in zip(r_E, rbwd[-i - 1])]
                r3 = sum([r**2 for r in dbwd[-i - 1]])**(3 / 2)
                disturbance = [
                    mfwd[i] * pk.MU_EARTH / r3 * ri for ri in dbwd[-i - 1]
                ]
                rbwd[-i -
                     2], vbwd[-i -
                              2], mbwd[-i -
                                       2] = pk.propagate_taylor_disturbance(
                                           rbwd[-i - 1], vbwd[-i - 1],
                                           mbwd[-i - 1], ubwd[-i - 1],
                                           disturbance, -bwd_dt[-i - 1],
                                           pk.MU_SUN, veff, -10, -10)
            else:
                rbwd[-i - 2], vbwd[-i - 2], mbwd[-i - 2] = pk.propagate_taylor(
                    rbwd[-i - 1], vbwd[-i - 1], mbwd[-i - 1], ubwd[-i - 1],
                    -bwd_dt[-i - 1], pk.MU_SUN, veff, -10, -10)

        return rfwd, rbwd, vfwd, vbwd, mfwd, mbwd, ufwd, ubwd, fwd_dt, bwd_dt, dfwd, dbwd
Exemplo n.º 9
0
def plot_taylor(r,
                v,
                m,
                u,
                t,
                mu,
                veff,
                N=60,
                units=1,
                color='b',
                legend=False,
                ax=None):
    """
    ax = plot_taylor(r, v, m, u, t, mu, veff, N=60, units=1, color='b', legend=False, ax=None):

    - ax:		3D axis object created using fig.gca(projection='3d')
    - r:		initial position (cartesian coordinates)
    - v:		initial velocity (cartesian coordinates)
    - m: 		initial mass
    - u:		cartesian components for the constant thrust
    - t:		propagation time
    - mu:		gravitational parameter
    - veff:	the product Isp * g0
    - N:		number of points to be plotted along one arc
    - units:	the length unit to be used in the plot
    - color:	matplotlib color to use to plot the line
    - legend:	when True it plots also the legend

    Plots the result of a taylor propagation of constant thrust
    """

    from pykep import propagate_taylor
    import matplotlib.pyplot as plt

    if ax is None:
        fig = plt.figure()
        axis = fig.gca(projection='3d')
    else:
        axis = ax

    # We define the integration time ...
    dt = t / (N - 1)

    # ... and calcuate the cartesian components for r
    x = [0.0] * N
    y = [0.0] * N
    z = [0.0] * N

    # We calculate the spacecraft position at each dt
    for i in range(N):
        x[i] = r[0] / units
        y[i] = r[1] / units
        z[i] = r[2] / units
        r, v, m = propagate_taylor(r, v, m, u, dt, mu, veff, -10, -10)

    # And we plot
    if legend:
        label = 'constant thrust arc'
    else:
        label = None
    axis.plot(x, y, z, c=color, label=label)

    if legend:
        axis.legend()

    if ax is None:  # show only if axis is not set
        plt.show()
    return axis