LeGO-LOAM 源码阅读笔记(featureAssociation.cpp)

本文详细解读LeGO-LOAM中featureAssociation.cpp的代码,涉及特征关联、点云处理、IMU数据处理等功能。介绍了点云坐标变换、加速度处理、特征抽取、光滑性计算等关键步骤,旨在帮助读者理解LeGO-LOAM的优化建图原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LeGO-LOAM是一种在LOAM之上进行改进的激光雷达建图方法,建图效果比LOAM要好,但是建图较为稀疏,计算量也更小了。

本文原地址:wykxwyc的博客

github注释后LeGO-LOAM源码:LeGO-LOAM_NOTED
关于代码的详细理解,建议阅读:

1.地图优化代码理解

2.图像重投影代码理解

3.特征关联代码理解

4.LeGO-LOAM中的数学公式推导

以上博客会随时更新,如果对你有帮助,请点击注释代码的github仓库右上角star按钮,你的鼓励将给我更多动力。

featureAssociation.cpp概述

featureAssociation.cpp顾名思义,进行特征关联的过程。

FeatureAssociation

FeatureAssociation()构造函数的内容如下:

  1. 订阅话题:

  2. 发布话题,这些topic有:

    • "/laser_cloud_sharp"(sensor_msgs::PointCloud2)
    • "/laser_cloud_less_sharp"(sensor_msgs::PointCloud2)
    • "/laser_cloud_flat"(sensor_msgs::PointCloud2)
    • "/laser_cloud_less_flat"(sensor_msgs::PointCloud2)
    • "/laser_cloud_corner_last"(sensor_msgs::PointCloud2)
    • "/laser_cloud_surf_last"(cloud_msgs::cloud_info)
    • "/outlier_cloud_last"(sensor_msgs::PointCloud2)
    • "/laser_odom_to_init"(nav_msgs::Odometry)

然后初始化各类参数。

laserCloudHandler

laserCloudHandler修改点云数据的时间戳,将点云数据从ROS定义的格式转化到pcl的格式。

laserCloudInfoHandler

函数比较小:

void laserCloudInfoHandler(const cloud_msgs::cloud_infoConstPtr& msgIn){
   
    timeNewSegmentedCloudInfo = msgIn->header.stamp.toSec();
    segInfo = *msgIn;
    newSegmentedCloudInfo = true;
}

outlierCloudHandler

void outlierCloudHandler(const sensor_msgs::PointCloud2ConstPtr& msgIn){
   
    timeNewOutlierCloud = msgIn->header.stamp.toSec();
    outlierCloud->clear();
    pcl::fromROSMsg(*msgIn, *outlierCloud);
    newOutlierCloud = true;
}

imuHandler

void imuHandler(const sensor_msgs::Imu::ConstPtr& imuIn)接触过很多次,因为它就是LOAM代码里的那个。
函数的实现:

  1. 通过接收到的imuIn里面的四元素得到roll,pitch,yaw三个角;
  2. 对加速度进行坐标变换(坐标变换可以参考下面这张图);
  3. 将欧拉角,加速度,速度保存到循环队列中;
  4. 对速度,角速度,加速度进行积分,得到位移,角度和速度(AccumulateIMUShiftAndRotation());

加速度坐标交换的示意图:
在这里插入图片描述

  • 进行加速度坐标交换时将重力加速度去除,然后再进行 x x x z z z, y y y x x x, z z z y y y的变换。
  • 去除重力加速度的影响时,需要把重力加速度分解到三个坐标轴上,然后分别去除他们分量的影响,在去除的过程中需要注意加减号(默认右手坐标系的旋转方向来看)。
  • 在上面示意图中,可以简单理解为红色箭头实线分解到红色箭头虚线上(根据 p i t c h pitch pitch进行分解),然后再按找 r o l l roll roll角进行分解。

runFeatureAssociation

