无人机光流模块选型与避坑:PMW3901、PX4Flow、EKF融合实战
2026/9/18 14:42:27 网站建设 项目流程

1. 先把光流模块在无人机里的角色说清楚

每次有人问我“无人机光流模块怎么选”,我第一反应不是报型号,而是先反问三句:你的机子打算在什么地面上飞、飞多高、什么机型。这三个问题的答案,基本就决定了你能不能买 PMW3901 这类便宜货,还是必须咬牙上 PX4Flow 甚至自己搭一套视觉方案。光流模块这个零件,属于典型的“看起来不起眼,装错了能让整机行为诡异到怀疑人生”的角色。它本身不贵,几十块到上千块都有,但它在整机里承担的职责,是代替 GNSS 给飞控提供水平速度观测,一旦它给的数据是错的,或者跟测距源对不上,整个 EKF 状态估计就会跟着一起歪。

我接触过的场景里,用它最多的是三类人。第一类是室内定点飞行,厂房、仓库、体育馆里做巡检演示,GNSS 完全没信号,靠光流加测距把飞机稳在原地;第二类是室外低空的补充手段,比如树林边、楼宇间 GNSS 多路径严重、卫星数掉得厉害的时候,光流顶上来当作短时间的速度参考;第三类是视觉类项目,比如光电吊舱稳像、运动目标检测的背景补偿,光流不是拿来定位,而是拿来算“画面整体在怎么动”。这三类需求对模块的要求差别非常大,如果不先分清自己属于哪一类,选型基本靠玄学。

1.1 GNSS 失锁的那几秒,飞控手里还剩什么

理解光流选型,得先理解飞控的状态估计在干什么。飞控的位置和速度估计是个多源融合的过程,加速度计给的是加速度,积分一次得到速度,再积分得到位置,但这个积分会漂,几秒钟就能漂出好几米。GNSS 提供的是绝对位置和速度,用来把漂移拉回来;气压计和测距雷达给高度;磁力计和陀螺给姿态。问题在于,一旦 GNSS 失效,水平方向就只剩加速度计在硬撑,漂移速度取决于 IMU 的零偏和噪声水平,普通消费级 IMU 在几秒内就能累积出可观的误差。

光流模块的作用就是在这个缺口上补一块木板。它通过向下拍摄地面、计算相邻两帧图像之间像素的移动量,反推出机体相对地面的水平速度。注意是“相对地面”,不是“相对空气”。这意味着只要地面有纹理,它就能在无 GNSS 环境下提供一个不随时间漂移的速度观测,把积分漂移按住。室内定高定点飞行能稳住,靠的就是“光流给水平速度、测距给高度”这个组合。

这里有个很多人一开始会误解的点:光流给的是速度,不是位置。它不直接告诉你飞机在哪儿,而是告诉你飞机此刻往哪个方向、以多快的速度移动。位置仍然靠积分得到,只不过积分用的速度是被光流不断修正过的,所以不会无限漂。搞清楚这一点,后面理解为什么光流必须配合测距源使用,就顺理成章了。

1.2 从像素位移到地面速度,这条物理链条是怎么走通的

光流的本质是角速度测量。相机往下看地面,地面纹理在图像上移动,移动的速率反映的是相机相对地面的角速度,而不是线速度。这个关系用一个小角度近似就能写清楚:地面上的线速度 v 等于角速度乘以高度,也就是 v ≈ ω × h。所以同样一个像素位移速率,在一米高时对应的地面速度,是两米高时的一半。这也是为什么光流模块永远不能脱离高度信息单独工作,飞控必须同时知道“光流说机体转动了多少”和“机体离地多高”,才能算出真正的速度。

角速度和像素位移之间还有一个换算系数,就是每个像素对应的角度,通常叫瞬时视场角 IFOV。它等于镜头视场角除以像素数。举个例子,一个视场角 42 度、输出 30×30 像素的模块,水平方向的 IFOV 大约是 42/30 等于 1.4 度,换算成弧度约 0.0244 弧度。如果某一帧算出来像素位移速率是每秒 100 像素,那角速度就是 100 乘以 0.0244,约 2.44 弧度每秒。此时如果高度是 1 米,地面速度就是 2.44 米每秒。这个数字很直观:低空飞得稍快一点,像素位移速率就很容易冲到几百甚至上千,超出模块的量程。

