1. 环境准备与前置检查

嘿,朋友们,今天咱们来聊聊怎么在Ubuntu 20.04上,用Intel的D435i深度相机,把VINS-Fusion这个强大的视觉惯性SLAM系统给跑起来。我自己在机器人项目里折腾这套组合已经有一阵子了,从最初的磕磕绊绊到现在的稳定运行,踩过的坑不少,也总结了不少经验。这篇文章就是想把整个部署过程掰开揉碎了讲清楚,让你能避开我走过的弯路,快速上手。无论你是做移动机器人、无人机,还是对视觉定位感兴趣的学生和开发者,这篇指南都希望能帮到你。

首先,咱们得把“地基”打好。我强烈建议你在开始之前,先确认好三件事,这能帮你节省大量后期排查问题的时间。第一,你的Ubuntu 20.04系统最好是全新安装的,或者至少是一个比较干净的状态。如果你之前装过各种乱七八糟的ROS包或者驱动,版本冲突起来会让你头疼欲裂。第二,ROS Noetic的桌面完整版必须已经安装好。别用ROS2,VINS-Fusion目前对ROS1的支持最成熟。安装ROS Noetic的教程网上很多,官方Wiki的步骤跟着走就行,记得在安装完成后执行 source /opt/ros/noetic/setup.bash 并把它加到你的 ~/.bashrc 文件里。第三,确保你的网络环境通畅,因为我们需要从Github克隆代码,以及下载一些依赖库。如果下载速度慢,可以考虑配置一下国内的一些镜像源,比如中科大的ROS镜像和Ubuntu软件源,这能极大提升安装效率。

接下来是硬件连接。D435i这个相机挺有意思,它集成了双目红外摄像头和一个IMU(惯性测量单元),这正是VINS-Fusion这类视觉惯性里程计最需要的传感器配置。连接时有个关键点:务必使用USB 3.0接口。你可以通过线缆上的“SS”(SuperSpeed)标志或者接口本身的蓝色塑料舌片来识别。如果误用了USB 2.0接口,相机的数据传输带宽会严重不足,导致图像帧率极低甚至无法启动,在 realsense-viewer 里你会看到左上角显示“USB2”而不是“USB3.2”,那样的话后续的SLAM根本没法跑。我一开始就犯过这个错误,盯着卡成PPT的图像琢磨了半天才发现是接口问题。把相机插上后,你可以先不忙装驱动,用 lsusb 命令看看系统是否识别到了Intel的设备。

2. 安装Ceres Solver与VINS-Fusion源码

万事开头难,安装VINS-Fusion的第一步是搞定它的核心依赖——Ceres Solver。这是一个由Google开发的开源C++库,专门用于求解大规模的非线性最小二乘问题,而SLAM中的位姿优化、Bundle Adjustment正是这类问题。VINS-Fusion的后端优化严重依赖它,所以我们必须先把它装好。

安装Ceres我推荐从源码编译,虽然步骤多一点,但能确保版本兼容性和性能。首先,我们把必要的依赖库一次性装上。打开终端,逐条执行下面的命令。这些包包括编译工具、数学库和线性代数库,是Ceres的基石。

sudo apt-get update
sudo apt-get install -y cmake
sudo apt-get install -y libgoogle-glog-dev libgflags-dev
sudo apt-get install -y libatlas-base-dev
sudo apt-get install -y libeigen3-dev
sudo apt-get install -y libsuitesparse-dev

依赖装好后,去Ceres Solver的官网或者它的Github发布页面,下载一个稳定版本的源码包,比如 ceres-solver-2.1.0.tar.gz。我习惯把它下载到主目录(~/)下进行操作。接着,我们解压、编译并安装它。

cd ~
tar zxf ceres-solver-2.1.0.tar.gz
mkdir ceres-build
cd ceres-build
cmake ../ceres-solver-2.1.0
make -j4  # 这里的4取决于你CPU的核心数,可以加快编译速度
sudo make install

编译安装完成后,最好验证一下。进入Ceres自带的例子目录,运行一个简单的测试程序。如果终端打印出一长串优化迭代过程,最后显示“CONVERGENCE”,那就说明Ceres安装成功了。这个过程可能会花上十几二十分钟,取决于你的电脑性能,泡杯茶等着就好。

