# 仿真

Simulation is a quick, easy, and most importantly, safe way to test changes to PX4 code before attempting to fly in the real world. It is also a good way to start flying with PX4 when you haven't yet got a vehicle to experiment with.

PX4 supports both Software In the Loop (SITL) simulation, where the flight stack runs on computer (either the same computer or another computer on the same network) and Hardware In the Loop (HITL) simulation using a simulation firmware on a real flight controller board.

Information about available simulators and how to set them up are provided in the next section. The other sections provide general information about how the simulator works, and are not required to use the simulators.

# 支持的仿真器

Gazebo

Supported Vehicles: Quad (Iris and Solo, Hex (Typhoon H480), Generic quad delta VTOL, Tailsitter, Plane, Rover, Submarine

FlightGear

A simulator that provides physically and visually realistic simulations. In particular it can simulate many weather conditions, including thunderstorms, snow, rain and hail, and can also simulate thermals and different types of atmospheric flows. Multi-vehicle simulation is also supported.

Supported Vehicles: Plane, Autogyro, Rover

JSBSim

A simulator that provides advanced flight dynamics models. This can be used to model realistic flight dynamics based on wind tunnel data.

jMAVSim A simple multirotor simulator that allows you to fly copter type vehicles around a simulated world.

AirSim

A cross platform simulator that provides physically and visually realistic simulations. 这个模拟器需要大量的资源，需要一台比这里描述的其他仿真器更强大的计算机。

Simulation-In-Hardware (SIH)

An alternative to HITL that offers a hard real-time simulation directly on the hardware autopilot. This simulator is implemented in C++ as a PX4 module directly in the Firmware code (opens new window).

Ignition Gazebo

Ignition Gazebo is derived from the popular robotics simulator Gazebo, featuring more advanced rendering, physics and sensor models.

Instructions for how to setup and use the simulators are in the topics linked above.

All simulators communicate with PX4 using the Simulator MAVLink API. This API defines a set of MAVLink messages that supply sensor data from the simulated world to PX4 and return motor and actuator values from the flight code that will be applied to the simulated vehicle. The image below shows the message flow.

A SITL build of PX4 uses SimulatorMavlink.cpp (opens new window) to handle these messages while a hardware build in HIL mode uses mavlink_receiver.cpp (opens new window). 这些端口是： All motors / actuators are blocked, but internal software is fully operational.

The messages are described below (see links for specific detail).

MAV_MODE:MAV_MODE_FLAG_HIL_ENABLED (opens new window) 不可用 使用模拟时的模式标志。 所有电机/执行器都被卡停，但内部软件可以完全正常运行。
HIL_ACTUATOR_CONTROLS (opens new window) PX4 至 Sim PX4 控制输出 （电机、执行器）。
HIL_SENSOR (opens new window) Sim 至 PX4 在 NED 体框架中以 SI 单位模拟 IMU 读数。
HIL_GPS (opens new window) Sim 至 PX4 模拟的 GPS RAW 传感器值。
HIL_OPTICAL_FLOW (opens new window) Sim 至 PX4 来自流量传感器的模拟光流 （例如 PX4FLOW 或光学鼠标传感器）。
HIL_STATE_QUATERNION (opens new window) Sim 至 PX4 包含实际的“仿真”无人机位置、姿态、速度等。 这可以记录并与 px4 的分析和调试估计进行比较 （例如，检查估计器在噪声 （仿真） 传感器输入中的工作情况）。
HIL_RC_INPUTS_RAW (opens new window) Sim 至 PX4 收到 RC 通道的 RAW 值。

By default, PX4 uses commonly established UDP ports for MAVLink communication with ground control stations (e.g. QGroundControl), Offboard APIs (e.g. MAVSDK, MAVROS) and simulator APIs (e.g. Gazebo). These ports are:

• PX4's remote UDP Port 14550 is used for communication with ground control stations. 期望外接 APIs 监听此端口上的连接。 QGroundControl listens to this port by default.
• PX4's remote UDP Port 14540 is used for communication with offboard APIs. 期望 GCS 将侦听此端口上的连接。 QGroundControl默认侦听此端口。 :::
• The simulator's local TCP Port, 4560, is used for communication with PX4. PX4 侦听此端口，仿真器应通过向该端口广播数据来启动通信。

# SITL 仿真环境

The diagram below shows a typical SITL simulation environment for any of the supported simulators.

The different parts of the system connect via UDP, and can be run on either the same computer or another computer on the same network.

• PX4 uses a simulation-specific module to connect to the simulator's local TCP port 4560. Simulators then exchange information with PX4 using the Simulator MAVLink API described above. SITL 和模拟器上的 PX4 可以在同一台计算机上运行，也可以在同一网络上运行不同的计算机。 :::note Simulators can also use the microRTPS bridge (PX4-FastRTPS Bridge) to directly interact with PX4 (i.e. via UORB topics rather than MAVLink). This approach may used by Gazebo multi-vehicle simulation. :::
• PX4 uses the normal MAVLink module to connect to ground stations and external developer APIs like MAVSDK or ROS
• Ground stations listen to PX4's remote UDP port: 14550
• External developer APIs listen to PX4's remote UDP port: 14540. For multi-vehicle simulations, PX4 sequentially allocates a separate remote port for each instance from 14540 to 14549 (additional instances all use port 14549).
• PX4 defines a number of local UDP ports (14580,18570), which are sometimes used when networking with PX4 running in a container or virtual machine. These are not recommended for "general" use and may change in future.
• A serial connection may be used to connect Joystick/Gamepad hardware via QGroundControl.

If you use the normal build system SITL make configuration targets (see next section) then both SITL and the Simulator will be launched on the same computer and the ports above will automatically be configured. You can configure additional MAVLink UDP connections and otherwise modify the simulation environment in the build configuration and initialisation files.

# 启动/构建 SITL 模拟

The build system makes it very easy to build and start PX4 on SITL, launch a simulator, and connect them. The syntax (simplified) looks like this:

make px4_sitl simulator[_vehicle-model]


A number of examples are shown below, and there are many more in the individual pages for each of the simulators:

# 启动固定翼机型的 Gazebo
make px4_sitl gazebo_plane

# 启动有光流的Iris机型的 Gazebo
make px4_sitl gazebo_iris_opt_flow

# 启动Iris（默认机型）的 JMavSim
make px4_sitl jmavsim


The simulation can be further configured via environment variables:

• PX4_ESTIMATOR：此变量配置要使用的估算器。 Possible options are: ekf2 (default), lpe (deprecated). 在运行模拟之前，可以通过 export PX4_ESTIMATOR=lpe 进行设置。

The syntax described here is simplified, and there are many other options that you can configure via make - for example, to set that you wish to connect to an IDE or debugger. For more information see: Building the Code > PX4 Make Build Targets.

# 以比实际时间更快的流速运行仿真

SITL can be run faster or slower than realtime when using jMAVSim or Gazebo.

The speed factor is set using the environment variable PX4_SIM_SPEED_FACTOR. For example, to run the jMAVSim simulation at 2 times the real time speed:

PX4_SIM_SPEED_FACTOR=2 make px4_sitl jmavsim


To run at half real-time:

PX4_SIM_SPEED_FACTOR=0.5 make px4_sitl jmavsim


You can apply the factor to all SITL runs in the current session using EXPORT:

export PX4_SIM_SPEED_FACTOR=2
make px4_sitl jmavsim


At some point IO or CPU will limit the speed that is possible on your machine and it will be slowed down "automatically". Powerful desktop machines can usually run the simulation at around 6-10x, for notebooks the achieved rates can be around 3-4x.

To avoid PX4 detecting data link timeouts, increase the value of param COM_DL_LOSS_T proportional to the simulation rate. For example, if COM_DL_LOSS_T is 10 in realtime, at 10x simulation rate increase to 100.

# Lockstep Simulation

PX4 SITL and the simulators (jMAVSim or Gazebo) have been set up to run in lockstep. What this means is that PX4 and the simulator wait on each other for sensor and actuator messages, rather than running at their own speeds.

Lockstep makes it possible to run the simulation faster or slower than realtime, and also to pause it in order to step through code.

The sequence of steps for lockstep are:

1. The simulation sends a sensor message HIL_SENSOR (opens new window) including a timestamp time_usec to update the sensor state and time of PX4.
2. PX4 receives this and does one iteration of state estimation, controls, etc. and eventually sends an actuator message HIL_ACTUATOR_CONTROLS (opens new window).
3. The simulation waits until it receives the actuator/motor message, then simulates the physics and calculates the next sensor message to send to PX4 again.

The system starts with a "freewheeling" period where the simulation sends sensor messages including time and therefore runs PX4 until it has initialized and responds with an actuator message.

# Disable Lockstep Simulation

The lockstep simulation can be disabled if, for example, SITL is to be used with a simulator that does not support this feature. In this case the simulator and PX4 use the host system time and do not wait on each other.

To disable lockstep in PX4, run make px4_sitl_default boardconfig and set the BOARD_NOLOCKSTEP "Force disable lockstep" symbol which is located under toolchain.

To disable lockstep in Gazebo, edit the model SDF file (opens new window) and set <enable_lockstep>false</enable_lockstep>.

To disable lockstep in jMAVSim, remove -l in sitl_run.sh (opens new window), or make sure otherwise that the java binary is started without the -lockstep flag. <!-- Relevant lines in sitl_run.sh are:

# Start Java simulator

"! -->

# 启动脚本

Scripts are used to control which parameter settings to use or which modules to start. They are located in the ROMFS/px4fmu_common/init.d-posix (opens new window) directory, the rcS file is the main entry point. See System Startup for more information.

# HITL 仿真环境

With Hardware-in-the-Loop (HITL) simulation the normal PX4 firmware is run on real hardware. The HITL Simulation Environment in documented in: HITL Simulation.

# 操纵杆／手柄集成

For setup information see the QGroundControl User Guide:

# 相机模拟

PX4 supports capture of both still images and video from within the Gazebo simulated environment. This can be enabled/set up as described in Gazebo > Video Streaming.

The simulated camera is a gazebo plugin that implements the MAVLink Camera Protocol (opens new window). PX4 connects/integrates with this camera in exactly the same way as it would with any other MAVLink camera:

1. TRIG_INTERFACE must be set to 3 to configure the camera trigger driver for use with a MAVLink camera :::tip In this mode the driver just sends a CAMERA_TRIGGER (opens new window) message whenever an image capture is requested. For more information see Camera. :::

2. PX4 必须在 GCS 和（模拟器）MAVLink Camera 之间转发所有摄像机命令。 You can do this by starting MAVLink with the -f flag as shown, specifying the UDP ports for the new connection.

mavlink start -u 14558 -o 14530 -r 4000 -f -m camera


注解

More than just the camera MAVLink messages will be forwarded, but the camera will ignore those that it doesn't consider relevant. :::

The same approach can be used by other simulators to implement camera support.

# 在远程服务器上运行仿真

It is possible to run the simulator on one computer, and access it from another computer on the same network (or on another network with appropriate routing). This might be useful, for example, if you want to test a drone application running on real companion computer hardware running against a simulated vehicle.

This does not work "out of the box" because PX4 does not route packets to external interfaces by default (in order to avoid spamming the network and different simulations interfering with each other). Instead it routes traffic internally - to "localhost".

There are a number of ways to make the UDP packets available on external interfaces, as outlined below.

The mavlink-router (opens new window) can be used to route packets from localhost to an external interface.

To route packets between SITL running on one computer (sending MAVLink traffic to localhost on UDP port 14550), and QGC running on another computer (e.g. at address 10.73.41.30) you could:

• Start mavlink-router with the following command:
mavlink-routerd -e 10.73.41.30:14550 127.0.0.1:14550

• Use a mavlink-router conf file.
[UdpEndpoint QGC]
Mode = Normal
Port = 14550

[UdpEndpoint SIM]
Mode = Eavesdropping
Port = 14550


The mavlink module routes to localhost by default, but you can enable UDP broadcasting of heartbeats using its -p option. Any remote computer on the network can then connect to the simulator by listening to the appropriate port (i.e. 14550 for QGroundControl).

UDP

broadcasting provides a simple way to set up the connection when there is only one simulation running on the network. Do not use this approach if there are multiple simulations running on the network (you might instead publish to a specific address).

This should be done in an appropriate configuration file where mavlink start is called. For example: /ROMFS/px4fmu_common/init.d-posix/px4-rc.mavlink (opens new window).

# 修改外部广播的配置

The mavlink module routes to localhost by default, but you can specify an external IP address to stream to using its -t option. The specified remote computer can then connect to the simulator by listening to the appropriate port (i.e. 14550 for QGroundControl).

This should be done in various configuration files where mavlink start is called. For example: /ROMFS/px4fmu_common/init.d-posix/px4-rc.mavlink (opens new window).

# SSH 通道

SSH tunneling is a flexible option because the simulation computer and the system using it need not be on the same network.

You might similarly use VPN to provide a tunnel to an external interface (on the same network or another network).

One way to create the tunnel is to use SSH tunneling options. The tunnel itself can be created by running the following command on localhost, where remote.local is the name of a remote computer:

ssh -C -fR 14551:localhost:14551 remote.local


The UDP packets need to be translated to TCP packets so they can be routed over SSH. The netcat (opens new window) utility can be used on both sides of the tunnel - first to convert packets from UDP to TCP, and then back to UDP at the other end.

QGC

must be running before executing netcat.

On the QGroundControl computer, UDP packet translation may be implemented by running following commands:

mkfifo /tmp/tcp2udp
netcat -lvp 14551 < /tmp/tcp2udp | netcat -u localhost 14550 > /tmp/tcp2udp


On the simulator side of the SSH tunnel, the command is:

mkfifo /tmp/udp2tcp
netcat -lvup 14550 < /tmp/udp2tcp | netcat localhost 14551 > /tmp/udp2tcp


The port number 14550 is valid for connecting to QGroundControl or another GCS, but should be adjusted for other endpoints (e.g. developer APIs etc.).

The tunnel may in theory run indefinitely, but netcat connections may need to be restarted if there is a problem.

The QGC_remote_connect.bash (opens new window) script can be run on the QGC computer to automatically setup/run the above instructions. The simulation must already be running on the remote server, and you must be able to SSH into that server.