多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测

多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测

参考博客
从零开始做自动驾驶定位(十一): 闭环修正
自动驾驶系统进阶与项目实战(四)自动驾驶高精度地图构建中的三维场景识别和闭环检测
自动驾驶系统进阶与项目实战(五)使用SC-LEGO-LOAM进行较大规模点云地图构建和闭环优化

源码:
这里使用scan context 部分源码来自 github sc-lego-loam
整体代码框架 来自 任乾 github tag11 闭环修正代码

ps:因为个人小白一枚,此处只是发表自己的见解,和学习思路,望指正

代码思路

整体框架

我们先来回顾一下整体的框架
参考博客 从零开始做自动驾驶定位(九): 建图系统结构优化
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第1张图片
本次,要完成的模块为 闭环检测模块

多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第2张图片
其中闭环检测 模块 又包含 两部分 : 分别是 闭环帧检测 与 点云的匹配
所对应的代码块如下:

    //闭环检测模块  (任乾)
    if (!DetectNearestKeyFrame(key_frame_index))
        return false;
        
	//点云配准 
    if (!CloudRegistration(key_frame_index))
        return false;

通过 调用 ScanContext,将当前帧 点云 与 历史帧 点云 进行 回环检测,得出 key_frame_index(检测出的回环帧) 和 yaw diff (位姿偏差角) ;进而把检测到的回环帧 传给 CloudRegistration 点云配准模块

代码编写

移植 sc-lego-loam 的 ScanContext相关 源代码 和 库文件

多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第3张图片
添加相关源文件 scan_context/Scancontext.cpp
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第4张图片
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第5张图片
添加头文件
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第6张图片

注意CMakeLists.txt添加

本机OpenCV路径添加

#本机OpenCV路径查看
locate   OpenCVConfig.cmake

多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第7张图片

主要调用SC中的两个函数

scManager.detectLoopClosureID(); 回环帧检测函数,没有检测到返回 -1 ,检测到回环帧返回 对应帧 的索引

scManager.makeAndSaveScancontextAndKeys(*raw_cloud_ptr); 实时保存当前帧点云,用于回环匹配

编写 函数

SaveCurrentFrame(int pcd_idx)
用于保存当前帧点云,仿照点云配准的方法,从磁盘实时获取当前帧点云的pcd存储在 raw_cloud_ptr 指针中,并调用 scManager.makeAndSaveScancontextAndKeys 进行当前帧的保存

DetectScanContext(int& key_frame_index,int pcd_idx)
检测回环帧,if true 输出 回环帧的索引 和 偏差位姿 ; else flase 返回 -1

void LoopClosing::SaveCurrentFrame(int pcd_idx){   
        // 读取并存储当前点云
    std::string file_path = key_frames_path_ + "/key_frame_" + std::to_string(pcd_idx) + ".pcd";
    CloudData::CLOUD_PTR raw_cloud_ptr(new CloudData::CLOUD());
     pcl::io::loadPCDFile(file_path, *raw_cloud_ptr);     //   raw_cloud_ptr  存储当前帧点云的point
    scManager.makeAndSaveScancontextAndKeys(*raw_cloud_ptr);     
}

// scan context  回环检测模块
int LoopClosing::DetectScanContext(int& key_frame_index,int pcd_idx) {        
    SaveCurrentFrame(pcd_idx);

    auto detectResult = scManager.detectLoopClosureID();     //  进行回环帧的检测  first: nn index, second: yaw diff

    key_frame_index = detectResult.first;    // 获取回环帧的索引
    yawDiffRad = detectResult.second; // not use for v1 (because pcl icp withi initial somthing wrong...)
    
    return   key_frame_index;    //没有检测到返回 -1 ,检测到回环帧返回   对应帧 的索引 
}

调用 函数

取代任乾老师的 DetectNearestKeyFrame 回环检测部分,eg: ScanContext 所做的工作为粗定位,检测到回环帧后,把回环帧输出给 下一个 点云配准模块CloudRegistration (精修定位) 才完成 整个 回环定位修正!!!

bool LoopClosing::Update(const KeyFrame key_frame, const KeyFrame key_gnss) {
    has_new_loop_pose_ = false;

    all_key_frames_.push_back(key_frame);
    all_key_gnss_.push_back(key_gnss);

    int key_frame_index = 0;

   //  scan  context   回环检测 
    if (DetectScanContext(key_frame_index,key_frame.index)  == -1)       //  key_frame_index  闭环检测帧 ;   key_frame.index  当前帧数
        return false;

    //任乾  闭环检测模块
    // if (!DetectNearestKeyFrame(key_frame_index))
    //     return false;
    
    if (!CloudRegistration(key_frame_index))
        return false;

    has_new_loop_pose_ = true;
        return true;
}

错误调试

在调试过程中,出现读取越界的原因,原因是在点云匹配模块部分,采取的配准策略时 Scan2Map方法,构建map需要取回环帧附近的帧融合,倘若 index为0 ,在构建map时就会出现 附近帧不存在的情况,进而导致指向越界的错误发生。
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第8张图片

修改部分:在 JointMap 添加

//越界保护
  if (i < 0 || i >= all_key_frames_.size( ) )    continue;

多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第9张图片

最终效果

使用任乾的 DetectNearestKeyFrame 回环检测

多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第10张图片
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第11张图片

rosservice call /optimize_map

生成 optimized.txt
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第12张图片
进行evo评估

evo_ape kitti ground_truth.txt optimized.txt -r full --plot --plot_mode xyz

多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第13张图片
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第14张图片
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第15张图片

使用 DetectScanContext 回环检测

多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第16张图片
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第17张图片
通过数据对比,可看出和任乾老师的回环检测模块差别不大
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第18张图片
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第19张图片
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第20张图片
多传感器融合定位(3-点云地图构建及基于地图定位)3-实现ScanContext 回环检测_第21张图片

你可能感兴趣的:(多传感器融合定位学习)