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数据的源码,里面涉及到坐标系转换