0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一个利用GT-SAM的紧耦合激光雷达惯导里程计的框架

工程师邓生 来源:古月居 作者:月照银海似蛟龙 2022-09-14 10:11 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

前言

LIO-SAM的全称是:Tightly-coupled Lidar Inertial Odometry via Smoothing and Mapping

从全称上可以看出,该算法是一个紧耦合的雷达惯导里程计(Tightly-coupled Lidar Inertial Odometry),借助的手段就是利用GT-SAM库中的方法。

LIO-SAM 提出了一个利用GT-SAM的紧耦合激光雷达惯导里程计的框架。

实现了高精度、实时的移动机器人的轨迹估计和建图。

其中点云运动畸变矫正的代码在图像投影的节点中

23c33d90-33ba-11ed-ba43-dac502259ad0.png

可以看到该节点 订阅 3种消息:

原始点云数据

原始imu数据

imu预积分后预测的imu里程计数据其中完成的一个主要功能就是进行畸变矫正

本篇博客将解读其畸变矫正处理流程部分。

23d60f9c-33ba-11ed-ba43-dac502259ad0.png

畸变矫正

将点云投影到一个矩阵上,并保存每个点的信息,并在内部进行畸变矫正

  void projectPointCloud()  {

    int cloudSize = laserCloudIn->points.size();    for (int i = 0; i < cloudSize; ++i)    {

遍历整个点云

      PointType thisPoint;       thisPoint.x = laserCloudIn->points[i].x;      thisPoint.y = laserCloudIn->points[i].y;      thisPoint.z = laserCloudIn->points[i].z;      thisPoint.intensity = laserCloudIn->points[i].intensity;

取出对应的某个点

float range = pointDistance(thisPoint);

计算这个点距离lidar中心的距离

      if (range < lidarMinRange || range > lidarMaxRange)        continue;

距离太小或者太远都认为是异常点

      int rowIdn = laserCloudIn->points[i].ring;      if (rowIdn < 0 || rowIdn >= N_SCAN)        continue;      if (rowIdn % downsampleRate != 0)        continue;

取出对应的在第几根scan上


scan id 合理判断


如果需要降采样,就根据scan id 适当跳过

      float horizonAngle = atan2(thisPoint.x, thisPoint.y) * 180 / M_PI;       static float ang_res_x = 360.0/float(Horizon_SCAN);      int columnIdn = -round((horizonAngle-90.0)/ang_res_x) + Horizon_SCAN/2;      if (columnIdn >= Horizon_SCAN)        columnIdn -= Horizon_SCAN;      if (columnIdn < 0 || columnIdn >= Horizon_SCAN)        continue;

计算水平角

计算水平分辨率


计算水平线束id ,转换到x负方向为起始,顺时针为正方向,范围[0-H]


对水平角做补偿,因为雷达是顺时针旋转,


对水平id进行检查

      if (rangeMat.at(rowIdn, columnIdn) != FLT_MAX)        continue;

如果这个位置有填充了就跳过


点云不是完全的360度,可能会多一些

      thisPoint = deskewPoint(&thisPoint, laserCloudIn->points[i].time);

对点做运动补偿

rangeMat.at(rowIdn, columnIdn) = range;

将这个点的距离数据保存进这个range矩阵种

int index = columnIdn + rowIdn * Horizon_SCAN;

算出点的索引

fullCloud->points[index] = thisPoint;

保存这个点的坐标

之后来看下运动补偿得函数deskewPoint

  PointType deskewPoint(PointType *point, double relTime)  {

    if (deskewFlag == -1 || cloudInfo.imuAvailable == false)      return *point;

判断是否可以进行运动补偿,不能得话则之间返回原点


判断依据:

deskewFlag 是原始点云 没有 time得标签 则为-1

cloudInfo.imuAvailable 的原始imu里面的数据判断

    double pointTime = timeScanCur + relTime;

relTime 是相对时间,加上起始时间就是绝对时间

    float rotXCur, rotYCur, rotZCur;    findRotation(pointTime, &rotXCur, &rotYCur, &rotZCur);

通过findRotation函数 计算当前点 相对起始点的相对旋转

其内部为:

  void findRotation(double pointTime, float *rotXCur, float *rotYCur, float *rotZCur)  {    *rotXCur = 0; *rotYCur = 0; *rotZCur = 0;

先将相对旋转至0

    int imuPointerFront = 0;    while (imuPointerFront < imuPointerCur)    {      if (pointTime < imuTime[imuPointerFront])        break;      ++imuPointerFront;    }

找到距离该点云时间最近的 大于该点云时间的点

    if (pointTime > imuTime[imuPointerFront] || imuPointerFront == 0)    {      *rotXCur = imuRotX[imuPointerFront];      *rotYCur = imuRotY[imuPointerFront];      *rotZCur = imuRotZ[imuPointerFront];    }

如果时间戳不在两个imu的旋转之间,就直接赋值了

    } else {       int imuPointerBack = imuPointerFront - 1;      double ratioFront = (pointTime - imuTime[imuPointerBack]) / (imuTime[imuPointerFront] - imuTime[imuPointerBack]);      double ratioBack = (imuTime[imuPointerFront] - pointTime) / (imuTime[imuPointerFront] - imuTime[imuPointerBack]);      *rotXCur = imuRotX[imuPointerFront] * ratioFront + imuRotX[imuPointerBack] * ratioBack;      *rotYCur = imuRotY[imuPointerFront] * ratioFront + imuRotY[imuPointerBack] * ratioBack;      *rotZCur = imuRotZ[imuPointerFront] * ratioFront + imuRotZ[imuPointerBack] * ratioBack;    }

否则 作一个线性插值,得到相对旋转


算两个权重 进行 插值

    float posXCur, posYCur, posZCur;    findPosition(relTime, &posXCur, &posYCur, &posZCur);

这里没有计算平移补偿 如果运动不快的话

    if (firstPointFlag == true)    {      transStartInverse = (pcl::getTransformation(posXCur, posYCur, posZCur, rotXCur, rotYCur, rotZCur)).inverse();      firstPointFlag = false;    }

计算第一个点的相对位姿

    Eigen::Affine3f transFinal = pcl::getTransformation(posXCur, posYCur, posZCur, rotXCur, rotYCur, rotZCur);    Eigen::Affine3f transBt = transStartInverse * transFinal;

计算当前点和第一点的相对位姿

    newPoint.x = transBt(0,0) * point->x + transBt(0,1) * point->y + transBt(0,2) * point->z + transBt(0,3);    newPoint.y = transBt(1,0) * point->x + transBt(1,1) * point->y + transBt(1,2) * point->z + transBt(1,3);    newPoint.z = transBt(2,0) * point->x + transBt(2,1) * point->y + transBt(2,2) * point->z + transBt(2,3);    newPoint.intensity = point->intensity;    return newPoint;

就是R*p+t ,把点补偿到第一个点对应的时刻的位姿

然后看提取出有效的点的信息 函数cloudExtraction

  void cloudExtraction()  {

    for (int i = 0; i < N_SCAN; ++i)    {

遍历每一根scan

cloudInfo.startRingIndex[i] = count - 1 + 5;

这个scan可以计算曲率的起始点(计算曲率需要左右各五个点)

      for (int j = 0; j < Horizon_SCAN; ++j)      {

遍历该 scan上的每 个点

        if (rangeMat.at(i,j) != FLT_MAX)//FLT_MAX就是最大的浮点数        {

判断该点 是否 是一个 有效的点


rangeMat的每个点初始化为FLT_MAX ,如果点有效,则会赋值为 range

cloudInfo.pointColInd[count] = j;

点云信息里面 这个点对应着哪一个垂直线

cloudInfo.pointRange[count] = rangeMat.at(i,j);

点云信息里面 保存它的距离信息

 extractedCloud->push_back(fullCloud->points[j + i*Horizon_SCAN]);

他的3d坐标信息

cloudInfo.endRingIndex[i] = count -1 - 5;

这个scan可以计算曲率的终端

在上面处理完后


即可发布点云

  void publishClouds()  {    cloudInfo.header = cloudHeader;    cloudInfo.cloud_deskewed = publishCloud(&pubExtractedCloud, extractedCloud, cloudHeader.stamp, lidarFrame);    pubLaserCloudInfo.publish(cloudInfo);  }

最后将处理后的点云发布出去

result

23ec0fe0-33ba-11ed-ba43-dac502259ad0.png

23fb2ef8-33ba-11ed-ba43-dac502259ad0.png

240d608c-33ba-11ed-ba43-dac502259ad0.png





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 3D
    3D
    +关注

    关注

    9

    文章

    2990

    浏览量

    113838
  • SAM
    SAM
    +关注

    关注

    0

    文章

    116

    浏览量

    34317
  • 激光雷达
    +关注

    关注

    978

    文章

    4378

    浏览量

    195382

原文标题:LIO-SAM点云预处理前端:畸变矫正

文章出处:【微信号:3D视觉工坊,微信公众号:3D视觉工坊】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    CES 2025激光雷达观察:“千线”激光雷达亮相,头部厂商布局具身智能

    电子发烧友网报道(文/梁浩斌)每年CES都是激光雷达厂商发布新品的节点,在今年CES 2025上,有超过30家激光雷达厂商参展。头部的厂商,禾赛、速腾聚创、Seyond都推出了新产品,另外国内多家
    的头像 发表于 01-12 09:08 3354次阅读
    CES 2025<b class='flag-5'>激光雷达</b>观察:“千线”<b class='flag-5'>激光雷达</b>亮相,头部厂商布局具身智能

    激光雷达为什么会出现串扰的问题?

    飞行时间(Time-of-Flight,TOF)和连续波调频型(Frequency-Modulated Continuous Wave,FMCW)两种。 图片源自:网络 脉冲型TOF激光雷达雷达的工作原理比较直观,发射器每隔
    的头像 发表于 11-04 10:42 543次阅读
    <b class='flag-5'>激光雷达</b>为什么会出现串扰的问题?

    【CIE全国RISC-V创新应用大赛】+基于MUSE Pi Pro的3d激光里程计实现

    基于MUSE Pi Pro的3D激光里程计实现技术文档 内容摘要 本文档详细介绍了基于MUSE Pi Pro开发板和速腾聚创Airy 96线激光雷达实现3D激光
    发表于 10-24 17:02

    华为,激光雷达! 车载激光雷达市场的“隐形冠军”

    达到93.4%!相比此前1-5月份的三家份额91%进步提高,激光雷达产业正形成“寡头”竞争格局。 值得关注的是,华为以 64.38 万颗的装机量稳居榜首,市场份额攀升至 41.1%,成为车载激光雷达市场的“隐形冠军”。   作
    的头像 发表于 10-23 18:57 3025次阅读
    华为,<b class='flag-5'>激光雷达</b>第<b class='flag-5'>一</b>! 车载<b class='flag-5'>激光雷达</b>市场的“隐形冠军”

    【SOA是什么?】#激光雷达

    激光雷达
    天津见合八方光电科技有限公司
    发布于 :2025年07月15日 14:39:59

    超酷的树莓派激光雷达扫描仪!

    摘要这款DIY的PiLiDAR扫描仪项目利用树莓派进行激光雷达测绘。激光雷达通过发射激光来扫描周围环境,从而创建三维模型。该项目需要树莓派4、摄像头、电机以及
    的头像 发表于 06-01 08:33 798次阅读
    超酷的树莓派<b class='flag-5'>激光雷达</b>扫描仪!

    种新型激光雷达惯性视觉里程计系统介绍

    针对具有挑战性的光照条件和恶劣环境,本文提出了LIR-LIVO,这是种轻量级且稳健的激光雷达-惯性-视觉里程计系统。通过采用诸如利用深度与激光雷达
    的头像 发表于 04-28 11:18 803次阅读
    <b class='flag-5'>一</b>种新型<b class='flag-5'>激光雷达</b>惯性视觉<b class='flag-5'>里程计</b>系统介绍

    极氪007GT搭载禾赛ATX激光雷达上市

    近日,极氪科技集团旗下首款搭载禾赛激光雷达的车型极氪 007GT 正式上市,共发布后驱智驾版、长续航后驱智驾版、四驱智驾版三版型,官方零售价为 20.29-23.29 万元。极氪 007GT
    的头像 发表于 04-18 11:31 1731次阅读

    激光雷达调研纪要

    、长安已跟上,广汽、上汽等后续也可能加入,但具体配置情况因各车企方案而异。 不同级别自动驾驶配置差异: L3级自动驾驶因需安全冗余,会配备多颗激光雷达以实现360度或270度覆盖,般应用于30万以上车型;L2+车型通常只配备
    的头像 发表于 04-17 16:54 769次阅读

    禾赛科技在车载激光雷达市场摘得三项全球第

    激光雷达市场摘得三项全球第:全球车载激光雷达市占率第、全球 ADAS 激光雷达市占率第
    的头像 发表于 04-14 15:26 1374次阅读
    禾赛科技在车载<b class='flag-5'>激光雷达</b>市场摘得三项全球第<b class='flag-5'>一</b>

    DeepSeek:2025年激光雷达技术与行业应用趋势

    近日DeepSeek的火爆,我想知道它对激光雷达技术与行业应用趋势的看法。以下内容来源于DeepSeek-R1,仅供参考。2025年激光雷达技术与行业应用趋势:深度分析与预测、技术趋势:从固态化到
    的头像 发表于 02-06 10:40 2872次阅读
    DeepSeek:2025年<b class='flag-5'>激光雷达</b>技术与行业应用趋势

    激光雷达领域的新秀利器—SPAD23

    分析在激光雷达系统中的关键应用以及在激光雷达系统中核心器件的技术特性
    的头像 发表于 01-23 14:35 1219次阅读
    <b class='flag-5'>激光雷达</b>领域的新秀利器—SPAD23

    则消息引爆激光雷达行业!特斯拉竟然在自研激光雷达

    电子发烧友网报道(文/梁浩斌)则消息引爆激光雷达行业?上周业界流传的份会议纪要称,有自动驾驶专家透露,特斯拉已经设计了自己的激光雷达,并正在与大陆集团合作,将自己开发的
    的头像 发表于 12-30 00:09 2882次阅读

    科普:文了解固态和半固态激光雷达

    激光雷达(LiDAR,Laser Detecting and Ranging)作为种先进的传感技术,通过发射激光脉冲并测量其返回时间来计算目标距离,被广泛应用于自动驾驶、机器人、工业自动化等领域
    的头像 发表于 12-23 18:06 3675次阅读

    激光雷达,明年要降价至200美元

    20万以下车型。 而最近,禾赛科技CEO李帆表示,远距ADAS激光雷达产品计划在明年价格减半,令激光雷达对于15万以下更廉价的电动汽车也有吸引力。现阶段15万以上电动汽车的激光雷达
    的头像 发表于 12-16 11:36 6074次阅读
    <b class='flag-5'>激光雷达</b>,明年要降价至200美元