基于Intel RealSense T265的无人机室内视觉定位与PX4融合实战指南

📅 发布时间:2026/9/29 8:57:27
基于Intel RealSense T265的无人机室内视觉定位与PX4融合实战指南
1. 方案选型为什么室内定位我选了T2651.1 T265到底是个什么硬件第一次接触Intel RealSense T265的人很容易把它误当成普通的深度相机。它确实属于Realsense系列但跟D435那种测深度的摄像头完全不同T265的任务只有一个算清楚“自己”在哪、朝哪个方向运动。它正面带了两颗鱼眼镜头内部还有一颗IMU也就是惯性测量单元这个组合就是典型的视觉惯性里程计英文缩写VIO。T265内部专门有一颗Movidius Myriad X VPU这颗芯片在相机里直接完成图像特征提取、特征跟踪和位姿解算不需要额外接电脑去跑算法。换句话说它输出的不是“画面”而是已经算好的6自由度位姿数据X轴、Y轴、Z轴坐标以及翻滚、俯仰、偏航角。这个数据通过USB线传给上位机上位机再转给飞控整个过程里无人机本体的PX4飞控不需要自己改算法。很多新手会问既然T265自己就能算位姿那为什么还要ROS和PX4参与这里需要分清两个概念T265算的是相对起点的一个轨迹它是一套“感知”系统而无人机要稳定悬停还需要飞控把姿态环、速度环、位置环串起来用这个位姿去做控制。ROS在这里的角色是数据搬运工和坐标系翻译官PX4的角色是把视觉位姿和机载IMU、气压计、磁力计统一融合最终输出一个可用的飞行控制状态。三者的分工实际上就是感知、通信、决策控制三层结构。1.2 几条室内定位路线的对比室内定位的方案并不少我在T265之前也折腾过光流、UWB、动作捕捉各有各的坑。放在一张表里对比会更直观方案典型硬件定位精度成本范围明显限制光流测距Pixhawk 光流传感器厘米级短时长时间会漂几百元依赖地面纹理灯光暗或者地面纯色就失效UWBTag/Anchor几件套10-30厘米数千元要布置基站需要开坐标系标定运动速度高时丢包动捕OptiTrack/Vicon毫米级数万起步价格劝退还需要空旷场地和反光球视觉惯性里程计T265 / 双目相机IMU厘米到分米级一千到几千不能对着纯白墙或强反光面飞长时间有偏航漂移从平衡角度看T265是性价比最高的室内定位方案。它不需要外部基站不依赖GPS通网通电就能自建坐标系在光线正常的室内走廊、实验室、办公室环境下都很稳定。虽然动捕的精度可以吊打它但动捕一套下来够买好几台T265。除了硬件成本我更喜欢T265的一点是它把视觉里程计里最头疼的“多传感器时间同步”问题从源头简化了。鱼眼相机和IMU数据在内部就被同步起来不像自己拿双目相机配IMU还要做时间戳对齐哪怕不精通卡尔曼滤波也能把整套系统跑起来。1.3 视觉惯性里程计的原理尽量说人话VIO的原理用一句话概括摄像头看环境变化IMU感知自身加速度和角速度两者互相“纠错”最后输出一个可信的位姿。具体展开一点。鱼眼镜头拍摄到的图像中有大量角点、边缘、纹理特征算法会提取这些特征点并在连续两帧里匹配它们的位置变化。如果画面中特征点向右移动相机大概率是向左转了或者向右平移了。但单个相机的位姿解算存在尺度模糊和快速运动模糊这时候IMU就派上用场。IMU能给出比较精准的加速度和角速度变化短时间内数值可靠但长时间积分会漂移到离谱。图像和IMU一结合相当于一个靠直觉短时记忆一个靠眼睛做长期校正EKF或者非线性优化再把两者缝合起来就得到了一条相对稳定、带尺度信息的运动轨迹。T265内部的Myriad X芯片干的就是这件事。需要注意的是T265输出的是“相对起始点”的位姿没有绝对意义。每次上电它的起点就是坐标系原点。所以无人机飞控端做视觉定位融合时也只是把视觉里程计当作位置传感器来用而不是当作绝对坐标来源。这个特性决定了后续参数配置里有一些辅助开关必须关掉否则飞控会把视觉位姿和GPS位置混在一起算直接打架。2. 准备工作ROS装好、固件刷好、驱动配好2.1 硬件清单和连接拓扑我手里的这套配置是这样的大家可以参考飞控Pixhawk 6C运行PX4 v1.13或者更新的稳定固件上位机树莓派4B4G内存版本跑Ubuntu 20.04和ROS Noetic定位传感器Intel RealSense T265数传/地面站Zed-F9P RTK只用于户外测试室内一律拔掉GPS模块机架500mm四轴电机选择在300-500g拉力范围桨带保护罩连接方式非常简单T265通过USB3.0线接到树莓派树莓派通过USB或者串口和Pixhawk连接。在实际调试时我是用USB连接飞控的方便省事量产再改串口。需要提醒的是树莓派的USB供电能力不算强T265峰值电流可能到800毫安建议用带独立供电的Y型USB线或加一个USB hub供电不然容易出现USB设备随机掉线的问题。这里有一个新手经常踩的坑T265开机后需要一定时间让内部算法收敛初始的零偏直接上电马上启动飞行会导致前一两分钟的数据有较大漂移。我的习惯是给无人机通电后先让T265和飞控静置至少一分钟确保系统完成初始化。2.2 安装ROS尽量用省心办法ROS的安装对新手来说最大痛点是依赖关系太乱。官方教程是一步一步添加软件源、设置密钥、安装一大堆包光环境变量就要配好几次。国内的话我推荐用鱼香ROS的一键安装脚本它能自动配置源、装ROS本体、装常用依赖省下大量折腾时间。它的本质是帮你把官方步骤封装成脚本里面涉及的关键内容一样都不少只是更省心。如果你坚持手动装ROS Noetic核心步骤也无非是这几条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 echo source /opt/ros/noetic/setup.bash ~/.bashrc source ~/.bashrc装完之后还要把rosdep、catkin_tools这些常用工具补齐。说实话除非你在编译包时遇到奇奇怪怪的依赖问题手动装和脚本装效果基本一样。我自己是在台式机上手动装、在树莓派上用脚本装这样两边环境还能互相验证。2.3 安装realsense-ros驱动T265要跑在ROS里必须要装Intell Realsense官方提供的SDK和ROS驱动。核心是三个包librealsense2、realsense2-camera包和realsense-ros包。安装SDK最省事的是用官方发布源sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key F6E65AC044F831AC80A06379C8B3A5A0276F7FBB sudo add-apt-repository deb https://librealsense.intel.com/Debian/apt-repo $(lsb_release -cs) main -u sudo apt-get install librealsense2-dkms sudo apt-get install librealsense2-utils装好之后先插上T265执行rs-enumerate-devices能看到设备信息就说明驱动OK。然后编译ROS功能包这一步需要先用catkin_make或者catkin build把realsense-ros源码编进工作空间里。mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone https://github.com/IntelRealSense/realsense-ros.git cd ~/catkin_ws catkin_make如果编译过程中缺了ddynamic-reconfigure之类的依赖直接sudo apt install ros-noetic-ddynamic-reconfigure装掉就行。在树莓派上首次编译时间会比较长建议挂个代理或者把Swap空间调大一点不然内存不够会直接OOM。2.4 PX4开发环境准备PX4固件的编译配置我这里不展开全部内容只说跟本方案相关的部分。如果你只是需要刷写固件最简单的办法是用QGroundControl地面站。打开QGC选择飞控型号固件版本选择稳定版PX4会提示是否保留当前参数。刷完固件以后进入参数界面检查SYS_MC_EST_GROUP确认当前估计器是EKF2因为稍后要用的视觉融合参数都挂在EKF2下面。如果你要改PX4源码做二次开发那就需要Linux上的PX4工具链一般是用官方脚本安装git clone https://github.com/PX4/PX4-Autopilot.git --recursive cd PX4-Autopilot ./Tools/setup/ubuntu.sh --no-nuttx make px4_fmu-v6c_default这里提醒一句PX4的版本迭代很快EKF2相关参数在不同版本有增删下面所有参数值都是基于PX4 v1.13和v1.14常见稳定版本写的。如果刷了新版本最好对照官方参数文档再确认一遍。3. 让T265在ROS里正常运行起来3.1 启动T265节点在ROS里启动T265最常用的命令是roslaunch realsense2_camera rs_t265.launch也可以自己写一个更精简的launch文件把需要打开的功能都显式声明出来方便后续调试。我习惯这样写launch node pkgrealsense2_camera typerealsense2_camera namers_t265 outputscreen param nameenable_gyro valuetrue/ param nameenable_accel valuetrue/ param nameenable_pose valuetrue/ param nameunite_imu_method valuelinear_interpolation/ param nameodom_frame valuecamera_odom_frame/ param namepose_frame valuecamera_pose_frame/ /node /launchunite_imu_method设成linear_interpolation是为了纠正IMU时间戳把加速度计和陀螺仪的数据统一成同一频率输出这一步会让后续数据融合稳定很多。odom_frame和pose_frame是T265的坐标系名称默认就是camera_odom_frame和camera_pose_frame建议保持默认减少后续TF配置的混乱。启动完成后用rostopic list确认话题存在重点看这几个/camera/odom/sample视觉里程计数据类型为nav_msgs/Odometry/camera/imuIMU数据/camera/pose/sample6自由度位姿数据/tfT265内部发布的坐标变换3.2 确认数据不是一堆零很多新手遇到的情况是话题存在但里面全是零或者数据变化异常。排查第一步先看频率rostopic hz /camera/odom/sample正常情况odom频率在30Hz左右IMU频率在200Hz左右。如果频率在1Hz以下说明USB带宽不够或者被其他进程占用。如果频率正常但位移始终是零多半是场景特征太少把T265对着白墙或者空旷的天空它也找不到特征匹配自然会输出零位姿。这时候调整一下无人机朝向让它对着有纹理的地面、桌椅、海报等明显特征的地方再观察数据。数据内容检查也很重要rostopic echo /camera/odom/sample --noarr主要看pose.pose.position和pose.pose.orientation两个字段。手动拿起无人机上下左右移动数值应该跟着变化。注意这里“拿起无人机”时T265看到的要在静止环境不要尝试把相机和场景一起转动这样会让VIO失去参照物。3.3 TF坐标系别小看这条base_link链条T265虽然输出位姿但PX4和MAVROS并不认识camera_pose_frame这个名字。飞控期望的是机体坐标系下的位姿所以需要告诉ROST265的坐标系和飞机机体坐标系是什么关系。最简单的办法是发一条静态坐标变换。如果T265安装方向和机头一致而且就在飞机重心附近那变换矩阵基本接近原点重合rosrun tf2_ros static_transform_publisher 0 0 0 0 0 0 1 base_link camera_pose_frame如果T265是装在机头朝前、偏上位置那就得把偏移量写进去。例如装在机体前方15厘米、上方5厘米并向右偏2厘米rosrun tf2_ros static_transform_publisher 0.15 0.02 0.05 0 0 0 1 base_link camera_pose_frame注意这里的坐标轴顺序和单位前三位是xyz单位米后三位是滚动、俯仰、偏航角单位弧度。很多人会忽略偏航角如果T265装歪了飞到后面就会发现视觉定位的轨迹整体旋转了怎么调参数都救不回来。4. 把视觉里程计喂给PX4和EKF24.1 数据流为什么要过MAVROS这一层T265算出的位姿是ROS的nav_msgs/Odometry消息而PX4飞控不认识这种消息它只认MAVLink协议。MAVROS的作用就是桥接两边它把ROS话题转成MAVLink的VISION_POSITION_ESTIMATE消息再通过串口或USB发给飞控同时飞控返回的IMU、状态、遥控信号又会变成MAVROS话题。如果你用的是Pixhawk和树莓派USB直连MAVROS启动命令是roslaunch mavros px4.launch fcu_url:/dev/ttyACM0:921600如果树莓派用的是串口那就把fcu_url改成类似/dev/serial0:921600。启动后MAVROS默认会有很多话题但核心只需关注/mavros/state、/mavros/local_position/odom和/mavros/vision_pose_estimate/odom。关键一步是让T265的里程计进入MAVROS。我用的方法是写一个launch文件在MAVROS节点前把topic重映射remap from/camera/odom/sample to/mavros/vision_pose_estimate/odom/这样MAVROS收到视觉里程计后会自动转换坐标系生成PX4能理解的VISION_POSITION_ESTIMATE并发送飞控。4.2 PX4参数配置逐项说明接下来是这篇文章最值钱的部分。打开QGC地面站进入参数界面逐项修改EKF2_AID_MASK这个参数用来决定EKF2使用哪些辅助传感器。没有GPS的室内场景必须关闭GPS融合的位打开视觉位置、视觉速度、视觉偏航融合。常用值是7表示视觉位置、视觉速度、视觉偏航三项全部开启。不同的PX4版本里位定义略有区别但视觉融合对应的位基本在bit0到bit2设置为7或直接参考固件参数说明设置即可。EKF2_EV_CTRL这个参数是较新PX4版本加入的用于更精细控制视觉数据在EKF2里怎么用。位0是水平视觉位置融合位1是垂直视觉位置融合位2是视觉速度融合位3是视觉偏航融合。如果只做室内定位我建议设置7也就是开启水平位置、垂直位置、偏航三项。这里要注意如果EKF2_EV_CTRL非零它会覆盖EKF2_AID_MASK里关于视觉的部分所以两个参数要保持语义一致。EKF2_HGT_MODE高度源选择。室内没有GPS我一般选4也就是视觉气压计融合。单独用视觉高度的话T265的Z方向在小范围悬停时还算稳但如果整个垮层飞行或者遇到轻微漂移视觉高度就容易失真。气压计虽然在高动态下有延迟和滞后但能提供一个长期稳定的基准。视觉气压计融合等于用气压计兜底用视觉细节做修正实际表现比单用视觉高度舒服很多。EKF2_GPS_CHECK既然没有GPS必须把GPS检查关掉否则EKF2会因为收不到GPS而疯狂报警甚至拒绝切换融合模式。设成0表示不检查GPS状态。SYS_HAS_GPS如果硬件上确实没有GPS模块就把这个参数设成0。这样系统知道机载环境没有GPS很多依赖GPS的航点和设定就不会报错。EKF2_IMU_POS_X/Y/Z这个参数描述飞控IMU相对飞机重心的位置。如果飞控装在飞机正中央三个值都是0也没问题如果偏了把实际偏移量以米为单位填进去。它对于EKF2融合后的动态控制响应有明显影响不能忽略。把上面的参数调整完之后最好重启一下飞控让参数生效。4.3 验证飞控是否真的收到了视觉数据参数配好MAVROS起来T265也在跑最怕的是飞控根本没收到视觉数据。我建议用两种方式确认。第一种是在QGC的MAVLink控制台里输入listener vision_position_estimate如果能看到一个不断刷新的几十Hz数据流说明MAVLink消息已经到达飞控。第二种是直接用MAVROS回读执行rostopic echo /mavros/vision_pose_estimate/odom --noarr如果这个topic有稳定数据且数值跟着相机运动变化说明链路已经通了。更直观地验证是看QGC右上角的EKF状态。正常情况下会看到“视觉位置”这个辅助源被激活。如果看到“GPS”或者“没有位置源”说明参数配置还没生效或者飞控还在寻找可用的传感器。5. 实操过程从地面站到空中悬停5.1 先在地面站里做一次“伪起飞”验证我强烈建议第一次飞行之前不要通电推油而是先把整机放在桌上拿着飞机在房间里走动观察QGC里的位置估计是否在实时更新。具体做法是上电后不解锁在QGC的飞行界面看到机头朝向、位置轨迹随走动而移动这就说明整套数据链路已经打通。如果不动那就别飞先排查数据问题不然解锁之后飞控会立刻发现定位丢失直接闪避或者切自稳模式。这一步还有一个容易忽略的细节房间里的光线和纹理。T265是视觉设备对光照敏感。开着明亮白炽灯或自然采光的房间效果最好环境光太暗或房间大白墙密布会让特征点数量骤减。我有一条经验把手放在T265视野前晃一晃如果QGC里的位置数值能随之变化说明环境特征足够。5.2 用自稳模式试悬停确认数据没问题后不要一上来就切位置模式。先用自稳模式Stabilized解锁轻轻推油让飞机离地10-20厘米悬停。这一步的目的是验证视觉定位在真实电机振动环境下是否依然稳定。T265虽然内部有减震设计但电机高频振动会给IMU带来额外噪声如果悬停过程中位置估计开始剧烈跳动多半是安装减震不够。建议在T265下方加一层4mm厚的泡棉双面胶或专用减震垫避免它的IMU直接吸收机架振动。如果嗡嗡声传得太清晰那就要考虑调整安装位置把摄像头往机架中心靠减少力臂效应。在自稳模式下飞控不使用视觉定位做位置控制所以即使视觉数据异常也不会炸机。等飞机能稳定悬停再切到位置模式感受一下有没有缓慢漂移。位置模式下面飞控会尝试通过视觉数据把飞机锁定在一个位置。5.3 调整EKF2接收视觉数据的阈值有些情况下数据链路是通的但EKF2仍然不信任视觉数据原因在于PX4有一组EKF2_REQ_*参数用来限制数据更新的质量和步数。比如EKF2_REQ_VEL、EKF2_REQ_POS等这些阈值如果太高视觉数据轻微跳变就会触发“数据超时”EKF2直接放弃使用视觉。我的经验是把这个阈值调低一些。例如在PX4里设置EKF2_REQ_VEL0.1EKF2_REQ_POS0.05具体看固件文档说明。这样即使偶尔有一次异常数据EKF2也不会立刻把整个视觉源踢出去。还有一个比较隐蔽的问题是偏航漂移。T265长时间运行后偏航会缓慢漂移室内没有罗盘校正的话无人机可能会在空中慢慢绕圈。解决办法有几个一是让T265初始对准一个明确特征方向再起飞二是用EKF2的磁罗盘辅助偏航但室内磁场干扰大反而可能更糟三是定期让飞控用遥控器的偏航杆“强制重置”视觉偏航基准。这个方法的效果取决于固件但至少能保证短时间的定位持续可用。6. 常见问题与避坑实录6.1 现象视觉位姿一直是零值可能原因排查顺序先看T265看到的环境是否有足够纹理再看rostopic hz /camera/odom/sample有没有数据最后看USB是不是跑在2.0模式下。尤其要注意有些树莓派的USB口供电不足T265会降速运行数据率直接掉到几赫兹。处理办法给T265换一个带独立供电的USB3.0 hub或者用高质量数据线。飞行时别让T265对准无纹理的白墙多让它看到地面和周围物体。6.2 现象飞控端的视觉位姿超时可能原因数据已发布但MAVROS没把数据发到飞控或者EKF2因为参数阈值太高完全不采信视觉数据。处理办法在QGC的MAVLink控制台输入listener vision_position_estimate如果消息频率正常说明MAVROS到飞控这半段没问题那就去改EKF2_REQ_*的阈值和下发的消息频率。如果消息频率几乎为零停下来检查MAVROS的重映射是否生效话题名有没有拼错。6.3 现象位置模式悬停时飞机缓慢漂移可能原因T265的偏航漂移在积分累积后会体现为位置漂移尤其在没有GPS校正、没有罗盘的场景下。另一个原因是TF变换未校准相机和机体的坐标系偏移有误差。处理办法起飞时让T265朝向与机头完全一致避免机头对准大块无纹理区域。如果漂移方向固定可以在TF静态变换里补偿一个偏航角。实测来看T265在10分钟内的偏航漂移通常小于2度对单次飞行来说完全可以接受但如果飞完一个起降还想保持高精度最好回原点重新初始化。6.4 现象悬停一段时间后飞控突然切换到了自稳模式可能原因EKF2判定视觉定位失效自动降级。最常见原因是视觉更新中断或者T265在上电后内部算法崩溃。其次是电机振动噪声污染了IMU数据导致EKF2的imu数据异常。处理办法检查T265的温度如果过热它会自动降低输出频率或暂停。长期飞行时要注意给T265加散热我见过不少新手把它塞进封闭的机舱里结果飞了五分钟就过热报警。另外安装减震垫也是必须的尤其是电机直接焊在小机架的情况下。6.5 避坑清单说了这么多最后把这套方案里最值得记住的经验汇总一下方便大家复现时少踩坑上电后静置1分钟再起飞让T265和EKF2完成初始化。室内灯光要是正常亮度避免逆光和纯白墙。没有GPS的场合把EKF2_GPS_CHECK设成0SYS_HAS_GPS设成0。视觉高度建议加上气压计兜底EKF2_HGT_MODE选4。用EKF2_EV_CTRL精细控制视觉融合时检查它和EKF2_AID_MASK是否是同一个语义别互相覆盖。T265的USB线要固定好空中振动导致接口松动是排查起来最痛苦的问题。每次更换安装位置或拍摄角度后重新做一次静态TF变换校准。先在地面上通过QGC观察位置更新再解锁起飞不要跳过验证。我在实际调试中最深刻的体会是T265这套方案并不难难的是数据链路上任何一个环节都可能静默失效。你看着ROS话题数据正常飞控参数也设置了但松杆悬停时它还是飘这种问题通常不是算法问题而是安装细节问题。把相机固定牢、把USB线捆好、把视角调整好往往比调参数更能解决问题。真希望当初有人把这些都写在教程开头能省下我一个月的折腾时间。