这篇博客讲解 如何在使用lookupTransform() 函数时, 监听指定时间一定延时内的 可以用的坐标变换
1、TF2 和 时间
在之前的博客 TF2 监听者的例子中 , 可以 获取 坐标变换树中 最新的 信息。
坐标变换树随时间改变,TF2会存储1段时间,每个坐标系的变换信息(默认是10s)
当我们通过使用lookupTransform() 函数获得最新的有效坐标变换时,并不知道这个变化发生的具体时间。可能由于某种原因 得到了很久之前的 坐标变换,导致系统出现错误。
例如 在1s时产生了有效的坐标变换,后发生故障,在10s时,我们像以前一样获取坐标变换,此时依然可以成功获取,但是是1s时产生的,类似这种情况就不是我们想要的了。 下面 主要讲解避免这种情况的方法
获取一个坐标变换在指定的时间
2、初步尝试 在指定时间获得 坐标变换
打开 TF2 监听者的例子 就是这篇博客写的
把 src/turtle_tf2_listener.cpp 这个文件 的 lookupTransform() 函数 进行 修改
改成下面的形式
把坐标系设置为 乌龟2 和 乌龟1 , 时间 改 为 now
之前是这样
try{
transformStamped = tfBuffer.lookupTransform("turtle2", "turtle1", ros::Time(0));
} catch (tf2::TransformException &ex) {
ROS_WARN("Could NOT transform turtle2 to turtle1: %s", ex.what());
}
改成这样
try{
transformStamped = tfBuffer.lookupTransform("turtle2", "turtle1", ros::Time::now());
} catch (tf2::TransformException &ex) {
ROS_WARN("Could NOT transform turtle2 to turtle1: %s", ex.what());
}
- ros::Time(0) 指的是 在buffer中最新可用的坐标变换
- ros::Time::now() 指的是 当前的坐标变换
编译运行下
会发现乌龟2 不像 之前例子中会自动跑到乌龟1 处
坐标变换失败了,原因如下:
每一个监听者会用一个buffer取存储所有的坐标变换有广播者发布的。当广播者发布一个坐标变换,会花一点时间存在buffer中,通常时几毫秒(0.007s)。所有当请求一个坐标变换的时间为 ros::Time::now() 的时候,不会立马有,要等几毫秒。
所有上面直接写 ros::Time::now() 这个方式就失败了
3、等待坐标变换
TF2 提供了 一种方式 ,在指定的时间上,等待一段时间 有效的坐标变换到来。
lookupTransform()函数有第四个参数,就是做这个用的。
把该部分代码改成如下形式
try{
transformStamped = tfBuffer.lookupTransform("turtle2", "turtle1", ros::Time::now(),
ros::Duration(3.0));
} catch (tf2::TransformException &ex) {
ROS_WARN("Could NOT transform turtle2 to turtle1: %s", ex.what());
}
ros::Duration(3.0) 这个 就是 说明 在请求当前时刻的坐标变换时 允许等待 3 s 的时间。
改成这种方式 再编译 运行
乌龟2 又会自动回到 乌龟1 上
在大部分的 TF2 使用的情况下 ros::Time(0) 使用的情况 更多些 。
ros::Time::now() 加 ros::Duration(3.0) 更加 严谨。