Ceres搞定后,我们就可以请出今天的主角——VINS-Fusion了。首先,为它创建一个独立的工作空间是个好习惯,这样便于管理,也避免污染系统环境。

mkdir -p ~/vinsfusion_ws/src
cd ~/vinsfusion_ws/src
git clone https://github.com/HKUST-Aerial-Robotics/VINS-Fusion.git

代码克隆下来后,有一个至关重要的步骤:因为VINS-Fusion源码默认是为较老的C++11标准编写的,而Ubuntu 20.04的默认编译器对C++14支持更好,我们需要修改几处代码来适配。这是我踩过的一个大坑,如果不改,编译会报一堆奇怪的错误。你需要修改几个 CMakeLists.txt 文件,把里面的 -std=c++11 改成 -std=c++14。主要涉及以下几个目录下的该文件:camera_models/, global_fusion/, loop_fusion/, vins_estimator/。用文本编辑器打开它们,找到 set(CMAKE_CXX_FLAGS "-std=c++11") 这一行,改成 set(CMAKE_CXX_FLAGS "-std=c++14") 即可。

此外,由于OpenCV版本的变化,一些旧的头文件或常量名已经废弃。你还需要在几个源文件里添加OpenCV的C语言接口头文件。具体来说,在 camera_model/include/chessboard/Chessboard.h 文件顶部添加两行:

#include <opencv2/imgproc/types_c.h>
#include <opencv2/calib3d/calib3d_c.h>

同样的,在 camera_models/include/calib/CameraCalibration.h、loop_fusion/src/pose_graph.h、vins_estimator/src/featureTracker/feature_tracker.h 以及 loop_fusion/src/ThirdParty/DVision/BRIEF.h 这几个文件里,也需要添加:

#include <opencv2/imgproc/types_c.h>
#include <opencv2/imgproc/imgproc_c.h>

最后,找到 vins_estimator/src/KITTIGPSTest.cpp 和 vins_estimator/src/KITTIOdomTest.cpp 这两个文件,将其中的 CV_LOAD_IMAGE_GRAYSCALE 替换为 cv::IMREAD_GRAYSCALE。这些修改都是为了兼容新版本的OpenCV,确保代码能顺利编译。

所有修改完成后,就可以编译整个VINS-Fusion工作空间了。

cd ~/vinsfusion_ws
catkin_make

编译过程会比较长,耐心等待。完成后,别忘了把工作空间的设置脚本添加到你的bash配置中,这样每次打开新终端都能自动找到这些ROS包。

echo "source ~/vinsfusion_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc

3. 配置Intel RealSense D435i驱动与ROS包

现在轮到我们的传感器了。要让Ubuntu和ROS认识D435i,需要安装两套东西:一是Intel官方的SDK(librealsense2),它提供了底层的驱动和查看工具;二是ROS的封装包(realsense-ros),它负责把相机的数据转换成ROS的话题(Topic)发布出来,这样VINS-Fusion才能订阅到。

首先安装官方SDK。Intel提供了APT仓库,安装起来非常方便。依次执行以下命令来添加仓库并安装核心包:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE || sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE
sudo add-apt-repository "deb https://librealsense.intel.com/Debian/apt-repo $(lsb_release -cs) main" -u
sudo apt-get update
sudo apt-get install librealsense2-dkms librealsense2-utils librealsense2-dev librealsense2-dbg

这里 librealsense2-dkms 是内核模块,librealsense2-utils 包含了 realsense-viewer 这个图形化工具,librealsense2-dev 是开发头文件,librealsense2-dbg 是调试符号。安装完成后,插上相机,运行 realsense-viewer。如果一切正常,你会看到一个图形界面,里面显示了相机的深度流、彩色流、红外流以及IMU数据。请务必确认界面左上角显示的是“USB3.2”或类似字样,如果显示“USB2”,请检查你的线缆和接口。

接下来安装ROS包。我们为它单独创建一个工作空间,避免和VINS-Fusion的编译环境冲突。

mkdir -p ~/realsense_ws/src
cd ~/realsense_ws/src
git clone https://github.com/IntelRealSense/realsense-ros.git
cd realsense-ros
# 切换到ROS Noetic对应的legacy分支
git checkout `git tag | sort -V | grep -P "^2.\d+\.\d+" | tail -1`
cd ~/realsense_ws

