Hardware in the Loop Simulation Setup

Hardware in the loop simulation (HIL or HITL) means to feed simulated sensor data to the autopilot and to return its control outputs into the simulation.

The simulation is optimized for USB connections. Do not attempt to perform HIL with a (low bandwidth) radio connection.

Supported Simulators

  • XPlane 10 (planes only)
  • FlightGear 3.x (planes only)
  • jMAVSim (multicopters only)
  • Python JSBSim wrapper (planes only)


  • Download the latest technology preview 2.x version of QGroundControl: Downloads
  • Officially supported: Download / Install XPlane (Windows/MacOS/Linux) from the XPlane Website
  • Alternative without support: Download / Install FlightGear (Windows/MacOS/Linux) from the FlightGear Website

Local network proxies can interfere with the communication between QGroundControl and the flight simulator. If your autopilot changes into HIL mode successfully but does not follow the simulator, try turning your proxy off


Just connect FMUv1.7 or Pixhawk (FMUv2.0) via microUSB and select it, click connect in QGroundControl.


jMAVSim is a Java based 3D simulation and visualisation engine for multicopters: jMAVSim.


X-Plane is a very accurate flight simulator which supports fixed wing models. Only XPlane 10 is officially supported and tested, but (untested) legacy support for XPlane 9 is available in QGroundControl.

USB Dongle Driver

For DVD-less devices (like the Macbook Air) XPlane offers an USB key. The driver for Windows / Linux / MacOS is available here.

Airplane Models

NOTE: We do not support multi rotor HIL with XPlane, as its update rate is not enough to allow stable flight. Please use jMAVSim instead.

Airplane Setup

Open the X-Plane installation directory, and copy the HILStar file to:

  • XPlane
    • Aircraft
      • HILStar17f

Then start X-Plane. In the main menu, select Aircraft → Open Aircraft. Choose the HILStar17f, then in the bottom left click on “Open Aircraft”.

Data Inputs and Output Settings

X-Plane needs a number of communication settings. Open Settings → Data Input & Output. For X-Plane 9 users: X-Plane 9 data settings. Check all the checkboxes below:

For HILS with quadrotor, enable 25: Throttle command.

IP Settings

On the IP screen of X-Plane (Settings → Net Connections), set the UDP data port to 49005 as in the picture below. QGroundControl uses port 49000 to send/receive data. The complete port setup is:

  • Port 49000: X-Plane port (from X-Plane to QGC: 49000 → 49005)
  • Port 49005: QGroundControl port (from QGC to X-Plane: 49005 → 49000)

This screen also contains info about incoming and outgoing data traffic

Simulation Update Rate Settings

The X-Plane simulation (physics) usually runs at the graphical frame rate. For small models like RC aircraft higher rates are needed. Open the menu at Settings → Operations & Warnings and increase the rate as shown below:

X-Plane rate settings

Vehicle Setup

If you have a custom rc.txt file on your microSD card, please make sure to DELETE it before proceeding. Custom startup files are only intended for developers interested creating their own apps.

