import%20marimo%0A%0A__generated_with%20%3D%20%220.16.0%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo%2C%20plot_std_atmosphere)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20rf%22%22%22%0A%20%20%20%20%23%20X-15%20Max%20Q%0A%0A%20%20%20%20I%20previously%20wrote%20about%20%5BMax%20Q%20-%20Maximum%20Dynamic%20Pressure%5D(https%3A%2F%2Fseanmcleod70.github.io%2FFlightDynamicsCalcs%2FMaxQ.html)%20comparing%20the%20Max%20Q%20experienced%20by%20a%20SpaceX%20rocket%20during%20launch%2C%20the%20Space%20Shuttle%20and%20a%20typical%20airliner.%20Now%20let%E2%80%99s%20take%20a%20look%20at%20the%20Max%20Q%20that%20was%20experienced%20by%20the%20X-15%20while%20it%20went%20about%20setting%20various%20speed%20and%20altitude%20records%20during%20it%E2%80%99s%20research.%0A%0A%20%20%20%20To%20recap%2C%20the%20dynamic%20pressure%20or%20Q%20is%20the%20product%20of%20the%20air-density%20and%20the%20velocity%20squared%20of%20the%20object%20travelling%20through%20the%20air.%0A%0A%20%20%20%20%24%24%5Cmathrm%7B%7BDynamic%5C%20Pressure%5C%20%7D%7D%20(Q)%20%3D%20%5Cfrac%7B%7B1%7D%7D%7B%7B2%7D%7D%20%5Crho%20V%5E2%24%24%0A%0A%20%20%20%20The%20SI%20unit%20for%20pressure%20is%20the%20pascal.%20One%20pascal%20is%20the%20pressure%20exerted%20by%20a%20force%20of%20magnitude%20of%20one%20newton%20perpendicularly%20upon%20an%20area%20of%20one%20square%20meter.%0A%0A%20%20%20%20The%20following%20graph%20shows%20how%20the%20density%20and%20the%20speed%20of%20sound%20vary%20in%20the%20standard%20atmosphere%20over%20the%20altitude%20range%20that%20the%20X-15%20operated%20in.%0A%0A%20%20%20%20%7Bplot_std_atmosphere()%7D%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20rf%22%22%22%0A%20%20%20%20%23%23%20X-15%20Report%0A%0A%20%20%20%20I%20came%20across%20a%20reference%20to%20an%20X-15%20report%20while%20watching%20Ben%20Dickinson%E2%80%99s%20YouTube%20video%20-%20%5BX-15%20Space%20Plane%20-%20A%20Review%20for%206DOF%20Model%20Development%20%7C%20Flight%20Simulation%20Tutorial%20-%20Section%202.1%5D(https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DiQrN6hgh8e0).%0A%0A%20%20%20%20The%20%5BDesign%20and%20Operation%20of%20the%20X-15%20Hypersonic%20Research%20Airplane%5D(https%3A%2F%2Fapps.dtic.mil%2Fsti%2Ftr%2Fpdf%2FAD0279830.pdf)%20report%20includes%20two%20graphs%20showing%20a%20plot%20of%20altitude%20vs%20time%20and%20Mach%20vs%20time%20for%20the%20two%20types%20of%20profiles%20flown.%20One%20profile%20targetting%20high%20altitude%20and%20one%20profile%20targetting%20high%20speed.%0A%0A%20%20%20%20%7Bmo.image(%22public%2FX-15-MaxQ%2Fx-15-report-graphs.png%22%2C%20width%3D600)%7D%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(dynamic_pressure%2C%20mo%2C%20plot_altitude_mission%2C%20plot_speed_mission)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20rf%22%22%22%0A%20%20%20%20%23%23%20Dynamic%20Pressure%20Variation%0A%0A%20%20%20%20So%20after%20digitizing%20the%20altitude%20and%20Mach%20data%20from%20the%20two%20graphs%20in%20the%20X-15%20report%20we%20can%20plot%20how%20the%20dynamic%20pressure%20varied%20during%20the%20two%20flight%20profiles%2C%20and%20also%20check%20when%20Max%20Q%20was%20achieved%20and%20how%20large%20Max%20Q%20was%20for%20each%20of%20the%20two%20profiles.%0A%0A%20%20%20%20%7Bplot_altitude_mission()%7D%0A%0A%20%20%20%20%7Bplot_speed_mission()%7D%0A%0A%20%20%20%20%7CAircraft%20Mission%7CTime%7CAltitude%7CMach%7CMax-Q%7C%0A%20%20%20%20%7C-------%7C----%7C--------%7C----%7C-----%7C%0A%20%20%20%20%7CX-15%20Altitude%7C30s%7C52%2C300ft%7C1.72%7C%7Bdynamic_pressure(52300%2C%201.72)%7D%7C%0A%20%20%20%20%7CX-15%20Speed%7C45s%7C69%2C000ft%7C2.91%7C%7Bdynamic_pressure(69000%2C%202.91)%7D%7C%0A%20%20%20%20%7CSR-71%7CN%2FA%7C80%2C000ft%7C3.5%7C%7Bdynamic_pressure(80000%2C%203.5)%7D%7C%0A%20%20%20%20%7CConcorde%7CN%2FA%7C60%2C000ft%7C2.04%7C%7Bdynamic_pressure(60000%2C%202.04)%7D%7C%0A%20%20%20%20%7CAirliner%7CN%2FA%7C37%2C000ft%7C0.85%7C%7Bdynamic_pressure(37000%2C%200.85)%7D%7C%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%23%23%20Code%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20from%20ISA%20import%20ISAtmosphere%0A%0A%20%20%20%20ISA%20%3D%20ISAtmosphere()%0A%20%20%20%20return%20ISA%2C%20mo%2C%20np%2C%20plt%0A%0A%0A%40app.cell%0Adef%20_(ISA%2C%20mo%2C%20plt)%3A%0A%20%20%20%20def%20plot_std_atmosphere()%3A%0A%20%20%20%20%20%20%20%20alts%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20rhos%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20speed_of_sounds%20%3D%20%5B%5D%0A%0A%20%20%20%20%20%20%20%20for%20h%20in%20range(0%2C%20260001%2C%201000)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_%2C%20rho%2C%20temp%2C%20speed_of_sound%20%3D%20ISA.state(h*0.3048)%20%23%20ft%20to%20m%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20alts.append(h)%0A%20%20%20%20%20%20%20%20%20%20%20%20rhos.append(rho)%0A%20%20%20%20%20%20%20%20%20%20%20%20speed_of_sounds.append(speed_of_sound*1.944012)%20%23%20m%2Fs%20to%20knots%0A%0A%20%20%20%20%20%20%20%20fig%20%3D%20plt.figure(layout%3D'constrained'%2C%20figsize%3D(10%2C%205))%0A%20%20%20%20%20%20%20%20host%20%3D%20fig.add_subplot(111)%0A%0A%20%20%20%20%20%20%20%20par1%20%3D%20host.twinx()%0A%0A%20%20%20%20%20%20%20%20host.set_ylim(-0.05%2C%201.5)%0A%20%20%20%20%20%20%20%20par1.set_ylim(400%2C%20700)%0A%0A%20%20%20%20%20%20%20%20host.set_xlabel('Altitude%20(ft)')%0A%20%20%20%20%20%20%20%20host.set_ylabel(r'Density%20%24%5Cfrac%7Bkg%7D%7Bm%5E3%7D%24')%0A%20%20%20%20%20%20%20%20par1.set_ylabel('Speed%20of%20Sound%20(kt)')%0A%0A%20%20%20%20%20%20%20%20p1%2C%20%3D%20host.plot(alts%2C%20rhos%2C%20label%3Dr'Density%20%24%5Cfrac%7Bkg%7D%7Bm%5E3%7D%24')%0A%20%20%20%20%20%20%20%20p2%2C%20%3D%20par1.plot(alts%2C%20speed_of_sounds%2C%20color%3D'r'%2C%20label%3D'Speed%20of%20sound%20(kt)')%0A%0A%20%20%20%20%20%20%20%20lns%20%3D%20%5Bp1%2C%20p2%5D%0A%20%20%20%20%20%20%20%20host.legend(handles%3Dlns%2C%20loc%3D'upper%20center')%0A%0A%20%20%20%20%20%20%20%20host.yaxis.label.set_color(p1.get_color())%0A%20%20%20%20%20%20%20%20par1.yaxis.label.set_color(p2.get_color())%0A%0A%20%20%20%20%20%20%20%20plt.title('Standard%20Atmosphere')%0A%0A%20%20%20%20%20%20%20%20return%20mo.md(f%22%7Bmo.as_html(fig)%7D%22)%0A%20%20%20%20return%20(plot_std_atmosphere%2C)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20def%20altitude_mission_altitude(t)%3A%0A%20%20%20%20%20%20%20%20return%2027.6113%20-%200.145776*t%20%2B%200.0657895*t**2%20-%200.00196133*t**3%20%2B%203.91021e-5*t**4%20-%204.40397e-7*t**5%20%2B%202.80813e-9*t**6%20-%201.01645e-11*t**7%20%2B%201.94942e-14*t**8%20-%201.53729e-17*t**9%0A%0A%20%20%20%20def%20speed_mission_altitude(t)%3A%0A%20%20%20%20%20%20%20%20return%2031.0556%20-%200.343199*t%20%2B%200.0910034*t**2%20-%200.00334765*t**3%20%2B%207.12152e-05*t**4%20-%208.67785e-07*t**5%20%2B%206.08275e-09*t**6%20-2.4314e-11*t**7%20%2B%205.15945e-14*t**8%20-%204.51568e-17*t**9%0A%0A%20%20%20%20def%20load_mission_mach(csv_filename)%3A%0A%20%20%20%20%20%20%20%20csv%20%3D%20open(csv_filename%2C%20'r')%0A%0A%20%20%20%20%20%20%20%20times%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20machs%20%3D%20%5B%5D%0A%0A%20%20%20%20%20%20%20%20for%20line%20in%20csv.readlines()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20vals%20%3D%20line.split('%2C')%0A%20%20%20%20%20%20%20%20%20%20%20%20t%20%3D%20float(vals%5B0%5D)%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20mach%20%3D%20float(vals%5B1%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20times.append(t)%0A%20%20%20%20%20%20%20%20%20%20%20%20machs.append(mach)%0A%0A%20%20%20%20%20%20%20%20return%20(times%2C%20machs)%0A%20%20%20%20return%20altitude_mission_altitude%2C%20load_mission_mach%0A%0A%0A%40app.cell%0Adef%20_(plot_mission)%3A%0A%20%20%20%20def%20plot_altitude_mission()%3A%0A%20%20%20%20%20%20%20%20return%20plot_mission('Altitude%20Mission'%2C%20'upper%20left'%2C%20'x-15-altitude-mission-mach.csv')%0A%0A%20%20%20%20def%20plot_speed_mission()%3A%0A%20%20%20%20%20%20%20%20return%20plot_mission('Speed%20Mission'%2C%20'upper%20right'%2C%20'x-15-speed-mission-mach.csv')%20%20%20%20%0A%20%20%20%20return%20plot_altitude_mission%2C%20plot_speed_mission%0A%0A%0A%40app.cell%0Adef%20_(ISA%2C%20altitude_mission_altitude%2C%20load_mission_mach%2C%20mo%2C%20np%2C%20plt)%3A%0A%20%20%20%20def%20plot_mission(title%2C%20legend_location%2C%20mach_file)%3A%0A%20%20%20%20%20%20%20%20fig%20%3D%20plt.figure(layout%3D'constrained'%2C%20figsize%3D(10%2C%205))%0A%20%20%20%20%20%20%20%20host%20%3D%20fig.add_subplot(111)%0A%0A%20%20%20%20%20%20%20%20par1%20%3D%20host.twinx()%0A%20%20%20%20%20%20%20%20par2%20%3D%20host.twinx()%0A%0A%20%20%20%20%20%20%20%20host.set_ylim(0%2C%20280)%0A%20%20%20%20%20%20%20%20par1.set_ylim(0%2C%207)%0A%20%20%20%20%20%20%20%20par2.set_ylim(0%2C%2030)%0A%0A%20%20%20%20%20%20%20%20host.set_xlabel('Time%20(s)')%0A%20%20%20%20%20%20%20%20host.set_ylabel('Altitude%20(1000%20ft)')%0A%20%20%20%20%20%20%20%20par1.set_ylabel('Mach')%0A%20%20%20%20%20%20%20%20par2.set_ylabel('Dynamic%20Pressure%20(kPa)')%0A%0A%20%20%20%20%20%20%20%20times%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20maxq%20%3D%200%0A%20%20%20%20%20%20%20%20maxq_time%20%3D%200%0A%20%20%20%20%20%20%20%20maxq_mach%20%3D%200%0A%20%20%20%20%20%20%20%20maxq_alt%20%3D%200%0A%0A%20%20%20%20%20%20%20%20%23%20Altitude%0A%20%20%20%20%20%20%20%20alts%20%3D%20%5B%5D%0A%0A%20%20%20%20%20%20%20%20for%20t%20in%20range(0%2C%20261%2C%201)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20alt%20%3D%20altitude_mission_altitude(t)%0A%20%20%20%20%20%20%20%20%20%20%20%20times.append(t)%0A%20%20%20%20%20%20%20%20%20%20%20%20alts.append(alt)%20%20%20%20%0A%0A%20%20%20%20%20%20%20%20%23%20Mach%0A%20%20%20%20%20%20%20%20mach_times%2C%20machs_raw%20%3D%20load_mission_mach(f'data%2FX-15-MaxQ%2F%7Bmach_file%7D')%20%20%20%20%0A%20%20%20%20%20%20%20%20machs%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20for%20t%20in%20range(0%2C%20261%2C%201)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20mach%20%3D%20np.interp(t%2C%20mach_times%2C%20machs_raw)%0A%20%20%20%20%20%20%20%20%20%20%20%20machs.append(mach)%0A%0A%20%20%20%20%20%20%20%20%23%20Dynamic%20pressure%0A%20%20%20%20%20%20%20%20qs%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20for%20i%20in%20range(0%2C%20len(times))%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20mach%20%3D%20machs%5Bi%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20h%20%3D%20alts%5Bi%5D%20*%201000%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20_%2C%20rho%2C%20temp%2C%20speed_of_sound%20%3D%20ISA.state(h*0.3048)%20%23%20ft%20to%20m%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20v%20%3D%20mach%20*%20speed_of_sound%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20q%20%3D%200.5%20*%20rho%20*%20v**2%0A%20%20%20%20%20%20%20%20%20%20%20%20qs.append(q%2F1000)%20%23%20kPa%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20q%20%3E%20maxq%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20maxq%20%3D%20q%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20maxq_time%20%3D%20i%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20maxq_mach%20%3D%20mach%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20maxq_alt%20%3D%20h%0A%0A%20%20%20%20%20%20%20%20p1%2C%20%3D%20host.plot(times%2C%20alts%2C%20label%3D'Altitude%20(1000%20ft)')%0A%20%20%20%20%20%20%20%20p2%2C%20%3D%20par1.plot(times%2C%20machs%2C%20color%3D'r'%2C%20label%3D'Mach')%0A%20%20%20%20%20%20%20%20p3%2C%20%3D%20par2.plot(times%2C%20qs%2C%20color%3D'g'%2C%20label%3D'Dynamic%20Pressure%20(kPa)'%20)%0A%0A%20%20%20%20%20%20%20%20%23plt.axvline(x%3Dmaxq_time)%0A%20%20%20%20%20%20%20%20%23print(maxq_time%2C%20maxq_alt%2C%20maxq_mach%2C%20maxq%2F1000)%0A%0A%20%20%20%20%20%20%20%20lns%20%3D%20%5Bp1%2C%20p2%2C%20p3%5D%0A%20%20%20%20%20%20%20%20host.legend(handles%3Dlns%2C%20loc%3Dlegend_location)%0A%0A%20%20%20%20%20%20%20%20par2.spines%5B'right'%5D.set_position(('outward'%2C%2040))%20%0A%0A%20%20%20%20%20%20%20%20host.yaxis.label.set_color(p1.get_color())%0A%20%20%20%20%20%20%20%20par1.yaxis.label.set_color(p2.get_color())%0A%20%20%20%20%20%20%20%20par2.yaxis.label.set_color(p3.get_color())%0A%0A%20%20%20%20%20%20%20%20plt.title(title)%0A%0A%20%20%20%20%20%20%20%20return%20mo.md(f%22%7Bmo.as_html(fig)%7D%22)%0A%20%20%20%20return%20(plot_mission%2C)%0A%0A%0A%40app.cell%0Adef%20_(ISA)%3A%0A%20%20%20%20def%20dynamic_pressure(altitude%2C%20mach)%3A%0A%20%20%20%20%20%20%20%20_%2C%20rho%2C%20_%2C%20speed_of_sound%20%3D%20ISA.state(altitude*0.3048)%20%23%20ft%20to%20m%0A%20%20%20%20%20%20%20%20v%20%3D%20mach%20*%20speed_of_sound%0A%20%20%20%20%20%20%20%20q%20%3D%200.5%20*%20rho%20*%20v**2%0A%0A%20%20%20%20%20%20%20%20return%20f'%7Bq%2F1000%3A.1f%7D%20kPa'%20%0A%20%20%20%20return%20(dynamic_pressure%2C)%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
691c2a0a9dd9446ebb2d96690afc5d148e19a6147901a84c6c1f7b03648eb4af