ROS与C++入门教程-tf-深入Time和TF
ROS与C++入门教程-tf-深入Time和TF
说明:
- 介绍使用waitForTransform函数去等待TF树中的变换生效
TF和Time
- 在前面的教程中,我们了解了tf如何跟踪坐标系树。
- 此树随时间变化,tf存储每个变换的时间快照(默认情况下最多为10秒)。
- 直到现在,我们使用lookupTransform()函数来获取该tf树中最新的可用变换,而不知道什么时候记录变换。
- 本教程将教您如何在特定时间获取转换。
- 在上个教程的文件上修改:
$ roscd learning_tf
$ vim src/turtle_tf_listener.cpp
- 找到代码:
try{
listener.lookupTransform("/turtle2", "/carrot1",
ros::Time(0), transform);
- 修改为:
try{
listener.lookupTransform("/turtle2", "/turtle1",
ros::Time(0), transform);
- 更改/turtle2跟随/turtle1,不是/carrot1,我们指定了时间为0,即获得最新有效的变换。
- 改变获取当前时间的变换,即改为now(), 修改代码:
try{
listener.lookupTransform("/turtle2", "/turtle1",
ros::Time::now(), transform);
- 编译运行:
$ catkin_make
$ roslaunch learning_tf start_demo.launch
- lookupTransform()函数提示失败:
[ERROR] [1287871653.885277559]: You requested a transform that is 0.018 miliseconds in the past, but the most recent transform in the tf buffer is 7.681 miliseconds old.
When trying to transform between /turtle1 and /turtle2.
- 这是为什么? 每个监听器有一个缓冲区,它存储来自不同tf广播者的所有坐标变换。 当广播者发出变换时,变换进入缓冲区之前需要一些时间(通常是几个毫秒)。 因此,当您在时间“now”请求坐标系变换时,您应该等待几毫秒以获得该信息。
等待变换
- tf提供了一个很好的工具,它将等待,直到变换可用。
- 修改代码为:
try{
ros::Time now = ros::Time::now();
listener.waitForTransform("/turtle2", "/turtle1",
now, ros::Duration(3.0));
listener.lookupTransform("/turtle2", "/turtle1",
now, transform);
waitForTransform() 四个参数:
- 1.需要等待变换从坐标系turtle2
- 2.到坐标系turtle1
- 3.在now时间
- 4.超时时间,不要等待超过此最大持续时间
注意:使用ros::Time::now()是为了这个例子。通常这将是希望被转换的数据的时间戳。
所以waitForTransform()实际上会阻塞直到两个海龟之间的变换可用(这通常需要几毫秒)
或者如果变换不可用,直到达到超时。
编译运行:
$ catkin_make
$ roslaunch learning_tf start_demo.launch
- 但等待,您可能仍会看到错误一次(错误msg可能会有所不同):
[ERROR] [1287872014.408401177]: You requested a transform that is 3.009 seconds in the past, but the tf buffer only has a history of 2.688 seconds.
When trying to transform between /turtle1 and /turtle2.
- 这是因为turtle2需要非零时间来生成并开始发布tf帧。 因此,第一次请求现在时间的/turtle2坐标系可能不存在,当请求转换时,转换可能不存在,并且第一次失败。 在第一次变换之后,所有的变换都存在,并且乌龟的行为如预期的那样。
检查结果
- 现在,你应该能够使用箭头键(确保你的终端窗口是活跃的,而不是你的模拟器窗口),你会看到第二只乌龟跟随第一只乌龟!
- 所以,你注意到乌龟的行为没有明显的区别。 这是因为实际的时间差只有几个毫秒。 但是为什么我们从Time(0)到now()进行这种改变? 只是教你关于tf缓冲区和与它相关的时间延迟。对于真实的tf用例,使用Time(0)通常是完全正常的。
获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号