Skip to content

Language

Currency

Latest PX4 x ROS2 Step-by-Step Simulation Deployment Tutorial

by AMOVLAB 04 Jul 2025 0 Comments

In the field of UAV system development, an integrated framework that combines high reliability, strong scalability and real physical simulation has become the "standard configuration" for developers. This tutorial is based on PX4 (v1.16), ROS2 Humble, Gazebo Sim8, and integrates the XRCE-DDS communication mechanism to help you quickly build a closed-loop control system and achieve seamless migration from simulation to real machine. The tutorial covers the following content and explains the entire process from environment installation to complete simulation deployment. It is worthy of its name.“step-by-step” guide. It is recommended to keep it in three consecutive numbers (like, share, recommend) first, so that you can learn slowly later.

Ubuntu22.04+ROS2humble+PX4v1.16+Gazebo Sim8+XRCE_DDS+official control example

System advantages:
1. PX4 (v1.16)
The latest version of LTS introduces a stronger mission route engine, unified parameter tree and rich aircraft model presets, and both performance and maintainability are upgraded.2. ROS2
The distributed real-time communication architecture based on DDS allows sensing, planning, and control nodes to be plug-and-play.

3. XRCE-DDS
A lightweight protocol stack of only 75KB realizes millisecond-level interconnection between flight controller MCU and ROS 2 topics.
4.Applicable people
UAV/robot beginners, scientific researchers and engineering developers, etc.

01 Environmental preparation

Install Ubuntu22.04

1. Obtain the system file iso from the Ubuntu official website:https://releases.ubuntu.com/jammy/
2. Refer to the installation tutorial:https://monojson.com/s/Ct09d
3. Note: After installation, only upgrade to the latest patch of 22.04. There is no need to click to upgrade to 24.04.

Install ROS2 Humble

1. Install according to the official tutorial

sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US. UTF-8
sudo update-locale LC_ALL=en_US. UTF-8 LANG=en_US. UTF-8
export LANG=en_US. UTF-8
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -y
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
sudo apt update && sudo apt upgrade -y
sudo apt install ros-humble-desktop
sudo apt install ros-dev-tools
source /opt/ros/humble/setup.bash && echo "source /opt/ros/humble/setup.bash" >> .bashrc

2. Refer to the domestic “Xiaoyu one-click installation”: _https://monojson.com/s/0Nlgo_3\. After the installation is completed, use the classic turtle to verify whether the ROS2 installation is complete, open two terminals, and enter the following commands in sequence:

ros2 run turtlesim turtlesim_node
ros2 run turtlesim turtle_teleop_key

Make sure that the mouse is in the second open terminal. At this time, you can use the keyboard's arrow keys to control the movement of the little turtle. The normal situation is as shown in the figure below, which means that the ROS2 installation is complete.

Install PX4(v1.16)

1. First install some necessary components
Open the terminal and install in sequence. If prompted "Do you want to continue\? [Y/n]", enter y (meaning yes) to continue the installation.

  • Install the Python 3 package management tool pip (required for download) sudo apt install python3-pip

  • Install the Git version control tool (required to download the code) sudo apt install git

  • Fixed empy version to 3.3.4pip3 uninstall empypip3 install empy==3.3.4

2. Deploy PX4
Open the terminal and make sure it is in the home directory: enter the command and press Enter

git clone https://github.com/PX4/PX4-Autopilot.git --recursive

This will download PX4 and its submodules. The following figure shows that PX4 starts to download, and the PX4 folder appears under home.

This process may take a long time, please be patient...

After downloading, confirm whether all sub-modules have been downloaded and continue running the following command:

# Enter the folder after the download completes
cd PX4-Autopilot
# Run the submodule download command again to confirm all submodules were downloaded
git submodule update --init –recursive

If the download is completed, there will be no output when executing this command; if there are still undownloaded submodules, completion will start automatically. Repeat the execution until there is no display on the terminal, which means that PX4 and all its sub-modules have been successfully obtained, as shown in the figure below.

Open a new terminal and enter the following command in the home directory to start the automatic installation and deployment of PX4 scripts:

bash ./PX4-Autopilot/Tools/setup/ubuntu.sh

After the installation is complete, check the version. The latest version of PX4 is v1.16.0-rc1.

cd PX4-Autopilot/
git describe --tags

3. Simulation deployment
Create a new terminal and enter the following command:

# Run this in the PX4-Autopilot directory
cd PX4-Autopilot
# Start the simulation with make
make px4_sitl gz_x500

Compilation is displayed first, then PX4 is displayed, and Gazebo Sim is automatically opened to display the simulated UAV, which means that the PX4 simulation deployment is successful.

