
无人机在室外靠GPS放飞自我一进室内就彻底成“盲鸟”——这应该是很多玩PX4的朋友最头疼的问题。我自己调室内无人机踩了不少坑最后稳定下来的方案就是用Intel RealSense T265做视觉惯性里程计VIO配合ROS把位姿喂给PX4飞控让EKF2做状态估计。这篇直接把硬件连接、软件配置、PX4参数、调试避坑一次讲清楚适合刚接触ROS和PX4、想在室内跑定点甚至自主飞行方向的新手。文中所有参数和步骤都是我实际跑通过的方案你可以直接照着抄。1. 方案选型室内定位为什么选T2651.1 室内定位的常见思路对比室内没有GPS无人机要稳住位置必须自己想办法知道“我在哪”。目前主流方案无非这么几种光流测距模块、UWB超宽带、动捕系统以及视觉SLAM/VIO。我一个个说下实际体验。光流模块比如PX4FLOW这类的原理是拍摄地面纹理通过图像运动推算水平位移再配合激光测距或者气压计获得高度。这套方案胜在便宜、轻量、功耗低小四轴上很常见。缺点也非常明显它本质上是在“数像素”对地面纹理要求高地砖、地毯、纯色地面都会导致数据跳变而且光流测的是相对位移时间一长必然累积漂移很难长时间悬停在一个点上。UWB是近几年很火的室内定位方案靠布置三四个基站解算标签位置精度能做到10~30厘米左右。它不受光照影响也不怕地面没纹理。但代价是你要先布置基站、标定基站坐标移动性差换一个场地就得重新布置而且UWB输出的位置更新频率一般只有20~50Hz快速机动时容易跟不上。动捕系统Vicon、OptiTrack等精度确实最高亚毫米级但价格也最“劝退”一套少说十几万还要固定场地、贴反光点。除非是实验室做科研写论文一般个人玩家和多数工程场景根本用不起。剩下就是T265这种视觉惯性方案。它把双鱼眼相机和IMU集成在一个小盒子里内部用VIO算法实时算出6自由度位姿不需要外部基站不依赖GPS插上USB就能输出位置和姿态。因为双鱼眼视场角大IMU频率又高短时间内的定位精度和稳定性相当能打特别适合无人机这种运动快的载体。T265虽然官方已经停产但二手市场货源充足资料和教程遍地都是拿来入门视觉定位再合适不过。1.2 T265的VIO定位原理T265能定位靠的是“视觉惯性”融合。两个鱼眼镜头以190°左右的视场角同时采集图像覆盖周围大范围环境内置的IMU则以约200Hz频率测量加速度和角速度。视觉提供“我相对之前的位置移动了多少”IMU提供“我在加速、在转”两者互补再用内部的融合算法输出一个完整的6自由度位姿即XYZ位置加四元数姿态。从原理上理解视觉部分擅长感知环境的“不变特征”能纠正IMU短时间积分带来的漂移而IMU反应快能在图像曝光和曝光之间提供高频运动预测尤其在快速转弯、剧烈加减速时纯视觉容易丢帧IMU能顶住。这就像你闭着眼走直线容易偏离但睁着眼一直盯着路边路灯就能走得很准。T265就是让“眼睛”和“内耳”互相校正。它输出的位姿是相对于启动时刻建立的“局部世界坐标系”在ROS里通常体现为camera_odom_frame到camera_pose_frame的变换。换句话说每次上电开机原点就是当时设备所在的位置和朝向这决定了你每次起飞前要让无人机和T265保持静止让它把“零点”记住。这个特性实际用起来很重要下文调试部分我会再强调。T265另一个优点是直接输出处理好的位姿不需要你在机载电脑上再跑ORB-SLAM之类的算法。市面上很多无人机视觉方案要装一个沉重的AR标签板或者用树莓派跑VINS-Fusion算力压力大延迟还高。T265等于把算法硬件化、集成化了对入门者极其友好。1.3 整体架构与数据流这套方案的完整数据链路是这样的T265通过USB3.0连接机载电脑通常是jetson nano、树莓派4B或笔记本realsense-ros驱动把VIO位姿和IMU数据发布到ROS话题我们再写一个转发节点把位姿转成MAVROS的vision_pose/pose话题MAVROS包装成MAVLink消息发给PX4飞控最后PX4的EKF2估计器把视觉位姿和飞控自身的IMU、气压计融合输出稳定位置供Position模式、Offboard模式使用。看到这里你可能会问T265已经自带IMU了能不能把它的IMU数据也一起发给PX4我的经验是不要这样干。PX4的EKF2有自己的陀螺仪和加速度计你只需要喂给它外部视觉位姿就够了。把T265的IMU再灌进去等于让飞控同时处理两套IMU标定不一致时反而容易把状态估计搞乱。数据流里要理清的只有“视觉位姿”这一路。整体架构中还有个容易绕晕的概念——坐标系。ROS默认坐标系是ENUX东、Y北、Z上而PX4的机体坐标系是NEDX北、Y东、Z下。这套方案里MAVROS会在底层自动完成ENU到NED的转换所以你只需要保证ROS侧给MAVROS的数据是ENU下的准确位姿就行千万别自己在转发节点里手动“转NED”否则两边各转一次结果必定歪掉。2. 环境搭建Ubuntu、ROS和T265驱动2.1 系统与ROS版本选择这个方案最省心的是Ubuntu 20.04 ROS Noetic组合因为realsense-ros和mavros都有非常成熟的预编译包不用自己编译源码能少踩一半的坑。如果你手头是Ubuntu 18.04那用ROS Melodic也可以但建议驱动相关依赖尽量跟着发行版的默认版本走不要混装。至于PX4固件建议v1.11以上本文的EKF2参数说明也是基于v1.11到v1.13这个区间的。老一点的v1.8、v1.9不是不能用但参数位定义和现在有不少差异照抄下面的值可能会出现“看起来设置了但EKF根本没融合视觉数据”的情况。如果你用的是机载电脑和飞控分离的结构飞控端固件建议直接用QGroundControl升级到最新稳定版再用USB连上机载电脑做参数配置。ROS本身安装没什么好说的桌面完整版就行sudo apt update sudo apt install ros-noetic-desktop-full如果你刚配Ubuntu环境嫌手动初始化rosdep麻烦现在也有鱼香ROS这种一键安装脚本对新手确实省时间。不过我个人建议至少手动跑一遍官方流程了解工作空间、source环境这些基础概念后面排查问题会顺手很多。2.2 安装并验证T265驱动T265的官方驱动是librealsenseROS封装叫realsense-ros。Ubuntu 20.04 Noetic直接用apt装预编译包最方便sudo apt install ros-noetic-realsense2-cameraT265需要USB3.0带宽一定要插蓝色USB口而且别用太长的延长线。USB3.0对线材质量很敏感我之前用一根3米普通延长线T265频繁掉线换成带供电的主动延长线之后就稳定了。这个坑很隐蔽排查半天才发现是供电问题。装好后先插上T265用工具确认设备枚举是否正常rs-enumerate-devices如果能看到设备并显示两个鱼眼镜头型号说明驱动识别没问题。接下来启动ROS驱动验证数据roslaunch realsense2_camera rs_camera.launchT265默认会发布/camera/odom/samplenav_msgs/Odometry也就是VIO位姿和/camera/imusensor_msgs/Imu同时也会发布左右鱼眼图像话题。用下面命令确认rostopic list | grep camera rostopic echo /camera/odom/sampleecho位姿时拿着T265在手里慢慢平移观察position数值跟着变化说明VIO已经正常工作了。这一部一定要在装机前完成否则后面装到无人机上再调试很难分清是硬件问题还是软件问题。如果你发现rostopic里没有IMU话题或者没有pose话题多半是launch里没开对应开关。我建议自己写一个launch文件显式开启pose、gyro、accellaunch arg nameunite_imu_method default1/ include file$(find realsense2_camera)/launch/rs_camera.launch arg nameenable_pose valuetrue/ arg nameenable_gyro valuetrue/ arg nameenable_accel valuetrue/ arg nameunite_imu_method value1/ /include /launchunite_imu_method1的作用是把gyro和accel合并到一个IMU话题里避免两个话题在时间戳上不同步。T265的IMU数据虽然我们不直接喂给PX4但realsense-ros内部融合位姿时可能会用到IMU话题的发布状态所以建议一并开着。2.3 驱动输出的话题类型和坐标系这里稍微细说一下T265输出的数据形态。realsense-ros驱动主要发布两类位姿相关话题一类是/camera/odom/sample类型是nav_msgs/Odometry包含位置、姿态四元数、以及对应的协方差另一类可能是/camera/pose/sample类型是geometry_msgs/PoseStamped。不同版本驱动略有差别所以你在抄网上的转发脚本前一定要先用rostopic info看准当前驱动实际发布的是哪个话题。坐标系方面T265的odometry话题通常以odom作为world framecamera_pose_frame作为body frame。驱动还会发布odom到camera_pose_frame的TF变换。这里有个常见的理解误区T265输出的“odom”并不是PX4里的odom我们只需要把它的位置和姿态取出来作为“外部视觉观测”送给PX4的EKF不需要去和飞控的TF树强行对齐。等于说T265是一个“能告诉你相对零点移动了多少”的传感器而不是飞控导航系统的一部分。要特别提醒的是T265的两个鱼眼镜头怕强光尤其是太阳直射。室内使用时尽量别让镜头正对窗外的强光或者大功率射灯过曝会导致特征点丢失位姿瞬间漂移甚至卡住。无人机在室内飞行时最好给T265配一个遮阳罩能显著提高稳定性。3. 让PX4吃上T265数据MAVROS桥接与参数配置3.1 安装并启动MAVROSMAVROS是ROS和PX4之间的官方桥接通道。在Noetic下直接apt安装即可sudo apt install ros-noetic-mavros ros-noetic-mavros-extras装完MAVROS后按官方流程还要下载GeographicLib的数据集主要用于磁偏角补偿室内定位不依赖它但如果以后要切换到室外GPS模式建议还是补上免得以后报一堆奇怪的警告。连接飞控和机载电脑一般有两种方式。如果你用的是飞控USB口直接连机载电脑常见命令是roslaunch mavros px4.launch fcu_url:/dev/ttyACM0:921600如果飞控通过数传模块连机载电脑fcu_url就要改成类似/dev/ttyUSB0:57600的串口配置具体波特率看你的数传型号。启动后先验证MAVROS是否收到飞控数据rostopic echo /mavros/state如果能看到connected: true说明MAVROS和飞控通信正常。飞控这边建议先在QGroundControl里把参数配置好再启动MAVROS顺序反了容易让EKF在启动早期错过视觉数据。3.2 写一个转发节点把T265位姿送入MAVROSMAVROS提供/mavros/vision_pose/pose话题专门接收外部视觉位姿类型是geometry_msgs/PoseStamped。我们只需要写一个简单节点把/camera/odom/sample里的pose转发过去即可。脚本我用python写Noetic下面默认就是python3兼容性没问题。#!/usr/bin/env python3 import rospy from nav_msgs.msg import Odometry from geometry_msgs.msg import PoseStamped pub rospy.Publisher(/mavros/vision_pose/pose, PoseStamped, queue_size10) def callback(msg): pose PoseStamped() pose.header.stamp msg.header.stamp pose.header.frame_id odom pose.pose msg.pose.pose pub.publish(pose) if __name__ __main__: rospy.init_node(t265_to_mavros) rospy.Subscriber(/camera/odom/sample, Odometry, callback) rospy.spin()把脚本保存成t265_to_mavros.py加上执行权限然后rosrun运行。如果驱动发布的是/camera/pose/sample就把Subscriber的类型改成PoseStamped回调里直接取msg.pose即可。关于frame_idMAVROS其实不太在意这个字段但我习惯填“odom”避免后续用Rviz查看时TF树对不上。启动顺序建议是先启动T265驱动再启动这个转发节点最后启动MAVROS。这样MAVROS一启动就能立刻收到vision poseEKF不会因为等待数据而进入保守模式。3.3 PX4参数配置详解这套方案的灵魂在这一节。PX4使用EKF2做状态估计要让飞控认可用T265的视觉数据需要配置几个关键参数。在QGroundControl的“参数”页面直接搜索修改即可。我直接给一套我实测可用的参数组合适用于PX4 v1.11至v1.13T265作为室内唯一外部定位源参数名推荐值作用说明SYS_MC_EST_GROUP1使用EKF2估计器而不是旧的Q估计器EKF2_AID_MASK12按位启用视觉位置融合和视觉偏航融合EKF2_EV_CTRL1允许融合外部视觉水平位置与高度EKF2_HGT_MODE3高度源选择视觉高度室内气压计不稳时更可靠EKF2_EV_DELAY0视觉数据延迟补偿默认0即可EKF2_EV_POS_X0视觉传感器相对飞控坐标系的前向偏移EKF2_EV_POS_Y0视觉传感器相对飞控坐标系的右向偏移EKF2_EV_POS_Z0视觉传感器相对飞控坐标系的向下偏移EKF2_AID_MASK这个参数特别容易抄错。它是个位掩码每个bit代表一类传感器融合选项按官方位定义bit2对应视觉位置bit3对应视觉偏航所以4812。如果你用的PX4版本较老或者QGC界面上显示的是可勾选的复选框建议直接在界面上勾选“vision position fusion”和“vision yaw fusion”比硬记数字更不容易错。网上很多教程写EKF2_AID_MASK1那是另一种位定义或者老版本的习惯直接照抄容易翻车。EKF2_EV_POS_X/Y/Z三个偏移参数指的是T265安装位置相对于飞控机体坐标系原点的偏移。如果T265装在机架中心上方三个值都可以保持0。如果相机装在机头前方、离飞控中心比较远就必须量好距离填进去否则EKF做坐标旋转时会产生杠杆臂误差飞机在激烈机动时会明显感觉到位置估计“晃”。高度源这里多说一句。EKF2_HGT_MODE3表示用视觉高度作为主要高度来源因为室内气压计会受空调气流、飞机旋翼气流干扰数值经常飘。但视觉高度也有自身问题VIO对Z轴的估计在垂直方向快速运动时偶尔会漂。我的经验是如果悬停高度稳定就用视觉高度如果发现高度慢慢上浮下沉可以改回EKF2_HGT_MODE0气压计高度比较两种模式的实际表现再定。无人机试飞本来就是变量控制一次只改一个参数记住“改动最小原则”。另外还有一个重要提示室内没有GPS信号时飞控可能会因为丢失GPS而报警甚至切换飞行模式。建议在QGC里确认GPS相关融合选项没有被强制启用最好把EKF2_AID_MASK中的GPS位明确关闭避免GPS偶发性飘星把位置估计带跑。有些版本有SYS_USE_GPS参数室内纯视觉场景直接置0比较稳妥。4. 实机调试与常见问题排查4.1 上机前的地面测试和标准起飞流程参数配好别急着直接解锁起飞。我建议按下面流程走一遍能提前发现80%的问题。第一步把T265固定到机架上。安装位置尽量靠近机架中心镜头朝前或略带下压角度都可以。固定要刚性不能有明显晃动最好用3M胶加扎带双重固定。T265对震动其实还算耐受但你的机架如果本身震动大建议加一层减震泡棉。第二步上电后保持无人机静止不动5到10秒让T265建立原点同时让PX4的EKF收敛。此时用rostopic echo看一眼/camera/odom/sample确认位置输出基本为零且有微小噪声而不是持续朝一个方向漂移。如果一上电就漂多半是T265初始化时设备本身还在移动或者场景纹理太差。第三步观察QGroundControl里的EKF状态。点开MAVLink Inspector查看VISION_POSITION_ESTIMATE消息是否以固定频率进来。也可以看EKF的innovation值如果视觉位置数据的innovation一直为零说明EKF压根没有使用视觉数据优先检查EKF2_AID_MASK。第四步解锁并切到Position模式缓慢推油让飞机离地半米左右。第一次试飞强烈建议系上安全绳或者装好螺旋桨保护罩室内无GPS新方案第一次放飞机大概率会出现位置抖动或突然漂移安全措施不能省。如果飞机在Position模式下能悬停住但缓慢漂移通常不是大问题多数是T265原点建立时的轻微误差可以在起飞后重新降落、再次上电重新建零点来消除。4.2 典型问题速查表下面这些坑是我自己踩过、以及帮别人排查时见过最多的整理成表格方便你在现场快速定位。现象可能原因排查与解决rostopic里看不到/camera/odom/sampleT265供电不足或USB接触不良驱动未开启pose输出换USB3.0口、换线检查rs-enumerate-deviceslaunch里确认enable_posetrueT265运行一段时间后掉线USB线材质量差、供电不稳、设备过热换带供电的主动延长线避免阳光直晒给T265加散热片或小风扇MAVROS没有收到vision_pose转发节点没启动话题名或类型不匹配rosrun前没source环境用rostopic echo /mavros/vision_pose/pose验证确认订阅的话题实际存在QGC里没有VISION_POSITION_ESTIMATEMAVROS和飞控通信异常转发节点没有成功publish先验证/mavros/state是否connected再echo vision_pose话题EKF innovation里看不到视觉融合EKF2_AID_MASK配置错误EKF2_EV_CTRL被设为关闭GPS位干扰按位检查AID_MASKQGC参数页面勾选vision position和vision yaw悬停时飞机往一个方向缓慢漂移起飞前T265建立原点时飞机有移动场景纹理稀疏重新启动T265并保持无人机静止10秒以上在纹理丰富的区域起飞快速机动时位置估计跳变T265安装不牢固、震动过大EKF2_EV_DELAY设置不合理安装偏移参数没填加固摄像头填写EKF2_EV_POS_X/Y/Z偏移尝试调节EKF2_EV_DELAY高度缓慢上浮或下沉视觉高度漂移室内气压场不稳切换EKF2_HGT_MODE到0或3对比测试检查T265是否被旋翼气流遮挡4.3 飞行安全与后续扩展建议室内飞行最大的风险是“定位突然失效”。T265本质上是一个相对定位传感器它不提供绝对坐标一旦发生视觉丢失位姿就只能靠内部IMU短时间猜猜久了必然漂。所以我在实飞时永远保持手里捏着遥控器切回Stabilized或者手动模式比什么都可靠。不要过度信任任何视觉定位系统这个行业里“飞得好好的突然抽风”才是常态。如果想把这套系统往自主方向扩展几个方向你可以接着研究。第一加一个激光雷达或者UWB做绝对定位的定期校正VIO做高频短时估计两者结合能长时间稳定。第二把T265位姿和PX4的Offboard模式打通后续可以做路径跟踪、自动巡检。第三如果无人机载重要求低T265这一套已经足够轻量机载电脑选jetson nano甚至树莓派4B都能跑得动整机重量能控制在1.5公斤以内。最后再分享一个我个人的心得T265这套方案最大的价值是让新手绕过了“从零手写VIO算法”这个高门槛直接用一套成熟硬件把视觉定位全链路跑通。调室内无人机前几次失败基本都是坐标系、参数位、话题名这类细节问题。只要按“先地面验证驱动、再桥接话题、再配EKF参数、最后小高度试飞”的次序走大多数坑都能提前规避。等你把这条链路跑顺了再回头读PX4的EKF2源码、研究协方差和innovation的物理意义会有一种“原来如此”的通透感。