ROS Learning-021 learning_tf-05(编程) now() 和 Time(0) 的区别 (Python版)
2016-09-08 17:07
639 查看
ROS Indigo learning_tf-05 now()
和 Time(0)
的区别 (Python版) — waitForTransform()
函数
我使用的虚拟机软件:VMware Workstation 11使用的Ubuntu系统:Ubuntu 14.04.4 LTS
ROS 版本:ROS Indigo
一. 前言
这一节要做的事情:使用 tf 的now()和
Time(0)的区别 。
为什么要讲这个,这是因为 ROS 的 tf 在进行坐标之间的转换变换不是实时的转换,它有一个缓冲器来存放一段时间的坐标转换数据,所以有时,可能没有当前时间的坐标转换数据,使用
lookupTransform()函数就可以得到你想的某个时间的坐标数据,前提是缓冲区里要有这个时间的坐标数据,tf 的坐标转换是自动计算的,所以有时,你想得到当前的时间的坐标转换数据,你调用
lookupTransform()函数去获取,但是缓冲器里还没有来得及去计算现在的坐标转换数据,就是说:现在还没有。如果你非要获取,就会出错,所以你要使用
waitForTransform()函数来等待 tf 的坐标转换线程得到你想要的时间点的坐标转换数据。
简单的说:
waitForTransform()就是一个安全程序。
什么意思,下面编写程序,让大家深入理解:
二. 写程序
1 . 讲解
代码就是下面这个样子:learning_tf软件包中的
nodes/turtle_tf_listener.py:
将源代码中:
---- rate = rospy.Rate(10.0) while not rospy.is_shutdown(): try: (trans,rot) = listener.lookupTransform('/turtle2', '/turtle1', rospy.Time(0)) except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException): continue ----
修改为:
---- rate = rospy.Rate(10.0) listener.waitForTransform("/turtle2", "/turtle1", rospy.Time(), rospy.Duration(4.0)) while not rospy.is_shutdown(): try: now = rospy.Time.now() listener.waitForTransform('/turtle2', '/turtle1', now, rospy.Duration(4.0)) (trans,rot) = listener.lookupTransform('/turtle2', '/turtle1', now) except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException): continue ----
Q: 如果你在
try里使用了
waitForTransform()函数,但是在
while外并没有
waitForTransform(),程序就不正常运行。 为什么必须要有while外的
waitForTransform()函数?为什么要调用
waitForTransform()函数?
A: 在程序的开始,我们 再生(
/spawn服务)了一个
turtle2,但是在
waitForTransform()函数执行的时候,
tf里可能还没有
turtle2坐标系,就是
turtle2还没有 再生 完成。
所以,第一个
waitForTransform()函数将会等到
turtle2坐标系 再生 完成。
第二个
waitForTransform()函数将会等到
now时间的坐标系转换完成,在缓冲器中有。
waitForTransform()函数的4个形参:
waitForTransform( [父类坐标系], [子类坐标系], [在这一时刻], rospy.Duration(4.0) )
rospy.Duration(4.0): 为
waitForTransform()函数 的结束条件:最多等待
4秒,如果提前得到了坐标的转换信息,直接结束等待。
2 . 编写代码
在learning_tf程序包中的
nodes路径下,新建一个文件:
turtle_tf_listener_timeTravel.py:
roscd learning_tf/node/ gedit turtle_tf_listener_timeTravel.py
下面是完整的程序。将这段程序复制到
turtle_tf_listener_timeTravel.py文件里面:
#!/usr/bin/env python import roslib roslib.load_manifest('learning_tf') import rospy import math import tf import geometry_msgs.msg import turtlesim.srv if __name__ == '__main__': rospy.init_node('tf_turtle') listener = tf.TransformListener() rospy.wait_for_service('spawn') spawner = rospy.ServiceProxy('spawn', turtlesim.srv.Spawn) spawner(4, 2, 0, 'turtle2') turtle_vel = rospy.Publisher('turtle2/cmd_vel', geometry_msgs.msg.Twist, queue_size=1) rate = rospy.Rate(10.0) listener.waitForTransform("/turtle2", "/turtle1", rospy.Time(), rospy.Duration(4.0)) while not rospy.is_shutdown(): try: now = rospy.Time.now() listener.waitForTransform('/turtle2', '/turtle1', now, rospy.Duration(4.0)) (trans,rot) = listener.lookupTransform('/turtle2', '/turtle1', now) except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException): continue angular = 4 * math.atan2(trans[1], trans[0]) linear = 0.5 * math.sqrt(trans[0] ** 2 + trans[1] ** 2) cmd = geometry_msgs.msg.Twist() cmd.linear.x = linear cmd.angular.z = angular turtle_vel.publish(cmd) rate.sleep()
给这个文件添加可执行权限:
chmod 777 turtle_tf_listener_timeTravel.py
3 . 编写启动文件
在learning_tf程序包中的
launch路径下,新建一个文件:
start_demo5.launch:
roscd learning_tf/launch/ gedit start_demo5.launch
将下面的代码拷贝进去。(下面这段代码就是通过
start_demo2.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_timeTravel.py" name="listener" /> </launch>
4 . 运行
运行start_demo5.launch这个启动脚本文件:
$ roslaunch learning_tf start_demo5.launch
运行效果:看起来和之前 “ 编写一个 监听器 程序 ”这一节的运行效果一样 。
Q: 你肯定会问这样的问题:
rospy.Time.now()和
rospy.Time(0)有什么不同吗?运行时的效果都一样?
A: 虽然,你注意到 小海龟的行为 没有明显的变化。那是因为:实际的时间只差几毫秒的不同。但是我们为什么有时使用
Time(0),有时使用
now()。我这里只是想告诉你:tf 缓冲和时间延迟是相关联的。在实际使用
tf时,这2个可以认为是等同的。
Time(0): 是 tf 缓存里的第一个 tf 信息。
now(): 是当前这个时间的 tf 信息。
总结: 现在,我们知道了
now()和
Time(0)的区别,那它们究竟有什么用呢?下一节,我带你在 ROS 中进行现在与过去中的时间穿梭,你就知道了。
下一节: 现在与过去中穿梭 (Python版) —
waitForTransformFull()函数。
相关文章推荐
- ROS Learning-021 learning_tf-05(编程) now() 和 Time(0) 的区别 (Python版)
- ROS Learning-015 learning_tf(编程) 编写一个监听器程序 (Python版)
- ROS Learning-020 learning_tf-04(编程)让turtle2 海龟跟随turtle1海龟,并绕着 turtle1海龟转圈 (Python版)
- ROS Learning-020 learning_tf-04(编程)让turtle2 海龟跟随turtle1海龟,并绕着 turtle1海龟转圈 (Python版)
- ROS Learning-015 learning_tf(编程) 编写一个监听器程序 (Python版)
- ROS Learning-014 learning_tf(编程) 坐标系变换(tf)广播员 (Python版)
- ROS Learning-014 learning_tf(编程) 坐标系变换(tf)广播员 (Python版)
- ROS Learning-022 learning_tf-06(编程) 现在与过去中穿梭 (Python版) --- waitForTransformFull() 函数
- ROS Learning-019 learning_tf-03(编程) 添加额外的坐标系 (Python版)
- ROS Learning-022 learning_tf-06(编程) 现在与过去中穿梭 (Python版) --- waitForTransformFull() 函数
- ROS:关于tf的探索(4)Learning about tf and time(Python)
- ROS Learning-019 learning_tf-03(编程) 添加额外的坐标系 (Python版)
- python2.7和python3.4网络编程处理二进制数据区别
- ROS Learning-013 beginner_Tutorials (编程) 编写ROS服务版的Hello World程序(Python版)
- VB中now,date,time内部函数的几点区别
- Learning Python(17)--多线程编程之线程的局部变量
- 05 数字 - 《Python 核心编程》
- python time 与datetime之间的区别与联系
- python time 与datetime之间的区别与联系
- ROS Learning-011 beginner_Tutorials (编程) 编写 ROS 话题版的 Hello World 程序(Python版)