最新PX4xROS2保姆级仿真部署教程来了!

在无人机系统开发领域,一套兼具高可靠性、强扩展性与真实物理仿真的集成框架,已成为开发者的“标配”。本教程基于PX4(v1.16)、ROS2 Humble、Gazebo Sim8,并整合XRCE-DDS通信机制,带你快速搭建闭环控制系统,实现仿真到实机的无缝迁移。教程覆盖下述内容从环境安装到完整仿真部署的全流程讲解,是名副其实的“保姆级”指南。建议先三连码住(点赞、分享、推荐),方便后续慢慢学习。

Ubuntu22.04+ROS2humble+PX4v1.16+Gazebo Sim8+XRCE_DDS+官方控制实例

系统优势:
1. PX4 (v1.16)
最新版LTS引入更强任务航线引擎、统一参数树与丰富机型预设,性能与可维护性双升级。2. ROS2
基于DDS的分布式实时通信架构,让感知、规划、控制节点即插即用。

3. XRCE-DDS
仅75KB的轻量协议栈,实现飞控 MCU 与 ROS 2 话题的毫秒级互联。
4.适用人群
无人机/机器人初学者、科研人员与工程开发者等。

01 环境准备

安装Ubuntu22.04

1. 从Ubuntu官网获取系统文件iso:https://releases.ubuntu.com/jammy/
2. 参考安装教程:https://monojson.com/s/Ct09d
3. 注意:安装后只升级到 22.04 最新补丁,不需要点升级到 24.04。

安装ROS2 Humble

1. 按照官方教程安装

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. 参考国内“小鱼一键安装”:_https://monojson.com/s/0Nlgo_3\. 安装完成后,用经典小乌龟验证ROS2是否安装完成,打开两个终端,依次输入下面命令:

ros2 run turtlesim turtlesim_node
ros2 run turtlesim turtle_teleop_key

确保鼠标在第二个打开的终端内,这时使用键盘的方向键便可以控制小乌龟移动,正常情况如下图所示,即表示ROS2安装完成。

安装PX4(v1.16)

1. 首先安装一些必备组件
打开终端依次安装,如果提示“Do you want to continue\? [Y/n]”输入y(表示yes)继续安装。

  • 安装 Python 3 的包管理工具 pip(下载需要)sudo apt install python3-pip

  • 安装 Git 版本控制工具(下载代码需要)sudo apt install git

  • 固定empy版本为3.3.4pip3 uninstall empypip3 install empy==3.3.4

2. 部署PX4
打开终端确保是在home目录下:输入命令并回车

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

这样会下载PX4及其子模块,如下图显示PX4开始下载,home下出现PX4文件夹。

这个过程需要的时间可能有点长,耐心等待……

下载完后,确认是否所有子模块下载完毕,继续运行下面命令:

#下载完成后进入文件夹
cd PX4-Autopilot
#再次输入子模块下载来检查之前子模块是否下载全
git submodule update --init –recursive

若下载已完成,执行该命令不会有任何输出;如仍有未下载的子模块,则会自动开始补全。重复执行,直至终端无显示,表示 PX4 及其全部子模块已成功获取,如下图所示。

新开终端,在home目录下,输入下述命令,开始PX4的脚本自动安装部署:

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

安装完成后,查看版本,PX4目前最新版本为v1.16.0-rc1。

cd PX4-Autopilot/
git describe --tags

3. 仿真部署
新建终端,输入下述命令:

#需要在PX4-Autopilot目录下运行
cd PX4-Autopilot
#开始make运行仿真
make px4_sitl gz_x500

先显示编译,紧接着显示PX4,并自动打开Gazebo Sim显示仿真无人机,即表示PX4仿真部署成功。

有个小事项在终端中显示:pxh> WARN [health_and_arming_checks] Preflight Fail: No connection to the ground control station,表示警告没有连接地面站。

安装QGC地面站

建议在最新版PX4飞控中配合QGroundControl等地面站使用,便于实时监控飞行状态并加速后期调试开发。

下载及安装链接:https://monojson.com/s/8tuGW

