资讯详情

WSL2 + ROS 2 无人机多机协同与AI视觉仿真环境搭建

📅 2026/10/1 7:27:31 | 华诺云谱 👁 阅读
WSL2 + ROS 2 无人机多机协同与AI视觉仿真环境搭建
前阵子导师丢给我一台 Windows 11 笔记本要求把“无人机多机协同 AI 视觉”的整套仿真环境跑起来。我第一反应是装双系统 Ubuntu但折腾一晚上就放弃了——不是因为装不上而是因为开发过程中要频繁在 Windows 和 Linux 之间切换查资料、传文件、截图双系统这条路在项目早期实在太费人了。后来我改用 Windows 11 WSL2把 PX4、Gazebo、ROS 2、QGroundControl、Android 端全部串起来最终在笔记本上跑通了多机协同仿真和基于视觉的 offboard 控制。这篇文章就是我那台机器从零到多机协同的完整过程记录包括环境选型逻辑、WSL2 的落地细节、PX4 与 Gazebo 的版本泥潭、ROS 2 和 PX4 的通信链路、QGroundControl 的 Windows/Android 双端连接以及最后 AI 视觉如何接入控制闭环。目标读者很明确想在自己的 Windows 电脑上搭一套无人机开发环境、又不想为了仿真去装双系统的同学。只要按顺序走基本可以一次跑通少走我踩过的那几坑。1. 这套组合凭什么成立WSL2、PX4、ROS 2 的取舍逻辑1.1 为什么最终放弃双系统和传统虚拟机很多人一想到 Linux 开发环境第一反应就是“装个双系统”或者“开个 VMware”。这两种方案我都认真用过最后都换掉了原因很直接。双系统的问题是“切换成本”太高。PX4 源码编译、Gazebo 仿真、ROS 2 节点调试这些任务分散在一整天的开发流程里你不可能一直待在 Ubuntu 里。遇到编译报错要查资料、要截图发给同学、要改文档你就得重启进 Windows查完再重启回来。一天来回三四次心态很容易崩。更别说双系统引导损坏、Windows 更新覆盖 GRUB 这类经典事故。VMware 这类传统虚拟机的问题更致命——性能损耗和 3D 加速。Gazebo 是 OpenGL 渲染的仿真环境VMware 里经常出现画面闪烁、模型加载缓慢的问题。不少同学搜过“vmware 打开 gazebo 屏幕闪烁怎么办”我也经历过。那本质上是显卡 3D 加速没有正确透传折腾 VMware Tools 和加速选项的时间够重新装两遍系统了。WSL2 和这两者都不一样。它底层是一个轻量级虚拟机跑的是真正的 Linux 内核而不是翻译层模拟。这意味着 PX4 的 CMake 编译、ROS 2 的原生二进制包、Eigen 这些依赖库都能以接近原生 Linux 的方式工作。与此同时WSL2 和 Windows 共享文件系统、网络端口、GPU 资源你可以在 Windows 侧用熟悉的工具看代码、截图、跑 QGroundControlLinux 侧负责编译和仿真。两边不用重启互相切换这才是“开发环境”应有的样子。还有一个容易被忽略的点Docker Desktop 在 Windows 上的后端就是 WSL2。也就是说如果你以后想把仿真环境容器化、或者要跑团队统一的 ROS 镜像这套 WSL2 底子是现成的不用重新学一套虚拟化方案。1.2 版本选型是成败的一半Ubuntu 22.04 与 ROS 2 Humble 的匹配关系WSL2 只是底座真正的版本组合才是这套环境能不能稳的命门。我直接给出经过验证的推荐矩阵组件推荐版本原因WindowsWindows 11 21H2 及以上原生支持 WSLg 图形界面不用装第三方 X ServerWSL2 内核自动更新到最新修复了多个 DDS 组播转发和 localhost 转发问题Ubuntu22.04 LTS与 ROS 2 Humble 官方支持版本严格对应ROS 2Humble HawksbillUbuntu 22.04 对应版本社区文档最全PX4v1.14 或 main 分支SITL 仿真成熟uXRCE-DDS 桥接开箱即用GazeboGazebo Classic 11PX4 官方 SITL 默认模拟器兼容性最好QGroundControl最新稳定版Windows 和 Android 都支持协议兼容 PX4这里有个很容易被热搜词带偏的点很多人搜“gazebo 安装 ignition gazebo fortress”以为 Gazebo 的新版本就是 Fortress。实际上 Gazebo 生态已经分裂了——原本的 Gazebo经典版现在叫 Gazebo Classic新的那套基于 Ignition 架构软件名改成了 Gazebo Sim版本号是 Fortress、Garden 这些代号。ROS 2 Humble 里集成的 gazebo_ros_pkg 默认对接的还是 Gazebo Classic 11。而 PX4 官方 SITL 默认模拟器目前也用 Gazebo Classic。所以对这套环境来说老老实实用 Gazebo Classic 11 最稳Fortress 留给别的项目去折腾。ROS 2 用 Humble 而不是 Rolling 或其他版本理由也很简单Ubuntu 22.04 的 apt 源里原生提供 Humble 的二进制包apt install ros-humble-desktop一条命令就装齐。如果你用 Ubuntu 24.04 或 20.04版本对应关系又不一样网上大量教程会失效。环境的稳定性优先于尝鲜。2. Windows 11 上 WSL2 的落地细节从安装、迁移到图形界面2.1 安装前置检查与常见报错WSL2 的安装流程在 Windows 11 上已经简化到近乎无脑但有几个前置条件不检查的话会卡在奇怪的地方。首先确认 BIOS 里的虚拟化已开启。Windows 11 的任务管理器 - 性能 - CPU右下角能看到“虚拟化”是否为“已启用”。如果没启用需要进 BIOS 打开 Intel VT-x 或 AMD SVM否则 WSL2 的内核起不来报错一般是“请启用虚拟机平台 Windows 功能并确保在 BIOS 中启用了虚拟化”。接着在管理员 PowerShell 里执行wsl --install -d Ubuntu-22.04这条命令会自动做三件事启用“适用于 Linux 的 Windows 子系统”功能、启用“虚拟机平台”功能、下载安装 WSL2 内核然后安装 Ubuntu 22.04。第一次执行完按要求重启系统。重启后进入 Ubuntu 终端设置用户名和密码。这里建议记住你设置的用户名后面 WSL 迁移、Docker 共享、文件权限都会用到。如果你和我一样公司电脑可能禁止从商店安装软件或者网络环境受限那就走离线安装路线。先到官网下载 WSL2 内核安装包msi 文件和 Ubuntu 22.04 的 appx 包然后# 安装内核 wsl_update_x64.msi # 注册系统组件 dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart # 安装发行版 Add-AppxPackage .\Ubuntu2204-220630.5-x64.appx离线安装时要注意 WSL 版本默认可能是 1务必备份后执行wsl --set-default-version 2装完后确认版本wsl -l -v如果 NAME 旁边显示 VERSION 是 2就对了。如果是 1执行wsl --set-version Ubuntu-22.04 2升级。2.2 把 WSL2 迁移到 D 盘的正确姿势WSL2 的虚拟磁盘文件默认存储在 C 盘用户目录下的 AppData\Local\Packages 里。这个东西加 Ubuntu 系统、然后随着 PX4 源码、Gazebo 模型、ROS 2 环境、编译中间文件一起长大很快就能吃到 30-40GB。C 盘是系统盘空间本来就紧张所以大概率需要迁移。迁移的步骤有官方支持的导出/导入法比直接拷贝 vhdx 安全得多。先把 WSL 关掉wsl --shutdown然后导出到 D 盘wsl --export Ubuntu-22.04 D:\wsl-backup\ubuntu2204.tar然后注销原来的发行版wsl --unregister Ubuntu-22.04注意unregister会删除原发行版的所有数据所以导出一定要成功再执行。最后导入到新位置wsl --import Ubuntu-22.04 D:\WSL\Ubuntu2204 D:\wsl-backup\ubuntu2204.tar --version 2导入完成后WSL 会默认以 root 用户登录桌面图标可能也丢失需要执行一次ubuntu2204.exe config --default-user yourname把yourname换成第一步创建的用户名。顺便在 Windows 的开始菜单里把 Ubuntu 图标固定免得每次都要敲命令进子系统。2.3 WSLg 与网络模式为什么 Windows 11 不用装 X Server老教程里通常会让你在 Windows 上装 VcXsrv 或 X410再配置 DISPLAY 环境变量才能弹 Linux 图形界面。Windows 11 自带 WSLg已经把这件事做完了。我在 WSL2 里启动 Gazebo窗口能直接显示在 Windows 桌面上像是原生应用一样不需要任何额外的 X Server。验证 WSLg 是否正常工作echo $DISPLAY输出:0就说明 WSLg 在工作。如果输出为空检查 Windows 版本和 WSL 版本老版本内核不支持 WSLgwsl --update一下。网络模式是我这次搭建里遇到的另一个关键点。WSL2 默认的网络模式是 NATWSL 内部有一个独立 IPWindows 和 WSL 之间通过虚拟网卡互通。这在日常使用中问题不大但 ROS 2 的 DDS 发现机制依赖组播QGroundControl 连接 SITL 也依赖 UDP 端口转发NAT 模式下经常出现“Windows 里的 QGC 收不到 WSL 里 PX4 的 MAVLink 数据”这种玄学问题。解决办法是启用 WSL 的 mirrored 网络模式。在 Windows 用户目录下创建.wslconfig文件[wsl2] networkingModemirrored然后wsl --shutdown再启动。mirrored 模式下WSL2 共享 Windows 的网络栈IP 地址和 Windows 一样localhost 直接互通。这样 QGC 连127.0.0.1:14550就能连上 WSL 里的 SITLROS 2 节点之间的 DDS 发现也更加顺畅不用设置ROS_LOCALHOST_ONLY也基本能正常工作。2.4 英伟达驱动在 WSL2 里的工作方式后续要跑 AI 视觉GPU 是绕不开的。很多人的疑问是“WSL2 里英伟达驱动生效吗”——答案是生效但方式和传统 Linux 不一样。WSL2 的 GPU 方案是驱动装在 Windows 侧WSL2 通过 GPU 半虚拟化dxgkrnl直接调用 Windows 的显卡驱动Linux 侧不需要安装 NVIDIA Linux 驱动。你只需要在 Windows 侧安装最新的 NVIDIA 驱动包含 WSL2 支持的版本然后进 WSL2nvidia-smi如果能看到显卡信息说明 CUDA 调用链路是通的。接着装 CUDA Toolkit 的 WSL-Ubuntu 版本或者直接用pip install torch跑 PyTorch都能正常调用 GPU。我在 WSL2 里跑 YOLO 推理速度基本和原生 Linux 一致这一点 WSL2 做得比传统虚拟机好太多。需要参看的一点WSL2 里共享 GPU 显存并不完全等同于物理机显存和 Windows 侧是共享的。如果你要在 Windows 上同时开很多图形应用再在 WSL 里跑大模型推理显存会有竞争。开发调试阶段完全够用大规模训练我建议还是留给专门的 Linux 服务器。3. PX4 与 Gazebo 的仿真环境版本泥潭与冷启动坑3.1 从源码跑起 PX4 SITL 的完整过程PX4 的 SITLSoftware In The Loop仿真本质是把整套飞控逻辑编译成可执行文件跑在你的电脑上通过 Gazebo 模拟真实的物理世界。飞控的每个模块姿态估计、气压计、GPS、EKF在 SITL 里都有对应的仿真数据源所以你可以像操作真机一样通过 QGC 给它解锁、起飞、切换模式。依赖安装建议直接用 PX4 官方脚本cd ~ git clone --recursive https://github.com/PX4/PX4-Autopilot.git cd PX4-Autopilot bash ./Tools/setup/ubuntu.sh这个脚本很长会自动装一系列编译工具链和 Gazebo。如果你的网络比较差--recursive克隆子模块可能会失败多点几次或者用代理的方式单独拉取子模块目录都行。编译并启动仿真make px4_sitl gazebo-classic第一次编译会下载依赖、编译整个 PX4 固件我试过大约要 15-25 分钟取决于 CPU。编译完成自动弹出一个 Gazebo 窗口里面有一架默认的 iris 四旋翼终端里是 px4 控制台不断滚动输出消息。到这步 SITL 就活了。一个细节Ubuntu 22.04 上PX4 官方文档在 1.14 之后推荐写gazebo-classic而不是gazebo因为 PX4 在跟进新版的 Gazebo Sim 支持。如果你用老命令make px4_sitl gazebo在某些分支会提示需要指定模拟器类型。以官方文档为准用gazebo-classic最稳。3.2 首次启动 Gazebo 黑屏模型下载超时的处理第一次跑make px4_sitl gazebo-classic十有八九会遇到 Gazebo 窗口弹出来但世界是灰的终端里一直在waiting for model...过好几分钟才出现飞机。这个现象的根本原因不是 PX4 坏了而是 Gazebo 第一次要去下载飞机模型和传感器模型这些模型托管在开源服务器上网络稍差就超时。验证 解决方案如下。首先确认模型是否存在本地缓存ls ~/.gazebo/models如果该目录是空的或者缺 iris可以手工把 PX4 的模型仓库克隆下来然后指定资源路径git clone https://github.com/PX4/PX4-gazebo-models.git export GZ_SIM_RESOURCE_PATH$PWD/PX4-gazebo-models注意 PX4 1.15 之后的模型仓库路径有调整还能顺便把Tools/simulation/gazebo-classic/sitl_gazebo-classic/models目录显式加进GAZEBO_MODEL_PATH。命令行设置完毕后重新启动仿真模型加载就从本地读取黑屏问题基本消失。此外如果你的 Gazebo 窗口出现飞机爆炸、乱飞、直接掉落的动画通常不是仿真的 bug而是编译时和运行时使用了不同版本的 Gazebo 插件。稳妥起见PX4 的ubuntu.sh脚本装的是 Gazebo Classic 11不要手动去把 Gazebo 升级到更高版本除非你知道自己在干什么。3.3 多机仿真如何在同一个 Gazebo 世界里跑起来单机仿真跑通后多机协同才是标题里的重头戏。PX4 官方提供了一套多机 SITL 脚本能直接在一个 Gazebo 世界里生成多架飞机cd ~/PX4-Autopilot/Tools/simulation/gazebo-classic ./sitl_multiple_run.sh这个脚本默认启动 3 架 iris每架飞控一个独立进程端口递增Gazebo 世界里能看到三架飞机。如果你想手动控制飞机数量脚本里有参数也可以在已有的仿真基础上再启动新实例# 先启动第 0 号实例 make px4_sitl gazebo-classic # 新开终端启动第 1 号实例 PX4_SIM_MODELiris ./build/px4_sitl_default/bin/px4 -i 1 # 再开终端启动第 2 号实例 PX4_SIM_MODELiris ./build/px4_sitl_default/bin/px4 -i 2每个实例自动分配不同的系统 ID 和 MAVLink 端口QGC 默认会自动发现所有在广播的无人机。这就搭起了多机协同的下层基础——多套飞控、共享一个仿真物理世界彼此物理上可见、会碰撞控制上又是独立的。一个经验之谈多机仿真对电脑性能的要求是线性增长的。3 架 iris 在 i7 16G 内存的笔记本上还能流畅跑5 架以上就要关掉 Gazebo 的实时渲染或者降低图形质量再往上最好用无 GUI 的 headless 模式跑。4. ROS 2 与 PX4 的通信链路从 uORB 到 DDS 的桥怎么搭4.1 PX4 内部的 uORB 机制和它在 ROS 2 通信中的角色PX4 的核心是一个叫 uORB 的发布/订阅消息总线。飞控内部的传感器数据、姿态估计、位置控制状态全都通过 uORB topic 在模块之间流动。比如vehicle_attitude是姿态四元数vehicle_odometry是里程计offboard_control_mode是 offboard 模式切换指令trajectory_setpoint是期望轨迹点。问题是 uORB 是 PX4 自己的一套机制ROS 2 看不懂反之亦然。两者之间需要一座“桥”。老办法是 Fast-RTPS 桥新版本 PX4 已经用 uXRCE-DDSmicro eProsima XRCE-DDS取代了它。uXRCE-DDS 的思路是在 PX4 内部跑一个 XRCE 客户端client在飞控外部跑一个 XRCE 代理agent两者之间用轻量的 XRCE 协议通信agent 再把数据转换成完整的 DDS 消息进入 ROS 2 的世界。整个过程可以概括成四层Gazebo 物理仿真 - PX4 SITLuORB - XRCE Client - UDP - DDS Agent | v 用户程序rclpy / MAVSDK - ROS 2 topics - DDS 域这个架构的好处是职责清晰PX4 只负责飞控逻辑ROS 2 只负责应用层决策和 AI两者通过标准消息接口解耦。多机场景下每架 PX4 实例就是一个独立的 XRCE 客户端可以分别连到不同的 agent 端口在 ROS 2 侧用命名空间区分。4.2 uXRCE-DDS 桥接的配置与启动顺序先从源码安装 agentgit clone https://github.com/eProsima/Micro-XRCE-DDS-Agent.git cd Micro-XRCE-DDS-Agent mkdir build cd build cmake .. make sudo make install然后先启动 agent监听 UDP 8888 端口MicroXRCEAgent udp4 -p 8888接着再启动 PX4 SITLcd ~/PX4-Autopilot make px4_sitl gazebo-classicPX4 SITL 默认会启动 uXRCE-DDS 客户端去连127.0.0.1:8888这和 agent 正好对上。如果在 QGC 里想改配置参数名是UXRCE_DDS_CFG默认配置就是 UDP 8888不用额外设。启动顺序建议是agent 先起来PX4 SITL 后起来。如果顺序反了PX4 客户端连接失败会反复重试虽然最终也能连上但会浪费时间且日志刷屏。4.3 验证通信ros2 topic 看到飞机状态的完整命令与预期输出通信是否打通最直观的验证就是 ROS 2 能看到 PX4 的 topic。新开一个终端先加载 ROS 2 环境source /opt/ros/humble/setup.bash然后列出话题ros2 topic list如果桥接成功你会看到类似这样的输出/fmu/out/vehicle_attitude /fmu/out/vehicle_odometry /fmu/out/vehicle_status /fmu/in/offboard_control_mode /fmu/in/trajectory_setpoint注意/fmu/out/前缀是 PX4 向外部发布的主题/fmu/in/是接收外部指令的主题。查看具体的姿态ros2 topic echo /fmu/out/vehicle_attitude能看到四元数在实时刷新说明 PX4 内部的状态已经走进了 ROS 2 数据域里。至此ROS 2 能读状态、能发指令整个通信链路就算打通了。一个常见的坑如果你在 WSL2 里跑 ROS 2 和 agent又在 Windows 上的某个容器或另外一台机器跑 ROS 2 节点两边的 DDS discovery 可能因为网络安全策略互相看不到对方。优先保证所有 ROS 2 节点都在同一个 WSL2 发行版内等单机调试通了再考虑跨机器组网。5. QGroundControl 与 Android 端多机的地面控制与移动调试5.1 QGC 连接 SITL 的参数与网络配置QGroundControl 是 PX4 的官方地面站Windows 原生版本直接去官网下载安装即可。SITL 模式下PX4 默认在 UDP 14550 端口上广播 MAVLink 数据。大多数情况下打开 QGC 会自动连接上 WSL2 里的 SITL因为 QGC 默认监听 UDP 14550。如果自动连接没生效手动添加连接方式点击左上角“通信链路”设置 - 添加 - UDP端口填写14550目标地址留空或填127.0.0.1保存QGC 应该立刻显示无人机状态、姿态、电池图标WSL2 早期 NAT 模式下 QGC 偶尔收不到数据我提过的.wslconfigmirrored 网络模式可以根治这个问题。确保你改完配置后用wsl --shutdown重启过一次 WSL。QGC 在工作流里承担的角色不只是“看飞机状态”它还负责参数设置和校准。PX4 的很多关键参数比如UXRCE_DDS_CFG、飞控 ID、机架类型都可以在 QGC 的参数面板里改改完直接写入 SITL 实例比命令行改方便太多。5.2 Android 版 QGC手机连飞机的三种网络路径Android 版 QGC 是同一套软件手机端的价值在于现场调试和演示——不需要背着笔记本拿手机就能看飞机状态、切换模式、触发返航。手机要连上 WSL2 里的 SITL有三种路径按推荐程度排序第一种最省事如果 WSL2 开了 mirrored 网络模式WSL 里的服务和 Windows 共享网络栈。手机和电脑连同一个 Wi-Fi 时直接在手机 QGC 里添加 UDP 连接目标地址填电脑的局域网 IP端口填 14550就能收到 SITL 的数据。第二种老版本 WSL2 NAT 模式手机无法直接访问 WSL 的虚拟网卡 IP需要在 Windows 上做一个 UDP 端口转发。以管理员身份运行 PowerShell把 Windows 的 14550 端口转发到 WSL 的 IPnetsh interface portproxy add v4tov4 listenport14550 listenaddress0.0.0.0 connectport14550 connectaddressWSL2_IP其中WSL2_IP需要先通过wsl hostname -I查出来。注意 WSL2 重启后 IP 可能变化需要重新执行。第三种彻底绕开 WSL 网络在 WSL2 里启动一个 MAVLink 路由器把 SITL 的消息转发到局域网 IP手机再直连。这种方案适合后续要组多机、UDP 端口冲突的场景复杂度也更高。实际开发中我最常用的是第一种。手机 QGC 界面和桌面版基本一致飞行轨迹、姿态仪表、参数面板都有。5.3 多机协同中 QGC 的职责边界MAVLink 转发与日志回放多机协同场景下QGC 不只是监控界面还承担了很重要的调试职能。3 架飞机同时在 Gazebo 里飞QGC 会自动发现多个连接每个连接对应一架飞机。在通信链路面板里你可以给每个链接命名比如 drone0、drone1、drone2切换查看每架飞机的状态。调试编队算法时经常需要知道“某一时刻每架飞机收到的指令是什么”QGC 的 MAVLink 日志回放功能非常有用。我习惯在跑多机协同实验时全程开启日志记录跑完在 QGC 里回放能看到每架飞机的飞行姿态和指令人机接口的完整时间线定位算法问题比盯着实时终端高效得多。QGC 不负责编队算法本身它只提供监控和调试。真正的协同逻辑写在 ROS 2 节点里。边界要清楚QGC 是地面站不是机载大脑。6. 从仿真到 AI 多机协同最后一公里的控制闭环6.1 多机协同的核心难点分布发现、通信、决策、避碰当 ROS 2 和 PX4 通信跑通、多架飞机能同时升空之后多机协同真正的难点才开始浮现。以我的实践观察难点集中在四个方面第一是“发现”。多机场景里每架飞机要有唯一标识ROS 2 侧要用命名空间或 topic 前缀区分不同飞机。我习惯的做法是每架飞机配一个独立 agent 端口然后在 ROS 2 里为每个飞机的节点组设置命名空间drone0、drone1。这样/drone0/offboard_control_mode就不会和/drone1/offboard_control_mode互相干扰。第二是“通信”。PX4 内部消息是 uORBROS 2 决策节点的消息是 DDS跨飞机交互如果依赖 DDS discovery多机和单机的 QoS 策略差异会立刻暴露。相比 TCPDDS 的默认可靠传输在仿真高负载时会有明显延迟抖动。实际调试中控制类的 topic 我尽量用 best-effort QoS状态监控类用 reliable QoS混用两种策略才能既保证实时性又不丢关键状态。第三是“决策”。编队控制、任务分配、目标跟踪这些算法跑在 ROS 2 层。我用的是经典的 leader-follower 思路一架 leader 按预设轨迹飞行几架 follower 订阅 leader 的位姿结合自身位姿计算期望偏移再生成各自的 offboard setpoint。这个模式实现简单适合从零起步的多机项目。第四是“避碰”。这是多机系统里最容易出事故的环节。仿真里飞机碰撞虽然不会导致炸机损失但会让后续逻辑全乱。起步阶段我建议先在任务层避免冲突——给每架飞机分配不同的高度层或不同的任务区域别指望 PX4 自带编队避碰功能它在很多版本里压根不提供。6.2 把 YOLO 检测接入 offboard 控制的完整链路AI 视觉接入多机协同本质就是让决策节点能“看到”世界然后输出 setpoint 指令。我在 WSL2 里用 PyTorch 和 YOLO 做目标检测跑在 Gazebo 的机载相机图像上再接进 ROS 2 控制环。节点结构大致是三层第一层图像源。Gazebo 里的相机模型会把图像发布为 ROS 2 的sensor_msgs/Image或者你直接在仿真环境里配置机载相机的话题。我是在 iris 模型上挂了一个模拟 RGB 相机topic 名/drone0/camera/image_raw。第二层视觉检测。用 rclpy 写一个订阅节点收到图像后交给 YOLO 模型推理输出目标类别和检测框。检测结果发布为自定义消息比如包含目标中心坐标和帧中心偏移量。第三层控制节点。订阅检测结果把“目标在画面中心偏左多少像素”转换成“向左移动多少速度”然后通过 PX4 提供的 offboard 控制 topic 发送速度指令。核心伪代码逻辑如下import rclpy from rclpy.node import Node from geometry_msgs.msg import TwistStamped from px4_msgs.msg import OffboardControlMode, TrajectorySetpoint class VisionController(Node): def __init__(self): super().__init__(vision_controller) # 订阅检测结果 self.detection_sub self.create_subscription(Detection, /detection, self.on_detection, 10) # 发布 offboard 控制模式 self.offboard_pub self.create_publisher(OffboardControlMode, /fmu/in/offboard_control_mode, 10) self.traj_pub self.create_publisher(TrajectorySetpoint, /fmu/in/trajectory_setpoint, 10) def on_detection(self, msg): # 计算像素偏差 - 期望速度 vx self.kp * msg.x_error vy self.kp * msg.y_error # 发布 offboard 模式和期望轨迹点 self.publish_offboard(vx, vy, 1.0) # 稳定高度 1m实际跑的时候有两个关键细节。第一offboard 模式的进入需要在 QGC 或代码里先解锁然后切换模式等待 PX4 确认进入后再持续发送 setpoint如果 setpoint 发送频率低于 2 HzPX4 会自动退出 offboard 模式。第二在仿真里你的视觉控制环是有延迟的Gazebo 渲染图像、YOLO 推理、指令回传给飞控整个过程可能有几百毫秒。要在控制增益上留足裕度否则飞机会出现类似“醉汉”的震荡航迹。6.3 关于这套环境我拆过不少坑之后想说的几点最后分享几条实操体会都是这次搭建过程中反复折腾换来的。项目源码和 workspace 一定要放在 WSL2 的 Linux 文件系统里比如~/PX4-Autopilot不要放到/mnt/c/下。WSL2 访问 Windows 文件系统存在明显的 I/O 性能损耗PX4 这种包含几万个头文件的 C 工程在/mnt/c/下编译时间能翻倍。我第一次不知道放在 C 盘项目目录里编译每次改代码都要等很久才发现根因。组件之间要一件一件验证。WSL2 装好了先验证网络和图形界面PX4 单机仿真跑通了再上 ROS 2 桥桥通了再接 QGC最后才做多机和 AI。每一步的验证时间也许只要几分钟但跳步的排查成本是按小时算的。有一次我以为 ROS 2 和 PX4 的桥没问题直接上多机结果发现 topic 全是单机的排查半天才知道是 agent 端口配置不对每架飞机各自连了同一个 agent。.wslconfig这个文件值得反复调。mirrored 网络模式、内存上限、CPU 核数都能在这里配置。我现在的配置是内存限制 12GB、8 核跑 3 架 iris YOLO 推理仍然流畅。如果 Gazebo 频繁崩溃或者 WSL 整体卡顿先调这里而不是重装。这套环境最大的价值在于它把“多机协同 AI 视觉”烧钱且危险的开发过程搬进了一个完全可复现、可回放、可试错的仿真环境。当你在仿真里把 offboard 控制、视觉检测、编队逻辑全部调顺之后真机开发只是在同样的控制架构上换掉数据来源而已——飞控逻辑、通信链路、决策节点都不变。对于刚开始做无人机方向的同学这条从 Windows 桌面到多机 AI 仿真的路径省下来的不只是时间更是很多次真机调参的提心吊胆。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