博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ROS 中TF学习
阅读量:6540 次
发布时间:2019-06-24

本文共 4429 字,大约阅读时间需要 14 分钟。

1.什么是TF

TF是处理机器人不同位置坐标系的一个包,机器人不同部位和世界的坐标系以  tree structure 的形式存储起来,TF可以使任何两个坐标系之间的点 向量相互转化。

机器人系统是有很多坐标系系统,并且每一个坐标系系统都随时间变化,tf 可以帮助你解决这些问题:头 坐标系跟世界坐标系是什么关系,栅格图中物体的位置跟我地盘有什么关系?在地图坐标系中,底盘的位置跟现在有什么关系?

tf实例讲解:

古月君 http://blog.csdn.net/hcx25909/article/details/9255001   

http://wiki.ros.org/tf/Tutorials/tf%20and%20Time%20%28Python%29

1.1 How to broadcast transforms

1  #!/usr/bin/env python      2   import roslib   3   roslib.load_manifest('learning_tf')  4   import rospy  5     6    import tf 7   import turtlesim.msg 8   #使用 tf 完成坐标变换,订阅这个topic "turtleX/pose" 并且对每一条msg进行以下计算 9   def handle_turtle_pose(msg, turtlename):10       br = tf.TransformBroadcaster()   #将turtlebot的坐标系发到 tf tree中11       br.sendTransform((msg.x, msg.y, 0),12                        tf.transformations.quaternion_from_euler(0, 0, msg.theta),  #使用四元数完成坐标变换13                        rospy.Time.now(),               #14                       turtlename,15                        "world")16  17   if __name__ == '__main__':18       rospy.init_node('turtle_tf_broadcaster')  #添加新的节点19       turtlename = rospy.get_param('~turtle')#20       rospy.Subscriber('/%s/pose' % turtlename,   #发布的信息内容21                        turtlesim.msg.Pose,22                        handle_turtle_pose,23                        turtlename)24       rospy.spin()

 

1.2  Running the broadcaster

rosrun tf tf_echo /world /turtle1   可以查看turtle的位置确实通过广播发到了tf .

1.3How to create a tf listener

 

1 #!/usr/bin/env python   2 import roslib 3 roslib.load_manifest('learning_tf') 4 import rospy 5 import math 6 import tf     #tf 里面有定义订阅者的函数 7 import geometry_msgs.msg 8 import turtlesim.srv 9 10 if __name__ == '__main__':11     rospy.init_node('tf_turtle')12 13     listener = tf.TransformListener()  #定义listener  一旦定义listener  ,他就开始接受信息,并且可以缓冲10S.14 15     rospy.wait_for_service('spawn')   #等待服务。 spwn ,这个服务可以创建另一只乌龟16     spawner = rospy.ServiceProxy('spawn', turtlesim.srv.Spawn)17     spawner(4, 2, 0, 'turtle2')   #位置 跟名字18 19     turtle_vel = rospy.Publisher('turtle2/cmd_vel', geometry_msgs.msg.Twist,queue_size=1)20    #这一段是我们真正做的工作,我们使 turtle1是父坐标系,turtle2是子坐标系,然后就调用了listener.lookupTransform21 rate = rospy.Rate(10.0)22   while not rospy.is_shutdown(): 23       try: 24        (trans,rot) = listener.lookupTransform('/turtle2', '/turtle1', rospy.Time(0))    #可以缓冲10S内最近的信息。25       except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException): 26       continue 27    angular = 4 * math.atan2(trans[1], trans[0]) 28    linear = 0.5 * math.sqrt(trans[0] ** 2 + trans[1] ** 2) 29    cmd = geometry_msgs.msg.Twist() 30    cmd.linear.x = linear 31    cmd.angular.z = angular 32    turtle_vel.publish(cmd) 33    rate.sleep()

 

 

  在launch 里面加入 

...

1.4 Adding a frame

往tf  tree 里面加入额外的坐标系。这跟创建一个tf boardcaster有点类似,为什么要加入坐标系呢?在tf 树中是不能构成回路的、只能有一个父坐标系,但是可以有很多子坐标系

。我们先前创造的世界中有 三个坐标系,父坐标系:世界坐标系   两个子:   turtle1坐标系跟 ,turtle2坐标系。

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")   #carrot 1 是tuttle的子坐标系 18         rate.sleep()

  

 在Launch文件中加入下列, 

...

 如果将listener 中的代码修改

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

1.5 Broadcasting a moving frame

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.pi15         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()

 

转载于:https://www.cnblogs.com/xialuobo/p/6097806.html

你可能感兴趣的文章
[Re]An Intentional Life
查看>>
Codeforces Round #422 (Div. 2)
查看>>
POJ 1101 译文
查看>>
制作Linux内核
查看>>
js typeof
查看>>
创建根对象
查看>>
rails内的class关于添加了has_many或者belongs_to后如何动态添加一些额外的方法 ?...
查看>>
理解离散傅立叶变换(一. 傅立叶变换的由来)
查看>>
Python学习笔记
查看>>
canvas画一个五角心
查看>>
【算法学习笔记】84.序列DP 松弛+代价处理 CODE_VS 1048 石子归并
查看>>
【NDK开发】使用NDK开发android
查看>>
mysql 查询库表磁盘占用
查看>>
20175311 2018-2019-2 《Java程序设计》第五周学习总结
查看>>
系统项目目标文档
查看>>
我的Android进阶之旅------>Android资源文件string.xml中\u2026的意思
查看>>
我的Java开发学习之旅------>计算从1到N中1的出现次数的效率优化问题
查看>>
Entity Framework – (复数)Plural and (单数)Singular 表名Table names
查看>>
Python lambda表达式
查看>>
C#调用Python代码
查看>>