文章目录

  • 一、函数waitForTransform()、lookupTransform()
    • 具体解释
  • 二、函数 tf::StampedTransform()、sendTransform()
    • 具体解释
  • 三、函数 Transformer::canTransform()
    • 具体解释
  • 四、函数 Transformer::transformPose ()、Transformer::transformQuaternion()
    • 具体解释
  • 五、函数 pcl_ros::transformPointCloud()
    • 具体解释

这里记录一些 ROS中的 tf 用到的一些重要函数解析,陆续更新…

一、函数waitForTransform()、lookupTransform()

// tf监听器
tf::TransformListener listener;
// 查找turtle2与turtle1的坐标变换
listener.waitForTransform("/turtle2", "/turtle1", ros::Time(0), ros::Duration(3.0));
listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform);

这里 waitForTransform()/turtle2target_frame,这里理解为 数据应转换到的frame, 也就是 tf 的 frame_id ; /turtle1source_frame ,这里理解为 数据来源的frame, 也就是 tf 的 child_frame_id 。 等待的是 /turtle2/turtle1 的坐标转换,ros::Time(0) 代表最近时刻的有效数据,ros::time::now() 是现在这个时刻的有效数据,不可以把 ros::Time(0) 改成 ros::time::now() ,因为监听做不到实时,会有几毫秒的延迟;最长等待 3.0 s 的时间。

这里 lookupTransform() , /turtle2target_frame,这里理解为 数据应转换到的frame, 也就是 tf 的 frame_id ; /turtle1source_frame ,这里理解为 数据来源的frame, 也就是 tf 的 child_frame_id 。 等待的是 /turtle2/turtle1 的坐标转换,ros::Time(0) 代表最近时刻的有效数据,ros::time::now() 是现在这个时刻的有效数据,不可以把 ros::Time(0) 改成 ros::time::now() ,因为监听做不到实时,会有几毫秒的延迟;将得到的转换结果存放到 transform 中。

具体解释

这里的 waitForTransform() 传入的第一个参数是 目标坐标系 , 第二个参数是 源坐标系。

waitForTransform() 原型是
(其函数原型可在这找到 :传送门 http://docs.ros.org/jade/api/tf/html/c++/classtf_1_1Transformer.html#a72dc26fe7bfcb9585123309e092e5c83 )

//  target_frame : 这里理解为 数据应转换到的frame, 也就是 tf 的 frame_id
//  source_frame : 这里理解为 数据来源的frame,    也就是 tf 的 child_frame_id
bool Transformer::waitForTransform  (const std::string &    target_frame,const std::string &    source_frame,const ros::Time &      time,const ros::Duration &      timeout,const ros::Duration &   polling_sleep_duration = ros::Duration(0.01),std::string *     error_msg = NULL )         const


同样,这里的 lookupTransform() 传入的第一个参数是 目标坐标系 , 第二个参数是 源坐标系。

lookupTransform() 原型是
(其函数原型可在这找到 :传送门 hhttp://docs.ros.org/en/jade/api/tf/html/c++/classtf_1_1Transformer.html#ac01a9f8709a828c427f1a5faa0ced42b )

//  target_frame : 这里理解为 数据应转换到的frame, 也就是 tf 的 frame_id
//  source_frame : 这里理解为 数据来源的frame,    也就是 tf 的 child_frame_id
void Transformer::lookupTransform   (   const std::string &     target_frame,const std::string &    source_frame,const ros::Time &      time,StampedTransform &     transform )         const

二、函数 tf::StampedTransform()、sendTransform()

tf::TransformBroadcaster br;
tf::Transform transform;transform.setOrigin( tf::Vector3(0.0, 2.0, 0.0) );
transform.setRotation( tf::Quaternion(0, 0, 0, 1) );
br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "turtle1", "carrot1"));

这里的 tf::StampedTransform() 是一个构造函数,给数据赋值,传入的参数中 transform 是包含tf的具体数据(现在这个数据里面还不包含frame_id、frame_child_id), turtle1 是父坐标系,carrot1 是子坐标系,时间戳是ros::Time::now()

具体解释

