ROS探索总结(十二)——坐标系统

        在机器人的控制中,坐标系统是非常重要的,在ROS使用tf软件库进行坐标转换。

        相关链接:http://www.ros.org/wiki/tf/Tutorials#Learning_tf

一、tf简介

        我们通过一个小小的实例来介绍tf的作用。

1、安装turtle包

 

  1. <span>$ rosdep install turtle_tf rviz  </span>
  2. $ rosmake turtle_tf rviz

 

2、运行demo

        运行简单的demo:

        $ roslaunch turtle_tf turtle_tf_demo.launch 
        然后就会看到两只小乌龟了。

 

        该例程中带有turtlesim仿真,可以在终端激活的情况下进行键盘控制。

        可以发现,第二只乌龟会跟随你移动的乌龟进行移动。

3、demo分析

        接下来我们就来看一看到底ROS做了什么事情。
        这个例程使用tf建立了三个参考系:a world frame, a turtle1 frame, and a turtle2 frame。然后使用tf broadcaster发布乌龟的参考系,并且使用tf listener计算乌龟参考系之间的差异,使得第二只乌龟跟随第一只乌龟。
        我们可以使用tf工具来具体研究。

       $ rosrun tf view_frames 
        然后会看到一些提示,并且生成了一个frames.pdf文件。

 

        该文件描述了参考系之间的联系。三个节点分别是三个参考系,而/world是其他两个乌龟参考系的父参考系。还包含一些调试需要的发送频率、最近时间等信息。
        tf还提供了一个tf_echo工具来查看两个广播参考系之间的关系。我们可以看一下第二只得乌龟坐标是怎么根据第一只乌龟得出来的。

 

          $ rosrun tf tf_echo turtle1 turtle2 

        控制一只乌龟,在终端中会看到第二只乌龟的坐标转换关系。

 

        我们也可以通过rviz的图形界面更加形象的看到这三者之间的关系。

        $ rosrun rviz rviz -d `rospack find turtle_tf`/rviz/turtle_rviz.vcg 

 

        移动乌龟,可以看到在rviz中的坐标会跟随变化。其中左下角的是/world,其他两个是乌龟的参考系。
       下面我们就来详细分析这个实例。

二、Writing a tf broadcaster

1、创建包

  1. $ roscd tutorials  
  2. $ roscreate-pkg learning_tf tf roscpp rospy turtlesim  
  3. $ rosmake learning_tf

 

2、broadcast transforms

        我们首先看一下如何把参考系发布到tf。
        代码文件:/nodes/turtle_tf_broadcaster.py

  1. #!/usr/bin/env python    
  2. import roslib  
  3. roslib.load_manifest('learning_tf')  
  4. import rospy  
  5.  
  6.  
  7. import tf  
  8. import turtlesim.msg  
  9.  
  10.  
  11. def handle_turtle_pose(msg, turtlename):  
  12.     br = tf.TransformBroadcaster()  
  13.     br.sendTransform((msg.x, msg.y, 0),  
  14.                      tf.transformations.quaternion_from_euler(0, 0, msg.theta),  
  15.                      rospy.Time.now(),  
  16.                      turtlename,  
  17.                      "world")  #发布乌龟的平移和翻转  
  18.  
  19.  
  20. if __name__ == '__main__':  
  21.     rospy.init_node('turtle_tf_broadcaster')  
  22.     turtlename = rospy.get_param('~turtle')   #获取海龟的名字(turtle1,turtle2)  
  23.     rospy.Subscriber('/%s/pose' % turtlename,  
  24.                      turtlesim.msg.Pose,  
  25.                      handle_turtle_pose,  
  26.                      turtlename)   #订阅 topic "turtleX/pose"  
  27.     rospy.spin()

 

        创建launch文件start_demo.launch: 

  1. <launch>  
  2.     <!-- Turtlesim Node-->  
  3.     <node pkg="turtlesim" type="turtlesim_node" name="sim"/>  
  4.     <node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen"/>  
  5.  
  6.  
  7.     <node name="turtle1_tf_broadcaster" pkg="learning_tf" type="turtle_tf_broadcaster.py" respawn="false" output="screen" >  
  8.       <param name="turtle" type="string" value="turtle1" />  
  9.     </node>  
  10.     <node name="turtle2_tf_broadcaster" pkg="learning_tf" type="turtle_tf_broadcaster.py" respawn="false" output="screen" >  
  11.       <param name="turtle" type="string" value="turtle2" />   
  12.     </node>  
  13.  
  14.  
  15.   </launch>

        运行:

       $ roslaunch learning_tf start_demo.launch 
        可以看到界面中只有移植乌龟了,打开tf_echo的信息窗口:

       $ rosrun tf tf_echo /world /turtle1  

 

        world参考系的原点在最下角,对于turtle1的转换关系,其实就是turtle1在world参考系中所在的坐标位置以及旋转角度。

 