There is a small item displayed in the terminal: pxh> WARN [health_and_arming_checks] Preflight Fail: No connection to the ground control station, indicating that the warning is not connected to the ground control station.

Install QGCground control station

It is recommended to use the latest version of PX4flight controller with ground control stations such as QGroundControl to facilitate real-time monitoring of flight status and accelerate later debugging and development.

Download and installation link:https://monojson.com/s/8tuGW

Complete the installation and operation of QGCground control station in three steps as shown in the figure below.

1. Create a new terminal and run the command according to the official manual

2. Click the official download and installation link above to start downloading QGC and place the downloaded file on the desktop. 3. Open the desktop terminal, grant QGC permissions, and run the following command:

chmod +x ./QGroundControl-x86_64. AppImage
./QGroundControl-x86_64. AppImage  (or double click)

4. The ground control station defaults to OK, which means the QGC installation is completed.

  1. If you don't like to run it with a command, you can right-click on the icon and select Run as a Program to run it. 6. Open QGC and start PX4 simulation.
cd PX4-Autopilot
make px4_sitl gz_x500

The terminal displays: INFO [commander] Ready for takeoff! indicating that PX4 is ready.

Install XRCE_DDS

XRCE-DDS is a lightweight implementation of DDS (Data Distribution Service), specially designed for resource-constrained embedded systems or IoT devices. XRCE-DDS is supported by the DDS-XRCE standard specification released by OMG (Object Management Group). It is an efficient publish-subscribe communication middleware that supports resource-constrained devices to communicate with full-featured computing nodes in the DDS network. Later in this tutorial, XRCE_DDS will be used as the information transfer intermediate layer to connect to the PX4flight controller.

The installation tutorial is as follows:

1. Create a new terminal in the home directory and enter the following command to download XRCE_DDS

git clone https://github.com/eProsima/Micro-XRCE-DDS-Agent.git

2.Notice: The current code version of XRCE_DDS is v3.0.1, which corresponds to the PX4 version (v1.16) used in this tutorial. If PX4 is upgraded in the future, XRCE_DDS will also need to adapt to the corresponding version simultaneously. The code below is based on the version configuration recommended by the current tutorial.

cd Micro-XRCE-DDS-Agent/
git describe --tags

3. After the source code is downloaded, compile it.

# Enter the DDS directory
cd Micro-XRCE-DDS-Agent
# Create the build folder for compiled files
mkdir build
# Enter the build folder
cd build
# Run cmake to configure and generate build files
cmake ..
# Run make to compile the source code and generate targets/executables
make
# Install the generated targets into the system directories
sudo make install
# After installation, update the system dynamic-linker cache
sudo ldconfig /usr/local/lib/
# At this point, XRCE-DDS should be installed

4. To verify whether the installation is complete, first open the ground control station to run PX4 simulation, create a new terminal and run XRCE_DDS, and enter the following command:

MicroXRCEAgent udp4 -p 8888

After normal operation, as shown below, you will find that the flight controller terminal will display more than before:

INFO  [uxrce_dds_client] successfully created rt/fmu/

Indicates that XRCE_DDS and flight controller are connected normally and generate ROS2 topic. ROS2 is different from ROS1, and its common commands are also different. For common commands, you can refer to the following link:https://monojson.com/s/jIqjz
5. Create a new terminal and enter the following command to list all topics in the current ROS 2 environment.

 ros2 topic list

