VINS-Fusion-gpu 在 Xavier NX 无人机上的部署教程
在 NVIDIA Jetson Xavier NX 上部署 VINS-Fusion-gpu,通过 GPU 并行加速,有效弥补 CPU 性能限制,提升视觉惯性定位算法的实时性与稳定性。
目前市面上许多教育版无人机的机载计算平台采用 NVIDIA Jetson Xavier NX。然而,NX 的 CPU 性能相对有限,在运行 VINS 算法时常出现 CPU 占用率过高甚至系统死机的情况。幸运的是,英伟达的开发板在 GPU 性能方面表现出色,因此可以通过部署 VINS-Fusion 的 GPU 加速版本,显著提升算法的运行速度与系统稳定性。
参考文档
本次共参考了3个CSDN上的教程,已有的教程不够完整,但是又能形成互补,所以本贴综合已有的教程,形成一个完善的教程。
1. NVIDIA Jetson Xavier NX开发板部署VINS-fusion-GPU
(作者:阿栋阿栋。主要参考这篇教程,步骤最清晰,但是缺少验证是否安装成功的步骤)
2. jeston xavier nx跑通vins-fusion GPU定位的ego_planner
(作者:什么时候能造钢铁侠啊。步骤有点多,细节不够具体)
3. Jetson Orin NX 开发指南(6): VINS-Fusion-gpu 的编译和运行
(作者:想要个小姑娘。是Orin NX与ubuntu20.04的教程,有些版本与18.04的不一样)
一、前提条件
开发板为NVIDIA Jetson Xavier NX,系统为ubuntu18.04,相机为realsense D435i。已经安装好了ROS、CUDA。
二、安装opencv GPU版本
关于 OpenCV 的安装需要特别谨慎,不建议频繁删除以前的库,因为多个项目使用的版本可能不同。建议做法:
-
将常用的稳定版本安装在
/usr/local下; -
将实验性或特定项目使用的版本安装在用户目录(如
~/opencv-3.4.1)下,避免文件冲突。
我的 NX 开发板已经在 /usr/local 下安装了 OpenCV 3.3 版本。这次安装的 OpenCV 3.4 版本将安装在 home 目录下,以免不同版本文件起冲突。
(1)安装依赖(整理成一行的命令如下,可直接复制使用)
sudo apt-get install -y cmake libavcodec-dev libavformat-dev libavutil-dev libglew-dev libgtk2.0-dev libgtk-3-dev libjpeg-dev libpng-dev libpostproc-dev libswscale-dev libtbb-dev libtiff5-dev libv4l-dev libxvidcore-dev libx264-dev qt5-default zlib1g-dev libgl1 libglvnd-dev pkg-config libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev mesa-utils
(2)下载opencv源码
由于开发板通常无法直接访问 GitHub,建议先在笔记本电脑上下载压缩包,然后使用 scp 命令传输至开发板。
- 下载 OpenCV 3.4.1 源码包
- 使用 scp 命令传输到 NX 开发板(示例如下):
# scp .\压缩包名字 机载电脑的用户名@机载电脑的IP地址:机载电脑的某个目录
scp .\opencv-3.4.1.zip nvidia@172.31.6.110:~
传输完成后,在开发板的 home 目录中解压该压缩包,得到 opencv-3.4.1 文件夹。
(3)编译GPU版本的opencv
假设源码路径为 /home/nvidia/opencv-3.4.1,编译步骤如下:
cd ~/opencv-3.4.1
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \ # 设置安装路径。这里可任意,因为不执行 make install。
-D WITH_CUDA=ON \
-D CUDA_ARCH_BIN=7.2 \ # NX/AGX 选 7.2,Nano/TX2 选 6.2
-D CUDA_ARCH_PTX="" \
-D ENABLE_FAST_MATH=ON \
-D CUDA_FAST_MATH=ON \
-D WITH_CUBLAS=ON \
-D WITH_LIBV4L=ON \
-D WITH_GSTREAMER=ON \
-D WITH_GSTREAMER_0_10=OFF \
-D WITH_QT=ON \
-D WITH_OPENGL=ON \
-D CUDA_NVCC_FLAGS="--expt-relaxed-constexpr" \
-D WITH_TBB=ON \
../
make -j$(nproc)
注意:
- 粘贴 cmake 命令时,请去掉行尾的 \ 符号,或直接将命令写为一行执行。
- 若板载资源有限,可去掉 -j$(nproc) 改为 make,以减少内存占用。
- 之所以安装的是 GPU 版 OpenCV,关键在于 cmake 阶段设置了 WITH_CUDA=ON,并且系统存在 CUDA 工具链。
(4)常见编译错误及解决方案
错误信息:
error Please include the appropriate gl headers before including cuda_gl_interop.h
解决措施: 编辑文件 /usr/local/cuda/include/cuda_gl_interop.h,修改第 62~68 行为以下内容:
sudo vim /usr/local/cuda/include/cuda_gl_interop.h
修改后:
//#if defined(__arm__) || defined(__aarch64__)
//#ifndef GL_VERSION
//#error Please include the appropriate gl headers before including cuda_gl_interop.h
//#endif
//#else
#include <GL/gl.h>
//#endif
保存退出后重新执行 make。
(5)验证 OpenCV 的GPU版本是否编译成功
进入 build 目录后执行:
cd ~/opencv-3.4.1/build
bin/opencv_version --verbose
如果输出中包含类似以下内容:
Use Cuda: YES (ver 11.4)
CUDA Device: NVIDIA Xavier (Arch 7.2)
则说明 OpenCV 已成功编译并启用了 CUDA 支持。
三、安装对应的CV-Bridge
cv_bridge 是 ROS 中连接 ROS 图像消息 (sensor_msgs/Image) 和 OpenCV 图像格式 (cv::Mat) 的桥梁。
如果你的 OpenCV 是自己编译的 GPU 版本,那么系统自带的 cv_bridge 很可能是针对旧版或 CPU 版编译的,会导致版本冲突或找不到头文件,因此需要重新编译一份对应版本的 cv_bridge。
(1)下载源码
进入 vision_opencv 官方仓库,选择与自己 ROS 版本对应的分支。例如:
- ROS Melodic → 选择 melodic 分支
- ROS Noetic → 选择 noetic 分支
由于本教程使用 Ubuntu 18.04 + ROS Melodic,因此选择 melodic 分支。
你可以直接在电脑端下载该分支的 ZIP 压缩包,或使用命令行:
git clone -b melodic https://github.com/ros-perception/vision_opencv.git
如果开发板无法连接 GitHub,可以先在笔记本上下载压缩包,然后使用 scp 命令传输到机载电脑:
scp ./vision_opencv-melodic.zip nvidia@172.31.6.110:~
传输后解压为 vision_opencv 文件夹:
unzip vision_opencv-melodic.zip
mv vision_opencv-melodic vision_opencv
(2)修改为自己刚刚安装的opencv路径
由于系统内可能有多个版本的 OpenCV,需要手动指定刚刚编译好的 GPU 版本路径。
编辑 cv_bridge 功能包的 CMakeLists.txt 文件:
gedit vision_opencv/cv_bridge/CMakeLists.txt
在 find_package(OpenCV 3 REQUIRED) 之前,添加以下一行:
set(OpenCV_DIR "/home/nvidia/opencv-3.4.1/build")
注意事项:
-
路径要与你前面编译的 OpenCV 实际位置一致;
-
不要遗漏
/build目录,否则会找不到OpenCVConfig.cmake文件。
(3)编译源码
进入 cv_bridge 目录并执行编译:
cd vision_opencv/cv_bridge
mkdir build
cd build
cmake ..
make -j$(nproc)
sudo make install
(4)验证是否安装成功
输入
rospack find cv_bridge
得到
/opt/ros/melodic/share/cv_bridge
四、编译安装Vin-fusion GPU
(1)下载源码
新建一个工作空间,例如vins_gpu_ws,进入工作空间并获取 GPU 版本的 VINS-Fusion 源码:
cd ~/vins_gpu_ws/src
git clone https://github.com/pjrambo/VINS-Fusion-gpu
如果开发板网络不稳定,也可以在本地电脑上下载后用 scp 传输到板子上,方式与之前安装 OpenCV 时相同。
(2)修改CMakeLists.txt—— 指定 GPU 版 OpenCV 与自编译 CV-Bridge
由于 ROS 默认会链接系统版本的 OpenCV 和 cv_bridge,而我们前面已经编译了新的 GPU 版 OpenCV 和自定义 cv_bridge,因此需要在相关模块的 CMakeLists.txt 中显式指定路径。
分别修改以下三个文件:
1、第一处,修改camera_models的CMakeLists文件,改一行:
gedit VINS-Fusion-gpu/camera_models/CMakeLists.txt
在最前面添加:
set(OpenCV_DIR "/home/nvidia/opencv/opencv-3.4.1/build")
如图所示
2、第二处,修改loop_fusion的CMakeLists文件,改三行:
gedit VINS-Fusion-gpu/loop_fusion/CMakeLists.txt
在最前面添加:
set(OpenCV_DIR "/home/nvidia/opencv/opencv-3.4.1/build")
set(cv_bridge_DIR /usr/local/share/cv_bridge/cmake)
并且把原工程的opencv路径改成自己的,原github工程写的路径是include(/home/dji/opencv/build/OpenCVConfig.cmake),如图所示:
3、第三处,修改vins_estimator的CMakeLists文件,改三行:
gedit VINS-Fusion-gpu/vins_estimator/CMakeLists.txt
在最前面添加:
set(OpenCV_DIR "/home/nvidia/opencv/opencv-3.4.1/build")
set(cv_bridge_DIR /usr/local/share/cv_bridge/cmake)
并且把原工程的opencv路径改成自己的,原github工程写的路径是include(/home/dji/opencv/build/OpenCVConfig.cmake),如图所示:
提示:
这样做的意义是让编译系统始终使用你手动编译的 GPU 版 OpenCV 和自定义 cv_bridge。
(3)编译源码
进入工作空间并开始编译:
cd ~/vins_gpu_ws
# 由于其他库会依赖camera_models,所以用catkin build编译得先单独编译该模块
catkin build camera_models
catkin build
(4)可能遇到的报错及解决方案
报错:
double free or corruption (out)
问题原因:
经调试发现,该问题通常出现在使用 cv::FileStorage fsSettings 读取 YAML 文件中矩阵类型数据时。
这往往是因为系统中混用了不同版本的 OpenCV(例如部分模块仍然调用系统旧版库),导致内存分配不一致。
解决措施:
修改VINS-Fusion/vins_estimator/src/estimator/parameters.cpp文件,该文件里面会使用fsSettings["body_T_cam0"]和fsSettings["body_T_cam1"]从yaml文件读取数值,赋值给变量,这里会出现问题,因此都修改为手动输入矩阵参数。
需要修改143行和178行,143行修改前:
143行修改后:
178行修改前:
178行修改后:
注意: 总而言之,手动输入矩阵数据,替代从 YAML 文件读取。这两个矩阵是相机的外参,在realsense_stereo_imu_config.yaml中有写,假如没有的话,先看第五章的(1)配置 D435i相机文件。例如,以下是我的相机外参数据:

