新闻详情

新闻详情

首页 / 资讯中心 / 详情

Ubuntu 20.04下PX4+Gazebo+QGC多机仿真编队从零到三机实战

发布时间:2026/9/25 1:16:28来源:尧图网络
Ubuntu 20.04下PX4+Gazebo+QGC多机仿真编队从零到三机实战
1. 为什么多机仿真值得折腾以及这套组合到底解决了什么问题单机仿真跑通之后很多人会卡在同一个地方想让三架、五架甚至十架无人机同时起飞、编队、避障结果要么是 Gazebo 里模型互相穿模要么是 QGC 只认到一架要么是 PX4 实例之间抢端口直接崩掉。这不是你操作有问题而是单机仿真的默认配置压根没考虑多实例共存这件事。Ubuntu 20.04 PX4 Gazebo QGC 这套组合本质上是在一台机器上模拟出多个独立的飞控实例每个实例有自己的 MAVLink 端口、自己的传感器数据流、自己的 Gazebo 模型命名空间。QGC 作为地面站通过不同的 UDP 端口同时连接这些实例你就能在一个界面里看到多架飞机的状态并分别下发指令。这套方案适合做编队算法验证、多机任务分配、集群控制策略测试也适合教学场景下让一个学生同时观察多机行为。我选择 Ubuntu 20.04 而不是 22.04原因很直接PX4 的某些版本在 20.04 上的依赖兼容性更成熟尤其是 Gazebo 9 和 Gazebo 11 的切换、ROS 版本的匹配20.04 踩的坑明显少。当然如果你已经上了 22.04也不是不能跑只是后面提到的某些依赖包名和路径需要微调。整套流程的核心逻辑是PX4 源码编译出可执行文件Gazebo 提供物理环境和模型渲染QGC 负责地面监控和指令下发而多机的关键就在于用不同的启动脚本和端口配置把这三者串起来。下面我会从环境准备开始一步步拆到多机启动、QGC 配置、常见报错排查最后给几个我实际踩过的坑和偷懒技巧。2. 环境准备从裸机到能跑单机仿真的完整链路2.1 系统版本与基础依赖的取舍Ubuntu 20.04 装好之后第一件事不是急着 clone PX4 源码而是把基础工具链补齐。很多人跳过这一步后面编译报错再回头补浪费的时间更多。sudo apt update sudo apt install -y git cmake build-essential ninja-build \ python3-pip python3-dev python3-setuptools \ libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \ libgstreamer-plugins-good1.0-dev \ libeigen3-dev libopencv-dev这里有几个点值得说明。ninja-build是 PX4 推荐的构建工具比 make 快不少尤其是多机仿真时你可能会反复编译。libeigen3-dev和libopencv-dev是后续如果要做视觉相关开发时需要的现在装上省得后面再补。GStreamer 那一串是 Gazebo 渲染视频流用的不装的话 Gazebo 可能启动后黑屏或者直接报错退出。注意如果你用的是虚拟机务必确认开启了 3D 加速否则 Gazebo 界面会卡到无法操作。VMware 下需要在虚拟机设置里勾选“加速 3D 图形”VirtualBox 下要安装增强功能并启用 3D 加速。2.2 PX4 源码的版本选择与编译PX4 的版本选择直接影响后续多机仿真的难易程度。我实测下来v1.13 和 v1.14 系列在多机支持上比较稳定v1.12 虽然也能跑但某些启动脚本的参数命名不太一样。这里以 v1.14 为例。git clone https://github.com/PX4/PX4-Autopilot.git --recursive cd PX4-Autopilot git checkout v1.14.0 make px4_sitl gazebo最后这条命令会同时编译 PX4 并启动一个单机 Gazebo 仿真。第一次编译时间比较长取决于机器性能大概 10 到 30 分钟。编译完成后你应该能看到 Gazebo 界面里出现一架 iris 无人机同时终端里 PX4 的 nsh 控制台在滚动输出。如果这一步就报错大概率是依赖没装全。最常见的报错是cmake找不到某个包根据提示apt install对应的-dev包即可。另一个常见问题是 Python 包版本冲突尤其是empy和jinja2PX4 的Tools/setup/ubuntu.sh脚本其实已经帮你处理了大部分依赖如果你不想手动一个个装可以直接跑bash Tools/setup/ubuntu.sh这个脚本会自动安装所有需要的依赖包括 Gazebo。跑完之后重启终端再执行make px4_sitl gazebo。2.3 Gazebo 模型库的补充PX4 自带的 Gazebo 模型库只包含 iris、solo 等少数几种机型。如果你要做多机异构仿真比如固定翼加多旋翼混编就需要额外下载模型。git clone https://github.com/PX4/PX4-gazebo-models.git ~/.gazebo/models或者你也可以从 Gazebo 官方模型库下载hg clone https://bitbucket.org/osrf/gazebo_models ~/.gazebo/models模型放对位置很关键必须是~/.gazebo/models目录下每个模型一个文件夹里面包含model.config和model.sdf。放错位置 Gazebo 会报“找不到模型”的警告虽然不影响已有模型加载但你想插入新模型时就抓瞎了。2.4 QGC 的安装与版本匹配QGC 的安装相对简单官网下载 AppImage 或者 deb 包都行。但要注意版本匹配QGC 4.x 系列对 PX4 v1.14 的支持比较好QGC 3.x 虽然也能连但某些 MAVLink 消息解析可能有问题。chmod x QGroundControl.AppImage ./QGroundControl.AppImage第一次启动 QGC 时它会自动检测 UDP 端口 14550这是 PX4 单机仿真的默认 MAVLink 输出端口。如果你能看到 QGC 左上角显示“Connected”并且有飞行数据说明单机链路已经通了。这一步是后面多机配置的基础单机都连不上就别急着搞多机。3. 多机仿真的核心机制端口、命名空间与启动脚本3.1 多实例并存的底层逻辑单机仿真时PX4 启动一个实例占用 UDP 端口 14550 输出 MAVLink 数据Gazebo 加载一个 iris 模型。多机仿真时你需要启动多个 PX4 实例每个实例有不同的MAVLink 输出端口比如 14550、14560、14570QGC 分别连接这些端口Gazebo 模型命名空间比如 iris_0、iris_1、iris_2避免模型名冲突仿真世界中的初始位置每架飞机在不同的坐标点出生否则会叠在一起PX4 的启动脚本Tools/simulation/gazebo-classic/sitl_multiple_run.sh就是干这件事的。它接收一个参数指定飞机数量然后循环启动多个 PX4 实例每个实例的PX4_SIM_MODEL环境变量和ROS_NAMESPACE不同。3.2 启动脚本的关键参数拆解打开sitl_multiple_run.sh你会看到类似这样的逻辑for i in $(seq 0 $((N-1))); do px4_instance$i mavlink_port$((14550 i * 10)) ... done这里14550 i * 10意味着第一架飞机用 14550第二架用 14560第三架用 14570以此类推。QGC 需要分别添加这些端口的连接。Gazebo 模型的位置设置通常在Tools/simulation/gazebo-classic/sitl_gazebo-classic/models/iris/iris.sdf.jinja模板里通过{{ x }}、{{ y }}这样的变量注入。多机启动时脚本会为每个实例传入不同的坐标。3.3 手动启动多机的替代方案如果你不想用官方脚本或者需要更精细的控制可以手动启动。核心是设置环境变量# 第一架 export PX4_SIM_MODELiris export ROS_NAMESPACEiris_0 ./build/px4_sitl_default/bin/px4 -i 0 # 第二架 export PX4_SIM_MODELiris export ROS_NAMESPACEiris_1 ./build/px4_sitl_default/bin/px4 -i 1-i参数指定实例编号PX4 会根据这个编号自动计算 MAVLink 端口和 Gazebo 模型命名空间。手动启动的好处是你可以单独控制每个实例的启动顺序和参数调试时更方便。提示手动启动时Gazebo 需要先启动一个空的 world然后每个 PX4 实例通过gz model命令往 world 里插入模型。这个过程如果顺序不对会出现模型插入失败的情况。建议先启动 Gazebo再依次启动 PX4 实例。4. 从零跑通三机编队完整操作流程与验证4.1 启动三机仿真的具体命令假设你已经编译好了 PX4进入 PX4-Autopilot 目录执行./Tools/simulation/gazebo-classic/sitl_multiple_run.sh -n 3 -m iris-n 3表示三架飞机-m iris指定机型。脚本会自动启动 Gazebo 并加载三架 iris 模型同时启动三个 PX4 实例。启动完成后你会看到 Gazebo 界面里三架飞机停在不同的位置。终端里会有三个 PX4 nsh 控制台在输出日志。此时 Gazebo 的模型列表里应该能看到 iris_0、iris_1、iris_2 三个模型。4.2 QGC 多机连接配置打开 QGC进入 Application Settings - Comm Links手动添加三个 UDP 连接连接名称端口对应飞机UAV014550第一架UAV114560第二架UAV214570第三架添加完成后QGC 会自动连接这三个端口。你可以在 QGC 的飞行视图里看到三架飞机的图标分别标注为 Vehicle 1、Vehicle 2、Vehicle 3。点击不同的飞机图标可以切换当前控制的飞机。如果 QGC 只显示一架飞机检查端口是否被占用或者防火墙是否拦截了 UDP 包。Ubuntu 默认的 ufw 防火墙一般不会拦截本地 UDP但如果你手动配置过规则需要放行 14550-14570 范围。4.3 验证多机通信是否正常连接成功后在 QGC 的 MAVLink Inspector 里可以看到每个端口的消息流。切换到不同的飞机检查HEARTBEAT消息的system_id是否不同。正常情况下三架飞机的 system_id 分别是 1、2、3。另一个验证方法是让三架飞机同时起飞。在 QGC 里选中一架执行 Takeoff然后切换到另一架再执行 Takeoff。如果三架都能正常起飞并悬停说明多机链路完全打通。注意多机同时起飞时Gazebo 的物理计算量会显著增加。如果机器性能不够会出现仿真时间变慢、飞机响应延迟的情况。建议至少 16GB 内存、四核以上 CPU显卡支持 OpenGL 3.3 以上。4.4 编队飞行的简单实现三架飞机都能独立控制之后你可以尝试让它们飞一个简单的三角形编队。最直接的方法是在 QGC 里手动规划航点每架飞机设置不同的航点序列。但更高效的方式是用 MAVSDK 或者 ROS 写脚本控制。以 MAVSDK-Python 为例import asyncio from mavsdk import System async def fly_formation(): drones [] for port in [14550, 14560, 14570]: drone System() await drone.connect(system_addressfudp://:{port}) drones.append(drone) for i, drone in enumerate(drones): async for state in drone.core.connection_state(): if state.is_connected: break await drone.action.takeoff() await asyncio.sleep(5) # 设置不同航点 for i, drone in enumerate(drones): await drone.mission.start_mission() asyncio.run(fly_formation())这段代码的核心是分别连接三个端口然后对每个实例独立下发指令。实际编队算法会更复杂但通信框架就是这样。5. 踩坑实录多机仿真中最容易翻车的几个地方5.1 Gazebo 模型插入失败与命名冲突最常见的报错是 Gazebo 启动后只显示一架飞机或者三架飞机叠在同一个位置。前者通常是模型命名冲突后者是初始位置没设置对。模型命名冲突的根源在于iris.sdf.jinja模板里的model nameiris是硬编码的。多机启动时脚本会通过sed或者环境变量替换这个名称但如果替换失败三个实例都往 Gazebo 里插入同名模型Gazebo 只会保留第一个。排查方法启动后执行gz model --list看看模型列表里是不是只有 iris 而没有 iris_0、iris_1、iris_2。如果是检查启动脚本里的名称替换逻辑。初始位置问题更隐蔽。三架飞机如果都在 (0,0,0) 出生物理引擎会把它们挤开表现为飞机乱飞或者直接翻掉。正确的做法是在 SDF 模板里用pose标签设置不同的 x、y 坐标比如第一架在 (0,0,0)第二架在 (2,0,0)第三架在 (4,0,0)。5.2 QGC 连接不稳定与端口占用QGC 有时候能连上一架但连不上另外两架或者连接后频繁断开。第一个要检查的是端口是否被其他进程占用sudo lsof -i :14550 sudo lsof -i :14560 sudo lsof -i :14570如果某个端口被占用kill 掉对应进程再重启仿真。另一个原因是 QGC 的自动连接功能会干扰手动配置的连接建议在 Application Settings - General 里取消勾选“AutoConnect to the following devices”只保留手动添加的 UDP 连接。还有一种情况是 PX4 实例启动顺序不对。如果 QGC 在 PX4 实例还没完全启动时就尝试连接会连接失败并且不会自动重试。解决办法是先启动仿真等 Gazebo 里三架飞机都稳定显示后再打开 QGC。5.3 仿真时间不同步与物理引擎崩溃多机仿真时Gazebo 的物理计算量是单机的三倍以上。如果机器性能不足会出现仿真时间步长不稳定表现为飞机动作卡顿、QGC 显示的位置跳变。一个缓解方法是降低 Gazebo 的物理更新频率。在 world 文件里找到physics标签把max_step_size从默认的 0.001 改成 0.004real_time_update_rate从 1000 改成 250。这样物理计算量减少到四分之一但仿真精度会有所下降适合对精度要求不高的编队验证。另一个方法是关闭 Gazebo 的阴影和高质量渲染。在 Gazebo 界面里进入 Edit - Building Editor或者直接修改~/.gazebo/gui.ini把阴影选项关掉。视觉上会差一些但帧率能提升不少。5.4 PX4 实例之间的参数冲突多机仿真时每个 PX4 实例都有自己的参数系统。如果你在 QGC 里修改了第一架飞机的参数第二架和第三架不会同步。这本身是合理的但有时候你会遇到参数修改后不生效的情况。原因是 PX4 的参数保存路径默认是~/.px4/下的共享目录多实例同时写入会导致冲突。解决办法是在启动每个实例时指定不同的参数文件路径export PX4_PARAM_FILE/tmp/px4_params_$i或者在启动脚本里加上-d参数指定不同的工作目录。这样每个实例的参数互不干扰。6. 性能调优与进阶玩法让多机仿真更接近真实场景6.1 减少 Gazebo 渲染开销的几种手段多机仿真跑起来之后你会发现 CPU 占用率很高其中很大一部分是 Gazebo 的渲染线程。如果你不需要实时看 3D 画面可以用无头模式启动export HEADLESS1 ./Tools/simulation/gazebo-classic/sitl_multiple_run.sh -n 3 -m iris无头模式下 Gazebo 不启动 GUI只跑物理引擎和传感器仿真。QGC 依然能正常连接和显示数据只是你看不到 3D 画面。这种方式适合跑自动化测试或者长时间编队实验。如果必须看画面可以降低 Gazebo 的分辨率。在~/.gazebo/gui.ini里设置[geometry] x0 y0 width800 height600把窗口尺寸调小渲染压力会明显下降。6.2 用 ROS 做多机通信的中间层如果你后续要做更复杂的编队算法直接通过 MAVSDK 控制每架飞机虽然可行但代码会变得很臃肿。更好的方式是用 ROS 做中间层每个 PX4 实例通过 MAVROS 连接到 ROS 网络然后你在 ROS 里统一处理多机消息。启动 MAVROS 连接第一架飞机roslaunch mavros px4.launch fcu_url:udp://:14550127.0.0.1:14555第二架roslaunch mavros px4.launch fcu_url:udp://:14560127.0.0.1:14565每个 MAVROS 实例有不同的fcu_url对应不同的 PX4 实例。然后在 ROS 里用命名空间区分group nsuav0 node pkgmavros typemavros_node namemavros param namefcu_url valueudp://:14550127.0.0.1:14555/ /node /group这样你在 ROS 里就能用/uav0/mavros/state、/uav1/mavros/state分别获取每架飞机的状态编队算法只需要订阅这些话题即可。6.3 多机仿真的扩展方向三机跑通之后扩展到五机、十机的瓶颈主要在 CPU 和内存。每增加一架飞机Gazebo 的物理计算量和 PX4 的传感器仿真量都线性增长。我实测在 16GB 内存、i7-10700 的机器上五机仿真还能保持实时十机就开始明显掉帧。如果你需要更多飞机可以考虑用 Gazebo 的简化模型比如去掉摄像头、激光雷达等传感器只保留 IMU 和气压计。这样每架飞机的计算量能减少一半以上。另一个扩展方向是异构编队比如两架多旋翼加一架固定翼。固定翼的启动脚本和模型跟多旋翼不同需要单独配置。PX4 支持plane机型启动时把-m iris改成-m plane即可但固定翼的起飞方式和航点规划跟多旋翼差别很大需要额外调试。6.4 一些偷懒但好用的技巧最后分享几个我常用的偷懒技巧。第一把多机启动命令写成 alias 或者 shell 脚本省得每次敲一长串alias sim3cd ~/PX4-Autopilot ./Tools/simulation/gazebo-classic/sitl_multiple_run.sh -n 3 -m iris第二QGC 的连接配置可以导出成.qgc文件换机器时直接导入不用重新添加端口。在 Application Settings - Comm Links 里点“Export”即可。第三如果 Gazebo 启动时卡在“Loading world”超过一分钟大概率是模型库路径有问题。检查GAZEBO_MODEL_PATH环境变量是否包含~/.gazebo/models和 PX4 的模型目录export GAZEBO_MODEL_PATH$GAZEBO_MODEL_PATH:~/.gazebo/models:~/PX4-Autopilot/Tools/simulation/gazebo-classic/sitl_gazebo-classic/models这个环境变量建议写进~/.bashrc省得每次手动设置。多机仿真这件事说到底就是耐心加细心。端口别搞错模型名别冲突初始位置别重叠剩下的就是等机器慢慢跑了。我刚开始搞的时候三架飞机折腾了一整天才让它们同时起飞后来摸清套路之后十分钟就能搭好一套五机环境。希望这些经验能帮你少走点弯路。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

