LEGO-LOAM代码阅读之 imageProjection

代码结构

main函数:

    ImageProjection IP;

在初始化ros后,只实例化出一个ImageProjection对象:IP,没进行其他相关操作,因此调用该类的构造函数

构造函数

    ImageProjection():
        nh("~"){
   
//nh("~") 意味着创建一个私有的节点句柄。
//使用 "~" 作为参数意味着这个节点句柄将只访问与当前节点相关的参数,而不是全局参数。这对于避免命名冲突和管理参数非常有用。
        subLaserCloud = nh.subscribe<sensor_msgs::PointCloud2>(pointCloudTopic, 1, &ImageProjection::cloudHandler, this);
extern const string pointCloudTopic = "/velodyne_points";

subLaserCloud订阅话题pointCloudTopic,当该话题中来新消息时会触发回调函数
&ImageProjection::cloudHandler,1 表示缓冲队列长度为 1,最新消息会覆盖旧消息。

回调函数cloudHandler

主要负责对话题中的点云数据消息进行处理。

    void cloudHandler(const sensor_msgs::PointCloud2ConstPtr& laserCloudMsg){
   
        // 1. Convert ros message to pcl point cloud
        copyPointCloud(laserCloudMsg);
        //将 laserCloudMsg 中的点云数据复制到另一个数据结构中,以便后续的处理或分析
        //将来自传感器的原始点云数据转换成自己定义的点云格式,或者进行必要的预处理
        // 2. Start and end angle of a scan// 2. 找到开始时刻和结束时刻的方向角度
        findStartEndAngle();
        // 3. Range image projection
        projectPointCloud();
        // 4. Mark ground points
        groundRemoval();
        // 5. Point cloud segmentation
        cloudSegmentation();
        // 6. Publish all clouds
        publishCloud();
        // 7. Reset parameters for next iteration
        resetParameters();
    }

copyPointCloud(laserCloudMsg);函数

功能:

1.复制消息头到cloudHeader,包括输入消息的头部信息(如时间戳、帧 ID);
2.将换 PointCloud2 消息到 PCL 格式,将ROS 消息格式的点云转换为 PCL 格式,并存储在 laserCloudIn 中;
3.移除laserCloudIn中的无效点(NaN 点) pcl::removeNaNFromPointCloud(*laserCloudIn, *laserCloudIn, indices);

removeNaNFromPointCloud函数:
如果输入点云是稠密点云,则直接复制到cloud_out中,即如果laserCloudIn为稠密点云,则不进行什么操作;
cpp if (cloud_in.is_dense) { // Simply copy the data cloud_out = cloud_in; for (std::size_t j = 0; j < cloud_out.points.size (); ++j) index[j] = static_cast<int>(j); }
如果laserCloudIn是稀疏点云,则进行下面操作:

if (!std::isfinite (cloud_in.points[i].x) ||
          !std::isfinite (cloud_in.points[i].y) ||
          !std::isfinite (cloud_in.points[i].z))
        continue;
      cloud_out.points[j] = cloud_in.points[i];
      index[j] = static_cast<int>(i);
      j++;

判断cloud_out的点是否为有效点,若某点的坐标x,y,z不是有限值,即为无效点,则continue,判断下个点,若该点是有效值,则将该点添加到cloud_out中,即对laserCloudIn点云数据进行剔除无效点,并将有效点在原点云中的索引记录到indices中;

cloud_out.height = 1;
cloud_out.width  = static_cast<std::uint32_t>(j);
// Removing bad points => dense (note: 'dense' doesn't mean 'organized')
cloud_out.is_dense = true;

最终剔除无效点的点云laserCloudIn设置为单行点云,稠密;

4.检查点云是否包含“环号”信息,if (useCloudRing == true){

如果有ring信息,则将原始点云信息转化为PCL格式,存储在 laserCloudInRing 中,如果laserCloudInRing点云不是稠密的,则输出错误信息并关闭 ROS 节点(ros::shutdown())。

**useCloudRing**标志,为bool类型,
```cpp
extern const bool useCloudRing = true; // if true, ang_res_y and ang_bottom are not used
```
解释:
注释说明了 useCloudRing 的作用:
    如果 useCloudRing 为 true,则程序不需要依赖 ang_res_y(垂直角分辨率)和 ang_bottom(激光束底部角度)来计算激光雷达的点云分布。
    这是因为环号信息可以直接提供每个点所属激光束的信息,替代这些计算。
    激光雷达环号(**ring**)信息:某些激光雷达(如 Velodyne 系列)会为每个点云点提供“环号”(ring),表示该点由哪一根激光束生成。

findStartEndAngle() 函数

1. 上一个函数处理后,剔除无效点的laserCloudIn点云数据,对其第一个点,计算初始点的扫描方向角(orientation),存储到segMsg.startOrientation中;
segMsg.startOrientation = -atan2(laserCloudIn->points[0].y, laserCloudIn->points[0].x);

负号为约定逆时针为负,顺时针为正。

2. 计算最后一个点的方向角,存储到segMsg.endOrientation中;
segMsg.endOrientation   = -atan2(laserCloudIn->points[laserCloudIn->points.size() - 1].y,
                    
### Lego-LOAM与KITTI数据集的使用教程 为了评估Lego-LOAM在KITTI数据集上的表现,需遵循一系列特定的操作流程。首先,在准备阶段,下载并解压KITTI数据集至指定文件夹[^1]。接着,安装`kitti2bag`工具用于转换原始数据格式到ROS bag文件,这一步骤对于后续处理至关重要。 针对Lego-LOAM源码部分,则需要对几个核心文件做出调整以适配KITTI的数据结构。具体而言,涉及到了`utility.h`, `imageProjection.cpp`以及`transformFusion.cpp`这三个主要组件中的代码改动[^2]。这些更改旨在优化算法性能,并确保其能够正确解析来自KITTI传感器的信息流。 完成上述准备工作之后,下一步就是配置实验环境。推荐使用的操作系统版本为Ubuntu 18.04 LTS,搭配ROS Melodic Morenia发行版、PCL (Point Cloud Library) 版本号不低于1.10以及GTSAM库至少达到4.0.3以上标准[^3]。 最后,通过执行预训练好的模型或者自行训练的新模型来获取轨迹估计结果。此时可以利用专门设计用来比较不同SLAM系统的误差统计软件包——evo来进行定量分析。该工具不仅支持多种评价指标计算,还提供了直观可视化界面帮助理解定位精度变化趋势。 ```bash # 安装 evo 工具链 pip install evo --upgrade ``` ### 实验结果展示 当一切设置妥当后,即可启动Lego-LOAM节点读取由`kitti2bag`转化而来的rosbags文件作为输入源。随着程序运行结束,会自动生成包含位姿预测路径在内的各类中间产物供进一步审查。借助于evo命令行接口,可方便快捷地对比真实GPS/INS记录下的地面实况同估算所得之间的差异程度: ```bash # 对齐并绘制两组轨迹图象 evo_ape kitti groundtruth.txt estimated_trajectory.txt -a --plot --save_plot output.png ``` 此过程产生的图表有助于直观感受两者间相对位置关系及其随时间演变情况;同时输出的日志文档详尽列出了各项技术参数数值,便于深入探讨影响因素所在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值