欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > ROS2移植【激光点云】(hdl_localization)

ROS2移植【激光点云】(hdl_localization)

2025/6/20 16:11:11 来源:https://blog.csdn.net/2201_75436278/article/details/148776174  浏览:    关键词:ROS2移植【激光点云】(hdl_localization)

### 移植源码:koide3/hdl_localization: Real-time 3D localization using a (velodyne) 3D LIDAR

### 移植后的代码:https://github.com/XzLuckh/hdl_localization

一、ROS2介绍

        ROS 1 和 ROS 2 是机器人操作系统(Robot Operating System)的两个主要版本,ROS 2 是对 ROS 1 的全面升级,解决了 ROS 1 的许多架构缺陷,并引入了现代机器人开发所需的新特性。下面对ROS1和ROS2进行对比:

ROS1

ROS2

通信机制

依赖 Master,TCPROS

DDS,去中心化

实时性

较差

支持 QoS,更实时

跨平台

主要 Linux

Linux/Windows/macOS/RTOS

编程语言

C++03/Python 2

C++17/Python 3

构建系统

catkin

ament/colcon

我在ROS1中部署了该项目,实现效果如下:

二、hdl_localization代码移植

首先得安装一个ROS2系统(可参考以下博客):

Ubuntu安装ROS(2) —— 安装ROS2 humble(最新、超详细图文教程,包含配置rosdep)_ros2安装-CSDN博客

首先查看hdl_localization包的结构,直接查看其CMakeLists.txt文件

我们需要在ROS2 系统中创建一个新的工作空间

mkdir -p ros2_ws_test/src

将hdl_localization项目克隆到src文件目录下

git clone https://github.com/koide3/hdl_localization

        准备工作完成后,首先应该对CMakeLists.txt文件进行修改。下面先给出ROS1和ROS2的主要区别。

        ROS1与ROS2的CMakeLists.txt文件在构建系统设计上存在显著差异,主要体现在架构理念和实现方式上。ROS1基于传统的catkin构建系统,采用集中式的依赖管理方式,通过catkin_package()宏统一处理包信息和依赖关系,其语法相对简单但灵活性较低。而ROS2采用现代化的ament_cmake构建系统,遵循更模块化的设计原则,每个依赖项需独立声明,使用面向目标的现代CMake特性(如命名空间目标和接口库),使得依赖关系更清晰、包隔离性更好。在安装部署方面,ROS2简化了安装规则但增加了导出控制的显式声明,同时引入标准化的测试框架集成方式。这些改进使ROS2的构建系统在跨平台支持、依赖管理和可维护性方面具有明显优势,但也要求开发者掌握更复杂的CMake编写规范。总体而言,从ROS1到ROS2的CMake配置转变反映了构建系统从简单统一向灵活精确的设计演进趋势。

        基础框架对比:

        ROS1

cmake_minimum_required(VERSION 2.8.3)
project(my_pkg)find_package(catkin REQUIRED COMPONENTSroscppstd_msgs
)catkin_package()

        ROS2

cmake_minimum_required(VERSION 3.5)
project(my_pkg)find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)ament_package()

        对于package.xml:ROS1 采用分层次的依赖声明(如 build_depend、exec_depend),需单独处理消息生成的编译/运行时依赖(message_generation 和 message_runtime),格式支持 version 1 或 2;而 ROS2 强制使用 version 3 格式,大幅简化依赖分类,用统一的 <depend> 替代 ROS1 的多类依赖,合并消息生成工具为 rosidl_default_generators,并强制显式声明构建工具(如 ament_cmake)。此外,ROS2 更频繁使用 <export> 标签定义组件插件,体现其模块化设计理念。这些改动使 ROS2 的依赖管理更简洁,但要求更严格的规范遵循。

        依赖包的区别

ROS1ROS2

find_package(catkin REQUIRED COMPONENTS

  nodelet

  tf2

  tf2_ros

  tf2_eigen

  tf2_geometry_msgs

  eigen_conversions

  pcl_ros

  roscpp

  rospy

  sensor_msgs

  geometry_msgs

  message_generation

  ndt_omp

  fast_gicp

  hdl_global_localization

)

find_package(rclcpp REQUIRED)

find_package(rcl REQUIRED)

find_package(std_msgs REQUIRED)