AI时代工程师转型指南:从Java工作流重构到效率提升 2026/9/25 4:29:56

AI时代工程师转型指南:从Java工作流重构到效率提升

1. 这句话到底在说什么:从一句口号拆出三层真实含义“AI不会取代工程师,但懂AI的工程师会取代不懂AI的工程师。”这句话这两年几乎成了技术圈的“口头禅”,但大多数人只是把它当鸡汤转发,很少有人真正拆开看它到底在说什么。我做了…

阅读更多 →
SolidWorks中NACA4机翼生成:从坐标公式到实体建模避坑指南 2026/9/25 4:29:50

SolidWorks中NACA4机翼生成:从坐标公式到实体建模避坑指南

简介:面向航空工程、机械设计及CFD仿真学习者,提供NACA4系列机翼的几何数据生成与建模分析工具包。压缩包共2个文件,包含txt格式的翼型数据文件和m脚本文件,整体仅1KB。该资源以NACA4四参数翼型为核心,涵盖最大厚度位置…

阅读更多 →
大模型网关+MCP协议+CLI自动密钥分配实战指南 2026/9/25 4:29:50

大模型网关+MCP协议+CLI自动密钥分配实战指南

1. 项目概述:为什么需要一个“自动分配密钥”的大模型网关调用中枢?你有没有遇到过这样的场景:团队里五个人同时在调试同一个大模型服务,有人用 curl 直连,有人写 Python 脚本,有人塞 Postman 里反复点&…

阅读更多 →
Sketch素材包从解压到交付:美食App界面设计全流程指南 2026/9/25 4:29:50

Sketch素材包从解压到交付:美食App界面设计全流程指南

简介:一份面向UI/UX设计师和移动端产品设计者的美食类APP界面设计Sketch素材包。资源以FoodNow.sketch为核心,涵盖首页、菜单页、订单页等完整页面,便于在Sketch中直接编辑与二次调整,适用于个人练习或中小型项目快速出稿。压缩包…

阅读更多 →
芯片测试座精确定位:微米级重复精度实现方法 2026/9/25 4:29:44

芯片测试座精确定位:微米级重复精度实现方法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
diagrams.net 绘图实战:从架构图到工程级文件管理的完整指南 2026/9/25 4:29:44

diagrams.net 绘图实战:从架构图到工程级文件管理的完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