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()
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()
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 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)
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])
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
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