find_package(sensor_msgs REQUIRED)

find_package(geometry_msgs REQUIRED)

find_package(tf2 REQUIRED)

find_package(tf2_ros REQUIRED)

find_package(tf2_eigen REQUIRED)

find_package(tf2_geometry_msgs REQUIRED)

find_package(pluginlib REQUIRED)

find_package(pcl_conversions REQUIRED)

find_package(statistics_msgs REQUIRED)

        rclcpp 替代了 roscpp 作为 C++ 客户端库,tf2 系列包(如 tf2_ros)在 ROS2 中保留了相同功能但实现更现代化,而 pluginlib 仍然用于插件机制但集成更标准化。此外,ROS2 新增了 rcl 作为底层客户端库,不再需要 message_generation,并将 nodelet 替换为 Component 机制。对于点云处理,pcl_ros 的功能在 ROS2 中主要通过 pcl_conversions 和原生 PCL 实现。整体上,ROS2 的依赖管理更模块化,许多 ROS1 包在 ROS2 中仍保持同名但接口可能略有调整,部分功能包(如 ndt_omp)则需要寻找 ROS2 兼容版本或自行移植。

        下面给出部分ROS2版本的CMakeLists.txt文件代码:

        然后对package.xml进行修改

        对于hdl_localization包中的.msg文件,ROS2与ROS1不同:

  • ROS 1 允许将 .msg 文件放在功能包的 msg/ 目录下,通过 add_message_files() 生成。
  • ROS 2 要求自定义消息必须放在 独立的接口包(如 ros2_msgs)中,通过 rosidl_generate_interfaces() 生成。

        因此需要在ROS2中创建一个ros2_msgs接口包。

        ros2_msg编译成功

        接下来要对cpp文件进行修改:

1.头文件更改

        #include <ros/ros.h>       改为       #include "rclcpp/rclcpp.hpp"

        #include<ros/time.h>      改为       #include "rclcpp/time.hpp"

        #include <pcl_ros/point_cloud.h>  

改为:

        #include <pcl_conversions/pcl_conversions.hpp>  // 用于PCL和ROS2消息的转换

        #include <sensor_msgs/msg/point_cloud2.hpp>     // ROS2的PointCloud2消息

2. 显式转换

        ROS1的pcl_ros/point_cloud.h 定义了pcl::Pointcloud<T>到sensor_msgs::PointCloud2的便捷转换,而 ROS2 需要显式转换:

ROS1风格:

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::Pointcloud<pcl::PointXYZ>);
sensor_msgs::PointCloud2 output;
pcl::toROSMsg(*cloud, output):

ROS2风格:

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl: :PointXYZ>);
auto output = std::make_shared<sensor_msgs::msg::Pointcloud2>();
pcl::toRoSMsg(*cloud, *output);

3. 更换时间API

        hd1_1ocalization 中的代码使用了ROS 1的时间API(ros::Time),但ROS 2中使用的是rclcpp::Time ,API有所不同

        替换所有的time.is_zero()为:time == rclcpp::Time(0, 0, time.get_clock_type())

        替换所有的duration.toSec()为:duration.seconds()

ROS1和ROS2的启动launch文件也存在较大的差异:

        ROS1的.launch文件是基于XML格式,使用<launch>作为根标签,通过标签定义节点和参数。典型示例如下:

<launch><node pkg="turtlesim" type="turtlesim_node" name="sim"/><node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen"/><param name="scale_linear" value="2" type="double"/><param name="scale_angular" value="2" type="double"/><rosparam file="$(find pkg)/config/params.yaml" command="load"/>
</launch>

        ROS2的launch.py文件是基于Python脚本使用LaunchDescription类,通过函数和对象定义启动行为。典型示例如下:

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='turtlesim',executable='turtlesim_node',name='sim'),Node(package='turtlesim',executable='turtle_teleop_key',name='teleop',output='screen')])

        所有的cpp文件和hpp文件修改完成后,还需要修改对应的CMakeList.txt和Package.xml文件然后对工作空间进行编译。在此编译过程间会遇到很多报错问题,需要逐个解决,这里没有记录,不再叙述。

        最终改完所有报错信息。如上图所示,编译成功

        导入data/map.pcd文件启动rviz,如下图所示(应该是移植成功):

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词