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%23%20Trim%20Envelope%0A%0A%20%20%20%20Calculate%20the%20set%20of%20trim%20points%20for%20an%20aircraft%20over%20a%20range%20of%20airspeeds%20and%20range%20of%20flight%20path%20angles%20%24%5Cgamma%24.%20The%20required%20thrust%20and%20AoA%20is%20indicated%20via%20a%20colormap%20for%20each%20trim%20point.%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_(mo)%3A%0A%20%20%20%20%23%20Supress%20stdout%20messages%20about%20expected%20trim%20failures%0A%20%20%20%20with%20mo.redirect_stdout()%3A%0A%0A%20%20%20%20%20%20%20%20import%20jsbsim%0A%20%20%20%20%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20%20%20%20%20import%20math%0A%0A%20%20%20%20%20%20%20%20%23%20Global%20variables%20that%20must%20be%20modified%20to%20match%20your%20particular%20need%0A%20%20%20%20%20%20%20%20%23%20The%20aircraft%20name%0A%20%20%20%20%20%20%20%20%23%20Note%20-%20It%20should%20match%20the%20exact%20spelling%20of%20the%20model%20file%0A%20%20%20%20%20%20%20%20AIRCRAFT_NAME%3D%22737%22%0A%20%20%20%20%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%20%20%20%20%20PATH_TO_JSBSIM_FILES%3D%22data%2Fjsbsim%22%0A%0A%20%20%20%20%20%20%20%20%23%20Avoid%20flooding%20the%20console%20with%20log%20messages%0A%20%20%20%20%20%20%20%20jsbsim.FGJSBBase().debug_lvl%20%3D%200%0A%0A%20%20%20%20%20%20%20%20fdm%20%3D%20jsbsim.FGFDMExec(PATH_TO_JSBSIM_FILES)%0A%0A%20%20%20%20%20%20%20%20%23%20Load%20the%20aircraft%20model%0A%20%20%20%20%20%20%20%20fdm.load_model(AIRCRAFT_NAME)%0A%0A%20%20%20%20%20%20%20%20%23%20Set%20engines%20running%0A%20%20%20%20%20%20%20%20fdm%5B'propulsion%2Fset-running'%5D%20%3D%20-1%0A%0A%20%20%20%20%20%20%20%20%23%20Set%20alpha%20range%20for%20trim%20solutions%0A%20%20%20%20%20%20%20%20fdm%5B'aero%2Falpha-max-rad'%5D%20%3D%20math.radians(12)%0A%20%20%20%20%20%20%20%20fdm%5B'aero%2Falpha-min-rad'%5D%20%3D%20math.radians(-4.0)%0A%0A%20%20%20%20%20%20%20%20%23%20Set%20envelope%20limits%0A%20%20%20%20%20%20%20%20min_speed%20%3D%20120%0A%20%20%20%20%20%20%20%20max_speed%20%3D%20460%0A%20%20%20%20%20%20%20%20altitude%20%3D%2015000%0A%20%20%20%20%20%20%20%20min_gamma%20%3D%20-10%0A%20%20%20%20%20%20%20%20max_gamma%20%3D%2010%0A%0A%20%20%20%20%20%20%20%20%23%20Trim%20results%0A%20%20%20%20%20%20%20%20results%20%3D%20%5B%5D%0A%0A%20%20%20%20%20%20%20%20%23%20Iterate%20over%20a%20range%20of%20speeds%20and%20for%20each%20speed%20a%20range%20of%20flight%20path%20angles%20(gamma)%0A%20%20%20%20%20%20%20%20%23%20and%20check%20whether%20a%20trim%20point%20is%20possible%0A%20%20%20%20%20%20%20%20for%20speed%20in%20range(min_speed%2C%20max_speed%2C%2010)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20gamma%20in%20range(min_gamma%2C%20max_gamma%2C%201)%3A%0A%20%20%20%20%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%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%20%20%20%20%20fdm%5B'ic%2Fgamma-deg'%5D%20%3D%20gamma%0A%0A%20%20%20%20%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%20%20%20%20%20fdm.run_ic()%0A%0A%20%20%20%20%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%20%20%20%20%20try%3A%0A%20%20%20%20%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%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20results.append((fdm%5B'velocities%2Fvc-kts'%5D%2C%20fdm%5B'aero%2Falpha-deg'%5D%2C%20gamma%2C%20fdm%5B'fcs%2Fthrottle-cmd-norm%5B0%5D'%5D))%0A%20%20%20%20%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%20%20%20%20%20pass%20%20%23%20Ignore%20trim%20failures%0A%0A%20%20%20%20%20%20%20%20%23%20Extract%20the%20trim%20results%0A%20%20%20%20%20%20%20%20speed%2C%20alpha%2C%20gamma%2C%20throttle%20%3D%20zip(*results)%0A%0A%20%20%20%20%20%20%20%20plt.rcParams%5B%22figure.figsize%22%5D%20%3D%20(16%2C%208)%0A%0A%20%20%20%20%20%20%20%20%23%20Plot%20the%20trim%20envelope%20results%2C%20with%20required%20thrust%20and%20AoA%20indicated%20via%20a%20colormap%0A%20%20%20%20%20%20%20%20fig%2C%20(axThrust%2C%20axAoA)%20%3D%20plt.subplots(1%2C%202)%0A%0A%20%20%20%20%20%20%20%20%23%20Graph%20data%20for%20each%20of%20the%20sub%20plots%0A%20%20%20%20%20%20%20%20graph_data%20%3D%20%5B%20('Thrust'%2C%20axThrust%2C%20throttle)%2C%20('AoA'%2C%20axAoA%2C%20alpha)%20%5D%0A%0A%20%20%20%20%20%20%20%20for%20title%2C%20ax%2C%20data%20in%20graph_data%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Scatter%20plot%20with%20airspeed%20on%20x-axis%2C%20gamma%20on%20y-axis%20and%20either%20thrust%20setting%20or%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20AoA%20indicated%20via%20color%20map%0A%20%20%20%20%20%20%20%20%20%20%20%20scatter%20%3D%20ax.scatter(speed%2C%20gamma%2C%20c%3Ddata%2C%20cmap%3D'viridis')%0A%20%20%20%20%20%20%20%20%20%20%20%20cb%20%3D%20fig.colorbar(scatter%2C%20ax%3Dax)%0A%20%20%20%20%20%20%20%20%20%20%20%20cb.set_label(title)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Graph%20axis%20range%20for%20speed%20and%20gamma%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_xlim(min_speed%20-%2020%2C%20max_speed%20%2B%2020)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_ylim(min_gamma%20*%202%2C%20max_gamma%20*%202)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.grid(True%2C%20linestyle%3D'-.')%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_xlabel('IAS%20(kt)')%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_ylabel('Flight%20Path%20Angle%20%24%5Cgamma%24%20(deg)')%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_title(f'Trim%20Envelope%20-%20%7Btitle%7D')%0A%0A%20%20%20%20plt.gca()%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%20return%20(mo%2C)%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
10608e3e8a3b3371e1da2e92d413da9bf46358c719d98974a31d63c3684438b1