反过来推,你就能明白选型时要盯哪些参数。视场角越大,同样速度下像素位移越小,越不容易饱和,但每个像素对应的角度也越大,测速的分辨率会下降;像素数越多,角分辨率越细,低速时测得更准,但计算量和成本上去了;帧率越高,能跟踪的速度上限越高,但延迟和噪声问题也会更明显。这三个参数是互相拉扯的,没有哪个模块能在所有维度上都占优。

1.3 光流解决不了的三件事,买之前必须接受

第一件,它解决不了无纹理地面。纯色地面、镜面地砖、平静水面、均匀的雪地、正午强光下反光的沥青,这些地方光流要么输出零,要么输出噪声。这不是模块质量问题,是原理决定的。我见过有人在抛光大理石地面上试飞,飞机一起飞就开始横着飘,换到有花纹的地毯上立刻稳如磐石,问题完全出在地面。

第二件,它解决不了高空。光流精度随高度下降,这不是线性的,而是纹理细节在图像上被压缩后辨识度急剧降低。常见的 PMW3901 类模块,实测在 1.5 米以内表现最好,超过 2 米就开始明显退化;PX4Flow 这类带 752×480 传感器的方案能撑到 3 米甚至更高,但对光照和纹理的要求也更苛刻。你要是打算在 5 米以上高度靠光流定位,基本可以放弃这个念头,改用其他手段。

第三件,它解决不了纯旋转和纯平移的区分。光流算出来的是图像整体运动,如果飞机原地打转,图像也会整体旋转;如果飞机平移,图像平移。飞控需要用陀螺提供的角速度把旋转分量减掉,剩下的才是平移分量。所以光流必须和 IMU 配合使用,陀螺噪声大、延迟大的机子,光流效果一定差。这条经常被忽略,但它是很多“光流明明装对了却还是飘”的真实原因。

2. 选型前必须算清楚的三组数字

我在选购任何传感器之前都会先在纸上算一遍,光流尤其值得这么干,因为它涉及“速度-高度-视场”三者耦合,光看参数表很容易买错。下面三组数字,我建议你也按自己的机型算一遍,算完基本就知道该往哪个价位段走了。

2.1 角分辨率决定低速精度,视场决定速度上限

先算你需要多大的速度量程。假设你的机子最快水平速度是 3 米每秒,最低工作高度 0.5 米,那么需要的最大角速度就是 3 除以 0.5,等于 6 弧度每秒。这时候你去看模块手册里标的最大角速度,PMW3901 标称大约 7.4 弧度每秒,理论上够用,但只留了 20% 的余量。实际飞行中还有振动、姿态倾斜带来的额外像素运动,一旦饱和,光流输出会直接钳位在最大值,飞控会以为机子在全速前进,结果是越修越偏。所以我的经验是把余量留到 2 倍以上,也就是算出来需要 6 就选能到 12 的。

再算低速精度。假设你希望飞机在 0.2 米每秒的慢速漂移时还能被纠正,高度 1 米,那对应角速度是 0.2 弧度每秒。按每像素 0.0244 弧度的 IFOV 算,像素位移速率只有每秒 8 个像素左右。这个量级在纹理丰富的表面上没问题,但如果表面纹理稀疏或者光照偏暗,信噪比就很差,飞控可能根本感知不到这 0.2 米每秒的漂移。想提升这个底线,办法是提高角分辨率(更多像素或更窄视场),或者降低飞行高度。窄视场镜头的模块在低速定点上更稳,代价是速度上限下降,这是个纯交换。

模块类型典型视场输出像素规模适合高度速度余量
PMW3901 类小模块约 42 度30×30 级0.3 至 1.5 米中,低空够用
PX4Flow 类相机模块约 22 度64×64 光流块0.5 至 3 米以上高,但体积重量大
自研相机方案可调可调视镜头而定取决于算法和算力

这张表只是量级参考,实际数字一定要以你手上模块的手册为准,不同厂家改镜头之后参数会完全变样。

2.2 高度量程:光流和测距源必须是同一档

这是我在选型里最看重的一条。光流的有效高度区间,必须和你的测距源有效区间有足够大的重叠,否则整套方案在某个高度段就是废的。常见搭配里,PMW3901 加 VL53L1X 是很流行的组合,体积小、重量轻、走 UART 或者 SPI 都行。但 VL53L1X 在室内量程大概 4 米,室外强光环境下会缩到 1 米出头甚至更短。也就是说这套组合的“黄金工作区间”其实是 0.3 到 1.2 米的室内环境,出了这个范围,测距数据先失效,光流跟着一起失效。

