plt.style.use('dark_background') # AWP library import numerical_tools as nt import orbit_calculations as oc import plotting_tools as pt if __name__ == '__main__': state0 = [7500.0, 0, 0, 0, 9.0, 0] tspan = 5 * 24 * 3600.0 ets, states = nt.propagate_ode(oc.two_body_ode, state0, tspan, 30.0) pt.plot_orbits([states[:, :3]], { 'colors': ['m'], 'traj_lws': 2, 'show': True }) n_states = 1350 tas = np.zeros(n_states) for n in range(n_states): tas[n] = oc.state2coes(states[n])[3] plt.figure(figsize=(14, 8)) plt.plot(ets[:n_states] / 3600.0, tas, 'm', linewidth=3) plt.grid(linestyle='dotted') plt.yticks(range(0, 390, 30), fontsize=15) plt.xticks(fontsize=15) plt.ylim([0, 360]) plt.xlabel('Time (hours)', fontsize=15)
] colors = ['m', 'c', 'm', 'c', 'b', 'C3', 'C1'] # ensure all states are heliocentric rs0 = sc0.states[:, :3] + states_earth[:sc0.step] rs1 = sc1.states[:, :3] c0 = sc0.step + sc1.step c1 = c0 + sc2.step rs2 = sc2.states[:, :3] + states_jupiter[c0:c1] rs3 = sc3.states[:, :3] pt.plot_orbits( [rs0, rs1, rs2, rs3, states_earth, states_jupiter, states_saturn], { 'labels': labels, 'colors': colors, 'axes_mag': 1.0, 'traj_lws': 2, 'azimuth': -90, 'elevation': 94, 'show': True }) ''' The following part of this script was used to create the GIF showed in this video. At this time I'm not ready to show the OrbitalAnimator class since I am going to implement class inheritance to organize all the animator classes together, but I kept this part in here in case anyone is curious ''' if False: from sys import path path.append('/home/alfonso/AWP/python_tools') from OrbitalAnimator import animate_orbits, DummySC
def plot_3d(self, args={'show': True}): pt.plot_orbits([self.states[:, :3]], args)
import ode_tools as ot import plotting_tools as pt import planetary_data as pd if __name__ == '__main__': r0 = pd.earth['radius'] + 1000.0 v0_circ = (pd.earth['mu'] / r0)**0.5 state0_sc0 = [r0, 0, 0, 0, v0_circ, 0.0] state0_sc1 = [r0, 0, 0, 2.0, 9.0, 0.0] state0_sc2 = [r0, 0, 0, 1.0, 0.0, 8.0] state0_sc3 = [r0, 0, 0, 1.0, 6.0, 6.0] states0 = [state0_sc0, state0_sc1, state0_sc2, state0_sc3] rs = [] sc_config = {'tspan': '1'} for state0 in states0: sc_config['orbit_state'] = state0 rs.append(SC(sc_config).states[:, :3]) pt.plot_orbits( rs, { 'labels': range(4), 'colors': ['C3', 'm', 'c', 'lime'], 'traj_lws': 2, 'azimuth': -32, 'elevation': 70, 'show': True })
[ periapsis, 1.0, 0, 0, 0, -10.0, 0, pd.earth[ 'mu' ] ], 0 ) state_hyperbolic = spice.conics( [ periapsis, 2.5, 0, 0, 0, -10.0, 0, pd.earth[ 'mu' ] ], 0 ) sc_circular = SC( { 'coes': coes_circular, 'tspan': '1' } ) sc_elliptical = SC( { 'coes': coes_elliptical, 'tspan': '2' } ) sc_parabolic = SC( { 'orbit_state': state_parabolic, 'tspan': 70000.0 } ) sc_hyperbolic = SC( { 'orbit_state': state_hyperbolic, 'tspan': 30000.0 } ) rs = [ sc_circular.states [ :, :3 ], sc_elliptical.states[ :, :3 ], sc_parabolic.states[ :, :3 ], sc_hyperbolic.states[ :, :3 ] ] labels = [ 'Circular $(ecc=0.0)$', 'Elliptical $(ecc=0.7)$', 'Parabolic $(ecc=1.0)$', 'Hyperbolic $(ecc=3.0)$' ] sc_elliptical.plot_states( { 'time_unit': 'hours', 'show' : True } ) pt.plot_orbits( rs, { 'labels' : labels, 'colors' : [ 'r', 'g', 'b', 'm' ], 'azimuth' : -90.0, 'elevation' : 90.0, 'axes_custom': 36000.0, 'hide_axes' : True, 'traj_lws' : 2.5, 'show' : True } )
dt = 10.0 coes_list.append([11000.0, 0.3, 30, 0, 180, 30]) coes_list.append([11000.0, 0.3, 30, 0, 0, 30]) for coes in coes_list: state0 = oc.coes2state(coes) ets, states = nt.propagate_ode(oc.two_body_ode, state0, tspan, dt) states_list.append(states) ets += spice.str2et('2021-12-26') pt.plot_orbits( states_list, { 'labels': ['180', '0'], 'colors': ['lime', 'r'], 'traj_lws': 2, 'show': True }) latlons = [] for states in states_list: latlons.append( nt.cart2lat(states[:3000, :3], 'J2000', 'IAU_EARTH', ets)) pt.plot_groundtracks(latlons, { 'labels': ['180', '0'], 'colors': ['lime', 'r'], 'show': True }) '''
dt = 10.0 coes_list.append([8000.0, 0.2, 88, 0, 0, 0]) coes_list.append([8000.0, 0.2, 88, 0, 0, 30]) for coes in coes_list: state0 = oc.coes2state(coes) ets, states = nt.propagate_ode(oc.two_body_ode, state0, tspan, dt) states_list.append(states) ets += spice.str2et('2021-12-26') pt.plot_orbits( states_list, { 'labels': ['0', '45', '75', '100'], 'colors': ['crimson', 'lime', 'c', 'm'], 'traj_lws': 2, 'show': True }) latlons = [] for states in states_list: latlons.append( nt.cart2lat(states[:1000, :3], 'J2000', 'IAU_EARTH', ets)) pt.plot_groundtracks( latlons, { 'labels': ['0', '45', '75', '100'], 'colors': ['crimson', 'lime', 'c', 'm'], 'show': True })
states_gps = np.zeros( ( steps, 6 ) ) states_iss = np.zeros( ( steps, 6 ) ) states_geo = np.zeros( ( steps, 6 ) ) states_molniya = np.zeros( ( steps, 6 ) ) states_gps [ 0 ] = state0_gps states_iss [ 0 ] = state0_iss states_geo [ 0 ] = state0_geo states_molniya[ 0 ] = state0_molniya for step in range( steps - 1 ): states_gps[ step + 1 ] = ot.rk4_step( oc.two_body_ode, ets[ step ], states_gps[ step ], dt ) states_iss[ step + 1 ] = ot.rk4_step( oc.two_body_ode, ets[ step ], states_iss[ step ], dt ) states_geo[ step + 1 ] = ot.rk4_step( oc.two_body_ode, ets[ step ], states_geo[ step ], dt ) states_molniya[ step + 1 ] = ot.rk4_step( oc.two_body_ode, ets[ step ], states_molniya[ step ], dt ) pt.plot_orbits( [ states_gps, states_iss, states_geo, states_molniya ], { 'labels' : [ 'GPS', 'ISS', 'Geostationary', 'Molniya' ], 'colors' : [ 'crimson', 'm', 'lime', 'b' ], 'traj_lws': 2, 'show' : True } )
vdelta = v_depart - v_arrive v0 = {'r': v_arrive, 'label': r'$\vec{v}_{arrive}$', 'color': 'm'} v1 = {'r': v_depart, 'label': r'$\vec{v}_{depart}$', 'color': 'm'} v2 = {'r': v_jup0, 'label': r'$\vec{v}_{Jupiter}$', 'color': 'C3'} v3 = {'r': vinf0, 'label': r'$\vec{v}_{incoming}$', 'color': 'm'} v4 = {'r': vinf1, 'label': r'$\vec{v}_{outgoing}$', 'color': 'm'} v5 = {'r': vdelta, 'label': r'$\vec{\Delta v}$', 'color': 'lime'} pt.plot_orbits( [], { 'vector_texts': True, 'vector_text_scale': 1, 'cb_radius': 0.4, 'dist_unit': r'$\dfrac{km}{s}$', 'axes_custom': 25.0, 'azimuth': -49, 'elevation': 90, 'hide_axes': True, 'show': True }, vectors=[v0, v1, v2, v5]) pt.plot_orbits( [], { 'vector_texts': True, 'vector_text_scale': 1, 'cb_radius': 0.1, 'dist_unit': r'$\dfrac{km}{s}$', 'axes_custom': 15.0, 'azimuth': -44,
def test_Spacecraft_enter_SOI_voyager2_jupiter(plot=False): spice.furnsh(sd.leapseconds_kernel) spice.furnsh(sd.de432) frame = 'ECLIPJ2000' # beginning of coverage for Voyager 2 SPK kernel et0 = spice.str2et('1977 AUG 20 15:32:32.182') ''' Voyager 2 initial state w.r.t Earth at et0 ''' state0 = [ 7.44304239e+03, -5.12480267e+02, 2.37748995e+03, # km 5.99287925e+00, 1.19056063e+01, 5.17252832e+00 ] # km / s ''' Propagate Voyager 2 trajectory until it exits Earth's sphere of influence, where maximum altitude stop condition will be triggered ''' stop_conditions = {'max_alt': pd.earth['SOI'] - pd.earth['radius']} sc0 = SC({ 'orbit_state': state0, 'et0': et0, 'frame': frame, 'tspan': 100000, 'stop_conditions': stop_conditions }) assert sc0.cb == pd.earth assert sc0.ode_sol.success assert sc0.ode_sol.message == 'A termination event occurred.' assert sc0.ode_sol.status == 1 ''' Calculate spacecraft state w.r.t solar system barycenter at ephemeris time when spacecraft left Earth SOI ''' state_earth = spice.spkgeo(399, sc0.ets[-1], frame, 0)[0] state1 = sc0.states[-1, :6] + state_earth ''' Now model the spacecraft as a heliocentric elliptical orbit and propagate until enter Jupiter SOI ''' sc1 = SC({ 'orbit_state': state1, 'et0': sc0.ets[-1], 'frame': frame, 'tspan': 5 * 365 * 24 * 3600.0, 'dt': 30000, 'stop_conditions': { 'enter_SOI': pd.jupiter }, 'cb': pd.sun }) assert sc1.cb == pd.sun assert sc1.ode_sol.success assert sc1.ode_sol.message == 'A termination event occurred.' assert sc1.ode_sol.status == 1 if plot: ets = np.concatenate((sc0.ets, sc1.ets)) rs_earth = st.calc_ephemeris(3, ets, frame, 10)[:, :3] rs_jupiter = st.calc_ephemeris(5, ets, frame, 10)[:, :3] rs0 = sc0.states[ :, :3 ] +\ st.calc_ephemeris( 3, sc0.ets, frame, 10 )[ :, :3 ] labels = [ '$Voyager2_{EarthSOI}$', '$Voyager2_{SunSOI}$', 'Earth', 'Jupiter' ] pt.plot_orbits([rs0, sc1.states[:, :3], rs_earth, rs_jupiter], { 'labels': labels, 'colors': ['m', 'c', 'b', 'C3'], 'show': True })
Orbital propagation Circular orbit propagation ''' # 3rd party libraries import numpy as np # AWP library import orbit_calculations as oc import ode_tools as ot import plotting_tools as pt import planetary_data as pd if __name__ == '__main__': r0_norm = pd.earth['radius'] + 450.0 # km v0_norm = (pd.earth['mu'] / r0_norm)**0.5 # km / s statei = [r0_norm, 0, 0, 0, v0_norm, 0] tspan = 100.0 * 60.0 # seconds dt = 100.0 # seconds steps = int(tspan / dt) ets = np.zeros((steps, 1)) states = np.zeros((steps, 6)) states[0] = statei for step in range(steps - 1): states[step + 1] = ot.rk4_step(oc.two_body_ode, ets[step], states[step], dt) pt.plot_orbits([states], {'show': True})
# AWP libraries from Spacecraft import Spacecraft as SC from planetary_data import earth import plotting_tools as pt # 3rd party libraries import numpy as np aops = np.arange(0, 360, 90) incs = np.arange(0, 90, 20) tas = [0, 180] coes = [earth['radius'] + 10000, 0.05, 0.0, 0.0, 0.0, 0.0] scs = [] config = {'tspan': '1', 'dt': 100.0} print(len(aops) * len(incs) * len(tas)) if __name__ == '__main__': for inc in incs: for aop in aops: for ta in tas: coes[2] = inc coes[4] = ta coes[5] = aop config['coes'] = coes sc = SC(config) scs.append(sc) rs = [sc.states[:, :3] for sc in scs] pt.plot_orbits(rs, {'traj_lws': 1, 'show': True})
from numerical_tools import norm if __name__ == '__main__': spice.furnsh(sd.leapseconds_kernel) spice.furnsh('voyager2_jupiter_flyby.bsp') et = spice.str2et('1979-07-09 TDB') dt = 20 * 24 * 3600.0 ets = np.arange(et - dt, et + dt, 5000.0) states = st.calc_ephemeris(-32, ets, 'ECLIPJ2000', 5) pt.plot_orbits( [states[:, :3]], { 'labels': ['Voyager 2'], 'colors': ['m'], 'cb_radius': pd.jupiter['radius'], 'cb_cmap': 'Oranges', 'dist_unit': 'JR', 'azimuth': -57, 'elevation': 15, 'axes_mag': 0.5, 'show': True }) hline = {'val': norm(states[0, 3:]), 'color': 'm'} pt.plot_velocities(ets, states[:, 3:], { 'time_unit': 'hours', 'hlines': [hline], 'show': True })
# 3rd party libraries import numpy as np # AWP library from Spacecraft import Spacecraft as SC import orbit_calculations as oc import numerical_tools as nt import plotting_tools as pt import planetary_data as pd if __name__ == '__main__': periapsis = pd.earth[ 'radius' ] + 4000.0 # km coes = [ periapsis / 0.3, 0.7, 0, 30.0, 0, 0 ] state = oc.coes2state( coes ) v_rot = np.dot( nt.Cz( 40.0 * nt.d2r ), state[ 3: ] ) state_rot = np.concatenate( ( state[ :3 ], v_rot ) ) sc0 = SC( { 'orbit_state': state, 'tspan': '1' } ) sc_rot = SC( { 'orbit_state': state_rot, 'tspan': '1' } ) pt.plot_orbits( [ sc0.states[ :, :3 ], sc_rot.states[ :, :3 ] ], { 'labels' : [ 'Before', 'After' ], 'colors' : [ 'c', 'm' ], 'azimuth' : -90.0, 'elevation' : 90.0, 'axes_custom': 36000.0, 'traj_lws' : 2.5, 'show' : True } )