Exemple #1
0
    def solve(self, *args, validate_barker=True, verbose=False, **kwargs):
        "Solves Lambert's problem for the requested transfer."

        # departure and arrival epochs
        dep_t = pk.epoch(self.dep_t, "mjd")
        arr_t = pk.epoch(self.arr_t, "mjd")

        # departure and arrival positions & velocities
        # (could obtain `dep_ast_eph` in `lambert_optimize_dt` and pass it as
        # argument to avoid having it being repeatedly calculated here)

        # r1, v1 = self.dep_ast.eph(dep_t) if dep_ast_eph is None else dep_ast_eph

        r1, v1 = self.dep_ast.eph(dep_t)
        r2, v2 = self.arr_ast.eph(arr_t)

        # Barker equation used to skip useless Lambert computations
        # https://en.wikipedia.org/wiki/Parabolic_trajectory#Barker.27s_equation
        if validate_barker and self.dT < pk.barker(r1, r2, MU_SUN) * SEC2DAY:
            if verbose:
                print(
                    self.dT,
                    "Fails Barker:",
                    self.dT,
                    pk.barker(r1, r2, MU_SUN) * SEC2DAY,
                )
            self.fail()
            return None

        l = pk.lambert_problem(r1, r2, self.dT * DAY2SEC, MU_SUN)

        # don't compute any multi-rev solutions:
        # l = pk.lambert_problem(r1, r2, self.dT * DAY2SEC, MU_SUN, False, 0)

        return l, v1, v2
Exemple #2
0
def process_single_pair(id_start, id_end, departure_dates, transfer_durations, dt):

    obj_start = pykep.planet.gtoc2(id_start)
    obj_end = pykep.planet.gtoc2(id_end)

    DV_matrix = np.zeros((len(transfer_durations), len(departure_dates)))

    for j, dep_date in enumerate(departure_dates):
        for i, transf_dur in enumerate(transfer_durations):

            # Handle times
            t_dep = pykep.epoch(dep_date)
            t_arr = pykep.epoch(dep_date+transf_dur)
            t_flight = (t_arr.mjd2000 - t_dep.mjd2000) * pykep.DAY2SEC

            # Calculate ephemerides
            r_start, v_start = obj_start.eph(t_dep)
            r_end, v_end = obj_end.eph(t_arr)

            # Solve the Lambert problem
            lambert_solution = pykep.lambert_problem(r_start, r_end, t_flight, pykep.MU_SUN)

            # Compute the DV
            DV_start = np.min(np.linalg.norm(np.array(lambert_solution.get_v1()) - np.array(v_start)[np.newaxis, :], axis=1))
            DV_end = np.min(np.linalg.norm(np.array(lambert_solution.get_v2()) - np.array(v_end)[np.newaxis, :], axis=1))
            DV_total = DV_start + DV_end

            if np.isnan(DV_total):
                DV_total = np.inf
            DV_matrix[i,j] = DV_total

    return DV_matrix
def orbit_trajectory(x1_new, x2_new, time):
    '''
    Tool for checking if the motion of the sallite is retrogade or counter - clock wise
    
    Args:
        x1 (numpy array): time and position for point 1 [time1,x1,y1,z1]
        x2 (numpy array): time and position for point 2 [time2,x2,y2,z2]
        time (float): time difference between the 2 points
        
    Returns:
        bool: true if we want to keep retrogade, False if we want counter-clock wise
    '''

    l = pkp.lambert_problem(x1_new, x2_new, time, 398600.4405, False, 0)

    # only one revolution is needed
    v1 = l.get_v1()[0]
    v1 = np.asarray(v1)
    #v1 = np.reshape(v1, 3)
    x1_new = np.asarray(x1_new)

    kep1 = state_kep.state_kep(x1_new, v1)

    if kep1[0] < 0.0:
        traj = True
    elif kep1[1] > 1.0:
        traj = True
    else:
        traj = False

    return traj
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()
def lamberts(x1, x2, traj):
    '''
    Takes two position points - numpy arrays with time,x,y,z as elements
    and produces two vectors with the state vector for both positions using Lamberts solution

    Args:
        x1(numpy array): time and position for point 1 [time1,x1,y1,z1]
        x2(numpy array): time and position for point 2 [time2,x2,y2,z2]

    Returns:
        numpy array: velocity vector for point 1 (vx, vy, vz)
    '''

    x1_new = [1, 1, 1]
    x1_new[:] = x1[1:4]
    x2_new = [1, 1, 1]
    x2_new[:] = x2[1:4]
    time = x2[0] - x1[0]

    # traj = orbit_trajectory(x1_new, x2_new, time)

    l = pkp.lambert_problem(x1_new, x2_new, time, 398600.4405, traj, 0)

    # only one revolution is needed
    v1 = l.get_v1()[0]
    v1 = np.asarray(v1)
    #v1 = np.reshape(v1, 3)

    return v1
Exemple #6
0
    def get_v(self, x, soln=False):
        '''
        x contains the decision vector, the times when we reach each planet, the initial velocities
        '''
        # 0. mission time and number of GAs
        et, GAps, enctrs = np.array(
            x[:len(self.times)]), x[len(self.times):-1], x[
                -1]  # [t0,t1,t2, ... ], [i0,i1,i2,...], [ectrs]
        visits = int(enctrs) // 10 + 2
        GAps = np.array(GAps, dtype=int)[:visits - 2] // 10
        ts = np.zeros_like(self.planets[:visits])
        ts[0] = et[0]
        ts[-1] = et[-1]
        if (visits - 2 > 0):
            ts[1:-1] = et[
                GAps]  # find the times that correspond to the times for each gravity assist
        et = np.cumsum(ts)

        # 1. find the pos and velocities of the planets
        r = np.zeros_like(self.planets[:visits])
        v = np.zeros_like(self.planets[:visits])

        r[0], v[0] = [
            self.planets[0].get_pos(et[0]), self.planets[0].get_vel(et[0])
        ]  # find the position and velocity of start planet
        r[-1], v[-1] = [
            self.planets[-1].get_pos(et[-1]), self.planets[-1].get_vel(et[-1])
        ]  # find the position and velocity of end planet

        if (visits - 2 > 0):
            choices = np.array(self.planets)[GAps]
            for i, plts in enumerate(choices):
                r[i + 1], v[i + 1] = [
                    plts.get_pos(et[i + 1]),
                    plts.get_vel(et[i + 1])
                ]

        # 2. find path between each planet
        paths = []
        for i in range(visits - 1):
            paths.append(
                pk.lambert_problem(r[i], r[i + 1], et[i + 1] - et[i], self.mu))

        # 3. calc fitness
        if (self.multiRev
            ):  # attempt to do more than one rev in lambert solver
            vlam = [
                [np.array(p.get_v1()[-1]),
                 np.array(p.get_v2()[-1])] for p in paths
            ]  # contains the initial and final velocities for each path. Every velocity is a triple (v_x,v_y,v_z)
        else:
            vlam = [[np.array(p.get_v1()[0]),
                     np.array(p.get_v2()[0])] for p in paths]
        if (not soln):
            return (vlam, v, et[-1], r)
        return (vlam, v, r, et, GAps, enctrs)