在编译之前,需要安装一个ROS依赖包 ddynamic_reconfigure:

sudo apt-get install ros-noetic-ddynamic-reconfigure

然后开始编译。这里我建议先清理一下再编译,并使用Release模式以获得更好性能:

catkin_make clean
catkin_make -DCATKIN_ENABLE_TESTING=False -DCMAKE_BUILD_TYPE=Release
catkin_make install
echo "source ~/realsense_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc

安装完成后,我们来测试一下ROS驱动是否工作。打开一个终端,启动相机节点:

roslaunch realsense2_camera rs_camera.launch

如果启动成功,不会有报错,并且会开始输出一些日志信息。再打开另一个终端,输入 rostopic list,你应该能看到一串以 /camera 开头的话题列表,比如 /camera/color/image_raw, /camera/infra1/image_rect_raw, /camera/imu 等。这证明相机数据已经成功发布到ROS系统中了。你还可以用 rqt_image_view 工具来查看实时图像,或者用 roslaunch realsense2_camera demo_pointcloud.launch 来查看点云,这些都是验证驱动是否正常工作的好方法。

4. 为VINS-Fusion定制相机启动与配置文件

到了最关键的一步:把D435i和VINS-Fusion连接起来。VINS-Fusion需要订阅特定话题名的图像和IMU数据,并且对图像分辨率、帧率以及IMU的频率有要求。我们需要修改RealSense的启动文件,并创建VINS-Fusion的配置文件。

首先,我们创建一个专为VINS-Fusion优化的启动文件。进入 realsense-ros 包的launch目录,复制一份 rs_camera.launch 并重命名,比如叫 rs_camera_vins.launch。然后我们需要修改其中的一些参数。核心改动如下:

  1. 启用双目红外摄像头:VINS-Fusion的默认配置使用双目灰度图像,所以我们需要启用 infra1 和 infra2,并关闭彩色流(enable_color: false)以节省带宽。但有时为了调试方便,也可以保留彩色流。
  2. 设置分辨率与帧率:将 infra_width, infra_height 设为 640x480,infra_fps 设为 30。这个分辨率在精度和计算负担之间是个不错的平衡。
  3. 启用并配置IMU:确保 enable_accel 和 enable_gyro 为 true,并将 accel_fps 和 gyro_fps 分别设为 250 和 200。高频率的IMU数据对VINS-Fusion的预积分至关重要。
  4. 启用同步:将 enable_sync 设为 true,这能确保左右目图像的时间戳严格对齐,避免时间不同步导致的估计误差。
  5. 关闭点云:将 enable_pointcloud 设为 false,因为我们暂时用不到,减少不必要的计算。

你可以直接基于原始文章提供的launch文件内容进行修改。修改好后,将这个文件保存在一个方便的位置,例如 ~/realsense_ws/src/realsense-ros/realsense2_camera/launch/ 目录下。

接下来,配置VINS-Fusion。在VINS-Fusion的源码目录中,config 文件夹下有很多示例配置。我们复制一份双目IMU的配置(例如 euroc_stereo_imu_config.yaml)来修改。我建议在 config 目录下新建一个文件夹,比如叫 realsense_d435i,专门存放我们的配置文件。主要需要修改的参数包括:

  • imu_topic 和 image0/1_topic:确保它们与RealSense节点发布的话题名一致。默认的 rs_camera.launch 发布的话题是 /camera/imu, /camera/infra1/image_rect_raw 和 /camera/infra2/image_rect_raw。
  • output_path:设置一个你希望保存轨迹和地图数据的路径。
  • cam0_calib 和 cam1_calib:指向左右目相机的内参文件。D435i是出厂校准过的,我们可以从相机里读取内参,或者使用一个通用值。更准确的做法是运行RealSense的 camera_info 话题来获取,但为了快速启动,可以先用典型值。你需要创建 left.yaml 和 right.yaml 两个文件,内容格式如下:
%YAML:1.0
model_type: PINHOLE
camera_name: camera
image_width: 640
image_height: 480
distortion_parameters:
   k1: 0.0
   k2: 0.0
   p1: 0.0
   p2: 0.0
