资讯动态

小觅S系列跑vins-mono轨迹飘飞?一套调参流程帮你稳定输出六自由度里程计

发布时间:2026/10/16 5:21:38 来源:尧图企业网站定制
先说一下我这段时间的实际经历。模拟项目X要求用一台小觅S系列双目相机跑vins-mono输出六自由度里程计。相机一接上、launch一启动前两三秒还能看到轨迹正常往前走再往后就是失控现场——轨迹直接飘到窗外或者原地疯狂打转。我把网上能搜到的参数几乎都调了一遍最后真正让轨迹稳定下来的不是某一个“魔法参数”而是一整套环环相扣的处理流程。这篇内容就是把这套“轨迹飘飞解决版”完整记录下来从驱动配置、写参数文件、采数据、跑算法到用工具量化轨迹误差每一步都讲清楚背后的原因。适合手里有小觅S系列、正准备跑vins-mono但被漂移折磨到怀疑人生的同学参考。1. 先拆根源S系列跑vins-mono为什么容易轨迹飘飞1.1 轨迹飘飞的三种典型现场我收到的反馈里轨迹飘飞基本可以分成三类。第一类是“开局即飞”系统启动没几秒轨迹就一下蹦到几米外这种情况大概率是相机内参、图像分辨率或者外参方向写错了。第二类是“慢飘型”一开始轨迹看着正常跑十几秒后开始逐渐偏离真实路径转弯的时候偏差尤其明显这种多半是外参不够准或者时间戳没对齐。第三类是“尺度型漂移”轨迹形状大体对但距离越跑越短或越长单目视觉融合IMU时尺度估计不稳和初始化质量、运动模式都有关系。明确是哪种“飘”很重要因为排查方向完全不同。很多人一上来就调IMU噪声权重结果把原本还算稳定的系统越调越糟。我后来养成一个习惯先录一段数据固定复现漂移现象再针对现象动手而不是凭感觉乱试。1.2 从原理上解释视觉、IMU和坐标系是怎么打架的vins-mono的核心思路是把相机图像和IMU测量放進一个紧耦合的滑窗优化里。图像告诉你“我看到了什么”IMU告诉你“我动了多少”。但如果这两套信息在空间和时间上对不齐它们就会互相矛盾优化器只能在一个错误的折中点上收敛表现出来就是轨迹飘飞。空间上的对齐靠的是相机到IMU的外参也就是旋转和平移。这是最容易被忽视又最容易出大问题的参数。外参旋转哪怕偏差一两度系统在直线运动时看着没事一旦有转弯或者加减速估计出的轨迹就会朝固定方向持续偏。时间上的对齐靠的是时间戳相机图像和IMU数据之间如果存在一个固定的延迟相当于“眼睛看到的东西”和“身体感受到的运动”不同步运动越快偏差越离谱。我做过一个排序影响轨迹稳定性的因素大致是外参方向/数值错误 图像分辨率与内参不匹配 IMU与图像时间偏移 IMU噪声参数不合适 初始化静止时间不足 运动退化纯旋转等。后面所有检查和调参我都按这个优先级走。影响因素 | 典型现象 | 影响程度 | 建议排查顺序 --- | --- | --- | --- 相机内参/分辨率错误 | 启动即飞、轨迹瞬间发散 | 极高 | 1 外参方向/数值错误 | 定向漂移、转弯更明显 | 极高 | 2 时间戳偏移 | 运动越快越飘、振荡 | 高 | 3 IMU噪声参数不合理 | 整体漂移或抖动 | 中 | 4 初始化静止不足 | 前期轨迹抖、尺度不稳 | 中 | 5 纯旋转/快速运动退化 | 轨迹乱飞或丢失 | 中 | 62. 环境与驱动相机驱动和vins-mono编译避坑2.1 软件版本与依赖清单我用的环境是Ubuntu 18.04加ROS Melodic这套组合跑下来兼容性最省心。小觅S系列的SDK官方推荐的是Ubuntu 16.04/18.04加对应ROS版本如果系统版本太新驱动编译容易出现各种依赖问题。编译相机SDK前有几个系统库需要提前装好OpenCV开发库、Eigen3、以及一些图像处理库。如果SDK编译时报缺少leptonica或tesseract头文件说明图像处理依赖没装全直接通过apt安装对应包就能解决。这里提醒一句SDK里有些demo需要OpenCV 3.x而系统里如果同时装了OpenCV 4.x编译时容易链接到错误版本建议在编译前先确认默认OpenCV版本或者直接在CMake里指定路径。vins-mono这边核心依赖是Ceres Solver和Eigen3。Ceres版本建议用1.14.x太新的版本和vins-mono的代码可能存在兼容问题我自己就遇到过2.x版本编译通过但运行时报内存错误的坑。Eigen3则需要3.3.x以上版本太低某些矩阵运算会出问题。2.2 相机驱动启动与话题检查驱动编译完成后插上相机启动launch文件。S系列的驱动会发布一系列话题vins-mono真正需要的只有两个左目图像话题和IMU原始数据话题。启动之后第一件事不是急着跑vins而是检查话题频率。用rostopic hz分别看图像话题和IMU话题的频率。S系列的IMU一般是200Hz图像在配置的分辨率下通常为20到30帧。频率不对就要先排查如果IMU只有100Hz很可能是USB3.0接口没插好或者用了USB延长线、劣质集线器导致带宽不足。图像频率低则可能是分辨率设置过高在vins-mono场景下没必要跑高分辨率640x480完全够用反而能降低丢帧概率。还要检查时间戳是否连续。用rostopic echo -n 5 /mynteye/imu/data_raw看输出的header时间戳如果出现时间戳倒跳、长时间不变的情况说明驱动和系统时钟有问题这种数据跑vins必飘。我后来习惯在录制前先跑一个timeout 3 rostopic echo /mynteye/imu/data_raw快速确认一下时间戳是否单调递增。检查命令示例rostopic hz /mynteye/left/image_raw rostopic hz /mynteye/imu/data_raw rostopic echo -n 5 /mynteye/imu/data_raw2.3 编译vins-mono的常见拦路虎vins-mono的源码从开源仓库克隆到工作空间src目录后直接catkin_make理论上会自动拉取依赖但实际编译中总会碰到几个固定问题。最常见的是找不到Eigen3。报错信息是Could not find a package configuration file provided by Eigen3。这不是依赖没装而是CMake的查找路径没指向系统Eigen3目录。解决办法是在~/.bashrc或当前终端里设置环境变量export CMAKE_PREFIX_PATH/usr/include/eigen3:$CMAKE_PREFIX_PATH还有一个高频问题是Ceres版本过高导致编译错误比如某些头文件路径变了。最直接的方案就是卸载高版本编译安装Ceres 1.14.x。编译Ceres时记得安装它的依赖liblapack-dev、libsuitesparse-dev否则会报BLAS相关错误。如果以上都排除了还遇到glog相关错误通常是glog版本和Ceres不匹配把glog升级或降级到兼容版本即可。这些坑单看都不难但在一个环境里连续出现会很消磨耐心。我的建议是先在一台干净的机器上把流程跑通一次再移植到主力环境能省大量时间。3. 配置文件是命门cam和imu参数逐项修改3.1 相机内参与分辨率必须匹配vins-mono启动时读入yaml配置文件里的相机内参和畸变参数然后用这些参数对图像特征点去畸变再投影到单位球面上。如果内参或分辨率不对特征点的空间位置从一开始就是错的初始化阶段就会判定失败或者轨迹乱飞。小觅S系列在驱动层面已经提供了标定内参。关键是用左目的内参不是右目。别笑我真的见过配置里把右目内参写到cam0里的情况结果整个系统完全无法初始化。还有一个更容易踩的坑是分辨率。S系列支持多种分辨率输出如果SDK里设置的是1280x480而配置文件里resolution写的是[640, 480]焦距也不改那么图像中心虽然对得上但边缘畸变和尺度全是错的轨迹会渐进式地飘。最稳妥的做法是把SDK的分辨率固定成640x480然后把配置文件里的resolution和内参都按这个分辨率来。提取内参时注意SDK给出的畸变系数可能包含两个以上参数vins-mono默认使用pinhole模型加k1、k2、p1、p2四个畸变参数如果标定结果里还有其他项先用这四项近似影响不大。3.2 IMU与外参的“方向坑”外参的定义方向是vins-mono里最容易写错的地方。配置文件里的body_T_cam0指的是从相机坐标系到IMUbody坐标系的变换也就是把相机坐标系下的点变换到IMU坐标系。而小觅S系列的标定文件里通常给出的是从IMU到相机的变换或者反过来需要自己确认并求逆。我做个类比内参是“眼睛怎么成像”外参是“眼睛长在身体的哪个位置、朝哪个方向”。如果标定文件给的是相机到IMU的变换那么写入vins配置文件时必须取逆[ T_{imu_from_cam} (T_{cam_from_imu})^{-1} ]包括旋转矩阵求逆平移部分求逆后再旋转。这一步只要搞反系统表现就是开机后轨迹直接发射。千万别觉得“反正也会被在线标定纠正”如果不开启estimate_extrinsic外参错就是错优化器怎么都救不回来。外参的平移单位是米S系列的基线一般是毫米级数字转换成米时小数点错一位会导致IMU和图像之间的空间错位在几十厘米以上轨迹也会出现明显漂移。写完参数后我习惯打印出来看一遍旋转矩阵的行列式是不是1平移量的量级是否正常。3.3 参数文件逐项说明一份基本能跑的配置下面是我稳定运行的一份基础配置核心字段已经标注用途。不同固件版本和分辨率下内参数值会不一样不能照抄但结构可以直接参考。imu_topic: /mynteye/imu/data_raw image_topic: /mynteye/left/image_raw output_path: /home/yourname/vins_output cam0: camera_model: pinhole resolution: [640, 480] intrinsics: [351.2, 350.8, 319.5, 239.5] distortion: [-0.28, 0.08, -0.0012, 0.0015] body_T_cam0: data: [0.012, -0.004, 0.021, 0.9997, -0.0152, 0.0041, 0.0153, 0.9999, 0.0035] estimate_extrinsic: 0 estimate_td: 1 acc_n: 0.08 acc_w: 0.00004 gyr_n: 0.004 gyr_w: 0.00004这里有几个关键决策说明一下。estimate_extrinsic我建议先设0用标定文件里的外参。如果你不确定外参是否转换正确可以先设1让vins在初始化阶段在线估计外参连续跑一段运动较丰富的短数据。如果设1时能收敛、轨迹基本正常但设0后直接飘那问题基本可以锁定是外参转换方向或数值错了。estimate_td设1让系统在线估计相机图像和IMU之间的时间偏移。S系列驱动输出的图像和IMU数据虽然来自同一硬件但也存在微小时间差在线估计能把这个偏差算出来并在优化中补偿。设0的前提是你已经通过标定工具得到了准确的时间延迟大多数情况下设1更省事。acc_n、acc_w、gyr_n、gyr_w这几个值是IMU噪声密度和随机游走参数很多资料建议按IMU数据手册来填。实际经验是只要量级正确对轨迹影响没那么致命vins会自己估计零偏。真正致命的是把acc_w和gyr_w设得特别小让优化器对IMU过度信任如果外参还有一点点误差轨迹反而更容易飞。4. 解决版实操从采数到评估的一整套流程4.1 采数规范决定成败的前三秒轨迹飘飞和抗不抗干扰的差距很多时候在数据采集阶段就决定了。vins-mono启动时需要初始化初始化的核心是让重力方向被准确估计。这就要求采集数据的开头有一段静止而且静止期间IMU的噪声要能被充分观测到。我录数据前会先进入一个开阔、光线稳定、纹理比较丰富的环境把相机放在静止平面上不动5秒以上然后才开始缓慢移动。初期移动要平滑不要猛加速不要一开始就原地快速旋转。很多人在室内随便拿起相机就大步流星地走结果vins初始化都没完成轨迹当然飘。关于曝光一定要把相机驱动里的自动曝光关掉手动固定曝光。自动曝光在从窗户附近走到室内暗处时图像亮度会发生阶跃变化特征点跟踪会大面积丢失系统会拿错误的数据做优化轨迹立刻飘。同样自动白平衡最好也关掉固定色温减少颜色跳变对特征匹配的影响。准备好后可以录制bag便于反复调试同一份数据rosbag record -O seq01.bag /mynteye/left/image_raw /mynteye/imu/data_raw录制期间如果方便可以同步用手机拍一段实际路径或者在地面上贴标记点后面评估轨迹时有参照物比纯看RViz可视化靠谱得多。4.2 在线运行vins-mono的启动顺序启动顺序也有讲究。我的固定流程是先启动相机驱动等待图像和IMU话题频率稳定再启动vins_estimator主程序最后打开RViz可视化。倒过来容易让vins读取不到IMU数据而卡在初始化阶段。roslaunch mynt_eye_wrapper mynteye_wrapper.launch roslaunch vins_estimator s1030.launch roslaunch vins_estimator vins_rviz.launch如果录好了bag可以关掉相机驱动直接播放数据集rosbag play seq01.bag播放时注意--clock参数要把bag里的时间戳同步到ROS时钟否则vins处理数据时可能因为时间不连续出问题。如果用的是在线相机流不需要设置时钟。跑起来后RViz里会先看到特征点显示然后进入初始化窗口。正常情况下要等几秒出现“Initialization finished”类似的提示后轨迹开始绘制。如果一直卡在等待初始化先检查运动是否太剧烈、静止时间是否足够再检查内参和分辨率。4.3 用evo量化轨迹到底飘没飘肉眼看RViz轨迹飘不飘不够严谨调参后必须量化对比。vins-mono运行时会发布里程计话题也会把轨迹保存到output_path目录下的csv文件。我习惯用evo这个工具做轨迹评估它支持TUM和Euroc格式能算APE和RPE误差。先把轨迹话题转成TUM格式。最简单的方式是用rostopic echo导出原始位姿再写成tum格式文本也可以用rosbag里的/vins_estimator/odometry配合evo自带工具直接转换。转换完成后逐项运行evo_ape tum vins_result_no_loop.csv groundtruth.tum -va --plot evo_rpe tum vins_result_no_loop.csv groundtruth.tum -va --plot没有真值轨迹时可以把第一次采集并处理出的轨迹当作参考或者用手持方式走一个闭合路径回到起点后看起点误差大致是多少。闭合轨迹的起点误差是很好的直观指标一般几米长的路径回到起点偏差在厘米级算正常如果偏差几十厘米甚至几米就要继续排查。4.4 调参决策顺序不盲调、不乱试如果量化后发现轨迹确实飘应该按顺序调整而不是随机组合参数。下面这套顺序是我反复实践后总结出来的能覆盖绝大多数漂移场景。第一步确认图像话题和配置分辨率一致。分辨率不一致时系统可能能勉强运行但轨迹会渐进式发飘肉眼不易察觉量化的APE却很高。第二步外参在线标定一次。把estimate_extrinsic设1estimate_td设1用一段运动丰富的短数据跑一遍。如果在线标定后轨迹明显好转说明之前的外参不对。可以记录下在线标定输出的外参把estimate_extrinsic设回0填入新的外参继续测试。第三步检查IMU频率和时间戳排除硬件层面的数据问题。第四步固定相机曝光和白平衡重新采一遍数据再对比。第五步如果以上都做了还飘再考虑特征跟踪参数。把feature_tracker里的max_cnt适当提高比如从150改成200min_dist从30降到20让特征点数量更充足抗运动模糊能力更强。第六步实在不行检查滑动窗口相关参数但我一般不推荐动窗口大小和边缘化策略改这些参数容易引入新的不稳定。调整顺序的表格版调整步骤 | 操作 | 判断标准 --- | --- | --- 1 | 核对分辨率和内参 | 初始化是否成功 2 | 外参在线标定对比 | 轨迹是否显著改善 3 | 检查IMU频率/时间戳 | 数据是否稳定 4 | 固定曝光与白平衡 | 特征跟踪是否稳定 5 | 调整特征点数量 | APE是否下降 6 | 微调IMU权重参数 | 抖动是否减少4.5 我实测下来的效果变化为方便说明我记录过一次调参前后的对比。最初配置是外参方向填反启动后轨迹在1.2秒内直接飞出视野属于“开局即飞”。修正外参后系统可以初始化并运行但APE达到了0.9米路径绕一圈后回到起点偏差0.55米。固定曝光并重新采数后APE下降到0.31米。再把estimate_td打开在线估计时间偏移APE进一步下降到0.17米。最后将特征点数量从150提到200终点闭环误差降到0.08米。这个对比可以明显看出轨迹飘飞不是单一原因而是多个小误差叠加的结果每解决一层精度就上一个台阶。5. 轨迹飘飞排查实录常见问题与解决顺序5.1 高频问题速查表下面是一份可直接对照的速查表覆盖我处理过的绝大多数S系列加vins-mono问题。现象 | 优先级 | 核心排查点 | 解决思路 --- | --- | --- | --- 启动即飞 | 1 | 分辨率/内参/外参方向 | 逐项核对配置和SDK标定参数 初始化卡住 | 2 | 静止时间/运动激烈程度 | 开机后静止5秒平滑起步 运行十几秒后缓慢偏 | 3 | 时间偏移/外参精度 | 打开estimate_td重新标定外参 转弯时明显漂 | 4 | 外参旋转部分 | 用在线标定结果替换原外参 固定场景原地抖动 | 5 | 特征点太少/曝光变化 | 增大max_cnt固定曝光 轨迹尺度缩水或放大 | 6 | 初始化质量/纯旋转过多 | 保证静止初始化减少纯旋转 回环后位置跳变 | 7 | 回环检测误匹配 | 检查特征跟踪必要时关闭回环5.2 三个典型案例展开第一个案例启动即飞开局就失控。排查后发现配置文件里resolution写的是[752, 480]而SDK实际输出是[640, 480]内参没改导致系统按错误的缩放比例理解图像特征点投影全错。把分辨率统一后问题立刻消失。这种问题隐蔽在“看起来差不多”的数据里不量化你根本发现不了。第二个案例慢飘型跑十几秒后轨迹逐渐向外偏。一开始怀疑IMU噪声参数调整后无改善。后来把estimate_td从0改成1系统在线估计出的时间偏移有将近28毫秒。这个延迟足以让图像和IMU的运动估计错位尤其在快速运动时特别明显。修正后轨迹明显稳定。第三个案例手持设备原地转圈轨迹乱成一团。原因很典型大量纯旋转运动让单目视觉无法约束尺度算法靠IMU积分支撑而IMU积分本身在纯旋转下漂移严重。解决办法很简单采集数据时加入平移运动不要只顾着转圈让画面有明显的视差变化。这属于运动模式问题调参解决不了。5.3 一个忘记不了的教训别迷信“推荐参数”网上很多帖子里会贴出某个配置文件说是“亲测不飘”我一开始也直接拿来用结果换了一台相机仍然飘。后来才明白每台设备的固件版本、出厂标定、安装方式都有差异参数文件必须基于自己手上这台设备的标定结果生成别人的配置只能作为结构参考。实际操作中我踩过几次坑之后最终的体会是把基础数据链路打通比调参更重要。分辨率、内参、外参方向、IMU频率、时间戳、静止初始化、固定曝光这七件事全部确认到位轨迹飘飞的问题大概率已经解决了七成。剩下的小幅漂移才轮到用那些细碎的IMU权重参数去修。之后再遇到轨迹飘飞的案例我第一反应永远是回头查配置和数据链路而不是去动vins的优化参数。这个思路分享给你至少能帮你少走几个星期的弯路。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