Exemple #7
0
    def result(self, dt, phi0, leo_and_drag=False):
        """
        Calculate best delta v from Lambert problem solution with multiple revolution,
        both prograde and retrograde.
        """
        rm, re = self.rm, self.re

        l = lambert_problem([re, 0.0, 0.0], [rm*np.cos(phi0), rm*np.sin(phi0), 0.0],
                            dt, GRAV*SOL_M, False)

        dv = np.asarray([self.calc_dv(l.get_v1()[i], l.get_v2()[i], phi0, leo_and_drag=leo_and_drag)
                         for i in range(len(l.get_v1()))])

        l = lambert_problem([re, 0.0, 0.0], [rm*np.cos(phi0), rm*np.sin(phi0), 0.0],
                            dt, GRAV*SOL_M, True)
        dv2 = np.asarray([self.calc_dv(l.get_v1()[i], l.get_v2()[i], phi0, leo_and_drag=leo_and_drag)
                          for i in range(len(l.get_v1()))])

        return np.min(np.concatenate([dv, dv2]))
Exemple #8
0
def distance_dynamic_TSP_lambert(o1, o2, t0, T):
    """ compute lambert problem at epoch t0 arriving at t0 + T """

    r1,v1 = o1.eph(t0)
    r2,v2 = o2.eph(t0 + T)
    l = pk.lambert_problem(r1,r2,T)

    v1 = np.asarray(v1)
    v2 = np.asarray(v2)
    v1_l = np.asarray(l.get_v1()[0])
    v2_l = np.asarray(l.get_v2()[0])

    c = np.linalg.norm(v1 - v1_l, ord = 1) + np.linalg.norm(v2 - v2_l, ord = 1)

    return c
Exemple #9
0
def findValidLambert():
    SF = CONFIG.SimsFlan_config()

    earthephem = pk.planet.jpl_lp('earth')
    marsephem = pk.planet.jpl_lp('mars')

    counter = 0

    valid = False
    while valid == False:
        decv = np.zeros(len(SF.bnds))
        for i in range(6,8): 
            decv[i] = np.random.uniform(low = SF.bnds[i][0], \
                high = SF.bnds[i][1], size = 1)

        r_E, v_E = earthephem.eph(decv[6])
        r_M, v_M = marsephem.eph(decv[6] + AL_BF.sec2days(decv[7]) )

        # Create transfer in the first moment
        nrevs = 2
        l = pk.lambert_problem(r1 = r_E, r2 = r_M, tof = decv[7], \
            cw = False, mu =  Cts.mu_S_m, max_revs=nrevs)
        v1 = np.array(l.get_v1())
        v2 = np.array(l.get_v2())

        v_i_prev = 1e12 # Excessive random value
        for rev in range(len(v1)):
            v_i = np.linalg.norm(v1[rev] - np.array(v_E)) # Relative velocities for the bounds 
            v_i2 = np.linalg.norm(v2[rev] - np.array(v_M))
            # Change to polar for the bounds
            if v_i >= SF.bnds[0][0] and  v_i <= SF.bnds[0][1] and \
            v_i2 >= SF.bnds[3][0] and  v_i2 <= SF.bnds[3][1]:
                print('decv')
                print(v1[rev]-v_E,v2[rev]-v_M)
                decv[0:3] = AL_BF.convert3dvector(v1[rev]-v_E, "cartesian")
                decv[3:6] = AL_BF.convert3dvector(v2[rev]-v_M, "cartesian")
                print(decv[0:6])
                valid = True

                print('rev', rev, v1[rev], v2[rev])

        counter += 1
        print(counter)
    return decv, l
def plotContours(start_planet, end_planet, eph1, eph2, flt1, flt2,
                 sampling_size):

    start_epochs = np.arange(eph1, eph2, sampling_size)
    duration = np.arange(flt1, flt2, sampling_size)
    data = list()
    for start in start_epochs:
        row = list()
        for T in duration:
            r1, v1 = start_planet.eph(pk.epoch(start))
            r2, v2 = end_planet.eph(pk.epoch(start + T))
            l = pk.lambert_problem(r1, r2, T * 60 * 60 * 24,
                                   start_planet.mu_central_body)
            DV1 = np.linalg.norm(array(v1) - array(l.get_v1()[0]))
            DV2 = np.linalg.norm(array(v2) - array(l.get_v2()[0]))
            DV1 = max([0, DV1 - eph1])
            DV = DV1 + DV2
            row.append(DV)
        data.append(row)

    minrows = [min(l) for l in data]
    i_idx = np.argmin(minrows)
    j_idx = np.argmin(data[i_idx])
    best = data[i_idx][j_idx]
    print('\nBest DV: ', best)
    print('Launch epoch (MJD2000): ', start_epochs[i_idx])
    print('Duration (days): ', duration[j_idx])
    duration_pl2, start_epochs_pl2 = np.meshgrid(duration, start_epochs)

    CP2 = plt.contourf(start_epochs_pl2,
                       duration_pl2,
                       array(data),
                       levels=list(np.linspace(best, 5000, 10)))
    plt.colorbar(CP2).set_label('△V km/s')
    plt.title(f'{start_planet.name} - {end_planet.name} Total △V Requirements'.
              title())
    plt.xlabel('Launch Date (MJD2000)')
    plt.ylabel('Mission Duration (days)')
    plt.show()
