
写这套环境搭建的博客之前我已经不止一次被问到同一个问题“我想在Ubuntu上搞ROS2和PX4的仿真到底怎么一步步搭起来为什么我照着网上教程做总是卡住”说实话这活儿本身不复杂但坑是真的多。版本不对、依赖炸了、Gazebo黑屏、桥接不上每个环节都能让人折腾一整天。这篇文章就基于我自己在Ubuntu 22.04上从零搭通ROS2和PX4仿真环境的完整经历把每一步的原理、命令和踩坑点都摊开讲清楚希望能帮你少走点弯路。这套环境能做什么简单说你可以在Gazebo里起飞一架仿真无人机然后在ROS2里订阅它的位姿、发布控制指令跑通完整的“感知—决策—控制”闭环。对于做无人机算法开发、SLAM导航、集群协同或者单纯想入门ROS2和PX4二次开发的朋友来说这是性价比最高的起步方案。不需要买硬件不怕炸机随时可以重置环境非常适合前期调算法和验证逻辑。我这篇文章会按照我自己实际操作的时间线来组织从版本选型和系统准备开始然后是ROS2 Humble的安装验证接着是PX4源码获取与编译再到Gazebo仿真启动与底层验证最后是ROS2和PX4的桥接通信。每个环节都会说明为什么这么做以及我实际遇到过的问题。内容比较长建议收藏后按章节操作。1. 版本选型与思路拆解为什么是Ubuntu 22.04、ROS2 Humble和特定PX4版本很多新手上来就装最新的东西结果装完发现互相不兼容这是环境搭建失败的最大原因。我先说一下我的选型逻辑。1.1 版本匹配关系是前提不是首选Ubuntu 22.04对应ROS2的发行版是Humble Hawksbill。这个版本是2022年5月发布的LTS长期支持版本支持到2027年。ROS2的每个发行版都绑定特定的Ubuntu版本乱配就会出各种诡异的依赖冲突。需要注意的是更新版本的ROS2 Jazzy对应的是Ubuntu 24.04如果你的系统是22.04就别想着装Jazzy了依赖关系会让你痛不欲生。至于PX4我用的是v1.13.3稳定版。为什么不选最新的main分支因为main分支的代码迭代太快工具链要求变化也快很多时候今天能编译明天就报错。v1.13系列的PX4对Ubuntu 22.04和ROS2 Humble的适配已经非常成熟网上资料也最多遇到问题更容易查到解决方案。PX4和ROS2的通信方式也需要提前想清楚。PX4从v1.13开始重点推进用uXRCE-DDSMicro XRCE-DDS作为和ROS2通信的桥梁也就是PX4-ROS2-Bridge这套方案。传统上大家用的MAVROS也可以但MAVROS的本质是把MAVLink协议转换成ROS2话题多了一层转换时延更高而且配置繁琐。所以我最终选择了PX4官方推荐的uXRCE-DDS方案这也是当前和未来PX4开发的主流方向。1.2 硬件建议与系统准备仿真环境下CPU单核性能和内存大小是瓶颈。我的建议是最起码4核CPU、8GB内存起步16GB内存会比较舒服。Gazebo启动后会占用不少CPU资源如果你还要同时跑Rviz2和感知算法内存不够会直接卡到怀疑人生。显卡方面Gazebo Classic用的是OpenGL渲染集成显卡也能凑合跑但独立显卡体验会好很多。系统准备阶段有两个事一定要做换源和装基础工具。Ubuntu 22.04的默认软件源在国内访问速度很慢建议换成国内镜像源。我用的清华源效果稳定。另外需要确保系统是全新安装或者至少没有乱七八糟的Python环境冲突因为ROS2和PX4的编译工具链对Python版本很敏感。提示如果你之前装过ROS1或者其他版本的ROS2建议先彻底清理干净再开始不然ROS2的apt源和Python包很容易冲突。清理方式不展开说了重点是/opt/ros下目录和~/.bashrc里相关环境变量都要删掉。1.3 换源操作与基础工具安装换源的操作网络上教程很多这里简单说下核心步骤。先把/etc/apt/sources.list备份然后替换为国内源的Ubuntu 22.04源配置。以清华源为例配置内容大致是把archive.ubuntu.com和security.ubuntu.com替换为mirrors.tuna.tsinghua.edu.cn。之后执行sudo apt update sudo apt upgrade确保系统软件包为最新。基础工具方面我建议先安装这些sudo apt update sudo apt upgrade -y sudo apt install -y git vim curl wget \ terminator \ net-tools \ python3-pip \ python3-venv \ cmake \ build-essential这里特别说明一下terminator是个终端模拟器支持分屏后面同时启动Gazebo、Rviz2、命令行工具时非常方便。python3-pip和python3-venv是因为后面前编译PX4固件和构建ROS2功能包时可能需要用到Python环境隔离。2. 一步一步装好ROS2 Humble安装、环境变量与验证ROS2 Humble的安装方式主要有三种从apt源安装二进制包、从源码编译安装、使用鱼香ROS一键安装脚本。我自己第一次用的是鱼香ROS的一键脚本确实方便但出了问题不好排查因为脚本封装太多。后来重新装系统后我改用apt官方源方式每一步都清清楚楚出问题也知道去哪查。这里只讲apt安装方式。2.1 配置ROS2软件源与安装桌面版先把ROS2的apt源加进系统。ROS2默认源在packages.ros.org如果你网络访问慢也可以配置清华的ROS源镜像。配置完成后执行sudo apt update sudo apt upgrade -y sudo apt install -y ros-humble-desktopros-humble-desktop会安装ROS2的核心功能、可视化工具Rviz2、demo节点、示例代码等对仿真开发来说已经够了。如果空间充足建议额外安装ros-humble-dev方便后面自己编写功能包时需要用的头文件和工具链。注意安装过程如果报错E: Unable to locate package ros-humble-desktop大概率是ROS2源没配好或者没有执行apt update。检查一下/etc/apt/sources.list.d/ros2.list的内容是否指向jammyUbuntu 22.04的代号别不小心用了其他版本的源。2.2 配置环境变量与自动加载安装完成后需要把ROS2的环境变量写进shell配置文件否则每次打开终端都要手动sourceecho source /opt/ros/humble/setup.bash ~/.bashrc source ~/.bashrc这里有个细节值得多说一句。ROS2默认使用DDS作为通信中间件如果局域网内有多个设备可能会因为多网卡或者多DDS实现冲突导致节点发现失败。如果你是单机仿真一般不需要额外配置但如果节点之间老是找不到对方可以在~/.bashrc里加一行export ROS_LOCALHOST_ONLY1强制只在本机通信。另外还需要安装colcon构建工具和rosdep依赖管理工具sudo apt install -y python3-colcon-common-extensions python3-rosdeprosdep用于自动解析功能包依赖后边构建工作空间时会用到。安装后需要初始化sudo rosdep init rosdep update如果你的网络环境无法直接访问rosdep的源可能需要配置代理或者使用镜像脚本这个属于网络层面的问题不展开了。2.3 用talker和listener验证ROS2是否可用ROS2装得对不对最直观的验证方式是跑起来看看节点能不能互相通信。打开一个终端启动talker节点ros2 run demo_nodes_cpp talker再开另一个终端启动listener节点ros2 run demo_nodes_py listener如果listener终端里能持续打印I heard: [Hello World: ...]说明ROS2的核心通信机制正常。我习惯验证完成后顺手再跑一把ros2 doctor这个命令会检查整个ROS2环境的健康状态包括环境变量、网络配置、RMW实现等。有问题它会给提示很实用。3. PX4开发环境搭建源码获取、依赖安装与编译PX4的仿真环境和ROS2不同它不是apt装的而是需要拉源码、装工具链自己编译。这个环节也是坑最多的地方我一条一条拆开说。3.1 获取PX4源码并处理好子模块PX4官方源码托管在GitHub上。获取源码的命令是git clone --recursive https://github.com/PX4/PX4-Autopilot.git这里有两个关键点。第一--recursive参数不能少因为PX4项目包含大量submodule子模块比如固件依赖的mavlink、px4_msgs等。如果忘记带这个参数编译时会报一堆缺少头文件的错误。如果已经clone了但忘了带递归参数也可以用git submodule update --init --recursive补救。第二clone完成后要切换到稳定分支。我用的命令是cd PX4-Autopilot git checkout v1.13.3 git submodule update --init --recursive切分支后再同步一次子模块确保和该版本匹配这一步很重要。很多人直接clone下来就用main分支过几天再拉代码突然编译不过大概率就是main分支工具链要求变了。3.2 运行官方依赖安装脚本PX4源码里带了一个自动安装依赖的脚本路径是Tools/setup/ubuntu.sh。运行方式bash ./Tools/setup/ubuntu.sh这个脚本会帮你安装编译PX4所需的全部工具链包括gcc-arm-none-eabi交叉编译器、ninja、gstreamer、MAVLink工具链、Gazebo等。脚本执行时间比较久而且中途可能需要输入密码因为有sudo操作建议盯在那里不要挂机离开太久。脚本跑完后可能会提示你重新登录或者重启系统因为某些环境变量比如PATH里加ARM编译器需要重新加载。我个人习惯是跑完脚本后直接重启一次省得后面踩莫名其妙的坑。注意脚本安装Gazebo时如果用的是apt-get install gazebo装的是旧版本或者依赖不全有可能会出问题。更稳妥的做法是先手动用sudo apt install gazebo ros-humble-gazebo-ros-pkgs装好ROS2版的Gazebo插件包再跑PX4的ubuntu.sh脚本这样Gazebo相关依赖会更完整。3.3 编译PX4固件并启动Gazebo仿真依赖全部就绪后开始编译。在PX4-Autopilot目录下执行make px4_sitl gazebo-classic这个命令做了两件事编译PX4固件的SITLSoftware In The Loop版本——也就是纯软件仿真模式以及启动Gazebo Classic仿真环境并加载默认的Iris四旋翼模型。首次编译时间比较久取决于CPU性能十几分钟到半小时都可能。编译输出的最后会看到类似这样的提示[100%] Linking CXX executable px4 SITL COMMAND: ./build/px4_sitl_default/bin/px4然后Gazebo Classic会弹出来里面有一架Iris四旋翼停在草地上。同时PX4的shell也会启动出现pxh提示符。如果Gazebo启动时黑屏或者加载不出模型八成是模型路径没设对。PX4的Gazebo模型存放在Tools/simulation/gazebo-classic/sitl_gazebo-classic/models目录下正常情况下启动脚本会自动设置GAZEBO_MODEL_PATH。如果模型加载不出来可以手动导出export GAZEBO_MODEL_PATH$PWD/Tools/simulation/gazebo-classic/sitl_gazebo-classic/models3.4 在PX4 Shell中做基础飞行验证PX4仿真跑起来后在pxh提示符下可以做基础操作验证。比如解锁电机并起飞commander takeoff这条命令会让无人机自动起飞到一定高度你可以切换到Gazebo的3D视图观察螺旋桨转动和飞行姿态。更常用的方式是从外部发送MAVLink指令来控制。在另一个终端里可以输入python3 Tools/simulation/gazebo-classic/sitl_gazebo-classic/scripts/jmavsim_run.sh不过这个脚本一般是用jmavsim仿真器的Gazebo Classic场景下不一定适用。我自己常用的外部控制方式是后续配合ROS2或者MAVSDK来做这里先在PX4 shell里验证一下就行。关于起飞测试我的经验是不要在commander takeoff后立刻再用commander land要等飞机稳定悬停几秒钟再说否则状态机容易混乱。4. 打通ROS2与PX4通信uXRCE-DDS桥接方案环境各自跑通了还不行ROS2和PX4之间必须能通信这才是做算法开发的关键。前面说了我选的方案是PX4官方推荐的uXRCE-DDS也就是Micro XRCE-DDS通信桥。这套方案的核心是PX4固件作为DDS客户端ROS2这边运行一个Micro XRCE-DDS Agent作为服务端两者之间通过UDP或者串口通信实现话题数据的双向传输。4.1 安装Micro XRCE-DDS AgentMicro XRCE-DDS Agent有现成的源码需要自己编译。我使用的流程git clone https://github.com/eProsima/Micro-XRCE-DDS-Agent.git cd Micro-XRCE-DDS-Agent mkdir build cd build cmake .. make -j$(nproc) sudo make install编译完成后Agent可执行文件名为MicroXRCEAgent。安装到系统后启动方式有两种常用模式。最常用的是UDP模式MicroXRCEAgent udp4 -p 8888这条命令让Agent在UDP端口8888上监听等待PX4客户端的连接。4.2 配置PX4固件启动uXRCE-DDS客户端PX4固件默认并没有启动uXRCE-DDS客户端需要在PX4的启动参数里指定。最简单的方式是在pxh提示符下输入uxrce_dds_ns start但这样每次启动都要手动输入比较麻烦。更推荐的方式是在PX4的启动脚本里加入相关配置。PX4启动配置位于ROMFS/px4fmu_common/init.d-posix/rcS文件。这个文件是SITL模式下的系统初始化脚本。我需要在这个文件末尾加上uxrce_dds_ns start这样以后每次启动PX4 SITL都会自动启动DDS客户端。需要注意的是v1.13版本的PX4这个命令可能在pxh下是dds start不同版本命令略有差异。如果uxrce_dds_ns start报错找不到命令可以输入dds help查看当前版本支持的DDS命令。4.3 构建px4_ros_com功能包并启动桥接测试要让ROS2能拿到PX4的数据还需要在ROS2工作空间里配置px4_ros_com和px4_msgs两个功能包。px4_msgs是PX4消息定义px4_ros_com是桥接和ROS2交互的中间层。我是在PX4-Autopilot同级目录下创建了一个ROS2工作空间mkdir -p ~/ws_px4/src cd ~/ws_px4/src git clone https://github.com/PX4/px4_msgs.git git clone https://github.com/PX4/px4_ros_com.git cd ~/ws_px4 colcon build这里需要说明colcon build之前要确保src目录下还有ros2_px4_ws相关的依赖其实最简单的做法是px4_ros_com的README里面提到的依赖关系会通过rosdep解决。先装好依赖sudo apt install -y ros-humble-rosidl-default-generators ros-humble-rosidl-default-runtime然后在~/ws_px4下执行source /opt/ros/humble/setup.bash再执行colcon build。构建完成后source工作空间source ~/ws_px4/install/setup.bash接着验证通信链路。确保PX4 SITL和MicroXRCEAgent都在运行然后在ROS2终端里订阅PX4的位姿话题ros2 topic echo /fmu/out/vehicle_attitude如果桥接成功这个终端会持续输出飞机的姿态四元数信息roll、pitch、yaw对应的四元数分量。这个信息证明PX4的仿真数据确确实实通过DDS桥接到了ROS2。4.4 测试从ROS2发布控制指令到PX4能接收数据只是单向打通还要能反向控制。PX4在DDS模式下通过/fmu/in/offboard_control_mode和/fmu/in/trajectory_setpoint话题接收外部控制指令。一个简单的做法是运行px4_ros_com里的offboard控制例程。不过更轻量的验证方式是手动发布话题。先发布offboard控制模式ros2 topic pub --once /fmu/in/offboard_control_mode px4_msgs/msg/OffboardControlMode {timestamp: 0, position: true}然后发布速度设定点ros2 topic pub --rate 10 /fmu/in/trajectory_setpoint px4_msgs/msg/TrajectorySetpoint {timestamp: 0, position: [0.0, 0.0, -5.0]}同时需要在PX4 shell里执行commander mode offboard切换飞行模式。实测中这个过程需要PX4已经解锁。所以完整的顺序是先解锁再切offboard模式最后以10Hz频率持续发布设定点。注意设定点必须持续发布否则PX4会因丢失设定点而退出offboard模式。这套流程玩通了ROS2和PX4的通信链路就真正构建起来了。后面无论是写自定义控制器、跑路径规划、做视觉SLAM本质上都是在ROS2里订阅PX4状态、经过算法处理后再发回控制指令。5. 常见问题与排查技巧手把手解决我踩过的坑环境搭建过程中遇到的问题五花八门但归根结底主要集中在几个环节。我把实操中遇到的典型问题分类整理成速查表每个问题都附上排查思路和我实际使用的解决办法。问题现象可能原因解决办法colcon build报错找不到px4_msgs没有在PX4工作空间里link px4_msgs或没有先编译px4_msgs确认src目录包含px4_msgs并先单独编译colcon build --packages-select px4_msgsGazebo模型加载不出来GAZEBO_MODEL_PATH没设或者模型库不完整手动设置GAZEBO_MODEL_PATH并确认路径下有iris模型PX4编译报clang或arm-none-eabi-gcc找不到工具链安装不完整或PATH没更新重新运行bash Tools/setup/ubuntu.sh检查~/.profile中PATH配置MicroXRCEAgent启动后连接被拒绝UDP端口被占用或PX4客户端未启动检查8888端口占用netstat -anpROS2订阅/fmu/out/vehicle_attitude无数据DDS桥未打通或者Agent端和PX4端的IP/端口不匹配在Agent终端看是否有连接日志检查PX4使用的UDP端口是否和Agent的监听一致rosdep update超时或失败网络问题或rosdep源初始化有问题尝试设置代理或使用rosdep update --include-eol-distros忽略过时发行版错误Gazebo启动后无人机掉到地面以下物理引擎/地面模型冲突重启Gazebo服务或者删除~/.gazebo缓存后重新启动PX4 shell输入commander takeoff没反应未解锁或电量仿真参数异常先执行commander arm再执行commander takeoff编译PX4时内存不够导致进程被killswap空间不足扩大swap分区或者减少并行编译核数make px4_sitl gazebo-classic -j25.1 关于版本不匹配问题这是最隐蔽的坑。比如PX4 v1.13.3和px4_ros_com最新的main分支有时会因为消息定义字段不一致导致ROS2话题能连上但数据对不上。我的做法是px4_ros_com和px4_msgs也切换到和PX4固件版本匹配的分支。在px4_ros_com目录下git checkout v1.13.3如果提示分支不存在就去GitHub上查看该版本或者直接使用main分支通常和v1.13兼容性还行。但最稳妥的还是固定版本一一对应。另一个版本相关的坑是Python 3.10的兼容性。Ubuntu 22.04默认Python是3.10有些老的PX4辅助脚本或ROS2包可能在3.10下有兼容问题。遇到报错时先看是不是Python语法或库兼容问题别急着改代码优先找对应版本的新版工具。5.2 关于环境变量和source顺序问题这个坑很普遍。如果你同时source了ROS1的setup.bash或PX4的setup脚本会导致环境混乱。我的做法是~/.bashrc里只source以下内容按顺序来source /opt/ros/humble/setup.bash source ~/ws_px4/install/setup.bash这两个必须放在其他source之后。如果发现ROS2命令执行异常先在终端里看echo $ROS_DISTRO如果不是humble说明环境变量加载顺序出问题了。另外还有个小技巧把MicroXRCEAgent的启动命令写进一个脚本或者直接加到启动项里省得每次都需要手动开终端启动。我自己习惯是写一个简单的start_sim.sh脚本依次启动Agent、PX4、Gazebo这样整个仿真环境一键拉起不用反复敲命令。5.3 关于性能优化问题Gazebo仿真非常消耗CPU资源。我的经验是如果电脑配置一般可以减少Gazebo的渲染负担。几个有效手段第一减少仿真频率。PX4的SITL仿真频率默认是250Hz这个频率意味着PX4内部在高速模拟传感器输出和飞控运算。如果没有必要可以在启动时通过SYS_MC_EST_RATE和SIM_RATE_HZ参数调低。例如在pxh提示符下param set SIM_RATE_HZ 100调低仿真频率会降低Gazebo的计算压力但也会降低仿真精度。日常验证算法逻辑没问题但如果你在调滤波器或者频率比较敏感的算法建议保持默认。第二关闭其他模型和插件。Gazebo默认加载了一些传感器插件如果不需要可以在PX4的模型sdf文件里注释掉。但这种方法会影响PX4对传感器的感知不建议新手动。第三如果主要是做ROS2算法验证可以考虑不启动Gazebo直接使用PX4的无头仿真模式只跑逻辑不渲染。启动命令是make px4_sitl none这种模式下PX4照样运行但没有3D画面资源占用小了很多。缺点是看不到飞机状态只能通过日志和终端输出判断。5.4 一个容易忽略的小问题模型初始坐标Gazebo里仿真无人机默认起飞点在原点。如果你想要在指定经纬度起飞比如在城市的某个位置测试飞行逻辑可以在启动PX4前设置环境变量export PX4_HOME_LAT31.2304 export PX4_HOME_LON121.4737 export PX4_HOME_ALT0.0这组变量会覆盖默认起飞点。我常用这个方法在特定场景下测试比如模拟高楼间飞行或者在同一个离线地图里做多机协同测试时给每架飞机指定不同的初始位置。6. 后续扩展方向与个人心得环境跑通只是开始。以这套配置为基础你可以做的事情很多。接上Rviz2可视化订阅/fmu/out/vehicle_attitude和/fmu/out/vehicle_local_position就能实时查看飞机状态配合Nav2做自主导航或者接入YOLO等目标检测算法做视觉跟踪整个链路都是通的。我个人实际使用中的体会是这套环境最宝贵的地方在于它完全是软件闭环可以反复验证各种极端工况。我曾经在Gazebo里模拟GPS丢失的场景调了一周的故障检测逻辑这在真机上试又要场地又要安全员成本高得多。仿真环境出了问题随时重置完全不用心疼飞机。最后再分享一个小技巧如果你要在多台机器上复现这套环境建议在装好PX4依赖后做一次系统快照或者写一份自己的安装脚本把所有步骤固化。我后来重装过两次系统都是靠脚本十分钟搞定基础环境这比网上任何教程都靠谱。这套环境搭建完后面无论是学习PX4源码架构、写ROS2节点还是做上层决策算法都有了稳固的底子。接下来就好好享受调代码的过程吧。