import numpy as np import matplotlib.pyplot as plt from scipy.integrate import odeint

Constants#

M_E = 5.974e20 G = 6.6742e11 R_E = 6371e3 # radius of Earth (m) Isp = 300 # specific impulse (s) g0 = G*M_E/R_E**2 # 9.81 # gravitational acceleration at Earth’s surface (m/s^2) c = Isp * g0 # effective exhaust velocity (m/s) A_e = 1.0 # exit area of the nozzle (m^2), assumed p_a = 101325 # atmospheric pressure at sea level (Pa) p_e = 0 # exhaust pressure, assumed vacuum for simplicity

Initial conditions#

v0 = 0 # initial velocity (m/s) gamma0 = np.radians(90) # initial flight path angle (radians), vertical launch x0 = 0 # initial downrange distance (m) h0 = 0 # initial altitude (m) m_wet = 500e3 # initial wet mass (kg) m_dry = 50e3 # dry mass (kg) T = 7.5e6 # initial thrust (N)

Time span#

t = np.linspace(0, 3600, 1000) # 3600 seconds, 1000 points

Gravitational acceleration as a function of altitude#

def gravity(h): return g0 * (R_E**2 / (R_E + h)**2)

Differential equations#

def rocket_dynamics(y, t, c, A_e, p_a, p_e, m_dry, T): v, gamma, x, h, m = y g = gravity(h) if m > m_dry: mdot_e = T / c # mass flow rate (kg/s) else: mdot_e = 0 # no more propellant to burn T_dynamic = mdot_e * (c + (p_e - p_a) * A_e / mdot_e) if mdot_e != 0 else 0 dvdt = (T_dynamic / m) - g * np.sin(gamma) if v == 0: print(“v==0 at t=”, t) dgamma_dt = 0 else: print(“v is”, v) print(“gamma is”, gamma) dgamma_dt = -(1 / v) * (g - (v**2 / (R_E + h))) * np.cos(gamma) dxdt = (R_E / (R_E + h)) * v * np.cos(gamma) dhdt = v * np.sin(gamma) dmdt = -mdot_e # rate of mass consumption return [dvdt, dgamma_dt, dxdt, dhdt, dmdt]

Initial state#

y0 = [v0, gamma0, x0, h0, m_wet]

Integrate the equations over the time grid#

solution = odeint(rocket_dynamics, y0, t, args=(c, A_e, p_a, p_e, m_dry, T))

Extract the results#

v, gamma, x, h, m = solution.T

Plotting the trajectory#

plt.figure(figsize=(10, 6)) plt.plot(x / 1e3, h / 1e3) # convert to kilometers for readability plt.title(‘Rocket Trajectory’) plt.xlabel(‘Downrange Distance (km)’) plt.ylabel(‘Altitude (km)’) plt.grid(True) plt.show()

Plotting g as a function of altitude#

z = np.linspace(0, 1000e3, 1000) # altitude from 0 to 1000 km g_z = gravity(z) plt.figure(figsize=(10, 6)) plt.plot(z / 1e3, g_z / g0) # plot g/g0 plt.title(‘Gravitational Acceleration vs Altitude’) plt.xlabel(‘Altitude (km)’) plt.ylabel(‘g / g0’) plt.grid(True) plt.show()

Plotting mass vs time#

plt.figure(figsize=(10, 6)) plt.plot(t, m / 1e3) # convert mass to tonnes for readability plt.title(‘Rocket Mass vs Time’) plt.xlabel(‘Time (s)’) plt.ylabel(‘Mass (tonnes)’) plt.grid(True) plt.show()

Plotting velocity vs time#

plt.figure(figsize=(10, 6)) plt.plot(t, v / 1e3) # convert velocity to km/s for readability plt.title(‘Rocket Velocity vs Time’) plt.xlabel(‘Time (s)’) plt.ylabel(‘Velocity (km/s)’) plt.grid(True) plt.show()