没有GPS的室内,想让一台PX4无人机稳稳定住,是很多玩无人机的人迈不过去的坎。室外有卫星信号,切到定点模式飞机自己就能稳住;一进室内GPS失效,飞控失去了“位置”的概念,飞机就开始乱飘,速度稍快一点就撞墙。我这次就用一颗微空MTF-01光流传感器,在PX4上实现了室内定点悬停。整个过程从硬件接线、QGC参数配置到实飞调试,一条线走通,适合刚接触光流定位和PX4室内飞行的同学按步骤抄作业。
这套方案的核心思路不复杂:光流传感器像一个小摄像头,持续拍地面图像并计算纹理移动,把“飞机相对于地面在往哪个方向平移”这件事测出来,再配合激光测距或气压计获得高度,就能够在无GPS环境下给飞控一个相对位置参考,让飞控像室外用GPS一样做位置保持。后面我会把MTF-01的接口接线、PX4参数、QGC地面站校准流程、EKF2状态验证、试飞调试和现场排障全部展开讲,尽量把每一步都讲透。
1. 项目背景与总体思路
1.1 室内定位的痛点:GPS失效后飞控在“盲飞”
先聊两句为什么室内定位这么麻烦。PX4飞控的姿态估计用的是陀螺仪和加速度计,这两个传感器能告诉飞控“飞机现在的姿态是什么”,但没办法直接告诉飞控“飞机现在在房间里的哪个位置”。室外定点靠的是GPS给出一组经纬度坐标,飞控内部再把经纬度换算成本地坐标系下的x、y位置,然后做位置环控制。一旦GPS信号被屋顶和钢筋混凝土挡住,位置环就失去了输入源。
更麻烦的是,加速度计在积分过程中会产生漂移。飞控内部其实也用加速度计做过短时间的位置推算,但几秒钟之后误差就会积累到无法接受的程度,飞机会朝着一个方向缓慢飘走,看起来就像“有人在拿绳子拖着它”。所以室内定点不能只靠IMU,必须引入外部传感器来提供绝对或相对位置参考。
可选方案大致有几种:UWB室内定位基站、运动捕捉系统(Vicon/OptiTrack)、激光雷达SLAM、视觉SLAM,以及光流传感器。前几种要么贵要么搭建麻烦,UWB需要在房间多个位置布基站,动捕系统一套下来价格感人。光流传感器的成本最低、部署最简单,一颗模块几十到几百块,贴在机腹就能用,对于“室内悬停、低速平移”这种典型需求来说,性价比最高。
1.2 光流定位的原理:像看地板“走路”
光流法定位的原理,说穿了就像是人坐在地板上盯着地面看:如果你看到地板花纹在向左移动,你就能知道你正在向右移动。光流模块内部有一颗极小的图像传感器,以几十到上百帧每秒的速率拍地面。处理器对连续两帧图像做特征匹配,计算这些特征点的位移方向和大小,再除以两帧之间的时间间隔,就得到了图像平面的运动速度。这就是“光流”(Optical Flow)两字的由来。
但这里有个关键问题:图像平面的像素移动速度跟飞机的实际水平速度并不是简单的线性关系,因为同一个水平速度在不同高度下产生的图像移动速度完全不同。飞机离地1米和离地5米时,同样的水平速度会导致截然不同的像素位移。所以光流模块必须结合离地高度才能换算成真实速度。这也是为什么几乎所有光流方案都要搭配测距传感器来用。
换上距离传感器之后,整个计算链条就是:光流模块给出“像素/秒”级别的角速度或尺度化速度,测距传感器给出离地高度,飞控内部把二者乘起来,得到米/秒级别的水平速度。这个速度再放进位置估计器里积分,就得到了飞机的水平位置变化量。PX4的策略是把这些数据送进EKF2滤波器,和IMU数据做融合,最终输出一个相对稳定的位置估计。
2. 硬件准备与飞控连接
2.1 MTF-01光流模块的核心参数
微空MTF-01是一颗主打低功耗、小体积的微型光流模块,市面上常见的版本基于PMW3901芯片方案,也就是 pixart 那颗被大量无人机光流模块采用的传感器。PMW3901是一颗专门做光学导航的芯片,内部集成了图像传感器和专用的DSP处理器,对外通过SPI接口输出测量结果。
我第一次拿到MTF-01时最直观的感受就是小,模块本身大概一个小拇指甲盖大小,重量几克,装在机架上几乎不影响整机重量。它的工作高度范围通常在10厘米到10米之间,地面亮度要求不高,普通室内灯光环境下就能正常工作,但在纯色无纹理地面(比如纯白地板、纯色地毯)上容易失效,因为图像特征太少,DSP找不到可以用来匹配的特征点。
MTF-01通常还会在同一个模组上预留I2C接口,如果你买的是带测距功能的一体化版本,激光测距部分一般走I2C。如果买的是纯光流版本,那测距就要另配一颗激光或超声波传感器,通过飞控的I2C或UART口接进来。我这次用的是一体化版本,光流和测距在同一个模组上,接线省事不少。
2.2 飞控选型与接口规划
光流定位对飞控的要求并不算高,只要是能跑PX4固件的飞控都行,常见的有Pixhawk 4、Pixhawk 6C、Holybro系列,或者是各种国产兼容版。我用的是Pixhawk 4,因为有足够多的空闲接口,而且QGC的参数支持比较完整。
接线前先想清楚一件事:MTF-01的光流数据走哪个接口,测距数据走哪个接口。如果模块是SPI接口的光流加I2C接口的测距,那就需要分别占用飞控的SPI和I2C接口。SPI接口在Pixhawk上通常是固定的,比如TELEM2旁边或者AUX口附近会有SPI排针;I2C则有专门的四针接口(VCC、GND、SCL、SDA)。
一个容易踩坑的地方是电压。MTF-01的工作电压一般是3.3V或5V,具体要看模块丝印。接错电压轻则模块不工作,重则直接烧掉。我习惯先看模块背面的印刷标识,找不到标识就用万用表量一下模块降压芯片的输出,确认之后再接到飞控上。飞控I2C接口的供电脚通常输出的是5V,如果模块支持3.3V输入,那就需要额外找一路3.3V供电,或者用模块自带的稳压电路。
2.3 安装方向:机头朝向必须对齐
光流模块的安装方向是整个项目里最容易被忽略、但错了最折腾的问题。PMW3901这类光流芯片本身并不“知道”自己装在飞机上的朝向,它只是如实报告“图像在往哪个方向移动”。如果模块安装时和机头方向差了90度,飞控就会把前方的运动误判成侧向运动,飞机在室内会做出完全错误的修正动作,看起来就像喝醉了。
我的做法是:先确定模块上丝印标出的箭头方向,有些版本会印一个小三角形或箭头来表示模块的“前方”,然后把箭头对准机头方向安装。如果模块没有丝印标记,就看芯片的引脚定义,通常芯片的1脚方向或文字印刷方向可以当作参考。
安装时还要考虑一个细节:光流模块底部到地面的距离最好在10厘米以上,避免起落架或机架结构遮挡光流镜头的视场角。光流芯片的视场角普遍很大,一般能达到40度左右,但如果镜头被遮挡,哪怕只挡了一个角,也会导致一个方向上的测量失真。
3. QGC参数配置与固件准备
3.1 固件选择与地面站连接
在动参数之前,先确认飞控固件版本。我使用的是PX4 v1.14.3,这款固件对光流传感器的支持比较成熟,EKF2的融合逻辑也稳定。QGC地面站建议用最新稳定版,老版本界面和参数位置差异比较大,照着文章操作容易对不上号。
连接流程没什么特别的:USB线连飞控,打开QGC,等它识别到设备。如果连不上,优先检查驱动。Windows下Pixhawk通常自动识别为串口设备,但如果装了其他USB转串口驱动,可能会出现设备占用或端口冲突,此时在设备管理器里先卸载冲突驱动再重插。Ubuntu下一般免驱,但如果出现权限问题,需要在udev规则里把当前用户加进dialout用户组,否则QGC会提示“No device found”。
连上之后第一件事是校准传感器:加速度计、陀螺仪、磁力计、水平校准。很多新手急着设参数,结果传感器校准没做,试飞时机身姿态都是歪的,光流调得再好也没用。加速度计校准要在水平面上放平飞机,按QGC引导操作;磁力计校准需要拿着飞机在空中转几个特定的姿态圈,室内磁场干扰比较大,最好离钢筋墙和金属桌面远一点。
3.2 光流与测距传感器的关键参数
固件刷好、传感器校准完毕,接下来就是核心的参数配置环节。以下是我在QGC参数界面实际修改的参数清单,每一项都附了配置说明。
| 参数名 | 推荐值 | 作用说明 |
|---|---|---|
| SENS_EN_PMW3901 | 1 | 启用PMW3901光流传感器驱动,MTF-01就是基于该芯片方案 |
| SENS_EN_LIDAR | 1 | 启用板载I2C/串口激光测距传感器 |
| SENS_FLOW_MINHGT | 0.3 | 光流有效的最小高度,低于该高度光流数据不参与融合 |
| SENS_FLOW_MAXHGT | 8.0 | 光流有效的最大高度,超过后光流数据权重降为零 |
| EKF2_HGT_MODE | 0 | 高度源选择:0=气压计,1=GPS,2=测距仪 |
| EKF2_OF_CTRL | 1 | 启用EKF2光流融合功能 |
| EKF2_GPS_CTRL | 0 | 关闭GPS辅助融合,室内没有GPS时必须关闭 |
这里多说一句SENS_EN_PMW3901这个参数。不同厂家的光流模块,驱动使能方式可能不同。MTF-01如果是基于PMW3901芯片并采用SPI通信,那在PX4里就需要把这个参数设为1。如果模块是串口版或使用了自定义协议,那可能要改用SENS_EN_OPFLOW或者通过MAVLink光流消息接入。具体看模块手册里的通信协议说明,大部分国内模块厂商都会在文档里写明适配方式。
高度源的选择也很讲究。室内飞行高度比较低,如果直接选择测距仪作为高度源(EKF2_HGT_MODE=2),飞控对高度变化的响应会比气压计灵敏得多,但测距仪容易受到地面材质和倾角的影响。我的做法是:在离地1米以内的低空,用测距仪作为高度源;如果要飞超过1.5米,则用气压计更稳。如果需要切换,在QGC里把EKF2_HGT_MODE改成0或2即可,改完记得重启飞控。
3.3 参数写入与保存
修改参数后一定要点击QGC右上角的“Apply”按钮,参数才会写入飞控。写入完成后建议断开重连一次,在参数树里重新搜索该参数名,确认保存的值是你设置的值。有些参数具有内部联动关系,比如你改了SENS_EN_PMW3901,飞控可能要求重启动才生效,QGC会给出提示,跟着提示做就行。
我先按照上表的参数全部改完,重启飞控后,在QGC的MAVLink控制台里输入:
param show SENS_EN_PMW3901输出显示SENS_EN_PMW3901 1,确认参数已生效。这个命令在排查参数是否写入时非常有用,如果你发现参数没生效,很大概率是飞控没有重启,或者QGC虽然提示应用成功但实际没写入成功。
4. 数据验证与估计器状态监测
4.1 在QGC里实时查看光流数据
参数配置完成不代表光流模块真的在工作,必须验证数据。把飞机放在桌面上,稍微拿起来一点,让光流镜头离地面有一定距离,然后在QGC的“Analyze Tools”里打开MAVLink Inspector,或者用“Flight Data”页面的状态查看器,找到光流相关的信息。
我在实测中主要看两个指标:
OPTICAL_FLOW消息是否在持续更新,消息里的flow_x和flow_y应该随着你手动平移飞机而改变。把飞机往左移,flow_y或者flow_x就应该有对应的变化,方向不对就说明模块装反了。DISTANCE_SENSOR消息是否在正常输出距离值。手在光流镜头下方晃动时,距离值应该有明显变化。如果距离值恒为0或跳变异常,多半是测距部分没接好或驱动没使能。
一个很实用的验证技巧:把飞机拿在手里,水平向右快速移动一小段,然后停止。观察光流消息里的速度值,如果它有一个先增大再归零的过程,说明模块响应正常。如果速度值一直恒定在0,那基本可以确定光流数据没有进到飞控里。这个时候不要急着怀疑模块坏了,先查SPI接线,再查驱动使能参数,最后查设备枚举。
4.2 EKF2估计器的状态检查
光流数据有没有被EKF2滤波器真正用起来,光看原始光流消息还不够。EKF2是PX4的“融合大脑”,它会对多个传感器数据做加权融合,如果它认为光流数据不可靠,就会自动把光流权重降为0。也就是说,哪怕光流模块正在输出正常数据,EKF2也可能不采信。
在QGC里按Ctrl+Shift+E打开EKF2专用界面,最直观的是看innovation和test ratio。光流相关的innovation如果一直很大(比如超过3倍标准差),说明光流测量值和EKF2其他传感器的预测值对不上,融合逻辑会认为光流数据有误,自动降低其权重。遇到这种情况,常见原因是传感器外参配置错了,比如安装位置距离飞控IMU太远,或者安装方向角度设置不正确。
EKF2里还有一个参数叫EKF2_OF_N_MIN,用于设置光流数据参与位置估计所需的最小测距值。如果测距传感器输出的高度低于这个值,光流数据也会被忽略。我在配置时的取值是0.3米,也就是飞机离地低于30厘米时光流不参与定位,这样在起飞和降落阶段不会因为地面纹理太近导致位置估计剧烈跳动。
姿态估计器状态在室内试飞前必须确认收敛。把飞机放在地面上静止不动,等EKF2界面里所有的test ratio小于1,位置估计的innovations接近0,才算做好准备。如果EKF2一直在报错,比如罗盘异常或加速度计饱和,先解决这些问题再起飞,任何警告都不能忽略。
5. 定点悬停试飞与调试流程
5.1 首次试飞前的安全检查
室内试飞和室外完全不是一个危险等级。室内空间狭小,墙壁、家具、顶灯都是障碍物,就算飞控出了极小的控制偏差,也很容易撞上东西。我强烈建议第一次试飞在空旷的客厅或走廊进行,地面纹理要丰富一些,最好是木地板、瓷砖或者有地毯。
螺旋桨防护罩必须装。很多人觉得光流模块轻,飞机总重小,就不装护罩。实际上在没有GPS的室内,飞控很容易出现短时的位置估计漂移,哪怕只是漂了半米,高速旋转的桨叶碰到人也是一道口子。装护罩不会对飞行性能产生明显影响,但能避免很多不必要的受伤。
电量管理也要提前安排好。室内飞行的续航通常比室外短,因为飞机需要不断调整位置,电机一直在小幅度变速。我习惯在首次试飞前把电池充满,并且起飞前先在QGC里确认电池电压和剩余电量显示正常。室内飞行不要飞到低电压报警才降落,低电量时电机推力下降,位置保持会变得很吃力,更容易出危险。
5.2 首次起飞:先手动模式验证姿态
试飞的第一步不是直接切定点模式,而是先用手动模式验证飞机的基本姿态控制是否正常。把飞行模式开关拨到自稳模式(Stabilized),慢慢推油门让飞机离地约30厘米,保持在这个高度悬停。这个阶段的目的很简单:确认飞控的姿态控制正常,确认光流模块没有因为电机振动而输出异常数据。
自稳模式下,飞控只负责保持姿态,不管位置,所以飞机有明显的水平漂移是正常的。此时重点观察QGC里的光流数据是否仍然稳定输出。电机启动后整机振动加剧,有些光流模块在振动环境下会出现数据跳变,如果发现光流数据开始频繁归零或者剧烈跳动,说明模块的减震没有做好。
在正确安装光流模块后,我实测的典型数据是这样的:电机怠速时,光流的噪声水平在±0.02米/秒内;全油门爬升瞬间,光流数据会出现一个短暂的跳变,但在一两秒内恢复平稳。如果跳变持续时间过长,就要检查光流模块的安装是否和机架产生了共振。
此后尝试把飞行模式切到位置模式(Position),观察飞机的反应。位置模式下飞控会主动修正水平位置,如果光流定位正常运行,飞机会有一个明显的“被拉住”的感觉,即使有风或者推杆松手,它也会自己回到原来的位置。第一次切位置模式时手要一直放在模式开关上,一旦发现飞机往某个方向乱冲,立刻切回自稳模式收油门。
5.3 位置模式的参数微调
位置模式切过去之后,如果飞机能基本停住,那恭喜你,光流定位链路已经打通了。接下来就是让悬停更稳、更准的微调阶段。PX4里和光流悬停手感直接相关的参数有这几个:
| 参数名 | 推荐值范围 | 作用说明 |
|---|---|---|
| MPC_XY_P | 1.2 ~ 1.8 | 水平位置环比例增益,越大越“硬”,容易振荡 |
| MPC_XY_V_P | 1.8 ~ 2.5 | 水平速度环比例增益,影响整体响应速度 |
| MPC_XY_V_I | 0.1 ~ 0.3 | 水平速度环积分增益,用于消除稳态误差 |
| MPC_HOLD_DZ | 0.1 ~ 0.3 | 摇杆输入死区,避免手部小动作被放大 |
| MPC_XY_CRUISE | 3.0 ~ 5.0 | 最大水平巡航速度,室内建议设置小一些 |
我的调试思路是:先保留默认参数,看飞机实际表现,再逐个微调。如果飞机悬停时在水平方向上有小幅慢速振荡,通常说明速度环的增益偏大,此时把MPC_XY_V_P往下调0.2左右,观察两分钟。如果飞机表现出“懒洋洋”的、需要过很久才修正位置偏移的特性,则把MPC_XY_V_I调大一点。
室内调试切忌一次改多个参数。改一个参数,试飞,观察,记录下来,再改下一个。这个流程看起来很慢,但实际上是排查问题最高效的办法。我见过不少同学一次性改了四五个参数,结果飞机出现振荡时根本不知道是哪个参数改坏了。
振动对光流定位的影响也要特别说明。PX4的振动分析工具在QGC的“Analysis”页面里可以查看,正常情况下加速度计频谱图的能量集中在一个窄频带内,如果频带很宽或者出现多个尖峰,说明振动过大。光流模块受振动影响尤其明显,因为振动会让相机传感器产生像素级抖动,被DSP误识别为光流运动。我遇到过一次悬停时飞机缓慢往一个方向飘的问题,排查了很久,最后发现是光流模块固定螺丝松动导致的微振动。
5.4 无GPS模式下的定位精度评估
调到飞机能稳定悬停之后,还有一个不容忽视的环节:评估定位精度和鲁棒性。在室内做定位精度评估不需要精密测量仪器,我用了一个很土但很有效的办法:在地板上用美纹纸贴出一个50厘米见方的方格,飞机悬停在这个方格上空,观察三分钟内飞机是否始终保持在方格范围之内。
实测下来,在2米高度悬停、室内正常灯光条件下,MTF-01配合PX4的EKF2融合,三分钟内的位置漂移大概在15到25厘米左右。这个精度对于室内悬停和低速巡检来说是足够的,但如果需要厘米级的定位精度,光流方案就力不从心了,只能上动捕系统。
还有一个影响精度的重要因素是地面纹理。我在地板、瓷砖、短绒地毯、白色光滑桌面几种地面上都试过。地砖和木地板的定位稳定性最好,短绒地毯次之,纯白色光滑桌面基本失效。原因就是纯色表面缺乏可供光流芯片追踪的特征点。如果你的飞行环境是纯色地板,有两个办法:一是贴一些随机图案的地贴纸,二是在试飞区域铺一块有纹理的地毯。
6. 常见问题排查与避坑技巧
6.1 常见问题速查表
调试过程中我把遇到过的、以及身边朋友在室内光流项目上踩过的问题整理成了一张表格,基本覆盖了能遇到的问题类型。
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| QGC里看不到光流消息 | SPI连线错误/驱动未启用 | 检查接线,确认SENS_EN_PMW3901=1 |
| 光流有数据但EKF2不用 | 高度低于SENS_FLOW_MINHGT | 调低最小高度阈值,或抬高飞机 |
| 飞机往固定方向飘 | 光流安装方向错 | 确认模块箭头与机头方向一致 |
| 光流数据噪声巨大 | 模块固定不牢/振动过大 | 重新固定模块,检查桨叶是否缺角 |
| 悬停时持续低频振荡 | P参数过大 | 降低MPC_XY_P和MPC_XY_V_P |
| 切位置模式后飞机猛冲 | 位置估计跳变/EKF2未收敛 | 先在地面等EKF2 test ratio全部小于1 |
| 测距高度值跳动 | 测量面不平整/测距仪视角内有遮挡 | 清理镜头表面,检查安装倾角 |
| 灯光变暗后精度急剧下降 | 光流模块感光度不足 | 增加补光,或更换动态范围更大的模块 |
6.2 关于光流模块的低温与低光表现
室内环境温度和光线的波动比室外小得多,但仍然有两个特殊情况要留意。第一个是低温环境。我冬天在没暖气的库房试飞时,飞机刚上电光流数据正常,飞行一两分钟后开始出现间歇性丢数据。后来发现是光流模块的工作温度低于数据手册标称值,芯片内部的振荡器频率发生了漂移。解决办法是在起飞前让模块通电预热几分钟。如果你经常在低温环境飞行,考虑给模块加一个小的加热片。
第二个是低光环境。PMW3901芯片在光线不足时会自动增加曝光时间,导致帧率下降,最终的结果是光流数据延迟增加,飞机感觉“迟钝”。室内灯光通常足够,但如果房间用了偏暖色的低亮度灯,或者光流镜头朝下时刚好处于飞机阴影里,就比较容易触发这个问题。增加飞行区域的亮度是最直接的解决方式,有条件的话可以在机腹加一个朝下的LED补光灯,但要注意不要让灯直射光流镜头,否则会产生过曝,效果反而更差。
6.3 现场调试的独家心得
最后分享几个不太会写进文档里、但实际调试中非常管用的经验。
第一个心得是关于数据记录。每次试飞前我都会在QGC里开启日志记录,试飞结束后下载U盘日志做离线分析。QGC的日志分析和MATLAB的Plot工具功能很强大,可以直观地看到光流数据在哪个时间点开始被EKF2采纳、当时的innovation变化趋势。没有日志,出了问题就只能靠猜。我之所以能快速定位很多问题,靠的就是事后翻日志,看数据曲线说话。
第二个心得是关于磁力计的。室内磁场环境复杂,钢筋、电线、桌子里的金属都会让磁力计产生随机误差。虽然光流定位本身不依赖磁力计,但EKF2在融合多个传感器时,如果磁力计数据严重异常,可能会影响整个滤波器的收敛状态,间接影响光流融合效果。所以我建议室内试飞时把EKF2_MAG_TYPE设置为0或按实际情况调整磁力计融合策略,避免磁场干扰拖累整个估计器。
第三个心得是不要迷信某一个参数。网上很多帖子喜欢发“最优参数表”,但实际上一架飞机的参数是跟它的质量、轴距、电机响应、重心位置强相关的。同一套参数在别人飞机上很稳,在你这儿可能就振荡。最靠谱的做法是理解每个参数的物理意义,然后根据自己飞机的表现去做针对性的调整。这套方法论比任何参数表都值钱。
第四个心得是关于备份。每次调试出稳定效果后,及时在QGC里导出参数文件备份到电脑上。室内飞行环境复杂,调试过程容易手滑改错参数,有备份就可以一键恢复。这种感觉就像写代码定期提交commit一样,关键时刻能救命。