projection_parameters:
   fx: 386.03  # 焦距x,单位像素,此为示例值,需替换
   fy: 386.03  # 焦距y
   cx: 321.94  # 光心x
   cy: 237.32  # 光心y

如何获取准确的相机内参? 一个简单的方法是先启动 rs_camera.launch,然后运行 rostopic echo /camera/infra1/camera_info,在打印出的信息里找到 K 矩阵,K[0]和K[4]就是 fx 和 fy,K[2]和K[5]就是 cx 和 cy。把左右目的内参分别填到对应的yaml文件中。外参矩阵 body_T_cam0 和 body_T_cam1 描述了相机和IMU之间的相对位置关系。对于D435i,这个变换是固定的,你可以使用原始文章里提供的矩阵,或者从RealSense的 tf 树中获取近似值。在配置文件中,将 estimate_extrinsic 设为 1,让VINS-Fusion在启动初期在线估计一下外参,这通常能得到更准确的结果。

5. 运行、调试与效果验证

激动人心的时刻到了!我们需要打开四个终端,分别运行不同的节点。请注意,每个终端都需要先 source 对应的ROS工作空间环境。

终端1:启动D435i相机驱动

source ~/realsense_ws/devel/setup.bash
roslaunch realsense2_camera rs_camera_vins.launch

这个终端会输出很多相机初始化、数据流开启的信息。观察是否有红色错误(ERROR)出现。正常情况是持续输出图像帧率和IMU数据的日志。

终端2:启动VINS-Fusion核心估计器

source ~/vinsfusion_ws/devel/setup.bash
rosrun vins vins_node ~/vinsfusion_ws/src/VINS-Fusion/config/realsense_d435i/realsense_stereo_imu_config.yaml

这个节点是SLAM的核心,负责从图像和IMU数据中计算相机的位姿。启动后,它会读取配置文件,初始化特征跟踪器、优化器等。如果配置文件路径或话题名不对,这里会报错,比如提示找不到话题或者无法解析yaml文件。

终端3:启动回环检测节点(可选但推荐)

source ~/vinsfusion_ws/devel/setup.bash
rosrun loop_fusion loop_fusion_node ~/vinsfusion_ws/src/VINS-Fusion/config/realsense_d435i/realsense_stereo_imu_config.yaml

这个节点负责检测回环(即识别之前到过的地方),并进行全局位姿图优化,可以有效地消除累积误差,让地图更闭合。对于长时间运行或者大范围运动,开启它效果提升非常明显。

终端4:启动RVIZ可视化界面

source ~/vinsfusion_ws/devel/setup.bash
roslaunch vins vins_rviz.launch

这会打开一个RVIZ窗口。你需要手动添加一些显示项来观察结果。通常我会添加:

  • Path:话题选择 /vins_estimator/path,这是估计出的相机运动轨迹。
  • PointCloud2:话题选择 /vins_estimator/point_cloud,这是根据特征点重建的稀疏点云地图。
  • Image:话题选择 /vins_estimator/image_track,这是特征跟踪的可视化图像,可以看到绿色的小点(特征点)是如何被跟踪的。

当所有节点都正常运行后,拿起你的D435i相机,缓慢地左右、前后移动。你应该能在RVIZ中看到一个绿色的路径开始延伸,同时点云地图也逐渐构建出来。特征跟踪图像上应该能看到稳定的绿色光点流。如果相机静止不动,轨迹应该基本是一条直线;如果移动,轨迹应该平滑地变化。

常见问题与调试技巧:

  1. 没有轨迹或点云:首先检查RVIZ的话题是否订阅正确,坐标系(通常设为 world 或 vins_world)是否正确。然后回到终端2,查看 vins_node 是否有输出信息,特别是特征跟踪的数量。如果特征点数量为0或极少,可能是图像话题没订阅到,或者相机内参错误导致特征提取失败。
  2. 轨迹漂移严重:这可能是IMU噪声参数 (acc_n, gyr_n 等) 设置不合理。D435i的IMU噪声相对较大,你可以尝试稍微增大配置文件中的 acc_n 和 gyr_n 值(例如分别设为0.1和0.01),让滤波器更信任视觉信息。此外,确保相机运动不要太剧烈,尤其是快速旋转,这容易导致视觉模糊和IMU积分误差增大。
  3. 启动即崩溃:最常见的原因是Ceres Solver或Eigen库的版本冲突,或者之前提到的C++标准修改、OpenCV头文件修改没有做。仔细检查编译时的错误信息,回溯安装步骤。
  4. 图像延迟或卡顿:确认相机连接在USB 3.0端口,并在 rs_camera_vins.launch 中适当降低帧率(如降到15fps)或分辨率试试。