void runFeatureAssociation()是featureAssociation.cpp中最主要的函数,它调用这个cpp文件中的其他函数。算法步骤如下:

  1. 如果有新数据进来则执行,否则不执行任何操作;
  2. 将点云数据进行坐标变换,进行插补等工作;
  3. 进行光滑性计算,并保存结果;
  4. 标记阻塞点(阻塞点:点云中可能出现的互相遮挡的点);
  5. 特征抽取,然后分别保存到cornerPointsSharp等等队列中去;
  6. 发布cornerPointsSharp等4种类型的点云数据;
  7. 预测位姿;
  8. 更新变换;
  9. 积分总变换;
  10. 发布里程计信息及上一次点云信息;

adjustDistortion

void adjustDistortion()将点云数据进行坐标变换,进行插补等工作。

  1. 对每个点进行处理,首先进行和laboshin_loam代码中的一样的坐标轴变换过程。
point.x = segmentedCloud->points[i].y;
point.y = segmentedCloud->points[i].z;
point.z = segmentedCloud->points[i].x;
  1. 针对每个点计算偏航角yaw,然后根据不同的偏航角,可以知道激光雷达扫过的位置有没有超过一半,计算的时候有一部分需要注意一下:
    函数原型:
// -atan2(p.x,p.z)==>-atan2(y,x)
// ori表示的是偏航角yaw,因为前面有负号,ori=[-M_PI,M_PI)
// 因为segInfo.orientationDiff表示的范围是(PI,3PI),在2PI附近
// 下面过程的主要作用是调整ori大小,满足start<ori<end
float ori = -atan2(point.x, point.z);

