1. 环境准备与源码编译
搞ORB-SLAM2稠密建图的第一步,就是把代码和环境折腾明白。我当初用高翔老师的ORBSLAM2_with_pointcloud_map仓库时,踩了不少坑。先说说怎么把代码搞到本地:
git clone https://github.com/gaoxiang12/ORBSLAM2_with_pointcloud_map.git克隆完别急着编译,有几个准备工作必须做。首先要把ORB-SLAM2里的Vocabulary文件夹拷贝到新仓库的ORB_SLAM2_modified目录下,这个词袋文件相当于系统的"字典",没有它后面特征匹配全完蛋。
接下来要清理build文件夹,这三个地方的一定要删干净:
- ORB_SLAM2_modified/Thirdparty/DBoW2/build
- ORB_SLAM2_modified/Thirdparty/g2o/build
- ORB_SLAM2_modified/Examples/ROS/ORB_SLAM2/build
我第一次编译时就栽在这儿,旧build文件残留导致各种诡异错误。删干净后给build.sh加执行权限:
chmod +x build.sh ./build.sh这时候大概率会报PCL版本问题,错误信息长这样:
/usr/include/pcl-1.10/pcl/pcl_config.h:7:4: error: #error PCL requires C++14 or above1.1 解决C++标准问题
这个错是因为PCL 1.10要求C++14,但默认配置是C++11。解决方法很简单,打开ORB_SLAM2_modified/CMakeLists.txt,找到C++标准设置部分,把原来的-std=c++11全改成-std=c++14。我建议直接替换整段代码:
# Check C++14 support include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14) if(COMPILER_SUPPORTS_CXX14) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") add_definitions(-DCOMPILEDWITHC14) message(STATUS "Using flag -std=c++14.") else() message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support.") endif()改完再编译,可能会遇到新的坑——STL容器分配器报错。这个错误信息里会有"static assertion failed: std::map must have the same value_type"之类的提示。解决方法是在LoopClosing.h里找到KeyFrameAndPose定义,改成这样:
typedef map<KeyFrame*,g2o::Sim3,std::less<KeyFrame*>, Eigen::aligned_allocator<std::pair<KeyFrame *const, g2o::Sim3>> > KeyFrameAndPose;1.2 处理过时的chrono API
还有个常见坑是monotonic_clock报错,这个API在新版C++里被废弃了。打开所有用到std::chrono::monotonic_clock的地方(比如mono_tum.cc),替换为std::chrono::steady_clock:
// 原代码 std::chrono::monotonic_clock::time_point t1 = std::chrono::monotonic_clock::now(); // 修改为 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();这些坑都填完后,应该就能顺利编译通过了。建议每次修改后都执行make clean再重新编译,避免缓存导致的问题。
2. 数据集测试与段错误排查
编译通过只是万里长征第一步,真正折磨人的是运行时各种段错误(Segmentation fault)和核心已转储(Core dumped)。我用TUM数据集测试时,经常遇到程序跑着跑着就崩溃的情况。
2.1 运行TUM数据集
先看看正常运行的命令格式:
./bin/rgbd_tum Vocabulary/ORBvoc.txt Examples/RGB-D/TUM1.yaml \ /home/user/Dataset/rgbd_dataset_freiburg1_xyz \ Examples/RGB-D/associations/fr1_xyz.txt这里最容易出问题的就是路径配置。我建议先用绝对路径,确保所有文件都能找到。运行时如果看到类似下面的输出,说明系统开始工作了:
ORB Extractor Parameters: - Number of Features: 1000 - Scale Levels: 8 - Scale Factor: 1.2 Depth Threshold (Close/Far Points): 3.09294 ------- Start processing sequence ... Images in the sequence: 792 New map created with 834 points2.2 解决段错误问题
当看到"段错误 (核心已转储)"时,别慌,这通常是内存访问越界导致的。根据我的经验,90%的情况是-march=native编译选项没删干净。这个选项会让编译器针对当前CPU优化,但可能引发兼容性问题。
需要检查以下四个CMakeLists.txt文件:
- ORB_SLAM2_modified/CMakeLists.txt
- ORB_SLAM2_modified/Thirdparty/DBoW2/CMakeLists.txt
- ORB_SLAM2_modified/Thirdparty/g2o/CMakeLists.txt
- ORB_SLAM2_modified/Examples/ROS/ORB_SLAM2/CMakeLists.txt
用文本编辑器的全局搜索功能,把所有-march=native都替换为空。建议直接用sed命令批量处理:
find . -name "CMakeLists.txt" -exec sed -i 's/-march=native//g' {} +2.3 PCL版本冲突处理
另一个常见问题是PCL版本不匹配。虽然错误提示说需要PCL 1.7,但实际用新版本也行。关键是要修改CMakeLists.txt里的查找语句:
# 原代码 find_package(PCL 1.7 REQUIRED) # 修改为 find_package(PCL REQUIRED) message("PCL version: ${PCL_VERSION}")这样能自动适配已安装的PCL版本。我用的PCL 1.10就没问题,关键是要保持所有依赖库的版本一致性。
3. 彩色点云地图生成
默认的ORB-SLAM2只生成灰色点云,想要彩色地图得自己改代码。我摸索出一套可行的修改方案,分享给大家。
3.1 代码修改步骤
首先在Tracking.h中添加彩色图像成员变量:
// Current Frame Frame mCurrentFrame; cv::Mat mImRGB; // 新增这行 cv::Mat mImGray; cv::Mat mImDepth;然后在Tracking.cc中修改两处:
- 在GrabImageRGBD函数里保存彩色图像:
cv::Mat Tracking::GrabImageRGBD(const cv::Mat &imRGB, const cv::Mat &imD, const double ×tamp) { mImRGB = imRGB; // 新增 mImGray = imRGB; mImDepth = imD;- 修改关键帧插入逻辑,传递彩色图像:
// 原代码 // mpPointCloudMapping->insertKeyFrame(pKF, this->mImGray, this->mImDepth); // 修改为 mpPointCloudMapping->insertKeyFrame(pKF, this->mImRGB, this->mImDepth);3.2 点云保存功能
要让系统保存点云地图,需要修改pointcloudmapping.cc。在viewer()函数里添加保存代码:
for (size_t i = lastKeyframeSize; i < N; i++) { PointCloud::Ptr p = generatePointCloud(keyframes[i], colorImgs[i], depthImgs[i]); *globalMap += *p; } // 保存点云 string save_path = "./resultPointCloudFile.pcd"; pcl::io::savePCDFile(save_path, *globalMap); cout << "save pcd files to : " << save_path << endl;记得在文件开头添加PCL IO头文件:
#include <pcl/io/pcd_io.h>3.3 查看点云结果
安装PCL工具查看生成的点云:
sudo apt-get install pcl-tools pcl_viewer resultPointCloudFile.pcd在pcl_viewer里可以用这些操作:
- Shift+鼠标滚轮:上下移动视角
- Ctrl+鼠标左键:旋转点云
- 鼠标右键:平移场景
4. D435i实时建图实战
最后说说怎么用Intel RealSense D435i相机做实时稠密建图。这个相机性价比很高,但配置起来有些门道。
4.1 ROS环境配置
先创建ROS工作空间:
mkdir -p ~/catkin_pointcloudmap_ws/src cd ~/catkin_pointcloudmap_ws/src catkin_init_workspace cd .. catkin_make把之前修改好的ORB_SLAM2_modified放到src目录下,然后删除旧的build文件:
cd src/ORB_SLAM2_modified/Examples/ROS/ORB_SLAM2/ rm -rf build4.2 解决编译错误
编译时可能会报OpenCV版本冲突,这是因为ROS Noetic默认用OpenCV4,而ORB-SLAM2原本是为OpenCV3设计的。修改CMakeLists.txt:
# 原代码 find_package(OpenCV 3.0 QUIET) # 修改为 find_package(OpenCV 4.2 QUIET)如果遇到opencv/cv.h找不到的错误,把相关include语句改为:
#include <opencv2/imgproc/imgproc_c.h> #include <opencv2/highgui/highgui_c.h>4.3 相机参数配置
启动相机获取内参:
roslaunch realsense2_camera rs_camera.launch rostopic echo /camera/color/camera_info根据输出创建MyD435i.yaml配置文件,重点配置这些参数:
Camera.fx: 909.855712890625 Camera.fy: 909.7683715820312 Camera.cx: 651.5874633789062 Camera.cy: 381.3797302246094 Camera.width: 640 Camera.height: 480 Camera.bf: 50.0 # 基线长度(mm)乘以fx DepthMapFactor: 1000.0 # 深度图缩放因子4.4 实时建图运行
启动相机:
roslaunch realsense2_camera rs_camera.launch新建终端运行ORB-SLAM2:
rosrun ORB_SLAM2 RGBD Vocabulary/ORBvoc.txt Examples/ROS/ORB_SLAM2/MyD435i.yaml如果遇到ROS包路径问题,记得设置环境变量:
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/path/to/ORB_SLAM2/Examples/ROS source ~/catkin_pointcloudmap_ws/devel/setup.bash成功运行后,你就能看到实时生成的彩色点云地图了。建图过程中要注意保持相机运动平稳,快速移动容易导致跟踪丢失。