コード例 #1
0
    def plot_tvsT(self):

        t = np.linspace(self.t0,
                        self.t0 + AL_BF.sec2days(self.t_t),
                        num=self.Nimp + 2)
        deltaV_i = [
            np.linalg.norm(self.DeltaV_list[i, :]) * self.DeltaV_max
            for i in range(len(self.DeltaV_list[:, 0]))
        ]
        deltaV = np.zeros(self.Nimp + 2)
        deltaV[1:-1] = deltaV_i

        fig, ax = plt.subplots()
        plt.plot(t, deltaV, 'o-', color='k')

        plt.title("Epoch vs Delta V")
        plt.ylabel("Delta V (m/s)")
        plt.xlabel("JD0 (days)")
        plt.grid(alpha=0.5)
        # AL_Plot.set_axes_equal(ax)

        dpi = 200
        layoutSave = 'tight'
        plt.savefig('OptSol/tvsT.png', dpi=dpi, bbox_inches=layoutSave)

        plt.show()
コード例 #2
0
def propagateSimsFlanagan():
    "Test the propagation of SimsFlanagan back and forth using the velocities from Lambert"
    ### Using ephemeris
    # Lambert trajectory obtain terminal velocity vectors
    SF = CONFIG.SimsFlan_config()

    # Create bodies
    sun = AL_2BP.Body('sun', 'yellow', mu = Cts.mu_S_m)
    earth = AL_2BP.Body('earth', 'blue', mu = Cts.mu_E_m)
    mars = AL_2BP.Body('mars', 'red', mu = Cts.mu_M_m)

    # Calculate trajectory of the bodies based on ephem
    earthephem = pk.planet.jpl_lp('earth')
    marsephem = pk.planet.jpl_lp('mars')
    
    decv, l = findValidLambert()

    print(decv)

    Fit = Fitness(Nimp = SF.Nimp)
    Fit.calculateFitness(decv)
    Fit.printResult()

    # We plot
    mpl.rcParams['legend.fontsize'] = 10

    # Create the figure and axis
    fig = plt.figure(figsize = (16,5))
    ax1 = fig.add_subplot(1, 3, 1, projection='3d')
    ax1.scatter([0], [0], [0], color=['y'])

    ax2 = fig.add_subplot(1, 3, 2, projection='3d')
    ax2.scatter([0], [0], [0], color=['y'])
    ax2.view_init(90, 0)

    ax3 = fig.add_subplot(1, 3, 3, projection='3d')
    ax3.scatter([0], [0], [0], color=['y'])
    ax3.view_init(0,0)

    t1 = SF.t0.JD
    t2 = t1 + AL_BF.sec2days(decv[7])

    for ax in [ax1, ax2, ax3]:
        # Plot the planet orbits
        # plot_planet(earth, t0=t1, color=(0.8, 0.8, 1), legend=True, units=AU, axes=ax)
        # plot_planet(mars, t0=t2, color=(0.8, 0.8, 1), legend=True, units=AU, axes=ax)

        # Plot the Lambert solutions
        axis = plot_lambert(l, color='b', legend=True, units=AU, axes=ax)
        # axis = plot_lambert(l, sol=1, color='g', legend=True, units=AU, axes=ax)
        # axis = plot_lambert(l, sol=2, color='g', legend=True, units=AU, axes=ax)

    plt.show()
コード例 #3
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
コード例 #4
0
def propagateSimsFlanaganForward():
    "Test the propagation of SimsFlanagan forward using the velocities from Lambert"
    ### Using ephemeris
    # Lambert trajectory obtain terminal velocity vectors
    SF = CONFIG.SimsFlan_config()

    # Create bodies
    sun = AL_2BP.Body('sun', 'yellow', mu = Cts.mu_S_m)
    earth = AL_2BP.Body('earth', 'blue', mu = Cts.mu_E_m)
    mars = AL_2BP.Body('mars', 'red', mu = Cts.mu_M_m)

    # Calculate trajectory of the bodies based on ephem
    earthephem = pk.planet.jpl_lp('earth')
    marsephem = pk.planet.jpl_lp('mars')
    
    decv, l = findValidLambert()
    print(decv)

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

    Fit = Propagate(Nimp = SF.Nimp)
    Fit.prop(decv, plot = True)
    print("Final", Fit.rv_final)
    print("Theoretical final", r_M,  AL_BF.convert3dvector(decv[3:6], "polar")+v_M)
