def plot_taylor(r0, v0, m0, thrust, tof, mu, veff, N=60, units=1, color='b', legend=False, axes=None): """ ax = plot_taylor(r0, v0, m0, thrust, tof, mu, veff, N=60, units=1, color='b', legend=False, axes=None): - axes: 3D axis object created using fig.gca(projection='3d') - r0: initial position (cartesian coordinates) - v0: initial velocity (cartesian coordinates) - m0: initial mass - u: cartesian components for the constant thrust - tof: propagation time - mu: gravitational parameter - veff: the product Isp * g0 - 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 taylor propagation of constant thrust Example:: import pykep as pk import matplotlib.pyplot as plt pi = 3.14 fig = plt.figure() ax = fig.gca(projection = '3d') pk.orbit_plots.plot_taylor([1,0,0],[0,1,0],100,[1,1,0],40, 1, 1, N = 1000, axes = ax) plt.show() """ from pykep import propagate_taylor import matplotlib.pyplot as plt 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 calcuate the cartesian components for r x = [0.0] * N y = [0.0] * N z = [0.0] * N # Replace r0, v0, m0 for r, v, m r = r0 v = v0 m = m0 # 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, m = propagate_taylor(r, v, m, thrust, dt, mu, veff, -10, -10) # And we plot if legend: label = 'constant thrust arc' else: label = None ax.plot(x, y, z, c=color, label=label) if legend: ax.legend() if axes is None: # show only if axis is not set plt.show() return ax
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 _leg_eph(self, t, debug=False): """ Computes the ephemerides (r, v) along the leg. Should only be called on high_fidelity legs having no state mismatch. Otherwise the values returned will not correspond to physical quantities. - t: epoch (either a pykep epoch, or assumes mjd2000). This value must be between self.get_ti() and self.get_tf() """ from pykep import epoch, propagate_taylor, G0, DAY2SEC from bisect import bisect if isinstance(t, epoch): t0 = t.mjd2000 else: t0 = t # We extract the leg states t_grid, r, v, m = self.get_states() # We check that requested epoch is valid if (t0 < t_grid[0]) or (t0 > t_grid[-1]): raise ValueError("The requested epoch is out of bounds") # We check that the leg is high fidelity, otherwise this makes little sense if not self.high_fidelity: raise ValueError( "The eph method works only for high fidelity legs at the moment") # Extract some information from the leg mu = self.get_mu() sc = self.get_spacecraft() isp = sc.isp max_thrust = sc.thrust t_grid, r, v, m = self.get_states() # If by chance its in the grid node, we are done if t0 in t_grid: idx = t_grid.index(t0) if debug: raise ValueError("DEBUG!!!!") return r[idx], v[idx], m[idx] # Find the index to start from (need to account for the midpoint # repetition) idx = bisect(t_grid, t0) - 1 # We compute the number of segments of forward propagation n_seg = len(self.get_throttles()) fwd_seg = (n_seg + 1) // 2 # We start with the backward propagation cases if idx > 2 * fwd_seg: r0 = r[idx + 1] v0 = v[idx + 1] m0 = m[idx + 1] idx_thrust = (idx - 1) / 2 dt_int = (t_grid[idx + 1] - t0) * DAY2SEC th = self.get_throttles()[idx_thrust].value if debug: raise ValueError("DEBUG!!!!") return propagate_taylor(r0, v0, m0, [d * max_thrust for d in th], -dt_int, mu, isp * G0, -12, -12) # Find the index to start from idx = bisect(t_grid, t0) - 1 r0 = r[idx] v0 = v[idx] m0 = m[idx] idx_thrust = idx / 2 dt_int = (t0 - t_grid[idx]) * DAY2SEC th = self.get_throttles()[idx_thrust].value if debug: raise ValueError("DEBUG!!!!") return propagate_taylor(r0, v0, m0, [d * max_thrust for d in th], dt_int, mu, isp * G0, -12, -12)
def _propagate(self, x): # 1 - We decode the chromosome t0 = x[0] T = x[1] m_f = x[2] # We extract the number of segments for forward and backward # propagation n_seg = self.__n_seg fwd_seg = self.__fwd_seg bwd_seg = self.__bwd_seg # We extract information on the spacecraft m_i = self.__sc.mass max_thrust = self.__sc.thrust isp = self.__sc.isp veff = isp * pk.G0 # And on the leg throttles = [x[3 + 3 * i: 6 + 3 * i] for i in range(n_seg)] # Return lists n_points_fwd = fwd_seg + 1 n_points_bwd = bwd_seg + 1 rfwd = [[0.0] * 3] * (n_points_fwd) vfwd = [[0.0] * 3] * (n_points_fwd) mfwd = [0.0] * (n_points_fwd) ufwd = [[0.0] * 3] * (fwd_seg) dfwd = [[0.0] * 3] * (fwd_seg) # distances E/S rbwd = [[0.0] * 3] * (n_points_bwd) vbwd = [[0.0] * 3] * (n_points_bwd) mbwd = [0.0] * (n_points_bwd) ubwd = [[0.0] * 3] * (bwd_seg) dbwd = [[0.0] * 3] * (bwd_seg) # 2 - We compute the initial and final epochs and ephemerides t_i = pk.epoch(t0) r_i, v_i = self.__earth.eph(t_i) if self.__start == 'l1': r_i = [r * 0.99 for r in r_i] v_i = [v * 0.99 for v in v_i] elif self.__start == 'l2': r_i = [r * 1.01 for r in r_i] v_i = [v * 1.01 for v in v_i] t_f = pk.epoch(t0 + T) r_f, v_f = self.target.eph(t_f) # 3 - Forward propagation fwd_grid = t0 + T * self.__fwd_grid # days fwd_dt = T * self.__fwd_dt # seconds # Initial conditions rfwd[0] = r_i vfwd[0] = v_i mfwd[0] = m_i # Propagate for i, t in enumerate(throttles[:fwd_seg]): if self.__sep: r = math.sqrt(rfwd[i][0]**2 + rfwd[i][1] ** 2 + rfwd[i][2]**2) / pk.AU max_thrust, isp = self._sep_model(r) veff = isp * pk.G0 ufwd[i] = [max_thrust * thr for thr in t] if self.__earth_gravity: r_E, v_E = self.__earth.eph(pk.epoch(fwd_grid[i])) dfwd[i] = [a - b for a, b in zip(r_E, rfwd[i])] r3 = sum([r**2 for r in dfwd[i]])**(3 / 2) disturbance = [mfwd[i] * pk.MU_EARTH / r3 * ri for ri in dfwd[i]] rfwd[i + 1], vfwd[i + 1], mfwd[i + 1] = pk.propagate_taylor_disturbance( rfwd[i], vfwd[i], mfwd[i], ufwd[i], disturbance, fwd_dt[i], pk.MU_SUN, veff, -10, -10) else: rfwd[i + 1], vfwd[i + 1], mfwd[i + 1] = pk.propagate_taylor( rfwd[i], vfwd[i], mfwd[i], ufwd[i], fwd_dt[i], pk.MU_SUN, veff, -10, -10) # 4 - Backward propagation bwd_grid = t0 + T * self.__bwd_grid # days bwd_dt = T * self.__bwd_dt # seconds # Final conditions rbwd[-1] = r_f vbwd[-1] = v_f mbwd[-1] = m_f # Propagate for i, t in enumerate(throttles[-1:-bwd_seg - 1:-1]): if self.__sep: r = math.sqrt(rbwd[-i - 1][0]**2 + rbwd[-i - 1] [1]**2 + rbwd[-i - 1][2]**2) / pk.AU max_thrust, isp = self._sep_model(r) veff = isp * pk.G0 ubwd[-i - 1] = [max_thrust * thr for thr in t] if self.__earth_gravity: r_E, v_E = self.__earth.eph(pk.epoch(bwd_grid[-i - 1])) dbwd[-i - 1] = [a - b for a, b in zip(r_E, rbwd[-i - 1])] r3 = sum([r**2 for r in dbwd[-i - 1]])**(3 / 2) disturbance = [mfwd[i] * pk.MU_EARTH / r3 * ri for ri in dbwd[-i - 1]] rbwd[-i - 2], vbwd[-i - 2], mbwd[-i - 2] = pk.propagate_taylor_disturbance( rbwd[-i - 1], vbwd[-i - 1], mbwd[-i - 1], ubwd[-i - 1], disturbance, -bwd_dt[-i - 1], pk.MU_SUN, veff, -10, -10) else: rbwd[-i - 2], vbwd[-i - 2], mbwd[-i - 2] = pk.propagate_taylor( rbwd[-i - 1], vbwd[-i - 1], mbwd[-i - 1], ubwd[-i - 1], -bwd_dt[-i - 1], pk.MU_SUN, veff, -10, -10) return rfwd, rbwd, vfwd, vbwd, mfwd, mbwd, ufwd, ubwd, fwd_dt, bwd_dt, dfwd, dbwd
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 _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 _propagate(self, x): # 1 - We decode the chromosome t0 = x[0] T = x[1] m_f = x[2] # We extract the number of segments for forward and backward # propagation n_seg = self.__n_seg fwd_seg = self.__fwd_seg bwd_seg = self.__bwd_seg # We extract information on the spacecraft m_i = self.__sc.mass max_thrust = self.__sc.thrust isp = self.__sc.isp veff = isp * pk.G0 # And on the leg throttles = [x[3 + 3 * i:6 + 3 * i] for i in range(n_seg)] # Return lists n_points_fwd = fwd_seg + 1 n_points_bwd = bwd_seg + 1 rfwd = [[0.0] * 3] * (n_points_fwd) vfwd = [[0.0] * 3] * (n_points_fwd) mfwd = [0.0] * (n_points_fwd) ufwd = [[0.0] * 3] * (fwd_seg) dfwd = [[0.0] * 3] * (fwd_seg) # distances E/S rbwd = [[0.0] * 3] * (n_points_bwd) vbwd = [[0.0] * 3] * (n_points_bwd) mbwd = [0.0] * (n_points_bwd) ubwd = [[0.0] * 3] * (bwd_seg) dbwd = [[0.0] * 3] * (bwd_seg) # 2 - We compute the initial and final epochs and ephemerides t_i = pk.epoch(t0) r_i, v_i = self.__earth.eph(t_i) if self.__start == 'l1': r_i = [r * 0.99 for r in r_i] v_i = [v * 0.99 for v in v_i] elif self.__start == 'l2': r_i = [r * 1.01 for r in r_i] v_i = [v * 1.01 for v in v_i] t_f = pk.epoch(t0 + T) r_f, v_f = self.target.eph(t_f) # 3 - Forward propagation fwd_grid = t0 + T * self.__fwd_grid # days fwd_dt = T * self.__fwd_dt # seconds # Initial conditions rfwd[0] = r_i vfwd[0] = v_i mfwd[0] = m_i # Propagate for i, t in enumerate(throttles[:fwd_seg]): if self.__sep: r = math.sqrt(rfwd[i][0]**2 + rfwd[i][1]**2 + rfwd[i][2]**2) / pk.AU max_thrust, isp = self._sep_model(r) veff = isp * pk.G0 ufwd[i] = [max_thrust * thr for thr in t] if self.__earth_gravity: r_E, v_E = self.__earth.eph(pk.epoch(fwd_grid[i])) dfwd[i] = [a - b for a, b in zip(r_E, rfwd[i])] r3 = sum([r**2 for r in dfwd[i]])**(3 / 2) disturbance = [ mfwd[i] * pk.MU_EARTH / r3 * ri for ri in dfwd[i] ] rfwd[i + 1], vfwd[i + 1], mfwd[i + 1] = pk.propagate_taylor_disturbance( rfwd[i], vfwd[i], mfwd[i], ufwd[i], disturbance, fwd_dt[i], pk.MU_SUN, veff, -10, -10) else: rfwd[i + 1], vfwd[i + 1], mfwd[i + 1] = pk.propagate_taylor( rfwd[i], vfwd[i], mfwd[i], ufwd[i], fwd_dt[i], pk.MU_SUN, veff, -10, -10) # 4 - Backward propagation bwd_grid = t0 + T * self.__bwd_grid # days bwd_dt = T * self.__bwd_dt # seconds # Final conditions rbwd[-1] = r_f vbwd[-1] = v_f mbwd[-1] = m_f # Propagate for i, t in enumerate(throttles[-1:-bwd_seg - 1:-1]): if self.__sep: r = math.sqrt(rbwd[-i - 1][0]**2 + rbwd[-i - 1][1]**2 + rbwd[-i - 1][2]**2) / pk.AU max_thrust, isp = self._sep_model(r) veff = isp * pk.G0 ubwd[-i - 1] = [max_thrust * thr for thr in t] if self.__earth_gravity: r_E, v_E = self.__earth.eph(pk.epoch(bwd_grid[-i - 1])) dbwd[-i - 1] = [a - b for a, b in zip(r_E, rbwd[-i - 1])] r3 = sum([r**2 for r in dbwd[-i - 1]])**(3 / 2) disturbance = [ mfwd[i] * pk.MU_EARTH / r3 * ri for ri in dbwd[-i - 1] ] rbwd[-i - 2], vbwd[-i - 2], mbwd[-i - 2] = pk.propagate_taylor_disturbance( rbwd[-i - 1], vbwd[-i - 1], mbwd[-i - 1], ubwd[-i - 1], disturbance, -bwd_dt[-i - 1], pk.MU_SUN, veff, -10, -10) else: rbwd[-i - 2], vbwd[-i - 2], mbwd[-i - 2] = pk.propagate_taylor( rbwd[-i - 1], vbwd[-i - 1], mbwd[-i - 1], ubwd[-i - 1], -bwd_dt[-i - 1], pk.MU_SUN, veff, -10, -10) return rfwd, rbwd, vfwd, vbwd, mfwd, mbwd, ufwd, ubwd, fwd_dt, bwd_dt, dfwd, dbwd
def plot_taylor(r, v, m, u, t, mu, veff, N=60, units=1, color='b', legend=False, ax=None): """ ax = plot_taylor(r, v, m, u, t, mu, veff, 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) - m: initial mass - u: cartesian components for the constant thrust - t: propagation time - mu: gravitational parameter - veff: the product Isp * g0 - 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 taylor propagation of constant thrust """ from pykep import propagate_taylor import matplotlib.pyplot as plt 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 calcuate 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, m = propagate_taylor(r, v, m, u, dt, mu, veff, -10, -10) # And we plot if legend: label = 'constant thrust 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