如果要在室外用,测距源就得换。超声波看起来量程够,标称 7 米以上,但它是声波,桨叶下洗气流会严重干扰它,飞机在 1.5 米以上悬停时,超声波读数经常在几米范围内乱跳,EKF 会直接把高度源判为不可信。所以室外我一般推荐激光测距模块,量程从十几米到上百米都有,抗干扰好,缺点是贵、重,而且近距离有盲区,通常 0.1 到 0.3 米以下测不到,需要在降落阶段做特殊处理。

举个真实案例,我曾经在一台四轴上装 PMW3901 加超声波,室内 1 米高度飞得很稳,一到室外就出问题:飞机刚离地读数正常,升到 1.5 米后高度开始跳,光流速度也跟着乱,飞控在定高模式和定点模式之间反复横跳。后来换成激光测距,问题立刻消失。所以选光流模块时,我从来是把它和测距源当成一个整体来选,不分开看。

2.3 接口、带宽和飞控资源也得算一笔账

接口这件事看起来简单,实际上坑不少。SPI 直连的模块延迟最低,适合对实时性要求高的场合,比如 PMW3901 直接挂到飞控 SPI 总线上,飞控自己读取原始运动数据并转发给 EKF。但 SPI 需要飞控有对应驱动,接线也敏感,时钟极性、片选、供电电压错了就完全读不到数据,我曾经因为模块板载稳压输出是 3.0 伏而不是 3.3 伏,折腾了一个下午才定位到问题。

UART 加 MAVLink 的方式最省心,模块自己算完光流,按标准消息发出来,飞控只要解析就行,适配性好,缺点是延迟比 SPI 高一些,一般在 20 到 50 毫秒这个量级,需要在参数里把延迟补偿填对。I2C 的方案介于两者之间,接线简单,但总线速率有限,容易被其他 I2C 设备拖慢。还有走 CAN 的版本,抗干扰和布线方便,适合多设备组网,但对飞控固件版本有要求。

带宽方面,光流数据本身的速率很低,几十赫兹而已,不用担心占用。真正要留意的是飞控的算力和 EKF 融合逻辑。老固件版本对光流融合的支持不完整,比如某些版本里光流只参与速度观测但不参与位置观测,定点效果会打折扣。选模块之前先确认你的飞控固件当前版本对光流的支持程度,这比换模块有用得多。

3. 市面主流方案横向拆解与对照

讲完原理和约束,终于可以聊具体方案了。我把常见的方案分成三条线:一体化小模块、相机模块、自研视觉方案。这三条线的定位差异很清楚,选之前先想清楚自己属于哪条线。

3.1 一体化模块:便宜、小、够用,但有明确天花板

这一类里最有代表性的是基于 PMW3901 的方案。它原本是光学鼠标传感器,被移植到无人机上做光流,优点非常突出:体积只有指甲盖大小、重量几克、功耗低、SPI 或者 UART 都支持、价格便宜。配套的板子通常还会集成一个激光测距芯片,把光流和高度打包成一个模块,接线和配置都很省事。

它的天花板同样明显。第一,高度受限,前面说过 1.5 米以内是舒适区;第二,对光照敏感,暗光环境下表面质量指标会掉,输出噪声上升;第三,视场角偏大,低速分辨率一般。这类模块最适合室内小型机、微型定高定点演示、教育类项目。你要是拿它做室外大轴距机型的主力定位,一定会失望。

另一类是 PX4Flow。它算是个老将,板载一颗 752×480 的全局快门传感器加一颗做光流计算的协处理器,直接输出算好的光流和高度数据,串口或 I2C 都支持。它的优势是算法成熟、适配度高,很多开源飞控的文档里都以它为范例,视场窄带来更好的低速精度,能工作的高度也比小模块高。缺点同样鲜明:体积大、重量重、需要 5 伏供电、成本高,而且这个方案已经有些年头,新固件对它的支持在逐步减弱。如果你的飞控固件比较新,装之前一定确认驱动还在。

还有一类是老的鼠标传感器方案,比如基于 ADNS 系列的模块。这类东西现在基本属于“能跑但别买”,量程和表面质量要求都比 PMW3901 更苛刻,市场上货源也杂。除非你手上正好有,或者纯粹为了做实验,否则不建议作为新项目的选型。

3.2 自研视觉路线:相机加光流算法

