def __init__(self, seq=[jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], dim=1, obj_dim=1, avoid=[]): # Sanity checks ...... all planets need to have the same # mu_central_body if ([r.mu_central_body for r in seq].count(seq[0].mu_central_body) != len(seq)): raise ValueError( 'All planets in the sequence need to have exactly the same mu_central_body' ) self.n_legs = len(seq) - 1 # We then define all planets in the sequence and the common central # body gravity as data members self.seq = seq self.common_mu = seq[0].mu_central_body if self.common_mu == 0: self.common_mu = 1e10 self.avoid = [] # First we call the constructor for the base PyGMO problem # As our problem is n dimensional, box-bounded (may be multi-objective), we write # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(transx_problem, self).__init__(dim, 0, obj_dim, 0, 0, 0)
def __init__(self, mass=2000, Tmax=0.5, Isp=3500, Vinf_dep=3, Vinf_arr=2, nseg1=5, nseg2=20): # First we call the constructor for the base PyGMO problem # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(mga_lt_EVMe, self).__init__(17 + 3 * (nseg1 + nseg2), 0, 1, 14 + 1 + nseg1 + nseg2 + 3, nseg1 + nseg2 + 3, 1e-4) # We then define some data members (we use the double underscore to # indicate they are private) from PyKEP import MU_SUN from PyKEP.planet import jpl_lp from PyKEP.sims_flanagan import spacecraft, leg self.__earth = jpl_lp('earth') self.__venus = jpl_lp('venus') self.__mercury = jpl_lp('mercury') self.__sc = spacecraft(mass, Tmax, Isp) self.__Vinf_dep = Vinf_dep * 1000 self.__Vinf_arr = Vinf_arr * 1000 self.__leg1 = leg() self.__leg2 = leg() self.__leg1.set_mu(MU_SUN) self.__leg1.set_spacecraft(self.__sc) self.__leg2.set_mu(MU_SUN) self.__leg2.set_spacecraft(self.__sc) self.__nseg1 = nseg1 self.__nseg2 = nseg2 # And the box-bounds (launch windows, allowed velocities, etc.) lb = [3000, 100, mass / 2] + [-self.__Vinf_dep] * 3 + [-6000] * 3 + [200, mass / 9] + [-6000] * 3 + [-self.__Vinf_arr] * 3 + [-1, -1, -1] * (nseg1 + nseg2) ub = [4000, 1000, mass] + [self.__Vinf_dep] * 3 + [6000] * 3 + [2000, mass] + [6000] * 3 + [self.__Vinf_arr] * 3 + [1, 1, 1] * (nseg1 + nseg2) self.set_bounds(lb, ub)
def __init__(self, mass=1000, Tmax=0.05, Isp=2500, Vinf=3.0, nseg=20): # First we call the constructor for the base PyGMO problem # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(mga_lt_earth_mars, self).__init__(6 + nseg * 3, 0, 1, 8 + nseg, nseg + 1, 1e-4) # We then define some data members (we use the double underscore to # indicate they are private) from PyKEP import MU_SUN from PyKEP.planet import jpl_lp from PyKEP.sims_flanagan import spacecraft, leg self.__earth = jpl_lp('earth') self.__mars = jpl_lp('mars') self.__sc = spacecraft(mass, Tmax, Isp) self.__Vinf = Vinf * 1000 self.__leg = leg() self.__leg.set_mu(MU_SUN) self.__leg.set_spacecraft(self.__sc) self.__nseg = nseg self.set_bounds([ 2480, 2400, self.__sc.mass / 10, -self.__Vinf, -self.__Vinf, -self.__Vinf ] + [-1] * 3 * nseg, [ 2490, 2500, self.__sc.mass, self.__Vinf, self.__Vinf, self.__Vinf ] + [1] * 3 * nseg)
def run_example5(): from PyGMO import archipelago, problem from PyGMO.algorithm import jde from PyGMO.topology import ring from PyKEP import epoch from PyKEP.planet import jpl_lp from PyKEP.trajopt import mga_1dsm # We define an Earth-Venus-Earth problem (single-objective) seq = [jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')] prob = mga_1dsm(seq=seq) prob.set_tof(0.7, 3) prob.set_vinf(2.5) prob.set_launch_window(epoch(5844), epoch(6209)) prob.set_tof(0.7, 3) # We solve it!! algo = jde(100) topo = ring() archi = archipelago(algo, prob, 8, 20, topology=topo) print( "Running a Self-Adaptive Differential Evolution Algorithm .... on 8 parallel islands" ) archi.evolve(10) archi.join() isl = min(archi, key=lambda x: x.population.champion.f[0]) print("Done!! Best solution found is: " + str(isl.population.champion.f[0] / 1000) + " km / sec") prob.pretty(isl.population.champion.x) prob.plot(isl.population.champion.x)
def __init__(self, seq=[jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], t0=[epoch(0), epoch(1000)], tof=[1.0, 5.0], vinf=[0.5, 2.5], mga_sol = None, add_vinf_dep=False, add_vinf_arr=True, multi_objective=False, avoid = []): """ PyKEP.trajopt.mga_1dsm(seq = [jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], t0 = [epoch(0),epoch(1000)], tof = [1.0,5.0], vinf = [0.5, 2.5], multi_objective = False, add_vinf_dep = False, add_vinf_arr=True) - seq: list of PyKEP planets defining the encounter sequence (including the starting launch) - t0: list of two epochs defining the launch window - tof: list of two floats defining the minimum and maximum allowed mission lenght (years) - vinf: list of two floats defining the minimum and maximum allowed initial hyperbolic velocity (at launch), in km/sec - multi_objective: when True constructs a multiobjective problem (dv, T) - add_vinf_dep: when True the computed Dv includes the initial hyperbolic velocity (at launch) - add_vinf_arr: when True the computed Dv includes the final hyperbolic velocity (at the last planet) """ # First we call the constructor for the base PyGMO problem # As our problem is n dimensional, box-bounded (may be multi-objective), we write # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) dim = 7 + (len(seq) - 2) * 4 obj_dim = multi_objective + 1 super(mga_1dsm_transx, self).__init__(seq, dim, obj_dim, avoid) self.__add_vinf_dep = add_vinf_dep self.__add_vinf_arr = add_vinf_arr # And we compute the bounds lb = [t0[0].mjd2000, tof[0] * 365.25] + [0.0, 0.0, vinf[0] * 1000, 1e-5, 1e-5] + [-2 * pi, 1.1, 1e-5, 1e-5] * (self.n_legs - 1) ub = [t0[1].mjd2000, tof[1] * 365.25] + [1.0, 1.0, vinf[1] * 1000, 1.0 - 1e-5, 1.0 - 1e-5] + [2 * pi, 30.0, 1.0 - 1e-5, 1.0 - 1e-5] * (self.n_legs - 1) self.__mga_sol = mga_sol # Accounting that each planet has a different safe radius...... for i, pl in enumerate(seq[1:-1]): lb[8 + 4 * i] = pl.safe_radius / pl.radius # And we set them self.set_bounds(lb, ub)
def run_example5(): from PyGMO import archipelago, problem from PyGMO.algorithm import jde from PyGMO.topology import ring from PyKEP import epoch from PyKEP.planet import jpl_lp from PyKEP.trajopt import mga_1dsm # We define an Earth-Venus-Earth problem (single-objective) seq = [jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')] prob = mga_1dsm(seq=seq) prob.set_tof(0.7, 3) prob.set_vinf(2.5) prob.set_launch_window(epoch(5844), epoch(6209)) prob.set_tof(0.7, 3) # We solve it!! algo = jde(100) topo = ring() archi = archipelago(algo, prob, 8, 20, topology=topo) print( "Running a Self-Adaptive Differential Evolution Algorithm .... on 8 parallel islands") archi.evolve(10) archi.join() isl = min(archi, key=lambda x: x.population.champion.f[0]) print("Done!! Best solution found is: " + str(isl.population.champion.f[0] / 1000) + " km / sec") prob.pretty(isl.population.champion.x) prob.plot(isl.population.champion.x)
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 _mga_1dsm_tof_ctor( self, seq=[ jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], t0=[ epoch(0), epoch(1000)], tof=[ [ 50, 900], [ 50, 900]], vinf=[ 0.5, 2.5], multi_objective=False, add_vinf_dep=False, add_vinf_arr=True): """ Constructs an mga_1dsm problem (tof-encoding) USAGE: problem.mga_1dsm(seq = [jpl_lp('earth'),jpl_lp('venus'),jpl_lp('earth')], t0 = [epoch(0),epoch(1000)], tof = [ [50, 900], [50, 900] ], vinf = [0.5, 2.5], multi_objective = False, add_vinf_dep = False, add_vinf_arr = True) * seq: list of PyKEP planets defining the encounter sequence (including the starting planet) * t0: list of two epochs defining the launch window * tof: list of intervals defining the times of flight (days) * vinf: list of two floats defining the minimum and maximum allowed initial hyperbolic velocity at launch (km/sec) * multi_objective: when True constructs a multiobjective problem (dv, T) * add_vinf_dep: when True the computed Dv includes the initial hyperbolic velocity (at launch) * add_vinf_arr: when True the computed Dv includes the final hyperbolic velocity (at arrival) """ # We construct the arg list for the original constructor exposed by # boost_python arg_list = [] arg_list.append(seq) arg_list.append(t0[0]) arg_list.append(t0[1]) arg_list.append(tof) arg_list.append(vinf[0]) arg_list.append(vinf[1]) arg_list.append(multi_objective) arg_list.append(add_vinf_dep) arg_list.append(add_vinf_arr) self._orig_init(*arg_list)
def __init__(self, mass=1000, Tmax=0.1, Isp=2500, Vinf=3.0, nseg=20): # First we call the constructor for the base PyGMO problem # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(mga_lt_earth_mars_sundmann, self).__init__(7 + nseg * 3, 0, 1, 9 + nseg, nseg + 1, 1e-4) # We then define some data members (we use the double underscore to # indicate they are private) from PyKEP import MU_SUN, AU from PyKEP.planet import jpl_lp from PyKEP.sims_flanagan import spacecraft, leg_s self.__earth = jpl_lp('earth') self.__mars = jpl_lp('jupiter') self.__sc = spacecraft(mass, Tmax, Isp) self.__Vinf = Vinf * 1000 # here we construct the trajectory leg in Sundman's variable t = # (r/10AU)^1.5 s self.__leg = leg_s(nseg, 1.0 / (100 * AU)**1.0, 1.0) self.__leg.set_mu(MU_SUN) self.__leg.set_spacecraft(self.__sc) # This is needed to use the plotting function plot_sf_leg self.__leg.high_fidelity = False self.__nseg = nseg # The bounds on Sundman's variable can be evaluated considering # circular orbits at r=1AU and r=0.7AU (for example) self.set_bounds([ 5000, 2400, 10000, self.__sc.mass / 10, -self.__Vinf, -self.__Vinf, -self.__Vinf ] + [-1] * 3 * nseg, [ 8000, 2500, 150000, self.__sc.mass, self.__Vinf, self.__Vinf, self.__Vinf ] + [1] * 3 * nseg)
def __init__(self, mass=1000, Tmax=0.1, Isp=2500, Vinf=3.0, nseg=20): # First we call the constructor for the base PyGMO problem # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(mga_lt_earth_mars_sundmann, self).__init__(7 + nseg * 3, 0, 1, 9 + nseg, nseg + 1, 1e-4) # We then define some data members (we use the double underscore to # indicate they are private) from PyKEP import MU_SUN, AU from PyKEP.planet import jpl_lp from PyKEP.sims_flanagan import spacecraft, leg_s self.__earth = jpl_lp('earth') self.__mars = jpl_lp('jupiter') self.__sc = spacecraft(mass, Tmax, Isp) self.__Vinf = Vinf * 1000 # here we construct the trajectory leg in Sundman's variable t = # (r/10AU)^1.5 s self.__leg = leg_s(nseg, 1.0 / (100 * AU) ** 1.0, 1.0) self.__leg.set_mu(MU_SUN) self.__leg.set_spacecraft(self.__sc) # This is needed to use the plotting function plot_sf_leg self.__leg.high_fidelity = False self.__nseg = nseg # The bounds on Sundman's variable can be evaluated considering # circular orbits at r=1AU and r=0.7AU (for example) self.set_bounds([5000, 2400, 10000, self.__sc.mass / 10, -self.__Vinf, -self.__Vinf, -self.__Vinf] + [-1] * 3 * nseg, [8000, 2500, 150000, self.__sc.mass, self.__Vinf, self.__Vinf, self.__Vinf] + [1] * 3 * nseg)
def planet_planet(start_planet, arrive_planet, tlaunch, tarrive, rev, N): # Create PyKEP epoch objects and calculate flight time t1 = epoch(tlaunch) t2 = epoch(tarrive) dt = (tarrive - tlaunch) * DAY2SEC OBJ1 = planet.jpl_lp(start_planet) OBJ2 = planet.jpl_lp( arrive_planet) # Calculate location of objects in flight path r1, v1 = OBJ1.eph(t1) r2, v2 = OBJ2.eph(t2) # Find trajectory l = lambert_problem(r1, r2, dt, MU_SUN) #extract relevant information from solution r = l.get_r1() v = l.get_v1()[0] mu = l.get_mu() #define the integration time dtn = dt / (N - 1) dtn_days = dtn * SEC2DAY #alocate the cartesian components for r t = np.array([0.0] * N) x = np.array([0.0] * N) y = np.array([0.0] * N) z = np.array([0.0] * N) #calculate the spacecraft position at each dt for i in range(N): t[i] = tlaunch + dtn_days * i x[i] = r[0] / AU y[i] = r[1] / AU z[i] = r[2] / AU r, v = propagate_lagrangian(r, v, dtn, mu) #traj = [t, x, y, z] vin = l.get_v1()[rev] vout = l.get_v2()[rev] #dV=fb_vel(vin,vout,planet.jpl_lp(arrive_planet)) #dV=np.sqrt( np.square(vin[0]/vout[0])+np.square(vin[1]/vout[1])+np.square(vin[2]/vout[2])) #dV=np.sqrt( np.square(vin[0]-v1[0])+np.square(v1[1]-vin[1])+np.square(v1[2]-vin[2])) #dV=np.sqrt( np.square(v2[0]-vout[0])+np.square(v2[1]-vout[1])+np.square(v2[2]-vout[2])) #dV=np.sqrt( np.square(v1[0]/vin[0])+np.square(v1[1]/vin[1])+np.square(v1[2]/vin[2])) C3_launch = (np.sqrt( np.square(vin[0] - v1[0]) + np.square(vin[1] - v1[1]) + np.square(vin[2] - v1[2])))**2 C3_arrive = (np.sqrt( np.square(vout[0] - v2[0]) + np.square(vout[1] - v2[1]) + np.square(vout[2] - v2[2])))**2 C3 = np.sqrt((C3_arrive**2) + (C3_launch**2)) return C3
def __init__(self, seq=[jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], t0=[epoch(0), epoch(1000)], tof=[1.0, 5.0], vinf=[0.5, 2.5], add_vinf_dep=False, add_vinf_arr=True, multi_objective=False): """ PyKEP.trajopt.mga_1dsm(seq = [jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], t0 = [epoch(0),epoch(1000)], tof = [1.0,5.0], vinf = [0.5, 2.5], multi_objective = False, add_vinf_dep = False, add_vinf_arr=True) - seq: list of PyKEP planets defining the encounter sequence (including the starting launch) - t0: list of two epochs defining the launch window - tof: list of two floats defining the minimum and maximum allowed mission lenght (years) - vinf: list of two floats defining the minimum and maximum allowed initial hyperbolic velocity (at launch), in km/sec - multi_objective: when True constructs a multiobjective problem (dv, T) - add_vinf_dep: when True the computed Dv includes the initial hyperbolic velocity (at launch) - add_vinf_arr: when True the computed Dv includes the final hyperbolic velocity (at the last planet) """ # Sanity checks ...... all planets need to have the same # mu_central_body if ([r.mu_central_body for r in seq].count(seq[0].mu_central_body) != len(seq)): raise ValueError( 'All planets in the sequence need to have exactly the same mu_central_body' ) self.__add_vinf_dep = add_vinf_dep self.__add_vinf_arr = add_vinf_arr self.__n_legs = len(seq) - 1 dim = 7 + (self.__n_legs - 1) * 4 obj_dim = multi_objective + 1 # First we call the constructor for the base PyGMO problem # As our problem is n dimensional, box-bounded (may be multi-objective), we write # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(mga_1dsm, self).__init__(dim, 0, obj_dim, 0, 0, 0) # We then define all planets in the sequence and the common central # body gravity as data members self.seq = seq self.common_mu = seq[0].mu_central_body # And we compute the bounds lb = [t0[0].mjd2000, tof[0] * 365.25] + [ 0.0, 0.0, vinf[0] * 1000, 1e-5, 1e-5 ] + [-2 * pi, 1.1, 1e-5, 1e-5] * (self.__n_legs - 1) ub = [t0[1].mjd2000, tof[1] * 365.25] + [ 1.0, 1.0, vinf[1] * 1000, 1.0 - 1e-5, 1.0 - 1e-5 ] + [2 * pi, 30.0, 1.0 - 1e-5, 1.0 - 1e-5] * (self.__n_legs - 1) # Accounting that each planet has a different safe radius...... for i, pl in enumerate(seq[1:-1]): lb[8 + 4 * i] = pl.safe_radius / pl.radius # And we set them self.set_bounds(lb, ub)
def __init__(self, seq=[jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], t0=[epoch(0), epoch(1000)], tof=[1.0, 5.0], vinf=[0.5, 2.5], mga_sol=None, add_vinf_dep=False, add_vinf_arr=True, multi_objective=False, avoid=[]): """ PyKEP.trajopt.mga_1dsm(seq = [jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], t0 = [epoch(0),epoch(1000)], tof = [1.0,5.0], vinf = [0.5, 2.5], multi_objective = False, add_vinf_dep = False, add_vinf_arr=True) - seq: list of PyKEP planets defining the encounter sequence (including the starting launch) - t0: list of two epochs defining the launch window - tof: list of two floats defining the minimum and maximum allowed mission lenght (years) - vinf: list of two floats defining the minimum and maximum allowed initial hyperbolic velocity (at launch), in km/sec - multi_objective: when True constructs a multiobjective problem (dv, T) - add_vinf_dep: when True the computed Dv includes the initial hyperbolic velocity (at launch) - add_vinf_arr: when True the computed Dv includes the final hyperbolic velocity (at the last planet) """ # First we call the constructor for the base PyGMO problem # As our problem is n dimensional, box-bounded (may be multi-objective), we write # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) dim = 7 + (len(seq) - 2) * 4 obj_dim = multi_objective + 1 super(mga_1dsm_transx, self).__init__(seq, dim, obj_dim, avoid) self.__add_vinf_dep = add_vinf_dep self.__add_vinf_arr = add_vinf_arr # And we compute the bounds lb = [t0[0].mjd2000, tof[0] * 365.25] + [ 0.0, 0.0, vinf[0] * 1000, 1e-5, 1e-5 ] + [-2 * pi, 1.1, 1e-5, 1e-5] * (self.n_legs - 1) ub = [t0[1].mjd2000, tof[1] * 365.25] + [ 1.0, 1.0, vinf[1] * 1000, 1.0 - 1e-5, 1.0 - 1e-5 ] + [2 * pi, 30.0, 1.0 - 1e-5, 1.0 - 1e-5] * (self.n_legs - 1) self.__mga_sol = mga_sol # Accounting that each planet has a different safe radius...... for i, pl in enumerate(seq[1:-1]): lb[8 + 4 * i] = pl.safe_radius / pl.radius # And we set them self.set_bounds(lb, ub)
def make_sequence(self, planets): seq = [] for e in planets: if e == 'earth': seq.append(planet.jpl_lp('earth')) elif e == 'mars': seq.append(planet.jpl_lp('mars')) elif e == 'venus': seq.append(planet.jpl_lp('venus')) elif e == 'ceres': seq.append(planet.mpcorb('00001 3.34 0.12 K167V 224.09531 72.81471 80.31427 '\ ' 10.59170 0.0757051 0.21400472 2.7681342 0 MPO384741 6634 113 1801-2016'\ ' 0.60 M-v 30h MPCLINUX 0000 Ceres 20160723')) else: print 'Planet not known' return seq
def __init__(self, mass=2000, Tmax=0.5, Isp=3500, Vinf_dep=3, Vinf_arr=2, nseg1=5, nseg2=20): # First we call the constructor for the base PyGMO problem # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(mga_lt_EVMe, self).__init__(17 + 3 * (nseg1 + nseg2), 0, 1, 14 + 1 + nseg1 + nseg2 + 3, nseg1 + nseg2 + 3, 1e-4) # We then define some data members (we use the double underscore to # indicate they are private) from PyKEP import MU_SUN from PyKEP.planet import jpl_lp from PyKEP.sims_flanagan import spacecraft, leg self.__earth = jpl_lp('earth') self.__venus = jpl_lp('venus') self.__mercury = jpl_lp('mercury') self.__sc = spacecraft(mass, Tmax, Isp) self.__Vinf_dep = Vinf_dep * 1000 self.__Vinf_arr = Vinf_arr * 1000 self.__leg1 = leg() self.__leg2 = leg() self.__leg1.set_mu(MU_SUN) self.__leg1.set_spacecraft(self.__sc) self.__leg2.set_mu(MU_SUN) self.__leg2.set_spacecraft(self.__sc) self.__nseg1 = nseg1 self.__nseg2 = nseg2 # And the box-bounds (launch windows, allowed velocities, etc.) lb = [3000, 100, mass / 2] + [-self.__Vinf_dep] * 3 + [-6000] * 3 + [ 200, mass / 9 ] + [-6000] * 3 + [-self.__Vinf_arr ] * 3 + [-1, -1, -1] * (nseg1 + nseg2) ub = [4000, 1000, mass] + [self.__Vinf_dep] * 3 + [6000] * 3 + [ 2000, mass ] + [6000] * 3 + [self.__Vinf_arr] * 3 + [1, 1, 1 ] * (nseg1 + nseg2) self.set_bounds(lb, ub)
def __init__(self, seq=[jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], dim = 1, obj_dim = 1, avoid = []): # Sanity checks ...... all planets need to have the same # mu_central_body if ([r.mu_central_body for r in seq].count(seq[0].mu_central_body) != len(seq)): raise ValueError('All planets in the sequence need to have exactly the same mu_central_body') self.n_legs = len(seq) - 1 # We then define all planets in the sequence and the common central # body gravity as data members self.seq = seq self.common_mu = seq[0].mu_central_body if self.common_mu == 0: self.common_mu = 1e10 self.avoid = [] # First we call the constructor for the base PyGMO problem # As our problem is n dimensional, box-bounded (may be multi-objective), we write # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(transx_problem, self).__init__(dim, 0, obj_dim, 0, 0, 0)
def __init__(self, mass=1000, Tmax=0.05, Isp=2500, Vinf=3.0, nseg=20): # First we call the constructor for the base PyGMO problem # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(mga_lt_earth_mars, self).__init__( 6 + nseg * 3, 0, 1, 8 + nseg, nseg + 1, 1e-4 ) self.earth = jpl_lp('earth') self.mars = jpl_lp('mars') self.sc = spacecraft(mass, Tmax, Isp) self.Vinf = Vinf * 1000 self.leg = leg() self.leg.set_mu(MU_SUN) self.leg.set_spacecraft(self.sc) self.nseg = nseg self.set_bounds( [2480, 2400, self.sc.mass / 10, -self.Vinf, -self.Vinf, -self.Vinf] + [-1]* 3 * nseg, [2490, 2500, self.sc.mass, self.Vinf, self.Vinf, self.Vinf] + [1] * 3 * nseg )
def __init__(self, seq=[jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], t0=[epoch(0), epoch(1000)], tof=[1.0, 5.0], vinf=[0.5, 2.5], add_vinf_dep=False, add_vinf_arr=True, multi_objective=False): """ PyKEP.trajopt.mga_1dsm(seq = [jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], t0 = [epoch(0),epoch(1000)], tof = [1.0,5.0], vinf = [0.5, 2.5], multi_objective = False, add_vinf_dep = False, add_vinf_arr=True) - seq: list of PyKEP planets defining the encounter sequence (including the starting launch) - t0: list of two epochs defining the launch window - tof: list of two floats defining the minimum and maximum allowed mission lenght (years) - vinf: list of two floats defining the minimum and maximum allowed initial hyperbolic velocity (at launch), in km/sec - multi_objective: when True constructs a multiobjective problem (dv, T) - add_vinf_dep: when True the computed Dv includes the initial hyperbolic velocity (at launch) - add_vinf_arr: when True the computed Dv includes the final hyperbolic velocity (at the last planet) """ # Sanity checks ...... all planets need to have the same # mu_central_body if ([r.mu_central_body for r in seq].count(seq[0].mu_central_body) != len(seq)): raise ValueError('All planets in the sequence need to have exactly the same mu_central_body') self.__add_vinf_dep = add_vinf_dep self.__add_vinf_arr = add_vinf_arr self.__n_legs = len(seq) - 1 dim = 7 + (self.__n_legs - 1) * 4 obj_dim = multi_objective + 1 # First we call the constructor for the base PyGMO problem # As our problem is n dimensional, box-bounded (may be multi-objective), we write # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(mga_1dsm, self).__init__(dim, 0, obj_dim, 0, 0, 0) # We then define all planets in the sequence and the common central # body gravity as data members self.seq = seq self.common_mu = seq[0].mu_central_body # And we compute the bounds lb = [t0[0].mjd2000, tof[0] * 365.25] + [0.0, 0.0, vinf[0] * 1000, 1e-5, 1e-5] + [-2 * pi, 1.1, 1e-5, 1e-5] * (self.__n_legs - 1) ub = [t0[1].mjd2000, tof[1] * 365.25] + [1.0, 1.0, vinf[1] * 1000, 1.0 - 1e-5, 1.0 - 1e-5] + [2 * pi, 30.0, 1.0 - 1e-5, 1.0 - 1e-5] * (self.__n_legs - 1) # Accounting that each planet has a different safe radius...... for i, pl in enumerate(seq[1:-1]): lb[8 + 4 * i] = pl.safe_radius / pl.radius # And we set them self.set_bounds(lb, ub)
def __init__(self, mass=1000, Tmax=0.05, Isp=2500, Vinf=3.0, nseg=20): # First we call the constructor for the base PyGMO problem # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(mga_lt_earth_mars, self).__init__( 6 + nseg * 3, 0, 1, 8 + nseg, nseg + 1, 1e-4) # We then define some data members (we use the double underscore to # indicate they are private) from PyKEP import MU_SUN from PyKEP.planet import jpl_lp from PyKEP.sims_flanagan import spacecraft, leg self.__earth = jpl_lp('earth') self.__mars = jpl_lp('mars') self.__sc = spacecraft(mass, Tmax, Isp) self.__Vinf = Vinf * 1000 self.__leg = leg() self.__leg.set_mu(MU_SUN) self.__leg.set_spacecraft(self.__sc) self.__nseg = nseg self.set_bounds([2480, 2400, self.__sc.mass / 10, -self.__Vinf, -self.__Vinf, -self.__Vinf] + [-1] * 3 * nseg, [2490, 2500, self.__sc.mass, self.__Vinf, self.__Vinf, self.__Vinf] + [1] * 3 * nseg)
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 getTraj_simple(start_planet, arrive_planet, tlaunch, tarrive, N): ''' Finds a trajectory between two objects orbiting the Sun USAGE: traj = getTraj(K1, K2, tlaunch, tarrive) K: array of object parameters. epoch: epoch of Keplerian orbital elements (JD) a: semimajor axis (AU) e: eccentricity (none) i: inclination (deg) om: longitude of the ascending node (deg) w: argument of perihelion (deg) ma: mean anomaly at epoch (deg) mass: mass of object (kg) r: radius of object (m) sr: safe radius to approach object (m) K1: [epoch1,a1,e1,i1,om1,w1,ma1,mass1,r1,sr1] K2: [epoch2,a2,e2,i2,om2,w2,ma2,mass2,r2,sr2] tlaunch: launch time (JD) tarrive: arrival time (JD) N: number of points in calculated trajectory ''' import numpy as np from PyKEP import epoch, DAY2SEC, SEC2DAY, AU, DEG2RAD, MU_SUN, planet, lambert_problem, propagate_lagrangian, fb_vel # Create PyKEP epoch objects and calculate flight time t1 = epoch(tlaunch) t2 = epoch(tarrive) dt = (tarrive - tlaunch) * DAY2SEC rev = 0 #number of revolutions before intercept OBJ1 = planet.jpl_lp(start_planet) OBJ2 = planet.jpl_lp( arrive_planet) # Calculate location of objects in flight path r1, v1 = OBJ1.eph(t1) r2, v2 = OBJ2.eph(t2) #Find trajectory l = lambert_problem(r1, r2, dt, MU_SUN) #extract relevant information from solution r = l.get_r1() v = l.get_v1()[0] mu = l.get_mu() #define the integration time dtn = dt / (N - 1) dtn_days = dtn * SEC2DAY #alocate the cartesian components for r t = np.array([0.0] * N) x = np.array([0.0] * N) y = np.array([0.0] * N) z = np.array([0.0] * N) #calculate the spacecraft position at each dt for i in range(N): t[i] = tlaunch + dtn_days * i x[i] = r[0] / AU y[i] = r[1] / AU z[i] = r[2] / AU r, v = propagate_lagrangian(r, v, dtn, mu) #traj = [t, x, y, z] vin = l.get_v1()[rev] vout = l.get_v2()[rev] dV = fb_vel(vin, vout, planet.jpl_lp(arrive_planet)) #dV=np.sqrt( np.square(vout[0])+np.square(vout[1])+np.square(vout[2]))-np.sqrt( np.square(vin[0])+np.square(vin[1])+np.square(vin[2])) return dV
def getTraj_simple(start_planet, arrive_planet, tlaunch, tarrive, N): ''' Finds a trajectory between two objects orbiting the Sun USAGE: traj = getTraj(K1, K2, tlaunch, tarrive) K: array of object parameters. epoch: epoch of Keplerian orbital elements (JD) a: semimajor axis (AU) e: eccentricity (none) i: inclination (deg) om: longitude of the ascending node (deg) w: argument of perihelion (deg) ma: mean anomaly at epoch (deg) mass: mass of object (kg) r: radius of object (m) sr: safe radius to approach object (m) K1: [epoch1,a1,e1,i1,om1,w1,ma1,mass1,r1,sr1] K2: [epoch2,a2,e2,i2,om2,w2,ma2,mass2,r2,sr2] tlaunch: launch time (JD) tarrive: arrival time (JD) N: number of points in calculated trajectory ''' import numpy as np from PyKEP import epoch, DAY2SEC, SEC2DAY, AU, DEG2RAD, MU_SUN, planet, lambert_problem, propagate_lagrangian, fb_vel # Create PyKEP epoch objects and calculate flight time t1 = epoch(tlaunch) t2 = epoch(tarrive) dt = (tarrive - tlaunch) * DAY2SEC rev=0 #number of revolutions before intercept OBJ1 = planet.jpl_lp(start_planet) OBJ2 = planet.jpl_lp(arrive_planet) # Calculate location of objects in flight path r1, v1 = OBJ1.eph(t1) r2, v2 = OBJ2.eph(t2) #Find trajectory l = lambert_problem(r1, r2, dt, MU_SUN) #extract relevant information from solution r = l.get_r1() v = l.get_v1()[0] mu = l.get_mu() #define the integration time dtn = dt / (N - 1) dtn_days = dtn * SEC2DAY #alocate the cartesian components for r t = np.array([0.0] * N) x = np.array([0.0] * N) y = np.array([0.0] * N) z = np.array([0.0] * N) #calculate the spacecraft position at each dt for i in range(N): t[i] = tlaunch + dtn_days * i x[i] = r[0] / AU y[i] = r[1] / AU z[i] = r[2] / AU r, v = propagate_lagrangian(r, v, dtn, mu) #traj = [t, x, y, z] vin=l.get_v1()[rev] vout=l.get_v2()[rev] dV=fb_vel(vin,vout,planet.jpl_lp(arrive_planet)) #dV=np.sqrt( np.square(vout[0])+np.square(vout[1])+np.square(vout[2]))-np.sqrt( np.square(vin[0])+np.square(vin[1])+np.square(vin[2])) return dV
def __init__(self, target = jpl_lp('mars'), n_seg = 20, grid_type = "uniform", t0 = [epoch(0), epoch(1000)], tof = [200, 500], m0 = 50.0, Tmax = 0.001, Isp = 2000.0, earth_gravity = False, start = "earth"): """ prob = lt_margo(target = jpl_lp('mars'), n_seg = 20, grid_type = "uniform", t0 = [epoch(0), epoch(1000)], tof = [200, 500], m0 = 50.0, Tmax = 0.001, Isp = 2000.0, earth_gravity = False, start = "earth") - target: target PyKEP.planet - n_seg: number of segments - grid_type: "uniform" for uniform segments, "nonuniform" for a denser grid in the first part of the trajectory - t0: list of two epochs defining the launch window - tof: list of two floats definind the minimum and maximum time of flight (days) - m0: initial mass of the spacecraft - Tmax: maximum thrust - Isp: engine specific impulse - earth_gravity: boolean specifying whether to take Earth's gravity into account - start: starting point ("earth", "l1", or "l2"). .. note:: L1 and L2 are approximated as the points on the line connecting the Sun and the Earth at a distance of, respectively, 0.99 and 1.01 AU from the Sun. .. note:: If the Earth's gravity is enabled, the starting point cannot be the Earth """ # Various checks if start not in ["earth", "l1", "l2"]: raise ValueError("start must be either 'earth', 'l1' or 'l2'") if grid_type not in ["uniform", "nonuniform"]: raise ValueError("grid_type must be either 'uniform' or 'nonuniform'") if earth_gravity and start == "earth": raise ValueError("If Earth gravity is enabled the starting point cannot be the Earth") # 1a) The decision vector length ([t0, tof, mf, [Tx,Ty,Tz] * n_seg]) dim = 3 + n_seg * 3 # 1b) The total number of constraints (mismatch + throttles) c_dim = 7 + n_seg # 1c) The number of inequality constraints (throttles) c_ineq_dim = n_seg # First we call the constructor for the base PyGMO problem super(lt_margo, self).__init__(dim, 0, 1, c_dim, c_ineq_dim, 1e-4) # 2) We then define some class data members # public: self.target = target # private: self.__n_seg = n_seg self.__grid_type = grid_type # gridding function (must be 0 in 0, 1 in 1, and strictly increasing) self.__sc = spacecraft(m0, Tmax, Isp) self.__earth = jpl_lp('earth') self.__earth_gravity = earth_gravity self.__start = start # grid construction if grid_type == "uniform": grid = np.array([i/n_seg for i in range(n_seg + 1)]) elif grid_type == "nonuniform": grid_f = lambda x : x**2 if x<0.5 else 0.25+1.5*(x-0.5) # quadratic in [0,0.5], linear in [0.5,1] grid = np.array([grid_f(i/n_seg) for i in range(n_seg + 1)]) fwd_seg = np.searchsorted(grid, 0.5, side='right') # index corresponding to the middle of the transfer bwd_seg = n_seg - fwd_seg fwd_grid = grid[:fwd_seg + 1] bwd_grid = grid[fwd_seg:] self.__fwd_seg = fwd_seg self.__fwd_grid = fwd_grid self.__fwd_dt = np.array([(fwd_grid[i+1] - fwd_grid[i]) for i in range(fwd_seg)]) * DAY2SEC self.__bwd_seg = bwd_seg self.__bwd_grid = bwd_grid self.__bwd_dt = np.array([(bwd_grid[i+1] - bwd_grid[i]) for i in range(bwd_seg)]) * DAY2SEC # 3) We compute the bounds lb = [t0[0].mjd2000] + [tof[0]] + [0] + [-1, -1, -1] * n_seg ub = [t0[1].mjd2000] + [tof[1]] + [m0] + [1, 1, 1] * n_seg # 4) And we set the bounds self.set_bounds(lb, ub)
def __init__(self, seq=[jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], n_seg=[10] * 2, t0=[epoch(0), epoch(1000)], tof=[[200, 500], [200, 500]], vinf_dep=2.5, vinf_arr=2.0, mass=4000.0, Tmax=1.0, Isp=2000.0, fb_rel_vel=6, multi_objective=False, high_fidelity=False): """ prob = mga_lt_nep(seq = [jpl_lp('earth'),jpl_lp('venus'),jpl_lp('earth')], n_seg = [10]*2, t0 = [epoch(0),epoch(1000)], tof = [[200,500],[200,500]], vinf_dep=2.5, vinf_arr=2.0, mass=4000.0, Tmax=1.0, Isp=2000.0, multi_objective = False, fb_rel_vel = 6, high_fidelity=False) - seq: list of PyKEP.planet defining the encounter sequence for the trajectoty (including the initial planet) - n_seg: list of integers containing the number of segments to be used for each leg (len(n_seg) = len(seq)-1) - t0: list of PyKEP epochs defining the launch window - tof: minimum and maximum time of each leg (days) - vinf_dep: maximum launch hyperbolic velocity allowed (in km/sec) - vinf_arr: maximum arrival hyperbolic velocity allowed (in km/sec) - mass: spacecraft starting mass - Tmax: maximum thrust - Isp: engine specific impulse - fb_rel_vel = determines the bounds on the maximum allowed relative velocity at all fly-bys (in km/sec) - multi-objective: when True defines the problem as a multi-objective problem, returning total DV and time of flight - high_fidelity = makes the trajectory computations slower, but actually dynamically feasible. """ # 1) We compute the problem dimensions .... and call the base problem constructor self.__n_legs = len(seq) - 1 n_fb = self.__n_legs - 1 # 1a) The decision vector length dim = 1 + self.__n_legs * 8 + sum(n_seg) * 3 # 1b) The total number of constraints (mismatch + fly-by + boundary + throttles c_dim = self.__n_legs * 7 + n_fb * 2 + 2 + sum(n_seg) # 1c) The number of inequality constraints (boundary + fly-by angle + throttles) c_ineq_dim = 2 + n_fb + sum(n_seg) # 1d) the number of objectives f_dim = multi_objective + 1 # First we call the constructor for the base PyGMO problem # As our problem is n dimensional, box-bounded (may be multi-objective), we write # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(mga_lt_nep, self).__init__(dim, 0, f_dim, c_dim, c_ineq_dim, 1e-4) # 2) We then define some class data members # public: self.seq = seq # private: self.__n_seg = n_seg self.__vinf_dep = vinf_dep * 1000 self.__vinf_arr = vinf_arr * 1000 self.__sc = spacecraft(mass, Tmax, Isp) self.__leg = leg() self.__leg.set_mu(MU_SUN) self.__leg.set_spacecraft(self.__sc) self.__leg.high_fidelity = high_fidelity fb_rel_vel *= 1000 # 3) We compute the bounds lb = [t0[0].mjd2000] + [ 0, mass / 2, -fb_rel_vel, -fb_rel_vel, -fb_rel_vel, -fb_rel_vel, -fb_rel_vel, -fb_rel_vel ] * self.__n_legs + [-1, -1, -1] * sum(self.__n_seg) ub = [t0[1].mjd2000] + [ 1, mass, fb_rel_vel, fb_rel_vel, fb_rel_vel, fb_rel_vel, fb_rel_vel, fb_rel_vel ] * self.__n_legs + [1, 1, 1] * sum(self.__n_seg) # 3a ... and account for the bounds on the vinfs...... lb[3:6] = [-self.__vinf_dep] * 3 ub[3:6] = [self.__vinf_dep] * 3 lb[-sum(self.__n_seg) * 3 - 3:-sum(self.__n_seg) * 3] = [-self.__vinf_arr] * 3 ub[-sum(self.__n_seg) * 3 - 3:-sum(self.__n_seg) * 3] = [self.__vinf_arr] * 3 # 3b... and for the time of flight lb[1:1 + 8 * self.__n_legs:8] = [el[0] for el in tof] ub[1:1 + 8 * self.__n_legs:8] = [el[1] for el in tof] # 4) And we set the bounds self.set_bounds(lb, ub)
def __init__(self, seq=[jpl_lp('earth'), jpl_lp('venus'), jpl_lp('earth')], n_seg=[10] * 2, t0=[epoch(0), epoch(1000)], tof=[[200, 500], [200, 500]], vinf_dep=2.5, vinf_arr=2.0, mass=4000.0, Tmax=1.0, Isp=2000.0, fb_rel_vel=6, multi_objective=False, high_fidelity=False): """ prob = mga_lt_nep(seq = [jpl_lp('earth'),jpl_lp('venus'),jpl_lp('earth')], n_seg = [10]*2, t0 = [epoch(0),epoch(1000)], tof = [[200,500],[200,500]], Vinf_dep=2.5, Vinf_arr=2.0, mass=4000.0, Tmax=1.0, Isp=2000.0, multi_objective = False, fb_rel_vel = 6, high_fidelity=False) - seq: list of PyKEP.planet defining the encounter sequence for the trajectoty (including the initial planet) - n_seg: list of integers containing the number of segments to be used for each leg (len(n_seg) = len(seq)-1) - t0: list of PyKEP epochs defining the launch window - tof: minimum and maximum time of each leg (days) - vinf_dep: maximum launch hyperbolic velocity allowed (in km/sec) - vinf_arr: maximum arrival hyperbolic velocity allowed (in km/sec) - mass: spacecraft starting mass - Tmax: maximum thrust - Isp: engine specific impulse - fb_rel_vel = determines the bounds on the maximum allowed relative velocity at all fly-bys (in km/sec) - multi-objective: when True defines the problem as a multi-objective problem, returning total DV and time of flight - high_fidelity = makes the trajectory computations slower, but actually dynamically feasible. """ # 1) We compute the problem dimensions .... and call the base problem constructor self.__n_legs = len(seq) - 1 n_fb = self.__n_legs - 1 # 1a) The decision vector length dim = 1 + self.__n_legs * 8 + sum(n_seg) * 3 # 1b) The total number of constraints (mismatch + fly-by + boundary + throttles c_dim = self.__n_legs * 7 + n_fb * 2 + 2 + sum(n_seg) # 1c) The number of inequality constraints (boundary + fly-by angle + throttles) c_ineq_dim = 2 + n_fb + sum(n_seg) # 1d) the number of objectives f_dim = multi_objective + 1 # First we call the constructor for the base PyGMO problem # As our problem is n dimensional, box-bounded (may be multi-objective), we write # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(mga_lt_nep, self).__init__(dim, 0, f_dim, c_dim, c_ineq_dim, 1e-4) # 2) We then define some class data members # public: self.seq = seq # private: self.__n_seg = n_seg self.__vinf_dep = vinf_dep * 1000 self.__vinf_arr = vinf_arr * 1000 self.__sc = spacecraft(mass, Tmax, Isp) self.__leg = leg() self.__leg.set_mu(MU_SUN) self.__leg.set_spacecraft(self.__sc) self.__leg.high_fidelity = high_fidelity fb_rel_vel *= 1000 # 3) We compute the bounds lb = [t0[0].mjd2000] + [0, mass / 2, -fb_rel_vel, -fb_rel_vel, -fb_rel_vel, -fb_rel_vel, -fb_rel_vel, -fb_rel_vel] * self.__n_legs + [-1, -1, -1] * sum(self.__n_seg) ub = [t0[1].mjd2000] + [1, mass, fb_rel_vel, fb_rel_vel, fb_rel_vel, fb_rel_vel, fb_rel_vel, fb_rel_vel] * self.__n_legs + [1, 1, 1] * sum(self.__n_seg) # 3a ... and account for the bounds on the vinfs...... lb[3:6] = [-self.__vinf_dep] * 3 ub[3:6] = [self.__vinf_dep] * 3 lb[-sum(self.__n_seg) * 3 - 3:-sum(self.__n_seg) * 3] = [-self.__vinf_arr] * 3 ub[-sum(self.__n_seg) * 3 - 3:-sum(self.__n_seg) * 3] = [self.__vinf_arr] * 3 # 3b... and for the time of flight lb[1:1 + 8 * self.__n_legs:8] = [el[0] for el in tof] ub[1:1 + 8 * self.__n_legs:8] = [el[1] for el in tof] # 4) And we set the bounds self.set_bounds(lb, ub)
def planet_asteroid(start_planet, target_name, tlaunch, tarrive, rev, N): # Create PyKEP epoch objects and calculate flight time t1 = epoch(tlaunch) t2 = epoch(tarrive) dt = (tarrive - tlaunch) * DAY2SEC import py.AsteroidDB as asteroidDB neo_db = asteroidDB.neo target = (item for item in neo_db if item["name"] == target_name).next() ep = epoch(target["epoch_mjd"], epoch.epoch_type.MJD) a = target["a"] * AU e = target["e"] i = target["i"] * DEG2RAD om = target["om"] * DEG2RAD w = target["w"] * DEG2RAD ma = target["ma"] * DEG2RAD as_mu = 1E17 * 6.67384E-11 # maybe need to calculate actual mass from density and radius r = (target["diameter"] / 2) * 1000 sr = r * 1.1 OBJ2 = planet(ep, (a, e, i, om, w, ma), MU_SUN, as_mu, r, sr) OBJ1 = planet.jpl_lp( start_planet) # Calculate location of objects in flight path r1, v1 = OBJ1.eph(t1) r2, v2 = OBJ2.eph(t2) # Find trajectory l = lambert_problem(r1, r2, dt, MU_SUN) #extract relevant information from solution r = l.get_r1() v = l.get_v1()[rev] mu = l.get_mu() #define the integration time dtn = dt / (N - 1) dtn_days = dtn * SEC2DAY #alocate the cartesian components for r t = np.array([0.0] * N) x = np.array([0.0] * N) y = np.array([0.0] * N) z = np.array([0.0] * N) #calculate the spacecraft position at each dt for i in range(N): t[i] = tlaunch + dtn_days * i x[i] = r[0] / AU y[i] = r[1] / AU z[i] = r[2] / AU r, v = propagate_lagrangian(r, v, dtn, mu) #traj = [t, x, y, z] vin = l.get_v1()[rev] vout = l.get_v2()[rev] #dV=fb_vel(vin,vout,planet.jpl_lp(arrive_planet)) #dV=np.sqrt( np.square(vin[0]/vout[0])+np.square(vin[1]/vout[1])+np.square(vin[2]/vout[2])) #dV=np.sqrt( np.square(vin[0]-v1[0])+np.square(v1[1]-vin[1])+np.square(v1[2]-vin[2])) #dV=np.sqrt( np.square(v2[0]-vout[0])+np.square(v2[1]-vout[1])+np.square(v2[2]-vout[2])) #dV=np.sqrt( np.square(v1[0]/vin[0])+np.square(v1[1]/vin[1])+np.square(v1[2]/vin[2])) C3_launch = (np.sqrt( np.square(vin[0] - v1[0]) + np.square(vin[1] - v1[1]) + np.square(vin[2] - v1[2])))**2 C3_arrive = (np.sqrt( np.square(vout[0] - v2[0]) + np.square(vout[1] - v2[1]) + np.square(vout[2] - v2[2])))**2 C3 = np.sqrt((C3_arrive**2) + (C3_launch**2)) return C3
from optimise import optimizer parser.add_argument('--ship-max-deltaV', dest='max_deltav', help='your ship\'s Delta-V budget', default = 20000) args = parser.parse_args() for root, dirs, filenames in os.walk('spice'): for f in filenames: load_spice_kernel('./spice/' + f) launch = [epoch_from_iso_string(x) for x in args.launch.split(',')] tof = [float(x) for x in args.tof.split(',')] vinf = [0.5, float(args.vinf_max)] # We define an Earth-Venus-Earth problem (single-objective) seq = [jpl_lp(name) for name in args.planets.split(',')] # seq = [spice(name) for name in args.planets.split(',')] # seq = [jpl_lp('earth'), jpl_lp('venus'), jpl_lp('venus'), jpl_lp('earth'), jpl_lp('jupiter'), jpl_lp('saturn')] # enc_times = [50736.36319, 50929.5, 51353.5, 51408.14444, 51908.5, 53187.11667] enc_times = [] runMGA = True runMGA_1DSM = True sol_mga = None t = None nTrialMGA = int(args.n_mga) nTrialMGA1DSM = int(args.n_mga_1dsm)
def __init__(self, start=jpl_lp('earth'), target=jpl_lp('venus'), N_max=3, tof=[20., 400.], vinf=[0., 4.], phase_free=True, multi_objective=False, t0=None ): """ prob = PyKEP.trajopt.pl2pl_N_impulses(start=jpl_lp('earth'), target=jpl_lp('venus'), N_max=3, tof=[20., 400.], vinf=[0., 4.], phase_free=True, multi_objective=False, t0=None) - start: a PyKEP planet defining the starting orbit - target: a PyKEP planet defining the target orbit - N_max: maximum number of impulses - tof: a list containing the box bounds [lower,upper] for the time of flight (days) - vinf: a list containing the box bounds [lower,upper] for each DV magnitude (km/sec) - phase_free: when True, no randezvous condition is enforced and the final orbit will be reached at an optimal true anomaly - multi_objective: when True, a multi-objective problem is constructed with DV and time of flight as objectives - t0: launch window defined as a list of two epochs [epoch,epoch] """ # Sanity checks # 1) all planets need to have the same mu_central_body if (start.mu_central_body != target.mu_central_body): raise ValueError('Starting and ending PyKEP.planet must have the same mu_central_body') # 2) Number of impulses must be at least 2 if N_max < 2: raise ValueError('Number of impulses N is less than 2') # 3) If phase_free is True, t0 does not make sense if (t0 is None and not phase_free): t0 = [epoch(0), epoch(1000)] if (t0 is not None and phase_free): raise ValueError('When phase_free is True no t0 can be specified') # We compute the PyGMO problem dimensions dim = 2 + 4 * (N_max - 2) + 1 + phase_free obj_dim = multi_objective + 1 # First we call the constructor for the base PyGMO problem # As our problem is n dimensional, box-bounded (may be multi-objective), we write # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(pl2pl_N_impulses, self).__init__(dim, 0, obj_dim, 0, 0, 0) # We then define all class data members self.start = start self.target = target self.N_max = N_max self.phase_free = phase_free self.multi_objective = multi_objective self.__common_mu = start.mu_central_body # And we compute the bounds if phase_free: lb = [start.ref_epoch.mjd2000, tof[0]] + [0.0, 0.0, 0.0, vinf[0] * 1000] * (N_max - 2) + [0.0] + [target.ref_epoch.mjd2000] ub = [start.ref_epoch.mjd2000 + 2 * start.period * SEC2DAY, tof[1]] + [1.0, 1.0, 1.0, vinf[1] * 1000] * (N_max - 2) + [1.0] + [target.ref_epoch.mjd2000 + 2 * target.period * SEC2DAY] else: lb = [t0[0].mjd2000, tof[0]] + [0.0, 0.0, 0.0, vinf[0] * 1000] * (N_max - 2) + [0.0] ub = [t0[1].mjd2000, tof[1]] + [1.0, 1.0, 1.0, vinf[1] * 1000] * (N_max - 2) + [1.0] # And we set them self.set_bounds(lb, ub)
def __init__(self, start=jpl_lp('earth'), target=jpl_lp('venus'), N_max=3, tof=[20., 400.], vinf=[0., 4.], phase_free=True, multi_objective=False, t0=None): """ prob = PyKEP.trajopt.pl2pl_N_impulses(start=jpl_lp('earth'), target=jpl_lp('venus'), N_max=3, tof=[20., 400.], vinf=[0., 4.], phase_free=True, multi_objective=False, t0=None) - start: a PyKEP planet defining the starting orbit - target: a PyKEP planet defining the target orbit - N_max: maximum number of impulses - tof: a list containing the box bounds [lower,upper] for the time of flight (days) - vinf: a list containing the box bounds [lower,upper] for each DV magnitude (km/sec) - phase_free: when True, no randezvous condition is enforced and the final orbit will be reached at an optimal true anomaly - multi_objective: when True, a multi-objective problem is constructed with DV and time of flight as objectives - t0: launch window defined as a list of two epochs [epoch,epoch] """ # Sanity checks # 1) all planets need to have the same mu_central_body if (start.mu_central_body != target.mu_central_body): raise ValueError( 'Starting and ending PyKEP.planet must have the same mu_central_body' ) # 2) Number of impulses must be at least 2 if N_max < 2: raise ValueError('Number of impulses N is less than 2') # 3) If phase_free is True, t0 does not make sense if (t0 is None and not phase_free): t0 = [epoch(0), epoch(1000)] if (t0 is not None and phase_free): raise ValueError('When phase_free is True no t0 can be specified') # We compute the PyGMO problem dimensions dim = 2 + 4 * (N_max - 2) + 1 + phase_free obj_dim = multi_objective + 1 # First we call the constructor for the base PyGMO problem # As our problem is n dimensional, box-bounded (may be multi-objective), we write # (dim, integer dim, number of obj, number of con, number of inequality con, tolerance on con violation) super(pl2pl_N_impulses, self).__init__(dim, 0, obj_dim, 0, 0, 0) # We then define all class data members self.start = start self.target = target self.N_max = N_max self.phase_free = phase_free self.multi_objective = multi_objective self.__common_mu = start.mu_central_body # And we compute the bounds if phase_free: lb = [start.ref_epoch.mjd2000, tof[0] ] + [0.0, 0.0, 0.0, vinf[0] * 1000] * (N_max - 2) + [0.0] + [ target.ref_epoch.mjd2000 ] ub = [ start.ref_epoch.mjd2000 + 2 * start.period * SEC2DAY, tof[1] ] + [1.0, 1.0, 1.0, vinf[1] * 1000] * (N_max - 2) + [1.0] + [ target.ref_epoch.mjd2000 + 2 * target.period * SEC2DAY ] else: lb = [t0[0].mjd2000, tof[0] ] + [0.0, 0.0, 0.0, vinf[0] * 1000] * (N_max - 2) + [0.0] ub = [t0[1].mjd2000, tof[1] ] + [1.0, 1.0, 1.0, vinf[1] * 1000] * (N_max - 2) + [1.0] # And we set them self.set_bounds(lb, ub)