jsbsim --script=scripts/x1_test.xml The script: set prop/engine[0]/running 1 , set fcs/throttle-cmd-norm 0.7 , run 30 .

<aerodynamics> <axis name="LIFT"> <coefficient name="CL"> <function> <table> <independentVar lookup="row">aero/alpha-rad</independentVar> <independentVar lookup="column">fcs/camber-command</independentVar> <!-- data from wind tunnel: rows alpha (-0.2 to 0.4 rad), cols camber (0 to 0.05) --> <tableData> -0.2 -0.4 -0.35 ... 0.0 0.2 0.25 ... 0.4 1.2 1.3 ... </tableData> </table> </function> </coefficient> </axis> </aerodynamics> He does the same for drag and pitch moment. For sideforce, yaw, roll, he uses simpler stability derivatives.

aero/alpha-rad is a property. JSBSim has hundreds of built‑in properties (like velocities/u-fps , attitude/phi-rad ). You can also define custom properties under <property> . Part 4: The Control System – First Crash Alex adds controls:

import jsbsim fdm = jsbsim.FGFDMExec() fdm.load_model('x1') fdm['propulsion/engine[0]/running'] = 1 fdm['fcs/throttle-cmd-norm'] = 1.0 for t in range(1000): fdm.Run() if t == 200: fdm['fcs/elevator-cmd-norm'] = -0.3 # pitch up print(fdm['position/h-sl-ft'], fdm['attitude/theta-deg'])

Alex opens the drive. Inside: x1_fdm.xml , a blank JSBSim configuration file. No UI. Just XML.

Why? The PID gains were tuned for a Cessna, not the X‑1’s high‑lift wing.

Alex launches FlightGear: fgfs --fdm=jsbsim --aircraft=x1 . The X‑1 appears on the runway, virtual sun glinting. He takes off, and for the first time, the simulation looks and feels alive .