def calcOrbit(self): errEAN_L = 0 * pi / 180 errArgPe = 0 * pi / 180 v0_pred = [0, 0, 0] r0_pred = [0, 0, 0] v1_pred = [0, 0, 0] r1_pred = [0, 0, 0] # we try to first convert keplerian elements to carthesian, then propagate print("------------------------------------------------------") self.rL_data, self.vL_data = par2ic([ self.SMA, self.e, 0, 0, self.ArgPe + errArgPe, self.EAN_L + errEAN_L ], self.mu_c) self.printVect(self.rL_data, "rL pred") self.printVect(self.vL_data, "vL pred") r0_pred, v0_pred = propagate_lagrangian(self.rL_data, self.vL_data, self.t0_M, self.mu_c) self.printVect(r0_pred, "r0 pred") self.printVect(v0_pred, "v0 pred") self.deltasAtPoint(norm(r0_pred), norm(v0_pred), self.rn0, self.vn0, "r0", "v0") r1_pred, v1_pred = propagate_lagrangian(self.rL_data, self.vL_data, self.t1_M, self.mu_c) self.printVect(r1_pred, "r1 pred") self.printVect(v1_pred, "v1 pred") self.deltasAtPoint(norm(r1_pred), norm(v1_pred), self.rn1, self.vn1, "r0", "v0") '''
def plot_kepler(r, v, t, mu, N=60, units=1, color='b', legend=False, ax=None): """ ax = plot_kepler(r, v, t, mu, N=60, units=1, color='b', legend=False, ax=None): - ax: 3D axis object created using fig.gca(projection='3d') - r: initial position (cartesian coordinates) - v: initial velocity (cartesian coordinates) - t: propagation time - mu: gravitational parameter - N: number of points to be plotted along one arc - units: the length unit to be used in the plot - color: matplotlib color to use to plot the line - legend when True it plots also the legend Plots the result of a keplerian propagation """ from pykep import propagate_lagrangian import matplotlib.pylab as plt from mpl_toolkits.mplot3d import Axes3D if ax is None: fig = plt.figure() axis = fig.gca(projection='3d') else: axis = ax # We define the integration time ... dt = t / (N - 1) # ... and calculate the cartesian components for r x = [0.0] * N y = [0.0] * N z = [0.0] * N # We calculate the spacecraft position at each dt for i in range(N): x[i] = r[0] / units y[i] = r[1] / units z[i] = r[2] / units r, v = propagate_lagrangian(r, v, dt, mu) # And we plot if legend: label = 'ballistic arc' else: label = None axis.plot(x, y, z, c=color, label=label) if legend: axis.legend() if ax is None: # show only if axis is not set plt.show() return axis
def plot_kepler(r0, v0, tof, mu, N=60, units=1, color='b', label=None, axes=None): """ ax = plot_kepler(r0, v0, tof, mu, N=60, units=1, color='b', label=None, axes=None): - axes: 3D axis object created using fig.gca(projection='3d') - r0: initial position (cartesian coordinates) - v0: initial velocity (cartesian coordinates) - tof: propagation time - mu: gravitational parameter - N: number of points to be plotted along one arc - units: the length unit to be used in the plot - color: matplotlib color to use to plot the line - label adds a label to the plotted arc. Plots the result of a keplerian propagation Example:: import pykep as pk pi = 3.14 pk.orbit_plots.plot_kepler(r0 = [1,0,0], v0 = [0,1,0], tof = pi/3, mu = 1) """ from pykep import propagate_lagrangian import matplotlib.pylab as plt from mpl_toolkits.mplot3d import Axes3D from copy import deepcopy if axes is None: fig = plt.figure() ax = fig.gca(projection='3d') else: ax = axes # We define the integration time ... dt = tof / (N - 1) # ... and calculate the cartesian components for r x = [0.0] * N y = [0.0] * N z = [0.0] * N # We calculate the spacecraft position at each dt r = deepcopy(r0) v = deepcopy(v0) for i in range(N): x[i] = r[0] / units y[i] = r[1] / units z[i] = r[2] / units r, v = propagate_lagrangian(r, v, dt, mu) # And we plot ax.plot(x, y, z, c=color, label=label) return ax
def calcOrbit(self): errEAN_L = 0 * pi/180 errArgPe = 0# -3.91 * pi/180 timeErr = 0 # we try to first convert keplerian elements (assuming ArgPe = 0) to carthesian at t1, then back-propagate to tL to get r, then TAN_L then ArgPe. Hopefully.... print("------------------------------------------------------") #First, fisrt guess at t1 : self.OrbitPoints[1].r, self.OrbitPoints[1].v = par2ic([self.SMA,self.e,0,0,0,self.OrbitPoints[1].EAN],self.mu_c) #Then back propagate to tL : self.OrbitPoints[0].r, self.OrbitPoints[0].v = propagate_lagrangian(self.OrbitPoints[1].r,self.OrbitPoints[1].v,self.OrbitPoints[0].t-self.OrbitPoints[1].t,self.mu_c) #-t0_M should be tL self.printVect(self.OrbitPoints[0].r,"rLaunch pred") self.printVect(self.OrbitPoints[0].v,"vLaunch pred") print("Launch influence free radius : ",np.round(self.OrbitPoints[0].r_n/1000,1)," [km]") print("Launch radius delta from K orbit : ",np.round(self.OrbitPoints[0].r_n/1000-norm(self.OrbitPoints[0].r)/1000,1)," [km]") #we need the sign for the TAN, i.e. are we before or after Pe Do this with a small delta T dt = 1 rLdt, vLdt = propagate_lagrangian(self.OrbitPoints[1].r,self.OrbitPoints[1].v,self.OrbitPoints[0].t-self.OrbitPoints[1].t+dt,self.mu_c) #measure dr from dt. # if dr is increasing with dt, Pe is past, if decreasing Pe is in front of us sign = 1 if norm(self.OrbitPoints[0].r)-norm(rLdt) < 0 : sign = -1 self.OrbitPoints[0].SetAN(self.SMA,self.e,sign,"fromVector") self.ArgPe = self.calcArgPe(self.OrbitPoints[0].t)+errArgPe #now that we have a proper radius (virtual radius ignoring kerbin influence at tL, we get a proper trueAnom and can get the ArgPe) #self.ArgPe = (17.9)*pi/180 print("------------------------------------------------------") print("TAN at Launch : ",self.OrbitPoints[0].TAN*180/pi) print("EAN at Launch : ",self.OrbitPoints[0].EAN*180/pi) print("KTAN at Launch : ",self.KerbinTAN(self.OrbitPoints[0].t)*180/pi) print("Arg Pe : ",self.ArgPe*180/pi) print("------------------------------------------------------") self.OrbitPoints[2].r, self.OrbitPoints[2].v = propagate_lagrangian(self.OrbitPoints[1].r,self.OrbitPoints[1].v,self.OrbitPoints[2].t-self.OrbitPoints[1].t,self.mu_c) #-t0_M should be tL self.printVect(self.OrbitPoints[2].r,"r2 pred from t1") self.printVect(self.OrbitPoints[2].v,"v2 pred from t1") self.deltasAtPoint(norm(self.OrbitPoints[2].r),norm(self.OrbitPoints[2].v),self.OrbitPoints[2].r_n,self.OrbitPoints[2].v_n,"r2","v2") print("------------------------------------------------------") # This all good and well, but the orbit epoch is set to t0, which is unpractical. # For lambert solving, it would be much better to have it set to epoch zero i.e. y1d1 00:00:00 # To do that we need to back propagate to -self.t1, then use r to derive the true anomaly self.AddOrbitPoint("0:0:0:0:0",0,0) #Orbit at epoch Zero self.OrbitPoints[-1].r, self.OrbitPoints[-1].v = propagate_lagrangian(self.OrbitPoints[1].r,self.OrbitPoints[1].v,-self.OrbitPoints[1].t,self.mu_c) #we now have r,v at epoch Zero #print(self.rZero," ",self.vZero) self.OrbitPoints[-1].SetAN(self.SMA,self.e,-1,"fromVector") # we are definitly before Pe #self.ArgPe = self.calcArgPe(0)+errArgPe print("TAN at Epoch Zero : ",self.OrbitPoints[-1].TAN*180/pi) self.OrbitPoints[-1].r, self.OrbitPoints[-1].v = par2ic([self.SMA,self.e,0,0,self.ArgPe,self.OrbitPoints[-1].EAN],self.mu_c) r0Z, v0Z = propagate_lagrangian(self.OrbitPoints[-1].r,self.OrbitPoints[-1].v,self.OrbitPoints[1].t,self.mu_c) self.printVect(r0Z,"r1 pred") self.printVect(v0Z,"v1 pred") self.deltasAtPoint(norm(r0Z),norm(v0Z),(self.OrbitPoints[1].r_n),(self.OrbitPoints[1].v_n),"r1 fromZero","v1 fromZero") r1Z, v1Z = propagate_lagrangian(self.OrbitPoints[-1].r,self.OrbitPoints[-1].v,self.OrbitPoints[2].t,self.mu_c) self.printVect(r1Z,"r2 pred") self.printVect(v1Z,"v2 pred") self.deltasAtPoint(norm(r1Z),norm(v1Z),(self.OrbitPoints[2].r_n),(self.OrbitPoints[2].v_n),"r2 fromZero","v2 fromZero")
def calcOrbit(self): errEAN_L = 0 * pi/180 errArgPe = 0 * pi/180 timeErr = 0 # we try to first convert keplerian elements (assuming ArgPe = 0) to carthesian at t1, then back-propagate to tL to get r, then TAN_L then ArgPe. Hopefully.... print("------------------------------------------------------") #First, fisrt guess at t1 : self.r0, self.v0 = par2ic([self.SMA,self.e,0,0,0,self.EAN_t0],self.mu_c) #Then back propagate to tL : self.rL, self.vL = propagate_lagrangian(self.r0,self.v0,-self.t0_M,self.mu_c) #-t0_M should be tL self.printVect(self.rL,"rL pred") self.printVect(self.vL,"vL pred") print("rL influence free radius : ",self.rnL) print("rL radius delta from K orbit : ",self.rnL-norm(self.rL)) #we need the sign for the TAN, i.e. are we before or after Pe Do this with a small delta T dt = 1 rLdt, vLdt = propagate_lagrangian(self.r0,self.v0,-self.t0_M+dt,self.mu_c) #measure dr from dt. # if dr is increasing with dt, Pe is past, if decreasing Pe is in front of us sign = 1 if norm(self.rL)-norm(rLdt) < 0 : sign = -1 self.TAN_L = self.calcTAN(norm(self.rL),sign) self.EAN_L = self.calcEAN(self.TAN_L) self.ArgPe = self.calcArgPe(self.tL)+errArgPe #now that we have a proper radius (virtual radius ignoring kerbin influence at tL, we get a proper trueAnom and can get the ArgPe) print("------------------------------------------------------") print("TAN at Launch : ",self.TAN_L*180/pi) print("EAN at Launch : ",self.EAN_L*180/pi) print("KTAN at Launch : ",self.KerbinTAN(self.tL)*180/pi) print("Arg Pe : ",self.ArgPe*180/pi) print("------------------------------------------------------") self.r1, self.v1 = propagate_lagrangian(self.r0,self.v0,self.t1-self.t0,self.mu_c) #-t0_M should be tL self.printVect(self.r1,"r1 pred") self.printVect(self.v1,"v1 pred") self.deltasAtPoint(norm(self.r1),norm(self.v1),self.rn1,self.vn1,"r1","v1") # This all good and well, but the orbit epoch is set to t0, which is unpractical. # For lambert solving, it would be much better to have it set to epoch zero i.e. y1d1 00:00:00 # To do that we need to back propagate to -self.t1, then use r to derive the true anomaly self.rZero, self.vZero = propagate_lagrangian(self.r0,self.v0,-self.t0,self.mu_c) #we now have r,v at epoch Zero print(self.rZero," ",self.vZero) self.TAN_Zero = self.calcTAN(norm(self.rZero),-1) # we are definitly before Pe EAN_ZeroErr = 0*pi/180 ### There is a problem with E at epoch self.EAN_Zero = self.calcEAN(self.TAN_Zero)+EAN_ZeroErr #self.ArgPe = self.calcArgPe(0)+errArgPe print("TAN at Epoch Zero : ",self.TAN_Zero*180/pi) self.rZero, self.vZero = par2ic([self.SMA,self.e,0,0,self.ArgPe,self.EAN_Zero],self.mu_c) r0Z, v0Z = propagate_lagrangian(self.rZero,self.vZero,self.t0,self.mu_c) self.printVect(r0Z,"r0 pred") self.printVect(v0Z,"v0 pred") self.deltasAtPoint(norm(r0Z),norm(v0Z),(self.rn0),(self.vn0),"r0fromZero","v0fromZero") r1Z, v1Z = propagate_lagrangian(self.rZero,self.vZero,self.t1,self.mu_c) self.printVect(r1Z,"r1 pred") self.printVect(v1Z,"v1 pred") self.deltasAtPoint(norm(r1Z),norm(v1Z),(self.rn1),(self.vn1),"r1fromZero","v1fromZero")
def plot_lambert_2d(lambert, sol=0): if sol > lambert.get_Nmax() * 2: return ValueError("sol must be in 0 .. NMax*2 \n", "* Nmax is the maximum number of revolutions ", "for which there exists a solution.") r = lambert.get_r1() v = lambert.get_v1()[sol] T = lambert.get_tof() mu = lambert.get_mu() dt = T / (60 - 1) x = np.array([0.0] * 60) y = np.array([0.0] * 60) z = np.array([0.0] * 60) for i in range(60): x[i] = r[0] / AU y[i] = r[1] / AU z[i] = r[2] / AU r, v = propagate_lagrangian(r, v, dt, mu) return x, y, z
def plot_sf_leg(leg, N=5, units=1, color='b', legend=False, plot_line=True, plot_segments=False, axes=None): """ ax = plot_sf_leg(leg, N=5, units=1, color='b', legend=False, no_trajectory=False, axes=None): - axes: 3D axis object created using fig.gca(projection='3d') - leg: a pykep.sims_flanagan.leg - N: number of points to be plotted along one arc - units: the length unit to be used in the plot - color: matplotlib color to use to plot the trajectory and the grid points - legend when True it plots also the legend - plot_line: when True plots also the trajectory (between mid-points and grid points) Plots a Sims-Flanagan leg Example:: from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt fig = plt.figure() ax = fig.gca(projection='3d') t1 = epoch(0) pl = planet_ss('earth') rE,vE = pl.eph(t1) plot_planet(pl,t0=t1, units=AU, axes=ax) t2 = epoch(440) pl = planet_ss('mars') rM, vM = pl.eph(t2) plot_planet(pl,t0=t2, units=AU, axes=ax) sc = sims_flanagan.spacecraft(4500,0.5,2500) x0 = sims_flanagan.sc_state(rE,vE,sc.mass) xe = sims_flanagan.sc_state(rM,vM,sc.mass) l = sims_flanagan.leg(t1,x0,[1,0,0]*5,t2,xe,sc,MU_SUN) plot_sf_leg(l, units=AU, axes=ax) """ from pykep import propagate_lagrangian, AU, DAY2SEC, G0, propagate_taylor import numpy as np from scipy.linalg import norm from math import exp import matplotlib.pylab as plt from mpl_toolkits.mplot3d import Axes3D if axes is None: fig = plt.figure() ax = fig.gca(projection='3d') else: ax = axes # We compute the number of segments for forward and backward propagation n_seg = len(leg.get_throttles()) fwd_seg = (n_seg + 1) // 2 back_seg = n_seg // 2 # We extract information on the spacecraft sc = leg.get_spacecraft() isp = sc.isp max_thrust = sc.thrust # And on the leg throttles = leg.get_throttles() mu = leg.get_mu() # Forward propagation # x,y,z contain the cartesian components of all points (grid+midpoints) x = [0.0] * (fwd_seg * 2 + 1) y = [0.0] * (fwd_seg * 2 + 1) z = [0.0] * (fwd_seg * 2 + 1) state = leg.get_xi() # Initial conditions r = state.r v = state.v m = state.m x[0] = r[0] / units y[0] = r[1] / units z[0] = r[2] / units # We compute all points by propagation for i, t in enumerate(throttles[:fwd_seg]): dt = (t.end.mjd - t.start.mjd) * DAY2SEC alpha = min(norm(t.value), 1.0) # Keplerian propagation and dV application if leg.high_fidelity is False: dV = [max_thrust / m * dt * dumb for dumb in t.value] if plot_line: plot_kepler(r, v, dt / 2, mu, N=N, units=units, color=(alpha, 0, 1 - alpha), axes=ax) r, v = propagate_lagrangian(r, v, dt / 2, mu) x[2 * i + 1] = r[0] / units y[2 * i + 1] = r[1] / units z[2 * i + 1] = r[2] / units # v= v+dV v = [a + b for a, b in zip(v, dV)] if plot_line: plot_kepler(r, v, dt / 2, mu, N=N, units=units, color=(alpha, 0, 1 - alpha), axes=ax) r, v = propagate_lagrangian(r, v, dt / 2, mu) x[2 * i + 2] = r[0] / units y[2 * i + 2] = r[1] / units z[2 * i + 2] = r[2] / units m *= exp(-norm(dV) / isp / G0) # Taylor propagation of constant thrust u else: u = [max_thrust * dumb for dumb in t.value] if plot_line: plot_taylor(r, v, m, u, dt / 2, mu, isp * G0, N=N, units=units, color=(alpha, 0, 1 - alpha), axes=ax) r, v, m = propagate_taylor(r, v, m, u, dt / 2, mu, isp * G0, -12, -12) x[2 * i + 1] = r[0] / units y[2 * i + 1] = r[1] / units z[2 * i + 1] = r[2] / units if plot_line: plot_taylor(r, v, m, u, dt / 2, mu, isp * G0, N=N, units=units, color=(alpha, 0, 1 - alpha), axes=ax) r, v, m = propagate_taylor(r, v, m, u, dt / 2, mu, isp * G0, -12, -12) x[2 * i + 2] = r[0] / units y[2 * i + 2] = r[1] / units z[2 * i + 2] = r[2] / units x_grid = x[::2] y_grid = y[::2] z_grid = z[::2] x_midpoint = x[1::2] y_midpoint = y[1::2] z_midpoint = z[1::2] if plot_segments: ax.scatter(x_grid[:-1], y_grid[:-1], z_grid[:-1], label='nodes', marker='o') ax.scatter(x_midpoint, y_midpoint, z_midpoint, label='mid-points', marker='x') ax.scatter(x_grid[-1], y_grid[-1], z_grid[-1], marker='^', c='y', label='mismatch point') # Backward propagation # x,y,z will contain the cartesian components of x = [0.0] * (back_seg * 2 + 1) y = [0.0] * (back_seg * 2 + 1) z = [0.0] * (back_seg * 2 + 1) state = leg.get_xf() # Final conditions r = state.r v = state.v m = state.m x[-1] = r[0] / units y[-1] = r[1] / units z[-1] = r[2] / units for i, t in enumerate(throttles[-1:-back_seg - 1:-1]): dt = (t.end.mjd - t.start.mjd) * DAY2SEC alpha = min(norm(t.value), 1.0) if leg.high_fidelity is False: dV = [max_thrust / m * dt * dumb for dumb in t.value] if plot_line: plot_kepler(r, v, -dt / 2, mu, N=N, units=units, color=(alpha, 0, 1 - alpha), axes=ax) r, v = propagate_lagrangian(r, v, -dt / 2, mu) x[-2 * i - 2] = r[0] / units y[-2 * i - 2] = r[1] / units z[-2 * i - 2] = r[2] / units # v= v+dV v = [a - b for a, b in zip(v, dV)] if plot_line: plot_kepler(r, v, -dt / 2, mu, N=N, units=units, color=(alpha, 0, 1 - alpha), axes=ax) r, v = propagate_lagrangian(r, v, -dt / 2, mu) x[-2 * i - 3] = r[0] / units y[-2 * i - 3] = r[1] / units z[-2 * i - 3] = r[2] / units m *= exp(norm(dV) / isp / G0) else: u = [max_thrust * dumb for dumb in t.value] if plot_line: plot_taylor(r, v, m, u, -dt / 2, mu, isp * G0, N=N, units=units, color=(alpha, 0, 1 - alpha), axes=ax) r, v, m = propagate_taylor(r, v, m, u, -dt / 2, mu, isp * G0, -12, -12) x[-2 * i - 2] = r[0] / units y[-2 * i - 2] = r[1] / units z[-2 * i - 2] = r[2] / units if plot_line: plot_taylor(r, v, m, u, -dt / 2, mu, isp * G0, N=N, units=units, color=(alpha, 0, 1 - alpha), axes=ax) r, v, m = propagate_taylor(r, v, m, u, -dt / 2, mu, isp * G0, -12, -12) x[-2 * i - 3] = r[0] / units y[-2 * i - 3] = r[1] / units z[-2 * i - 3] = r[2] / units x_grid = x[::2] y_grid = y[::2] z_grid = z[::2] x_midpoint = x[1::2] y_midpoint = y[1::2] z_midpoint = z[1::2] if plot_segments: ax.scatter(x_grid[1:], y_grid[1:], z_grid[1:], marker='o', label='nodes') ax.scatter(x_midpoint, y_midpoint, z_midpoint, marker='x', label='mid-points') ax.scatter(x_grid[0], y_grid[0], z_grid[0], marker='^', c='y', label='mismatch point') if legend: ax.legend() if axes is None: # show only if axis is not set plt.show() return ax
def plot_lambert(l, N=60, sol=0, units=1.0, color='b', legend=False, axes=None, alpha=1.): """ ax = plot_lambert(l, N=60, sol=0, units='pykep.AU', legend='False', axes=None, alpha=1.) - axes: 3D axis object created using fig.gca(projection='3d') - l: pykep.lambert_problem object - N: number of points to be plotted along one arc - sol: solution to the Lambert's problem we want to plot (must be in 0..Nmax*2) where Nmax is the maximum number of revolutions for which there exist a solution. - units: the length unit to be used in the plot - color: matplotlib color to use to plot the line - legend: when True it plots also the legend with info on the Lambert's solution chosen Plots a particular solution to a Lambert's problem Example:: import pykep as pk import matplotlib.pyplot as plt fig = plt.figure() ax = fig.gca(projection='3d') t1 = pk.epoch(0) t2 = pk.epoch(640) dt = (t2.mjd2000 - t1.mjd2000) * pk.DAY2SEC pl = pk.planet.jpl_lp('earth') pk.orbit_plots.plot_planet(pl, t0=t1, axes=ax, color='k') rE,vE = pl.eph(t1) pl = pk.planet.jpl_lp('mars') pk.orbit_plots.plot_planet(pl, t0=t2, axes=ax, color='r') rM, vM = pl.eph(t2) l = lambert_problem(rE,rM,dt,pk.MU_SUN) pk.orbit_plots.plot_lambert(l, ax=ax, color='b') pk.orbit_plots.plot_lambert(l, sol=1, axes=ax, color='g') pk.orbit_plots.plot_lambert(l, sol=2, axes=ax, color='g', legend = True) plt.show() """ from pykep import propagate_lagrangian, AU import numpy as np import matplotlib.pylab as plt from mpl_toolkits.mplot3d import Axes3D if axes is None: fig = plt.figure() ax = fig.gca(projection='3d') else: ax = axes if sol > l.get_Nmax() * 2: raise ValueError( "sol must be in 0 .. NMax*2 \n * Nmax is the maximum number of revolutions for which there exist a solution to the Lambert's problem \n * You can compute Nmax calling the get_Nmax() method of the lambert_problem object" ) # We extract the relevant information from the Lambert's problem r = l.get_r1() v = l.get_v1()[sol] T = l.get_tof() mu = l.get_mu() # We define the integration time ... dt = T / (N - 1) # ... and allocate the cartesian components for r x = np.array([0.0] * N) y = np.array([0.0] * N) z = np.array([0.0] * N) # We calculate the spacecraft position at each dt for i in range(N): x[i] = r[0] / units y[i] = r[1] / units z[i] = r[2] / units r, v = propagate_lagrangian(r, v, dt, mu) # And we plot if legend: label = 'Lambert solution (' + str((sol + 1) // 2) + ' revs.)' else: label = None ax.plot(x, y, z, c=color, label=label, alpha=alpha) if legend: ax.legend() return ax
def _leg_get_states(self): """ Returns the spacecraft states (t,r,v,m) at the leg grid points Examples:: times,r,v,m = pykep.sims_flanagan.leg.get_states() """ from pykep import propagate_lagrangian, AU, DAY2SEC, G0, propagate_taylor import numpy as np from scipy.linalg import norm from math import exp # We compute the number of segments for forward and backward propagation n_seg = len(self.get_throttles()) fwd_seg = (n_seg + 1) // 2 back_seg = n_seg // 2 # We extract information on the spacecraft sc = self.get_spacecraft() isp = sc.isp max_thrust = sc.thrust # And on the leg throttles = self.get_throttles() mu = self.get_mu() # time grid (the mismatch is repeated twice) t_grid = [0.0] * (n_seg * 2 + 2) # Forward propagation # x,y,z contain the cartesian components of all points (grid+midpints) x = [0.0] * (fwd_seg * 2 + 1) y = [0.0] * (fwd_seg * 2 + 1) z = [0.0] * (fwd_seg * 2 + 1) vx = [0.0] * (fwd_seg * 2 + 1) vy = [0.0] * (fwd_seg * 2 + 1) vz = [0.0] * (fwd_seg * 2 + 1) mass = [0.0] * (fwd_seg * 2 + 1) state = self.get_xi() # Initial conditions r = state.r v = state.v m = state.m x[0], y[0], z[0] = r vx[0], vy[0], vz[0] = v mass[0] = m # We compute all points by propagation for i, t in enumerate(throttles[:fwd_seg]): t_grid[2 * i] = t.start.mjd2000 t_grid[2 * i + 1] = t.start.mjd2000 + \ (t.end.mjd2000 - t.start.mjd2000) / 2. dt = (t.end.mjd - t.start.mjd) * DAY2SEC alpha = min(norm(t.value), 1.0) # Keplerian propagation and dV application if self.high_fidelity is False: dV = [max_thrust / m * dt * dumb for dumb in t.value] r, v = propagate_lagrangian(r, v, dt / 2, mu) x[2 * i + 1], y[2 * i + 1], z[2 * i + 1] = r vx[2 * i + 1], vy[2 * i + 1], vz[2 * i + 1] = v mass[2 * i + 1] = m # v= v+dV v = [a + b for a, b in zip(v, dV)] r, v = propagate_lagrangian(r, v, dt / 2, mu) m *= exp(-norm(dV) / isp / G0) x[2 * i + 2], y[2 * i + 2], z[2 * i + 2] = r vx[2 * i + 2], vy[2 * i + 2], vz[2 * i + 2] = v mass[2 * i + 2] = m # Taylor propagation of constant thrust u else: u = [max_thrust * dumb for dumb in t.value] r, v, m = propagate_taylor( r, v, m, u, dt / 2, mu, isp * G0, -12, -12) x[2 * i + 1], y[2 * i + 1], z[2 * i + 1] = r vx[2 * i + 1], vy[2 * i + 1], vz[2 * i + 1] = v mass[2 * i + 1] = m r, v, m = propagate_taylor( r, v, m, u, dt / 2, mu, isp * G0, -12, -12) x[2 * i + 2], y[2 * i + 2], z[2 * i + 2] = r vx[2 * i + 2], vy[2 * i + 2], vz[2 * i + 2] = v mass[2 * i + 2] = m t_grid[2 * i + 2] = t.end.mjd2000 # Backward propagation # x,y,z will contain the cartesian components of x_back = [0.123] * (back_seg * 2 + 1) y_back = [0.123] * (back_seg * 2 + 1) z_back = [0.123] * (back_seg * 2 + 1) vx_back = [0.0] * (back_seg * 2 + 1) vy_back = [0.0] * (back_seg * 2 + 1) vz_back = [0.0] * (back_seg * 2 + 1) mass_back = [0.0] * (back_seg * 2 + 1) state = self.get_xf() # Final conditions r = state.r v = state.v m = state.m x_back[-1], y_back[-1], z_back[-1] = r vx_back[-1], vy_back[-1], vz_back[-1] = v mass_back[-1] = m for i, t in enumerate(throttles[-1:-back_seg - 1:-1]): t_grid[-2 * i - 2] = t.end.mjd2000 - \ (t.end .mjd2000 - t.start.mjd2000) / 2. t_grid[-2 * i - 1] = t.end.mjd2000 dt = (t.end.mjd - t.start.mjd) * DAY2SEC alpha = min(norm(t.value), 1.0) if self.high_fidelity is False: dV = [max_thrust / m * dt * dumb for dumb in t.value] r, v = propagate_lagrangian(r, v, -dt / 2, mu) x_back[-2 * i - 2], y_back[-2 * i - 2], z_back[-2 * i - 2] = r vx_back[-2 * i - 2], vy_back[-2 * i - 2], vz_back[-2 * i - 2] = v mass_back[-2 * i - 2] = m # v= v+dV v = [a - b for a, b in zip(v, dV)] r, v = propagate_lagrangian(r, v, -dt / 2, mu) m *= exp(norm(dV) / isp / G0) x_back[-2 * i - 3], y_back[-2 * i - 3], z_back[-2 * i - 3] = r vx_back[-2 * i - 3], vy_back[-2 * i - 3], vz_back[-2 * i - 3] = v mass_back[-2 * i - 3] = m else: u = [max_thrust * dumb for dumb in t.value] r, v, m = propagate_taylor( r, v, m, u, -dt / 2, mu, isp * G0, -12, -12) x_back[-2 * i - 2], y_back[-2 * i - 2], z_back[-2 * i - 2] = r vx_back[-2 * i - 2], vy_back[-2 * i - 2], vz_back[-2 * i - 2] = v mass_back[-2 * i - 2] = m r, v, m = propagate_taylor( r, v, m, u, -dt / 2, mu, isp * G0, -12, -12) x_back[-2 * i - 3], y_back[-2 * i - 3], z_back[-2 * i - 3] = r vx_back[-2 * i - 3], vy_back[-2 * i - 3], vz_back[-2 * i - 3] = v mass_back[-2 * i - 3] = m t_grid[-2 * i - 3] = t.start.mjd2000 x = x + x_back y = y + y_back z = z + z_back vx = vx + vx_back vy = vy + vy_back vz = vz + vz_back mass = mass + mass_back return t_grid, list(zip(x, y, z)), list(zip(vx, vy, vz)), mass
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 _leg_get_states(self): """ Returns the spacecraft states (t,r,v,m) at the leg grid points Examples:: times,r,v,m = pykep.sims_flanagan.leg.get_states() """ from pykep import propagate_lagrangian, AU, DAY2SEC, G0, propagate_taylor import numpy as np from scipy.linalg import norm from math import exp # We compute the number of segments for forward and backward propagation n_seg = len(self.get_throttles()) fwd_seg = (n_seg + 1) // 2 back_seg = n_seg // 2 # We extract information on the spacecraft sc = self.get_spacecraft() isp = sc.isp max_thrust = sc.thrust # And on the leg throttles = self.get_throttles() mu = self.get_mu() # time grid (the mismatch is repeated twice) t_grid = [0.0] * (n_seg * 2 + 2) # Forward propagation # x,y,z contain the cartesian components of all points (grid+midpints) x = [0.0] * (fwd_seg * 2 + 1) y = [0.0] * (fwd_seg * 2 + 1) z = [0.0] * (fwd_seg * 2 + 1) vx = [0.0] * (fwd_seg * 2 + 1) vy = [0.0] * (fwd_seg * 2 + 1) vz = [0.0] * (fwd_seg * 2 + 1) mass = [0.0] * (fwd_seg * 2 + 1) state = self.get_xi() # Initial conditions r = state.r v = state.v m = state.m x[0], y[0], z[0] = r vx[0], vy[0], vz[0] = v mass[0] = m # We compute all points by propagation for i, t in enumerate(throttles[:fwd_seg]): t_grid[2 * i] = t.start.mjd2000 t_grid[2 * i + 1] = t.start.mjd2000 + \ (t.end.mjd2000 - t.start.mjd2000) / 2. dt = (t.end.mjd - t.start.mjd) * DAY2SEC alpha = min(norm(t.value), 1.0) # Keplerian propagation and dV application if self.high_fidelity is False: dV = [max_thrust / m * dt * dumb for dumb in t.value] r, v = propagate_lagrangian(r, v, dt / 2, mu) x[2 * i + 1], y[2 * i + 1], z[2 * i + 1] = r vx[2 * i + 1], vy[2 * i + 1], vz[2 * i + 1] = v mass[2 * i + 1] = m # v= v+dV v = [a + b for a, b in zip(v, dV)] r, v = propagate_lagrangian(r, v, dt / 2, mu) m *= exp(-norm(dV) / isp / G0) x[2 * i + 2], y[2 * i + 2], z[2 * i + 2] = r vx[2 * i + 2], vy[2 * i + 2], vz[2 * i + 2] = v mass[2 * i + 2] = m # Taylor propagation of constant thrust u else: u = [max_thrust * dumb for dumb in t.value] r, v, m = propagate_taylor(r, v, m, u, dt / 2, mu, isp * G0, -12, -12) x[2 * i + 1], y[2 * i + 1], z[2 * i + 1] = r vx[2 * i + 1], vy[2 * i + 1], vz[2 * i + 1] = v mass[2 * i + 1] = m r, v, m = propagate_taylor(r, v, m, u, dt / 2, mu, isp * G0, -12, -12) x[2 * i + 2], y[2 * i + 2], z[2 * i + 2] = r vx[2 * i + 2], vy[2 * i + 2], vz[2 * i + 2] = v mass[2 * i + 2] = m t_grid[2 * i + 2] = t.end.mjd2000 # Backward propagation # x,y,z will contain the cartesian components of x_back = [0.123] * (back_seg * 2 + 1) y_back = [0.123] * (back_seg * 2 + 1) z_back = [0.123] * (back_seg * 2 + 1) vx_back = [0.0] * (back_seg * 2 + 1) vy_back = [0.0] * (back_seg * 2 + 1) vz_back = [0.0] * (back_seg * 2 + 1) mass_back = [0.0] * (back_seg * 2 + 1) state = self.get_xf() # Final conditions r = state.r v = state.v m = state.m x_back[-1], y_back[-1], z_back[-1] = r vx_back[-1], vy_back[-1], vz_back[-1] = v mass_back[-1] = m for i, t in enumerate(throttles[-1:-back_seg - 1:-1]): t_grid[-2 * i - 2] = t.end.mjd2000 - \ (t.end .mjd2000 - t.start.mjd2000) / 2. t_grid[-2 * i - 1] = t.end.mjd2000 dt = (t.end.mjd - t.start.mjd) * DAY2SEC alpha = min(norm(t.value), 1.0) if self.high_fidelity is False: dV = [max_thrust / m * dt * dumb for dumb in t.value] r, v = propagate_lagrangian(r, v, -dt / 2, mu) x_back[-2 * i - 2], y_back[-2 * i - 2], z_back[-2 * i - 2] = r vx_back[-2 * i - 2], vy_back[-2 * i - 2], vz_back[-2 * i - 2] = v mass_back[-2 * i - 2] = m # v= v+dV v = [a - b for a, b in zip(v, dV)] r, v = propagate_lagrangian(r, v, -dt / 2, mu) m *= exp(norm(dV) / isp / G0) x_back[-2 * i - 3], y_back[-2 * i - 3], z_back[-2 * i - 3] = r vx_back[-2 * i - 3], vy_back[-2 * i - 3], vz_back[-2 * i - 3] = v mass_back[-2 * i - 3] = m else: u = [max_thrust * dumb for dumb in t.value] r, v, m = propagate_taylor(r, v, m, u, -dt / 2, mu, isp * G0, -12, -12) x_back[-2 * i - 2], y_back[-2 * i - 2], z_back[-2 * i - 2] = r vx_back[-2 * i - 2], vy_back[-2 * i - 2], vz_back[-2 * i - 2] = v mass_back[-2 * i - 2] = m r, v, m = propagate_taylor(r, v, m, u, -dt / 2, mu, isp * G0, -12, -12) x_back[-2 * i - 3], y_back[-2 * i - 3], z_back[-2 * i - 3] = r vx_back[-2 * i - 3], vy_back[-2 * i - 3], vz_back[-2 * i - 3] = v mass_back[-2 * i - 3] = m t_grid[-2 * i - 3] = t.start.mjd2000 x = x + x_back y = y + y_back z = z + z_back vx = vx + vx_back vy = vy + vy_back vz = vz + vz_back mass = mass + mass_back return t_grid, list(zip(x, y, z)), list(zip(vx, vy, vz)), mass
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 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 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