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. jQuery学习笔记(DOM操作)

    DOM操作的分类 一般来说,DOM操作分为3个方面,即DOM Core.HTML-DOM和CSS-DOM. 1. DOM Core DOM Core并不专属于JavaScript,任何一种支持DOM的 ...

  2. SQL SERVER 查看数据库信息

    a.使用sys.database_files查看有关数据库文件的信息 b.使用sys.filegroups查看有关数据库组的信息. c.使用sys.master_files 查看数据库文件的基本信息和 ...

  3. Ubuntu 18.04 安装和常用软件安装

    Ubuntu 18.04 安装 下载 Ubuntu 制作 U 盘启动盘 设置电脑为 U 盘启动 插入 U 盘,重启电脑 按照提示安装 Ubuntu 更新 NVIDIA 显卡和 Broadcom 无线网 ...

  4. 【iOS XMPP】使用XMPPFramewok(四):收发消息

    转自:http://www.cnblogs.com/dyingbleed/archive/2013/05/16/3075105.html 收发消息 接收消息 通过实现 - (void)xmppStre ...

  5. 行为类模式(七):观察者(Observer)

    定义 定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新. UML 优点 观察者和被观察者之间是松耦合的,分别可以各自独立改变. Subject在发送 ...

  6. android笔记---百度地图api应用 (一)

    package com.example.bdtest; import com.baidu.mapapi.MKEvent; import com.baidu.mapapi.MKPlanNode; imp ...

  7. git push remote error解决办法

    通常在用git clone了remote端(服务器)的git仓库后,再进行了自己一系列修改后,会将自己测试后稳定的状态push到remote端,以更新源仓库,使 其他人在pull的时候得到自己的修改. ...

  8. Python 操作redis有序集合(sorted set)

    #coding:utf8 import redis r =redis.Redis(host=") 1.Zadd Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中.如果某个成员 ...

  9. DIOCP开源项目-DIOCP3的LoadRunner11测试报告

    昨天有个多年的群友(B3.Locet)用LoadRunner11对DIOCP3做压力测试,说测试的时候出现了大量的10053,10054的报告.昨天晚上下载了个LoadRunner11, 今天捣鼓了下 ...

  10. java8新特性(六):Stream多线程并行数据处理

    转:http://blog.csdn.net/sunjin9418/article/details/53143588 将一个顺序执行的流转变成一个并发的流只要调用 parallel()方法 publi ...