rslidar LOAM系列建图

本文详细介绍了使用LOAM、A-LOAM和LeGO-LOAM等算法进行激光雷达SLAM建图的过程。从工作空间创建、源码下载编译到实时与离线建图的步骤,逐一展开。针对不同雷达型号,如RS-LIDAR-16,进行了话题映射和数据过滤的调整。此外,还提到了如何保存和转换点云地图,并针对LeGO-LOAM的运行中出现的问题给出了解决方案,包括修改源代码以适应特定硬件。最后,文章提及了SC-LeGO-LOAM和SC-A-LOAM等相关算法的应用。

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

1 LOAM建图

1.1 工作空间建立

mkdir -p catkin_jt/src
cd catkin_jt/src
catkin_init_workspace

1.2 源码下载及编译

cd ~/catkin_jt/src # catkin_jt自己的ROS工作空间。
git clone https://github.com/laboshinl/loam_velodyne.git
cd catkin_jt
catkin_make
source ~/devel/setup.bash

1.3 使用

  • 根据rslidar新建loam_rslidar.launch文件
<launch>

  <node pkg="tf" type="static_transform_publisher" name="rslidarlink_broadcaster" args="0.0 0.0 0.42 0.0 0.0 0.0 base_link laser 50"/>

  <arg name="rviz" default="false" />
  <arg name="scanPeriod" default="0.1" />
  <arg name="lidartype" default="VLP-16" /> <!-- options: VLP-16  HDL-32  HDL-64E RS-32 RS-16-->


  <node pkg="loam_velodyne" type="multiScanRegistration" name="multiScanRegistration" output="screen">
    <param name="lidar" value="$(arg lidartype)" /> <!-- options: VLP-16  HDL-32  HDL-64E RS-32 RS-16 -->
    <param name="scanPeriod" value="$(arg scanPeriod)" />

    <remap from="/multi_scan_points" to="/rslidar_points" />
    <remap from="/imu/data"  to="/mobile_base/sensors/imu_data" />
  </node>

  <node pkg="loam_velodyne" type="laserOdometry" name="laserOdometry" output="screen" respawn="true">
    <param name="scanPeriod" value="$(arg scanPeriod)" />
  </node>

  <node pkg="loam_velodyne" type="laserMapping" name="laserMapping" output="screen">
    <param name="scanPeriod" value="$(arg scanPeriod)" />
    <remap from="/imu/data"  to="/mobile_base/sensors/imu_data" />
  </node>

  <node pkg="loam_velodyne" type="transformMaintenance" name="transformMaintenance" output="screen">
  </node>

  <group if="$(arg rviz)">
    <node launch-prefix="nice" pkg="rviz" type="rviz" name="rviz" args="-d $(find loam_velodyne)/rviz_cfg/loam_velodyne.rviz" />
  </group>

</launch>

新建rslidar_rviz.launch启动rviz显示界面

<launch>
  <node launch-prefix="nice" pkg="rviz" type="rviz" name="rviz" args="-d $(find loam_velodyne)/rviz_cfg/loam_velodyne.rviz" />
</launch>

1.4建图

  • 离线建图
roscore
roslaunch loam_velodyne loam_rslidar.launch
# 播放
rosbag play ###.bag
rosbag play -s 50 ###.bag  时间段
roslaunch loam_velodyne rslidar_rviz.launch
  • 实时建图:
roslaunch rslidar_pointcloud rs_lidar_16.launch
roslaunch loam_velodyne loam_rslidar.launch
roslaunch loam_velodyne rslidar_rviz.launch

1.5 查看并保存LOAM的三维点云地图

在建图过程中执行, 来录制 loam 后生成的地图。点云话题是 laser_cloud_surround
录好之后 ctrl+c 结束, my_loam.bag 是录好之后的包的名字。

 rosbag record -o myloam.bag out /laser_cloud_surround

将 bag 文件转换成 pcd 文件:

rosrun pcl_ros bag_to_pcd myloam.bag /laser_cloud_surround my_loam_pcd

my_loam_pcd 是转换成 pcd 的文件夹名字。获取的 pcd 文件是很多个,每一个 pcd 是一
帧数据。可以通过 pcl_viewer 命令查看 pcd 格式的最后一个文件:

pcl_viewer ###.pcd

2 A-LOAM建图

roslaunch aloam_velodyne aloam_velodyne_VLP_16.launch 
rosbag play 2021-10-12-09-27-52.bag  --clock /rslidar_points:=/velodyne_points
#地图录制
 rosbag record -o aloam /laser_cloud_map

3 LeGO-LOAM建图

3.1 安装gtsam

git clone https://bitbucket.org/gtborg/gtsam.git
cd gtsam
mkdir build
cd build
cmake ..
sudo make install