这里分为4种情况:

  • 没有转过一半,但是start-ori>M_PI/2
  • 没有转过一半,但是ori-start>3/2*M_PI,说明ori太大,不合理(正常情况在前半圈的话,ori-start范围[0,M_PI]
  • 转过一半,end-ori>3/2*PI,ori太小
  • 转过一半,ori-end>M_PI/2,太大
  1. 然后进行imu数据与激光数据的时间轴对齐操作。
    对齐时候有两种情况,一种不能用插补来优化,一种可以通过插补进行优化。
  • 不能通过插补进行优化:imu数据比激光数据早,但是没有更后面的数据(打个比方,激光在9点时出现,imu现在只有8点的)
    这种情况下while循环是以imuPointerFront == imuPointerLast结束的:
// while循环内进行时间轴对齐
while (imuPointerFront != imuPointerLast) {
   
    if (timeScanCur + pointTime < imuTime[imuPointerFront]) {
   
        break;
    }
     imuPointerFront = (imuPointerFront + 1) % imuQueLength;
}
  • 可以通过插补来进行数据的优化:
    这种情况只有在imu数据充足的情况下才会发生,
    进行插补时,当前timeScanCur + pointTime < imuTime[imuPointerFront],
    而且imuPointerFront是最早一个时间大于timeScanCur + pointTime的imu数据
<think>嗯,用户遇到了CMake构建错误,提示“target pattern contains no '%'”,特别是在SC-LeGO-LOAM项目中。我需要先理解这个错误的常见原因。根据引用[3]和[4],这个问题通常与Makefile中的错误模式规则有关。可能的触发点包括路径中的空格或特殊字符,错误的变量引用,或者自定义构建规则中的错误。 首先,用户的项目涉及SC-LeGO-LOAM,这可能是一个ROS项目,使用catkin_make构建。用户提到的引用[1]和[2]中有关于编译步骤和文件修改的内容,比如修改utility.h中的话题名称,以及安装GTSAM。这些步骤是否可能引入错误呢? 比如,在引用[3]中,编译DBUS时出现同样的错误,问题出在CMakeLists.txt生成Makefile时,路径或规则中的错误。可能是在某些规则中使用了不正确的变量,比如缺少转义或者变量名错误,导致生成的目标模式缺少必要的%。 接下来,我需要考虑用户可能的操作步骤。用户可能按照引用[1]克隆了仓库,然后进行catkin_make,但在此过程中出现了错误。根据错误信息,检查CMakeLists.txt中的add_custom_command或add_custom_target是否有问题。比如,自定义命令中的输出或依赖路径可能包含空格,或者使用了不正确的语法,比如缺少$<TARGET_FILE_DIR:...>的变量引用。 另外,引用[4]提到在AURIX开发环境中,添加了错误的函数参数导致构建错误,这可能类比于用户在修改源码时(如修改pointCloudTopic或imuTopic)可能出现的配置错误,或者CMake文件中参数传递错误。 可能的解决方案包括检查CMakeLists.txt中的自定义规则,确保路径正确,转义特殊字符,尤其是处理空格。另外,确保所有变量正确展开,特别是在使用生成器表达式时。如果用户修改了某些文件路径,可能导致路径中包含空格,需要加上引号。 总结步骤:首先定位报错的CMakeLists.txt文件和具体行号,检查相关规则;处理路径中的特殊字符;验证自定义命令语法;更新CMake版本;清理构建目录后重新构建。同时,参考用户提供的引用中提到的utility.h修改是否影响了构建过程,或者是否在克隆仓库后有其他未注意的步骤导致路径问题。</think>针对CMake构建时出现的`target pattern contains no '%'`错误,该问题通常由Makefile生成过程中路径格式异常或自定义规则语法错误引发。以下是具体分析及解决方案: --- ### **错误原因分析** 1. **路径中的特殊字符或空格** CMake生成的Makefile若遇到包含空格或未转义特殊字符(如`#`、`%`)的路径,会导致模式规则解析失败。例如路径`/home/user/my project/`中的空格可能被误解析为多个参数[^3][^4]。 2. **自定义构建规则语法错误** 在`CMakeLists.txt`中使用`add_custom_command`或`add_custom_target`时,若输出文件路径未正确使用`$<TARGET_FILE_DIR:target>`变量,或缺少必要的转义符(如`$`需写为`$$`),会导致生成无效的Makefile规则[^3][^4]。 3. **变量未正确展开** 使用`${VAR}`格式引用变量时,若变量值为空或未正确定义,可能生成不完整的命令参数,进而破坏Makefile语法结构。 --- ### **解决方案步骤** 1. **定位错误位置** 通过错误日志中的行号(如`doc/CMakeFiles/dbus-test-plan.html.dir/build.make:51`)找到对应的`CMakeLists.txt`文件,检查相关自定义命令或目标定义。 2. **检查路径格式** - 确保所有路径变量(如`pointCloudTopic`)不包含空格或特殊字符 - 若路径必须包含空格,需用引号包裹路径: ```cmake add_custom_command( OUTPUT "${PROJECT_SOURCE_DIR}/output/file.txt" COMMAND ... ) ``` 3. **验证自定义命令语法** 修正`add_custom_command`中可能的语法错误,例如: ```cmake add_custom_command( OUTPUT $<TARGET_FILE_DIR:my_target>/generated_file.cpp # 正确使用生成器表达式 COMMAND ${PYTHON_EXECUTABLE} ${SCRIPT_PATH}/generate.py DEPENDS ${INPUT_FILES} ) ``` 4. **更新CMake版本** 低版本CMake(如<3.0)对路径处理存在缺陷,建议升级至最新稳定版: ```bash sudo apt-get update && sudo apt-get install cmake ``` 5. **清理并重建项目** 删除`build/`和`devel/`目录后重新编译: ```bash cd ~/catkin_ws rm -rf build/ devel/ catkin_make clean catkin_make ``` --- ### **SC-LeGO-LOAM项目注意事项** 1. **检查`utility.h`配置** 确保`pointCloudTopic`和`imuTopic`的字符串值不包含非法字符,例如: ```cpp extern const string pointCloudTopic = "/os1_points"; // 确认引号闭合且无多余符号[^2] ``` 2. **验证GTSAM依赖安装** 若项目依赖GTSAM,需按官方文档正确编译安装: ```bash git clone https://github.com/borglab/gtsam.git cd gtsam && mkdir build && cd build cmake .. && make -j4 sudo make install ``` ---
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值