Flight Simulator with SysML - SysFly. Integrating FlightGear, SysML v1 Simulation, FMI/FMU (Dymola), HiL

This project demonstrates a hardware-in-the-loop (HiL) flight-simulation testbench in which an executable SysML model in CATIA Magic verifies its requirements against a high-fidelity flight dynamics model running in FlightGear. A Python bridge mediates between the two tools and an Arduino UNO R4 joystick, performing byte-order translation between the little-endian UDP frames exchanged with CATIA Magic FMUs and the big-endian Generic Protocol expected by FlightGear, and arbitrating the active control source between CATIA Magic and Joystick on a freshness window so that the human pilot and the model can share the same aircraft without modification on either side.

The model includes an Aircraft block whose value properties mirror the simulator state through binding connectors and an Automatic Takeoff state machine The result is a closed-loop verification pipeline in which model-based requirements such as "airspeed shall reach at least 55 knots before rotation" are checked against an industry-grade flight simulator, while still allowing the engineer to grab a stick and fly the same aircraft when the model is paused.

Demo:

https://youtu.be/Mz8-IUq-hDw

 

 

Flying a SysML Model

When you write a state machine that says "rotate at 55 knots", how do you know it actually does? You can stare at the diagram, but a diagram doesn't fly. So I wired one up to a real flight simulator and let it fly itself.

Solution architecture

The setup (see instructions at the end) is four pieces of software talking to each other over loopback: FlightGear runs a Cessna 172P at San Francisco International. CATIA Magic holds the executable SysML model — an Aircraft block with value properties for altitude, airspeed, throttle, elevator, and the rest, plus a state machine that progresses Idle → TakeoffRoll → Rotate → InitialClimb → LevelOff → Cruise driven entirely by change events on the value properties. A small Python bridge translates between them: little-endian floats from the model's UDP_Sender FMU become big-endian floats on FlightGear's Generic Protocol input, and vice versa for telemetry coming back. And an Arduino UNO R4 WiFi with a thumbstick shield joins the local network, broadcasts a UDP beacon so the bridge can find it, and feeds joystick frames over TCP when nobody else is driving.

The interesting bit is the source-arbitration. The bridge keeps a 1.5-second freshness window on the model's command vector. While the state machine is writing values, the model wins. The instant the simulation pauses, the joystick takes over - no flag, no toggle, just "whoever's actually moving the controls". You can stop the takeoff sequence mid-rotation, fly manually for a minute, then resume the model and it picks back up.

Requirements describing aircraft take off conditions

Eleven requirements are wired into the model with Satisfy links — "throttle shall be greater than 0.95 during takeoff roll", "pitch shall be between 5 and 15 degrees during initial climb", and so on. Each is bound to one of the Aircraft block's value properties, which is itself bound to a flow port and sender and receivver FMU's generated by DYMOLA FMU's send and receives data over UPD from to python bridge. So the requirement stasify status updates live in CATIA Magic. In flight: the airspeed gauge in the cockpit and the airspeed property in CATIA  Magic read the same value, ten times a second.

FMU's connected to aircraft logic block
Auto take off state machine
Auto sequence recording of take off

Total cost: the Arduino board (about 25 EUR), a thumbstick shield (about 10 EUR), and an evening of Python. Total stack: free open-source simulator, the SysML modeler you already have, and roughly 400 lines of glue. 

Use Cases of the solution

File-share paragraph

Installation and setup guide

 

Flight Simulator HiL — project bundle. Everything you need to fly a SysML model against FlightGear: the Python bridge (TripleBridge.py), the Arduino joystick firmware (JoisticBidirectionaAPmode.ino), the FlightGear Generic Protocol XML files (flight-controls.xml, flight-state.xml),  the launcher batch file (LaunchFlightGear.bat), and a 5-page setup guide PDF. Open the PDF first; it walks through the install of FlightGear (one winget command), Python, Arduino IDE, and CATIA Magic, then through the run sequence and the most common gotchas. Edit the WiFi SSID and password at the top of the .ino before flashing the board, and you are airborne in under an hour from a clean machine.