tf变换(1)

简介: TF库的目的是实现系统中任一个点在所有坐标系之间的坐标变换,也就是说,只要给定一个坐标系下的一个点的坐标,就能获得这个点在其他坐标系的坐标. 使用tf功能包,a. 监听tf变换: 接收并缓存系统中发布的所有参考系变换,并从中查询所需要的参考系变换。

TF库的目的是实现系统中任一个点在所有坐标系之间的坐标变换,也就是说,只要给定一个坐标系下的一个点的坐标,就能获得这个点在其他坐标系的坐标.

 使用tf功能包,a. 监听tf变换: 接收并缓存系统中发布的所有参考系变换,并从中查询所需要的参考系变换。

                         b.广播 tf变换: 向系统中广播参考系之间的坐标变换关系。系统中更可能会存在多个不同部分的tf变换广播,每个广播都可以直接将参考系变换关系直接插入tf树中,不需要再进行同步。

 

首先介绍关于TF的API的一些数据结构:

基本的数据类型有(Quaternion, Vector, Point, Pose, Transform)

  

这其中Quaternion 是表示四元数,vector3是一个3*1 的向量,point是一个表示一个点坐标,Pose是位姿(位姿是包括坐标以及方向) Transform是一个转换的模版

tf::Stamped <T>

是一种包含了除了Transform的其他几种基本的数据结构的一种数据结构:

template <typename T>    //模版结构可以是tf::Pose tf:Point 这些基本的结构
class Stamped : public T{
 public:
  ros::Time stamp_;    //记录时间
  std::string frame_id_;   //ID

  Stamped() :frame_id_ ("NO_ID_STAMPED_DEFAULT_CONSTRUCTION"){}; //Default constructor used only for preallocation

  Stamped(const T& input, const ros::Time& timestamp, const std::string & frame_id);
  
  void setData(const T& input);
};

tf::StampedTransform

TF::stampedtransform是TF的一种特殊情况:它需要frame_id和stamp以及child_frame_id。

/** \brief The Stamped Transform datatype used by tf */
class StampedTransform : public tf::Transform
{
public:
  ros::Time stamp_; ///< The timestamp associated with this transform 时间戳                                                                                                                                                                                                                                                       
  std::string frame_id_; ///< The frame_id of the coordinate frame  in which this transform is defined  定义转换坐标框架的frameID                                                                                                                                                                                                                    
  std::string child_frame_id_; ///< The frame_id of the coordinate frame this transform defines 的坐标系变换定义的id                                                                                                                                                                                                                            
  StampedTransform(const tf::Transform& input, const ros::Time& timestamp, const std::string & frame_id, const std::string & child_frame_id):
    tf::Transform (input), stamp_ ( timestamp ), frame_id_ (frame_id), child_frame_id_(child_frame_id){ };

  /** \brief Default constructor only to be used for preallocation */
  StampedTransform() { };

  /** \brief Set the inherited Traonsform data */
  void setData(const tf::Transform& input){*static_cast<tf::Transform*>(this) = input;};

};

 举个例子

在机器人的定位领域有蒙特卡罗定位(AMCL)的算法,这个算法是根据给定的地图,结合粒子滤波获取最佳定位点Mp,这个定位点是相对于地图map上的坐标,也就是base_link(也就是机器人的基坐标)相对map上的坐标。我们知道 odom 的原点是机器人启动时刻的位置,它在map上的位置或转换矩阵是未知的。但是AMCL可以根据最佳粒子的位置推算出 odom->map(就是说通过最佳粒子推算出机器人在地图的中的位置)的tf转换信息并发布到 tf主题上。因为base_link->odom的tf转换信息是每时每刻都在发布的,所以它是已知的

,所以这里有个这样的tf关系

map->base_link(就是地图中机器人的位置  是根据最佳粒子推算的)

base_link->odom(这是现实中机器人的位姿可以说是里程计的信息)

可以理解:机器人的里程计的信息 = 当前地图中的机器人的的位置    减去  地图中机器人的起点位置。

 转为公式可以写成 :map->odom = map->base_link   -  base_link->odom