3.2 LeGO-LOAM安装

cd catkin_jt/src
git clone https://github.com/RobustFieldAutonomyLab/LeGO-LOAM.git
cd ..
catkin_make 

编译报错:
/usr/local/lib/cmake/GTSAM/GTSAMConfig.cmake:17 行的find_dependency改成find_package。具体操作:

cd /usr/local/lib/cmake/GTSAM/
sudo chmod a+w GTSAMConfig.cmake
gedit GTSAMConfig.cmake

重新编译

3.3 运行

roslaunch lego_loam run.launch
rosbag play *.bag --clock --topic /velodyne_points

注:

  • 1 参数“/ use_sim_time”,对于模拟则设置为“true”,对于使用真实机器人则设置为“false”。
  • 2 RS-LIDAR-16默认发布的 topic 为/rslidar_points,而LeGO-LOAM需要订阅的 topic 为/velodyne_points,因此使用以下命令:
rosbag play *.bag --clock /rslidar_points:=/velodyne_points
  • 3 或者修改雷达发布的话题,convert.cc中output_points_topic由rslidar_points改为velodyne_points
  • 4 使用速腾聚创时在rslidar的launch文件内添加一个映射,将rslidar_points修改为velodyne_points。在legoloam的launch文件内添加rslidar和base_link这两个frame的tf转换,即:
 <node pkg="tf" type="static_transform_publisher" name="base_link_to_rslidar" args="0 0 0 -1.570795 -1.570795 0        /rslidar /base_link   10" />
  • 5 由于RS16的输出有NaN points ,需要自己利用pcl函数进行过滤,在launch文件中加入:
<launch>
    <param name="/use_sim_time" value="true" />
   <node pkg="nodelet" type="nodelet" name="pcl_manager" args="manager" output="screen" />

  <!-- Run a passthrough filter to clean NaNs -->
  <node pkg="nodelet" type="nodelet" name="passthrough" args="load pcl/PassThrough pcl_manager" output="screen">
    <remap from="~input" to="/rslidar_points" />
    <remap from="/passthrough/output" to="/velodyne_points" />
    
    <rosparam>
      filter_field_name: z
      filter_limit_negative: True
    </rosparam>

   <rosparam>
      filter_field_name: x
      filter_limit_negative: True
    </rosparam>

   <rosparam>
      filter_field_name: y
      filter_limit_negative: True
    </rosparam>
  </node>
</launch>
  • 6 最后run.launch文件内容为:
 -`<launch>
    
    <!--- Sim Time -->
    <param name="/use_sim_time" value="false" />
    <node pkg="nodelet" type="nodelet" name="pcl_manager" args="manager" output="screen" />
    
    <!-- Run a passthrough filter to clean NaNs -->
    <node pkg="nodelet" type="nodelet" name="passthrough" args="load pcl/PassThrough pcl_manager" output="screen">
    <remap from="~input" to="/rslidar_points" />
    <remap from="/passthrough/output" to="/velodyne_points" />
    
    <rosparam>
      filter_field_name: z
      filter_limit_negative: True
    </rosparam>
 
    <rosparam>
      filter_field_name: x
      filter_limit_negative: True
    </rosparam>
 
    <rosparam>
      filter_field_name: y
      filter_limit_negative: True
    </rosparam>
   </node>
 
    <!--- Run Rviz-->
    <node pkg="rviz" type="rviz" name="rviz" args="-d $(find lego_loam)/launch/test.rviz" />
 
    <!--- TF -->
    <node pkg="tf" type="static_transform_publisher" name="camera_init_to_map"  args="0 0 0 1.570795   0        1.570795 /map    /camera_init 10" />
    <node pkg="tf" type="static_transform_publisher" name="base_link_to_camera" args="0 0 0 -1.570795 -1.570795 0        /camera /base_link   10" />
    <node pkg="tf" type="static_transform_publisher" name="base_link_to_rslidar" args="0 0 0 -1.570795 -1.570795 0        /rslidar velodyne   10" />

    <!--- LeGO-LOAM -->    
    <node pkg="lego_loam" type="imageProjection"    name="imageProjection"    output="screen"/>
    <node pkg="lego_loam" type="featureAssociation" name="featureAssociation" output="screen"/>
    <node pkg="lego_loam" type="mapOptmization"     name="mapOptmization"     output="screen"/>
    <node pkg="lego_loam" type="transformFusion"    name="transformFusion"    output="screen"/>

</launch>`

录制数据包运行:

roslaunch lego_loam run.launch
rosbag play 2021-09-30-08-09-02.bag  --clock /rslidar_points:=/velodyne_points --loop

