# Hardware in the Loop Simulation (HITL)

:::warning
HITL is [community supported and maintained](../simulation/community_supported_simulators.md).
It may or may not work with current versions of PX4.

See [Toolchain Installation](../dev_setup/dev_env.md) for information about the environments and tools supported by the core development team.
:::

Hardware-in-the-Loop (HITL or HIL) is a simulation mode in which normal PX4 firmware is run on real flight controller hardware.
This approach has the benefit of testing most of the actual flight code on the real hardware.

PX4 supports HITL for multicopters (using [jMAVSim](../sim_jmavsim/index.md) or [Gazebo Classic](../sim_gazebo_classic/index.md)) and VTOL (using Gazebo Classic).

For a comparison of HITL and SIH on hardware, see [Hardware Simulation](../simulation/hardware.md).

## HITL-Compatible Airframes {#compatible_airframe}

The set of compatible airframes vs simulators is:

| Airframe                                                                                                         | `SYS_AUTOSTART` | Gazebo Classic | jMAVSim |
| ---------------------------------------------------------------------------------------------------------------- | --------------- | -------------- | ------- |
| [HIL Quadcopter X](../airframes/airframe_reference.md#copter_simulation_hil_quadcopter_x)                        | 1001            | Y              | Y       |
| [HIL Standard VTOL QuadPlane](../airframes/airframe_reference.md#vtol_standard_vtol_hil_standard_vtol_quadplane) | 1002            | Y              |         |

## HITL Simulation Environment {#simulation_environment}

With Hardware-in-the-Loop (HITL) simulation the normal PX4 firmware is run on real hardware.
JMAVSim or Gazebo Classic (running on a development computer) are connected to the flight controller hardware via USB/UART.
The simulator acts as gateway to share MAVLink data between PX4 and _QGroundControl_.

::: info
The simulator can also be connected via UDP if the flight controller has networking support and uses a stable, low-latency connection (e.g. a wired Ethernet connection - WiFi is usually not sufficiently reliable).
For example, this configuration has been tested with PX4 running on a Raspberry Pi connected via Ethernet to the computer (a startup configuration that includes the command for running jMAVSim can be found in [px4_hil.config](https://github.com/PX4/PX4-Autopilot/blob/main/posix-configs/rpi/px4_hil.config)).
:::

The diagram below shows the simulation environment:

- A HITL configuration is selected (via _QGroundControl_) that doesn't start any real sensors.
- _jMAVSim_ or _Gazebo Classic_ are connected to the flight controller via USB.
- The simulator is connected to _QGroundControl_ via UDP and bridges its MAVLink messages to PX4.
- _Gazebo Classic_ and _jMAVSim_ can also connect to an offboard API and bridge MAVLink messages to PX4.
- (Optional) A serial connection can be used to connect Joystick/Gamepad hardware via _QGroundControl_.

![HITL Setup - jMAVSim and Gazebo Classic](../../assets/simulation/px4_hitl_overview_jmavsim_gazebo.svg)

## HITL vs SITL

SITL runs on a development computer in a simulated environment, and uses firmware specifically generated for that environment.
Other than simulation drivers to provide fake environmental data from the simulator the system behaves normally.

By contrast, HITL runs normal PX4 firmware in "HITL mode", on normal hardware.
The simulation data enters the system at a different point than for SITL.
Core modules like commander and sensors have HITL modes at startup that bypass some of the normal functionality.

In summary, HITL runs PX4 on the actual hardware using standard firmware, but SITL actually executes more of the standard system code.

## Setting up HITL

## Check if HITL is in Firmware

The module required for HITL ([`pwm_out_sim`](../modules/modules_driver.md#pwm-out-sim)) is not built into all PX4 firmware by default.

To check if the module is present on your Flight Controller:

1. Open QGroundControl
2. Open **Analyze Tools > Mavlink Console**.
3. Type the following command in the console:

   ```sh
   pwm_out_sim status
   ```

4. If the returned value is `nsh: pwm_out_sim: command not found`, then you don't have the module installed.

If `pwm_out_sim` is not present you will need to add it to the firmware in order to use HITL simulation.

### Adding HITL modules to the Firmware

Add the following key to the configuration file for your flight controller to include the required module (for an example see [boards/px4/fmu-v6x/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6x/default.px4board)).
Then re-build the firmware and flash it to the board.

```text
CONFIG_MODULES_SIMULATION_PWM_OUT_SIM=y
```

You can alternatively use the following command to launch a GUI configuration tool, and interactively enable them at the path: **modules > Simulation > pwm_out_sim**.
For example, to update fmu-v6x you would use:

```sh
make px4_fmu-v6x boardconfig
```

### PX4 Configuration

1. Connect the autopilot directly to _QGroundControl_ via USB.
2. Select Airframe
   1. Open **Setup > Airframes**
   2. Select a [compatible airframe](#compatible_airframe) you want to test.
      Then click **Apply and Restart** on top-right of the _Airframe Setup_ page.

3. Calibrate your [Manual Controller](../config/manual_control.md) (RC or Joystick), if needed.
4. Setup UDP
   1. Under the _General_ tab of the settings menu, uncheck all _AutoConnect_ boxes except for **UDP**.

      ![QGC Auto-connect settings for HITL](../../assets/gcs/qgc_hitl_autoconnect.png)

5. (Optional) Configure your manual controller priority and failsafe:
   - [Enable a mode in `COM_RC_IN_MODE` that enables and prioritises the controllers you want to use](../config/manual_control.md#px4-configuration).
     The default `RC or MAVLink keep first` should work if you plan to only have a Joystick (no RC).
   - You can set [NAV_RCL_ACT](../advanced_config/parameter_reference.md#NAV_RCL_ACT) to disable manual control loss failsafe while flying in a simulation.

   :::tip
   The _QGroundControl User Guide_ also has instructions on [Joystick](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/joystick.html) and [Virtual Joystick](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/settings_view/virtual_joystick.html) setup.
   :::

Once configuration is complete, **close** _QGroundControl_ and disconnect the flight controller hardware from the computer.

### Simulator-Specific Setup

Follow the appropriate setup steps for the specific simulator in the following sections.

#### Gazebo Classic

::: info
Make sure _QGroundControl_ is not running!
:::

1. Build PX4 with [Gazebo Classic](../sim_gazebo_classic/index.md) (in order to build the Gazebo Classic plugins).

   ```sh
   cd <PX4-Autopilot clone>
   DONT_RUN=1 make px4_sitl_default gazebo-classic
   ```

2. Open the vehicle model's sdf file (e.g. **Tools/simulation/gazebo-classic/sitl_gazebo-classic/models/iris_hitl/iris_hitl.sdf**).
3. Replace the `serialDevice` parameter (`/dev/ttyACM0`) if necessary.

   ::: info
   The serial device depends on what port is used to connect the vehicle to the computer (this is usually `/dev/ttyACM0`).
   An easy way to check on Ubuntu is to plug in the autopilot, open up a terminal, and type `dmesg | grep "tty"`.
   The correct device will be the last one shown.
   :::

4. Set up the environment variables:

   ```sh
   source Tools/simulation/gazebo-classic/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default
   ```

   and run Gazebo Classic in HITL mode:

   ```sh
   gazebo Tools/simulation/gazebo-classic/sitl_gazebo-classic/worlds/hitl_iris.world
   ```

5. Start _QGroundControl_.
   It should autoconnect to PX4 and Gazebo Classic.

#### jMAVSim (Quadrotor only)

::: info
Make sure _QGroundControl_ is not running!
:::

1. Connect the flight controller to the computer and wait for it to boot.
2. Run jMAVSim in HITL mode:

   ```sh
   ./Tools/simulation/jmavsim/jmavsim_run.sh -q -s -d /dev/ttyACM0 -b 921600 -r 250
   ```

   ::: info
   Replace the serial port name `/dev/ttyACM0` as appropriate.
   On macOS this port would be `/dev/tty.usbmodem1`.
   On Windows (including Cygwin) it would be the COM1 or another port - check the connection in the Windows Device Manager.
   :::

3. Start _QGroundControl_.
   It should autoconnect to PX4 and jMAVSim.

## Fly an Autonomous Mission in HITL

You should be able to use _QGroundControl_ to [run missions](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/fly_view/fly_view.html#missions) and otherwise control the vehicle.