当现成模块满足不了需求时,自研就是唯一出路。典型架构是一块带摄像头的计算板,向下拍摄地面,用稀疏光流或者特征点匹配算出图像位移,再结合测距数据换算成速度,最后通过 MAVLink 消息发给飞控。这条路线的自由度极高:镜头可以换,分辨率可以调,算法可以改,能覆盖从 0.3 米到十几米的范围,也能适应室外强光环境。

代价也很真实。首先是算力,稀疏光流在低分辨率小图上跑很快,但分辨率一上去、金字塔层数一加,帧率就掉。其次是标定麻烦,镜头畸变、像素焦距、与机体的安装偏差都要逐一标定,标不准的话速度输出会有一到两成的系统误差,表现出来就是飞机会持续朝一个方向缓慢漂移。第三是延迟,图像采集加算法处理加串口传输,累积延迟很容易到 60 到 100 毫秒,必须在滤波器里如实填写延迟参数,否则速度估计会震荡。

我给一段实际用过的稀疏光流核心逻辑,思路是取上一帧的特征点,在当前帧里做金字塔光流跟踪,再用前后一致性检查剔除错配,最后用这些点的平均位移估计像素运动量。

import cv2 import numpy as np lk_params = dict(winSize=(21, 21), maxLevel=3, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 30, 0.01)) def estimate_flow(prev_gray, gray, prev_pts, fov_rad, width): next_pts, status, _ = cv2.calcOpticalFlowPyrLK(prev_gray, gray, prev_pts, None, **lk_params) back_pts, status_b, _ = cv2.calcOpticalFlowPyrLK(gray, prev_gray, next_pts, None, **lk_params) # 前后一致性检查,过滤掉跟踪错误的点 good = (status.ravel() == 1) & (status_b.ravel() == 1) fb_err = np.linalg.norm(prev_pts - back_pts, axis=2).ravel() good &= fb_err < 1.0 src = prev_pts[good] dst = next_pts[good] if len(src) < 10: return None delta = (dst - src).mean(axis=0) # 像素位移换算成角速度,IFOV = 视场角 / 图像宽度 ifov = fov_rad / float(width) omega_x = delta[1] * ifov # 前后方向 omega_y = delta[0] * ifov # 左右方向 return omega_x, omega_y, len(src)

提示:特征点数量少于十个的时候,我一般直接丢弃这一帧,宁可让飞控少一个观测,也不要给它一个噪声很大的速度。EKF 对野值的容忍度比想象中低。

这段代码只是骨架,实际工程里还要处理镜头畸变校正、地面平面假设验证、以及和陀螺数据的同步。但核心思路就这些:跟踪、剔坏点、求平均位移、乘 IFOV、乘高度。

3.3 一张表看清三条路线的取舍

维度一体化小模块相机模块自研视觉方案
体积重量极小极轻中大偏重取决于计算板
有效高度0.3 至 1.5 米0.5 至 3 米以上可覆盖更大范围
光照要求较高,暗光退化中等可通过算法和曝光控制优化
延迟偏高,需补偿
标定难度低,基本免标定
成本中到高
适配工作量

看完这张表你应该能感觉到,选型本质是在“省事”和“能力”之间做权衡。室内小机做演示,选第一列;室外中大型机做长航时巡检,第二列或者第三列才现实。

3.4 我的选型决策顺序

我自己下单前会按这个顺序过一遍,供你参考。先定高度区间,因为这是最硬的约束,它直接砍掉一半候选;再看地面类型,如果现场是可移动的深色地面或者水面,直接放弃光流换其他手段;然后看飞控固件对驱动的支持情况,新版固件优先选支持度好的型号;最后才看价格和体积重量。很多人反过来,先看价格再想效果,结果买回来发现高度不够用,或者暗光照下没法工作,钱和时间都浪费了。

4. 装到机上了:安装、标定与参数落地

模块买回来只是开始,我遇到的光流问题里,大概七成出在安装和参数配置,只有三成是模块本身。所以这一部分值得花比选型更多的时间。

4.1 安装位置和朝向,先解决这七成问题

