SLAM:loam算法架构分析

匿名 (未验证) 提交于 2019-12-03 00:30:01

在研读了论文及开源代码后,对LOAM的一些理解做一个整理。

文章:Low-drift and real-time lidar odometry and mapping

开源代码:https://github.com/daobilige-su/loam_velodyne

系统概述

LOAM的整体思想就是将复杂的SLAM问题分为:1. 高频的运动估计; 2. 低频的环境建图。


Lidar接收数据,首先进行Point Cloud Registration,Lidar Odometry以10Hz的频率进行运动估计和坐标转换,Lidar Mapping以1Hz的频率构建三维地图,Transform Integration完成位姿的优化。这样并行的结构保证了系统的实时性。

接下来是代码的框架图:



整个算法分为四个模块,相对于其它直接匹配两个点云的算法,LOAM是通过提取特征点进行匹配之后计算坐标变换。具体流程为:ScanRegistration 提取特征点并排除瑕点;LaserOdometry从特征点中估计运动,然后整合数据发送给LaserMapping;LaserMapping输出的laser_cloud_surround为地图;TransformMaintenance订阅LaserOdometry与LaserMapping发布的Odometry消息,对位姿进行融合优化。后面将详细进行说明。

ScanRegistration

这一模块(节点)主要功能是:特征点的提取

一次扫描的点通过曲率值来分类,特征点曲率大于阈值的为边缘点;特征点曲率小于阈值的为平面点。为了使特征点均匀的分布在环境中,将一次扫描划分为4个独立的子区域。每个子区域最多提供2个边缘点和4个平面点。此外,将不稳定的特征点(瑕点)排除。下面将通过代码进行说明。

从主函数开始:

  1. intintchar
  2. "scanRegistration"
  3. /*
  4. /*
  5. "/velodyne_points"
  6. "/imu/data"
  7. /*
  8. "/velodyne_cloud_2"
  9. "/laser_cloud_sharp"
  10. "/laser_cloud_less_sharp"
  11. "/laser_cloud_flat"
  12. "/laser_cloud_less_flat"
  13. "/imu_trans"
  14. /**
  15. return
主函数比较简单,订阅了2个节点和发布了6个节点。通过回调函数的处理,将处理后的点云重新发出去。主要涉及的函数为

laserCloudHandler与imuHandler。

・laserHandler

laserCloudHandler是这一模块的重点部分,主要功能是对接收到的点云进行预处理,完成分类。具体分类内容为:一是将点云划入不同线中存储;二是对其进行特征分类。

首先对收到的点云进行处理

  1. voidconst
  2. if
  3. if
  4. true
  5. return
  6. int
  7. int
  8. double
  9. int
  10. //去除无效值
  11. int
  12. //计算点云的起始角度/终止角度
  13. float
  14. float
接下来的处理是根据角度将点划入不同数组中
  1. forint
  2. float
  3. int
  4. intint
  5. if
  6. else
  7. if
  8. continue

接下来计算每个点的相对方位角计算出相对时间,根据线性插值的方法计算速度及角度,并转换到sweep k的初始imu坐标系下,再划入16线数组中

  1. float
  2. if
  3. if
  4. elseif
  5. if
  6. true
  7. else
  8. if
  9. elseif
  10. //scanPeriod=0.1,是因为lidar工作周期是10HZ,意味着转一圈是0.1秒;intensity是一个整数+小数,小数不会超过0.1,完成了按照时间排序的需求
  11. float
  12. if
  13. float
  14. while
  15. if
  16. break
  17. if
  18. else
  19. int
  20. float
  21. float
  22. if
  23. elseif
  24. else
  25. if
  26. else

之后将对所有点进行曲率值的计算并记录每一层曲率数组的起始和终止

  1. new
  2. //将所有点存入laserCloud中,点按线序进行排列
  3. forint
  4. int
  5. forint
  6. float
  7. float
  8. float
  9. ifint
  10. int(laserCloud->points[i].intensity);//scanCount=scanID
  11. if

接下来,对提到的两种瑕点进行排除


  1. forint
  2. float
  3. float
  4. float
  5. float
  6. if
  7. float
  8. float
  9. if
  10. if
  11. else
  12. if
  13. float
  14. float
  15. float
  16. float
  17. float
  18. if
之后对平面点以及角点进行shai'xu
  1. forint
  2. new
  3. forint
  4. int
  5. int
  6. forint
  7. forint
  8. if
  9. int
  10. int
  11. forint
  12. int
  13. if
  14. if
  15. elseif
  16. else
  17. break
  18. forint
  19. float
  20. float
  21. float
  22. if
  23. break
  24. forint
  25. float
  26. float
  27. float
  28. if
  29. break
  30. int
  31. forint
  32. int
  33. if
  34. if
  35. break
  36. forint
  37. float
  38. float
  39. float
  40. if
  41. break
  42. forint
  43. float
  44. float
  45. float
  46. if
  47. break
  48. forint
  49. if

之后再将信息发布出去

・imuHandler

  1. voidconst
  2. double
  3. float
  4. float
  5. float
  6. void
  7. float
  8. float
  9. float
  10. float
  11. float
  12. float
  13. float
  14. float
  15. float
  16. float
  17. float
  18. float
  19. int
  20. double
  21. if

后面涉及的坐标变换即欧拉角的旋转计算,这部分尚不熟悉,需要进一步学习。

・小结



以上数据传输流帮助理解这个模块源代码的功能。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!