def point_taylor(r, v, m, u, t, mu, veff, N=60, units=1): from PyKEP import propagate_taylor # We define the integration time ... dt = t / (N - 1) mm = [] # ... 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 mm = mm + [m] r, v, m = propagate_taylor(r, v, m, u, dt, mu, veff, -10, -10) tt = range(N) tt = [e*dt/(60*60*24) for e in tt] return x,y,z,tt,mm
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
def plot_taylor(ax,r,v,m,u,t,mu, veff, N=60, units = 1, color = 'b', legend = False): """ Plots the result of a taylor propagation of constant thrust USAGE: plot_taylor(ax,r,v,m,u,t,mu, veff, N=60, units = 1, color = 'b', legend = False): * 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 """ from PyKEP import propagate_taylor #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 ax.plot(x, y, z, c=color, label=label) if legend: ax.legend()
def plot_sf_leg(leg, N=5, units=1, color='b', legend=False, plot_line=True, ax=None): """ ax = plot_sf_leg(leg, N=5, units=1, color='b', legend=False, no_trajectory=False, ax=None): - ax: 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, ax=ax) t2 = epoch(440) pl = planet_ss('mars') rM, vM = pl.eph(t2) plot_planet(pl,t0=t2, units=AU, ax=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, ax=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 ax is None: fig = plt.figure() axis = fig.gca(projection='3d') else: axis = ax # 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+midpints) 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), ax=axis) 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), ax=axis) 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), ax=axis) r, v, m = propagate_taylor(r, v, m, u, dt / 2, mu, isp * G0, -10, -10) 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), ax=axis) r, v, m = propagate_taylor(r, v, m, u, dt / 2, mu, isp * G0, -10, -10) 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] axis.scatter(x_grid[:-1], y_grid[:-1], z_grid[:-1], label='nodes', marker='o') axis.scatter(x_midpoint, y_midpoint, z_midpoint, label='mid-points', marker='x') axis.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), ax=axis) 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), ax=axis) 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), ax=axis) r, v, m = propagate_taylor(r, v, m, u, -dt / 2, mu, isp * G0, -10, -10) 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), ax=axis) r, v, m = propagate_taylor(r, v, m, u, -dt / 2, mu, isp * G0, -10, -10) 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] axis.scatter(x_grid[1:], y_grid[1:], z_grid[1:], marker='o') axis.scatter(x_midpoint, y_midpoint, z_midpoint, marker='x') axis.scatter(x_grid[0], y_grid[0], z_grid[0], marker='^', c='y') if legend: axis.legend() if ax is None: # show only if axis is not set plt.show() return axis
def plot_sf_leg(leg, N=5, units=1, color='b', legend=False, plot_line=True, plot_segments=True, ax=None): """ ax = plot_sf_leg(leg, N=5, units=1, color='b', legend=False, no_trajectory=False, ax=None): - ax: 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, ax=ax) t2 = epoch(440) pl = planet_ss('mars') rM, vM = pl.eph(t2) plot_planet(pl,t0=t2, units=AU, ax=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, ax=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 ax is None: fig = plt.figure() axis = fig.gca(projection='3d') else: axis = ax # 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+midpints) 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), ax=axis) 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), ax=axis) 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), ax=axis) 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), ax=axis) 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: axis.scatter(x_grid[:-1], y_grid[:-1], z_grid[:-1], label='nodes', marker='o') axis.scatter(x_midpoint, y_midpoint, z_midpoint, label='mid-points', marker='x') axis.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), ax=axis) 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), ax=axis) 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), ax=axis) 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), ax=axis) 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: axis.scatter(x_grid[1:], y_grid[1:], z_grid[1:], marker='o') axis.scatter(x_midpoint, y_midpoint, z_midpoint, marker='x') axis.scatter(x_grid[0], y_grid[0], z_grid[0], marker='^', c='y') if legend: axis.legend() if ax is None: # show only if axis is not set plt.show() return axis
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 _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 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 _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 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, -10, -10) 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, -10, -10) 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, -10, -10) 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, -10, -10) 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 plot_leg(ax, leg, N=5, units=1, color='b', legend=False, plot_line = True): """ Plots a trajectory leg USAGE: plot_leg(ax, leg, N=5, units=1, color='b', legend=False, no_trajectory = False): * ax: 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) 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(ax, pl,t0=t1, units=AU) t2 = epoch(440) pl = planet_ss('mars') rM, vM = pl.eph(t2) plot_planet(ax, pl,t0=t2, units=AU) 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(ax,l,units=AU) """ 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(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 containd in states x = [0.0]*(fwd_seg+1) y = [0.0]*(fwd_seg+1) z = [0.0]*(fwd_seg+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) #Taylor propagation of constant thrust u u = [max_thrust * dumb for dumb in t.value] if plot_line: plot_taylor(ax,r,v,m,u,dt,mu,isp*G0,N=N,units=units,color=(alpha,0,1-alpha)) r,v,m = propagate_taylor(r,v,m,u,dt,mu,isp*G0,-10,-10) x[i+1] = r[0]/units y[i+1] = r[1]/units z[i+1] = r[2]/units ax.scatter(x[:-1], y[:-1], z[:-1], label='nodes',marker='o') ax.scatter(x[-1],y[-1],z[-1], marker='^', c='y', label='mismatch point') #Backward propagation #x,y,z will contain the cartesian components of x = [0.0]*(back_seg+1) y = [0.0]*(back_seg+1) z = [0.0]*(back_seg+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) u = [max_thrust * dumb for dumb in t.value] if plot_line: plot_taylor(ax,r,v,m,u,-dt,mu,isp*G0,N=N,units=units,color=(alpha,0,1-alpha)) r,v,m = propagate_taylor(r,v,m,u,-dt,mu,isp*G0,-10,-10) x[-i-2] = r[0]/units y[-i-2] = r[1]/units z[-i-2] = r[2]/units ax.scatter(x[1:], y[1:], z[1:], marker = 'o') ax.scatter(x[0], y[0], z[0], marker='^', c='y') if legend: ax.legend()
def point_sf_leg(leg, N=5, units=1, color='b'): from PyKEP import propagate_lagrangian, AU, DAY2SEC, G0, propagate_taylor, SEC2DAY import numpy as np from scipy.linalg import norm from math import exp, sqrt # 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 see if the propulsion is nuclear or solar powered sp = leg.solar_powered; # 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+midpints) x_bounds = [] y_bounds = [] z_bounds = [] x = [] y = [] z = [] Tx = [] Ty = [] Tz = [] Tmax = [] mm = [] tt = [] state = leg.get_xi() # Initial conditions r = state.r v = state.v m = state.m x_bounds = x_bounds + [r[0] / units] y_bounds = y_bounds + [r[1] / units] z_bounds = z_bounds + [r[2] / units] segmentID = 0 temptime = 0 # 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: if(sp): dSun = sqrt(r[0]*r[0]+r[1]*r[1]+r[2]*r[2]) max_thrust = sc.get_thrust_electricSolar(dSun) isp = isp; dV = [max_thrust / m * dt * dumb for dumb in t.value] xi,yi,zi,ti = point_kepler(r, v, dt / 2, mu, N=N, units=units) 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 x = x + xi y = y + yi z = z + zi tt = tt + [e + temptime for e in ti] temptime = tt[-1] mm = mm + [m]*len(ti) x_bounds = x_bounds + [r[0] / units] y_bounds = y_bounds + [r[1] / units] z_bounds = z_bounds + [r[2] / units] # the thrust is constant on the segment (1st half-segment) Tx = Tx + [t.value[0]]*len(ti) Ty = Ty + [t.value[1]]*len(ti) Tz = Tz + [t.value[2]]*len(ti) Tmax = Tmax + [max_thrust]*len(ti) # v= v+dV v = [a + b for a, b in zip(v, dV)] xi,yi,zi,ti = point_kepler(r, v, dt / 2, mu, N=N, units=units) 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) x = x + xi y = y + yi z = z + zi tt = tt + [e + temptime for e in ti] temptime = tt[-1] mm = mm+ [m]*len(ti) x_bounds = x_bounds + [r[0] / units] y_bounds = y_bounds + [r[1] / units] z_bounds = z_bounds + [r[2] / units] # the thrust is constant on the segment (2nd half-segment) Tx = Tx + [t.value[0]]*len(ti) Ty = Ty + [t.value[1]]*len(ti) Tz = Tz + [t.value[2]]*len(ti) Tmax = Tmax + [max_thrust]*len(ti) else: if(sp): dSun = sqrt(r[0]*r[0]+r[1]*r[1]+r[2]*r[2]) max_thrust = sc.get_thrust_electricSolar(dSun) isp = isp; u = [max_thrust * dumb for dumb in t.value] xi,yi,zi,ti,mi = point_taylor(r, v, m, u, dt , mu, isp * G0, N=N, units=units) x = x + xi y = y + yi z = z + zi tt = tt + [e + temptime for e in ti] temptime = tt[-1] mm = mm + mi r, v, m = propagate_taylor(r, v, m, u, dt , mu, isp * G0, -12, -12) x_bounds = x_bounds + [r[0] / units] y_bounds = y_bounds + [r[1] / units] z_bounds = z_bounds + [r[2] / units] # the thrust is constant of the whole segment Tx = Tx + [t.value[0]]*len(ti) Ty = Ty + [t.value[1]]*len(ti) Tz = Tz + [t.value[2]]*len(ti) Tmax = Tmax + [max_thrust]*len(ti) state = leg.get_xf() # Final conditions r = state.r v = state.v m = state.m # used to reverse the order caused by the back-propagation xt = [] yt = [] zt = [] mmt = [] ttt = [] Txt = [] Tyt = [] Tzt = [] Tmaxt = [] x_bounds = x_bounds + [r[0] / units] #gonna be the wrong side over... y_bounds = y_bounds + [r[1] / units] z_bounds = z_bounds + [r[2] / units] temptime = 0 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: if(sp): dSun = sqrt(r[0]*r[0]+r[1]*r[1]+r[2]*r[2]) max_thrust = sc.get_thrust_electricSolar(dSun) isp = isp; dV = [max_thrust / m * dt * dumb for dumb in t.value] xi,yi,zi,ti = point_kepler(r, v, -dt / 2, mu, N=N, units=units) 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 xt = xt + xi yt = yt + yi zt = zt + zi ttt = ttt + [e + temptime for e in ti] temptime = ttt[-1] mmt = mmt + [m]*len(ti) x_bounds = x_bounds + [r[0] / units] y_bounds = y_bounds + [r[1] / units] z_bounds = z_bounds + [r[2] / units] # the thrust is constant on the segment (1st half-segment) Txt = Txt + [t.value[0]]*len(ti) Tyt = Tyt + [t.value[1]]*len(ti) Tzt = Tzt + [t.value[2]]*len(ti) Tmaxt = Tmaxt + [max_thrust]*len(ti) # v= v+dV v = [a - b for a, b in zip(v, dV)] xi,yi,zi,ti = point_kepler(r, v, -dt / 2, mu, N=N, units=units) 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) xt = xt + xi yt = yt + yi zt = zt + zi ttt = ttt + [e + temptime for e in ti] temptime = ttt[-1] mmt = mmt + [m]*len(ti) x_bounds = x_bounds + [r[0] / units] y_bounds = y_bounds + [r[1] / units] z_bounds = z_bounds + [r[2] / units] # the thrust is constant on the segment (2nd half-segment) Txt = Txt + [t.value[0]]*len(ti) Tyt = Tyt + [t.value[1]]*len(ti) Tzt = Tzt + [t.value[2]]*len(ti) Tmaxt = Tmaxt + [max_thrust]*len(ti) else: if(sp): dSun = sqrt(r[0]*r[0]+r[1]*r[1]+r[2]*r[2]) max_thrust = sc.get_thrust_electricSolar(dSun) isp = isp; u = [max_thrust * dumb for dumb in t.value] xi,yi,zi,ti,mi = point_taylor(r, v, m, u, -dt , mu, isp * G0, N=N, units=units) xt = xt + xi yt = yt + yi zt = zt + zi ttt = ttt + [e + temptime for e in ti] temptime = ttt[-1] mmt = mmt + mi r, v, m = propagate_taylor(r, v, m, u, -dt , mu, isp * G0, -12, -12) x_bounds = x_bounds + [r[0] / units] y_bounds = y_bounds + [r[1] / units] z_bounds = z_bounds + [r[2] / units] # the thrust is constant on the whole segment Txt = Txt + [t.value[0]]*len(ti) Tyt = Tyt + [t.value[1]]*len(ti) Tzt = Tzt + [t.value[2]]*len(ti) Tmaxt = Tmaxt + [max_thrust]*len(ti) Tpx = Tx Tpy = Ty Tpz = Tz x = x + xt[::-1] y = y + yt[::-1] z = z + zt[::-1] Tx = Tx + Txt[::-1] Ty = Ty + Tyt[::-1] Tz = Tz + Tzt[::-1] Tmax = Tmax + Tmaxt[::-1] mm = mm + mmt[::-1] temptime = tt[-1] - ttt[-1] tt = tt + [e + temptime for e in ttt[::-1]] return x,y,z,mm,tt,Tx,Ty,Tz,Tmax,x_bounds,y_bounds,z_bounds