Kimera SLAM是MIT开源的一个视觉惯性语义SLAM系统,第一次接触的人通常会问:它和ORB-SLAM、VINS-Fusion到底有什么不一样?一句话说清楚,Kimera不只是给相机跑出一条轨迹,它能同步输出稀疏位姿、稠密三维网格和像素级语义标签。在Ubuntu 18.04 + ROS Melodic这套经典组合下,把Kimera从源码编译起来并跑通公开数据集,是很多人入坑多模态SLAM的第一道坎。这篇文章面向已经装过ROS、跑过简单demo,但还没完整编译过大型SLAM工程的同学。我会把整个安装流程、依赖库版本、编译参数、demo启动方式和排坑记录全部过一遍,尽量做到你照着操作就能跑通。
1. 项目整体设计与选型思路
1.1 Kimera SLAM到底是什么
Kimera是MIT SPARK实验室开源的一套基于因子图的视觉惯性里程计与多模态建图系统。它最大的特点不是某一个模块特别强,而是把“视觉惯性状态估计 + 鲁棒位姿图优化 + 三维网格重建 + 语义分割标注”四件事做在了同一个框架里,并且以ROS节点的方式运行,对工程研究非常友好。
网上有人把它叫作“会语义理解的VIO”,这个说法不算夸张。普通VIO只给定位结果,Kimera能顺带告诉你这面墙是建筑、这个物体是人、那棵树是植被。如果你在做机器人导航、无人机自主飞行或者自动驾驶相关的课题,这套系统能让你的感知层一次性拿到“我在地图哪里 + 周围长什么样 + 这些东西是什么”三份信息。
从代码结构上看,Kimera分为几个核心模块:Kimera-VIO负责视觉惯性里程计;Kimera-RPGO负责在检测到回环后做鲁棒位姿图优化,剔除错误回环;Kimera-Mesher负责把稀疏特征点升级成带纹理的三角网格;Kimera-Semantics负责把语义分割结果融合到三维网格上。每个模块可以单独编译使用,也可以整个串起来跑。
1.2 为什么选Ubuntu 18.04和ROS Melodic
Kimera官方对系统兼容性的态度比较保守,长期推荐的组合就是Ubuntu 18.04 + ROS Melodic。这不是说20.04完全不行,但18.04下所有依赖库都能用apt直接装到合适版本,不需要为OpenCV或PCL版本冲突花太多时间。
另外一个现实原因是ROS Melodic的包管理器里已经内置了OpenCV 3.2、PCL 1.8、Eigen 3.3这些和Kimera-VIO匹配的版本。你从源码编译的时候,系统自动找到的库版本刚刚好,不会出现“OpenCV 4.5编译通过但运行时崩溃”这种折腾人的问题。
如果你是新手,我建议第一遍老老实实用18.04。等跑通了,再在别的版本里折腾不迟。上来就用20.04或者22.04,很可能会卡在GTSAM或者OpenCV的兼容性上,最后连demo都跑不起来,挫败感太强。
1.3 整体系统模块拆解
在动手之前把模块关系理清楚很重要。Kimera在ROS里主要包含三个nodelet或者节点:
- Kimera-VIO节点:输入双目或单目图像 + IMU数据,输出里程计位姿和稀疏特征;
- Kimera-RPGO节点:接收VIO的因子图信息,做位姿图优化和回环修正;
- Kimera-Mesher节点:把优化后的位姿和历史关键帧融合成三角网格;
- Kimera-Semantics节点:在网格基础上做语义融合,输出带标签的三维地图。
注意,VIO部分本身可以独立跑,不需要Mesher和Semantics。如果你只是想先验证定位效果,可以只编译VIO模块,能省下不少时间。我自己的习惯是第一次全编译,后面调试只改相关模块,这样整体跑通了,后面再拆开也方便。
2. 环境准备与依赖安装
2.1 基础系统安装与软件源配置
安装Ubuntu 18.04时我建议直接选完整安装,不要用minimal版本,否则后面缺一堆图形库。系统装好后第一件事是更新apt源。
sudo apt update sudo apt upgrade -y如果你所在网络访问官方源慢,可以换成国内常用软件源。这里不展开讲具体源配置,你自己选择访问速度合适的镜像站即可。更新完源之后执行下面命令安装基础编译工具:
sudo apt install -y build-essential cmake git wget unzip \ python3 python3-pip python3-catkin-tools \ libeigen3-dev libopencv-dev libpcl-dev \ libyaml-cpp-dev libgoogle-glog-dev libgflags-dev \ libsuitesparse-dev libqt5widgets5这里有几个点值得说明。python3-catkin-tools是必须的,因为Kimera官方构建脚本用的是catkin_tools而不是传统的catkin_make,后面会讲原因。libsuitesparse-dev是GTSAM编译时需要的稀疏线性代数库,少了它编译GTSAM会报找不到CHOLMOD之类的错误。libyaml-cpp-dev用于读取yaml配置文件,缺了它运行demo时配置文件解析会崩溃。
2.2 安装ROS Melodic
如果之前装过ROS,可以跳过这一段。没装过的按ROS Melodic官网步骤来,核心是这三步:
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-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 sudo apt update sudo apt install -y ros-melodic-desktop-full如果apt-key这步因为网络原因失败,通常换keyserver或者稍后再试就能解决。安装完成后初始化rosdep并配置环境变量:
sudo rosdep init rosdep update echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrcrosdep初始化偶尔会遇到超时问题。我遇到过的原因是网络对rosdistro.ros.org访问不稳定,多试几次rosdep update一般能过。如果一直失败,也可以手动把所有依赖写到环境里,但工程量偏大,不建议新手走这条路径。
2.3 创建catkin工作空间并下载源码
这一步是整个安装过程中的关键拐点。首先创建并初始化工作空间:
mkdir -p ~/catkin_ws/src cd ~/catkin_ws catkin initKimera官方仓库结构比较特殊,它把VIO模块单独放在一个仓库里,Mesher、Semantics、RPGO则分属不同仓库。要一次性拉全所有模块,官方推荐使用kimera这个顶层仓库,里面包含vcs配置和构建脚本,一条命令就能把所有子模块下载到位。
下载顶层仓库:
cd ~/catkin_ws/src git clone https://github.com/MIT-SPARK/Kimera.git cd Kimera仓库里有一个install.sh脚本,它会自动下载依赖库并编译。但我不建议直接无脑执行,因为不同机器网络情况不一样,一旦某个依赖下载失败,整个脚本就中断,重新来过很浪费时间。我建议手动分步执行,这样每一步出问题都能及时定位。
查看仓库根目录下的文件和vcs配置:
ls -la cat .vcsconfig.vcsconfig文件里列出了所有需要clone的子仓库地址。你可以用vcs import来拉取全部源码,也可以手动逐个clone。手动逐个clone的好处是能看清每个仓库装到哪里,出了问题好排查;缺点是命令比较长。我的建议是用vcs工具,但提前把https换成可访问的网络协议,避免下载中断。
sudo apt install -y python3-vcstool vcs import < .vcsconfig执行完之后,src目录下应该出现kimera-vio、kimera-rpgo、kimera-mesher、kimera-semantics等目录。检查一下目录是否齐全,再继续下一步。
3. 源码编译与配置
3.1 编译GTSAM:整个工程最大的难点
Kimera-VIO对位姿优化的核心依赖是GTSAM,这是Georgia Tech开发的因子图优化库。编译版本上,官方要求的是4.0.2,这个版本有对应的bug修复,不能直接拿4.1或4.2替代,除非你自己会改代码适配API。
建议直接下载源码编译:
cd ~/catkin_ws/src git clone --branch 4.0.2 https://github.com/borglab/gtsam.git cd gtsam mkdir build && cd build cmake -DGTSAM_USE_SYSTEM_EIGEN=ON -DGTSAM_BUILD_TESTS=OFF -DGTSAM_BUILD_UNSTABLE=ON .. make -j$(nproc) sudo make install这里-DGTSAM_USE_SYSTEM_EIGEN=ON很关键。如果不开这个选项,GTSAM会自己下载一套Eigen,编译时间长且容易和系统中其他库的Eigen冲突。-DGTSAM_BUILD_UNSTABLE=ON是为了让GTSAM的不稳定功能模块也被编译,Kimera-VIO部分代码会用到它。
编译GTSAM的时间取决于机器性能,8核以上大概20到40分钟,4核老机器可能得一个半小时。我当时踩过最大的坑就是内存不足,make -j$(nproc)在8G内存机器上直接把内存吃满然后交换空间持续飙升,最后编译进程被系统杀掉。后来限制编译线程数来解决:
make -j4内存只有8G的机器建议用-j2或-j4,不要贪多。编译完成执行sudo make install,GTSAM库会被安装到/usr/local,后面其他模块编译时会自动找到它。
3.2 编译Ceres Solver和OpenCV相关组件
Kimera-Mesher模块在构建网格时需要用到Ceres Solver做优化,所以这个库也要提前安装。Ceres的版本建议用1.14.0,新版API有变动,可能导致Mesher编译不过。
cd ~/catkin_ws/src git clone --branch 1.14.0 https://github.com/ceres-solver/ceres-solver.git cd ceres-solver mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release .. make -j4 sudo make installOpenCV方面,ROS Melodic自带的OpenCV 3.2对Kimera来说完全够用。你不用自己编译OpenCV,直接用系统库就行。唯一需要注意的是,如果之前手动编译过其他版本的OpenCV并且设置了OpenCV_DIR环境变量,编译Kimera的时候可能会出现版本错乱。遇到这种情况,先echo $OpenCV_DIR检查环境变量,有用的话取消掉。
另外,Kimera-Semantics会用到TensorFlow的C++接口做语义推理。如果你只想先跑通demo不看语义网格,可以暂时不编译Semantics模块,后面再单独补。我第一次跑的时候就没有开Semantics,先把VIO和Mesher跑通,确认没问题再回头搞语义,排错范围小很多。
3.3 使用catkin build批量编译
进入工作空间,开始编译整个Kimera工程:
cd ~/catkin_ws catkin build kimera_vio kimera_rpgo kimera_mesher如果Semantics相关代码也拉下来了,并且你确定要一起编译,就加上kimera_semantics。但注意编译Semantics需要额外的推理依赖,容易失败,建议第一次先跳过。
为什么用catkin build而不是catkin_make?Kimera的多个包之间存在依赖关系,catkin_make在并行编译时经常搞错依赖顺序,导致头文件找不到。catkin build会先解析依赖拓扑,按依赖顺序编译,而且支持增量编译,修改某个包后重新编译速度很快。
编译过程中如果卡住,注意看终端最后输出的错误信息。最常见的错误就是找不到GTSAM头文件,原因是GTSAM没有正确安装到/usr/local,或者是cmake缓存里没有刷新。这时重新执行一下cmake或者在catkin build前面加一个--no-deps参数,先编译依赖包再编译整个工程。
3.4 环境变量与动态库链接检查
编译完成后,配置一下环境:
echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc source ~/.bashrc然后检查GTSAM是否能被正常调用:
ldconfig -p | grep gtsam如果输出里没有libgtsam.so,说明动态库路径没生效。执行:
sudo ldconfig再试一次。如果还是没有,就手动把/usr/local/lib加入/etc/ld.so.conf.d下的配置文件里,重新ldconfig。这一步不搞定,后面运行demo时会直接报error while loading shared libraries,非常影响心情。
4. Demo测试与可视化分析
4.1 准备EuRoC数据集
Kimera官方demo推荐使用EuRoC数据集,它是一个双目加IMU的无人机数据集,采集自室内和室外环境,包含丰富的视觉纹理和运动激励,非常适合验证VIO系统。下载时不需要全下,只需要其中一条序列,比如MH_01_easy。数据集是rosbag格式,下载完直接回放就能被Kimera订阅。
数据集文件比较大,通常几个GB,下载时间取决于网络。下完之后放到一个固定目录,比如~/datasets/下面。记住bag文件的完整路径,后面启动demo要用。
4.2 启动roscore与launch文件
打开第一个终端,启动核心:
source ~/.bashrc roscore打开第二个终端,启动Kimera VIO节点:
source ~/catkin_ws/devel/setup.bash roslaunch kimera_vio_ros kimera_vio_ros_euroc.launch这个launch文件会加载EuRoC相机的内参、外参、IMU噪声参数以及VIO参数。正常启动后,终端会输出Successfully launched node之类的信息,同时开始等待图像和IMU数据。
打开第三个终端,回放数据集:
rosbag play ~/datasets/MH_01_easy.bag回放一开始,VIO节点就会开始输出里程计数据。如果想顺便看网格重建,还需要再启动Mesher节点:
roslaunch kimera_mesher_ros kimera_mesher_euroc.launch注意Mesher节点需要和VIO节点同时运行才能接收到网格生成所需的关键帧信息。如果先把bag放完再启动Mesher,就什么都收不到了。
4.3 在Rviz中查看位姿和三维地图
打开第四个终端,启动Rviz:
rviz在Rviz中添加以下显示项:
rviz/PoseArray,话题选择/kimera_vio_ros/odometry或/kimera_vio_ros/pose_array,可以看到相机轨迹;rviz/Grid,固定坐标系设为world;rviz/Path,订阅odometry消息,查看连续轨迹;- 如果Mesher已启动,添加
rviz/MarkerArray或rviz/PointCloud2用于显示生成的网格。
跑通之后你会在Rviz里看到一条逐渐延伸的轨迹,以及周围环境的稀疏或者三维网格。EuRoC MH_01这条序列场景不大,跑完差不多一两分钟就能看到全貌。
如果你发现图像和IMU数据一直在回放,但轨迹没有任何输出,先检查话题名称是否匹配。用rostopic list查看当前活跃话题,看有没有/kimera_vio_ros/odometry。没有的话检查launch文件里的输入话题和bag里的话题是否一致。
4.4 只跑VIO与完整SLAM的性能差异
Kimera系统最灵活的地方在于模块可裁剪。只跑VIO时,处理一帧图像大概需要20到40毫秒,基本上能跟上30fps的数据流。加上Mesher之后,CPU占用会明显上升,因为三角网格化和纹理融合比较耗时。再加上Semantics,如果机器没有GPU加速,很难实时。
所以如果只是验证定位精度,建议先关闭Mesher和Semantics。关闭方法很简单,在launch文件中把对应节点的enabled参数改成false,或者干脆不启动那个节点。等需要出图或者做语义建图时再打开。
5. 常见问题与排查实战
5.1 编译阶段典型报错及处理
我把实际编译过程中最容易遇到的几个问题整理成了下面这个速查表,方便你定位。
| 报错信息 | 可能原因 | 解决方案 |
|---|---|---|
fatal error: gtsam/base/Matrix.h: No such file | GTSAM未安装或未安装到系统路径 | 重新编译GTSAM并sudo make install,执行sudo ldconfig |
Could NOT find Cholmod | 缺少suitesparse | sudo apt install libsuitesparse-dev |
Could NOT find Eigen3 | Eigen未安装或cmake缓存问题 | sudo apt install libeigen3-dev;如果之前编译过,清空build目录重来 |
g++: internal compiler error: Killed | 内存不足,编译进程被杀 | 降低make -j线程数,或增加swap空间 |
OpenCV_DIR-NOTFOUND | OpenCV环境变量指向错误版本 | echo $OpenCV_DIR检查,必要时unset OpenCV_DIR后重新编译 |
Could NOT find GTSAM (missing: GTSAM_UNSTABLE_BUILD) | GTSAM编译时未开启unstable模块 | 重新编译GTSAM,加-DGTSAM_BUILD_UNSTABLE=ON |
其中内存不足是最难从报错日志里一眼辨认的问题,它经常表现为“编译器被杀”或者“进程退出码137”。如果你用的是老机器,建议编译之前先配置swap空间,至少留出8G的交换分区,能够大幅降低被杀的概率。
5.2 运行阶段常见问题
运行demo时最常遇到的问题有几个,我这里按出现频率排序。
第一个是bag跑完了但Rviz里没有轨迹。这个十有八九是VIO没有完成初始化。EuRoC数据集的初始几秒如果相机运动太平稳,VIO会长时间停留在初始化状态,后面再怎么运动都起不来。解决办法是在回放bag之前,先在Rviz里查看一下IMU话题,确认IMU数据已经稳定输出;另外,rosbag play默认是持续播放的,如果数据流已经因为某些原因暂停,也会导致初始化失败,可以加上--loop参数让bag循环播放。
第二个是轨迹漂移剧烈,几秒钟后就飞出天际。这通常是IMU和相机之间的外参配置不对,或者是相机内参加载错误。检查launch文件里加载的yaml文件,确认实际图像分辨率和VIO配置参数一致。
第三个是网格重建非常慢,Rviz刷新卡顿。这是正常的,Mesher模块本身计算量就大。如果电脑配置一般,可以把bag的播放速度降下来,比如用rosbag play -r 0.5来播放,让Mesher有更充裕的时间处理。
5.3 可视化阶段常见问题
在Rviz中看不到网格时,先检查固定坐标系是不是world,很多人在默认的map坐标系下看不到任何东西。其次检查Mesher节点输出的topic名称,用rostopic list | grep mesh看一看。如果topic存在但仍然没显示,可能是MarkerArray的消息类型没有选择正确的显示插件。
另外一个经典问题:Rviz里轨迹显示正常,但网格模型位置和轨迹对不上。这种情况一般是因为Mesher节点和VIO节点使用了不同的坐标系定义,或者是在T265这种自带IMU的设备上出现了内外参微偏移。在EuRoC数据集上,官方参数已经验证过,基本不会出现这个问题;如果你换用自己的传感器数据,需要重点检查T_body_imu和T_cam0_body这些外参矩阵是否准确。
最后提醒一句,Kimera-VIO在Rviz里的显示默认可能会屏蔽部分消息,导致看起来像没有数据。你可以在Rviz左上角的“Add”面板里检查所有已添加的Display是否处于勾选状态,有些消息因为命名重复会自动隐藏。
6. 写在最后:几条个人顺手经验
从零开始把Kimera在Ubuntu 18.04上跑通,我前后折腾了三个晚上,大部分时间都花在GTSAM编译和依赖版本对齐上。现在回头看,有几个习惯确实帮了大忙。
第一,编译大型工程前先做好最小化验证。不要一上来就全量编译所有模块,先把VIO跑通,再加Mesher,最后再碰Semantics。这样每一步出问题都知道是哪个模块的事,不会一锅粥。
第二,学会看日志而不是只看报错末尾。有时候catkin build输出几百行,真正有用的错误信息在最前面或者藏在CMakeError.log里。遇到找不到头文件的错误,先确认这个头文件到底有没有安装,再确认cmake是否找到了它,最后确认是不是缓存问题。
第三,swap空间一定要配够。我至今记得第一次编译GTSAM时眼睁睁看着内存从4G涨到8G,然后系统卡死,最后只能强制重启。提前配好swap,省下的不只是时间,还有重新编译的耐心。
第四,跑demo之前确认好三个东西:bag文件路径没错、话题名匹配、launch文件里的相机参数对应的是EuRoC还是你自己的传感器。一次跑通的人,基本都是提前做好了这三件事的检查,而不是运气好。
Kimera这套系统后续可以做很多扩展。比如给它换自己采集的数据集,验证不同场景下的定位鲁棒性;把Mesher模块的输出接到导航栈里,用语义地图辅助路径规划;或者把Kimera-VIO和VINS-Fusion做对比实验,分析两者在快速运动场景下的性能差异。基础跑通之后,你会发现它值得折腾的地方比想象中多得多。