コード例 #5
0
def validateSimsFlanagan():
    SF = CONFIG.SimsFlan_config()

    # Create bodies
    sun = AL_2BP.Body('sun', 'yellow', mu = Cts.mu_S_m)
    earth = AL_2BP.Body('earth', 'blue', mu = Cts.mu_E_m)
    mars = AL_2BP.Body('mars', 'red', mu = Cts.mu_M_m)
    Spacecraft = AL_2BP.Spacecraft( )

    # Calculate trajectory of the bodies based on ephem
    earthephem = pk.planet.jpl_lp('earth')
    marsephem = pk.planet.jpl_lp('mars')

    # Create a random decision vector
    DecV = np.zeros(len(SF.bnds))
    samples_rand = 1
    np.random.seed(1)
    for decv in range(len(SF.bnds)): 
        DecV[decv] = np.random.rand(samples_rand) * (SF.bnds[decv][1]-SF.bnds[decv][0]) + SF.bnds[decv][0]
    
    DecV[8:] = np.zeros(3*SF.Nimp)

    Fit = Fitness(Nimp = 21)
    Fit.adaptDecisionVector(DecV)
    r = Fit.r_p0
    r2 = Fit.r_p1
    v = Fit.v0
    v2 = Fit.vf
    imp = Fit.DeltaV_list.flatten()
    # imp = (0,0,0,0,0,0,0,0,0,0,0,0)
    m0 = Fit.m0

    # Pykep Sims-Flanagan
    start = pk.epoch(DecV[6])
    end = pk.epoch(DecV[6] + AL_BF.sec2days(DecV[7]) )
    sc = pk.sims_flanagan.spacecraft(m0, Spacecraft.T, Spacecraft.Isp)
    
    
    x0 = pk.sims_flanagan.sc_state(r,v,sc.mass)
    xe = pk.sims_flanagan.sc_state(r2,v2,sc.mass)
    l = pk.sims_flanagan.leg(start, x0, imp, end, xe, sc,pk.MU_SUN)

    ceq = l.mismatch_constraints()
    c = l.throttles_constraints()
    times,r,v,m = l.get_states()
    r_vec = np.zeros((len(r),3))
    for i in range(len(r)):
        r_vec[i, :] = r[i]
        plt.scatter(r[i][0], r[i][1], color = 'black')
        if i == 0:
            plt.scatter(r[i][0], r[i][1], color = 'blue')
        elif i == len(r)-1:
            plt.scatter(r[i][0], r[i][1], color = 'red')
        elif i == len(r)//2+1:
            plt.scatter(r[i][0], r[i][1], color = 'orange')
        elif i == len(r)//2:
            plt.scatter(r[i][0], r[i][1], color = 'green')
    # plt.show()
    # plt.plot(r_vec[:,0], r_vec[:,1])
    plt.grid()

    print("State middle point")
    print(r[len(r)//2], v[len(r)//2])
    print(r[len(r)//2+1], v[len(r)//2+1])

    print("Mismatch middle point")
    mis_r = -(np.array(r[len(r)//2]) - np.array(r[len(r)//2+1]))
    mis_v = -(np.array(v[len(r)//2] )- np.array(v[len(r)//2+1]))
    print(mis_r, mis_v)
    mis = np.append(mis_r, mis_v)


    Fit = Fitness(Nimp = SF.Nimp)
    Fit.calculateFitness(DecV, plot=True)
    cep2 = Fit.Error
    # print(Fit.SV_0, Fit.SV_f)

    for i in range(6):
        print(i, ceq[i], '%.4E'%cep2[i], '%.4E'%mis[i])
コード例 #6
0
    def adaptDecisionVector(self, DecV, optMode=True):
        """ 
        adaptDecisionVector: modify decision vector to input in the problem
        """
        self.DecV = DecV
        v0 = np.array(DecV[0:3])  # vector, [magnitude, angle, angle]
        vf = np.array(DecV[3:6])  # vector, [magnitude, angle, angle]
        self.t0, self.t_t = DecV[6:8]

        # Delta V
        if optMode == True:
            DeltaV_list = np.array(DecV[8:]).reshape(
                -1, 3)  # make a Nimp x 3 matrix
        else:
            DeltaV_list = DecV[8:][0]

        ########################################################################
        # INITIAL CALCULATION OF VARIABLES
        ########################################################################
        # Modify from magnitude angle angle to cartesian
        self.DeltaV_list = np.zeros(np.shape(DeltaV_list))
        DeltaV_sum = np.zeros(len(
            self.DeltaV_list))  # Magnitude of the impulses
        for i in range(len(self.DeltaV_list)):
            self.DeltaV_list[i, :] = AL_BF.convert3dvector(
                DeltaV_list[i, :], "polar")
            DeltaV_sum[i] = np.linalg.norm(self.DeltaV_list[i])

        # Write velocity as x,y,z vector
        v0_cart = AL_BF.convert3dvector(v0, "polar")
        vf_cart = AL_BF.convert3dvector(vf, "polar")

        # Sum of all the Delta V = DeltaV max * sum Delta V_list
        # Assumption: the DeltaV_max is calculated as if mass is constant and
        # equal to the dry mass as it is the largest contribution. This means
        # that the DelaV_max is actually smaller than it will be obtained in this
        # problem
        # = Thrust for segment
        self.DeltaV_max = self.Spacecraft.T / self.Spacecraft.m_dry * \
            self.t_t / (self.Nimp + 1)

        # Total DeltaV
        DeltaV_total = sum(DeltaV_sum) * self.DeltaV_max

        #Calculate total mass of fuel for the given impulses
        self.m0 = \
            self.Spacecraft.MassChangeInverse(self.Spacecraft.m_dry, DeltaV_total)
        self.m_fuel = self.m0 - self.Spacecraft.m_dry

        # Times and ephemeris
        # t_0 = AL_Eph.DateConv(self.date0,'calendar') #To JD
        self.t_1 = AL_Eph.DateConv(self.t0 + AL_BF.sec2days(self.t_t), 'JD_0')

        self.r_p0, self.v_p0 = self.departureephem.eph(self.t0)
        self.r_p1, self.v_p1 = self.arrivalephem.eph(self.t_1.JD_0)

        # Change from relative to heliocentric velocity
        self.v0 = v0_cart + self.v_p0
        self.vf = vf_cart + self.v_p1

        # Create state vector for initial and final point
        self.SV_0 = np.append(self.r_p0, self.v0)
        self.SV_f = np.append(self.r_p1, self.vf)  # - to propagate backwards
        self.SV_f_corrected = np.append(self.r_p1,
                                        -self.vf)  # - to propagate backwards
コード例 #7
0
    def DecV2inputV(self, typeinputs, newDecV=0):

        if type(newDecV) != int:
            self.adaptDecisionVector(newDecV)

        inputs = np.zeros(8)
        inputs[0] = self.t_t
        inputs[1] = self.m0

        if typeinputs == "deltakeplerian":

            # Elements of the spacecraft
            earth_elem = AL_2BP.BodyOrbit(self.SV_0, "Cartesian", self.sun)
            elem_0 = earth_elem.KeplerElem
            mars_elem = AL_2BP.BodyOrbit(self.SV_f, "Cartesian", self.sun)
            elem_f = mars_elem.KeplerElem

            K_0 = np.array(elem_0)
            K_f = np.array(elem_f)

            # Mean anomaly to true anomaly
            K_0[-1] = AL_2BP.Kepler(K_0[-1], K_0[1], 'Mean')[0]
            K_f[-1] = AL_2BP.Kepler(K_f[-1], K_f[1], 'Mean')[0]

            inputs[2:] = K_f - K_0
            inputs[2] = abs(inputs[2])  # absolute value
            inputs[3] = abs(inputs[3])  # absolute value
            inputs[4] = np.cos(inputs[4])  # cosine

            labels = [
                r'$t_t$', r'$m_0$', r'$\vert \Delta a \vert$',
                r'$\vert \Delta e \vert$', r'$cos( \Delta i) $',
                r'$ \Delta \Omega$', r'$ \Delta \omega$', r'$ \Delta \theta$'
            ]

        elif typeinputs == "deltakeplerian_planet":
            t_1 = self.t0 + AL_BF.sec2days(self.t_t)

            # Elements of the planets
            elem_0 = self.departureephem.osculating_elements(
                pk.epoch(self.t0, 'mjd2000'))
            elem_f = self.arrivalephem.osculating_elements(
                pk.epoch(t_1, 'mjd2000'))

            K_0 = np.array(elem_0)
            K_f = np.array(elem_f)

            # Mean anomaly to true anomaly
            K_0[-1] = AL_2BP.Kepler(K_0[-1], K_0[1], 'Mean')[0]
            K_f[-1] = AL_2BP.Kepler(K_f[-1], K_f[1], 'Mean')[0]

            inputs[2:] = K_f - K_0
            inputs[2] = abs(inputs[2])  # absolute value
            inputs[3] = abs(inputs[3])  # absolute value
            inputs[4] = np.cos(inputs[4])  # cosine

            labels = [
                r'$t_t$', r'$m_0$', r'$\vert \Delta a \vert$',
                r'$\vert \Delta e \vert$', r'$cos( \Delta i) $',
                r'$ \Delta \Omega$', r'$ \Delta \omega$', r'$ \Delta \theta$'
            ]

        elif typeinputs == "cartesian":
            delta_r = np.array(self.SV_f[0:3]) - np.array(self.SV_0[0:3])
            delta_v = np.array(self.SV_f[3:]) - np.array(self.SV_0[3:])
            inputs[2:5] = np.abs(delta_r)
            inputs[5:] = np.abs(delta_v)

            labels = [
                r'$t_t$', r'$m_0$', r'$\vert \Delta x \vert$',
                r'$\vert \Delta y \vert$', r'$\vert \Delta z \vert$',
                r'$\vert \Delta v_x \vert$', r'$\vert \Delta v_y \vert$',
                r'$\vert \Delta v_z \vert$'
            ]

        return inputs, labels