Monte Carlo

Another attempt at a monte carlo analysis, this time with LV2-like numbers.

This directory has an attempt at a managing JSBSim sessions that can spin up multiple threads to run simulations in parallel. It also kills the sim at apogee, whenever that may be. The upshot is that I can run many more simulations per minute than the naive approach.

This setup:

# starting values, real numbers for an N2501 motor
isp     =   179    # s
thrust  =  2510    # N
impulse = 15280    # N*s
CD      =     0.6

# Randomize
isp = random.gauss(isp, isp*0.03)                       # 3% spread
thrust = random.gauss(thrust, thrust*0.10)              # 10% spread
impulse = random.uniform(impulse - 200, impulse + 200)  # +/- 200 N*s
cd_avg = random.gauss(0.6, 0.1)                         # ~16% spread

In [ ]:
print("Ran 4000 indapendent simulations in 12.8 miuntes.")
print("That's about %0.2f seconds per simulation." % (720/4000))

In [ ]:
# Chart
import csv
import statistics
import matplotlib.pyplot as plt
%matplotlib inline

FPS2M = 0.3048
LBF2N = 4.44822
LBS2KG = 0.453592

n_times = 4000

max_alt = 0
max_alt_time = 0
max_alts = []
sim_times = []
sim_vel_ups = []
sim_thrusts = []
sim_alts = []
for i in range(n_times):
    # Read data from JSBSim
    sim_time = []
    sim_vel_up = []
    sim_alt = []
    sim_thrust = []
    this_max_alt = 0
    with open("data/sim-%05d.csv" % i) as datafile:
        reader = csv.reader(datafile, delimiter=',')
        for row in reader:
            # ignore first line
            if row[0][0] == 'T':
                continue
            time      = float(row[0])           # s
            alt       = float(row[1])           # m
            vel_down  = float(row[2]) * FPS2M   # m/s
            thrust    = float(row[3]) * LBF2N   # N
            
            sim_time.append(time)
            sim_vel_up.append(-vel_down)
            sim_alt.append(alt)
            sim_thrust.append(thrust)

            # max alt
            if alt > max_alt:
                max_alt = alt
                max_alt_time = time
            if alt > this_max_alt:
                this_max_alt = alt
    max_alts.append((i, this_max_alt))
    sim_times.append(sim_time)
    sim_vel_ups.append(sim_vel_up)
    sim_alts.append(sim_alt)
    sim_thrusts.append(sim_thrust)

sorted_max = sorted(max_alts, key=lambda tup: tup[1])
mlist = [tup[1] for tup in sorted_max]

print("Highest sim went to:         %5.1f km\n" % (mlist[-1] / 1000.0))
print("Lowest sim went to:          %5.1f km\n" % (mlist[0] / 1000.0))

mean = statistics.mean(mlist)
median = statistics.median(mlist)

max_i = sorted_max[-1][0]
min_i = sorted_max[0][0]
median_i = min(sorted_max, key=lambda tup: abs(tup[1]-median))

print("The mean sim altitude was:   %5.1f km\n" % (mean / 1000.0))
print("The median sim altitude was: %5.1f km\n" % (median / 1000.0))

In [ ]:
fig, ax1 = plt.subplots(figsize=(18,7))
plt.title(r"Distribution of Maximum Altitudes")
plt.xlabel(r"Maximum Altitude [m]")

n, bins, patches = plt.hist(mlist, 40, histtype='step', normed=1, alpha=0.4, linewidth=1, fill=True)

#plt.ylim([0, 35])
#plt.xlim()
plt.show()

In [ ]:
fig, ax1 = plt.subplots(figsize=(18,7))
plt.title(r"Simulated Rocket Altitude: All Runs")
plt.ylabel(r"Altitude MSL [meters]")
plt.xlabel(r"Time [s]")
    
for i in range(len(max_alts)):
    plt.plot(sim_times[i], sim_alts[i], 'b-', lw=1.0, alpha=0.005)


plt.plot(sim_times[max_i], sim_alts[max_i], 'r-', lw=1.2, alpha=0.6, label="Maximum Altitude Sim")
plt.plot(sim_times[min_i], sim_alts[min_i], 'g-', lw=1.2, alpha=0.6, label="Minimum Altitude Sim")
plt.plot(sim_times[median_i[0]], sim_alts[median_i[0]], 'k-', lw=1.4, alpha=0.9, label="Median Altitude Sim")

#plt.ylim([0, max_alt + 1000])
#plt.xlim([0, max_alt_time])
plt.legend(loc=2)
plt.show()

In [ ]:
fig, ax1 = plt.subplots(figsize=(18,7))
plt.title(r"Simulated Rocket Altitude: All Runs")
plt.ylabel(r"Altitude MSL [meters]")
plt.xlabel(r"Time [s]")
    
for i in range(len(max_alts)):
    plt.plot(sim_times[i], sim_vel_ups[i], 'b-', lw=1.0, alpha=0.005)

plt.plot(sim_times[max_i], sim_vel_ups[max_i], 'r-', lw=1.2, alpha=0.6, label="Maximum Altitude Sim")
plt.plot(sim_times[min_i], sim_vel_ups[min_i], 'g-', lw=1.2, alpha=0.6, label="Minimum Altitude Sim")
plt.plot(sim_times[median_i[0]], sim_vel_ups[median_i[0]], 'k-', lw=1.4, alpha=0.9, label="Median Altitude Sim")

plt.ylim([0, 600])
#plt.xlim([0, max_alt_time])
plt.legend(loc=1)
plt.show()

In [ ]:
fig, ax1 = plt.subplots(figsize=(18,7))
plt.title(r"Simulated Rocket Altitude: All Runs")
plt.ylabel(r"Altitude MSL [meters]")
plt.xlabel(r"Time [s]")
    
for i in range(len(max_alts)):
    plt.plot(sim_times[i], sim_thrusts[i], 'b-', lw=1.0, alpha=0.005)

plt.plot(sim_times[max_i], sim_thrusts[max_i], 'r-', lw=1.2, alpha=0.6, label="Maximum Altitude Sim")
plt.plot(sim_times[min_i], sim_thrusts[min_i], 'g-', lw=1.2, alpha=0.6, label="Minimum Altitude Sim")
plt.plot(sim_times[median_i[0]], sim_thrusts[median_i[0]], 'k-', lw=1.4, alpha=0.9, label="Median Altitude Sim")

#plt.ylim([0, 600])
plt.xlim([-1, 15])
plt.legend(loc=1)
plt.show()