6. 参数调优与实战经验分享

系统能跑起来只是第一步,要想获得稳定、精确的定位和建图效果,参数调优是必不可少的。VINS-Fusion的配置文件里有几十个参数,新手可能会眼花缭乱。我结合自己的经验,挑几个最关键的说一说。

特征跟踪参数 (feature_tracker)

  • max_cnt: 每帧图像提取的最大特征点数。D435i在640x480分辨率下,设置在100-150之间比较合适。太少会导致跟踪不稳定,太多会增加计算量。室内纹理丰富的环境可以设低一点,纹理单一的走廊或白墙可以设高一点。
  • min_dist: 特征点之间的最小像素距离。这个值防止特征点扎堆。一般设为20-30。如果场景特征稀疏,可以适当减小;如果特征密集且容易误匹配,可以增大。
  • show_track: 设为1可以在RVIZ中看到特征跟踪图像,非常有助于直观判断跟踪质量。如果发现特征点瞬间全部丢失或乱跳,说明跟踪出了问题。

优化器参数

  • max_solver_time 和 max_num_iterations: 控制后端优化每次迭代的最大时间和迭代次数。为了保证实时性,max_solver_time 通常设为0.04或0.05(秒),max_num_iterations 设为4-8。如果你的电脑性能很强,可以适当增加以获得更精确的解;如果发现帧率跟不上,可以减小。
  • keyframe_parallax: 关键帧选择的视差阈值(像素)。当当前帧与上一个关键帧之间的平均视差大于这个值时,才会将当前帧设为新的关键帧。这个值影响地图点的数量和优化图的稀疏度。室内小范围运动可以设小一点(如5-10),大范围运动或旋转剧烈时可以设大一点(如15-20)。

IMU参数 这是调优的重点和难点,因为IMU的噪声特性直接影响融合效果。

  • acc_n, gyr_n: 分别是加速度计和陀螺仪的测量噪声标准差。D435i的IMU是消费级MEMS器件,噪声较大。实测下来,acc_n 在0.08到0.12之间,gyr_n 在0.008到0.015之间,是一个比较稳定的范围。你可以从默认值开始微调。
  • acc_w, gyr_w: 是加速度计和陀螺仪零偏的随机游走噪声。这两个参数对长期漂移影响大。通常 acc_w 在0.002左右,gyr_w 在4.0e-5左右。如果发现轨迹的尺度在缓慢变化,可以尝试调整 acc_w。
  • g_norm: 当地重力加速度大小。在中国大部分地区,使用9.805即可。

实战中的小技巧:

  • 预热:启动系统后,让相机在原地静止几秒钟。VINS-Fusion在初始化阶段需要估计重力方向、IMU零偏等,静止有助于得到一个好的初始值。
  • 运动激励:初始化完成后,进行充分的“运动激励”——即让相机在六个自由度上(前后、左右、上下、俯仰、偏航、横滚)都有一定的运动,这能帮助系统更准确地估计出尺度(Scale)和外参。单纯平移运动是无法估计出准确尺度的。
  • 光照与纹理:VINS-Fusion依赖视觉特征,因此要避免在纯色墙面、黑暗或强光直射的环境下使用。适当的光照和丰富的纹理(如书架、办公桌)能显著提升跟踪稳定性。
  • 保存与回放:调试时,你可以用 rosbag record 命令录制相机的话题数据包。一旦出现问题,就可以用 rosbag play 反复回放同一段数据来调试参数,而不用每次都拿着相机跑来跑去。

调参是个需要耐心的过程,没有一套参数能适应所有场景。我的建议是,先保证系统能稳定运行不崩溃,然后在一个固定的、有代表性的场景(比如你的实验室或客厅)里反复测试,每次只调整1-2个参数,观察轨迹漂移、回环闭合精度等指标的变化,逐步找到最适合你设备和场景的那组“黄金参数”。

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