Sunday, 12 April 2026

Tracking LADEE: The Physics of a Lunar Journey

On September 6, 2013, NASA’s Lunar Atmosphere and Dust Environment Explorer (LADEE) lit up the night sky over Virginia. While the mission was designed to study the moon’s thin atmosphere, the most intense part of its journey began at the Wallops Flight Facility. ​
Using trajectory data from the launch, we can use Python to "reverse engineer" the rocket's performance. By applying linear regression to the altitude, range, and velocity, we can see exactly how much power it takes to break free from Earth's grip.

The Raw Data

​We analyzed a 20-second window starting at 190 seconds after launch. At this stage, the rocket is already roughly 150 \text{ km} high—well into the thermosphere—and moving at hypersonic speeds.
​1. Vertical Ascent: Climbing the Gravity Well
​First, we look at the Altitude vs. Time. By fitting a linear trendline to the data, we can determine the vertical component of the rocket's velocity.
​The Equation: Altitude = 0.885 {time} + 149.636
​Vertical Velocity: 0.885 { km/s}
​Accuracy (R^2): 0.9926

​The high R^2 value tells us that during this specific 20-second window, the rocket’s vertical climb was incredibly steady.

​2. The Gravity Turn: Gaining Horizontal Speed
​Rockets don’t just go "up"—to stay in space, they must go "sideways" very fast. This is known as the Range.
​The Equation: Range = 5.433{time} + 444.667
​Horizontal Velocity: 5.433 { km/s}
​Accuracy (R^2): 0.9985
​Note how the horizontal velocity is nearly six times faster than the vertical velocity. LADEE was working hard to reach orbital velocity.
​The Flight Profile at T+190 Seconds
​By combining these vectors, we can calculate the exact state of the rocket at the start of our data set.

How We Calculated This (The Python Approach)

​For the developers and data nerds, we used numpy.polyfit to calculate the "Line of Best Fit" for the trajectory. This allows us to ignore minor sensor noise and see the true physics of the engine's thrust.





import numpy as np
import matplotlib.pyplot as plt

# Global Constants
g = 9.8  # Earth's gravity in m/s^2

def curvefit(x, y, deg=1):
    """Calculates the line of best fit."""
    return np.polyfit(x, y, deg)
    
def calculate_r2(y, y_pred):
    """Determines the Coefficient of Determination (Accuracy)."""
    ss_res = np.sum((y - y_pred)**2)
    ss_tot = np.sum((y - np.mean(y))**2)
    return 1 - (ss_res / ss_tot)

# Raw Trajectory Data: Time(s), Altitude(km), Range(km), Speed(m/s)
trajectory = [
    (190, 150, 446, 5339), (192, 151, 456, 5344),
    (194, 153, 467, 5535), (196, 154, 478, 5629),
    (198, 156, 489, 5744), (200, 158, 500, 5853),
    (202, 159, 511, 5962), (204, 161, 522, 5991),
    (206, 163, 533, 5993), (208, 164, 546, 5990),
]

# Data Extraction
start_time = trajectory[0][0]
time_steps = np.array([t for (t, alt, rng, v) in trajectory])
time_normalized = time_steps - start_time
altitudes = np.array([alt for (t, alt, rng, v) in trajectory])
ranges = np.array([rng for (t, alt, rng, v) in trajectory])
velocities = np.array([v for (t, alt, rng, v) in trajectory])

print(f"{'Rocket Dynamics Analysis':^40}")
print("-" * 40)

# --- Analysis: Vertical Performance ---
coeffs_alt = curvefit(time_normalized, altitudes)
v_vert = coeffs_alt[0]
alt_pred = np.polyval(coeffs_alt, time_normalized)
r2_alt = calculate_r2(altitudes, alt_pred)

print(f"Vertical Velocity:   {v_vert:.3f} km/s")
print(f"Altitude Fit (R2):   {r2_alt:.4f}")

# --- Analysis: Horizontal Performance ---
coeffs_rng = curvefit(time_normalized, ranges)
v_horiz = coeffs_rng[0]
rng_pred = np.polyval(coeffs_rng, time_normalized)
r2_rng = calculate_r2(ranges, rng_pred)

print(f"Horizontal Velocity: {v_horiz:.3f} km/s")
print(f"Range Fit (R2):      {r2_rng:.4f}")

# --- Vector Summation ---
total_vel = np.sqrt(v_vert**2 + v_horiz**2)
launch_angle = np.degrees(np.arctan2(v_vert, v_horiz))

print("-" * 40)
print(f"Total Velocity:      {total_vel:.3f} km/s")
print(f"Flight Path Angle:   {launch_angle:.2f} degrees")

# --- Acceleration Analysis ---
coeffs_vel = curvefit(time_normalized, velocities)
accel = coeffs_vel[0]
print(f"Acceleration:        {accel:.3f} m/s^2")
print(f"G-Force Load:        {accel/g:.2f} G")
Summary By using simple linear regression, we can visualize the sheer scale of a lunar launch. LADEE’s journey reminds us that getting to the moon isn't just about height—it’s about the massive horizontal velocity required to stay in the sky.

No comments:

Post a Comment

Visualizing Particle Kinematics with Python

Understanding the relationship between position, velocity, and acceleration is fundamental to physics. However, seeing how these variables e...