Exemple #11
0
def lambert(p0, e0, p1, e1):
    # Get Planetary Positions/Velocities
    s0, _ = spk.spkezr(p0, e0, 'J2000', 'NONE', '0')
    s1, _ = spk.spkezr(p1, e1, 'J2000', 'NONE', '0')

    # Time of Flight
    tof = e1 - e0

    # Performing Lambert
    l = pk.lambert_problem(r0=(s0[0], s0[1], s0[2]),
                           r1=(s1[0], s1[1], s1[2]),
                           tof=tof,
                           mu=1.327e01,
                           max_revs=1)

    # Calculating V∞'s
    v0 = np.array(l.get_v0()[0])
    v1 = np.array(l.get_v1()[0])
    vInfO = v0 - np.array(s0[3:5])
    vInfI = v1 - np.array(s1[3:5])

    # Returning Variables
    return vInfO, vInfI
Exemple #12
0
 def _compute_dvs(self, x):
     # 1 -  we 'decode' the times of flights and compute epochs (mjd2000)
     T = self._decode_tofs(x)  # [T1, T2 ...]
     ep = np.insert(T, 0, x[0])  # [t0, T1, T2 ...]
     ep = np.cumsum(ep)  # [t0, t1, t2, ...]
     # 2 - we compute the ephemerides
     r = [0] * len(self.seq)
     v = [0] * len(self.seq)
     for i in range(len(self.seq)):
         r[i], v[i] = self.seq[i].eph(ep[i])
     # 3 - we solve the lambert problems
     l = list()
     for i in range(self._n_legs):
         l.append(pk.lambert_problem(
             r[i], r[i + 1], T[i] * pk.DAY2SEC, self._common_mu, False, 0))
     # 4 - we compute the various dVs needed at fly-bys to match incoming
     # and outcoming
     DVfb = list()
     for i in range(len(l) - 1):
         vin = [a - b for a, b in zip(l[i].get_v2()[0], v[i + 1])]
         vout = [a - b for a, b in zip(l[i + 1].get_v1()[0], v[i + 1])]
         DVfb.append(pk.fb_vel(vin, vout, self.seq[i + 1]))
     # 5 - we add the departure and arrival dVs
     DVlaunch_tot = np.linalg.norm(
         [a - b for a, b in zip(v[0], l[0].get_v1()[0])])
     DVlaunch = max(0, DVlaunch_tot - self.vinf)
     DVarrival = np.linalg.norm(
         [a - b for a, b in zip(v[-1], l[-1].get_v2()[0])])
     if self.orbit_insertion:
         # In this case we compute the insertion DV as a single pericenter
         # burn
         DVper = np.sqrt(DVarrival * DVarrival + 2 *
                         self.seq[-1].mu_self / self.rp_target)
         DVper2 = np.sqrt(2 * self.seq[-1].mu_self / self.rp_target -
                          self.seq[-1].mu_self / self.rp_target * (1. - self.e_target))
         DVarrival = np.abs(DVper - DVper2)
     return (DVlaunch, DVfb, DVarrival, l, DVlaunch_tot)
Exemple #13
0
    def ic_from_mga_1dsm(self, x):
        """
        x_lt = prob.ic_from_mga_1dsm(x_mga)

        - x_mga: compatible trajectory as encoded by an mga_1dsm problem

        Returns an initial guess for the low-thrust trajectory, converting the mga_1dsm solution x_dsm. The user
        is responsible that x_mga makes sense (i.e. it is a viable mga_1dsm representation). The conversion is done by importing in the
        low-thrust encoding a) the launch date b) all the legs durations, c) the in and out relative velocities at each planet.
        All throttles are put to zero.

        Example::

          x_lt= prob.ic_from_mga_1dsm(x_mga)
        """
        from math import pi, cos, sin, acos
        from scipy.linalg import norm
        from pykep import propagate_lagrangian, lambert_problem, DAY2SEC, fb_prop

        retval = list([0.0] * self.dimension)
        # 1 -  we 'decode' the chromosome recording the various times of flight
        # (days) in the list T
        T = list([0] * (self.__n_legs))

        for i in range(len(T)):
            T[i] = log(x[2 + 4 * i])
        total = sum(T)
        T = [x[1] * time / total for time in T]

        retval[0] = x[0]
        for i in range(self.__n_legs):
            retval[1 + 8 * i] = T[i]
            retval[2 + 8 * i] = self.__sc.mass

        # 2 - We compute the epochs and ephemerides of the planetary encounters
        t_P = list([None] * (self.__n_legs + 1))
        r_P = list([None] * (self.__n_legs + 1))
        v_P = list([None] * (self.__n_legs + 1))
        DV = list([None] * (self.__n_legs + 1))

        for i, planet in enumerate(self.seq):
            t_P[i] = epoch(x[0] + sum(T[0:i]))
            r_P[i], v_P[i] = self.seq[i].eph(t_P[i])

        # 3 - We start with the first leg
        theta = 2 * pi * x[1]
        phi = acos(2 * x[2] - 1) - pi / 2

        Vinfx = x[3] * cos(phi) * cos(theta)
        Vinfy = x[3] * cos(phi) * sin(theta)
        Vinfz = x[3] * sin(phi)

        retval[3:6] = [Vinfx, Vinfy, Vinfz]

        v0 = [a + b for a, b in zip(v_P[0], [Vinfx, Vinfy, Vinfz])]
        r, v = propagate_lagrangian(r_P[0], v0, x[4] * T[0] * DAY2SEC, MU_SUN)

        # Lambert arc to reach seq[1]
        dt = (1 - x[4]) * T[0] * DAY2SEC
        l = lambert_problem(r, r_P[1], dt, MU_SUN)
        v_end_l = l.get_v2()[0]
        v_beg_l = l.get_v1()[0]

        retval[6:9] = [a - b for a, b in zip(v_end_l, v_P[1])]

        # 4 - And we proceed with each successive leg
        for i in range(1, self.__n_legs):
            # Fly-by
            v_out = fb_prop(v_end_l, v_P[i],
                            x[7 + (i - 1) * 4] * self.seq[i].radius,
                            x[6 + (i - 1) * 4], self.seq[i].mu_self)
            retval[3 + i * 8:6 +
                   i * 8] = [a - b for a, b in zip(v_out, v_P[i])]
            # s/c propagation before the DSM
            r, v = propagate_lagrangian(r_P[i], v_out,
                                        x[8 + (i - 1) * 4] * T[i] * DAY2SEC,
                                        MU_SUN)
            # Lambert arc to reach Earth during (1-nu2)*T2 (second segment)
            dt = (1 - x[8 + (i - 1) * 4]) * T[i] * DAY2SEC
            l = lambert_problem(r, r_P[i + 1], dt, MU_SUN)
            v_end_l = l.get_v2()[0]
            v_beg_l = l.get_v1()[0]
            # DSM occuring at time nu2*T2
            DV[i] = norm([a - b for a, b in zip(v_beg_l, v)])
            retval[6 + i * 8:9 +
                   i * 8] = [a - b for a, b in zip(v_end_l, v_P[i + 1])]
        return retval
