前言
在前几篇内容中,我们已经了解过了tf2广播、tf2监听,并且还了解了如何添加一个坐标系到tf2树图中,以及如何查看坐标系间的转换情况。实际上,是通过lookupTransform函数来查找的,这个函数允许我们查找所有的转换数据(我们并不需要了解这些数据是在何时被记录下来的),这节我们将学习如何获取一个特定时间的转换数据。
动动手
tf2和时间
我们打开learing_tf2_cpp包下的turtle_tf2_listener.cpp,重点关注下面这块代码:
try {
t = tf_buffer_->lookupTransform(
toFrameRel,
fromFrameRel,
tf2::TimePointZero);
} catch (const tf2::TransformException & ex) {
lookupTransform函数一共传入了3个参数,前两个分别是目标帧和源帧,最后一个是tf2::TimePointZero,其值为0,数据类型是tf2中关于时间的数据类型tf2::TimePoint(许多API都会自动处理rclcpp::time和tf2::TimePoint之间的转换),在tf2包中,这个值为0代表的是缓存中最新的可用的转换数据,我们现在来改变下这个参数(用rclcpp里面的形式),修改如下:
rclcpp::Time now = this->get_clock()->now();
try {
t = tf_buffer_->lookupTransform(
toFrameRel, fromFrameRel,
now);
} catch (const tf2::TransformException & ex) {
定义一个now变量(rclcpp::Time类型),其值为系统当前时间,重新构建下learning_tf2_cpp包,并启动launch文件:
$ros2 launch learning_tf2_cpp turtle_tf2_demo_launch.py
但是我们会得到如下的反馈信息,当前时间查找不到转换数据:
首先每一个tf2监听者节点都会保存所有tf2广播者发出的坐标转换数据到一个缓存中,其次,当一个tf2广播者发出数据到一个tf2监听者保存数据到缓存,这个过程需要毫秒级的时间消耗。所以上面的现象就很好理解了,我们要查找当前这个点的数据,但它还在路上,若干毫秒后才会被保存到缓存区,那个时候才能查找到。
等待转换数据
那么我们是不是可以设置个等待时间呢(超时时间),等待时间内数据到达则返回转换数据,如无,则一直阻塞在这里直到有数据或者到达超时时间。
修改如下:
rclcpp::Time now = this->get_clock()->now();
try {
t = tf_buffer_->lookupTransform(
toFrameRel,
fromFrameRel,
now,
50ms);
} catch (const tf2::TransformException & ex) {
添加了第四个参数为50ms,我们再重新构建包试试看。
检查结果
没有报错了,如果超时了还没数据,程序就会根据代码里面写的那样抛出一个异常(比如我们可以将超时时间改成2ms,此时就会抛出异常)。
本篇完。