或者写为:

 base_link->odom = map->base_link - map->odom  (这样更容易理解)

提示:首先我们可以先了解关于PRY这三个概念关于pitch yaw roll的博客 http://blog.csdn.net/yuzhongchun/article/details/22749521)

pitch是围绕X轴旋转,也叫做俯仰角,

yaw是围绕Y轴旋转,也叫偏航角,

roll是围绕Z轴旋转,也叫翻滚角

1.    ROS_DEBUG("New pose: %6.3f %6.3f %6.3f",  
2.             hyps[max_weight_hyp].pf_pose_mean.v[0],  
3.             hyps[max_weight_hyp].pf_pose_mean.v[1],  
4.             hyps[max_weight_hyp].pf_pose_mean.v[2]);  
5.     // hyps[max_weight_hyp].pf_pose_mean.v[0], [1], [2] 就代表了Mp  也就是机器人的位姿那么位姿的格式是(x,y,theta)最后一个是yaw偏航角,
6.    // subtracting base to odom from map to base and send map to odom instead  
7.    tf::Stamped<tf::Pose> odom_to_map;  
8.    try  
9.    {  
10.      tf::Transform tmp_tf(tf::createQuaternionFromYaw(hyps[max_weight_hyp].pf_pose_mean.v[2]),   tf::Vector3(hyps[max_weight_hyp].pf_pose_mean.v[0],  
11.                                       hyps[max_weight_hyp].pf_pose_mean.v[1],  
12.                                       0.0));  
13.    // tmp_tf = 从map原点看base_link的位置  为yaw生成四元数,最后的0.0是(x,y,z)的Z的值为0  因为这是在二维平面中。
14.      tf::Stamped<tf::Pose> tmp_tf_stamped (tmp_tf.inverse(),  
15.                                            laser_scan->header.stamp,  
16.                                            base_frame_id_);  
17.    //tmp_tf.inverse()  = 以为Mp为坐标的原点,地图map原点相对于Mp的位置,就是在base_link坐标系下map 原点的位置
18.      this->tf_->transformPose(odom_frame_id_,  
19.                               tmp_tf_stamped,  
20.                               odom_to_map); 
21.     //进行 base_link坐标系下的点转换到odom坐标系,也就是把map原点转换到odom坐标系下,等于从odom原点看map原点的位置。放到latest_tf_变量里面
22.    }  
23.    catch(tf::TransformException)  
24.    {  
25.      ROS_DEBUG("Failed to subtract base to odom transform");  
26.      return;  
27.    }  

 

TF命令行工具

(1) tf_monitor工具的功能是打印tf树中的所有参考系信息,通过输入参数来查看指定参考系之间的信息  用法: rosrun tf tf_monitor

  tf_monitor <source_frame> <target_target>  监视一个特定的转换 For example, to monitor the transform from /base_footprint to /odom:

  (2) tf_echo工具的功能是查看指定参考系之间的变换关系。命令的格式: tf_echo <source_frame> <target_frame>

 (3)static_transform_publisher工具的功能是发布两个参考系之间的静态坐标变换,两个参考系一般不发生相对位置变化

(4)view_frames 是可视化的调试工具,可以生成pdf文件,来显示整棵tf树的信息。用法:rosrun tf view_frames 

 

具体可以查看http://wiki.ros.org/tf/

博客园的编辑界面真实难以编辑啊  受不鸟了  所以还是不写了  转向CSDN了

 