如下图所示三步完成QGC地面站安装运行

1. 新建终端,按照官方手册运行命令

2. 点击上面官方下载及安装链接,开始下载QGC,并将下载文件放置桌面。3. 打开桌面终端,赋予QGC权限,运行下述命令:

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

4.地面站默认选择ok,即QGC安装完成。

  1. 不喜欢用命令运行,可以在图标右键选择Run as a Program就可以运行。6. 打开QGC,开始PX4仿真。
cd PX4-Autopilot
make px4_sitl gz_x500

终端显示:INFO [commander] Ready for takeoff!表示PX4已准备完成。

安装XRCE_DDS

XRCE-DDS是DDS(Data Distribution Service)的轻量级实现,专为资源受限的嵌入式系统或IoT设备设计。XRCE-DDS由OMG(Object Management Group)发布的DDS-XRCE标准规范支撑,是一种高效的发布-订阅通信中间件,支持资源受限设备与 DDS 网络中的全功能计算节点进行通信。本教程后面会使用XRCE_DDS来作为信息传递中间层,连接PX4飞控。

安装教程如下:

1. 在home目录下新建终端,输入下面命令下载XRCE_DDS

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

2.注意:XRCE_DDS当前代码版本为v3.0.1,与本教程使用的PX4版本(v1.16)相对应。若后续PX4升级,XRCE_DDS也需同步适配对应版本。下方代码基于当前教程推荐的版本配置。

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

3. 源代码下载完毕后,进行编译。

#进入DDS目录下
cd Micro-XRCE-DDS-Agent
#新建文件夹build:将会存放编译后的文件
mkdir build
#进入build文件夹
cd build
#执行cmake:配置和生成构建文件
cmake ..
#执行make:编译源码,生成目标文件/可执行文件
make
#安装:安装生成的目标文件到系统目录
sudo make install
#安装后,更新系统动态链接库缓存
sudo ldconfig /usr/local/lib/
#到这里正常情况XRCE_DDS便安装完成

4.验证是否安装完成,先打开地面站运行PX4仿真,新建终端运行XRCE_DDS,输入下述命令:

MicroXRCEAgent udp4 -p 8888

正常运行后如下图,会发现飞控终端相比之前会多显示:

INFO  [uxrce_dds_client] successfully created rt/fmu/

表示XRCE_DDS和飞控正常连接并生成ROS2话题ROS2与ROS1不同,其常用命令也不一样,常用命令可以参考下述链接:https://monojson.com/s/jIqjz
5. 新建终端,输入下述命令,即可列出当前ROS 2环境下的全部话题。

 ros2 topic list

