ARTICLE DETAIL

资讯详情

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

固定翼无人机视觉自主飞行:ROS+PX4二次开发全流程解析

固定翼无人机视觉自主飞行:ROS+PX4二次开发全流程解析 固定翼无人机的视觉自主飞行和四旋翼的悬停式感知完全不同。四旋翼可以低速悬停让视觉算法在一个相对稳定的坐标系里工作固定翼则始终处于运动状态姿态变化快视野连续移动视觉结果稍有延迟或坐标系接错就会直接影响飞行安全。这也是为什么固定翼的视觉二次开发平台通常不能只靠飞控自带能力完成而是需要 ROS 与 PX4 协同配合PX4 负责底层的姿态控制、航点跟踪和安全保护ROS 负责图像处理、目标识别、避障判断和任务决策。ROS PX4 是目前开源无人机领域最主流的一套组合。PX4 提供完整的固定翼、旋翼和垂直起降控制逻辑并通过 MAVLink 协议与外部设备通信ROS 提供节点、话题、参数服务和大量现成算法库适合承载视觉感知和复杂任务逻辑。两者通过 MAVROS 桥接形成“飞控管飞行、上位机管思考”的二次开发架构。本文以迅翼 S7 视觉版这类开源固定翼垂直起降或固定翼平台的开发方式为主线介绍如何从环境准备、仿真验证、视觉接入到 offboard 任务控制搭建一套可学习、可复现、可扩展的自主飞行开发环境。需要先说明的是不同厂家、不同版本的固定翼平台在机身结构、飞控固件和机载电脑配置上会有差异。下面所有命令和代码都用于说明开发思路落地到具体机型前要先确认固件版本、参数和通信协议是否一致。1. 先理解 ROS PX4 固定翼二次开发平台的组成结构1.1 固定翼视觉自主飞行难点为什么在软件架构固定翼飞行器的控制难点在于“不能停下来”。飞机一旦在空中就始终需要满足空速、姿态和高度约束。视觉算法如果突然丢帧飞控必须能自动接管回到航点模式或返航视觉目标识别如果出错任务决策层必须能判断置信度否则一个误检就可能引导飞机朝错误方向飞行。因此固定翼视觉自主飞行平台的软件架构至少要保证三件事第一感知结果能快速准确地进入飞控坐标系。相机安装在机身上图像检测得到的目标框需要通过相机内参、外参和机体姿态转换到机体坐标系再进一步转换到 NED 或 ENU 导航坐标系。这个链路如果只写代码而不做标定视觉定位结果一定是不准确的。第二飞控和安全逻辑不能完全交给上位机。固定翼一旦进入失速、超速或高度异常必须由 PX4 自身的状态机处理不能依赖 ROS 节点是否健康。ROS 节点崩溃时飞控要能通过超时机制自动退出 offboard 模式执行预设安全行为。第三仿真、真机要尽量复用同一套代码。开发阶段先在 Gazebo 里跑通感知、决策、控制闭环再切换到真机能大幅减少试错成本。PX4 SITL 的意义就在于把飞控固件跑在本地用仿真环境替代真实机体让 ROS 节点以为自己在和真实飞控通信。1.2 PX4 飞控、ROS 机载电脑和 MAVROS 的分工以迅翼 S7 视觉版这类典型的 ROS PX4 二次开发平台来看整机可以拆成四个软件层次层次运行载体典型组件职责飞行控制层Pixhawk 系列飞控或集成式飞控PX4 Autopilot姿态控制、速度控制、航点跟踪、安全策略、传感器融合通信桥接层机载电脑或地面站MAVROS / MAVLink在 ROS 与 PX4 之间转发消息感知计算层机载电脑ROS 节点、OpenCV、深度学习模型图像采集、目标检测、视觉定位、避障判断任务决策层机载电脑状态机、航点规划、自主任务脚本根据视觉结果和目标航点生成飞行指令PX4 本身已经内置了固定翼的航点跟踪、返航、失联保护和降落逻辑。ROS 一侧不需要重复实现底层控制重点做两件事感知任务和环境理解、任务级决策。MAVROS 是两者之间的桥它把 MAVLink 消息映射为 ROS 话题和服务例如/mavros/state表示飞控状态/mavros/setpoint_position/global可以把期望航点发给飞控。1.3 视觉版二次开发平台通常包含哪些功能模块标题里提到“视觉版”意味着这类平台除了基础飞行能力之外还会预留相机接口和视觉计算单元。常见的功能模块包括相机驱动模块负责读取可见光相机或双目相机图像发布到 ROS 话题。视觉定位模块通过视觉里程计或 AprilTag 标志物估计机体在外部坐标系中的位置。目标检测与跟踪模块检测降落区域、目标车辆或固定目标输出目标相对机体的位置。避障模块基于单目、双目或激光雷达数据向前方障碍物检测把限速或绕行指令交给飞控。航点任务模块按预设航线飞行并在到达指定区域后触发视觉流程。在开发初期不一定要让所有模块都运行起来。更合理的学习路径是先跑通 ROS 与 PX4 的通信再在仿真里完成航点任务然后加入视觉检测最后再把视觉结果与飞控控制闭环连接起来。2. 环境准备把 Ubuntu、ROS 和 PX4 工具链对齐2.1 版本选型不要只看最新匹配关系更关键ROS、PX4、MAVROS 之间没有“最新版本一定最好”的说法。固定翼二次开发涉及源码编译、仿真通信和飞控参数版本不匹配会出现编译通过但运行异常、或者 MAVLink 消息字段对不上的问题。以一套比较成熟、社区资料丰富的组合为例组件推荐选择说明操作系统Ubuntu 20.04长期支持版本ROS Noetic 官方支持ROS 发行版Noetic官方支持 Ubuntu 20.04资料最全PX4 Autopilotv1.13 或 v1.14如果使用较新的 PX4 版本需要单独确认 Gazebo 和 MAVLink 兼容性MAVROSmelodic/noetic 对应版本通过apt install ros-noetic-mavros安装GazeboGazebo Classic 11PX4 1.14 默认推荐 Gazebo Classic这里要注意PX4 较新版本已经逐步迁移到 Gazebo 新版本官方文档也给出了不同的启动方式。如果你的平台说明书明确指定了某一版 PX4 固件不要自行升级到最新版否则飞控参数、混控器和 MAVLink 消息都可能变化。2.2 安装 ROS 并配置国内源安装 ROS 的常见方式是先添加 ROS 软件源再安装完整桌面版。由于网络环境差异源码或软件源下载失败很常见国内开发者可以优先使用清华、阿里云或中科大等镜像源。安装基础步骤sudo sh -c echo deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main /etc/apt/sources.list.d/ros-latest.list sudo apt install curl curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add - sudo apt update sudo apt install ros-noetic-desktop-full如果网络不稳定也可以使用社区提供的一键安装脚本。搜索材料中经常提到的“鱼香ROS”一键安装就是一个社区维护的 ROS 安装工具适合快速搭建学习环境。它会把 ROS、常用依赖和部分工具链一起安装降低新手配置成本。但要注意一键脚本适合开发环境生产项目或定制化平台仍然建议手工安装并且记录每个依赖的来源和版本。安装完成后初始化 rosdepsudo rosdep init rosdep update如果 rosdep 更新失败可以检查网络和 rosdistro 源。这里的关键不是“能不能装上”而是装完后能否稳定解析package.xml中的依赖。检查环境是否正常source /opt/ros/noetic/setup.bash roscore能看到节点启动并且没有报错说明 ROS 基本环境可用。2.3 编译 PX4 固件并验证 SITL 工具链PX4 源码使用 Git 和 GCC 交叉编译工具链。拉取源码时要注意子模块不--recursive会导致后续编译缺少模块。cd ~ git clone https://github.com/PX4/PX4-Autopilot.git --recursive -b v1.14.0 cd PX4-Autopilot git submodule update --init --recursive如果源码拉取因为网络原因失败可以换用国内可访问的镜像仓库或稍后重试。拉取完整源码后运行 PX4 自带的检查脚本确认系统依赖是否完整bash ./Tools/setup/ubuntu.sh这个脚本会安装编译 PX4 所需的工具链。然后编译固定翼仿真目标make px4_sitl gazebo-classic_plane第一次编译时间比较长正常现象。编译完成后会看到启动提示PX4 固件已经运行在 SITL 模式下。关闭它之后再启动一次确保固定翼模型能正常加载。到这里ROS、PX4、Gazebo 三个核心工具都已就绪。下一步开始跑通仿真。3. 搭建 Gazebo 固定翼仿真环境3.1 PX4 SITL 与 Gazebo 的启动流程PX4 SITL 的意思是把完整的 PX4 飞控固件编译成可在 Ubuntu 上运行的程序并通过网络与 Gazebo 仿真器通信。对 ROS 节点来说SITL 和真实飞控的行为几乎一致。启动固定翼仿真cd ~/PX4-Autopilot make px4_sitl gazebo-classic_plane启动后Gazebo 窗口会加载固定翼模型。你可以在 QGroundControl 地面站中看到飞控在线。此时 PX4 会监听 UDP 端口通过 MAVLink 对外通信。启动 QGroundControl它会自动发现 SITL 飞控。之后可以在仿真环境中手动起飞验证飞机模型、舵面和推力是否正常工作。3.2 使用 MAVROS 连接仿真飞控启动 PX4 SITL 后再用另一个终端启动 MAVROSsource /opt/ros/noetic/setup.bash roslaunch mavros px4.launch fcu_url:udp://:14540127.0.0.1:14557fcu_url指定 MAVROS 与飞控通信的地址。SITL 默认监听14540端口并通过14557发送数据。启动正常后打开新终端查看飞控状态rostopic echo /mavros/state输出中connected: True说明 MAVROS 已经和 PX4 建立连接。armed: False说明飞控尚未解锁。这表示通信链路可用。也可以查看本地位置和姿态rostopic echo /mavros/local_position/pose rostopic echo /mavros/global_position/global这些话题是自主飞行开发的基础数据来源。3.3 固定翼仿真参数和起飞验证固定翼仿真与四旋翼不同起飞阶段需要跑道或弹射不能直接垂直起飞。可以在 QGroundControl 中切换到Fixed-wing机型然后在任务模式里添加航点或手动遥控油门起飞。在 SITL 中最简单的方式是先用 MAVROS 向飞控发布起飞指令但固定翼的自动起飞对航点参数和跑道模型要求较高。更稳妥的学习方式是在 QGroundControl 中用手动模式把飞机推上跑道然后切到自动模式执行航点。需要注意SITL 中的键盘控制或摇杆操作依赖 QGroundControl 的虚拟摇杆设置。仿真中几个常见参数含义参数默认值参考含义影响NAV_LOITER_RAD50盘旋半径飞机在等待航点时绕圈半径FW_AIRSPD_MIN10最小空速低于此值飞控会为避免失速而推油门FW_AIRSPD_MAX30最大空速限制油门输出和速度范围FW_PN_R0.1滚转角控制 P 增益过大容易震荡MIS_DIST_1WP900航点切换距离到达航点判定距离在仿真中修改参数的方法是在 QGroundControl 参数界面修改或通过 MAVROS 参数服务修改rosservice call /mavros/param/set param_id: NAV_LOITER_RAD value: {integer: 50, real: 50.0}3.4 仿真环境的检查点很多开发者把“仿真能启动”当成“仿真环境可用”这是误解。至少要做以下几个验证固定翼能否在手动模式下维持平飞。油门变化后空速是否按预期增加。切换到自动模式后飞机能否到达第一个航点。MAVROS 能否在任务执行过程中稳定读取位置和姿态。只有这些都正常才能在仿真里继续做视觉和 offboard 开发。否则后续每次遇到控制异常都要回过来排查是否底层通信不稳。4. 视觉感知链路相机、标定与 MAVLink 视觉消息4.1 相机驱动和 ROS 图像话题视觉版二次开发平台通常会在机身安装一个前置或多个感知相机。相机驱动完成后会在 ROS 中输出图像话题。常见相机驱动的输出话题形式/camera/rgb/image_raw /camera/depth/image_raw查看图像是否正常rqt_image_view /camera/rgb/image_raw在固定翼飞行中相机通常朝前下方安装既要看到前进方向的障碍物也要识别地面目标。实际使用时需要根据安装角度配置相机外参。4.2 相机标定不能跳过视觉结果要用于飞行控制必须做相机标定否则后续的距离估计和坐标转换都无法信任。相机内参标定常用 ROS 的camera_calibration功能包。准备一张棋盘格标定板然后运行rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.024 image:/camera/rgb/image_raw标定完成会生成相机内参矩阵和畸变系数。标定结果不仅给目标检测使用更重要的是给视觉定位的坐标转换使用。固定翼相机安装角度固定标定结束后还要测量相机在机体坐标系中的安装偏移写入 TF 树。4.3 把视觉定位结果接入 PX4PX4 本身具备 EKF2 传感器融合能力。当外部视觉系统能提供稳定的位置估计时可以通过 MAVLink 消息把视觉位置送给飞控。MAVROS 提供了对应的话题/mavros/vision_pose/pose向该话题发送geometry_msgs/PoseStampedMAVROS 会转换为VISION_POSITION_ESTIMATE消息发送给 PX4。PX4 侧需要设置 EKF 参数启用视觉融合。常见参数包括参数值说明EKF2_AID_MASK包含 external vision启用外部视觉位置作为辅助EKF2_EV_CTRL包含水平位置、垂直位置等设置视觉数据参与融合的维度EKF2_EV_POS_X/Y/Z相机相对机体位置补偿安装偏移需要强调的是视觉定位融合是一个涉及大量参数和校验逻辑的功能不要在仿真中看到消息就判断可以真机使用。必须先确认视觉输出的频率、延迟和坐标系方向。4.4 视觉避障的两种实现思路固定翼视觉避障在工程上有两种常见思路第一种是“绕行式避障”。机载电脑通过视觉检测到前方障碍物后在 ROS 中规划一个新的局部目标点通过 offboard 模式把绕行航点发给飞控。这种思路适合障碍物稀疏、执行速度要求不高的场景。第二种是“限制式避障”。视觉模块计算出前方危险距离后不直接接管航向而是通过转发限速、限航向建议给飞控或者直接触发飞控的航向偏移。这种思路更适合固定翼因为固定翼机动能力有限不能像四旋翼一样急停。具体实现时建议先在 Gazebo 中模拟目标用 ArUco 码或简单色块当作检测目标。检测到目标后计算目标在图像中的位置偏差再转换成相对机体的方位角用 MAVROS 话题发送给飞控。5. 自主飞行任务开发用 offboard 模式构建控制闭环5.1 offboard 模式的核心机制offboard 是 PX4 中最重要的外部控制模式。它允许地面站或机载电脑向飞控发送设定值由飞控执行姿态、速度或位置控制。对于固定翼视觉任务offboard 模式通常用于视觉目标跟踪。局部避障航点。特殊测量任务。offboard 有一个关键安全机制飞控必须持续收到设定值否则会自动退出 offboard。常用代码如下#!/usr/bin/env python3 import rospy from geometry_msgs.msg import PoseStamped, TwistStamped from mavros_msgs.msg import State from mavros_msgs.srv import CommandBool, SetMode import time class OffboardControl: def __init__(self): rospy.init_node(offboard_control_node) self.state State() self.position_setpoint PoseStamped() self.velocity_setpoint TwistStamped() self.position_pub rospy.Publisher(/mavros/setpoint_position/local, PoseStamped, queue_size10) self.velocity_pub rospy.Publisher(/mavros/setpoint_velocity/cmd_vel, TwistStamped, queue_size10) rospy.Subscriber(/mavros/state, State, self.state_callback) self.arm_service rospy.ServiceProxy(/mavros/cmd/arming, CommandBool) self.set_mode_service rospy.ServiceProxy(/mavros/set_mode, SetMode) def state_callback(self, msg): self.state msg def wait_for_connection(self): while not rospy.is_shutdown() and not self.state.connected: rospy.sleep(0.1) def set_offboard_mode(self): mode SetMode() mode.custom_mode OFFBOARD return self.set_mode_service(mode) def arm_vehicle(self): arm CommandBool() arm.value True return self.arm_service(arm) if __name__ __main__: ctrl OffboardControl() ctrl.wait_for_connection() # 持续发送设定值同时切换模式 rate rospy.Rate(20) while not rospy.is_shutdown(): ctrl.position_pub.publish(ctrl.position_setpoint) if ctrl.state.mode ! OFFBOARD: ctrl.set_offboard_mode() else: ctrl.arm_vehicle() rate.sleep()这段代码的核心是循环发布设定值。切换 offboard 模式前必须先发布一段时间设定值否则飞控可能拒绝切换。这个细节最容易忽略也是新手最常见的报错来源。5.2 编写一个航点跟踪程序视觉任务通常以航点为基础。例如飞机先飞到目标区域上空再开启视觉识别。以下代码实现一个简单的 offboard 航点发布逻辑def fly_to(self, x, y, z): self.position_setpoint.pose.position.x x self.position_setpoint.pose.position.y y self.position_setpoint.pose.position.z z self.position_setpoint.pose.orientation.w 1.0 for _ in range(100): self.position_pub.publish(self.position_setpoint) rospy.sleep(0.05)这里的100次循环是为了确保飞控连续收到同一个设定值避免因为发布中断而退出 offboard。实际任务需要根据飞行速度、航点距离和任务阶段决定切换时机。要注意的是固定翼的 offboard 位置控制依赖飞控的航向和最小空速约束。不要直接发送一个角度过大的目标点飞机需要时间转弯。否则飞控会尝试以最大滚转角转弯可能导致高度下降或速度异常。5.3 视觉目标跟踪的任务闭环视觉目标跟踪的闭环可以这样设计视觉节点检测目标输出目标中心在图像中的像素坐标(u, v)。根据图像中心偏差计算偏航角偏差yaw_error。在 offboard 模式下把当前位置和期望偏航角度发给飞控。如果目标丢失进入搜索模式保持当前高度盘旋。示例中利用 MAVROS 发布带偏航角的位置设定值def track_object(self, target_x, target_y): # 计算图像偏差 dx target_x - image_center_x dy target_y - image_center_y # 简化处理根据偏差调整目标点 self.fly_to(current_position.x dx * gain_x, current_position.y dy * gain_y, current_position.z)这个示例只能说明框架实际项目中还需要考虑滤波、目标丢失判断、跟踪目标切换等逻辑。5.4 任务切换和安全保护不要让 ROS 程序一直占用 offboard 模式。视觉任务完成后要主动切回自动模式或返航模式把控制权交还给飞控mode SetMode() mode.custom_mode AUTO.RTL self.set_mode_service(mode)同时机载电脑要监听飞控状态。如果视觉节点异常退出要确保飞控能自行处理。建议在任务主循环中定期检查/mavros/state的mode和armed字段出现异常时记录日志并切换安全模式。6. 常见问题排查从启动失败到飞行异常6.1 PX4 源码拉取失败或编译报错现象git clone卡住或编译时报找不到头文件。排查步骤确认拉取命令中是否包含--recursive。检查网络是否稳定必要时换用镜像源或稍后重试。确认系统架构和 Ubuntu 版本是否匹配。检查px4-fmu-v5等硬件平台是否选对SITL 编译使用px4_sitl目标。不要第一反应怀疑工具链损坏。多数编译问题是子模块缺失和依赖未更新导致的。6.2 ROS 话题没有数据现象rostopic echo /mavros/local_position/pose没有输出。检查链路PX4 SITL 是否正常运行Gazebo 是否加载了飞机模型。MAVROS 日志中connected: True还是False。端口是否被占用fcu_url是否与 SITL 端口一致。是否执行了source /opt/ros/noetic/setup.bash。常见原因是先启动 MAVROS、后启动 SITL或者端口写错。6.3 相机图像显示黑屏或无法打开现象rqt_image_view打开后看不到图像。原因可能包括相机权限不足、话题名不对、相机本身未上电。先用ls /dev/video*确认设备节点用v4l2-ctl --list-devices确认相机枚举情况再对比驱动节点发布的图像话题名。在真机上不要忽略相机供电问题。一些视觉版平台会设计独立电源开关需要确认机载电脑和相机已经正常上电。6.4 offboard 模式切换失败这是固定翼开发中最常见的问题。原因通常有两个第一没有预先向飞控发送设定值。PX4 要求收到一段时间的 offboard 设定值后才允许切换模式。第二设定值不在合理范围内。例如位置目标点距离起飞点太远或目标高度超出飞控参数限制。建议先发送当前飞机位置作为设定值切换成功后缓慢向前推进。检查方式rosservice call /mavros/set_mode custom_mode: OFFBOARD rostopic echo /mavros/state如果返回mode_changed: false优先确认设定值话题发布频率。6.5 固定翼飞行中姿态震荡或高度掉高现象切到 offboard 后飞机左右摇摆或者持续掉高度。可能原因设定值更新频率不够飞控不能得到平滑的控制轨迹。位置控制 P 增益过高导致机动过度。设定点有跳变例如从当前位置直接跳到横向 50 米外的航点。视觉定位数据噪声大进入飞控融合后造成位置估计抖动。处理方式是先让固定翼平飞修改目标点时逐步逼近不要一步到位。同时降低视觉数据的噪声使用滑动平均或卡尔曼滤波后再发送给飞控。6.6 常见问题速查表问题现象常见原因检查顺序处理建议源码编译失败子模块缺失检查 git submodule重新git submodule update --init --recursiveMAVROS 连接失败端口或启动顺序错误查看 MAVROS 日志先启动 SITL再启动 MAVROS核对端口图像话题不存在驱动未启动或话题名不同rostopic list按实际驱动节点名订阅offboard 切不过去缺少设定值或参数限制检查 setpoint 发布频率先发当前位置设定值再切换模式飞机掉高度机动过大或视觉噪声查看姿态和设定值变化平滑目标点、降低噪声、检查空速下限视觉定位不准未标定或坐标系错误检查 TF 树和相机外参重新标定确认坐标轴方向7. 针对固定翼二次开发的最佳实践和扩展方向7.1 代码组织仿真与真机复用是一开始就要考虑的事不要为仿真和真机各写一套代码。尽量把 ROS 节点分成三层驱动层负责相机、飞控等硬件抽象真机与仿真选择不同驱动但输出话题一致。算法层目标检测、视觉定位、避障判断与机型和传感器无关不应修改。决策层航点任务、offboard 控制逻辑根据真机参数做微调。这样的结构可以让大部分开发工作在仿真中完成。真机测试前只需要替换驱动层参数而不需要重写控制逻辑。7.2 二次开发发布前检查清单在真机测试或正式部署前建议逐项确认检查项具体内容固件版本PX4 版本与平台说明书一致参数备份完整通信链路MAVROS 连接状态正常掉线重连逻辑已处理坐标系相机外参、机体坐标系、导航坐标系全部确认视觉模型目标检测模型使用的训练数据覆盖实际飞行场景安全模式视觉丢失、offboard 超时、电量不足时的飞控策略日志视觉节点、控制节点、飞控日志都要能回溯权限飞行场地合规具备必要的操作许可应急操作遥控器切换手动模式的操作人员到位有些问题在仿真里不会被发现。例如相机曝光、运动模糊、真机振动对 IMU 的影响只有在真实环境下才能暴露。因此第一轮真机飞行要以人工遥控为主不要从一开始就完整执行自主任务。7.3 从视觉航点到自主任务的扩展方向当 ROS PX4 的固定翼自主飞行链路跑通后可以在现有平台上继续扩展加入深度学习目标检测提高目标识别泛化能力。使用双目相机或激光雷达实现稠密深度估计和更可靠的避障。增加任务状态机把起飞、航点、目标识别、自动降落串成完整流程。接入地面站或云平台实现远程任务下发和飞行日志回传。对固定翼平台做更精细的动力学建模用于训练和学习算法。对于刚入门固定翼二次开发的开发者最重要的练习不是直接写复杂的视觉跟踪而是先实现一个在所有模式下都能稳定运行的 offboard 控制节点并配合 QGroundControl 观察飞行曲线。视觉感知可以逐步加入但飞控通信、模式切换和安全保护才是整个平台能不能从仿真走到真机的根基。把这部分完全理解并掌握后续再接手迅翼 S7 视觉版这类具体机型的视觉任务就会有更清晰的开发路径和排查思路。
返回列表