Exemple #14
0
def transfer():
    star = Star(1817514095, 1905216634)
    origin = Planet(1817514095, 1905216634, -455609026)
    target = Planet(1817514095, 1905216634, 272811578)
    origin_orbit_radius = origin.planet.radius + 200000
    target_orbit_radius = target.planet.radius + 200000

    launch_time_start = int(float(flask_request.values['launch_start']))
    launch_time_end = int(float(flask_request.values['launch_end']))
    launch_time_offset = 0 if launch_time_start >= 0 else -launch_time_start

    flight_time_start = int(float(flask_request.values['flight_start']))
    flight_time_start = max(1, flight_time_start)
    flight_time_end = int(float(flask_request.values['flight_end']))
    flight_time_end = max(1, flight_time_end)

    t0 = epoch_from_string(str(datetime.now()))
    t0_number = int(t0.mjd2000)

    delta_v = np.full((flight_time_end - flight_time_start,
                       launch_time_end + launch_time_offset), None)

    for launch_time in range(launch_time_start, launch_time_end):
        for flight_time in range(flight_time_start, flight_time_end):
            launch_time = int(launch_time)
            launch_time_index = launch_time + launch_time_offset
            flight_time = int(flight_time)
            flight_time_index = flight_time - flight_time_start

            t1 = epoch(launch_time + t0_number)
            t2 = epoch(launch_time + t0_number + flight_time)
            dt = (t2.mjd - t1.mjd) * DAY2SEC
            r1, v1 = origin.planet.eph(t1)
            r2, v2 = target.planet.eph(t2)
            lambert = lambert_problem(list(r1), list(r2), dt, star.gm)

            delta_vs = list()

            for x in range(lambert.get_Nmax() + 1):
                vp_vec = np.array(v1)
                vs_vec = np.array(lambert.get_v1()[x])
                vsp_vec = vs_vec - vp_vec
                vsp = np.linalg.norm(vsp_vec)
                vo = sqrt(vsp * vsp +
                          2 * origin.planet.mu_self / origin_orbit_radius)
                inj_delta_v = vo - sqrt(
                    origin.planet.mu_self / origin_orbit_radius)

                vp_vec = np.array(v2)
                vs_vec = np.array(lambert.get_v2()[x])
                vsp_vec = vs_vec - vp_vec
                vsp = np.linalg.norm(vsp_vec)
                vo = sqrt(vsp * vsp +
                          2 * target.planet.mu_self / target_orbit_radius)
                ins_delta_v = vo - sqrt(
                    target.planet.mu_self / target_orbit_radius)

                delta_vs.append(inj_delta_v + ins_delta_v)

            delta_v[flight_time_index, launch_time_index] = min(delta_vs)

    return jsonify(success=True,
                   delta_v=delta_v.tolist(),
                   launch_start=launch_time_start,
                   launch_end=launch_time_end,
                   flight_start=flight_time_start,
                   flight_end=flight_time_end,
                   launch_offset=-launch_time_offset)
destination = 'mars'
earth = pk.planet.jpl_lp(origin)
mars = pk.planet.jpl_lp(destination)
data = list()

for start in start_epochs:
    row = list()

    for tof in duration:

        pos_1, v1 = earth.eph(pk.epoch(start, 'mjd2000'))
        pos_2, v2 = mars.eph(pk.epoch(start + tof, 'mjd2000'))

        seconds_elapsed = tof * 60 * 60 * 24 if tof > 0 else 1 * 60 * 60 * 24

        l = pk.lambert_problem(pos_1, pos_2, seconds_elapsed, pk.MU_SUN)

        DV1 = np.linalg.norm(np.array(v1) - np.array(l.get_v1()[0]))
        DV2 = np.linalg.norm(np.array(v2) - np.array(l.get_v2()[0]))

        DV1 = max([0, DV1 - 4000])
        DV = DV1 + DV2

        row.append(DV)

    data.append(row)

minrows = [min(l) for l in data]
i_idx = np.argmin(minrows)  # Index of minimum value
j_idx = np.argmin(data[i_idx])
best = data[i_idx][j_idx] / 1000
def solve_trajectory():
    ivs = [pk.lambert_problem(*leg, Sun).get_v1()[0] for leg in trajectory]
    print(convert(pos,times,ivs))
    print(trajectory)
    print('')
    print(ivs)
