ROS TF2 :通过tf2_ros::MessageFilter 将世界坐标系下的点转为期望坐标系下的点

本文涉及的产品
资源编排,不限时长
简介: ROS TF2 :通过tf2_ros::MessageFilter 将世界坐标系下的点转为期望坐标系下的点

本片博客描述:如何使用 tf2_ros::MessageFilter 处理 Stamped(时间戳) 数据类型

在 TF2 的 体系下 如何使用传感器的数据

在 实际 情况下 传感器的数据包括: 相机、激光雷达

1、情景

假设一只新的乌龟 命名为 乌龟3 , 它没有好的里程计(也就是说不指定它的具体坐标),但是现在有一个上方的相机 跟踪 它的位置并且发布 相对与 世界坐标系 下的 位置信息 ( PointStamped 类型的 topic)

乌龟1 想要知道 乌龟3 相对自己的位置

为此,turtle1必须监听正在发布turtle3位置的topic,直到准备好转换为期望坐标系下,然后进行操作。

做这件事的话,使用 tf2_ros::MessageFilter 类 非常有用

tf2_ros :: MessageFilter将使用标头对任何ros消息进行订阅,并将其缓存,直到可以将其转换为期望坐标系下为止。

2、实现代码

#include "ros/ros.h"
#include "geometry_msgs/PointStamped.h"

#include "tf2_ros/transform_listener.h"
#include "tf2_ros/message_filter.h"
#include "message_filters/subscriber.h"
#include "tf2_geometry_msgs/tf2_geometry_msgs.h"

class PoseDrawer
{
public:
  PoseDrawer() :
    tf2_(buffer_),  target_frame_("turtle1"),
    tf2_filter_(point_sub_, buffer_, target_frame_, 10, 0)
  {
    point_sub_.subscribe(n_, "turtle_point_stamped", 10);
    tf2_filter_.registerCallback( boost::bind(&PoseDrawer::msgCallback, this, _1) );
  }

  //  Callback to register with tf2_ros::MessageFilter to be called when transforms are available
  void msgCallback(const geometry_msgs::PointStampedConstPtr& point_ptr) 
  {
    geometry_msgs::PointStamped point_out;
    try 
    {
      buffer_.transform(*point_ptr, point_out, target_frame_);
      
      ROS_INFO("point of turtle 3 in frame of turtle 1 Position(x:%f y:%f z:%f)\n", 
             point_out.point.x,
             point_out.point.y,
             point_out.point.z);
    }
    catch (tf2::TransformException &ex) 
    {
      ROS_WARN("Failure %s\n", ex.what()); //Print exception which was caught
    }
  }

private:
  std::string target_frame_;
  tf2_ros::Buffer buffer_;
  tf2_ros::TransformListener tf2_;
  ros::NodeHandle n_;
  message_filters::Subscriber<geometry_msgs::PointStamped> point_sub_;
  tf2_ros::MessageFilter<geometry_msgs::PointStamped> tf2_filter_;

};


int main(int argc, char ** argv)
{
  ros::init(argc, argv, "pose_drawer"); //Init ROS
  PoseDrawer pd; //Construct class
  ros::spin(); // Run until interupted 
  return 0;
};

3、代码解释

=============================================================

#include "ros/ros.h"
#include "geometry_msgs/PointStamped.h"

#include "tf2_ros/transform_listener.h"
#include "tf2_ros/message_filter.h"
#include "message_filters/subscriber.h"
#include "tf2_geometry_msgs/tf2_geometry_msgs.h"

首先时包含 tf2_ros::MessageFilter 的头文件 和其它头文件

===============================================================

private:
  std::string target_frame_;
  tf2_ros::Buffer buffer_;
  tf2_ros::TransformListener tf2_;
  ros::NodeHandle n_;
  message_filters::Subscriber<geometry_msgs::PointStamped> point_sub_;
  tf2_ros::MessageFilter<geometry_msgs::PointStamped> tf2_filter_;

类的私有变量

tf2_ros::Buffer
tf2_ros::TransformListener
tf2_ros::MessageFilter
这三个要在构造函数时初始化 使数据一直被保持

====================================================================

  PoseDrawer() :
    tf2_(buffer_),  target_frame_("turtle1"),
    tf2_filter_(point_sub_, buffer_, target_frame_, 10, 0)
  {
    point_sub_.subscribe(n_, "turtle_point_stamped", 10);
    tf2_filter_.registerCallback( boost::bind(&PoseDrawer::msgCallback, this, _1) );
  }

启动ros message_filters :: Subscriber时必须使用该主题进行初始化。 并且tf2_ros :: MessageFilter必须使用该Subscriber对象进行初始化。 MessageFilter构造函数中需要注意的其他参数是target_frame和回调函数。 目标框架是确保canTransform成功执行的框架。 回调函数是在数据准备好后将被调用的函数。

