在Linux下编译运行GREAT-MSF的记录
GREAT (GNSS+ REsearch, Application and Teaching) 软件由武汉大学测绘学院设计开发,是一个用于空间大地测量数据处理、精密定位和定轨以及多源融合导航的综合性软件平台。
GREAT-MSF是GREAT软件中的一个重要模块,主要用于多传感器融合 (Multi-Sensor Fusion, MSF) 导航解算,包括卫星导航、惯性导航、相机、激光雷达、高精度地图、超宽带等,由GREAT-PVT扩展而来 (https:github.com/GREAT-WHU/GREAT-PVT.git )。软件中,核心计算模块使用C++语言编写,辅助脚本模块使用Python3语言实现结果绘制。GREAT-MSF软件使用CMAKE工具进行编译管理,用户可以灵活选择GCC、Clang、MSVC等主流C++编译器。目前支持在Windows下编译运行,Linux系统需要用户自行编译测试。
在GREAT团队的代码开源后学习一下先进经验,并尝试在Linux下跑通。
Linux下需要安装libglfw3-dev
和OpenGL(OpenGL直接安装ros-noetic得到,ros可运行其他SLAM代码使用),并对CMakeLists.txt
中相关设置进行更改,把glfw的include文件夹改为系统默认的路径,并链接使用包管理器安装的glfw。
sudo apt install libglfw3-dev libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev -y
具体配置可以参考我的仓库
先把仓库fork一份,然后克隆到本地
git clone [email protected]:SupremeLyre/GREAT-MSF.git
github已经不支持使用账密验证git,提前配置了ssh密钥
个人习惯,喜欢把最外层的CMakeLists.txt放在仓库根目录,把可执行程序放到bin文件夹,链接库放到lib文件夹,这样用vscode打开文件夹时还可以查看数据和日志等文件。因此,在仓库根目录新建CMakeLists.txt
,把src/
作为子目录。
cmake_minimum_required(VERSION 3.20)
project(mGREAT-MSF)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib/)
add_subdirectory(src)
将src
文件夹中的CMakeLists.txt
进行修改,注释掉cmake_minimum_required
和project
77-83行修改为
# Set the ROOT and subdirectory, you should put the CMakeList.txt in these file directories
set(ROOT ${PROJECT_SOURCE_DIR}/src)
message(STATUS "root directory is : ${ROOT}")
# set(EXECUTABLE_OUTPUT_PATH ${BUILD_DIR}/Bin)
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BUILD_DIR}/Bin)
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BUILD_DIR}/Lib)
# set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${BUILD_DIR}/Lib)
LibGNUT
和LibGREAT
的目录定义改为
set(LibGnutSrc ${ROOT}/${LibGnut})
set(LibGREATSrc ${ROOT}/${LibGREAT})
按F1调用Developer: Reload Window
,即可重启vscode窗口,激活cmake扩展。
configure过程没有出现问题。
测试机器系统为Ubuntu 20.04.6 LTS,使用默认的gcc/g++ 9.4.0进行编译测试。
编译时发现,仓库内提供的glfw库只在Windows下进行了编译(对Windows用户也太友好了),提供了编译好的静态链接库和cmake配置信息。因此,第一反应,使用apt装一下libglfw3-dev
,若是使用third-party中提供的glfw,则需要在GLFW文件夹下写一份CMakeLists.txt。
使用vscode搜索功能查找GLFW发现,使用了GLFW库的是LibGREAT,除GLFW外,还链接了opengl32.lib,本地环境之前安装过ros-noetic,所以opengl库应该是装齐了的。
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
link_directories(${BUILD_DIR}/Lib/Debug)
link_directories(${BUILD_DIR}/Lib/Release)
link_directories(${BUILD_DIR}/Lib/RelWithDebInfo)
link_directories(${BUILD_DIR}/Lib/MinSizeRel)
target_link_libraries(${PROJECT_NAME} ${Third_GLFW_ROOT}/lib/glfw3.lib opengl32.lib)
else()
link_directories(${BUILD_DIR}/Lib)
endif()
不管那么多,先把libglfw3-dev装一下:
sudo apt install libglfw3-dev -y
粗略看了下代码,虽然GLFW文件夹里面实现了GLFWViewer
类,但整体上使用的viewer貌似都是gviewer
这个类,GLFWViewer
类其实没用到,因此,只需要使用find找到使用apt装的glfw3就可以了,GLFW里面的代码理论上Linux端是不需要的。
对LibGREAT
目录下的CMakeLists.txt的12-36行做如下修改:
# link third party
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
#For windows
# ==============================================================================
if (NOT DEFINED Third_Eigen_ROOT)
find_path(Third_Eigen_ROOT HINTS "${Third_Eigen_ROOT}" "$ENV{Third_Eigen_ROOT} ")
endif()
if (NOT DEFINED Third_GLFW_ROOT)
set(Third_GLFW_ROOT ${ROOT}/third-party/GLFW)
endif()
# ==============================================================================
else()
# For linux
# write write_your_path_here
# ==============================================================================
find_package(OpenGL REQUIRED)
find_package(glfw3 3.3 REQUIRED)
if (NOT DEFINED Third_Eigen_ROOT)
set(Third_Eigen_ROOT ${ROOT}/third-party/Eigen)
endif()
# if (NOT DEFINED Third_GLFW_ROOT)
# set(Third_GLFW_ROOT ${ROOT}/third-party/GLFW)
# endif()
# ==============================================================================
endif()
使用搜索,把所有类似结构中定义的else()中的Third_GLFW_ROOT
变量都注释掉,同时,搜索 ${Third_GLFW_ROOT}/include
,加一个if判断。
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
include_directories(${Third_GLFW_ROOT}/include)
endif()
还有
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
set(include_path
${Third_Eigen_ROOT}
${Third_GLFW_ROOT}/include
${LibGnutSrc}
${LibGREATSrc})
else()
set(include_path
${Third_Eigen_ROOT}
# ${Third_GLFW_ROOT}/include
${LibGnutSrc}
${LibGREATSrc})
endif()
对LibGREAT
目录下的CMakeLists.txt的95-106行做如下修改:
# link third
# ==========================================================================================================================================
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
link_directories(${BUILD_DIR}/Lib/Debug)
link_directories(${BUILD_DIR}/Lib/Release)
link_directories(${BUILD_DIR}/Lib/RelWithDebInfo)
link_directories(${BUILD_DIR}/Lib/MinSizeRel)
target_link_libraries(${PROJECT_NAME} ${Third_GLFW_ROOT}/lib/glfw3.lib opengl32.lib)
else()
link_directories(${BUILD_DIR}/Lib)
target_link_libraries(${PROJECT_NAME} OpenGL::GL glfw)
endif()
# ==========================================================================================================================================
再次编译,发现编译通过了。
编译通过运行的时候发现找不到LibGREAT和LibGnut库,挠头看了一会儿,发现指定了src/CMakeLists.txt
里面指定了链接库路径,其实没必要。因为前面动了路径,所以这里也要改一下才行。
# Compilation options settings
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
add_compile_options(-O3)
# add_compile_options(-w)
add_compile_options(-m64)
add_compile_options(-lz)
add_compile_options(-lstdc++)
add_compile_options(-Wall)
add_compile_options(-w)
SET(BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}_Linux)
# SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
# SET(CMAKE_INSTALL_RPATH "\${ORIGIN}/../Lib")
把sample_data中的测试数据解压一下
cd sample_data
unzip MSF_20201029.zip
观察一下xml文档的内容,运行的目录应该是在MSF_20201029
下,xml文件中定义的相对路径成立。
按ctrl+,
在workspace配一下cmake.debugConfig
,会在.vscode
目录生成settings.json
,内容配置如下:
{
"cmake.debugConfig": {
"args": [
"-x",
"xml/GREAT_MSF_TCPPP_1029.xml",
],
"cwd": "${workspaceFolder}/sample_data/MSF_20201029"
}
}
arg控制运行时输入的参数,cwd控制程序运行路径。