Exemple #17
0
    def fineCorrectionBurn(self):
        #Propagate orbit to correction burn 1, then apply it to orbit, then propagage further and check.
        #If okay, then add in the manual inclination correction, and then do a final Lambert.
        self.AddOrbitPoint("1:319:0:0:0", 14646793325, 9353.0)
        rMan1, vMan1 = propagate_lagrangian(self.OrbitPoints[-2].r,
                                            self.OrbitPoints[-2].v,
                                            self.OrbitPoints[-1].t, self.mu_c)
        print(str(vMan1))
        vMan1 = np.asarray(vMan1)
        vMan1 += [-34.8, 35.9,
                  0]  #?????? WTF norm ok but direction is wrong (apprently)
        #vMan1 += [-25.87664536,+42.44449723,0]
        print(str(vMan1))
        self.OrbitPoints[-1].r = rMan1
        self.OrbitPoints[-1].r_n = norm(rMan1)
        self.OrbitPoints[-1].v = vMan1
        self.OrbitPoints[-1].v_n = norm(vMan1)

        #Propagate to a new point
        self.AddOrbitPoint("1:399:3:33:30", 17739170771, 7823.5)
        rCheck, vCheck = propagate_lagrangian(
            self.OrbitPoints[-2].r, self.OrbitPoints[-2].v,
            self.OrbitPoints[-1].t - self.OrbitPoints[-2].t, self.mu_c)
        self.printVect(rCheck, "r2 pred")
        self.printVect(vCheck, "v2 pred")
        self.deltasAtPoint(norm(rCheck), norm(vCheck),
                           (self.OrbitPoints[-1].r_n),
                           (self.OrbitPoints[-1].v_n), "r check fromZero",
                           "v check fromZero")
        self.AddOrbitPoint("1:417:2:58:04", 18284938767, 7574.6)
        rCheck, vCheck = propagate_lagrangian(
            self.OrbitPoints[-3].r, self.OrbitPoints[-3].v,
            self.OrbitPoints[-1].t - self.OrbitPoints[-3].t, self.mu_c)
        self.printVect(rCheck, "r3 pred")
        self.printVect(vCheck, "v3 pred")
        self.deltasAtPoint(norm(rCheck), norm(vCheck),
                           (self.OrbitPoints[-1].r_n),
                           (self.OrbitPoints[-1].v_n), "r check2 fromZero",
                           "v check2 fromZero")

        #self.OrbitPoints[-3].r, self.OrbitPoints[-3].v = propagate_lagrangian(self.OrbitPoints[-3].r,self.OrbitPoints[-3].v,0,self.mu_c)

        plt.rcParams['savefig.dpi'] = 100
        ManT = 76  # manoevre time
        ManT_W = 5  # manoevre window
        Edy2s = 24 * 3600
        dy2s = 6 * 3600
        start_epochs = np.arange(ManT, (ManT + ManT_W), 0.25)
        ETA = 20
        ETA_W = 200
        duration = np.arange(ETA, (ETA + ETA_W), 0.25)

        data = list()
        v_data = list()
        r_data = list()
        v1_data = list()
        for start in start_epochs:
            row = list()
            v_row = list()
            r_row = list()
            v1_row = list()
            for T in duration:
                #Need to replace the kerbin start point by the ship at time t using
                r1, v1 = propagate_lagrangian(
                    self.OrbitPoints[-3].r, self.OrbitPoints[-3].v,
                    (start) * Edy2s - self.OrbitPoints[-3].t, self.mu_c)
                #r1,v1 = Kerbin.eph(epoch(start))
                r2, v2 = Duna.eph(epoch(start + T))
                l = lambert_problem(r1, r2, T * Edy2s,
                                    Kerbin.mu_central_body)  #K day = 6h
                DV1 = np.linalg.norm(array(v1) - array(l.get_v1()[0]))
                v_DV1 = array(v1) - array(l.get_v1()[0])

                #DV2 = np.linalg.norm( array(v2)-array(l.get_v2()[0]) )
                #DV1 = max([0,DV1-4000])
                #DV = DV1+DV2
                DV = DV1
                #DV = sqrt(dot(DV1, DV1) + 2 * Kerbin.mu_self / Kerbin.safe_radius) - sqrt(Kerbin.mu_self / Kerbin.safe_radius )
                r_row.append(r1)
                v1_row.append(v1)
                v_row.append(v_DV1)
                row.append(DV)
            data.append(row)
            v_data.append(v_row)
            r_data.append(r_row)
            v1_data.append(v1_row)

        minrows = [min(l) for l in data]
        i_idx = np.argmin(minrows)
        j_idx = np.argmin(data[i_idx])
        best = data[i_idx][j_idx]
        v_best = v_data[i_idx][j_idx]
        r1 = r_data[i_idx][j_idx]
        v1 = v1_data[i_idx][j_idx]

        progrd_uv = -array(v1) / linalg.norm(v1)

        plane_uv = cross(v1, r1)
        plane_uv = plane_uv / linalg.norm(plane_uv)
        radial_uv = cross(plane_uv, progrd_uv)
        EJBK = sqrt(
            dot(v_best, v_best) + 2 * Kerbin.mu_central_body /
            norm(r1)) - sqrt(Kerbin.mu_central_body / norm(r1))

        progrd_v = dot(progrd_uv, v_best)
        radial_v = dot(radial_uv, v_best)

        #print(rad2deg(atan(radial_v/progrd_v)))

        print("TransX escape plan - Kerbin escape")
        print("--------------------------------------")
        print("Best DV: " + str(best))
        print("Best DV heliocentric components:" + str(v_best))
        print("Launch epoch (K-days): " + str((start_epochs[i_idx]) * 4))
        print("Duration (K-days): " + str(duration[j_idx] * 4))
        print("Prograde:            %10.3f m/s" %
              np.round(dot(progrd_uv, v_best), 3))
        print("Radial:              %10.3f m/s" %
              np.round(dot(radial_uv, v_best), 3))
        print("Planar:              %10.3f m/s" %
              np.round(dot(plane_uv, v_best), 3))
        print("Hyp. excess velocity:%10.3f m/s" %
              np.round(sqrt(dot(v_best, v_best)), 3))
        #print("Earth escape burn:   %10.3f m/s" % np.round(EJBK, 3))

        duration_pl, start_epochs_pl = np.meshgrid(duration, start_epochs)
        plt.contour(start_epochs_pl * 4,
                    duration_pl * 4,
                    array(data),
                    levels=list(np.linspace(best, 3000, 12)))
        #plt.imshow(array(data).T, cmap=plt.cm.rainbow, origin = "lower", vmin = best, vmax = 5000, extent=[0.0, 850, 10, 470.0], interpolation='bilinear')

        #plt.colorbar(im);
        plt.colorbar()
        plt.show()