光的流对安装位置有三条要求。第一条,尽量靠近机体重心,尤其是靠近水平旋转中心。因为飞控要减掉陀螺给的角速度分量,如果模块离重心太远,机体转动时模块本身会产生额外的平移运动,这个平移分量会被误认为是速度,造成偏差。第二条,避开桨叶遮挡,同时也要考虑下洗气流的影响。模块在桨盘正下方时,起降阶段容易被遮挡,而且如果配的是超声波测距,下洗会让读数乱跳。第三条,模块光轴要尽量与机体垂直轴平行,装歪了会造成两个轴的交叉耦合,前进时误报侧移。轻微的安装角可以用参数里的安装旋转来补偿,但角度大了补偿也没用。

朝向这块要特别注意。绝大多数模块都有明确的“前向”标记,需要和机头方向一致。如果装反了或者转了 90 度,飞控收到的速度符号就是错的,表现出来是飞机一往东漂,飞控就加大往西推,越推越快,几秒内就飞出去。这种情况我在调试初期遇到过,第一反应以为是 EKF 参数问题,查了两个小时才发现是模块装转了 180 度。参数里通常有一项专门用来声明安装朝向,可以按 45 度为单位旋转,但我建议物理安装尽量装正,参数只用来做小角度微调。

还有一条容易被忽略:模块下方不能有明显的反光面或者透明罩。有些机架为了美观加一块透明亚克力保护板,结果光流看到的是板子上的灰尘纹理和反光,不是地面,数据完全不可用。要么开孔,要么换成哑光深色的非透明材料。

4.2 PX4 侧的关键参数与落地顺序

PX4 里面光流的融合在 EKF2 里做,配置逻辑我按这个顺序走。第一步,确认光流传感器本身被识别到,看传感器状态里有没有对应的光流实例,以及数据是否在更新。第二步,确认测距源可用,高度数据稳定且在合理范围。第三步,设置安装朝向参数,声明模块相对机体的旋转角度。第四步,设置光流延迟参数,把从图像采集到数据进入飞控的延迟如实填上,SPI 直连可以填小一些,串口 MAVLink 要填大一些。第五步,打开 EKF2 中光流的使用开关,让它参与速度观测。第六步,确认高度参考源指向测距源,而不是气压计,否则低空定高会用气压计的数据,高度估计在地面效应下会不准,进而把光流速度算错。

这里有个我认为最关键的隐藏前提:光流融合需要三个条件同时成立,陀螺数据有效、测距数据有效、光流数据有效。任何一个失效,EKF 会直接把光流观测停用,而且这个状态有时不会在界面上明显提示,你只会看到飞机开始漂,却不知道原因。所以每次起飞前,我都会在状态面板上把这三个数据源挨个看一遍,确认都在正常更新。

注意:不同固件版本的参数名和取值会有差异,尤其是涉及速度源和高度源选择的参数,改动前务必对照当前版本的参数说明。我下面给的是我常用的组合逻辑,具体数值请以你飞控版本的参数表为准。

4.3 ArduPilot 侧的关键参数与落地顺序

ArduPilot 的配置逻辑类似,但参数分组不一样。我通常按这几步走:先设光流类型参数,告诉固件接的是哪种模块;再设焦距参数,也就是水平方向和垂直方向的像素焦距,这两个值直接决定像素位移换算成角速度的比例,标定不准会带来系统性的速度误差;然后设安装偏航角,声明模块和机头的角度差;接着把 EKF 的水平速度源指向光流;最后确认高度源指向测距,并检查光流和测距数据的更新率是否达到融合要求。

这里有个细节值得展开:焦距参数填的是像素焦距,不是视场角。它和视场角的关系是,像素焦距等于图像宽度的一半除以视场角一半的正切值。假设图像宽 640 像素,水平视场角 60 度,那么像素焦距约等于 320 除以 0.577,约 554 像素。填错这个数,光流输出的速度就会整体放大或缩小,看起来像是飞机在漂,其实是你把比例填错了。我一般不用算的,直接按后面的地面标定方法实测出来,更可靠。

4.4 地面标定:用尺子和秒表把焦距实测算出来

厂家给的视场角经常是典型值,镜头装配有公差,标称 42 度实际可能是 40 度或者 44 度,直接换算出来的焦距会有几个百分点的误差。对于低速定点飞行,几个百分点已经能造成可见的漂移了。所以我更相信实测。

实测方法很朴素:把飞机放在纹理丰富的地面上,固定好,水平缓慢直线移动一段已知距离,比如两米,同时记录光流累积输出的角度增量。用高度 h 和移动距离 d 算出实际的角度变化,也就是 atan(d/h) 或者小角度近似 d/h,再用这个角度除以光流累积的像素数,就得到每像素对应的真实角度,取倒数就是像素焦距。移动要慢要稳,最好用导轨或者匀速推车,手推的速度不均匀会让结果发散。重复三到五次取平均,和理论值的偏差如果超过 10%,我就以实测为准。

