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

ubuntu 14.04  indigo版本

转摘自:http://www.guyuehome.com/265

一、tf简介

1、安装turtle包

1 rosdep install turtle_tf rviz
2 rosmake turtle_tf rviz

2、运行demo

 roslaunch turtle_tf turtle_tf_demo.launch 

程序带turtlesim仿真,直接在终端进行键盘控制,可以看到两只小乌龟运行了。

3、demo分析

上例中使用tf建立了三个参考系:a world frame,a turtle1 frame, aturtle2 frame.

然后,使用tf broadcaster发布乌龟的参考系,使用tf listener计算乌龟参考系之间的差异,使用第二只乌龟跟随第一只乌龟。

使用tf工具来具体研究:

rosrun tf view_frames

 

可以看到生成了一个frames.pdf文件:

该文件描述了参考系之间的关系,三个节点分别是三个参考系,而/word是其他两个乌龟参考系的父参考系。还包含一些调试需要的发送频率、最近时间等信息。

tf提供了一个tf_echo工具来查看两个广播参考系之间的关系。第二只乌龟坐标如何根据第一只乌龟得出来。

rosrun tf tf_echo turtle1 turtle2  

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

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

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

移动乌龟,可以看到在rviz中的坐标会跟随变化。其中左下角的是/world,其他两个是乌龟的参考系。

二、Writing a tf broadcaster

1、创建一个包

在catkin_ws/src下,创建一个learning_tf包

1 cd ~/catkin_ws/src
2 catkin_create_pkg learning_tf tf roscpp roscp turtlesim
3 cd ..
4 catkin_make

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>

运行start_demo.launch文件:

roslaunch learning_tf start_demo.launch

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

rosrun tf tf_echo /world /turtle1

注意,/world 与 /turtle1中间有空格。

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

三、Writing a tf listener

如何使用tf进行参考系转换。

