【ROS学习】- tf学习 - tf中重要函数解析 (陆续更新....)
文章目录
- 一、函数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()
, /turtle2
是target_frame
,这里理解为 数据应转换到的frame, 也就是 tf 的 frame_id ; /turtle1
是source_frame
,这里理解为 数据来源的frame, 也就是 tf 的 child_frame_id 。 等待的是 /turtle2
到 /turtle1
的坐标转换,ros::Time(0)
代表最近时刻的有效数据,ros::time::now()
是现在这个时刻的有效数据,不可以把 ros::Time(0) 改成 ros::time::now() ,因为监听做不到实时,会有几毫秒的延迟;最长等待 3.0 s 的时间。
这里 lookupTransform()
, /turtle2
是target_frame
,这里理解为 数据应转换到的frame, 也就是 tf 的 frame_id ; /turtle1
是source_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中重要函数解析 (陆续更新....)相关推荐
- oracle中next_day()函数解析
oracle中next_day()函数解析 Sql代码 当前系统时间的下一星期一的时间select next_day(sysdate,1) from dual NEXT_DAY(date,char ...
- 深度学习————如何在Python中求解函数的解析表达式
1 致谢 感谢杨老师的教导! 2 在Python中求解函数的解析表达式 首先写出函数的表达式,然后使用SymPy函数库求解函数偏导数的解析表达式(符号微分),然后再使用SymPy库将求得的符号微分转换 ...
- 极大似然函数求解_关于极大似然估计的学习(附Matlab中mle函数的求解)
冒泡~是新的一周辣~温故而知新一下极大似然估计(真是很不容易了) 极大似然估计的基本思想 什么是极大似然?官方上的较清楚的解释是:利用已知的样本的结果,在使用某个模型的基础上,反推最有可能导致这样结果 ...
- python中append函数解析_对python中的pop函数和append函数详解
对python中的pop函数和append函数详解 pop()函数 1.描述 pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值. 语法 pop()方法语法: list. ...
- 【晕头晕脑的Python】Python中Reshape函数解析
Reshape函数解析 Reshape()作用: Reshape()实例说明: 一维reshape() 为 二维 二维数组 reshape 切片,逆置 三维Reshape情况 Reshape()作用: ...
- 【theano-windows】学习笔记二——theano中的函数和共享参数
前言 上一篇博客中学到了theano中的变量类型,也就是dscalar.dvector之类的, 然后还有一个theano.function和eval函数, 将我们所定义的操作转换成theano可执行的 ...
- python中argsort_(学习笔记)numpy中argsort函数用法
在Python中使用help帮助 >>> import numpy >>> help(numpy.argsort) Help on function argsort ...
- JS学习笔记——高级编程中compose函数的介绍和基本实现
1.前言 在之前探讨redux的中间件的时候,applyMiddleware源码中有遇到过compose()函数,当时不太明白起作用,所以就上网好好查了一下,做了个总结. 2.普通函数 在函数式编程当 ...
- (pytorch-深度学习系列)pytorch中backwards()函数对梯度的操作
backwards()函数对梯度的操作 对于一个新的tensor来说,梯度是空的:但当对这个tensor进行运算操作后,他就会拥有一个梯度: x = torch.ones(2, 2, requires ...
最新文章
- oc45--多对象内存管理 优化
- 如何打赢一场唯快不破的比赛,看看他们的绝招
- JAVA后端开发规范
- python标准输入输出用来干什么_python 以标准输出(sys.stdout)为例,看python的标准输入、标准错误输出...
- 【转】Asp.Net中Excel操作权限的问题
- LeetCode 2201. 统计可以提取的工件(哈希)
- mysql修改主从复制id_mysql主从复制设置
- 面向对面 静态参数 与 组合
- android 新浪微博客户端的表情功能的实现,flutter教程pdf
- php用for循环输出九九乘法表,php循环之打印九九乘法表
- android中实现图片圆形效果
- 【Laravel】Laravel-admin后台框架-2创建数据表建立模块增删改查CURD(1)
- ecshop模板教程——类似淘宝滚屏漂浮返回
- Android Studio 微信分享功能(包括可以分享到朋友圈,分享到朋友)
- Redis内存数据库的应用场景
- 手机rom,那些你不知道的事
- Cadence IUS 之二: 生成波形
- 我的毕业实习一年总结
- 20179311《网络攻防实践》第九周作业
- 数组的操作-集大成篇
热门文章
- 还记得最初的梦想么?——2018年小结
- 分解质因数-Pollard‘s Rho
- 期货交易的安全性分析
- NV21格式图像旋转 c++,平移、缩放实现代码
- inurl_inurl,intitle指令的含义、作用及用法
- IE if注释判断( [if gte IE 8] )的解释网上的完全乱七八糟啊!
- sqlite的count
- OD和CE使用示例-Python实现win98扫雷一键标雷外挂
- c语言阿拉伯数字转大写,c++阿拉伯数字转化为中文大写
- 经济法基础(2020年)——第三章 支付结算法律制度