LOAM主要由四个节点组成,分别为:
multiScanRegistration、laserOdometry、laserMapping和transformMaintenance。

其中,核心算法封装在BasicScanRegistration、BasicLaserOdomotry、BasicLaserMapping和BasicTransformMaintenance中,这几个类的实现不涉及ROS的函数,为loam移植到其他平台提供了方便。
按照数据流的顺序,我们来一步一步分析loam的算法。首先是multiScanRegistraition。
multiScanRegistration
设置节点的主程序位于multi_scan_registration_node.cpp中,代码十分简洁,只有20行,事实上,四个节点的主程序部分都是20行,非常工整。
multi_scan_registration_node.cpp:
#include <ros/ros.h>
#include "loam_velodyne/MultiScanRegistration.h"
/** Main node entry point. */
int main(int argc, char **argv)
{
ros::init(argc, argv, "scanRegistration");
ros::NodeHandle node;
ros::NodeHandle privateNode("~");
loam::MultiScanRegistration multiScan;
if (multiScan.setup(node, privateNode)) {
// initialization successful
ros::spin();
}
return 0;
}
点云注册的算法被封装在了MultiScanRegistration类中,他的继承关系为:
BasicLaserRegistration ———> ScanRegistraition ——>MultiScanRegistraion
ScanRegistration在父类的基础上增加了读取节点参数、发布/订阅消息的函数。MultiScanRegistraion在父类的基础上增加了对点云数据的预处理。
loam支持16线、32线和64线的激光雷达,默认参数为16线,可以对MultiScanMapper进行修改来切换不同的激光雷达模式。
MultiScanRegistration算法流程:
(1)预处理:读取点云后,先计算激光雷达的起始角度和终止角度,这里有一点需要注意一下,激光雷达一个扫描周期扫过的角度不一定刚好是360度。起始角为一帧点云数据中第一个点的水平角,终止角为最后一个点的水平角。去除点云中的极小值(坐标接近于0),对点云的坐标顺序进行调整,将坐标系改成:向左—x轴,向上—y轴,向前—z轴,根据垂直角计算每个点在第几条扫描线上(scanID),然后根据数据点的水平角计算该点在一个扫描周期中的相对时间,公式为:
R e l a t i v e T i m e = S c a n P e r i o d × H o r