标定完之后,我会做一次闭环验证:把飞机放在开阔的有纹理地面上,手动起降到一米左右,观察速度估计是否接近零,然后轻轻推杆让它缓慢前后移动,看看飞控估计的速度方向和大小是否跟实际吻合。如果方向和实际相反,说明安装朝向参数填反了;如果大小整体偏大或偏小,说明焦距参数还需要修。这一步做完,光流才算真正可用。

5. 现场排错:拒融合、乱跳、原地漂移怎么查

光流相关的故障,表现通常只有三种:飞控根本不融合光流、融合了但速度值乱跳、速度值平稳但飞机持续朝一个方向漂。这三种现象对应的排查路径完全不同,我按自己的习惯整理成下面这张速查表。

5.1 现象、原因、对策速查

现象最可能原因排查与对策
光流状态始终不融合测距源无效或高度数据跳变检查测距读数是否稳定,室外优先换激光测距
光流状态始终不融合光流数据更新率过低或有野值看数据更新频率,确认线序和接口方式,必要时降低串口波特率干扰
融合了但速度值乱跳振动传递到模块或镜头加减振、加固安装、检查镜头是否松动
融合了但速度值乱跳地面纹理不足或光照过暗换到有纹理的场地,或加补光,避免镜面地面
融合了但速度值乱跳陀螺与光流时间不同步检查时间戳,补偿光流延迟参数
速度平稳但持续单向漂移焦距参数偏大或偏小用尺子做地面标定,实测修正焦距
速度平稳但持续单向漂移模块安装朝向有偏差检查安装角度参数,物理上尽量装正
低速漂移方向与实际相反安装朝向填反修正朝向参数或物理转向
起飞瞬间光流就异常地面有透明保护罩或反光拆除遮挡物,或改用不透明哑光材料
高空后光流失效超出模块有效高度依据实际高度换方案或改用其他定位手段

这张表是我踩坑之后逐步攒起来的,实际排查时我会先看现象落在哪一行,然后按可能性从高到低试,不要一次改一堆参数,否则就算修好了也不知道是哪一项起的作用。

5.2 三块“光流杀手”地面,遇到就换方案

第一块是水面。水面在无风时几乎不产生稳定纹理,有风时纹理又完全随机,光流在水面上方基本不可用。做水上巡检或者跨水飞行时,不要指望光流给你水平速度参考,得换其他手段。

第二块是镜面地砖和抛光混凝土地面。这类地面的问题是反射,模块看到的是上方环境和反射光,不是地面本身的纹理,数据会呈现出无规律的跳动。解决方法是在这类地面上飞的时候,依靠其他定位手段,或者临时铺设纹理垫。

第三块是正午强光下的浅色沥青或者水泥地。光照太强会让图像过曝,纹理对比度下降,表面质量指标掉到阈值以下,光流输出变成零或者噪声。这种情况我一般会把飞行时间错开,或者调整模块的曝光设置,如果模块支持的话。

5.3 振动、光照和延迟这三个隐性杀手

振动的影响经常被低估。光流算的是像素位移,机体高频振动会让图像模糊,特征点跟踪就变成随机匹配,输出噪声。而且振动还会通过镜头结构传递,导致实际成像位置的抖动。我给光流模块加装减振的时候,用的是软性减振垫而不是硬连接,效果比加固连接好得多。这一点和很多人直觉相反,他们觉得光流不准是因为安装不牢,于是使劲拧紧,结果振动传得更直接。

光照方面,全局快门和卷帘快门的差别在光流上体现得很明显。卷帘快门在机体快速移动时会产生果冻效应,图像行与行之间有相位差,光流算出来的位移会失真。所以如果做高速应用,优先选全局快门传感器,这也是相机方案比小模块更能胜任高速场景的原因之一。

延迟方面,很多人填参数时习惯性地留空用默认值,但串口 MAVLink 光流的端到端延迟可能有几十毫秒,在快速机动时会造成速度估计滞后,表现出来是飞控修正总是慢半拍,飞机会画小幅度的波浪。我的做法是用示波器或者简单的时序打点,先把延迟测出来,再如实填进参数。测不准的话,宁可往大了填一点,因为延迟填小会让滤波器过度自信,比填大更危险。

