setting up your robot with tf(一)

2024-06-23 09:38
文章标签 robot tf setting

本文主要是介绍setting up your robot with tf(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1,setting up your robot using tf     官网学习http://wiki.ros.org/tf/Tutorials

2,transform configuration

Many ROS packages require the transform tree of a robot to be published using thetf software library. At an abstract level, a transform tree defines offsets in terms of both translation and rotation between different coordinate frames. To make this more concrete, consider the example of a simple robot that has a mobile base with a single laser mounted on top of it. In referring to the robot let's define two coordinate frames: one corresponding to the center point of the base of the robot and one for the center point of the laser that is mounted on top of the base. Let's also give them names for easy reference. We'll call the coordinate frame attached to the mobile base "base_link" (for navigation, its important that this be placed at the rotational center of the robot) and we'll call the coordinate frame attached to the laser "base_laser."

许多ROS包需要机器人转换树用tf软件包来发布。在抽象层次来看,一棵转换树定义了不同的坐标系之间的转换和旋转的偏差。为了更具体,用一个例子如一个简单的机器人带有一个移动的躯干和一个简单的激光器在躯干的上面。为了更好区分,我们称这个躯干的坐标系为base_link(这个坐标系通常放在正中间),激光器的坐标系称作base_laser.

At this point, let's assume that we have some data from the laser in the form of distances from the laser's center point. In other words, we have some data in the "base_laser" coordinate frame. Now suppose we want to take this data and use it to help the mobile base avoid obstacles in the world. To do this successfully, we need a way of transforming the laser scan we've received from the "base_laser" frame to the "base_link" frame. In essence, we need to define a relationship between the "base_laser" and "base_link" coordinate frames

这样来说,让我们假设我们有一些数据来自激光器正中间的前方,也就是说,我们有一些数据在base_laser坐标系上,现在假设我们想得到这些数据并利用它来帮助躯干移动来避开障碍物,这样的话,我们需要一种方式来将我们得到的base_laser数据转换给base_link框架,因此,我们需要在base_laser和base_link坐标系之间定义一种关系。(这段话说明的是,比如我们的机器人想用激光测距来使机器人避障,当激光器得到数据之后,怎样把相对的坐标位置转换给躯干,然后使躯干移动避障,这样就需要定义激光器和躯干也就是不同的frame之间要定义一种关系)

In defining this relationship, assume we know that the laser is mounted 10cm forward and 20cm above the center point of the mobile base. This gives us a translational offset that relates the "base_link" frame to the "base_laser" frame. Specifically, we know that to get data from the "base_link" frame to the "base_laser" frame we must apply a translation of (x: 0.1m, y: 0.0m, z: 0.2m), and to get data from the "base_laser" frame to the "base_link" frame we must apply the opposite translation (x: -0.1m, y: 0.0m, z: -0.20m).

为了定义这种关系,假设我们知道激光器是在躯干的前方10cm和上方20cm,这样框架base_link和base_laser之间有一个转换偏差。如果要定义base_laser对应于base_link的数据,则需要添加一个转换关系(x:0.1......),而要定义base_link对应与base_laser的数据,只需要添加一个转换关系(x:-0.1.....)

We could choose to manage this relationship ourselves, meaning storing and applying the appropriate translations between the frames when necessary, but this becomes a real pain as the number of coordinate frames increase. Luckily, however, we don't have to do this work ourselves. Instead we'll define the relationship between "base_link" and "base_laser" once using tf and let it manage the transformation between the two coordinate frames for us. 

我们需要自己管理这种转换关系,意思是当需要的时候,我们要存储并条用合适的转换关系,但是这是一项很复杂很令人头痛的工作,尤其是当坐标系的数量增加时。幸运的是,我们不用自己做这件事了。我们只需要用tf将base_link和base_laser之间的关系定义一次,之后就让tf来帮我们管理这两个坐标系之间的转换微笑

To define and store the relationship between the "base_link" and "base_laser" frames using tf, we need to add them to a transform tree. Conceptually, each node in the transform tree corresponds to a coordinate frame and each edge corresponds to the transform that needs to be applied to move from the current node to its child. Tf uses a tree structure to guarantee that there is only a single traversal that links any two coordinate frames together, and assumes that all edges in the tree are directed from parent to child nodes

为了用tf来定义和存储base_link和base_laser框架之间的关系,我们需要将它们添加进转换树。概念上来说,转化树上的每一个节点对应一个坐标系,每一条边对应从现在的节点到它子节点之间的转换。TF利用了树形结构来定义而且是单遍历的关系来将两个坐标系连接在一起,也即假设所有的边都是从父节点到子节点。

总的来说,就是定义了一个TF转换树,而且是单遍历的树,即关系是从父节点到子节点,tf定义和存储这棵关系树后,这样框架之间的关系就很明确了,tf会帮我们调用这些关系,比如当激光器测量到距离障碍物0.3米时,由关系树知道躯干距离障碍物为0.4米,这样就能使躯干决定是否移动来躲避障碍物了微笑

3,writing code(C++)

首先要创建一个节点负责发布转换消息,然后再创建一个节点来收听通过ROS发布的转换消息并用它来转换一个点。

3.1 broadcasting a transform发布转换,发布转换base_laser-->base_link之间的转换

tf_broadcaster.cpp:

   1 #include <ros/ros.h>
   2 #include <tf/transform_broadcaster.h>
//要使用TransformBroadcaster来发布转换消息,这样就必须包括tf包里面的tranform_broadcaster.h头文件
   3 
   4 int main(int argc, char** argv){
   5   ros::init(argc, argv, "robot_tf_publisher");
   6   ros::NodeHandle n;
   7 
   8   ros::Rate r(100);
   9 
  10   tf::TransformBroadcaster broadcaster;
//创建一个TransformBroadcaster对象来发送base_link转换消息给base_laser11 
  12   while(n.ok()){
  13     broadcaster.sendTransform(
  14       tf::StampedTransform(
  15         tf::Transform(tf::Quaternion(0, 0, 0, 1), tf::Vector3(0.1, 0.0, 0.2)),
  16         ros::Time::now(),"base_link", "base_laser"));
  17     r.sleep();
//用TransformBroadcaster来发布一个转换需要五个参数:第一个为旋转转换,那个包括btQuaternion和btVector3,其中btQuaternion包括pitch,roll,yaw,而btVector3
//就对应一个转换,对应robot base的laser的偏差为x轴偏差为10cm,z轴偏差为20cm;第三个为发布一个时间戳,这里设置为now();第四个为父节点的名称,这里为base_link;第五个为子节点的
//名称,这里为base_laser18   }
  19 }
3.2 using a transform

创建完一个节点来发布base_laser-->base_link的转换消息,也就是base_laser-->base_link之间的tf转换为(0.1,0.0,0.2).

现在来创建一个节点用来使用这个转换,给base_laser框架一个值之后,使用转换来获得base_link的值。

tf_listener.cpp:

   1 #include <ros/ros.h>
   2 #include <geometry_msgs/PointStamped.h>
   3 #include <tf/transform_listener.h>
//获得TransformListener来自动订阅转换消息,也即订阅到TransformBroadcaster发布的消息
   4 
   5 void transformPoint(const tf::TransformListener& listener)
//创建一个函数,给base_laser一个点,并将它转换为base_link框架
{
   6   //we'll create a point in the base_laser frame that we'd like to transform to the base_link frame
   7   geometry_msgs::PointStamped laser_point;
//创建一个geometry_msgs::PointStamped的点,其中Stamped意思是包含一个头文件,允许我们连接一个timestamp时间戳和一个frame_id框架id,其中timestamp设为
//ros::Time(),而frame_id设为base_laser,并将它的点值设为以下那些值x:1.0,y:0.2,z:0.0;
8   laser_point.header.frame_id = "base_laser";
   9 
  10   //we'll just use the most recent transform available for our simple example
  11   laser_point.header.stamp = ros::Time();
  12 
  13   //just an arbitrary point in space
  14   laser_point.point.x = 1.0;
  15   laser_point.point.y = 0.2;
  16   laser_point.point.z = 0.0;
  17 
  18   try{
  19     geometry_msgs::PointStamped base_point;
  20     listener.transformPoint("base_link", laser_point, base_point);
  21 
  22     ROS_INFO("base_laser: (%.2f, %.2f. %.2f) -----> base_link: (%.2f, %.2f, %.2f) at time %.2f",
  23         laser_point.point.x, laser_point.point.y, laser_point.point.z,
  24         base_point.point.x, base_point.point.y, base_point.point.z, base_point.header.stamp.toSec());
  25   }
//为了将base_laser转换为base_link框架,需要使用TransformListener对象,并调用它的转换点函数transformPoint(),里面含有三个参数:想转换点的框架的名称这里为
base_link,我们从哪里转换的点这里为laser_point,转换后存储点这里为base_point
26   catch(tf::TransformException& ex){
  27     ROS_ERROR("Received an exception trying to transform a point from \"base_laser\" to \"base_link\": %s", ex.what());
  28   }
  29 }
  30 
  31 int main(int argc, char** argv){
  32   ros::init(argc, argv, "robot_tf_listener");
  33   ros::NodeHandle n;
  34 
  35   tf::TransformListener listener(ros::Duration(10));
  36 
  37   //we'll transform a point once every second每隔一秒调用一次transformPoint函数,每隔一秒转换一次
  38   ros::Timer timer = n.createTimer(ros::Duration(1.0), boost::bind(&transformPoint, boost::ref(listener)));
  39 
  40   ros::spin();
  41 
  42 }
总结: 先运行节点tf_broadcaster,在运行节点tf_listener,即先发布base_link与base_laser的关系,再通过关系来计算使用。利用的是TransformBroadcaster和TransformListener这两个对象。


























这篇关于setting up your robot with tf(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1086790

相关文章

【深度学习 走进tensorflow2.0】TensorFlow 2.0 常用模块tf.config

无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。人工智能教程 本篇文章将会教大家如何 合理分配显卡资源,设置显存使用策略。主要使用tf.config模块进行设置。下面我们一起了解下具体用法和例子。 一、指定当前程序使用的 GPU 例如,在一台具有 4 块 GPU 和一个 C

【maven】setting.xml配置国内镜像地址

1、用文本编辑器打开 setting.xml 文件 找到 <mirrors> 节点,注意不是mirror 2、加入以下配置。讲道理,只要这一个就行了。 注意不要放到注释的结构了去了。 <mirrors><mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/cont

利用Setting Provider添加保存数据项

Framework需要定制的时候,可能会增加新的数据项,setting的数据实际是从SettingProvider里面读出来的,里面有一个settings.db的文件,在第一次启动android手机的时候会在默认的文件中读取设定的值,下面就以添加一项来说明这个过程: 1)第一次启动默认值在frameworks/base/packages/SettingsProvider/res/values

Tensorflow 中train和test的batchsize不同时, 如何设置: tf.nn.conv2d_transpose

大家可能都知道, 在tensorflow中, 如果想实现测试时的batchsize大小随意设置, 那么在训练时, 输入的placeholder的shape应该设置为[None, H, W, C]. 具体代码如下所示: # Placeholders for input data and the targetsx_input = tf.placeholder(dtype=tf.float32, s

NLP-词向量-发展:词袋模型【onehot、tf-idf】 -> 主题模型【LSA、LDA】 -> 词向量静态表征【Word2vec、GloVe、FastText】 -> 词向量动态表征【Bert】

NLP-词向量-发展: 词袋模型【onehot、tf-idf】主题模型【LSA、LDA】基于词向量的静态表征【Word2vec、GloVe、FastText】基于词向量的动态表征【Bert】 一、词袋模型(Bag-Of-Words) 1、One-Hot 词向量的维数为整个词汇表的长度,对于每个词,将其对应词汇表中的位置置为1,其余维度都置为0。 缺点是: 维度非常高,编码过于稀疏,易出

亦菲喊你来学机器学习(18) --TF-IDF方法

文章目录 TF-IDF词频TF逆文档频率IDF计算TF-IDF值 应用实验使用TF-IDF1. 收集数据2. 数据预处理3. 构建TF-IDF模型对象4. 转化稀疏矩阵5. 排序取值完整代码展示 jieba分词总结 TF-IDF TF-IDF(Term Frequency-Inverse Document Frequency,词频-逆文档频率)是一种用于信息检索与文本挖掘的常用加

NLP03:使用TF-IDF和LogisticRegression进行文本分类

公众号:数据挖掘与机器学习笔记 1.TF-IDF算法步骤 1.1 计算词频 考虑到文章有长短之分,为了便于不同文章的比较,进行"词频"标准化。 1.2 计算逆文档频率 需要一个语料库(corpus),用来模拟语言的使用环境。 如果一个词越常见,那么分母就越大,逆文档频率就越小越接近0。分母之所以要加1,是为了避免分母为0(即所有文档都不包含该词)。log表示对得到的值取对数

文本数据分析-(TF-IDF)(2)

文章目录 一、TF-IDF与jieba库介绍1.TF-IDF概述2.jieba库概述 二、TF-IDF与jieba库的结合1.结合2.提取步骤 三,代码实现1.导入必要的库读取文件:3.将文件路径和内容存储到DataFrame4.加载自定义词典和停用词5.分词并去除停用词 TF-IDF(Term Frequency-Inverse Document Frequency)与jieba

tf.train.batch 和 tf.train.batch_join的区别

先看两个函数的官方文档说明 tf.train.batch官方文档地址: https://www.tensorflow.org/api_docs/python/tf/train/batch tf.train.batch_join官方文档地址: https://www.tensorflow.org/api_docs/python/tf/train/batch_join tf.train.ba

《NLP自然语言处理》—— 关键字提取之TF-IDF算法

文章目录 一、TF-IDF算法介绍二、举例说明三、示例:代码实现四、总结 一、TF-IDF算法介绍 TF-IDF(Term Frequency-Inverse Document Frequency)是一种用于信息检索与文本挖掘的常用加权技术。TF-IDF是一种统计方法,用以评估一个词语对于一个文件集或一个语料库中的其中一份文件的重要程度。词语的重要性随着它在文件中出现的次数成正比