038、视觉惯性里程计(VIO)简介
从一次炸机说起
去年夏天,我在一个农业植保项目里调试PX4的VIO模块。飞机在麦田上空飞了大概三分钟,突然开始剧烈抖动,然后一头栽进田里。事后分析log,发现IMU数据在某个时刻出现了明显的漂移,而视觉里程计(VO)给出的位姿估计在那一帧完全跳变——两个传感器“吵起来了”,融合算法没兜住。
那次之后我花了整整两周时间,把VIO的底层逻辑重新捋了一遍。今天这篇笔记,就是当时踩坑的总结。
VIO到底在解决什么问题
纯视觉里程计(VO)靠图像特征点匹配来推算运动。但单目相机有个致命弱点:尺度不确定。你看到两张图里的特征点移动了,但不知道是相机走了1米还是10米——除非你已知场景中某个物体的真实尺寸。更麻烦的是,快速旋转或光照突变时,特征点会跟丢,VO直接崩掉。
IMU(惯性测量单元)提供加速度和角速度,短时间内的积分非常准,但积分误差会随时间累积,几分钟后位置可能偏出几公里。
VIO的思路很朴素:用IMU的短时精度来约束VO的尺度漂移,用VO的长期稳定性来修正IMU的累积误差。两者互补,就像你闭着眼睛走路时,每隔几秒睁眼看一下路标。
核心框架:紧耦合 vs 松耦合
这是VIO设计的第一道选择题。松耦合简单粗暴:VO算出一帧位姿,IMU算出一帧位姿,然后拿卡尔曼滤波去“平均”一下。我早期在STM32F4上试过这种方案,代码好写,但效果很差——两个传感器各自为政,一旦VO丢帧,IMU的漂移会瞬间接管。
紧耦合才是工业级的选