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轴旋转,也叫翻滚角

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

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了

tf变换(1)的更多相关文章

  1. Odometry的发布和发布odom到base_link的tf变换

    转载自http://www.ncnynl.com/archives/201702/1328.html ROS发布nav_msgs/Odometry消息,以及通过tf从“odom”坐标系到“base_l ...

  2. ROS探索总结(十八)——重读tf

    在之前的博客中,有讲解tf的相关内容,本篇博客重新整理了tf的介绍和学习内容,对tf的认识会更加系统. 1 tf简介 1.1 什么是tf tf是一个让用户随时间跟踪多个参考系的功能包,它使用一种树型数 ...

  3. SLAM+语音机器人DIY系列:(二)ROS入门——7.理解tf的原理

    摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...

  4. tf一些理解(根据资料)

    首先看了开源操作机器人系统-ros这本书(张建伟)第五章slam导航 5.1使用tf配置机器人 还有ros navigation 教程 http://wiki.ros.org/navigation/T ...

  5. tf树

    tf变换(1)   TF库的目的是实现系统中任一个点在所有坐标系之间的坐标变换,也就是说,只要给定一个坐标系下的一个点的坐标,就能获得这个点在其他坐标系的坐标. 使用tf功能包,a. 监听tf变换:  ...

  6. tf学习

    常用命令: 1.显示tf框架: rosrun tf view_frames evince frames.pd tf变换,定义不同坐标系之间的平移与旋转变换关系. 参考文献: tf教程 古月居博客

  7. ROS 机器人技术 - 广播与接收 TF 坐标

    上次我们学习了 TF 的基本概念和如何发布静态的 TF 坐标: ROS 机器人技术 - TF 坐标系统基本概念 ROS 机器人技术 - 静态 TF 坐标帧 这次来总结下如何发布一个自定义的 TF 坐标 ...

  8. 利用move_base导航--42

    摘要: 原创博客:转载请标明出处:http://www.cnblogs.com/zxouxuewei/ 各位博友好长时间又没有写博客了,突然发现上班和在学校是不一样的,在公司的却没有时间写博客了,不过 ...

  9. ROS探索总结(十九)——如何配置机器人的导航功能

    1.概述 ROS的二维导航功能包,简单来说,就是根据输入的里程计等传感器的信息流和机器人的全局位置,通过导航算法,计算得出安全可靠的机器人速度控制指令.但是,如何在特定的机器人上实现导航功能包的功能, ...

随机推荐

  1. ElasticSearh更新nested字段(Array数组)。怎么根据查询条件(query)复制一个(index)到新的Index how to update by query a nested fields data for elasticsearch

    GET usernested/_search { "query": { "nested": { "path": "tags&quo ...

  2. telegraf input的配置

    .操作系统基础监控指标配置标准 基础监控使用通用的全局配置文件telegraf.conf,以下只贴上采集器input部分代码 telegraf -config /etc/telegraf/telegr ...

  3. php分享十五:php的数据库操作

    一:术语解释: What is an Extension? API和扩展不能理解为一个东西,因为扩展不一定暴露一个api给用户 The PDO MySQL driver extension, for ...

  4. Atitit opencv 模板匹配

    Atitit opencv 模板匹配 1.1. 图片1 1.2. Atitit opencv 模板匹配  6中匹配算法貌似效果区别不大1 1.3. 对模板缩放的影响 一般的缩放可以,太大了就歇菜了.. ...

  5. 【Unity】2.11 了解游戏有哪些分类对你开阔思路有好处

    分类:Unity.C#.VS2015 创建日期:2016-03-31 一.简介 对游戏类型的划分有助于游戏的市场定位,以便吸引具有同一爱好的玩家群体.此外,制作游戏策划方案时,也通常会依据不同的游戏类 ...

  6. 细说php(二) 变量和常量

    一. 变量的声明 1. php中声明变量的方法:  $var = 123; 2. php是弱类型的语言, 变量的类型由存储的值决定 注: Java是强类型语言, 声明变量一定要先指定类型 二. 变量的 ...

  7. Robolectric使用教程

    转载请标明出处:http://blog.csdn.net/shensky711/article/details/53561172 本文出自: [HansChen的博客] 概述 怎样使用 为项目加入依赖 ...

  8. HHH

    https://data-artisans.com/flink-forward/resources/alibabas-common-algorithm-platform-on-flink https: ...

  9. close Spark Streaming gratefully

    https://blog.csdn.net/u010454030/article/details/78679930 https://blog.csdn.net/u010454030/article/d ...

  10. u3d中的INput

    属性 属性: 功能: 轴 (Axes) 包含当前工程的所有定义的输入轴:数目 (Size) 该工程中不同输入轴的数量,元素 0.1.... 是要修改的特定的轴. 名称 (Name) 在游戏启动器中以及 ...