若XRCE_DDS成功连接PX4飞控,终端将显示以 /fmu/ 开头的话题:/fmu/out/*:表示飞控向外发布的信息/fmu/out/battery_status_v1:飞控发送的电池状态;**/fmu/in/* 表示可向飞控发送指令的话题,如 /fmu/in/vehicle_command:**用于发送模式切换等控制命令。此时虽可使用ros2 topic echo\<话题> 查看话题内容,但由于相关msg类型尚未配置,数据暂无法正确显示,这将是下一步的工作重点。

02 创建PX4_msgs_ROS2空间

这一步主要用于部署px4_msgspx4_ros_com,为后续ROS2与PX4通信提供所需的消息接口(msg 类型)。1. 在主目录(home)下新开一个终端,执行以下命令:

#创建工作空间路径

mkdir -p ~/ws_ros2/src/

#进入src文件夹,将下面的源码下载至src

cd ~/ws_ros2/src/

#下载两个官方源代码,第一个是px4_msgs,第二个是PX4官方提供的控制示例代码
git clone https://github.com/PX4/px4_msgs.git

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

2. 检查版本号

git tag -l --sort=-creatordate

3. 编译源代码

#进入ws_ros2目录下
cd ~/ws_ros2
#colcon编译
colcon build

正常编译完成如下图所示:

4. 设置环境变量,确保之后程序运行能找到对应PX4_msgs等

#将环境变量加入.bashrc中
echo "source ~/ws_ros2/install/setup.bash" >> ~/.bashrc

5. 关闭所有终端,再次打开地面站,新建终端运行PX4仿真,运行XRCE_DDS连接飞控,列出全部ROS2话题,这时候再echo话题就可以获取到话题数据了。

ROS话题

1.输入话题(/fmu/in/…)

这些是 PX4 接收的指令或数据,通常由外部系统(如ROS2)发布。

2.输出话题(/fmu/out/…)

这些是 PX4 发布的状态或数据,供外部系统(如 ROS2)订阅。

这些话题对于后面二次开发非常重要,后期基本是通过程序订阅话题获取无人机信息,以及发布控制命令到对应ROS2话题来控制无人机,实现相应控制飞行等。

03 官方控制实例及代码讲解

PX4官方提供了基于ROS2的Offboard模式控制实例,适合初学者学习控制流程,也为二次开发提供了良好起点。

运行控制实例

确保PX4仿真,包含地面站和XRCE_DDS连接均已启动。新开终端,运行如下命令:

ros2 run px4_ros_com offboard_control

执行后,无人机将自动解锁,旋转 90° 并上升至 5 米高度悬停。

命令及源代码解析

要弄清楚为什么会有这样的飞行效果,就需要查看背后的代码逻辑。官方提供这个示例,正是为了帮助开发者上手实践,了解如何基于新版PX4实现控制操作。

命令含义

运行的命令是:

ros2 run px4_ros_com offboard_control

命令结构:

ros2 run <package_name> <executable_name>

ros2 run:ROS2 中用于运行指定包的可执行文件的命令。px4_ros_com:PX4与ROS2通信的包名,提供了与 PX4 飞控交互的节点和接口。offboard_control:可执行文件名,用于实现Offboard模式控制的节点。

源代码解析

运行的代码在px4_ros_com推荐使用vscode来查看源码VS code下载链接:https://code.visualstudio.com/Download
在px4_ros_com 目录下新建终端,输入以下命令并回车:

code .

该命令可快速使用VS Code打开当前目录,便于浏览与编辑源码。

点击左边搜索图标,直接全局搜索节点offboard_control。

在CMakeLists.txt中可看到节点的编译声明,其中关联的源文件为offboard_control.cpp。
路径:src/examples/offboard/offboard_control.cpp表明执行ros2 run px4_ros_com offboard_control实际运行的就是该文件中的程序。该示例由PX4开发团队的Mickey Cowden和Nuno Marques编写。

代码功能概述

该代码实现了一个ROS2节点,用于控制PX4飞控进入Offboard 模式,并使无人机悬停在指定位置(如 0, 0, -5 米,偏航角 180°)。控制流程通过发布 PX4专用消息来完成。
专用消息:OffboardControlMode,TrajectorySetpoint,VehicleCommand.
代码结构分析

本文引用的源码来自 PX4 官方开源项目(BSD 3-Clause License),仅供学习与交流。
原始代码仓库:https://github.com/PX4/PX4-Autopilot
官方文档:https://docs.px4.io/

1. 头文件引入

#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 消息:引入了PX4的ROS2消息类型,用于与飞控通信。ROS2核心库:引入rclcpp,用于创建 ROS2 节点。其他工具:引入chrono和iostream,用于时间处理和调试输出。

2. 命名空间与别名

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

std::chrono:用于处理时间相关操作。px4_msgs::msg:简化 PX4 消息类型的使用。

3. 类定义:OffboardControl

class OffboardControl : public rclcpp::Node

继承自 rclcpp::Node,表示这是一个 ROS2 节点。

成员变量:

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_:定时器,用于周期性执行回调函数。
offboard_control_mode_publisher_:发布 OffboardControlMode 消息。
trajectory_setpoint_publisher_:发布 TrajectorySetpoint 消息。
vehicle_command_publisher_:发布 VehicleCommand 消息。
offboard_setpoint_counter_:计数器,用于跟踪已发布的消息数量。


构造函数:

OffboardControl() : Node("offboard_control")
  • 初始化节点名称为 offboard_control。

  • 创建三个发布者:

offboard_control_mode_publisher_:发布Offboard 控制模式。trajectory_setpoint_publisher_:发布轨迹设定点。vehicle_command_publisher_:发布飞控命令。

  • 初始化计数器 offboard_setpoint_counter_ 为0。

  • 创建一个定时器,每 100 毫秒执行一次回调函数 timer_callback。

定时器回调函数:

auto timer_callback = [this]() -> void {
  • 每 100 毫秒执行一次。

  • 如果计数器达到 10,则:发送命令使飞控进入 Offboard 模式、发送命令解锁飞控。

  • 发布OffboardControlMode和TrajectorySetpoint 消息。

  • 计数器递增,直到达到 11。

成员函数:

  • arm():发送解锁飞控的命令。

  • disarm():发送锁定飞控的命令。

  • publish_offboard_control_mode():发布 OffboardControlMode 消息。

  • publish_trajectory_setpoint():发布 TrajectorySetpoint 消息。

  • publish_vehicle_command():发布 VehicleCommand 消息。

4. 成员函数实现
arm()

void OffboardControl::arm()
  • 发布VehicleCommand 消息,命令飞控解锁。

disarm()

void OffboardControl::disarm()
  • 发布VehicleCommand 消息,命令飞控锁定。

publish_offboard_control_mode()

void OffboardControl::publish_offboard_control_mode()
  • 发布OffboardControlMode 消息,启用位置控制,禁用其他控制模式。

publish_trajectory_setpoint()

void OffboardControl::publish_trajectory_setpoint()
  • 发布TrajectorySetpoint 消息,设置目标位置为 (0, 0, -5) 米,偏航角为 180 度。

publish_vehicle_command()

void OffboardControl::publish_vehicle_command(uint16_t command, float param1, float param2)
  • 发布VehicleCommand 消息,用于发送解锁、进入 Offboard 模式等命令。

5. 主函数:

int main(int argc, char *argv[])
  • 初始化ROS2节点。

  • 创建OffboardControl 节点并运行。

  • 关闭ROS2。

代码逻辑总结

  • 节点启动后,每 100 毫秒执行一次定时器回调。
  • 在回调中:a. 发布 OffboardControlMode 和 TrajectorySetpoint 消息。b. 当计数器达到 10 时,发送命令使飞控进入 Offboard 模式并解锁。

  • 飞控接收消息后,开始按照设定的轨迹(悬停在 5 米高度)飞行。

  • 节点持续运行,直到手动终止。

该示例代码演示了如何通过ROS2话题/fmu/in/vehicle_command等发送控制指令:切换飞行模式、解锁电机,并设置目标位置和偏航角。
开发者可在此基础上快速拓展动作逻辑,例如:无旋转起飞 → 飞至 (10, 10, 10) → 悬停 1 分钟 → 自动返航并降落。官方之所以提供该示例,正是为了让二次开发者在现成框架上便捷地实现此类自定义飞行流程。

04 Prometheus

Prometheus是由阿木实验室开源的一套完整无人机系统平台,面向自主飞行任务,提供从底层控制到任务规划的一体化解决方案。随着 ROS 从 ROS1 向 ROS2 迁移,以及对低延迟高性能通信的需求提升,Prometheus V3 版本应运而生。

  • 技术升级:系统全面迁移至Ubuntu 22.04 +ROS2 Humble,通信中间件采用 XRCE-DDS,并同步推出基于 MAVROS2的适配版本;

  • 开发友好:相比PX4原生示例,Prometheus 提供更丰富的控制接口与飞行模式,便于直接部署至实机进行二次开发;

  • 开源可用:所有功能与教程已开源发布,配套手册详尽,支持从 PX4 部署到任务控制的完整链路。

  • 官方手册地址:https://monojson.com/s/VfGMF

如果您有感兴趣的技术话题,请在留言区告诉我们!关注阿木实验室,更多技术干货不断更新! 开发遇到棘手难题可以上阿木官方论坛:bbs.amovlab.com
有工程师亲自解答10000+无人机开发者和你共同进步!