LIO-SAM多节点并行改造方案与ROS命名空间实践

发布时间:2026/11/4 13:05:55
LIO-SAM多节点并行改造方案与ROS命名空间实践

1. 项目背景与需求分析

在机器人SLAM(即时定位与地图构建)领域,LIO-SAM作为基于激光雷达-惯性测量单元紧耦合的先进算法,因其高精度和鲁棒性被广泛应用于自动驾驶、移动机器人导航等场景。但在实际部署中,我们常遇到一个关键限制:原生代码架构默认只允许单个节点在ROS master上运行,这在多机器人协同或算法对比测试时会造成严重制约。

上周我在部署一个多AGV仓储系统时就遇到了这个问题——需要同时运行三个LIO-SAM节点分别处理不同区域的建图数据。直接启动多个节点会导致参数命名冲突和话题抢占,最终系统崩溃。经过两天源码级调试,我总结出一套完整的改造方案,现在分享给遇到同样困境的同仁们。

2. 核心问题拆解

2.1 原生代码的限制机制

通过分析LIO-SAM的utility.h和run.launch文件,发现其硬编码了以下关键元素:

  • 所有节点的默认名称空间(namespace)均为/根目录
  • 话题名称如/odometry/imu、/lio_sam/mapping/odometry等未做隔离
  • 参数服务器中的参数键名如lio_sam/useImuHeadingInitialization全局唯一

这种设计在单节点运行时完全合理,但当第二个节点启动时:

  1. 相同名称的节点会互相覆盖
  2. 话题订阅/发布产生冲突
  3. 参数服务器键值被重复写入

2.2 多节点运行的技术需求

要实现安全的多实例并行,必须确保每个节点拥有:

  • 独立的ROS命名空间(namespace)
  • 隔离的话题通信通道
  • 专属的参数存储区域
  • 不冲突的TF帧命名

3. 代码改造方案

3.1 命名空间动态化改造

修改launch/run.launch文件,增加namespace参数:

<launch> <arg name="robot_ns" default="robot1" /> <group ns="$(arg robot_ns)"> <node pkg="lio_sam" type="lio_sam_imuPreintegration" name="imuPreintegration" output="screen" /> <!-- 其他节点同理 --> </group> </launch>

对应的C++代码中需要调整话题订阅:

// 原代码 ros::Subscriber subImu = nh.subscribe<sensor_msgs::Imu>("imu_correct", 200, &IMUPreintegration::imuHandler, this); // 修改为 ros::Subscriber subImu = nh.subscribe<sensor_msgs::Imu>("imu_correct", 200, &IMUPreintegration::imuHandler, this, ros::TransportHints().tcpNoDelay());

3.2 参数隔离方案

在config/params.yaml中采用分层参数结构:

robot1: lio_sam: useImuHeadingInitialization: true imuTopic: "imu_correct" robot2: lio_sam: useImuHeadingInitialization: false imuTopic: "imu_raw"

代码中通过ros::param::get("/robot1/lio_sam/useImuHeadingInitialization", useImuHeadingInitialization)方式读取。

3.3 TF帧命名冲突解决

修改include/utility.h中的帧定义:

#define MAP_FRAME (robot_ns + "/map") #define ODOM_FRAME (robot_ns + "/odom") #define BASE_FRAME (robot_ns + "/base_link")

4. 完整实施步骤

4.1 基础改造流程

  1. 备份原项目代码
  2. 修改所有launch文件,添加namespace参数
  3. 更新utility.h中的帧命名逻辑
  4. 重构参数配置文件结构
  5. 调整所有话题订阅/发布的代码段

4.2 多节点启动示例

# 终端1 roslaunch lio_sam run.launch robot_ns:=agv1 # 终端2 roslaunch lio_sam run.launch robot_ns:=agv2

此时可以通过rostopic list查看到隔离的话题:

/agv1/lio_sam/mapping/odometry /agv2/lio_sam/mapping/odometry

5. 关键问题与解决方案

5.1 TF树冲突处理

当多个节点发布相同父子关系的TF时,需要在rviz中配置显示过滤器:

<rviz> <Display type="TF" enabled="true"> <frame names="agv1/map agv1/odom agv1/base_link"/> </Display> </rviz>

5.2 资源占用优化

每个节点会独立加载点云地图,建议:

  • 共享静态层地图(通过/agv1/map话题转发)
  • 调整voxel_filter参数降低计算负载
  • 为每个节点分配固定CPU核心

6. 性能实测数据

在Intel NUC11上测试结果:

节点数CPU占用内存占用建图延迟
178%2.3GB120ms
2142%4.1GB135ms
3210%6.8GB155ms

提示:当运行超过3个节点时,建议禁用各节点的可视化模块以节省资源

7. 扩展应用场景

这套改造方案不仅适用于LIO-SAM,还可应用于:

  • 多机器人协同建图
  • 算法不同参数配置的对比测试
  • 传感器数据的分通道处理
  • 教学演示中的多案例并行展示

我在实际项目中验证过,配合namespace和remap技术,甚至可以实现不同版本算法的AB测试。比如同时运行改进前后的LIO-SAM节点,实时对比建图效果差异。