StampedTransform() 是一个构造函数, 原型是
(其函数原型可在这找到 :传送门 http://docs.ros.org/jade/api/tf/html/c++/classtf_1_1StampedTransform.html )

tf::StampedTransform::StampedTransform   (   const tf::Transform &   input,const ros::Time &     timestamp,const std::string &   frame_id,const std::string &    child_frame_id )        [inline]


sendTransform() 的原型是
(其函数原型可在这找到 :传送门 http://docs.ros.org/jade/api/tf/html/c++/classtf_1_1TransformBroadcaster.html#acea192abb3558dd1f53c3269f2922d14 )

注意这里有函数重载,这里调用的是第一个函数

void tf::TransformBroadcaster::sendTransform ( const StampedTransform &  transform   )   //Send a StampedTransform The stamped data structure includes frame_id, and time, and parent_id already.
//发送一个 StampedTransform(这是一个类) 类型的数据,这个数据包括父坐标系、子坐标系、时间戳

三、函数 Transformer::canTransform()

boost::shared_ptr<tf::TransformListener> listener;
if (!listener->canTransform(scan->header.frame_id, robot_frame, scan->header.stamp, &error_msg))
{ROS_ERROR_STREAM_THROTTLE(1.0, "can not transform: "<<robot_frame<<" to "<<scan->header.frame_id);return;
}

这里的 Transformer::canTransform() 作用是测试 tf 是否possible(可用),传入的参数中scan->header.frame_id 是目标坐标系,robot_frame 是源坐标系,scan->header.stamp 是时间戳,error_msg 是会返回 一个表征 如果 转换(transform) 失败的原因 的标志数据。

具体解释

Transformer::canTransform() 函数原型:
(其函数原型可在这找到 :传送门
(http://docs.ros.org/jade/api/tf/html/c++/classtf_1_1Transformer.html#aea15c33a1a24e55bd4a35b86b8423ee1)

bool Transformer::canTransform   (   const std::string &     target_frame,
const std::string &     source_frame,
const ros::Time &   time,
std::string *   error_msg = NULL
)       const


四、函数 Transformer::transformPose ()、Transformer::transformQuaternion()

( Transformer::transformPose () 和 Transformer::transformQuaternion()的使用方法和含义基本是一样的,这里只对 Transformer::transformPose () 做简单解释)

TransformListenerWrapper* tf_;
tf::Stamped<tf::Pose> ident (tf::Transform(tf::createIdentityQuaternion(),tf::Vector3(0,0,0)),ros::Time(), laser_scan->header.frame_id);
tf::Stamped<tf::Pose> laser_pose;
tf_->transformPose(base_frame_id_, ident, laser_pose);

这里传入的参数:目标坐标系、ident 是输入的 带时间戳的位姿、laser_pose 是输出的 带时间戳的位姿。
该函数主要是 查找了一个一个目标坐标系base_frame_id_ 到 ident 中的源坐标系laser 之间的 tf, ident 的中的tf转换数据会被赋值到 laser_pose 中。

具体解释

Transformer::transformPose() 函数主要是 查找了一个目标坐标系target_frame到stamped_in中的源坐标系之间的 tf , stamped_in 的中的tf转换数据会被赋值到 stamped_out 中。

Transformer::transformPose() 函数原型:
(其函数原型可在这找到 : 传送门 ( http://docs.ros.org/en/jade/api/tf/html/c++/classtf_1_1Transformer.html#a0a7b72eb4cc62194164d030afbefda9a ) )

注意这里有函数重载,这里调用的是第一个函数:

void Transformer::transformPose ( const std::string &  target_frame,const Stamped< tf::Pose > &    stamped_in,Stamped< tf::Pose > &      stamped_out )   const//   target_frame  目标坐标系
//    stamped_in    输入 带时间戳的位姿
//    stamped_out   输出 带时间戳的位姿

注意 Transformer::transformPose() 函数内部调用了 lookupTransform() 函数,所以这部分实际上做了一个监听 tf 的作用。
函数的具体实现:

 void Transformer::transformPose(const std::string& target_frame, const Stamped<Pose>& stamped_in, Stamped<Pose>& stamped_out) const
{StampedTransform transform;lookupTransform(target_frame, stamped_in.frame_id_, stamped_in.stamp_, transform);stamped_out.setData(transform * stamped_in);stamped_out.stamp_ = transform.stamp_;stamped_out.frame_id_ = target_frame;
};

由于函数重载,这个函数的第二个实现方法是:

void Transformer::transformPose(const std::string& target_frame, const ros::Time& target_time,const Stamped<Pose>& stamped_in,const std::string& fixed_frame,Stamped<Pose>& stamped_out) const
{StampedTransform transform;lookupTransform(target_frame, target_time,stamped_in.frame_id_,stamped_in.stamp_,fixed_frame, transform);stamped_out.setData(transform * stamped_in);stamped_out.stamp_ = transform.stamp_;stamped_out.frame_id_ = target_frame;
};

五、函数 pcl_ros::transformPointCloud()

pcl_ros::transformPointCloud("/velodyne", *input_cloud, *output_cloud, *tran);

其中第一个参数为目标坐标系,第二个参数为原始点云,第三个参数为 目标点云,
第四个参数为接收到的坐标,正变换、逆变换 都包含其中

具体解释

pcl_ros::transformPointCloud() 函数原型:
(其函数原型可在这找到 : 传送门 ( http://docs.ros.org/jade/api/pcl_ros/html/namespacepcl__ros.html#aad20af010640a41f1898e75f6a6121ad ) )

注意这里有函数重载,这里调用的是第二个函数

template<typename PointT >
bool pcl_ros::transformPointCloud   (   const std::string &     target_frame,const pcl::PointCloud< PointT > &    cloud_in,pcl::PointCloud< PointT > &      cloud_out,const tf::TransformListener &     tf_listener )       //Transforms a point cloud in a given target TF frame using a TransformListener.//把点云转换到给定的目标坐标系下//参数:
//    target_frame  目标坐标系
//    cloud_in  输入点云
//    cloud_out 输出点云
//    tf_listener    tf监听者对象

【ROS学习】- tf学习 - tf中重要函数解析 (陆续更新....)相关推荐

  1. oracle中next_day()函数解析

    oracle中next_day()函数解析 Sql代码 当前系统时间的下一星期一的时间select   next_day(sysdate,1) from dual NEXT_DAY(date,char ...

  2. 深度学习————如何在Python中求解函数的解析表达式

    1 致谢 感谢杨老师的教导! 2 在Python中求解函数的解析表达式 首先写出函数的表达式,然后使用SymPy函数库求解函数偏导数的解析表达式(符号微分),然后再使用SymPy库将求得的符号微分转换 ...

  3. 极大似然函数求解_关于极大似然估计的学习(附Matlab中mle函数的求解)

    冒泡~是新的一周辣~温故而知新一下极大似然估计(真是很不容易了) 极大似然估计的基本思想 什么是极大似然?官方上的较清楚的解释是:利用已知的样本的结果,在使用某个模型的基础上,反推最有可能导致这样结果 ...

  4. python中append函数解析_对python中的pop函数和append函数详解

    对python中的pop函数和append函数详解 pop()函数 1.描述 pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值. 语法 pop()方法语法: list. ...

  5. 【晕头晕脑的Python】Python中Reshape函数解析

    Reshape函数解析 Reshape()作用: Reshape()实例说明: 一维reshape() 为 二维 二维数组 reshape 切片,逆置 三维Reshape情况 Reshape()作用: ...

  6. 【theano-windows】学习笔记二——theano中的函数和共享参数

    前言 上一篇博客中学到了theano中的变量类型,也就是dscalar.dvector之类的, 然后还有一个theano.function和eval函数, 将我们所定义的操作转换成theano可执行的 ...

  7. python中argsort_(学习笔记)numpy中argsort函数用法

    在Python中使用help帮助 >>> import numpy >>> help(numpy.argsort) Help on function argsort ...

  8. JS学习笔记——高级编程中compose函数的介绍和基本实现

    1.前言 在之前探讨redux的中间件的时候,applyMiddleware源码中有遇到过compose()函数,当时不太明白起作用,所以就上网好好查了一下,做了个总结. 2.普通函数 在函数式编程当 ...

  9. (pytorch-深度学习系列)pytorch中backwards()函数对梯度的操作

    backwards()函数对梯度的操作 对于一个新的tensor来说,梯度是空的:但当对这个tensor进行运算操作后,他就会拥有一个梯度: x = torch.ones(2, 2, requires ...

最新文章

  1. oc45--多对象内存管理 优化
  2. 如何打赢一场唯快不破的比赛,看看他们的绝招
  3. JAVA后端开发规范
  4. python标准输入输出用来干什么_python 以标准输出(sys.stdout)为例,看python的标准输入、标准错误输出...
  5. 【转】Asp.Net中Excel操作权限的问题
  6. LeetCode 2201. 统计可以提取的工件(哈希)
  7. mysql修改主从复制id_mysql主从复制设置
  8. 面向对面 静态参数 与 组合
  9. android 新浪微博客户端的表情功能的实现,flutter教程pdf
  10. php用for循环输出九九乘法表,php循环之打印九九乘法表
  11. android中实现图片圆形效果
  12. 【Laravel】Laravel-admin后台框架-2创建数据表建立模块增删改查CURD(1)
  13. ecshop模板教程——类似淘宝滚屏漂浮返回
  14. Android Studio 微信分享功能(包括可以分享到朋友圈,分享到朋友)
  15. Redis内存数据库的应用场景
  16. 手机rom,那些你不知道的事
  17. Cadence IUS 之二: 生成波形
  18. 我的毕业实习一年总结
  19. 20179311《网络攻防实践》第九周作业
  20. 数组的操作-集大成篇

热门文章

  1. 还记得最初的梦想么?——2018年小结
  2. 分解质因数-Pollard‘s Rho
  3. 期货交易的安全性分析
  4. NV21格式图像旋转 c++,平移、缩放实现代码
  5. inurl_inurl,intitle指令的含义、作用及用法
  6. IE if注释判断( [if gte IE 8] )的解释网上的完全乱七八糟啊!
  7. sqlite的count
  8. OD和CE使用示例-Python实现win98扫雷一键标雷外挂
  9. c语言阿拉伯数字转大写,c++阿拉伯数字转化为中文大写
  10. 经济法基础(2020年)——第三章 支付结算法律制度