多传感器融合框架搭建

2023-05-16

架构

  1. src/include
    • apps:节点文件
      • front_end_node.cpp:前端节点
      • data_pretreat_node.cpp:数据预处理节点
      • back_end_node.cpp:后端节点
      • loop_closing_node.cpp:回环检测节点
    • data_pretreat:数据预处理节点相关代码
    • back_end_node:后端节点相关代码
    • loop_closing_node:回环检测节点相关代码
    • models:框架主要模块
    • publisher:发布者
    • subscriber:订阅者
    • tools:框架附带小功能,比如保存轨迹问txt文件
  2. slam_data 数据保存目录
    • key_frames:关键帧点云
    • map.pcd:全局点云
    • trajectory:真值轨迹和估计轨迹
    • scan context:回环检测数据
      • index.bin:scan context索引
      • scan_contexts.proto:scan context数据
      • ring_keys.proto:ring key数据
      • key_frames.proto,关键帧数据
  3. cmake ros第三方库
  4. config 配置文件
  5. Log 日志输出
  6. srv 服务

其他的略

编译

打开lidar_localization/config/scan_context文件夹,输入如下命令,生成pb文件

protoc --cpp_out=./ key_frames.proto
protoc --cpp_out=./ ring_keys.proto
protoc --cpp_out=./ scan_contexts.proto
mv key_frames.pb.cc key_frames.pb.cpp
mv ring_keys.pb.cc ring_keys.pb.cpp
mv scan_contexts.pb.cc scan_contexts.pb.cpp

分别修改生成的三个.pb.cpp文件。如下,以ring_keys.pb.cpp为例。

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: ring_keys.proto

#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
#include "ring_keys.pb.h" 替换为  #include "lidar_localization/models/scan_context_manager/ring_keys.pb.h"

#include <algorithm>

之后,用以上步骤生成的的.pb.h文件替换lidar_localization/include/lidar_localization/models/scan_context_manager
中的同名文件。
将.pb.cpp文件替换lidar_localization/src/models/scan_context_manager中的同名文件。

这样编译就没有问题了。

内容简述

请添加图片描述

预处理节点

  1. 订阅原始gnss数据,imu数据,点云数据
  2. 得到gnss里程计(真值),并对点云做畸变补偿

前端节点

front_end.yaml 中 whether_use_back_end 设置为NO

  1. 订阅gnss里程计和畸变补偿后的点云
  2. 通过前端算法配准点云得到lidar里程计,与gnss里程计一起发布,可以做evo评测

front_end.yaml 中 whether_use_back_end 设置为YES

  1. 订阅畸变补偿后的点云
  2. 通过前端算法配准得到lidar里程计,发布lidar里程计

服务:前端地图保存

rosservice call /save_front_end_map 

后端节点

  1. 订阅畸变补偿后的点云,lidar里程计,gnss里程计,回环检测节点的回环因子

  2. 根据距离上一帧位移是否足够远得到关键帧,gnss关键帧,关键帧点云(这里的关键帧只包含pose、id索引、时间戳,与点云是分开存储的)

    选取关键帧的方式大概分为三种

    1. 距离上一关键帧的帧数是否足够多,缺点较明显,当运动较慢时,会产生大量冗余关键帧,运动较快,会丢失重要关键帧
    2. 距离上一关键帧的位移足够远,可以解决上述问题,但是,当来回扫描同一个物体,同样会产生大量冗余关键帧
    3. 上一关键帧的共视点的数量足够少,这样就可以解决上述问题。

    展望:目前只使用了第2种方法,后期可以改进一下

  3. 给图优化器添加新关键帧顶点,与上一关键帧的边,以及gnss位置作为观测的先验一元边

  4. 根据图优化器中的关键帧顶点数,gnss因子数量,回环因子数判断是否需要优化,若需要优化,优化后保存更新位姿数据

服务:后端轨迹数据保存

rosservice call /save_back_end_pose

回环检测节点

  1. 订阅后端发布的关键帧、gnss关键帧、关键帧点云

  2. 将当前关键帧转换为scan context和ring key,加入回环系统

  3. 距离上一关键帧之间关键帧数数量足够多,就开始回环检测

  4. 先通过ring key得到回环关键帧的候选者,然后计算候选者的sector key得到精准的匹配方案

  5. 匹配候选者和当期关键帧的scan context,利用余弦距离得到相似度最高的最佳候选者:
    d ( I q , I c ) = 1 N s ∑ j = 1 N s ( 1 − c j q ⋅ c j c ∥ c j q ∥ ∥ c j c ∥ ) (5) d\left(I^{q}, I^{c}\right)=\frac{1}{N_{s}} \sum_{j=1}^{N_{s}}\left(1-\frac{c_{j}^{q} \cdot c_{j}^{c}}{\left\|c_{j}^{q}\right\|\left\|c_{j}^{c}\right\|}\right)\tag{5} d(Iq,Ic)=Ns1j=1Ns(1cjqcjccjqcjc)(5)

    参考我之前文章:

    https://blog.csdn.net/weixin_44035919/article/details/124926041

  6. 验证1:回环因子的两帧的id得到gnss位置误差小于阈值

  7. 点云配准优化回环因子的位姿:当前帧和最佳候选者的局部地图配准

  8. 验证2:返回点云配准的可靠得分大于阈值,最终全部通过即可发布回环因子

服务:回环数据保存

rosservice call /save_scan_context

可视化节点

这个比较简单直观,略。

主要工作

  1. 将之前前端拆分为两个节点,仍保留了原先前端算法对比的功能,只需要将front_end.yaml 中 whether_use_back_end 设置为NO即可
  2. 对所有订阅者加上了线程锁,保证数据的存取正常进行。
  3. 添加了后端和回环检测部分,注意要将front_end.yaml 中 whether_use_back_end 设置为YES。

期间遇到一个bug,在点云发布者中,点云点数不等于宽×高导致报错如下,

 pcl::toPCLPointCloud2(const pcl::PointCloud<PointT>&, pcl::PCLPointCloud2&)  [with PointT = pcl::PointXYZI]: Assertion `cloud.points.size () == cloud.width * cloud.height' failed.

将点云设置为无序点云解决:

cloud_ptr_input->width=cloud_ptr_input->points.size();
cloud_ptr_input->height = 1;

结果

请添加图片描述

分段误差:

请添加图片描述

  • 最大误差:3.597209 %
  • 平均误差:1.864868%
  • 最小误差: 0.883433%
  • RMSE:1.993375%

整体误差:

请添加图片描述

  • 最大误差:0.549552m
  • 平均误差:0.095091m
  • RMSE:0.132866m

平均绝对轨迹误差只有0.132866m,相比于前端有了很大的改进。

展望

只说一下目前想到的待改进之处吧

  1. 后端可以使用多态试试因子图的效果如何

  2. NDT算法改进

    请添加图片描述

  3. gnss位置作为观测先验时,需要考虑权重,当gps位于失效场景中时,要减小权重。

  4. 关键帧选择上采用的是位移足够远,是否能采用共视点数足够多,解决来回扫描的场景。

  5. 融合相机图像信息,使系统更加鲁棒。

框架链接如下:

链接: https://pan.baidu.com/s/19Rr1mcVWIUyAKoucRkTSYg 密码: nkbk
–来自百度网盘超级会员V4的分享

如有错误,请加我v:peak1229258698交流指正。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多传感器融合框架搭建 的相关文章

随机推荐