ROS Indigo learning_tf-03 添加额外的坐标系 (Python版)
我使用的虚拟机软件:VMware Workstation 11
使用的Ubuntu系统:Ubuntu 14.04.4 LTS
ROS 版本:ROS Indigo
前言
这一节要做的事情:添加额外的坐标系。为什么要添加额外的坐标系:
对于许多任务很容易想到内嵌一个局部的坐标系。例如,将激光扫描仪的中心作为坐标系原点的激光扫描的结果更容易被理解。 TF 允许您为每个传感器、连杆等系统定义局部坐标系。
还是在 learning_tf
软件包中的 nodes
文件夹中创建一个 fixed_tf_broadcaster.py
文件:
$ roscd learning_tf
$ gedit nodes/fixed_tf_broadcaster.py
并将下面的代码添加进去:
#!/usr/bin/env python
import roslib
roslib.load_manifest('learning_tf')
import rospy
import tf
import math
if __name__ == '__main__':
rospy.init_node('my_tf_broadcaster')
br = tf.TransformBroadcaster()
rate = rospy.Rate(10.0)
while not rospy.is_shutdown():
t = rospy.Time.now().to_sec() * math.pi
br.sendTransform((2.0 * math.sin(t), 2.0 * math.cos(t), 0.0),
(0.0, 0.0, 0.0, 1.0),
rospy.Time.now(),
"carrot1",
"turtle1")
rate.sleep()
代码讲解:
最后一步,给这个 fixed_tf_broadcaster.py
文件加上可执行权限:
$ chmod +x fixed_tf_broadcaster.py
和前几节一样,上面的程序是一个节点,我们需要编写一个启动脚本文件,将几个节点同时运行,才能看到效果:
$ roscd learning_tf/launch
$ gedit start_demo3.launch
所以,在 start_demo2.launch
文件的 <launch>
便签里面添加下面这句,另存为:start_demo3.launch
:
<node pkg="learning_tf" type="fixed_tf_broadcaster.py" name="broadcaster_fixed" />
完整的 start_demo3.launch
:
<launch>
<!-- Turtlesim Node -->
<node pkg="turtlesim" type="turtlesim_node" name="sim" />
<node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen" />
<node name="turtle1_tf_broadcaster" pkg="learning_tf" type="turtle_tf_broadcaster.py" respawn="false" output="screen" >
<param name="turtle" type="string" value="turtle1" />
</node>
<node name="turtle2_tf_broadcaster" pkg="learning_tf" type="turtle_tf_broadcaster.py" respawn="false" output="screen" >
<param name="turtle" type="string" value="turtle2" />
</node>
<node pkg="learning_tf" type="turtle_tf_listener.py" name="listener" />
<node pkg="learning_tf" type="fixed_tf_broadcaster.py" name="broadcaster_fixed" />
</launch>
运行 start_demo3.launch
启动脚本文件:
$ roslaunch learning_tf start_demo3.launch
程序运行的效果,和上一节的是一样的。这是为什么?
因为我们没有启动名字叫 ” carrot1
” 的节点。我们现在可以使用 rosnode list
将当前运行的节点都列出来:
$ rosnode list
/broadcaster_fixed
/listener
/rosout
/sim
/teleop
/turtle1_tf_broadcaster
/turtle2_tf_broadcaster
里面没有 “ carrot1
” 这个节点。但是,我们将当前的 tf
树型关系图: ( tf
关系树) (新的命令)
$ rosrun rqt_tf_tree rqt_tf_tree
我们现在可以使用 rosrun tf tf_echo /turtle1 /carrot1
命令来将 carrot1
的 tf
信息打印到终端上:
$ rosrun tf tf_echo /turtle1 /carrot1
在之前的博客里面,我们讲过:
tf_echo
关键字 : 打印出 源坐标系 和 目标坐标系 之间的特定转换信息。
$ rosrun tf tf_echo [源坐标系(父类)] [目标坐标系(子类)]
输出的信息:
这个结果是正确的,因为‘carrot1’ 绕着 ‘turtle1‘做半径为2的圆周运动。(上面打印出来的 ’ carrot1 ’ 的tf
信息 是以 ’ turtle1 ’ 为坐标原点 做参考的。)
我们上面编程的fixed_tf_broadcaster.py
程序它做了什么你知道吗?
它只是将 carrot1
的 tf
信息广播了出来,并没有给 /carrot1/cmd_vel
这个话题发布消息,并且我们也没有再生( spawn )一个 ” carrot1 ” 小海龟。所以,结果就是现在这个样子。
By The Way :
上面出现的 tf
关系树,下面我做以解释:
Tf 建立了一个坐标系的关系树型图。一个坐标系节点只能有一个父类,可以有多个子类。
现在你要添加一个坐标系( carrot1 )到这个树型关系图中, 就必须选择一个已有的坐标系(turtle1、turtle2、world)作为父类,而这个新的坐标系( carrot1 )就是子类。 如图:
总结:
其实这一节想要讲的内容已经讲完了:就是如何新建一个 tf 坐标系。
ok , 这一节,就已经介绍完了。因为这一节,我们还有没有看到小海龟窗口中小海龟什么新的动作。
所以,下一节我们在写一个新的监听坐标系变化的程序,希望看到的运行效果是: turtle2 海龟围绕着 ’ turtle1 ’ 海龟转圈。(因为:’ turtle2 ’ 小海龟设置在 ’ carrot1 ’ 这个坐标系节点上,而 carrot
坐标系节点围绕这个 turtle1
坐标系节点做画圆的变化。)