6. 光流不止用来定位:稳像、目标跟踪与背景补偿

前面讲的都是把光流当速度传感器用,但它其实还有另一类用法,就是纯粹当“画面运动估计器”。这类应用在视觉相关的项目里很常见,也值得单独聊一下,因为选型逻辑和定位用途完全不同。

6.1 光电吊舱稳像里的光流

光电吊舱在跟踪目标时,机体自身的姿态抖动、飞行振动都会传递到画面上,导致目标在画面里抖动,影响观察和跟踪。传统的做法是用陀螺数据做前馈补偿,但陀螺只能反映角运动,反映不了平移引起的画面位移。这时候用光流估计画面整体运动,把运动分量从跟踪框的位移里减掉,跟踪框就能牢牢锁在目标上。这种场景对光流模块的要求是延迟极低、分辨率够高,对高度的要求反而不重要,因为不需要换算成地面速度。

6.2 运动目标检测里的背景补偿

在“低慢小”这类目标探测的场景里,相机固定或者缓慢移动,画面里既有缓慢漂移的背景,也有快速移动的小目标。如果直接用帧差法,背景自身运动会产生大量假报警。用光流估计出背景的运动模型,也就是整体平移加旋转加缩放,把背景对齐之后再相减,剩下的就是真正的运动目标。这个思路在演示系统里很常见,配合告警信息弹出,整个链路从检测到报警一气呵成。这类应用对光流的绝对精度要求不高,但对鲁棒性要求很高,因为场景里光照变化、云影移动、树叶摇动都会干扰估计。

这两类用法提醒我一件事:光流模块的选型没有绝对答案,取决于你拿它干什么。做定位,看高度量程、测距配套和飞控适配;做视觉,看帧率、延迟和分辨率。同一个 PMW3901,做定位时可能勉强够用,做视觉时可能完全不够,因为它的输出是稀疏的低分辨率运动矢量,没有完整的光流场。

6.3 用光流延伸出视觉里程计

如果手上已经有相机和算力,光流还能往上长成视觉里程计。做法是同时估计相机的旋转和平移,用特征点匹配恢复两帧之间的运动,再结合 IMU 做尺度恢复。这条路线的产物是完整的位置和速度估计,可以独立于 GNSS 工作一段时间,和飞控里的 EKF 融合或者做交叉验证。这条路比单纯的光流模块复杂得多,但只要算力和标定到位,能力上限也高得多。我自己试过在小型计算板上跑稀疏特征加 IMU 的组合,室内短距离飞行的位置漂移可以控制在百分之几的量级,代价是调试周期以周计。

7. 几条我踩过坑之后才明白的硬经验

说了这么多,最后聊几条我认为最值钱的经验,都是自己吃过亏总结出来的。

第一,光流不是独立部件,它永远和测距源绑在一起选。买模块的时候把测距一起考虑,问清楚两者的有效高度区间,取交集,交集太窄就换方案。我见过太多人只盯着光流参数,装完了才发现测距在室外根本不好使,整套方案白搭。

第二,别信标称值,信实测。视场角、焦距、有效高度、最大速度,手册上的数字都是典型条件下的,你的镜头装配、你的安装角度、你的地面材质都会让实际值偏离。留余量,做标定,比看参数表有用。

第三,参数一次只改一个。调光流最忌讳同时改焦距、改朝向、改延迟、改融合开关,改完效果好你也不知道是哪一项起了作用,效果差更是一团乱麻。我的习惯是每次改一项,飞一次,记录日志,对比速度估计曲线。

第四,日志比感觉可靠。光流装得对不对,看日志里的速度估计和实际轨迹是否吻合,看陀螺和光流的相位关系,看是否出现周期性的振荡。肉眼看飞机“好像还行”,往往掩盖了正在积累的误差。

第五,这套东西的上限在原理,不在你的调试水平。地面没纹理、高度超量程、光照太差,这三条任何一条成立,再高明的参数调优都救不回来。遇到这种情况,及时认输换方案,比死磕参数省时间得多。

如果后续要扩展,我会优先考虑两件事:一是把光流和视觉里程计结合起来,用光流做快速的速度观测,用里程计做慢速的位置修正,两者互补;二是在有算力的平台上做多传感器融合测试,把光流、视觉、IMU、测距放在同一个框架里对比各自的漂移特性,这样下次选型就有实测数据打底,而不用再靠猜。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询