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