学习tf2和时间 (c ++) [待校准@8463]
Goal目标: Learn学习如何在特定时间进行转换,并使用 lookupTransform()
函数等待转换在tf2树上可用。 [待校准@8464]
Tutorial教程级别: Intermediate中级 [待校准@6713]
时间: 10分钟 [Alyssa@7452]
背景
在之前的教程中,我们通过编写 tf2 broadcaster and a tf2 listener. We also learned how to add a new frame to the transformation tree 重新创建了turtle例程,并学习了tf2如何跟踪坐标帧树。此树随时间变化,tf2为每次转换存储时间快照 (默认情况下最多10秒)。到目前为止,我们使用 lookupTransform()
函数来访问tf2树中的最新可用变换,而不知道该变换是在什么时候记录的。本教程将教您如何在特定时间进行转换。 [待校准@8465]
任务
1 tf2和时间 [待校准@8466]
所以让我们回到我们在 adding a frame tutorial 结束的地方。前往 learning_tf2_cpp
包裹。打开 turtle_tf2_listener.cpp
,看看 lookupTransform()
调用: [待校准@8467]
transformStamped = tf_buffer_->lookupTransform(
toFrameRel,
fromFrameRel,
tf2::TimePointZero);
您可以看到,我们通过调用 “tf2:: timepointzero” 指定了等于0的时间。对于tf2,时间0表示缓冲区中的 "the latest available" 变换。现在,更改此行以获得当前时间的转换, this->get_clock()->now()
: [待校准@8468]
rclcpp::Time now = this->get_clock()->now();
transformStamped = tf_buffer_->lookupTransform(
toFrameRel,
fromFrameRel,
now);
现在尝试运行launch文件。 [待校准@8469]
ros2 launch learning_tf2_cpp turtle_tf2_demo.launch.py
您将注意到它失败并输出类似的内容: [待校准@8470]
[INFO] [1629873136.345688064] [listener]: Could not transform turtle1 to turtle2: Lookup would
require extrapolation into the future. Requested time 1629873136.345539 but the latest data
is at time 1629873136.338804, when looking up transform from frame [turtle1] to frame [turtle2]
它告诉你帧不存在或者数据在将来。 [待校准@8471]
为了理解为什么会发生这种情况,我们需要了解缓冲区是如何工作的。首先,每个侦听器都有一个缓冲区,用于存储来自不同tf2广播器的所有坐标变换。其次,当广播器发出变换时,该变换需要一些时间才能进入缓冲区 (通常为几毫秒)。因此,当您在时间 "now" 请求帧变换时,您应该等待几毫秒以使该信息到达。 [待校准@8472]
2等待转换 [待校准@8473]
tf2提供了一个很好的工具,可以等到转换可用。您可以通过向 lookupTransform()
添加超时参数来使用它。要解决此问题,请如下所示编辑代码 (添加最后一个超时参数): [待校准@8474]
rclcpp::Time now = this->get_clock()->now();
transformStamped = tf_buffer_->lookupTransform(
toFrameRel,
fromFrameRel,
now,
50ms);
[需手动修复的语法] lookupTransform()
可以接受四个参数,其中最后一个是可选的超时。它将阻塞长达该持续时间,等待其超时。 [待校准@8475]
3检查结果 [待校准@8476]
您现在可以运行launch文件。 [待校准@8477]
ros2 launch learning_tf2_cpp turtle_tf2_demo.launch.py
你应该注意到 lookupTransform()
实际上会阻塞,直到两只海龟之间的转变变得可用 (这通常需要几毫秒)。一旦达到超时时间 (在这种情况下为50毫秒),仅当转换仍然不可用时才会引发异常。 [待校准@8478]
总结
在本教程中,您学习了如何在特定时间戳获取转换,以及如何在使用 lookupTransform()
函数时等待转换在tf2树上可用。 [待校准@8479]