相关实践学习
使用ROS创建VPC和VSwitch
本场景主要介绍如何利用阿里云资源编排服务,定义资源编排模板,实现自动化创建阿里云专有网络和交换机。
ROS入门实践
本课程将基于基础设施即代码 IaC 的理念,介绍阿里云自动化编排服务ROS的概念、功能和使用方式,并通过实际应用场景介绍如何借助ROS实现云资源的自动化部署,使得云上资源部署和运维工作更为高效。
相关文章
|
开发框架 供应链 监控
并行开发模型详解:类型、步骤及其应用解析
在现代研发环境中,企业需要在有限时间内推出高质量的产品,以满足客户不断变化的需求。传统的线性开发模式往往拖慢进度,导致资源浪费和延迟交付。并行开发模型通过允许多个开发阶段同时进行,极大提高了产品开发的效率和响应能力。本文将深入解析并行开发模型,涵盖其类型、步骤及如何通过辅助工具优化团队协作和管理工作流。
716 3
|
运维 Cloud Native Java
从 IDC 到云原生:稳定性提升 100%,成本下降 50%,热联集团的数字化转型与未来展望
热联集团在进行了云原生架构的升级与探索后,显著提升了业务系统的稳定性和敏捷性。这一转变不仅为公司冲击更高的销售目标奠定了坚实的技术基础,也标志着热联在数字化转型道路上迈出了关键一步。通过采用微服务、容器化等先进技术手段,热联能够更加灵活地响应市场变化,快速迭代产品和服务,满足客户日益增长的需求。
959 169
Bully、Raft、Zab选举算法的差异比较
Bully算法、Raft算法、Zab的差与异。他们如何脱胎于Paxos而成?
912 128
|
前端开发 UED 开发者
React 日期时间选择器 (DateTime Picker): 从基础到高级
本文详细介绍了如何在React应用中集成日期时间选择器,重点讲解了`react-datepicker`和Material-UI的`DatePicker`组件的安装、基本用法、自定义日期格式和设置日期范围的方法。同时,文章还探讨了常见问题及其解决方法,帮助开发者避免易错点,确保在项目中顺利集成日期时间选择功能。
1304 3
|
负载均衡 Java Nacos
Nacos服务注册与发现
【10月更文挑战第11天】Nacos 是一个开源平台,用于服务发现和配置管理,提供服务注册、发现及动态配置等功能,适用于微服务架构。其核心功能包括服务注册、服务发现和动态配置管理,支持多种语言如 Java、Go、Python 等,具备高可用性和易用性。Nacos 可用于微服务治理、动态扩展和跨语言服务调用等场景,简化了服务间的交互和管理。
826 10
|
传感器 存储 程序员
一文彻底搞明白51单片机的发展历程
51单片机自1980年Intel推出MCS-51系列以来,历经40余年发展,从最初的工业控制逐步扩展到家电、通信、智能家居等多领域。其哈佛架构和丰富的指令集奠定了技术基础,并通过持续创新保持竞争力。面对ARM等新架构的挑战,51单片机通过工艺革新和功能扩展,如集成ADC、USB、蓝牙等,仍占据电动工具、智能传感器等成本敏感领域的70%以上市场份额。如今,它不仅是嵌入式技术的活化石,更是中国电子产业崛起的见证者,全球90%的51单片机产自长三角地区。坚持学习,每天一个小知识点,是不是有了新收获,加油哈!
2227 0
|
网络协议 数据安全/隐私保护 网络虚拟化
计算机网络的体系结构
OSI模型,即开放系统互连模型,由ISO于1984年提出,是计算机网络通信的参考模型,将网络功能划分为七层:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。各层负责不同的通信任务,使网络设计与管理更加模块化和高效。
1578 1
|
存储 BI 芯片
#j计算机组成原理# chapter 3 系统总线(上)
#j计算机组成原理# chapter 3 系统总线
1019 1
#j计算机组成原理# chapter 3 系统总线(上)
|
机器学习/深度学习 安全 算法
安全多方计算之二:一文搞懂百万富翁问题
安全多方计算之二:一文搞懂百万富翁问题
1243 0
|
机器学习/深度学习 人工智能 物联网
快速玩转 Llama2!阿里云机器学习 PAI 推出最佳实践
近期,Meta 宣布大语言模型 Llama2 开源,阿里云机器学习平台PAI针对 Llama2 系列模型进行适配,推出全量微调、Lora微调、分布式训练、推理服务等场景最佳实践,助力AI开发者快速开箱。
12563 15