运行时提醒没有ring channel,是因为elodyne有单独的ring通道,rslidar没有,所以关闭该功能,打开include/utility.h文件,将useCloudRing关闭:

extern const bool useCloudRing = false

3.4实时运行

将launch文件中的true改为false:

<param name="/use_sim_time" value="false" />

将速腾的驱动的launch文件加入映射:

<remap from="/rslidar_points" to="/velodyne_points" />

先运行雷达的launch,在运行legoloam的launch

3.5 保存地图

点云输出在 /laser_cloud_surround Topic上 PointCloud2类型,在终端窗口,键入ctrl+c退出程序后,在/tmp目录下会生成4个pcd文件,分别为:

  • finalCloud.pcd
  • cornerMap.pcd
  • surfaceMap.pcd
  • trajectory.pcd

/tmp目录下的文件在每次重启后都会被清空,如果想保存在其他路径下,需要在mapOptmization.cpp中的visualizeGlobalMapThread函数中修改路径

// save final point cloud
pcl::io::savePCDFileASCII(fileDirectory+"finalCloud.pcd", *globalMapKeyFramesDS);

string cornerMapString = "/tmp/cornerMap.pcd";
string surfaceMapString = "/tmp/surfaceMap.pcd";
string trajectoryString = "/tmp/trajectory.pcd";

无法保存的问题:
当bag播放完毕后,在rviz中勾选Map Cloud,然后按ctrl+c退出程序,最终可以在/tmp目录下生成四个pcd文件。

这个问题是代码更新导致的,具体为https://github.com/RobustFieldAutonomyLab/LeGO-LOAM/blob/master/LeGO-LOAM/launch/test.rvizMap Cloud由默认的勾选变成不勾选

在终端执行以下命令,可以打印pose,第二个保存pose到pose.txt中

rostopic echo /aft_mapped_to_init
rostopic echo /aft_mapped_to_init > pose.txt

3.6 地图保存2

step1: 记录话题 /laser_cloud_surround 数据,这个可以在快结束的时候录制

rosbag record -o lego-loam-out /laser_cloud_surround

step2: 把 lego-loam-out* 这个bag的话题上的数据存为pcd文件

rosrun pcl_ros bag_to_pcd lego-loam-out_2021-02-01-17-01-06.bag /laser_cloud_surround test

4 SC-LeGO-LOAM

roslaunch lego_loam run.launch 

注:修改文件run.launch utility.h

5 SC-A-LOAM

6 LIO-SAM

7 SC-LIO-SAM

### LOAM实现原理 LOAM(Lidar Odometry and Mapping)是一种基于激光雷达的里程计和地算法,其核心思想是通过提取特征点并利用这些特征点来估计传感器的姿态变化以及构环境的地。以下是关于LOAM的核心实现原理: #### 特征点提取 LOAM主要依赖于两种类型的特征点:边缘点和平面点。边缘点是从物体边界处提取出来的稀疏点云数据,而平面点则是从平滑表面上提取的数据[^2]。 #### 数据分割与配准 为了减少计算量,LOAM将一帧点云分为多个子区域,并分别处理每个子区域中的点云数据。这种分块策略有助于提高实时性能。随后,通过对当前帧与前一帧之间的特征点进行匹配,完成初始姿态估计[^1]。 #### 非线性优化 LOAM采用Levenberg-Marquardt方法对初步估计的结果进一步精化。具体来说,它最小化了两帧之间对应特征点的距离误差。这一过程涉及到复杂的数学运算,包括雅克比矩阵的手动推导。 ### A-LOAM改进之处 相比原始版LOAM,A-LOAM做了以下几点重要改动: - **去除了IMU接口**:这使得A-LOAM更加独立于其他传感器输入。 - **引入Ceres Solver**:用于替代手动推导的ICP优化流程,从而提升了代码可维护性和易理解程度。尽管如此,由于采用了数值求导而非解析形式,可能会稍微影响运行速度。 ### 示例代码片段展示如何初始化Ceres solver 进行LM优化: ```cpp ceres::Problem problem; // 添加残差项到problem对象中... for (size_t i = 0; i < residuals.size(); ++i) { ceres::CostFunction* cost_function = LidarEdgeFactor::Create(residuals[i]); problem.AddResidualBlock(cost_function, nullptr, parameters); } ceres::Solver::Options options; options.linear_solver_type = ceres::DENSE_QR; options.minimizer_progress_to_stdout = true; ceres::Solver::Summary summary; ceres::Solve(options, &problem, &summary); std::cout << summary.FullReport() << "\n"; ``` 上述代码展示了如何设置一个基本的Ceres optimization问题实例,并调用`ceres::Solve()`执行实际最优化操作。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值