1. 项目背景与挑战
去年在ROS1上跑通的A-LOAM算法,最近需要迁移到ROS2 Humble版本上。这个看似简单的版本升级,实际踩坑无数。作为激光SLAM领域的经典算法实现,A-LOAM(Advanced LiDAR Odometry and Mapping)在ROS1时代已经相当成熟,但ROS2的架构变革让整个移植过程变成了一场硬仗。
最核心的痛点在于:ROS2彻底重构了通信机制。原先ROS1的topic通信是中心化的,而ROS2采用了DDS(Data Distribution Service)作为底层通信中间件。这意味着所有与消息收发相关的代码都需要重写,包括:
- 消息类型的API变更(比如Header变成了std_msgs/msg/Header)
- 回调函数接口的变化(从boost::function变成std::function)
- 时间API的差异(ros::Time变成rclcpp::Time)
2. 环境准备与依赖处理
2.1 基础环境配置
首先需要准备ROS2 Humble的标准环境:
# 设置locale sudo apt update && sudo apt install locales sudo locale-gen en_US en_US.UTF-8 sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 export LANG=en_US.UTF-8 # 添加ROS2仓库 sudo apt install software-properties-common sudo add-apt-repository universe sudo apt update && sudo apt install curl sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null # 安装完整版ROS2 sudo apt update sudo apt install ros-humble-desktop2.2 关键依赖项处理
A-LOAM在ROS2中需要特别注意这些依赖:
- PCL库:必须使用1.12版本以上,否则会与ROS2的tf2产生兼容性问题
sudo apt install libpcl-dev ros-humble-pcl-conversions- Eigen3:建议源码安装3.4.0以上版本
git clone https://gitlab.com/libeigen/eigen.git cd eigen && mkdir build && cd build cmake .. && make -j8 sudo make install- Ceres Solver:需要手动编译支持Suitesparse的版本
sudo apt install libsuitesparse-dev git clone https://ceres-solver.googlesource.com/ceres-solver cd ceres-solver && mkdir build && cd build cmake -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF .. make -j8 && sudo make install3. 核心代码迁移实战
3.1 消息接口改造
原ROS1代码中的传感器消息订阅需要全面重写。以激光雷达消息为例:
// ROS1旧代码 ros::Subscriber subLaserCloud = nh.subscribe<sensor_msgs::PointCloud2>( "/velodyne_points", 100, &LaserProcessingClass::handler, this); // ROS2新代码 auto subLaserCloud = this->create_subscription<sensor_msgs::msg::PointCloud2>( "/velodyne_points", 10, std::bind(&LaserProcessingClass::handler, this, std::placeholders::_1));关键变化点:
- 消息类型从
sensor_msgs::PointCloud2变为sensor_msgs::msg::PointCloud2 - 回调函数从boost绑定变为std::bind
- QoS配置需要显式声明(示例中使用默认配置)
3.2 TF系统迁移
ROS2的tf2使用方式有重大变化:
// ROS1旧代码 tf::StampedTransform transform; listener.lookupTransform("/map", "/laser", ros::Time(0), transform); // ROS2新代码 geometry_msgs::msg::TransformStamped transform; try { transform = tf_buffer_->lookupTransform( "map", "laser", this->now(), rclcpp::Duration::from_seconds(0.1)); } catch (tf2::TransformException &ex) { RCLCPP_WARN(this->get_logger(), "%s", ex.what()); return; }注意事项:
- 必须使用
tf2_ros::Buffer替代原来的tf::TransformListener - 时间戳获取从
ros::Time::now()变为this->now() - 异常处理更加严格,必须捕获
tf2::TransformException
4. 性能优化与调试
4.1 多线程处理优化
ROS2的executor机制可以显著提升性能:
// 单线程执行器(默认) rclcpp::executors::SingleThreadedExecutor executor; // 多线程执行器(推荐) rclcpp::executors::MultiThreadedExecutor executor( rclcpp::ExecutorOptions(), 4); // 使用4个线程 executor.add_node(node); executor.spin();实测数据对比:
| 配置 | 平均处理延迟 | CPU利用率 |
|---|---|---|
| 单线程 | 23ms | 25% |
| 4线程 | 8ms | 68% |
4.2 点云处理加速
使用OpenMP并行化关键算法:
#pragma omp parallel for for (size_t i = 0; i < cloud->points.size(); ++i) { // 点云特征计算... }编译时需要开启OpenMP支持:
find_package(OpenMP REQUIRED) target_link_libraries(your_target PRIVATE OpenMP::OpenMP_CXX)5. 常见问题解决方案
5.1 TF时间同步问题
症状:控制台不断输出"Lookup would require extrapolation into the past"警告
解决方案:
- 检查所有节点的系统时间是否同步
sudo apt install chrony sudo service chrony restart- 增加tf2缓存时间
tf_buffer_ = std::make_shared<tf2_ros::Buffer>( this->get_clock(), tf2::durationFromSec(10.0)); // 将缓存时间从默认3秒延长到10秒5.2 点云数据丢失
症状:回调函数接收到的点云消息frame_id为空
排查步骤:
- 检查原始传感器驱动是否适配ROS2
- 确认remap是否正确:
<node pkg="pointcloud_to_laserscan" exec="pointcloud_to_laserscan_node"> <remap from="cloud_in" to="/velodyne_points"/> </node>- 使用ros2 topic echo检查原始消息是否完整
6. 实机测试验证
最终在Velodyne VLP-16上的测试结果:
| 指标 | ROS1 Noetic | ROS2 Humble |
|---|---|---|
| 建图精度(RMSE) | 0.32m | 0.28m |
| 里程计漂移(/100m) | 1.2m | 0.8m |
| CPU占用率 | 45% | 62% |
| 内存占用 | 1.8GB | 2.3GB |
虽然资源占用有所增加,但精度和实时性都有提升。建议在性能足够的设备上使用ROS2版本,对于资源受限场景可以适当降低点云采样频率。