配置环境
环境要求
ubuntu 18.04
能够运行orb-slam2的库环境。
有git
环境准备
查看gcc和g++的版本:
g++ --version
gcc --version
因为c++17需要gcc-9和g+±9以及以上的版本,如果你不是则执行下列代码来换版本:
#安装gcc-9和g++-9
sudo apt-get update
sudo apt-get install gcc-9 g++-9
#更新默认版本:使用 update-alternatives 命令来更新系统默认的 GCC 和 G++ 版本
首先,添加新的 GCC 和 G++ 版本到 update-alternatives 系统中:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 70
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 90
选择默认版本:通过 update-alternatives 命令来选择默认版本
sudo update-alternatives --config gcc
你会看到类似如下的输出:
There are 2 choices for the alternative gcc (providing /usr/bin/gcc).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/bin/gcc-9 90 auto mode
1 /usr/bin/gcc-7 70 manual mode
2 /usr/bin/gcc-9 90 manual mode
Press <enter> to keep the current choice[*], or type selection number:
选2
--------------------------------------------------------------------------
然后,选择默认的 G++ 版本:
sudo update-alternatives --config g++
然后出现以下:
There are 2 choices for the alternative g++ (providing /usr/bin/g++).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/bin/g++-9 90 auto mode
1 /usr/bin/g++-7 70 manual mode
2 /usr/bin/g++-9 90 manual mode
Press <enter> to keep the current choice[*], or type selection number:
选2
------------------------------------------------------------------------
然后验证一下:
gcc --version
g++ --version
安装libtorch
注:在Libtorch下载时,有两个版本: Pre-cxx11 ABI 和 cxx11- ABI, 需要下载cxx11- ABI,否则会和其他库冲突(pangolin, DBOW)
我们需要根据我们系统的glibc
来安装libtorch
的版本,由于我是在虚拟机里跑的,所以用CPU版本的。
先检查我们安装的glibc
版本:
ldd --version
我的glibc 版本为 2.27 的系统,推荐安装 libtorch 1.6.0 或更早的版本(这里我下载的是1.6.0)
下载libtorch
将下载的解压到一个位置,后面这个位置需要写在CMakeLists.txt和build.sh文件里面
安装代码
mkdir gcnslam
cd gcnslam
git clone https://github.com/jiexiong2016/GCNv2_SLAM.git
拔下来之后先要修改CMakeLists.txt和部分文件,具体修改如下:
文件GCNextractor.h 和GCNextractor.cpp修改如下:
可以直接替换掉文件的内容。
//99行
//原
std::shared_ptr<torch::jit::script::Module> module;
//改为
torch::jit::script::Module module;
//270行
//原
auto output = module->forward(inputs).toTuple();
//改为
auto output = module.forward(inputs).toTuple();
//218改为
torch::DeviceType device_type;
device_type = torch::kCPU;
torch::Device device(device_type);
const char *net_fn = getenv("GCN_PATH");
net_fn = (net_fn == nullptr) ? "gcn2.pt" : net_fn;
module = torch::jit::load(net_fn, device);
//使用全局搜索,将torch::kCUDA替换为torch::kCPU。有两个地方,具体情况可能不一样。我看别的人说只有一个
文件CMakeLists.txt修改如下:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(ORB_SLAM2)
SET(CMAKE_BUILD_TYPE Release)
MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -march=native ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 -march=native")
# Check C++17, C++11, or C++0x support
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX17) # 添加对 C++17 的检查
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX17) # 优先使用 C++17
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
add_definitions(-DCOMPILEDWITHC17)
message(STATUS "Using flag -std=c++17.")
elseif(COMPILER_SUPPORTS_CXX11) # 然后使用 C++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_definitions(-DCOMPILEDWITHC11)
message(STATUS "Using flag -std=c++11.")
elseif(COMPILER_SUPPORTS_CXX0X) # 最后使用 C++0x
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_definitions(-DCOMPILEDWITHC0X)
message(STATUS "Using flag -std=c++0x.")
else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 or C++17 support. Please use a different C++ compiler.")
endif()
LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)
find_package(OpenCV 3.0 QUIET)
if(NOT OpenCV_FOUND)
find_package(OpenCV 2.4.3 QUIET)
if(NOT OpenCV_FOUND)
message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
endif()
endif()
find_package(Eigen3 3.1.0 REQUIRED)
find_package(Pangolin REQUIRED)
set(TORCH_PATH "PATH/libtorch/share/cmake/Torch")##这里填写的是前面解压的路径
if( TORCH_PATH )
message("TORCH_PATH set to: ${TORCH_PATH}")
set(Torch_DIR ${TORCH_PATH})
else()
message(FATAL_ERROR "Need to specify Torch path, e.g., pytorch/torch/share/cmake/Torch ")
endif()
find_package(Torch REQUIRED)
message(STATUS "Torch version is: ${Torch_VERSION}")
if(Torch_VERSION GREATER 1.0.1)
message(STATUS "Torch version is newer than v1.0.1, will use new api")
add_definitions(-DTORCH_NEW_API)
endif()
include_directories(
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/include
${EIGEN3_INCLUDE_DIR}
${Pangolin_INCLUDE_DIRS}
)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
add_library(${PROJECT_NAME} SHARED
src/System.cc
src/Tracking.cc
src/LocalMapping.cc
src/LoopClosing.cc
src/ORBextractor.cc
src/GCNextractor.cc
src/ORBmatcher.cc
src/FrameDrawer.cc
src/Converter.cc
src/MapPoint.cc
src/KeyFrame.cc
src/Map.cc
src/MapDrawer.cc
src/Optimizer.cc
src/PnPsolver.cc
src/Frame.cc
src/KeyFrameDatabase.cc
src/Sim3Solver.cc
src/Initializer.cc
src/Viewer.cc
)
target_link_libraries(${PROJECT_NAME}
${OpenCV_LIBS}
${EIGEN3_LIBS}
${Pangolin_LIBRARIES}
${TORCH_LIBRARIES}
${PROJECT_SOURCE_DIR}/Thirdparty/DBoW2/lib/libDBoW2.so
${PROJECT_SOURCE_DIR}/Thirdparty/g2o/lib/libg2o.so
)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/GCN2)
add_executable(rgbd_gcn GCN2/rgbd_gcn.cc)
target_link_libraries(rgbd_gcn ${PROJECT_NAME} ${TORCH_LIBRARIES})
set_property(TARGET rgbd_gcn PROPERTY CXX_STANDARD 17) # 修改为 C++17 标准
关于gcn2_320x240.pt (其他pt文件同理)
双击打开gcn2_320x240.pt (其他pt文件同理)(无需解压)/gcn/code/'下找到 ‘gcn.py’
这是因为1.3以前默认true 1.3以后默认false,这里我能是1.6,所以也要改
_32 = torch.squeeze(torch.grid_sampler(input, grid, 0, 0))
改为
_32 = torch.squeeze(torch.grid_sampler(input, grid, 0, 0, True))
# 所有的cuda:0替换为cpu
关于文件LoopClosing.c
#:439:21:
KeyFrameAndPose CorrectedSim3, NonCorrectedSim3;进入这个函数的定义里面
将
typedef map<KeyFrame*,g2o::Sim3,std::less<KeyFrame*>,
Eigen::aligned_allocator<std::pair<const KeyFrame*, g2o::Sim3> > > KeyFrameAndPose;
改为:
typedef map<KeyFrame*,g2o::Sim3,std::less<KeyFrame*>,
Eigen::aligned_allocator<std::pair<KeyFrame *const, g2o::Sim3> > > KeyFrameAndPose;
关于rgbd_gcn.cc文件
在文件前面加上:
#define COMPILEDWITHC11
下载数据集
下载地址:Computer Vision Group - Dataset Download
随便选一个,我下载的是fr3/long_office_household,将其解压缩到/home/chan/GCNv2_SLAM/datasets/TUM中(就是自己建个TUN文件夹,这个路径很重要,之后需要用到)
解压后里面包含一个depth.txt和一个rgb.txt两个用来保存filename的文件,代码是通过filename从文件夹里读取的图像。但是在GCN的run.sh启动文件里,启动参数传入的是association.txt,经过翻看了一下ORB的一些传入参数,发现这里传入的association.txt应该是上面rgb.txt与depth.txt合并的结果,所以用一个函数来完成
创建一个associate.py,其内容如下:
def split_line(f_rgbd):
rgbd_split = f_rgbd.read().split()
index_to_delete = []
for i in range(len(rgbd_split)):
if i%2:
index_to_delete.append(i)
count = 0
for index in index_to_delete:
index = index - count
rgbd_split.pop(index)
count += 1
return rgbd_split
def near_time_stamp(rgb_time_stamp, depth_time_stamp):
"""
假设len(rgb_time_stamp) > len(depth_time_stamp)
只需在rgb_time_stamp中取出len(depth_time_stamp)个元素即可
"""
near_rgb_stamp = []
for index in depth_time_stamp:
min_value = 1000000000
min_jndex = ''
depth_float = float(index)
for jndex in rgb_time_stamp:
rgb_float = float(jndex)
if abs(depth_float - rgb_float) < min_value:
min_value = abs(depth_float - rgb_float)
min_jndex = jndex
near_rgb_stamp.append(min_jndex)
return near_rgb_stamp
if __name__ == '__main__':
f_rgb = open("rgb.txt","r")
f_depth = open("depth.txt","r")
f_association = open('associations.txt','w',encoding='utf-8')
data_depth = f_depth.readlines()
f_depth.seek(0,0)
# 切分出时间戳
rgb_time_stamp = split_line(f_rgb)
depth_time_stamp = split_line(f_depth)
# 寻找最近时间戳
rgb_time_stamp = near_time_stamp(rgb_time_stamp, depth_time_stamp)
# 将rgb_time_stamp与depth_time_stamp对应行拼接起来
for i in range(len(rgb_time_stamp)):
str_association = rgb_time_stamp[i] + " " \
+ "rgb/" + rgb_time_stamp[i] + ".png" + " " \
+ data_depth[i]
f_association.write(str_association)
f_rgb.close()
f_depth.close()
f_association.close()
注:代码里按照filename读取文件的时候,没有考虑到这txt前三行的注释,所以也会有问题。故必须将传入的txt文件的前面三行的注释删掉,也就是rgb.txt与depth.txt按时间戳拼接后的.txt文件不要加前面的注释
预处理:python3 associate.py rgb.txt depth.txt > associations.txt
运行
cd /GCNv2_SLAM/GCN2
GCN_PATH=gcn2_320x240.pt ./rgbd_gcn ../Vocabulary/GCNvoc.bin TUM3_small.yaml /home/slam/GCNv2_SLAM/DataSet/rgbd_dataset_freiburg3_long_office_household /home/slam/GCNv2_SLAM/DataSet/rgbd_dataset_freiburg3_long_office_household/associations.txt
或者将run.sh数据集的路径改成你下载并解压的数据集路径就行
然后运行./run.sh
就行