If XRCE_DDS successfully connects to the PX4flight controller, the terminal will display /fmu/ Starting topic:/fmu/out/*: Represents the information released by the flight controller /fmu/out/battery_status_v1: Battery status sent by flight controller state;/fmu/in/* Represents a topic that can send instructions to the flight controller, such as /fmu/in/vehicle_command: Used to send control commands such as mode switching. Although you can use ROS2 topic echo\<topic> to view the topic content, the data cannot be displayed correctly because the relevant msg type has not been configured yet. This will be the focus of the next step.

02 Create PX4_msgs_ROS2 space

This step is mainly used for deployment px4_msgs and px4_ros_com, providing the required message interface (msg type) for subsequent communication between ROS2 and PX4. 1. Open a new terminal in the home directory (home) and execute the following command:

# Create the workspace path

mkdir -p ~/ws_ros2/src/

# Enter the src folder and download the source code below into src

cd ~/ws_ros2/src/

# Download two official repositories: px4_msgs and PX4's control example code
git clone https://github.com/PX4/px4_msgs.git

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

2. Check version number

git tag -l --sort=-creatordate

3. Compile source code

# Enter the ws_ros2 directory
cd ~/ws_ros2
# Build with colcon
colcon build

Normal compilation is completed as shown in the figure below:

4. Set environment variables to ensure that the corresponding PX4_msgs, etc. can be found when the program is run.

# Add the environment variable to .bashrc
echo "source ~/ws_ros2/install/setup.bash" >> ~/.bashrc

5. Close all terminals, open the ground control station again, create a new terminal and run PX4 simulation, run XRCE_DDS to connect to the flight controller, list all ROS2 topics, and then echo the topic to get the topic data.

ROS topic

1. Enter the topic (/fmu/in/…)

These are instructions or data received by the PX4, usually issued by an external system such as ROS2.

2. Output topic (/fmu/out/…)

These are state or data published by PX4 for external systems (such as ROS2) to subscribe to.

These topics are very important for subsequent custom development. In the later stage, the program basically subscribes to topics to obtain UAV information, and issues control commands to the corresponding ROS2 topics to control the UAV and achieve corresponding control of flight, etc.

03 Official control examples and code explanations

PX4 officially provides an Offboard mode control example based on ROS2, which is suitable for beginners to learn the control process and also provides a good starting point for custom development.

Run control instance

Ensure that PX4 simulation, including ground control station and XRCE_DDS connections are started. Open a new terminal and run the following command:

ros2 run px4_ros_com offboard_control

After execution, the UAV will automatically unlock, rotate 90° and rise to a height of 5 meters to hover.

Command and source code analysis

To figure out why there is such a flying effect, you need to look at the code logic behind it. The official provides this example to help developers get started and understand how to implement control operations based on the new version of PX4.

Command meaning

The command to run is:

ros2 run px4_ros_com offboard_control

Command structure:

ros2 run <package_name> <executable_name>

ros2 run: Command in ROS2 to run the executable of a specified package.px4_ros_com: The package name for communication between PX4 and ROS2, providing nodes and interfaces for interacting with the PX4 flight controller.offboard_control: Executable file name, used to implement the node controlled by Offboard mode.

Source code analysis

The running code is in px4_ros_com. It is recommended to use vscode to view the source code VS code download link:https://code.visualstudio.com/Download
Create a new terminal in the px4_ros_com directory, enter the following command and press Enter:

code .

This command can quickly use VS Code to open the current directory for easy browsing and editing of source code.

Click the search icon on the left to directly search for the node offboard_control globally.

The compilation declaration of node can be seen in CMakeLists.txt, and the associated source file is offboard_control.cpp。
Path: src/examples/offboard/offboard_control.cpp indicates that executing ROS2 run px4_ros_com offboard_control actually runs the program in this file. This sample was written by Mickey Cowden and Nuno Marques of the PX4 development team.

Overview of code functionality

This code implements a ROS2 node to control the PX4flight controller to enter Offboard mode and make the UAV hover at the localization location (such as 0, 0, -5 meters, yaw angle 180°). Control flow is accomplished by publishing PX4-specific messages.
Special messages: OffboardControlMode, TrajectorySetpoint, VehicleCommand.
Code structure analysis

The source code cited in this article comes from the PX4 official open-source project (BSD 3-Clause License) and is for learning and communication only.
Original code repository:https://github.com/PX4/PX4-Autopilot
Official documentation:https://docs.px4.io/

1. Header file introduction

#include <px4_msgs/msg/offboard_control_mode.hpp>
#include <px4_msgs/msg/trajectory_setpoint.hpp>
#include <px4_msgs/msg/vehicle_command.hpp>
#include <px4_msgs/msg/vehicle_control_mode.hpp>
#include <rclcpp/rclcpp.hpp>
#include <stdint.h>
#include <chrono>
#include <iostream>

PX4 message: The ROS2 message type of PX4 is introduced for communication with the flight controller. ROS2 core library: introduce rclcpp for creating ROS2 nodes. Other tools: Introduce chrono and iostream for time processing and debugging output.

2. Namespaces and aliases

using namespace std::chrono;
using namespace std::chrono_literals;
using namespace px4_msgs::msg;

std::chrono: used to handle time-related operations. px4_msgs::msg: Simplify the use of PX4 message types.

3. Class definition: OffboardControl

class OffboardControl : public rclcpp::Node

Inherited from rclcpp::Node, indicating that this is a ROS2 node.

Member variables:

rclcpp::TimerBase::SharedPtr timer_;
rclcpp::Publisher<OffboardControlMode>::SharedPtr offboard_control_mode_publisher_;
rclcpp::Publisher<TrajectorySetpoint>::SharedPtr trajectory_setpoint_publisher_;
rclcpp::Publisher<VehicleCommand>::SharedPtr vehicle_command_publisher_;
std::atomic<uint64_t> timestamp_;   //!< common synced timestamped
uint64_t offboard_setpoint_counter_;   //!< counter for the number of setpoints sent
timer_: timer used to execute callback functions periodically.
offboard_control_mode_publisher_: publishes OffboardControlMode messages.
trajectory_setpoint_publisher_: publishes TrajectorySetpoint messages.
vehicle_command_publisher_: publishes VehicleCommand messages.
offboard_setpoint_counter_: counter used to track the number of published messages.


Constructor:

OffboardControl() : Node("offboard_control")
  • The initial node name is offboard_control.

  • Create three publishers:

offboard_control_mode_publisher_: Publish Offboard control mode. trajectory_setpoint_publisher_: Publish trajectory set points. vehicle_command_publisher_: Publish flight controller command.

  • Initialize the counter offboard_setpoint_counter_ to 0.

  • Create a timer that executes the callback function timer_callback every 100 milliseconds.

Timer callback function:

auto timer_callback = [this]() -> void {
  • Executed every 100 milliseconds.

  • If the counter reaches 10, then: send a command to put the flight controller into Offboard mode, send a command to unlock the flight controller.

  • Post OffboardControlMode and TrajectorySetpoint messages.

  • The counter is incremented until it reaches 11.

Member functions:

  • arm(): Send the command to unlock the flight controller.

  • disarm(): Send a command to lock the flight controller.

  • publish_offboard_control_mode(): Publish OffboardControlMode message.

  • publish_trajectory_setpoint(): Publish TrajectorySetpoint message.

  • publish_vehicle_command(): Publish VehicleCommand message.

4. Member function implementation
arm()

void OffboardControl::arm()
  • Publish the VehicleCommand message to command the flight controller to unlock.

disarm()

void OffboardControl::disarm()
  • Publish a VehicleCommand message to order the flight controller to lock.

publish_offboard_control_mode()

void OffboardControl::publish_offboard_control_mode()
  • Publish the OffboardControlMode message to enable position control and disable other control modes.

publish_trajectory_setpoint()

void OffboardControl::publish_trajectory_setpoint()
  • Publish a TrajectorySetpoint message, setting the target position to (0, 0, -5) meters and the yaw angle to 180 degrees.

publish_vehicle_command()

void OffboardControl::publish_vehicle_command(uint16_t command, float param1, float param2)
  • Publish the VehicleCommand message to send commands such as unlocking and entering Offboard mode.

5. Main function:

int main(int argc, char *argv[])
  • Initialize the ROS2 node.

  • Create the OffboardControl node and run it.

  • Shut down ROS2.

Code logic summary

  • After the node starts, a timer callback is executed every 100 milliseconds.
  • In the callback: a. Post the OffboardControlMode and TrajectorySetpoint messages. b. When the counter reaches 10, send a command to make the flight controller enter Offboard mode and unlock it.

  • After receiving the message, the flight controller starts flying according to the set trajectory (hovering at a height of 5 meters).

  • The node continues to run until manually terminated.

This sample code demonstrates how to pass a ROS2 topic/fmu/in/vehicle_commandWait to send control instructions: switch flight mode, unlock the motors, and set the target position and yaw angle.
Developers can quickly expand action logic on this basis, for example: take off without rotation → fly to (10, 10, 10) → hover for 1 minute → automatically return and land. The official reason for providing this example is to allow secondary developers to easily implement such customized flight processes on ready-made frameworks.

04 Prometheus

Prometheus is a complete UAV system platform developed by AMOVLABopen-source. It provides an integrated solution from bottom-level control to mission planning for autonomous flight missions. With the migration of ROS from ROS1 to ROS2 and the increasing demand for low-latency and high-performance communication, Prometheus V3 version came into being.

  • Technology upgrade: The system is fully migrated to Ubuntu 22.04 +ROS2 Humble, the communication middleware uses XRCE-DDS, and an adapted version based on MAVROS2 is simultaneously launched;

  • Development-friendly: Compared with PX4 native examples, Prometheus provides richer control interfaces and flight modes, making it easy to deploy directly to real machines for custom development;

  • Open-source is available: All functions and tutorials have been released by open-source, and the supporting manual is detailed and supports a complete link from PX4 deployment to mission control.

  • Official manual address:https://monojson.com/s/VfGMF

Leave a comment

All blog comments are checked prior to publishing

Thanks for subscribing!

This email has been registered!

Shop the look

Choose Options

Recently Viewed

Edit Option
Back In Stock Notification
Terms & Conditions
What is Lorem Ipsum? Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Why do we use it? It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
this is just a warning
Login
Shopping Cart
0 items