Exemple #18
0
    def correctionBurn(self):
        plt.rcParams['savefig.dpi'] = 100
        ManT = 76  # manoevre time
        ManT_W = 200  # manoevre window
        Edy2s = 24 * 3600
        dy2s = 6 * 3600
        start_epochs = np.arange(ManT, (ManT + ManT_W), 0.25)
        ETA = 250
        ETA_W = 250
        duration = np.arange(ETA, (ETA + ETA_W), 0.25)
        '''        
        #these are Earth days, to *4 to Kdays (for eph function).

        
        #Sanity checks.
        r2,v2 = Duna.eph(epoch(312.8*0.25)) #check jool position
        print(norm(r2)-self.r_c)
        print(norm(v2))
        
        r1,v1 = propagate_lagrangian(self.OrbitPoints[-1].r,self.OrbitPoints[-1].v,312.8*dy2s,self.mu_c)        
        print(norm(r1)-self.r_c)
        print(norm(v1))       
        '''
        '''
        Solving the lambert problem. the function need times in Edays, so convert later to Kdays.
        Carefull with the Jool ephemeris, since kerbol year starts at y1 d1, substract 1Kday = 0.25Eday
        '''

        data = list()
        v_data = list()
        r_data = list()
        v1_data = list()
        for start in start_epochs:
            row = list()
            v_row = list()
            r_row = list()
            v1_row = list()
            for T in duration:
                #Need to replace the kerbin start point by the ship at time t using
                r1, v1 = propagate_lagrangian(self.OrbitPoints[-1].r,
                                              self.OrbitPoints[-1].v,
                                              (start) * Edy2s, self.mu_c)
                #r1,v1 = Kerbin.eph(epoch(start))
                r2, v2 = Jool.eph(epoch(start + T))
                l = lambert_problem(r1, r2, T * Edy2s,
                                    Kerbin.mu_central_body)  #K day = 6h
                DV1 = np.linalg.norm(array(v1) - array(l.get_v1()[0]))
                v_DV1 = array(v1) - array(l.get_v1()[0])

                #DV2 = np.linalg.norm( array(v2)-array(l.get_v2()[0]) )
                #DV1 = max([0,DV1-4000])
                #DV = DV1+DV2
                DV = DV1
                #DV = sqrt(dot(DV1, DV1) + 2 * Kerbin.mu_self / Kerbin.safe_radius) - sqrt(Kerbin.mu_self / Kerbin.safe_radius )
                r_row.append(r1)
                v1_row.append(v1)
                v_row.append(v_DV1)
                row.append(DV)
            data.append(row)
            v_data.append(v_row)
            r_data.append(r_row)
            v1_data.append(v1_row)

        minrows = [min(l) for l in data]
        i_idx = np.argmin(minrows)
        j_idx = np.argmin(data[i_idx])
        best = data[i_idx][j_idx]
        v_best = v_data[i_idx][j_idx]
        r1 = r_data[i_idx][j_idx]
        v1 = v1_data[i_idx][j_idx]

        progrd_uv = -array(v1) / linalg.norm(v1)

        plane_uv = cross(v1, r1)
        plane_uv = plane_uv / linalg.norm(plane_uv)
        radial_uv = cross(plane_uv, progrd_uv)
        EJBK = sqrt(
            dot(v_best, v_best) + 2 * Kerbin.mu_central_body /
            norm(r1)) - sqrt(Kerbin.mu_central_body / norm(r1))

        progrd_v = dot(progrd_uv, v_best)
        radial_v = dot(radial_uv, v_best)

        #print(rad2deg(atan(radial_v/progrd_v)))

        print("TransX escape plan - Kerbin escape")
        print("--------------------------------------")
        print("Best DV: " + str(best))
        print("Best DV heliocentric components:" + str(v_best))
        print("Launch epoch (K-days): " + str((start_epochs[i_idx]) * 4))
        print("Duration (K-days): " + str(duration[j_idx] * 4))
        print("Prograde:            %10.3f m/s" %
              np.round(dot(progrd_uv, v_best), 3))
        print("Radial:              %10.3f m/s" %
              np.round(dot(radial_uv, v_best), 3))
        print("Planar:              %10.3f m/s" %
              np.round(dot(plane_uv, v_best), 3))
        print("Hyp. excess velocity:%10.3f m/s" %
              np.round(sqrt(dot(v_best, v_best)), 3))
        #print("Earth escape burn:   %10.3f m/s" % np.round(EJBK, 3))

        duration_pl, start_epochs_pl = np.meshgrid(duration, start_epochs)
        plt.contour(start_epochs_pl * 4,
                    duration_pl * 4,
                    array(data),
                    levels=list(np.linspace(best, 3000, 12)))
        #plt.imshow(array(data).T, cmap=plt.cm.rainbow, origin = "lower", vmin = best, vmax = 5000, extent=[0.0, 850, 10, 470.0], interpolation='bilinear')

        #plt.colorbar(im);
        plt.colorbar()
        plt.show()
    def correctionBurn(self):
        plt.rcParams['savefig.dpi'] = 100
        ManT = 323  # manoevre time
        ManT_W = 5  # manoevre window
        dy2s = 6 * 3600
        start_epochs = np.arange(ManT * 0.25, (ManT + ManT_W) * 0.25, 0.25)
        ETA = 1000
        ETA_W = 2000
        duration = np.arange(ETA * 0.25, (ETA + ETA_W) * 0.25, 0.25)

        #these are Kdays, to *0.25 to Edays (for eph function).
        #Kerbin = planet.keplerian(epoch(0), (13599840256 ,0,0,0,0,3.14), 1.1723328e18, 3.5316000e12,600000, 670000 , 'Kerbin')
        #Duna   = planet.keplerian(epoch(0), (20726155264 ,0.051,deg2rad(0.06) ,0,deg2rad(135.5),3.14), 1.1723328e18, 3.0136321e11,320000, 370000 , 'Duna')
        r2, v2 = Jool.eph(epoch(322.5 * 0.25))  #check jool position
        print(norm(r2))
        print(norm(v2))
        r1, v1 = propagate_lagrangian(self.rL_data, self.vL_data,
                                      322.5 * dy2s - self.tL, self.mu_c)
        print(norm(r1))
        print(norm(v1))

        data = list()
        v_data = list()
        for start in start_epochs:
            row = list()
            v_row = list()
            for T in duration:
                #Need to replace the kerbin start point by the ship at time t using
                r1, v1 = propagate_lagrangian(self.rL_data, self.vL_data,
                                              (start - 1) * dy2s, self.mu_c)

                #r1,v1 = Kerbin.eph(epoch(start))
                r2, v2 = Jool.eph(epoch(start + T))
                l = lambert_problem(r1, r2, T * 60 * 60 * 24,
                                    Kerbin.mu_central_body)  #K day = 6h
                DV1 = np.linalg.norm(array(v1) - array(l.get_v1()[0]))
                v_DV1 = array(v1) - array(l.get_v1()[0])
                #DV2 = np.linalg.norm( array(v2)-array(l.get_v2()[0]) )
                #DV1 = max([0,DV1-4000])
                #DV = DV1+DV2
                DV = DV1
                #DV = sqrt(dot(DV1, DV1) + 2 * Kerbin.mu_self / Kerbin.safe_radius) - sqrt(Kerbin.mu_self / Kerbin.safe_radius )
                v_row.append(v_DV1)
                row.append(DV)
            data.append(row)
            v_data.append(v_row)

        minrows = [min(l) for l in data]
        i_idx = np.argmin(minrows)
        j_idx = np.argmin(data[i_idx])
        best = data[i_idx][j_idx]
        v_best = v_data[i_idx][j_idx]

        progrd_uv = array(v1) / linalg.norm(v1)

        plane_uv = cross(v1, r1)
        plane_uv = plane_uv / linalg.norm(plane_uv)
        radial_uv = cross(plane_uv, progrd_uv)
        EJBK = sqrt(
            dot(v_best, v_best) + 2 * Kerbin.mu_central_body /
            norm(r1)) - sqrt(Kerbin.mu_central_body / norm(r1))

        progrd_v = dot(progrd_uv, v_best)
        radial_v = dot(radial_uv, v_best)

        #print(rad2deg(atan(radial_v/progrd_v)))

        print("TransX escape plan - Kerbin escape")
        print("--------------------------------------")
        print("Best DV: " + str(best))
        print("Launch epoch (K-days): " + str(start_epochs[i_idx] * 4))
        print("Duration (K-days): " + str(duration[j_idx] * 4))
        print("Prograde:            %10.3f m/s" %
              np.round(dot(progrd_uv, v_best), 3))
        print("Radial:              %10.3f m/s" %
              np.round(dot(radial_uv, v_best), 3))
        print("Planar:              %10.3f m/s" %
              np.round(dot(plane_uv, v_best), 3))
        print("Hyp. excess velocity:%10.3f m/s" %
              np.round(sqrt(dot(v_best, v_best)), 3))
        #print("Earth escape burn:   %10.3f m/s" % np.round(EJBK, 3))

        duration_pl, start_epochs_pl = np.meshgrid(duration, start_epochs)
        plt.contour(start_epochs_pl * 4,
                    duration_pl * 4,
                    array(data),
                    levels=list(np.linspace(best, 3000, 12)))
        #plt.imshow(array(data).T, cmap=plt.cm.rainbow, origin = "lower", vmin = best, vmax = 5000, extent=[0.0, 850, 10, 470.0], interpolation='bilinear')

        #plt.colorbar(im);
        plt.colorbar()
        plt.show()
