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

摘要:
tf提供了一个tf_echo工具来查看两个广播参考系之间的关系。rosruntftf_echoturtle1turtle2  控制一只乌龟,在终端中会看到第二只乌龟的坐标转换关系我们也可以通过rviz的图形界面更加形象的看到这三者之间的关系。world参考系的原点在最下角,对于turtle1的转换关系,其实就是turtle1在world参考系中所在的坐标位置以及旋转角度。

ubuntu 14.04 indigo版本

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

一、tf简介

1、安装turtle包

1 rosdep install turtle_tf rviz
2 rosmake turtle_tf rviz

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

2、运行demo

 roslaunch turtle_tf turtle_tf_demo.launch 

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

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

3、demo分析

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

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

使用tf工具来具体研究:

rosrun tf view_frames

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

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

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

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

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

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

rosrun tf tf_echo turtle1 turtle2  

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

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

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

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

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

移动乌龟,可以看到在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 importroslib  
3 roslib.load_manifest('learning_tf')  
4 importrospy  
5  
6  
7 importtf  
8 importturtlesim.msg  
9  
10  
11 defhandle_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()

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

创建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>

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

运行start_demo.launch文件:

roslaunch learning_tf start_demo.launch

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

可以看到界面中只有移植乌龟了,打开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 importroslib  
3 roslib.load_manifest('learning_tf')  
4 importrospy  
5 importmath  
6 importtf  
7 importturtlesim.msg  
8 importturtlesim.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 notrospy.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参考系是最顶端的父参考系,其他的参考系都需要向下延伸。如果我们在上文的基础上添加一个参考系,就需要让这个新的参考系成为已有三个参考系中的一个的子参考系。

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

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

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

1 #!/usr/bin/env python    
2 importroslib  
3 roslib.load_manifest('learning_tf')  
4  
5 importrospy  
6 importtf  
7  
8 if __name__ == '__main__':  
9     rospy.init_node('my_tf_broadcaster')  
10     br =tf.TransformBroadcaster()  
11     rate = rospy.Rate(10.0)  
12     while notrospy.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 importroslib  
3 roslib.load_manifest('learning_tf')  
4  
5 importrospy  
6 importtf  
7 importmath  
8  
9 if __name__ == '__main__':  
10     rospy.init_node('my_tf_broadcaster')  
11     br =tf.TransformBroadcaster()  
12     rate = rospy.Rate(10.0)  
13     while notrospy.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>

免责声明:文章转载自《ROS探索总结(十二)——坐标系统》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇android入门 — 多线程(一)VC++/MFC 最常用宏和指令下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

解决python3.5无法导入cv2.so的问题

问题描述: 在python3.5环境中导入cv2报错,在python2.7中正常。注:命令行的前缀RL_2018HW是python3.5的环境。 (RL_2018HW) gordon@gordon-5577:$ python Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609...

ROS机器人开发实践学习笔记3

摘要: 刚刚开始学习ROS,打算入机器人的坑了,参考教材是《ROS及其人开发实践》胡春旭编著 机械工业出版社 华章科技出品。本来以为可以按照书上的步骤一步步来,但是,too young to simple啊,程序员的苦逼日子开始了,特地记录如下。 今天居然发现,不是linux没有安装成功,只是没有办法找到boot/efi下的引导文件,充分利用Manjaro...

第01课 安装并配置ROS环境

1. 安装ROS   注意事项:      如果你是使用类似apt这样的软件管理器来安装ROS的,那么安装后这些软件包将不具备写入权限,当前系统用户比如你自己也无法对这些软件包进行修改编辑。     当你的开发涉及到ROS软件包源码层面的操作或者在创建一个新的ROS软件包时,你应该是在一个具备读写权限的目录下工作,就像在你当前系统用户的home目录下一样。...

ROS入门笔记(六):ROS系统架构

ROS入门笔记(六): ROS系统架构 1 ROS系统架构    1.1 文件系统(重点)    1.2 计算图    1.3 开源社区 1 ROS系统架构   1.1 文件系统(重点) 文件系统:主要指在硬盘里能看到的ROS目录和文件:   1)元功能包(Meta Packages):组织多个用于同一目的功能包。2)元功能包清单(Meta...

一个ROS配置的脚本

#send common msg to api :local i [/system identity get name] :local u [/system resource get uptime] :local c [/system resource get cpu-load] :local f [/system resource get free-m...

ROS知识(5)----消息与服务的示例

ROS中已经定义了较多的标准类型的消息,你可以用在这些标准类型的消息上再自定义自己的消息类型。这个在复杂数据传输很有用,例如节点和服务器进行交互时,就可能用到传输多个参数到服务器,并返回相应的结果。为了保证例子的完整,将详述每一步。 基本思路和创建talker和listener的例子类似,步骤如下: 建立工作空间workspace(类似于vs下的解决方案,...