五、验证是否安装成功
(1)配置 D435i相机文件
创建/home/nvidia/vins_gpu_ws/src/VINS-Fusion-gpu/config/realsense_d435i/文件夹,用于存储三个yaml文件。
这三个yaml文件来源于VINS-Fuison,可以直接从本地直接复制过来。

如果本地没有VINS-Fusion文件夹,可以去 VINS-Fusion 的 github 网站上查看对应 realsense d435i 的配置文件。VINS-Fusion官方仓库
回到我们的vins_gpu_ws工作空间,粘贴上述三个文件之后,需要有一点改动。
- 其中 left.yaml 和right.yaml 文件配置相对于 VINS-Fuison 未做修改。
- 在realsense_stereo_imu_config.yaml 文件中添加两行:
use_gpu: 1
use_gpu_acc_flow: 1

当然,其他相机的配置文件设置和上面的内容是一致的,因为这是 VINS-Fuion 源码中需要读取的参数的内容和格式,为了达到更高的精度,往往需要对相机进行标定,标定完成后修改配置文件中的内外参和时延,从而提高估计精度,标定的方法可以参考
d435i 相机和imu标定_d435i imu标定_想要个小姑娘的博客-CSDN博客
当然,在此标定可以在后面熟悉 VINS-Fusion 的使用之后在进行,由于我们这里只是介绍如何使用 VINS-Fusion-gpu 测试真实数据,因此标定可以不进行(也不推荐现在进行,很费时间)。
(2)通过 launch 文件运行 realsense 相机
首先必须安装 librealsense 和 realsense-ros,已经安装的可以忽略。参考以下两篇文章(分别针对 Ubuntu 系统和 Jetson 系列的系统)
1. Ubuntu 20.04 配置 realsense_ubuntu安装realsense2-CSDN博客
2. Jetson Orin NX 开发指南(4): 安装 CUDA 和 Realsense_想要个小姑娘的博客-CSDN博客
安装完成后确保能够正常使用 ROS 启动 realsense 相机,并能够正确读取到相机数据和 IMU 数据,配置方式同样参考上面两篇文章。
接下来在 ~/vins_gpu_ws/src/vins-fusion-gpu/src/VINS-Fusion-gpu/vins_estimator/launch/ 路径下创建一个 launch 文件
cd ~/vins_gpu_ws/src/vins-fusion-gpu/src/VINS-Fusion-gpu/vins_estimator/launch/
touch realsense_d435i.launch
在 launch 文件中输入以下内容
<launch>
<node name="vins_estimator" pkg="vins" type="vins_node" output="screen" args="$(find vins)/../config/realsense_d435i/realsense_stereo_imu_config.yaml" />
<node name="loop_fusion" pkg="loop_fusion" type="loop_fusion_node" output="screen" args="$(find vins)/../config/realsense_d435i/realsense_stereo_imu_config.yaml" />
</launch>
这样 launch 文件就配置完成了。
接下来创建三个终端,并 source 一下vins_gpu_ws工作空间(或者在~/.bashrc文件中激活,就不用每次都source了)
第一个终端输入
roslaunch vins vins_rviz.launch
第二个终端输入
roslaunch vins realsense_d435i.launch
第三个终端输入
roslaunch realsense2_camera rs_camera.launch
拿着无人机绕场第一圈,查看rviz轨迹:
最后使用jtop命令检查,是否真的启用了GPU资源。
可以看到正在占用 GPU 资源,也就是说 VINS-Fusion-gpu 成功运行了。
此外,需要注意 VINS-Fusion-gpu 的特征追踪图片的显示方式与 VINS-Fusion 有所不同,VINS-Fusion-gpu 是将特征追踪图像单独显示出来的,而在 VINS-Fusion 中,特征追踪图像是集成在 rviz 中显示的,如果需要将特征追踪的图像显示在 rviz 中,可以参考下文:
Ubuntu 20.04 配置 VINS-Fusion-gpu + OpenCV 4.6.0-CSDN博客
至此,VINS-Fusion-gpu 的配置工作完成了。
更多推荐
所有评论(0)