0、写在前面
GCNv2-SLAM是一个基于深度学习的SLAM系统,SLAM用的是ORBSLAM2,用GCN提取特征点进行特征匹配,可以提升匹配的准确率和稳定性,有利于SLAM精度的提升。
我用的是Jetson Orin NX,烧录的镜像已经自带CUDA、CUDNN等与GPU相关的东西,而这个GCN方案是需要利用GPU的计算资源的,所以需要配置好GPU的一些环境。
另外,模型训练的数据集图片是320x240的分辨率,因此执行命令的时候需要注意使用的模型。
备注:真是历经千难万险...先是1.0.1版本的pytorch版本编译出现很奇怪的问题不通过,后来选择更换pytorch。但是发现官网上下下来的libtorch不适用于arm64架构,因此选择调用板子镜像自带的libtorch。好不容易libtorch能用了,又发现源码训练模型用的是libtorch1.0.1版本的,训来出来的模型在别的版本的libtorch下不适用,会报legacy model format...的问题。本来以为是GCNv2-SLAM的问题,因此又选择编译一下基本相同框架的Superpoint-SLAM,结果还是存在legacy model的问题。所以最终又不得不硬着头皮编译1.0.1版本的pytorch...
这篇博客主要记录了从0到成功运行GCNv2-SLAM的报错以及心路历程...
一、编译Libtorch
首先在github上找到GCNV2-SLAM项目,按照需求准备对应的库,如libtortch(这个是深度学习C++版本的库)、pangolin、g2o、DBoW2、opencv、Eigen3等。我这边Opencv是4.2.0版本,Pangolin是0.5版本。
Opencv4.2.0可能需要修改对应的CMakeLists文件,因为ORB本身用的Opencv版本比较低。
首先创建新的文件夹
mkdir -p GCN-SLAM
cd GCN-SLAM
不要根据官网上的libtorch库安装过程来安装,很有可能与你自己的板子不符合,比如我在编译过程中就出现了如下几个问题,非常难以找到解决措施。
1. 报错说usr/local/cuda/include/cudnn.h文件中没有#define CUDNN_MAJOR(如下图所示),
2. 子进程subprocess的问题
还有很多问题比如函数名称不对等等,如果不是深耕CUDA编程多年一般是解决不了的...
所以我选择从官网上下载libtorch自行编译,并且根据自己GPU的版本来。
首先进入pytorch的官网:
找到这里,根据自己的CUDA版本来选择对应的libtorch。我的CUDA是11.8版本的,我就选择对应的libtorch下载:
下载好了之后解压缩,放到我自己创建的GCN-SLAM文件夹下。根据库安装文档说明:
Installing C++ Distributions of PyTorch — PyTorch main documentation
我们可以在GCN-SLAM文件夹下创建一个example-libtorch,并在里面创建对应的CMakeLists.txt文件和example.cpp文件,两者的具体内容如上述链接所示。注,这里可能需要根据你自己的cmake版本修改CMakeLists开头的最小版本需求,我这里就改成了3.15
然后使用:
mkdir build
cd build
cmake ..
make -j4
对example.cpp文件编译并生成可执行文件。这里会产生报错,如下:
1. 找不到TorchConfig.cmake、torch-config.cmake这两个文件
我们需要在CMakeLists.txt文件中添加路径索引,这里我们可以先使用locate命令定位查找无法索引的文件路径,如下:
sudo updatedb
locate TorchConfig.cmake
第一行命令是更新本地的库文件,否则很有可能在执行第二行命令的时候出现查找不到的清卡ung。
第二行查找出来的结果如下所示:
因此我们可以直接选择第一个,这是我们自己下载的libtorch库里面的TorchConfig.cmake文件。
set(Torch_DIR /home/jetson/GCN-SLAM/libtorch-cxx11-abi-shared-with-deps-2.2.1+cu118/libtorch/share/cmake/Torch)
这样我们cmake就能通过了。
2. 然后再进行make,出现了新的报错:
这个问题一般是库的格式不对。我的Orin板子是arm架构,而下载下来的库可能是x86架构的,因此导致无法编译通过。所以需要更换libtorch库版本。我的jetson orin板子自带的镜像,有已经编译好的对应于arm架构的libtorch库,因此,我们需要将路径更改自自带的libtorch库下才可以。注意,一定要删除已经编译好的build文件夹重新建立新的build,否则会报同样的错误。路径如下:
set(Torch_DIR /usr/local/lib/python3.8/dist-packages/torch/share/cmake/Torch/)
重新cmake和make
mkdir build
cd build
cmake ..
make -j4
执行完这两行命令就成功编译通过啦!
测试用例通过:
二、编译GCNv2-SLAM
首先需要git一下代码,然后在git下来的文件夹内编译
git clone https://github.com/jiexiong2016/GCNv2_SLAM.git
cd GCNv2_SLAM
./build.sh
注意,此时需要我们修改自己对应的opencv版本以及设置libtorch路径,在CMakeLists.txt文件中。
我的opencv是4.2.0版本的。我们需要根据自己的opencv版本来修改存储路径,以及代码内部的api。
libtorch路径修改可以参考上面。
Opencv4.2.0修改:
加上自己的路径并且注释掉原本的代码即可
除了GCNv2-SLAM的CMakeLists之外,还有Thirdparty/DBoW2的CMakeLists.txt需要修改。
set(OpenCV_DIR "/usr/local/opencv420/lib/cmake/opencv4")
find_package(OpenCV 4.2.0 REQUIRED)
libtorch修改:
同样,加上自己libtorch路径即可
set(Torch_DIR /usr/local/lib/python3.8/dist-packages/torch/share/cmake/Torch/)
正常编译,ORB2编译过程中的问题,可以参考我的另一片博客:
Jetson Orin NX + RealSense-d455 + Ubuntu20.04部署orbslam2-CSDN博客
除了上面文章中提到的一些问题,还有如下遇到的一些新问题,这里也做一下记录:
问题:#error C++14 or later compatible compiler is required to use ATen
解决措施:只需要在CMakeLists.txt文件中将C++编译器从C++-11改成C++-14版本的即可:
问题:
原因是librotch1.12版本换了新的api
解决措施:
将
auto img_tensor = torch::CPU(torch::kFloat32).tensorFromBlob(img.data, {1, img_height, img_width, 1});
修改为
auto img_tensor = torch::from_blob(img.data, {1, img_height, img_width, 1}).permute({0, 3, 1, 2}).to(torch::kCUDA);
问题:
原因是等号左右两边的操作符不匹配
解决措施1:
将
module = torch::jit::load(net_fn);
改为
torch::jit::script::Module module = torch::jit::load(net_fn);
解决措施2:
首先在头文件GCNextractor.h中
将
std::shared_ptr<torch::jit::script::Module> module;
改成
torch::jit::script::Module module;
再在GCNextractor.cc中
将
auto output = module->forward(inputs).toTuple();
改为
auto output = module.forward(inputs).toTuple();
问题:opencv版本更新导致函数api不同
具体可以参考这篇博客:opencv3和opencv4的版本切换_opencv4切换到3-CSDN博客
解决措施:在对应的文件夹下添加头文件:
#include <opencv2/imgproc/types_c.h>
编译通过:
三、运行GCNv2-SLAM
我们需要参考run.sh文件,看看如何运行GCN。
run.sh文件中是这样写的:(暂时只能跑rgb-d图像)
因此,首先需要将深度图像和RGB图像关联(可以参考我的orb2那篇博客Jetson Orin NX + RealSense-d455 + Ubuntu20.04部署orbslam2-CSDN博客),我们需要在以下网址上寻找associate.py文件才可以。
Computer Vision Group - Useful tools for the RGB-D benchmark
下载下来后,将文件移动到GCN2文件夹下, 并在该文件夹下调用如下命令运行该文件,将深度图像和RGB图像关联:
python associate.py PATH_TO_SEQUENCE/rgb.txt PATH_TO_SEQUENCE/depth.txt > associations.txt
出现问题报错:
原因:python2和python3的版本差异
解决措施:
要么直接调用python2命令,命令行如下:
python2 associate.py PATH_TO_SEQUENCE/rgb.txt PATH_TO_SEQUENCE/depth.txt > associations.txt
要么修改.py文件。我选择修改.py文件,这样以后更统一一些。
在
for diff, a, b in potential_matches:
if a in first_keys and b in second_keys:
first_keys.remove(a)
second_keys.remove(b)
matches.append((a, b))
前面加上
first_keys = list(first_keys)
second_keys = list(second_keys)
变成
first_keys = list(first_keys)
second_keys = list(second_keys)
for diff, a, b in potential_matches:
if a in first_keys and b in second_keys:
first_keys.remove(a)
second_keys.remove(b)
matches.append((a, b))
生成的associations.py会在你执行命令终端所在的文件夹下。
执行运行的命令,参考run.sh文件:
FULL_RESOLUTION=1 GCN_PATH=gcn2_640x480.pt ./rgbd_gcn ../Vocabulary/GCNvoc.bin TUM3.yaml /home/jetson/ORB_SLAM2/rgbd_dataset_freiburg1_xyz /home/jetson/ORB_SLAM2/rgbd_dataset_freiburg1_xyz/associations.txt
执行后理论上是可以正常运行的,但是由于模型不支持移动端设备,所以暂时没跑出最终结果。跑出来的日志如下:
四、修改编译pytorch1.0.1
查了很多资料,猜测是libtorch版本的问题,准备按照项目给出的1.0.1版本重新编译和调用(md这不是又回到了最开始的问题...)。
这里编译过程中发现是cusparse库版本的问题,我自己的板子上的库是11.4版本,可以直接在文件-计算机里面搜索cusparse就能看到,没办法了...系统自带镜像就这样,cusparse库版本过新,而需要生成的libtorch版本过老,只能自己做适配了。没办法,硬着头皮改吧
问题1:
解决措施:
把相关的#if-#endif注释掉即可(主要我找不到新版本cusparse头文件里这个函数是什么...)
问题2:
error: more than one instance of function "at::native::sparse::cuda::cusparseGetErrorString" matches the argument list
解决措施:
在对应函数cusparseGetErrorString位置添加
#if (!((CUSPARSE_VER_MAJOR >= 10) && (CUSPARSE_VER_MINOR >= 2)))
/*code*/
#endif
问题3:
这个说明显卡的计算能力不够,我们需要修改对CUDA_ARCH的计算性能的定义。
我们在终端输入如下命令:
jtop
并查看自己CUDA ARCH BIN的值,我的是8.7,因此计算性能应该是870,
所以只需要在/home/jetson/GCN-SLAM/pytorch/caffe2/utils/GpuDefs.cuh中,
将
#if __CUDA_ARCH__ <= 750
改成
#if __CUDA_ARCH__ <= X
X是一个大于870的值即可,我的X是900。
问题4:
问题n...
所有的问题都是跟cudnn、cuda、pytorch版本相关...实在是太多了,根本解决不来...
或者选择重新在自己的终端上训练自己的模型即可。
五、总结
jetson Orin NX板子烧好的镜像,带的这些库的版本什么的几乎完全无法与pytorch1.0.1适配,实在是稿不动了...报错太多了,关键还全都找不到解决办法...要不就是需要花很长很长的时间,实在是非常令人头疼...