=======================================================================

  //  Callback to register with tf2_ros::MessageFilter to be called when transforms are available
  void msgCallback(const geometry_msgs::PointStampedConstPtr& point_ptr) 
  {
    geometry_msgs::PointStamped point_out;
    try 
    {
      buffer_.transform(*point_ptr, point_out, target_frame_);
      
      ROS_INFO("point of turtle 3 in frame of turtle 1 Position(x:%f y:%f z:%f)\n", 
             point_out.point.x,
             point_out.point.y,
             point_out.point.z);
    }
    catch (tf2::TransformException &ex) 
    {
      ROS_WARN("Failure %s\n", ex.what()); //Print exception which was caught
    }
  }

tf2_ros::MessageFilter 的 回调函数

buffer_.transform(*point_ptr, point_out, target_frame_);

通过这个函数(就是tf2_ros::TransformListener的一个功能函数) 将 在 世界坐标系的 点 转化为 期望坐标系 下的点

4、 疑问

上面通过 tf2_ros::MessageFilter 的 方式 和 直接订阅 位置信息 然后 通过tf2_ros::TransformListener的transform功能函数去结算 这两者有什么区别呢?

相关实践学习
使用ROS创建VPC和VSwitch
本场景主要介绍如何利用阿里云资源编排服务,定义资源编排模板,实现自动化创建阿里云专有网络和交换机。
阿里云资源编排ROS使用教程
资源编排(Resource Orchestration)是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、配置等,并自动完成所有资源的创建和配置,以达到自动化部署、运维等目的。编排模板同时也是一种标准化的资源和应用交付方式,并且可以随时编辑修改,使基础设施即代码(Infrastructure as Code)成为可能。 产品详情:https://www.aliyun.com/product/ros/
相关文章
|
算法 机器人 API
【ROS】TF2坐标转换及实战示例
ROS中提供了坐标转换的软件包 Transform Frame TF的作用是ROS中实现不同坐标点/向量的转换。
708 0
ROS TF2当前坐标系如何计算其它历史坐标系的坐标变换
ROS TF2当前坐标系如何计算其它历史坐标系的坐标变换
ROS TF2当前坐标系如何计算其它历史坐标系的坐标变换
|
数据可视化 机器人 C++
ROS TF2
turtlesim的多机器人示例中,展示了tf2的一些功能。 也介绍了使用tf2_echo,view_frames和rviz。 使对tf2可以做的事情有个很好的了解。
ROS TF2
|
传感器 存储 机器人
ROS TF 将传感器数据转换为机器人坐标系下
ROS TF 将传感器数据转换为机器人坐标系下
ROS TF 将传感器数据转换为机器人坐标系下
|
传感器 C++
ROS TF2 添加一个 坐标系 附实例
ROS TF2 添加一个 坐标系 附实例
ROS TF2 添加一个 坐标系 附实例
|
XML C++ 数据格式
【古月21讲】ROS入门系列(4)——参数使用与编程方法、坐标管理系统、tf坐标系广播与监听的编程实现、launch启动文件的使用方法
【古月21讲】ROS入门系列(4)——参数使用与编程方法、坐标管理系统、tf坐标系广播与监听的编程实现、launch启动文件的使用方法
274 0
【古月21讲】ROS入门系列(4)——参数使用与编程方法、坐标管理系统、tf坐标系广播与监听的编程实现、launch启动文件的使用方法
|
2月前
|
Ubuntu 机器人 Linux
|
15天前
|
自动驾驶 安全 机器人
ROS2:从初识到深入,探索机器人操作系统的进化之路
前言 最近开始接触到基于DDS的这个系统,是在稚晖君的机器人项目中了解和认识到。于是便开始自己买书学习起来,感觉挺有意思的,但是只是单纯的看书籍,总会显得枯燥无味,于是自己又开始在网上找了一些视频教程结合书籍一起来看,便让我对ROS系统有了更深的认识和理解。 ROS的发展历程 ROS诞生于2007年的斯坦福大学,这是早期PR2机器人的原型,这个项目很快被一家商业公司Willow Garage看中,类似现在的风险投资一样,他们投了一大笔钱给这群年轻人,PR2机器人在资本的助推下成功诞生。 2010年,随着PR2机器人的发布,其中的软件正式确定了名称,就叫做机器人操作系统,Robot Op
58 14
|
27天前
|
XML 算法 自动驾驶
ROS进阶:使用URDF和Xacro构建差速轮式机器人模型
【11月更文挑战第7天】本篇文章介绍的是ROS高效进阶内容,使用URDF 语言(xml格式)做一个差速轮式机器人模型,并使用URDF的增强版xacro,对机器人模型文件进行二次优化。

推荐镜像

更多