ROS2开发|将Pointcloud2数据

描述

我的点云数据发布在"map"坐标系下,我想把这个pointcloud2数据变化至"base_link"坐标系。

解决办法

方法一

找到tf关系,然后调用doTransform函数

#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/point_cloud2.hpp"
#include "geometry_msgs/msg/transform_stamped.hpp"

#include <tf2/transform_datatypes.h>
#include <tf2/utils.h>
#include "tf2_ros/buffer.h"
#include <tf2_sensor_msgs/tf2_sensor_msgs.h> //for tf transform
#include "tf2_ros/transform_listener.h"

....
auto tf_buffer =
      std::make_unique<tf2_ros::Buffer>(this->get_clock());
  auto in = std::make_shared<sensor_msgs::msg::PointCloud2>(); //输入点云
 auto out = std::make_shared<sensor_msgs::msg::PointCloud2>(); //输出点云
 
  
  geometry_msgs::msg::TransformStamped transformStamped;
  try {
    transformStamped = tf_buffer->lookupTransform(
        "base_link", in->header.frame_id, tf2::TimePointZero); 
  } catch (tf2::TransformException &ex) {
      SPDLOG_ERROR("{}", ex.what());
      return;
  }
  tf2::doTransform(*in, *out, transformStamped);

CMAKE文件需要

find_package(catkin REQUIRED COMPONENTS
  rclcpp
  tf2
  tf2_ros
  tf2_sensor_msgs
  geometry_msgs
  sensor_msgs
)

 target_link_libraries(your_node_name
    ${catkin_LIBRARIES}
)

方法二

更简单的方法时=是直接调用tf_bugger的transform函数

auto tf_buffer =
      std::make_unique<tf2_ros::Buffer>(this->get_clock());
  auto in = std::make_shared<sensor_msgs::msg::PointCloud2>(); //输入点云
 auto out = std::make_shared<sensor_msgs::msg::PointCloud2>(); //输出点云
  tf_buffer->transform(*in, *out, "base_link", tf2::durationFromSec(0.1));
  

方法三

PCL-ROS包里也有坐标系变换的功能,我没有仔细研究。感兴趣的同学可以下载源码研究一下
pcl_ros源码

遇到的问题

如果遇到了“未定义的引用“和"undefined reference to "之类的错误,大概率是tf2_sensor_msgs没有引入
在代码中加入

#include <tf2_sensor_msgs/tf2_sensor_msgs.h>```

并在CMAKELIST和package文件里添加tf2_sensor_msgs依赖就可以了

参考连接

ROS论坛里 有个哥们遇到和我一样的问题 参考他的解决办法
一些tf2的小例子
官方关于TF2的教程
官方开发的POINTCLOUD2数据转laserscan数据的源码,里面涉及到坐标系转换