ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

PX4+Gazebo+XRCE-DDS+QGC无人机仿真环境搭建实战指南

PX4+Gazebo+XRCE-DDS+QGC无人机仿真环境搭建实战指南 我先把这套东西吃透再动手写。说实话在无人机开发圈子里PX4 Gazebo XRCE-DDS QGC这四个词凑到一起基本就是一条完整的仿真开发主链路。但网上大部分教程都只讲了其中一个环节把四个串起来讲的很少能讲透的更少。我写这篇的时候会直接从实际搭建的角度出发把每个环节为什么需要、怎么配置、踩过什么坑都交代清楚不绕弯子。1. 这套组合到底是什么解决什么问题先把话说在前面PX4、Gazebo、XRCE-DDS、QGC这四个东西单独拎出来每一个都不是什么新概念但把它们串成一条完整链路就是当前开源无人机系统开发最主流的仿真验证环境。我自己的理解是这套组合解决的核心问题只有一句话代码改了到底能不能飞只不过不是在真机上试而是在一个高度接近真机的仿真环境里先跑一遍。先快速介绍一下这四个角色在整条链路里的分工PX4是飞控固件跑在飞控硬件上的完整自动驾驶系统负责姿态控制、位置控制、任务规划、传感器融合这些脏活累活。在仿真环境下它跑的是同一套代码只是底层驱动变成了仿真驱动。Gazebo是3D物理仿真环境提供机身模型、传感器仿真、物理碰撞、空气动力学模拟。飞机在它里面飞和在真实世界里飞的物理逻辑是同一套。XRCE-DDS是PX4和外部通信的桥接层它让PX4内部的uORB消息能够通过DDS协议发给外部的ROS 2节点或者反过来接收外部指令。没有它你就没法用ROS 2去控制或者读取飞机的状态。**QGCQGroundControl**是地面站软件提供人机交互的界面相当于飞机驾驶舱仪表盘可以实时看到飞机的姿态、位置、电池电压、飞行模式也能下发任务指令。这四者串起来的完整数据流大概是这样的PX4在Gazebo里面运行模拟出一架无人机把自身的状态消息通过XRCE-DDS桥接出来QGC作为地面站和PX4通过MAVLink通信你可以一边在QGC上看着飞机数据一边在ROS 2节点里发布控制指令共同驱动这架虚拟无人机完成起飞、巡航、降落。这个组合适合谁说白了任何想搞无人机开发但不想每次测试都炸机的人。不管是做视觉SLAM的、做路径规划的、做目标跟踪的还是就想搞清楚PX4内部数据流的这套环境都是绕不开的入场券。你可以在里面随便折腾代码写得稀烂也就炸个仿真飞机重启一下又是一条好汉。2. 工具选型的核心逻辑以及为什么绕不开很多刚开始接触这套技术栈的人首先遇到的问题不是怎么装而是为什么是这几个软件的组合。我先把这个底层逻辑讲清楚因为理解了为什么后面照着做的时候才不会被各种坑绕晕。2.1 为什么ROS 2要用XRCE-DDS而不是MAVROS旧方案PX4和ROS 2之间通信历史上换过好几波方案。早期主流是MAVROS走MAVLink协议通过串口或者UDP转发消息。这种方案的问题是MAVLink消息有固定的消息格式发什么消息、消息里带什么字段都被协议限定死了自定义性差而且封装层次多链路过长的导致消息延迟不可控。PX4从v1.14版本之后官方主推的是PX4-ROS 2 Interface走的就是XRCE-DDS这条链路。XRCE-DDS的全称是eXtremely Resource Constrained Environments DDS这个协议本身就是为了资源受限的嵌入式系统也就是飞控MCU设计的。它允许老旧的MCU设备通过一个轻量级的Agent和标准DDS网络建立通信PX4侧不用跑完整的DDS协议栈只需要维护一个轻量级的XRCE-DDS客户端跟电脑上跑的Micro XRCE-DDS Agent做桥接。这么做的好处是多方面的消息延迟可控性更好可以直接做实时性要求高的任务完整支持ROS 2的发布/订阅模型不用像MAVROS那样做消息转换适配直接支持自定义uORB主题映射PX4内部几乎任何topics都可以暴露出来换个说法你要是只跑个固定翼航点飞行MAVLinkMAVROS够用是够用但你要是想在ROS 2里做offboard控制、做机载SLAM、做编队协同MAVROS那套消息转换适配层能让你痛苦到怀疑人生。XRCE-DDS直接打通了PX4内部uORB世界和ROS 2外部世界整个开发体验是完全不一样的。2.2 Gazebo版本选择的纠结我终于弄明白了Gazebo的版本问题是一个巨大的坑。如果你看网上的老教程很多人会让你装Gazebo 11那个是配ROS 1和PX4老版本的。但如果你用的是Ubuntu 22.04 ROS 2 HumblePX4 v1.15及以上你的选择就应该是Gazebo GardenPX4官方默认或者FortressHumble官方支持。我自己一开始栽在这个地方照着旧教程装了Gazebo 11结果PX4编译完启动仿真直接闪退半天排查不出原因。后来查了官方文档才弄清楚PX4 v1.15的gazebo仿真插件是默认配套Gazebo Garden构建的旧版Gazebo 11的插件接口不兼容。这里要分清两个事情Gazebo classic11及以前ROS 1时代的老牌仿真器插件API和物理引擎都比较旧虽然社区积累大但在PX4 v1.15里已经不是亲儿子了Gazebo Garden/Ignition新一代仿真器重新设计了插件系统、传感器系统和渲染架构PX4官方从v1.15开始把默认支持切换到了这个系列如果你用的是Ubuntu 22.04我建议直接挂上PX4官方工具链脚本让它自动装或者你自己手动搞定Garden。Fortress也能凑合官方文档说支持和Gazebo Fortress搭配但是Fortress在Ubuntu 22.04上的依赖问题还挺多的不是特别推荐。别的不说光Fortress的渲染后端在虚拟机里闪退这个问题就能折腾你一个周末。2.3 RK3588这些ARM板子在整条链路里的位置热词里有基于rk3588 px4飞控开发这个说法就顺带说一下ARM平台在这套环境里的角色。严格意义上PX4固件跑在STM32这类MCU上RK3588这类ARM SoC跑的是Linux在PX4架构里属于机载计算机。也就是说仿真阶段你完全可以在x86电脑上把整套环境搭好跑熟了之后再把代码交叉编译部署到RK3588上去驱动真实的PX4飞控。因为你问的是完整的PX4 Gazebo XRCE-DDS QGC教程这是个纯软件模拟环境和Linux机载电脑的配合是后面真机移植的事。真机阶段PX4跑在飞控上RK3588上跑机载LinuxPX4通过串口/UART和RK3588通信XRCE-DDS Agent跑在RK3588上。这个扩展逻辑我在文章最后会稍微提一下。3. 环境准备与工具链搭建一步步来正式开始动手前先摆清楚建议的系统配置。我自己实际测试Ubuntu 22.04是当前最省心的选择因为PX4 v1.15和ROS 2 Humble在这个版本上都有官方验证支持。Ubuntu 20.04理论上也可以但ROS 2 Foxy已经停止维护了不建议新项目还在Foxy上折腾。这里说一下版本对照方便你自己排查问题组件推荐版本说明Ubuntu22.04 LTS稳定且各组件官方支持最完善ROS 2HumbleUbuntu 22.04对应的长期维护版本GazeboGarden默认/ FortressPX4 v1.15官方默认GardenPX4-Autopilotv1.15DDS接口完整可用的版本QGroundControl最新稳定版直接下载AppImage即可Micro-XRCE-DDS-Agent最新master和PX4配套更新3.1 PX4源码获取与编译PX4源码的获取非常直接官方仓库在GitHub上叫PX4-Autopilot直接拉就行。但这里有一个重要建议不要用main分支做开发直接切到最新稳定版tag。我见过太多人拉完main分支编译到一半报错然后网上查了一圈发现是main分支某个提交引起的临时代码问题白白浪费时间。# 克隆仓库 git clone --recurse-submodules https://github.com/PX4/PX4-Autopilot.git px4 cd px4 # 切换到最新稳定版 tag我写这篇文章时的稳定版是 v1.15.4 git checkout v1.15.4 git submodule update --init --recursive这个--recurse-submodules参数很重要。PX4源码里包含大量子模块比如内置的MAVLink消息库、各种驱动源码不提前拉全会导致编译的时候报各种莫名其妙的头文件缺失错误。如果你已经克隆到一半才发现子模块没拉可以后面补拉。编译的话PX4官方提供了一个自动化脚本帮你装好所有依赖。这套过程大概需要10到20分钟取决于你的网速和CPU性能bash ./Tools/setup/ubuntu.sh这个脚本会帮你安装ROS 2 Humble、Gazebo以及PX4编译所需的全部工具链。执行完之后官方建议重启电脑让环境变量生效。如果你不想重启也可以手动source一下source ~/.bashrc3.2 Gazebo仿真环境的验证很多教程直接跳过这个验证步骤但我建议你单独先试一次Gazebo能不能正常跑起来。因为如果Gazebo本身有问题后面启动PX4仿真时会报一堆和模型加载、渲染相关的错误你想排查都不容易分清是PX4的问题还是Gazebo的问题。可以直接启动一个最简单的PX4仿真环境来验证cd ~/px4 make px4_sitl gz_x500如果一切正常你会看到Gazebo窗口打开一架x500四旋翼出现在世界坐标原点附近同时终端窗口会输出PX4的启动日志显示姿态估计器初始化完成、传感器校准完成之类的信息。首次启动时Gazebo会从云端下载模型材质文件这一步可能很慢需要耐心等待。如果你看到的是终端卡住半天没反应或者Gazebo里面黑屏大概率是模型下载超时或者GPU渲染不兼容。前者的解决办法是提前手动下载模型文件放到指定缓存目录后者需要在启动前加上软件渲染参数。第三章我会把这两个问题的排查细节展开讲。3.3 XRCE-DDS Agent编译安装Micro XRCE-DDS Agent是PX4仿真和ROS 2之间的桥是一个独立的小工具负责在网络里代表PX4的DDS客户端和ROS 2主机进行通信。它的编译非常简单git 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仿真启动时固件会在内部自动启动一个本地的DDS客户端试图连接这个Agent。如果Agent没开PX4会打印连接失败的错误日志但不会影响仿真本身的运行。也就是说PX4仿真可以跑起来只是ROS 2外部没法建立通信。所以建议每次跑仿真之前先把Agent启动起来省得后面看到报错还要回头排查。4. PX4固件配置与Gazebo仿真启动详解搞定了环境接下来进入核心实操环节。很多新手在PX4仿真启动这一步就开始碰壁大部分原因是对PX4的启动方式不够理解不知道怎么去控制启动参数也不清楚不同环境变量对仿真行为的影响。这一节我把这些细节掰开揉碎讲清楚。4.1 理解PX4仿真启动的机制绕过大部分坑PX4的仿真环境本质上还是PX4固件跑在电脑上称为SITLSoftware In The Loop不同的是它不用连接真实的传感器和电机而是把传感器数据和电机控制指令都转发到Gazebo里由Gazebo里的物理引擎和传感器插件来响应。在PX4 v1.15版本里启动仿真的命令统一通过make来执行make px4_sitl gz_x500这条命令的逻辑是px4_sitl编译并运行PX4的SITL版本固件gz_x500指定启动Gazebo仿真并使用x500四旋翼机型模型这里有一些常用变量可以自定义启动行为环境变量作用示例PX4_GZ_MODEL指定Gazebo仿真模型PX4_GZ_MODELx500_depth加载带深度相机的x500PX4_GZ_WORLD指定仿真世界PX4_GZ_WORLDwindy加载带风场的世界PX4_SIM_SPEED_FACTOR仿真速度倍率设为2表示以2倍速运行仿真PX4_NO_MAVLINK禁用MAVLink输出主要在只想跑DDS时使用PX4_SYS_AUTOSTART指定要加载的机型配置make px4_sitl gz_x500 PX4_SYS_AUTOSTART4001举个例子启动时你想跑一个带风场扰动的仿真同事加载x500深度相机版本可以这样写make px4_sitl gz_x500_depth PX4_GZ_WORLDwindy4.2 内八解锁和参数设置飞起来了却启动不了电机热词里专门提到px4内八解锁要设置哪个参数这个问题挺常见的。在QGC地面站里解锁无人机有两种方式一种是内八解锁就是两个摇杆同时向下向外掰另一种是在QGC界面里直接用鼠标点击解锁按钮。如果你用的是仿真环境解锁前有一道坎很关键PX4在解锁之前会做安全检查其中一项是姿态估计是否正常工作。如果你启动仿真后立刻在马达还没就绪的状态下尝试解锁会发现飞机根本没有任何反应。这个时候你应该先看PX4的终端日志确认姿态估计器的工作状态pxh commander status正常情况下你应该看到状态显示为Arming check passed之类的信息说明飞控自检通过电机才能被解锁指令驱动。如果自检没有通过最常见的参数是COM_ARM_CHECK它控制解锁时是否需要执行完整的系统自检。你可以通过QGC的参数面板搜索并把它设为0来跳过检查注意COM_ARM_CHECK0是跳过所有的解锁安全检查包括传感器状态、电池电压等虽然仿真中不会有真实危险但建议搞清楚为什么自检失败再决定是否跳过。另外一个内八解锁相关的重要参数是MC_AIRMODE。航线模式下这个参数的意义不太大但如果你飞的是穿越机或者要用手动模式做特技飞行airmode会允许解锁状态下电机在油门零位时仍保持旋转确保姿态可控。默认值0disabled就够不需要改动。至于内八解锁这个动作本身要不要设置参数其实不需要。内八解锁是RC遥控器在默认配置下通过摇杆位置组合触发的解锁方式对应的是PX4的RC_MAP_ARM_SW这个参数。如果你用的是遥控器且没有单独设置解锁拨杆那么默认就是把油门降到最低并保持内八位置一段时间。在QGC界面上直接点解锁按钮更方便不需要依赖遥控器摇杆位置。4.3 多机仿真与自定义世界再补充一个后续扩展相关的内容多机联合仿真。编队、集群这类项目在仿真里验证几乎是标配PX4对此有完整的支持cd ~/px4 make px4_sitl gz_x500 PX4_SYS_AUTOSTART4001 PX4_GZ_MODEL_POSE0,0,0 # 新开终端启动第二架 make px4_sitl gz_x500 PX4_SYS_AUTOSTART4002 PX4_GZ_MODEL_POSE2,0,0这里的PX4_GZ_MODEL_POSE参数指定了每个飞机在Gazebo世界中的初始位置PX4_SYS_AUTOSTART参数则让每架飞机对应不同的PX4机型实例。这个过程涉及多机MAVLink和端口分配具体细节我以后有空再单独写一篇。4.4 QGroundControl地面站的连接与使用QGC的安装比自己编译省事得多直接在官网下载最新稳定版的AppImage给他赋予执行权限就能跑chmod x ./QGroundControl.AppImage ./QGroundControl.AppImage在仿真环境里QGC会自动检测到PX4在本地UDP端口14550上广播的MAVLink消息。所以不需要手动配置连接打开软件就能看到飞机出现在主界面类型显示为QGroundControl UDP Link。为什么会这么丝滑原因在于PX4的SITL默认启动脚本会自动启动一个MAVLink实例向本机的14550端口发送消息这个正好是QGC的默认监听端口。打开QGC后你可以看到顶部有一个与真实飞行几乎一致的界面包括左下角的姿态仪表盘右下角的虚拟摇杆中央的地图视图左上角的飞行模式下拉菜单此时你的飞机还在Gazebo世界中的原点位置地面上静止状态。点击右上角的起飞按钮QGC会执行一次自动起飞检查确认GPS定位、电池电压都正常后飞到设定高度并悬停。在QGC里切换飞行模式时选择Offboard模式后飞机就等着接收来自外部ROS 2节点的控制指令了。关于具体的Offboard控制和自定义消息收发在第六章的完整融合演示里再展开。5. XRCE-DDS桥接配置与ROS 2/C通信实操现在的重点转向整条链路的另一条主线XRCE-DDS桥接以及基于ROS 2的通信实施。前文已经提过它的核心作用是打通PX4内部uORB消息和外部ROS 2世界。这一节带你亲手把这条通路建起来并跑通一个简单的例子。5.1 理解PX4内部机制才能理解桥接层的存在价值PX4内部所有传感器数据、状态估计、执行器控制指令都是通过一种叫uORB的发布/订阅消息总线传递的。比如姿态估计器输出的四元数发布在vehicle_attitude这个主题上位置估计值发布在vehicle_local_position上电机的控制指令则是actuator_motors。这套消息机制是PX4在单芯片嵌入式环境里高效运作的基石因为它不需要引入复杂网络协议。但问题来了当外部程序比如你在ROS 2里写的节点想要读取这个姿态数据它怎么拿到它不可能直接访问PX4的内存总线。XRCE-DDS方案给出的答案是PX4启动一个轻量级的DDS客户端它订阅PX4内部指定的uORB主题然后通过UDP把消息传给Micro XRCE-DDS Agent。Agent再把这些消息翻译成标准的DDS消息直接进入ROS 2的网络世界。反过来也一样ROS 2发布的消息经由Agent翻译后写回到PX4内部的uORB总线上。这个结构的好处在于PX4本身的代码不需要引入繁重的DDS库MCU的性能开销几乎可以忽略而外部ROS 2节点完全按照标准DDS方式通信不涉及任何PX4内部协议的细节。5.2 用px4_ros_com包搭桥跑通离线航点控制在PX4官方支持的ROS 2接口工具链里有一个很关键的配套仓库叫px4_ros_com。它的作用是把PX4中需要在ROS 2侧配对的uORB消息定义转换成ROS 2接口并提供一个micro-ROS代理节点帮你从ROS 2世界向PX4世界发送Offboard指令。我们可以在一个ROS 2工作区里安装它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 source install/setup.bash编译完成后这个工作区里就有了所有PX4相关消息的自定义ROS 2消息类型比如px4_msgs::msg::VehicleAttitude、px4_msgs::msg::TrajectorySetpoint等等。现在一个最典型的验证实验是在Offboard模式下程序自动发布一组航点位置指令让PX4朝设定目标飞行。我写一个最简单的Python节点来说明整个逻辑#!/usr/bin/env python3 import rclpy from rclpy.node import Node from px4_msgs.msg import OffboardControlMode, TrajectorySetpoint, VehicleCommand from px4_msgs.msg import VehicleLocalPosition, VehicleAttitude import math class OffboardControl(Node): def __init__(self): super().__init__(offboard_control) # 创建发布器 self.offboard_mode_pub self.create_publisher(OffboardControlMode, /fmu/in/offboard_control_mode, 10) self.trajectory_pub self.create_publisher(TrajectorySetpoint, /fmu/in/trajectory_setpoint, 10) self.vehicle_command_pub self.create_publisher(VehicleCommand, /fmu/in/vehicle_command, 10) # 订阅位置和姿态消息用于反馈 self.local_position_sub self.create_subscription(VehicleLocalPosition, /fmu/out/vehicle_local_position, self.local_position_callback, 10) self.attitude_sub self.create_subscription(VehicleAttitude, /fmu/out/vehicle_attitude, self.attitude_callback, 10) # 定时器20Hz 发送控制指令 self.timer self.create_timer(0.05, self.timer_callback) # 目标位置 self.target_position [5.0, 0.0, -8.0] # 前方5米高度8米 self.current_position [0.0, 0.0, 0.0] self.arm_state False self.offboard_state False self.flight_phase 0 def local_position_callback(self, msg): self.current_position [msg.x, msg.y, msg.z] def attitude_callback(self, msg): pass # 这里可以用四元数来判断姿态稳定 def timer_callback(self): self.publish_offboard_control_mode() self.publish_trajectory_setpoint() self.arm_and_offboard_command() def publish_offboard_control_mode(self): msg OffboardControlMode() msg.timestamp int(self.get_clock().now().nanoseconds / 1000) msg.position True msg.velocity False msg.acceleration False msg.attitude False msg.body_rate False self.offboard_mode_pub.publish(msg) def publish_trajectory_setpoint(self): msg TrajectorySetpoint() msg.timestamp int(self.get_clock().now().nanoseconds / 1000) msg.position self.target_position msg.yaw 0.0 self.trajectory_pub.publish(msg) def arm_and_offboard_command(self): # 这里只是简化演示实际需要配合arming request和offboard mode命令 pass def main(argsNone): rclpy.init(argsargs) node OffboardControl() rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ __main__: main()这个节点做的事情是每50毫秒发布一次Offboard控制模式消息声明当前控制优先使用位置通道同时发布一个目标位置指令。只要你在QGC上先把飞机设成Offboard模式并解锁飞机就会飞向你指定的目标位置。5.3 验证DDS桥接状态避免数据静默断开实际开发中最令人抓狂的问题是程序跑得好好的没有任何报错但飞机就是没有反应。这种情况十有八九就是XRCE-DDS链路断开了。怎么排查最直接的办法是盯着PX4的终端日志看有没有以下这行输出[chrt] [px4_dds_client] connecting to UDP endpoint 127.0.0.1:8888如果这行之后紧跟着显示connected successfully说明链路通畅。如果你看到的是连接超时的提示说明Micro XRCE-DDS Agent没有启动或者启动的端口不对。另一个角度是从ROS 2侧验证用ros2 topic list确认PX4的消息主题是否可见ros2 topic list # 应该能看到 /fmu/out/vehicle_attitude、/fmu/out/vehicle_local_position 等主题如果你能看到/fmu/out/前缀的主题说明PX4的DDS数据已经进入了ROS 2网络。看不到的话大概率Agent的问题先排查Agent。6. 完整实操案例从零开始跑通一次仿真飞行前面都是拆开来讲这一节我把整套流程完整串一遍就像你第一天来实验室拿到的任务是把四旋翼在仿真里飞起来。按照这个步骤走大概率不会翻车。6.1 一键启动的完整操作序列整个流程的步骤看起来多实际跑熟了每次就三条命令的事。我第一次跑的时候大概花了一个小时主要时间花在编译和Gazebo模型加载上。Step 1启动XRCE-DDS AgentMicroXRCEAgent udp4 -p 8888启动后终端会保持挂起状态显示等待客户端连接。这个窗口先留着别关也可以在后面操作中随时切回来看日志。Step 2启动PX4 Gazebo仿真cd ~/px4 make px4_sitl gz_x500等编译启动完毕看到PX4命令行提示符pxh出现说明飞控进程已经就绪。另一头Gazebo窗口里x500四旋翼模型应该悬停在原点位置。Step 3启动QGC地面站./QGroundControl.AppImage打开后等几秒主界面出现飞机图标和实时姿态数据说明MAVLink通信正常。Step 4在QGC里起飞点击左上角的Takeoff按钮确认弹出的起飞检查项全部通过再点击确认。此时Gazebo窗口中的飞机应该缓缓升起QGC界面的高度数据同步变化。6.2 ROS 2节点控制飞机飞向指定点在飞机悬停稳定后切到ROS 2工作区运行刚才建好的示例节点cd ~/ws_px4 source install/setup.bash ros2 run offboard_control offboard_control # 实际包名和可执行文件名按你自己的配置运行之前记得先在QGC界面上把飞机的飞行模式切换为Offboard并解锁。切换模式可以通过QGC顶部的模式下拉菜单实现也可以用RC遥控器如果仿真里配了遥控器模拟模块。节点开始运行后飞机会先保持当前悬停位置然后向目标点移动。你在QGC的地图上应该能看到飞机图标从原点逐步向指定位置移动。6.3 飞行数据记录与回放验证算法结果飞行过程中的数据记录这件事儿我建议从第一次仿真就开始做别嫌麻烦。后面你调算法的时候会发现数据回放比实时观察要高效得多因为你可以在同一段飞行过程中反复调整数据处理逻辑不用一遍遍重复飞行。PX4自带ULog日志系统仿真环境下日志会自动记录在~/tmp目录下文件名类似于session_YYYY-MM-DD_HH-MM-SS.ulg。你可以用Flight Review在线工具或者pyulog库离线分析pip install pyulog ulog2csv 你的日志文件.ulg这条命令会把ulog里的所有消息转换成CSV表格方便你用Python、Excel或者MATLAB做后续分析。如果你在QGC里开了Log Download功能还可以直接从QGC的日志面板下载带完整姿态估计器内部状态的日志用Flight Review生成图表报告。7. 常见问题与排查技巧实录这一节是整个实操经验里价值密度最高的部分提到的每个问题我自己都踩过而且是很典型的、论坛上反复出现的问题。整理成一个速查表你遇到类似情况直接按图索骥。7.1 Gazebo启动相关的典型问题问题1Gazebo窗口卡在黑屏或者界面特别卡这个问题的根源基本是虚拟机显卡不支持OpenGL硬件加速。Gazebo新版对渲染要求很高如果运行在VMware或者VirtualBox里默认的3D加速能力往往不够用。解决方案是把Gazebo的渲染降到软件渲染模式在启动仿真的命令前加上环境变量export LIBGL_ALWAYS_SOFTWARE1 export GZ_GUI_CLIENT_PLUGIN_PATH make px4_sitl gz_x500如果还不行检查一下Gazebo的日志看有没有跟渲染相关的报错。另一个更省事的选择是直接放弃在虚拟机里跑仿真用WSL2或者双系统。问题2模型加载特别慢卡在Downloading modelGazebo首次加载模型时会去模型仓库在线拉取模型文件国内网络环境下这个下载速度很可能让人崩溃。解决办法是手动把模型文件下到本地缓存目录。打开~/.gz/gazebo/目录看看是否存在models目录如果不存在就创建一个然后去https://github.com/gazebo-tools/gazebo-models把对应的模型文件下载下来放进去。如果实在下载不下来可以考虑给Gazebo设置代理加速。问题3飞机在Gazebo里看起来是在飘而不是稳定的悬停如果飞机在仿真里出现剧烈抖动、像喝醉了一样乱飘多半是PX4的姿态估计器没有正确初始化。检查终端日志有没有类似EKF2 IMU data not ready的警告。解决方案是在pxh命令行里手动重启EKF2pxh commander mode auto pxh ekf2 stop pxh ekf2 start正常来说EKF2在2秒内就能收敛之后飞机姿态就能稳定下来。注意要在飞机解锁之前操作否则飞行状态下重启EKF2会让飞机失控。7.2 DDS和ROS 2通信相关的典型问题问题4在QGC里能看到飞机数据但ROS 2订阅不到任何PX4消息这代表MAVLink链路正常但DDS链路断了。最可能的原因是Micro XRCE-DDS Agent没有启动或者PX4仿真启动时环境变量没写对。排查步骤确认Agent窗口还活着在pxh命令行里手动启动DDS客户端dds start如果提示DDS client already running那就Agent的问题重启Agent问题5ROS 2报错找不到px4_msgs消息类型大概率就是没有source工作的install目录。在运行节点前一定要执行source ~/ws_px4/install/setup.bash或者在~/.bashrc里加上这一行免得每次开终端都要手动source。我自己就是这么干的省心太多。7.3 解锁和任务执行相关的典型问题问题6一直解锁失败QGC提示Preflight check failed出现这个提示先不要急着改COM_ARM_CHECK跳过自检应该在QGC的Analyze Tools里查看具体的检查项到底哪一项不满足。最常见的原因是GPS没有收到信号。仿真里GPS信号默认是正常的但如果你把世界模型改成了室内场景或者手动关掉了GPS仿真插件就会导致定位检查失败。仿真环境下最简单的处理方式就是直接把COM_ARM_CHECK改成0跳过自检。真机上绝对不要这么玩安全第一。问题7飞机起飞后垂直往下掉或者直接翻跟头这通常是电机方向和旋转方向配置错误。检查PX4加载的机型配置和Gazebo模型是否匹配。我用的是gz_x500机型对应的是标准四旋翼电机布局是十字型。如果你用了一个非标准的电机布局而不是在QGC里调整对应的参数比如CA_ROTOR_COUNT、CA_ROTOR0_AXIS、CA_ROTOR0_DIR等就会发生这种现象。这种问题的排查思路很简单打开QGC的电机测试界面逐个电机测试旋转方向和转速确认和PX4固件内部的编号一致。7.4 一个性价比极高的调试习惯最后分享一个我觉得非常实用的习惯用PX4自带的手动飞行模式来做基础验证。很多新手一上来就写Offboard代码遇到问题根本说不清是飞控的问题还是自己代码的问题。我建议每次改动完PX4参数或者Gazebo模型先切到Stabilized模式掐着手柄飞一圈确认基本操控正常再上Offboard代码调试。这样问题边界一下就能缩小到代码层排查效率翻倍。8. 我实际操作中的一些体会整套环境跑通之后回头看其实技术门槛并没有想象中那么高真正的门槛在于对这套工具链的把控能力和调试心态。我自己最初搭这套环境的时候前后折腾了两个晚上。第一个晚上卡在Gazebo渲染问题上什么东西都没跑起来第二个晚上卡在DDS通信上看了一堆资料才搞清楚Agent和Client的关系。现在回想起来大部分时间其实都花在了不知道某个报错是什么意思上面。所以我在这篇文章里尽可能把每个报错对应的问题根源和排查思路写清楚希望你能少走点弯路。还有一个因为长期使用养成的习惯要推荐给你搭建环境这件事本身值得写成一个脚本提交到你的代码仓库里。这样不管你是换电脑、换GPU服务器、还是带新同学入门一套脚本直接跑完省去每次手动复现环境的痛苦。我自己就是把PX4编译、ROS 2依赖、Agent安装、QGC下载全部写进了一个setup脚本Github Codespaces里也能直接拉起一套可用的仿真环境。这个做法的收益随着时间推移会越来越大。如果后面你把算法在仿真里调通了准备往真机上搬可以在PX4 v1.15自带的offboard例程基础上做增量开发。机载端用Raspberry Pi 4或你提到的RK3588跑Linux用MAVLink或者XRCE-DDS和飞控通信。仿真里写的代码逻辑可以复用大半只要把消息接口从仿真驱动换成串口驱动。这个阶段又是一个完全不同的挑战回头有机会写一篇硬件在环的教程再展开。
返回列表