智能机器人(77):ROS的TF-transform(04)

使用变换的方式, 如何跟踪坐标系树?

这棵tf-tree一直随着时间的推移而变化,并且每个变换都被存储了时间快照,默认的是最多保存10秒之内的。
可以用lookupTransform()函数来访问该tf-tree中最新的可用转换,但其实并不知道该转换会在什么时间发生。

例如,以下广播了一个新的坐标系转换,从父turtle1到新的carrot1,carrot1的左偏离turtle1了2米:
br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), “turtle1”, “carrot1”));
这里现给变换一个时间戳,用的就是当前时间ros :: Time :: now()。

随后, 可以开始使用carrot1的各种信息了:
listener.lookupTransform(“/turtle2”, “/carrot1”, ros::Time(0), transform);
这里指定了一个等于0的时间,对于tf来说, time0就是表示缓冲区中最新可用的变换。

当然,也可以获取特定的时间所进行的转换, 例如, 改为当前时间的变换:
listener.lookupTransform(“/turtle2”, “/carrot1”, ros::Time::now(), transform);

但是这时候, lookupTransform会失败,反复出错说:
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 /carrot1 and /turtle2.

或者这样的出错:
Exception thrown:
Lookup would require extrapolation into the past.
Requested time 1516087296.727826475 but the earliest data is at time 1516087297.522204578,
when looking up transform from frame [laser_link] to frame [map]

或者:
Transform [sender=unknown_publisher]
For frame [laser_link]: No transform to fixed frame [map]. TF error: [Lookup would require extrapolation into the future. Requested time 1516092877.852408757 but the latest data is at time 1516092875.632156846, when looking up transform from frame [laser_link] to frame [map]]

为什么?

因为每个listener都有一个缓冲区,存储来自不同broadcaster的所有坐标变换。
而当broadster发送一个转换时,该转换真正进入缓冲区需要几个毫秒的时间。

所以,如果在“现在”的时刻请求请求“现在“进行的转换的时候,应该等待几毫秒才能到达。
ros::Time now = ros::Time::now();
listener.waitForTransform(“/turtle2”, “/carrot1”, now, ros::Duration(3.0));
listener.lookupTransform(“/turtle2”, “/carrot1”, now, transform);
意思是,等待从这个t1到c1的变换,在now这个时候,等待不要超过3.0这个最长持续时间。

因此,这个waitForTransform()实际上会阻塞,直到两个frame间的转换可用;
这通常需要几毫秒,或者,严重的,如果转换一直不可用,那么一直等到3.0second的超时。

总结: lookupTransform是一个较低级别的方法,它返回两个坐标系之间的变换,这个方法是tf库的核心功能
然而最常见的是transform *方法,将被最终用户使用。
这个方法被设计用于transform *()方法中。

0 回复

发表评论

Want to join the discussion?
Feel free to contribute!

发表评论