Exemple #20
0
def plottransfer():
    star = Star(1817514095, 1905216634)
    origin = Planet(1817514095, 1905216634, -455609026)
    target = Planet(1817514095, 1905216634, 272811578)
    origin_orbit_radius = origin.planet.radius + 200000
    target_orbit_radius = target.planet.radius + 200000

    flight_time = int(flask_request.values['flight_time'])

    t0 = epoch_from_string(str(datetime.now()))
    t0_number = int(t0.mjd2000)
    launch_time = int(flask_request.values['launch_time']) + t0_number

    t1 = epoch(int(launch_time))
    t2 = epoch(int(launch_time) + int(flight_time))

    fig = plt.figure(figsize=(4, 4))
    orbit_ax = fig.gca(projection='3d', proj_type='ortho')
    orbit_ax.scatter([0], [0], [0], color='orange')
    orbit_ax.set_aspect('equal')

    x_fig = plt.figure(figsize=(4, 4))
    x_ax = x_fig.gca()
    x_ax.scatter([0], [0], color='orange')

    y_fig = plt.figure(figsize=(4, 4))
    y_ax = y_fig.gca()
    y_ax.scatter([0], [0], color='orange')

    z_fig = plt.figure(figsize=(4, 4))
    z_ax = z_fig.gca()
    z_ax.scatter([0], [0], color='orange')

    plot_planet(origin.planet,
                t0=t1,
                color='green',
                legend=True,
                units=AU,
                ax=orbit_ax)
    plot_planet(target.planet,
                t0=t2,
                color='gray',
                legend=True,
                units=AU,
                ax=orbit_ax)

    o_x, o_y, o_z = plot_planet_2d(origin.planet, t0=t1)
    t_x, t_y, t_z = plot_planet_2d(target.planet, t0=t2)

    x_ax.plot(o_y, o_z, label=origin.planet.name, c='green')
    x_ax.scatter(o_y[0], o_z[0], s=40, color='green')
    x_ax.plot(t_y, t_z, label=target.planet.name, c='gray')
    x_ax.scatter(t_y[0], t_z[0], s=40, color='gray')

    y_ax.plot(o_x, o_z, label=origin.planet.name, c='green')
    y_ax.scatter(o_x[0], o_z[0], s=40, color='green')
    y_ax.plot(t_x, t_z, label=target.planet.name, c='gray')
    y_ax.scatter(t_x[0], t_z[0], s=40, color='gray')

    z_ax.plot(o_x, o_y, label=origin.planet.name, c='green')
    z_ax.scatter(o_x[0], o_y[0], s=40, color='green')
    z_ax.plot(t_x, t_y, label=target.planet.name, c='gray')
    z_ax.scatter(t_x[0], t_y[0], s=40, color='gray')

    max_value = max(max([abs(x) for x in orbit_ax.get_xlim()]),
                    max([abs(x) for x in orbit_ax.get_ylim()]))
    max_z_value = max([abs(z) for z in orbit_ax.get_zlim()])

    dt = (t2.mjd - t1.mjd) * DAY2SEC
    r1, v1 = origin.planet.eph(t1)
    r2, v2 = target.planet.eph(t2)
    lambert = lambert_problem(list(r1), list(r2), dt, star.gm)

    min_n = None
    min_delta_v = None
    for x in range(lambert.get_Nmax() + 1):
        vp_vec = np.array(v1)
        vs_vec = np.array(lambert.get_v1()[x])
        vsp_vec = vs_vec - vp_vec
        vsp = np.linalg.norm(vsp_vec)
        vo = sqrt(vsp * vsp + 2 * origin.planet.mu_self / origin_orbit_radius)
        inj_delta_v = vo - sqrt(origin.planet.mu_self / origin_orbit_radius)

        vp_vec = np.array(v2)
        vs_vec = np.array(lambert.get_v2()[x])
        vsp_vec = vs_vec - vp_vec
        vsp = np.linalg.norm(vsp_vec)
        vo = sqrt(vsp * vsp + 2 * target.planet.mu_self / target_orbit_radius)
        ins_delta_v = vo - sqrt(target.planet.mu_self / target_orbit_radius)

        if min_delta_v is None or inj_delta_v + ins_delta_v < min_delta_v:
            min_n = x
            min_delta_v = inj_delta_v + ins_delta_v

    plot_lambert(lambert,
                 color='purple',
                 sol=min_n,
                 legend=False,
                 units=AU,
                 ax=orbit_ax)

    l_x, l_y, l_z = plot_lambert_2d(lambert, sol=min_n)

    x_ax.plot(l_y, l_z, c='purple')
    y_ax.plot(l_x, l_z, c='purple')
    z_ax.plot(l_x, l_y, c='purple')

    orbit_ax.set_xlim(-max_value * 1.2, max_value * 1.2)
    orbit_ax.set_ylim(-max_value * 1.2, max_value * 1.2)
    orbit_ax.set_zlim(-max_z_value * 1.2, max_z_value * 1.2)

    x_ax.set_xlim(-1.0, 1.0)
    x_ax.set_ylim(-0.05, 0.05)

    y_ax.set_xlim(-1.0, 1.0)
    y_ax.set_ylim(-0.05, 0.05)

    z_ax.set_xlim(-1.0, 1.0)
    z_ax.set_ylim(-1.0, 1.0)

    fig.savefig('orbit')

    x_fig.savefig('orbit-x')
    y_fig.savefig('orbit-y')
    z_fig.savefig('orbit-z')

    plt.close('all')

    return jsonify(success=True)