三、Writing a tf listener

        这一步,我们将看到如何使用tf进行参考系转换。首先写一个tf listener(nodes/turtle_tf_listener.py):

 

  1. #!/usr/bin/env python    
  2. import roslib  
  3. roslib.load_manifest('learning_tf')  
  4. import rospy  
  5. import math  
  6. import tf  
  7. import turtlesim.msg  
  8. import turtlesim.srv  
  9.  
  10. if __name__ == '__main__':  
  11.     rospy.init_node('tf_turtle')  
  12.  
  13.     listener = tf.TransformListener() #TransformListener创建后就开始接受tf广播信息,最多可以缓存10s  
  14.  
  15.     rospy.wait_for_service('spawn')  
  16.     spawner = rospy.ServiceProxy('spawn', turtlesim.srv.Spawn)  
  17.     spawner(4, 2, 0, 'turtle2')  
  18.  
  19.     turtle_vel = rospy.Publisher('turtle2/command_velocity', turtlesim.msg.Velocity)  
  20.  
  21.     rate = rospy.Rate(10.0)  
  22.     while not rospy.is_shutdown():  
  23.         try:  
  24.             (trans,rot) = listener.lookupTransform('/turtle2', '/turtle1', rospy.Time(0))  
  25.         except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):  
  26.             continue  
  27.  
  28.         angular = 4 * math.atan2(trans[1], trans[0])  
  29.         linear = 0.5 * math.sqrt(trans[0] ** 2 + trans[1] ** 2)  
  30.         turtle_vel.publish(turtlesim.msg.Velocity(linear, angular))  
  31.  
  32.         rate.sleep()

 

 

        在launch文件中添加下面的节点:

  1. <launch>  
  2.     ...  
  3.     <node pkg="learning_tf" type="turtle_tf_listener.py"   
  4.           name="listener" />  
  5. </launch>


 

        然后在运行,就可以看到两只turtle了,也就是我们在最开始见到的那种跟随效果。

四、Adding a frame

        在很多应用中,添加一个参考系是很有必要的,比如在一个world参考系下,有很一个激光扫描节点,tf可以帮助我们将激光扫描的信息坐标装换成全局坐标。

1、tf消息结构

        tf中的信息是一个树状的结构,world参考系是最顶端的父参考系,其他的参考系都需要向下延伸。如果我们在上文的基础上添加一个参考系,就需要让这个新的参考系成为已有三个参考系中的一个的子参考系。

 

2、建立固定参考系(fixed frame)

        我们以turtle1作为父参考系,建立一个新的参考系“carrot1”。代码如下(nodes/fixed_tf_broadcaster.py):

 

  1. #!/usr/bin/env python    
  2. import roslib  
  3. roslib.load_manifest('learning_tf')  
  4.  
  5. import rospy  
  6. import tf  
  7.  
  8. if __name__ == '__main__':  
  9.     rospy.init_node('my_tf_broadcaster')  
  10.     br = tf.TransformBroadcaster()  
  11.     rate = rospy.Rate(10.0)  
  12.     while not rospy.is_shutdown():  
  13.         br.sendTransform((0.0, 2.0, 0.0),  
  14.                          (0.0, 0.0, 0.0, 1.0),  
  15.                          rospy.Time.now(),  
  16.                          "carrot1",  
  17.                          "turtle1") #建立一个新的参考系,父参考系为turtle1,并且距离父参考系2米  
  18.         rate.sleep()

 

 

       在launch文件中添加节点:

  1. <launch>  
  2.   ...  
  3.   <node pkg="learning_tf" type="fixed_tf_broadcaster.py"  
  4.         name="broadcaster_fixed" />  
  5. </launch>


 

        运行,还是看到两只乌龟和之前的效果一样。新添加的参考系并没有对其他参考系产生什么影响。打开nodes/turtle_tf_listener.py文件,将turtle1改成carrot1:

        (trans,rot) = self.tf.lookupTransform("/turtle2", "/carrot1", rospy.Time(0)) 

 

        重新运行,现在乌龟之间的跟随关系就改变了:

3、建立移动参考系(moving frame)

        我们建立的新参考系是一个固定的参考系,在仿真过程中不会改变,如果我们要把carrot1参考系和turtle1参考系之间的关系设置可变的,可以修改代码如下:

  1. #!/usr/bin/env python    
  2. import roslib  
  3. roslib.load_manifest('learning_tf')  
  4.  
  5. import rospy  
  6. import tf  
  7. import math  
  8.  
  9. if __name__ == '__main__':  
  10.     rospy.init_node('my_tf_broadcaster')  
  11.     br = tf.TransformBroadcaster()  
  12.     rate = rospy.Rate(10.0)  
  13.     while not rospy.is_shutdown():  
  14.         t = rospy.Time.now().to_sec() * math.pi  
  15.         br.sendTransform((2.0 * math.sin(t), 2.0 * math.cos(t), 0.0),  
  16.                          (0.0, 0.0, 0.0, 1.0),  
  17.                          rospy.Time.now(),  
  18.                          "carrot1",  
  19.                          "turtle1")  
  20.         rate.sleep()<font size="3"><br></font>

        这次carrot1的位置现对于turtle1来说是一个三角函数关系了。

 

代码下载:http://download.csdn.net/detail/hcx25909/5708199

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440060.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【BZOJ - 3036】绿豆蛙的归宿(概率DAG图dp,拓扑排序,概率dp,期望的线性性)

题干&#xff1a; 随着新版百度空间的下线&#xff0c;Blog宠物绿豆蛙完成了它的使命&#xff0c;去寻找它新的归宿。 给出一个有向无环的连通图&#xff0c;起点为1终点为N&#xff0c;每条边都有一个长度。绿豆蛙从起点出发&#xff0c;走向终点。 到达每一个顶点时&#x…

【LightOJ - 1079】Just another Robbery(概率dp,概率背包)

题干&#xff1a; As Harry Potter series is over, Harry has no job. Since he wants to make quick money, (he wants everything quick!) so he decided to rob banks. He wants to make a calculated risk, and grab as much money as possible. But his friends - Hermi…

强烈推荐的TensorFlow、Pytorch和Keras的样例资源(深度学习初学者必须收藏)

目录 一、TensorFlow 二、Keras 三、Pytorch 总结 本文转自微信公众号&#xff1a;机器学习初学者 原创&#xff1a; 机器学习初学者 机器学习初学者 TensorFlow、Keras和Pytorch是目前深度学习的主要框架&#xff0c;也是入门深度学习必须掌握的三大框架&#xff0c;但…

【LightOJ - 1027】A Dangerous Maze(概率dp,数学期望)

题干&#xff1a; You are in a maze; seeing n doors in front of you in beginning. You can choose any door you like. The probability for choosing a door is equal for all doors. If you choose the ith door, it can either take you back to the same position wh…

由浅到深理解ROS(2)

ROS文件系统 用户可以直接参看官网&#xff1a; http://wiki.ros.org/ROS/Tutorials/NavigatingTheFilesystem ROS文件系统中的两个最基本的概念&#xff1a;Package和Manifest&#xff0c;即包和清单文件。 &#xff08;1&#xff09;Package是组织ROS代码的最基本单位&…

Django员工管理系统

Django员工管理系统&#xff08;ems&#xff09; 需求分析&#xff1a; 1.实现管理员的注册、登陆页面注册&#xff1a;用户名、真实名字、密码、确认密码、性别、验证码用户名需要判断是否合法、是否存在&#xff0c;loading图片提示密码和确认密码是否相同&#xff0c;load…

【LightOJ - 1104】Birthday Paradox(概率,思维)

题干&#xff1a; Sometimes some mathematical results are hard to believe. One of the common problems is the birthday paradox. Suppose you are in a party where there are 23 people including you. What is the probability that at least two people in the party…

爬虫小记

中国商标网 找到正确的入口 在此页面加入全部data数据获取xhr请求包

【LightOJ - 1038】Race to 1 Again(概率dp,数学期望)

题干&#xff1a; Rimi learned a new thing about integers, which is - any positive integer greater than 1 can be divided by its divisors. So, he is now playing with this property. He selects a number N. And he calls this D. In each turn he randomly choose…

使用matplotlib进行简单的数据展示