先建一个listener(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”。代码如下: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>

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>
时间: 2024-10-15 18:32:57

ROS探索总结(十二)——坐标系统的相关文章

ROS学习(十二)—— 编写简单的消息发布器和订阅器(C++)

一.创建发布器节点 1 节点功能: 不断的在ROS网络中广播消息 2 创建节点 (1)打开工作空间目录 cd ~/catkin_ws/src/beginner_tutorials p { margin-bottom: 0.25cm; line-height: 120% } a:link { } 创建一个发布器节点("talker"),它将不断的在ROS网络中广播消息. --> { } (2)创建src文件夹 mkdir -p ~/catkin_ws/src/beginner_tu

【C++探索之旅】第一部分第十二课:指针一出,谁与争锋

内容简介 1.第一部分第十二课:指针一出,谁与争锋 2.第一部分第十三课预告:第一部分小测验 指针一出,谁与争锋 上一课<[C++探索之旅]第一部分第十一课:小练习,猜单词>中,我们用一个小游戏来总结了之前几课学习的知识点. 现在,终于来到第一部分的最后一个知识点了,也是C++的基础部分的最后一个讲题.之后进入第二部分,就会开始面向对象之旅.因此,这一课也注定不平凡.系好安全带吧,因为马力要加足了! 指针这个C系语言的难点(著名的C语言里也有指针),令无数英雄"尽折腰",也

NeHe OpenGL教程 第二十二课:凹凸映射

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第二十二课:凹凸映射 凹凸映射,多重纹理扩展: 这是一课高级教程,请确信你对基本知识已经非常了解了.这一课是基于第六课的代码的,它将建立一个非常酷的立体纹理效果. 这一课由Jens Schneider所写,它基本上是由第6课改写而来

程序员的无奈(十二):终于获得了投资

没想到前期开发的那款手机应用居然给我们带来的项目投资.这是一家以研发为主的公司,他们投资的要求就是把那款手机软件的研发权交出去,公司会定期的给我们一定的研发费用,我们可以随意支配这笔资金,但是必须每两个月向这家公司提供一份我们的任务计划及执行情况.这一点让我想起了IBM的转型史,我们彼此不受约束,依旧按照我们自己的工作安排时间,只要拿得出成果,就能取得下一轮的研发资金,别说对那两个实习生,就是我和我媳妇也有些把持不住了.从此我们的团队就开始成型,一共四个人,我负责方向,我媳妇负责财务和人力,另外

凯文&#183;凯利最新演讲完整版:未来的十二个趋势

凯文·凯利最新演讲完整版:未来的十二个趋势 凯文·凯利(KK)<连线>(Wired)杂志创始主编.著有<失控>.<科技想要什么>.<技术元素>.<必然>. KK在深圳分享了未来将发生的十二个趋势: 一.所有的产业都在向分散式结构靠拢 1.“个体专家”分散式: 世界正在发生着翻天覆地的变化,在变动和未知的情况下,就没有所谓的专家了,每一个人都可以做出一些变革和创新,也就都有可能成为专家. 2.企业组织结构分散式: 层级化结构变成分散式的网络结构是一

天猫技术专家:测试十二年,六道轮回后的初心能否找回

摘要: 本期作者简介:高翔,天猫技术部测试开发专家. 很久没写文章了,之前测试十年,也是在自己有变化的时候 ,强迫自己写了一篇文章,说了自己的困惑和痛苦和思考,也得到一些共鸣.现在测试十二年了,相当于一个轮回,也有一些新的痛苦和感悟,趁还在这个圈子里面,纪念一下,当然了,YY比较多,干货也不多,反正纪念下,或许我是真的不太可能写测试15年的文章了. 本期作者简介:高翔,天猫技术部测试开发专家. 很久没写文章了,之前测试十年,也是在自己有变化的时候 ,强迫自己写了一篇文章,说了自己的困惑和痛苦和思

ROS探索总结(一)——ROS简介

转自古-月 ROS探索总结(一)--ROS简介 一.历史 随着机器人领域的快速发展和复杂化,代码的复用性和模块化的需求原来越强烈,而已有的开源机器人系统又不能很好的适应需求.2010年Willow Garage公司发布了开源机器人操作系统ROS(robot operating system),很快在机器人研究领域展开了学习和使用ROS的热潮. ROS系统是起源于2007年斯坦福大学人工智能实验室的项目与机器人技术公司Willow Garage的个人机器人项目(Personal Robots Pr

从零开始学习PYTHON3讲义(十二)画一颗心送给你

(内容需要,本讲使用了大量在线公式,如果因为转帖网站不支持公式无法显示的情况,欢迎访问原始博客.) <从零开始PYTHON3>第十二讲 上一节课我们主要讲解了数值计算和符号计算.数值计算的结果,很常用的目的之一就是用于绘制图像,从图像中寻找公式的更多内在规律. Python科学绘图 科学绘图是计算机图形学的一个重要分支.同其它绘图方式相比,更简单易用,能让使用者把工作的主要精力集注在公式和算法上而不是绘图本身.此外科学绘图的工具包普遍精度更高,数据.图的对应关系准确,从而保证基于图的研究工作顺

42. 蛤蟆的数据结构笔记之四十二图的遍历之广度优先

42. 蛤蟆的数据结构笔记之四十二图的遍历之广度优先 本篇名言:"生活真象这杯浓酒 ,不经三番五次的提炼呵 , 就不会这样一来可口 ! -- 郭小川" 继续看下广度优先的遍历,上篇我们看了深度遍历是每次一个节点的链表是走到底的. 欢迎转载,转载请标明出处:http://write.blog.csdn.net/postedit/47029275 1.  原理 首先,从图的某个顶点v0出发,访问了v0之后,依次访问与v0相邻的未被访问的顶点,然后分别从这些顶点出发,广度优先遍历,直至所有的

C和指针 (pointers on C)——第十二章:使用结构和指针

第十二章 使用结构和指针 这章就是链表.先单链表,后双向链表. 总结: 单链表是一种使用指针来存储值的数据结构.链表中的每个节点包含一个字段,用于指向链表的下一个节点. 有一个独立的根指针指向链表的第1个节点.单链表只能从一个方向遍历. 如何insert单链表:1.新节点的link字段必须设置为指向它的后面节点.2.前一个节点的link字段必须指向这个新节点. 为了防止可能会插入链表的起始位置这种情况,在C中,可以保存一个指向必须进行修改的link字段的指针,而不是保存一个指向前一个节点的指针.