Exemple #21
0
    def ic_from_mga_1dsm(self, x):
        """
        x_lt = prob.ic_from_mga_1dsm(x_mga)

        - x_mga: compatible trajectory as encoded by an mga_1dsm problem

        Returns an initial guess for the low-thrust trajectory, converting the mga_1dsm solution x_dsm. The user
        is responsible that x_mga makes sense (i.e. it is a viable mga_1dsm representation). The conversion is done by importing in the
        low-thrust encoding a) the launch date b) all the legs durations, c) the in and out relative velocities at each planet.
        All throttles are put to zero.

        Example::

          x_lt= prob.ic_from_mga_1dsm(x_mga)
        """
        from math import pi, cos, sin, acos
        from scipy.linalg import norm
        from pykep import propagate_lagrangian, lambert_problem, DAY2SEC, fb_prop

        retval = list([0.0] * self.dimension)
        # 1 -  we 'decode' the chromosome recording the various times of flight
        # (days) in the list T
        T = list([0] * (self.__n_legs))

        for i in range(len(T)):
            T[i] = log(x[2 + 4 * i])
        total = sum(T)
        T = [x[1] * time / total for time in T]

        retval[0] = x[0]
        for i in range(self.__n_legs):
            retval[1 + 8 * i] = T[i]
            retval[2 + 8 * i] = self.__sc.mass

        # 2 - We compute the epochs and ephemerides of the planetary encounters
        t_P = list([None] * (self.__n_legs + 1))
        r_P = list([None] * (self.__n_legs + 1))
        v_P = list([None] * (self.__n_legs + 1))
        DV = list([None] * (self.__n_legs + 1))

        for i, planet in enumerate(self.seq):
            t_P[i] = epoch(x[0] + sum(T[0:i]))
            r_P[i], v_P[i] = self.seq[i].eph(t_P[i])

        # 3 - We start with the first leg
        theta = 2 * pi * x[1]
        phi = acos(2 * x[2] - 1) - pi / 2

        Vinfx = x[3] * cos(phi) * cos(theta)
        Vinfy = x[3] * cos(phi) * sin(theta)
        Vinfz = x[3] * sin(phi)

        retval[3:6] = [Vinfx, Vinfy, Vinfz]

        v0 = [a + b for a, b in zip(v_P[0], [Vinfx, Vinfy, Vinfz])]
        r, v = propagate_lagrangian(r_P[0], v0, x[4] * T[0] * DAY2SEC, MU_SUN)

        # Lambert arc to reach seq[1]
        dt = (1 - x[4]) * T[0] * DAY2SEC
        l = lambert_problem(r, r_P[1], dt, MU_SUN)
        v_end_l = l.get_v2()[0]
        v_beg_l = l.get_v1()[0]

        retval[6:9] = [a - b for a, b in zip(v_end_l, v_P[1])]

        # 4 - And we proceed with each successive leg
        for i in range(1, self.__n_legs):
            # Fly-by
            v_out = fb_prop(v_end_l, v_P[i], x[
                            7 + (i - 1) * 4] * self.seq[i].radius, x[6 + (i - 1) * 4], self.seq[i].mu_self)
            retval[3 + i * 8:6 + i * 8] = [a -
                                           b for a, b in zip(v_out, v_P[i])]
            # s/c propagation before the DSM
            r, v = propagate_lagrangian(
                r_P[i], v_out, x[8 + (i - 1) * 4] * T[i] * DAY2SEC, MU_SUN)
            # Lambert arc to reach Earth during (1-nu2)*T2 (second segment)
            dt = (1 - x[8 + (i - 1) * 4]) * T[i] * DAY2SEC
            l = lambert_problem(r, r_P[i + 1], dt, MU_SUN)
            v_end_l = l.get_v2()[0]
            v_beg_l = l.get_v1()[0]
            # DSM occuring at time nu2*T2
            DV[i] = norm([a - b for a, b in zip(v_beg_l, v)])
            retval[6 + i * 8:9 + i * 8] = [a -
                                           b for a, b in zip(v_end_l, v_P[i + 1])]
        return retval