import numpy as np import matplotlib.pyplot as plt# 解决中文乱码 plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签 plt.rcParams[axes.unicode_minus] False # 用来正常显示负号# 建立一个坐标系 plt.subplot(1, 1, 1) # 指明x和y值 x np.array([1, 2…

由浅到深理解ROS(6)-坐标转换

转自 ROS 中对于多坐标系的处理是使用树型表示&#xff0c;在机器人自主导航中&#xff0c;ROS会构建这几个很重要的坐标系&#xff1a; base_link: 一般位于tf tree的最根部&#xff0c;物理语义原点一般为表示机器人中心&#xff0c;为相对机器人的本体的坐标系。(base_foot…

【BZOJ - 3450】Tyvj1952 Easy(数学期望,期望的线性性)

题干&#xff1a; 某一天WJMZBMR在打osu~~~但是他太弱逼了&#xff0c;有些地方完全靠运气:( 我们来简化一下这个游戏的规则 有n次点击要做&#xff0c;成功了就是o&#xff0c;失败了就是x&#xff0c;分数是按comb计算的&#xff0c;连续a个comb就有a*a分&#xff0c;comb就…

吐血推荐收藏的学位论文排版教程(完整版)

目录 01.保存的高级选项设置 02.纸张设置为A4纸大小 03.设置页边距和装订线距离 04.度量衡的设置 05.创建“论文正文”样式 06.修改论文正文样式 07.设置并修改标题样式 08.给中英文摘要、附录、等大标题套用样式 09.两个Word文档之间进行并排查看 12.一键生成多级列…

由浅到深理解ROS(7)-URDF

转自 相信许多爱好者止步于昂贵的机器人价格。虽然有了Arduino&#xff0c;但一个载重能力很弱的机器人小车成本也得一两百块钱。搭建自己的机器人更是费时费力。 所以如果你只是普通机器人爱好者&#xff0c;或者还没想好要拿机器人做什么&#xff0c;那我们还是从模拟器开始…

Apollo进阶课程 ① | 带你纵览无人车

目录 1&#xff09;无人驾驶级别的分类 2&#xff09;无人驾驶技术的关键点 3&#xff09;火热的无人驾驶 不缺独角兽 原文链接&#xff1a;Apollo进阶课程 ① | 带你纵览无人车 Apollo自动驾驶进阶课程是由百度Apollo联合北京大学共同开设的课程&#xff0c;邀请百度Apoll…

【BZOJ - 4318】OSU!(概率dp,数学期望,期望的线性性)

题干&#xff1a; osu 是一款群众喜闻乐见的休闲软件。 我们可以把osu的规则简化与改编成以下的样子: 一共有n次操作&#xff0c;每次操作只有成功与失败之分&#xff0c;成功对应1&#xff0c;失败对应0&#xff0c;n次操作对应为1个长度为n的01串。在这个串中连续的 X个…

word2vec原理详解及实战

目录 1&#xff09;前言 1.1 语言模型 1.2N-gram模型 1.3词向量表示 2&#xff09;预备知识 2.1 sigmoid函数 2.2 逻辑回归 2.3贝叶斯公式 2.4 Huffman编码 3&#xff09;神经网络概率语言模型 4&#xff09;基于Hierarchial Sodtmax模型 4.1CBOW模型 4.2 Skip-gr…

计算机网络通讯协议

网络通讯&#xff1a; 就是要把特定意义的数据通过物理介质传送给对方。把电信号变成有意义的数据&#xff1a; 以字节为单位分组&#xff0c;标识好每一组电信号的信息特征&#xff0c;按照分组的顺序来依次发送。 以太网规定&#xff1a;一组电信号为一个数据包&#xff0c…

【CodeForces - 518D】Ilya and Escalator(概率dp,数学期望)

题干&#xff1a; Ilya got tired of sports programming, left university and got a job in the subway. He was given the task to determine the escalator load factor. Lets assume that n people stand in the queue for the escalator. At each second one of the tw…

Apollo进阶课程 ② | 开源模块讲解(上)

目录 1&#xff09;无人驾驶车介绍 2&#xff09;高精地图 3&#xff09;定位 4&#xff09;感知 5&#xff09;轨迹规划 6&#xff09;控制 7&#xff09;云端 原文链接&#xff1a;Apollo进阶课程 ② | 开源模块讲解&#xff08;上&#xff09; Apollo自动驾驶进阶课…