import%20marimo%0A%0A__generated_with%20%3D%20%220.14.6%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%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%20r%22%22%22%0A%20%20%20%20%23Thrust%20Vectoring%20Analysis%0A%0A%20%20%20%20Based%20on%20a%20NASA%20report%20-%20%5BOptimal%20Pitch%20Thrust-Vector%20Angle%20and%20Benefits%20for%20all%20Flight%20Regimes%5D(https%3A%2F%2Fntrs.nasa.gov%2Fapi%2Fcitations%2F20000034897%2Fdownloads%2F20000034897.pdf)%0A%0A%20%20%20%20Use%20JSBSim%20to%20compare%20how%20varying%20the%20thrust%20vector%20angle%20can%20minimize%20fuel%20burn%20for%20a%20given%20flight%20condition%20and%20compare%20the%20results%20to%20the%20NASA%20report.%0A%0A%20%20%20%20Tests%20performed%20for%20a%20cruise%20condition%20and%20for%20a%20climb%20condition.%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(thrust_vector_range_test)%3A%0A%20%20%20%20%23%20Cruise%20conditions%20-%2030%2C000ft%20Mach%200.8%0A%20%20%20%20thrust_vector_range_test(30000%2C%200.8%2C%200%2C%20'Cruise%20-%2030%2C000ft%20Mach%200.8')%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(thrust_vector_range_test)%3A%0A%20%20%20%20%23%20Climb%20conditions%20-%2015%2C000ft%20300KIAS%20flight%20path%20angle%20of%203%20degrees%0A%20%20%20%20thrust_vector_range_test(15000%2C%20300%2C%203%2C%20'Climb%20-%2015%2C000ft%20300KIAS%20FPA%203%20deg')%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20jsbsim%0A%20%20%20%20import%20math%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%0A%20%20%20%20AIRCRAFT_NAME%3D%22737%22%0A%20%20%20%20%23%20Path%20to%20JSBSim%20files%2C%20location%20of%20the%20folders%20%22aircraft%22%2C%20%22engines%22%20and%20%22systems%22%0A%20%20%20%20PATH_TO_JSBSIM_FILES%3D%22data%2Fjsbsim%22%0A%0A%20%20%20%20%23%20Avoid%20flooding%20the%20console%20with%20log%20messages%0A%20%20%20%20jsbsim.FGJSBBase().debug_lvl%20%3D%200%0A%0A%20%20%20%20fdm%20%3D%20jsbsim.FGFDMExec(PATH_TO_JSBSIM_FILES)%0A%0A%20%20%20%20%23%20Load%20the%20aircraft%20model%0A%20%20%20%20fdm.load_model(AIRCRAFT_NAME)%0A%0A%20%20%20%20%23%20Set%20engines%20running%0A%20%20%20%20fdm%5B'propulsion%2Fset-running'%5D%20%3D%20-1%0A%0A%0A%20%20%20%20def%20thrust_vector_range_test(altitude%2C%20speed%2C%20flight_path_angle%2C%20title)%3A%0A%0A%20%20%20%20%20%20%20%20%23%20Thrust%20vectoring%20angles%20to%20test%0A%20%20%20%20%20%20%20%20tv_angles%20%3D%20np.linspace(0%2C%2010%2C%20100)%0A%0A%20%20%20%20%20%20%20%20%23%20Thrust%20and%20AoA%20trim%20results%0A%20%20%20%20%20%20%20%20thrusts%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20alphas%20%3D%20%5B%5D%0A%0A%20%20%20%20%20%20%20%20%23%20Track%20minimum%20thrust%0A%20%20%20%20%20%20%20%20min_thrust%20%3D%201000000%0A%20%20%20%20%20%20%20%20min_angle%20%3D%20100%0A%0A%20%20%20%20%20%20%20%20for%20tv_angle%20in%20tv_angles%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Initial%20conditions%0A%20%20%20%20%20%20%20%20%20%20%20%20fdm%5B'ic%2Fh-sl-ft'%5D%20%3D%20altitude%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20speed%20%3C%201.0%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fdm%5B'ic%2Fmach'%5D%20%3D%20speed%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fdm%5B'ic%2Fvc-kts'%5D%20%3D%20speed%0A%20%20%20%20%20%20%20%20%20%20%20%20fdm%5B'ic%2Fgamma-deg'%5D%20%3D%20flight_path_angle%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Initialize%20the%20aircraft%20with%20initial%20conditions%0A%20%20%20%20%20%20%20%20%20%20%20%20fdm.run_ic()%20%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Trim%0A%20%20%20%20%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20Set%20thrust%20vector%20angle%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fdm%5B%22propulsion%2Fengine%5B0%5D%2Fpitch-angle-rad%22%5D%20%3D%20math.radians(tv_angle)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fdm%5B%22propulsion%2Fengine%5B1%5D%2Fpitch-angle-rad%22%5D%20%3D%20math.radians(tv_angle)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fdm%5B'simulation%2Fdo_simple_trim'%5D%20%3D%201%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alphas.append(fdm%5B%22aero%2Falpha-deg%22%5D)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20thrust%20%3D%20fdm%5B%22propulsion%2Fengine%5B0%5D%2Fthrust-lbs%22%5D*2%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20thrusts.append(thrust)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20thrust%20%3C%20min_thrust%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20min_thrust%20%3D%20thrust%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20min_angle%20%3D%20tv_angle%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20except%20jsbsim.TrimFailureError%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%22Trim%20failed....%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pass%20%20%23%20Ignore%20trim%20failure%0A%0A%20%20%20%20%20%20%20%20%23%20Plot%20results%0A%20%20%20%20%20%20%20%20plt.rcParams%5B%22figure.figsize%22%5D%20%3D%20(12%2C%208)%0A%20%20%20%20%20%20%20%20fig%2C%20ax1%20%3D%20plt.subplots()%0A%20%20%20%20%20%20%20%20plt.title(title)%0A%0A%20%20%20%20%20%20%20%20ax1.plot(tv_angles%2C%20thrusts%2C%20label%3D'Thrust')%0A%20%20%20%20%20%20%20%20ax1.scatter(min_angle%2C%20min_thrust%2C%20color%3D'red'%2C%20label%3Df'Minimum%20Thrust%20at%20%7Bmin_angle%3A.2f%7D%20deg')%0A%20%20%20%20%20%20%20%20ax1.set_xlabel('Thrust%20Vector%20Angle%20(deg)')%0A%20%20%20%20%20%20%20%20ax1.set_ylabel('Thrust%20(lbf)')%0A%0A%20%20%20%20%20%20%20%20%23%20Create%20the%20second%20y-axis%20for%20AoA%0A%20%20%20%20%20%20%20%20ax2%20%3D%20ax1.twinx()%0A%20%20%20%20%20%20%20%20ax2.set_ylabel('Alpha%20(deg)')%0A%20%20%20%20%20%20%20%20ax2.plot(tv_angles%2C%20alphas%2C%20color%3D'green'%2C%20label%3D'Alpha')%0A%0A%20%20%20%20%20%20%20%20ax1.legend(loc%3D'upper%20center')%0A%20%20%20%20%20%20%20%20ax2.legend(loc%3D'center%20right')%0A%0A%20%20%20%20%20%20%20%20return%20plt.gca()%0A%20%20%20%20return%20(thrust_vector_range_test%2C)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20return%20(mo%2C)%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
ab39c7b8a228fb7635391a79c7e3a5d53718eecc0860a45dfadf1bc452eb2b45