Connect the USB serial port (choose the right port in the menu in the top right of the toolbar, the baud rate doesn't matter). In the top-left toolbar go to CONFIG, then select AIRFRAME CONFIG on the left menu.

  • Click on the top left on the airplane icon and select HILStar (SIMULATION)
  • Click on the bottom right on apply and reboot
  • After the board rebooted (reboot beep), disconnect it from USB, reconnect it physically and reconnect in QGroundControl

Now calibrate your remote control, by following the assistant.

Interface via QGroundControl

Connect the USB serial port (choose the right port in the menu in the top right of the toolbar, the baud rate doesn't matter). In the top-left toolbar go to PROSIMULATION.

Click on File → Advanced Mode to enable per-widget title bars. Close all widgets you do not need to free space (close all not present on the screenshots below)

In the HIL Config Widget select X-Plane as your simulator (is the default selection). Click on connect.

Fly towards a Waypoint

Double-click locations on the map. The waypoint list in the bottom part will be populated. Adjust the altitude. Click on SET, then click on the onboard tab. You need to arm first:

  • Check that the status is HIL:MANUAL. If not, make sure that the XPlane widget indicates “Receiving from X-Plane at xx Hz”. If not, re-check your settings.
  • Press on the safety switch (if present) to get a double-blip. ENSURE THAT NO MOTOR IS CONNECTED TO YOUR SYSTEM!
  • Put the throttle stick of your remote control into the lower-right corner. The system status should change to armed. If not, switch to the flight view and enable the message pane to see why the system does refuse to arm

Assuming everything went fine and the system is armed, it will take off once you switch the remote control to AUTO. To do so, put the mode switch into the AUTO position. You can change the current waypoint in the onboard list view and you can edit and change the mission in-flight.

Flightgear Setup

with qGroundControl


Start qGroundControl. Connect the vehicle UART and select 230400 baud, no parity, 8 data bits, 1 stop bit. Activate the unmanned system list (if not already present) via the main menu Tool WidgetsSystem List.

Right click the system and select HIL - Hardware in the Loop.

A new HIL Config Widget should appear. If not: try the Tool Widgets menu

In the HIL Config Widget select Flightgear as your simulator.

Press “Start” in the HIL Config Widget to launch Flightgear. Follow the on screen instructions to install the special protocol which is needed for qgroundcontrol be able to talk to Flightgear. TerraSync (downloads detailed terrain and objects) is started in the background. Usually you should see detailed terrain in Flightgear after the second start.

Have the RC connected and the flight mode set to auto as Flightgear starts. If the mode is not in auto the px4 will detect RC loss and refuse to start.

Once Flightgear is running, activate the Flightgear window and Press F11. Make sure that all autopilots are set to off.

Check from time to time if all Flightgear autopilots are set to off by pressing F11. This step can save you a lot of time!

If you want to use an airframe different from the default options, just type the name into the airfame dropdown menu. Your aircraft model has to be either in the Aircraft folder of flightgear or in the Aircraft folder of qgroundcontrol at [path to qgc]/files/flightgear/Aircraft.

Mac OS

:!: The Mac OS instructions for Flightgear have not been verified yet - please check paths and spellings.

Drop Flightgear into the apps folder, as with any other app. Right-click the app and select “Browse Package contents”. Then create MAVLink.xml in folder


with content MAVLink.xml

Python HIL

The Python HIL does use JSBSim directly and does not require a flight simulator to execute. The source files for James Goppert's excellent sensor-level HIL interface are here:

Clone the repository:

git clone https://github.com/PX4/HIL

HIL modes

  • State-level HIL: tests the control and guidance systems.
  • Sensor-level HIL: tests the navigation system in addition to the control, and guidance systems. This requires a lot of data to be sent to the vehicle and a high baudrate.


sudo easy_install pexpect

Pymavlink is the python library required for running the runhil.py script, you can install it with easy install or pypi-install

If you are using a debian based system (e.g. Ubuntu), you can install using pypi-install so that it can be installed as debian package:

sudo apt-get install python-stdeb
pypi-install pymavlink

If you are using mac/ other unix systems:

sudo easy_install pymavlink

JSBSim is the C++ flight dynamics model. It can be built with cmake/ or autotools.

git clone git://git.code.sf.net/p/jsbsim/code jsbsim
cd jsbsim
./configure --prefix=/usr/local --exec-prefix=/usr/local
make -j8
# Installs to /usr/local/bin, which is an ok default for Debian and Homebrew/MacOS
# use 'sudo make install' if permission errors are reported.
make install

Troubleshooting: If typing 'JSBSim' ENTER does not fire up the JSBSim help, you can hack around the failed install by adding a symlink to your executables directory

ln -s $HOME/src/jsbsim/src/JSBSim /usr/local/bin/JSBSim


Python Script

This python script runhil.py is used for conducting HIL. Both sensor-level and state-level HIL are supported. You can view the runhil.py usage with:

runhil.py -h

A call to runhil.py might look like this:

./runhil.py --waypoints data/sf_waypoints.txt --master /dev/ttyUSB1 --gcs localhost:14550 --mode sensor


  • Load the given waypoints in data/sf_waypoints.txt, NOTE: QGC waypoints are not compatible with pymavlink currently, you simply need to change the version number in the file to 110 if it is 120
  • Connect to the px4 autopilot on usb port 1
  • Setup external ground station communication of localhost:14550 udp.
  • Mode sensor says do sensor-level hardware-in-the-loop (HIL), this can be set to state as well
GroundControl Interface

Note that the script defaults to opening a mavlink slave port on udp:14550, this is the default udp port for QGroundControl. If you start QGC, it should start communicating with runhil.py automatically.



Magnetometer measurement model doesn't depend on lat/lot yet.

Translations of this page:

Quick Links

QR Code: URL of current page