您正在阅读的是旧版本但仍受支持的 ROS 2 文档。 Jazzy.
使用时间 (C++)
目标 了解如何在特定时间获取变换,并等待变换在 tf2 树上可用。 lookupTransform()
功能。
辅导水平: 中级
时间 10 分钟
背景介绍
在之前的教程中,我们通过编写一个 tf2 广播公司 和一个 tf2 监听器.我们还学会了如何 为变换树添加新帧 并了解了 tf2 如何跟踪坐标帧树。该树会随时间变化,tf2 会为每次变换存储时间快照(默认情况下最多 10 秒)。到目前为止,我们使用 lookupTransform()
函数来获取该 tf2 树中最新的可用变换,但不知道该变换是在什么时间记录的。本教程将教你如何获取特定时间的变换。
任务
1 更新监听节点
让我们回到我们结束的地方 添加框架教程.转到 learning_tf2_cpp
包装。打开 turtle_tf2_listener.cpp
并看看 lookupTransform()
打电话:
尝试 {
t = tf_buffer_->;查找变换(
toFrameRel,
fromFrameRel,
tf2::时间点零);
} 捕捉 (缢 tf2::转换异常 及样品; 从) {
您可以看到,我们通过调用 tf2::TimePointZero
.
备注
"(《世界人权宣言》) tf2
软件包有自己的时间类型 tf2::TimePoint
与 rclcpp::Time
.软件包中的许多应用程序接口 tf2_ros
自动转换为 rclcpp::Time
和 tf2::TimePoint
.
rclcpp::Time(0、 0, this->get_clock()->get_clock_type())
本可以在这里使用,但它会被转换为 tf2::TimePointZero
不管怎么说
对于 tf2,时间 0 表示缓冲区中 "最新可用 "的变换。现在,修改这一行以获取当前时间的变换、 this->get_clock()->now()
:
rclcpp::时间 现在 = 此->;获取时钟()->;现在();
尝试 {
t = tf_buffer_->;查找变换(
toFrameRel, fromFrameRel,
现在);
} 捕捉 (缢 tf2::转换异常 及样品; 从) {
现在构建软件包并尝试运行启动文件。
ros2 launch learning_tf2_cpp turtle_tf2_demo_launch.py
你会发现它失败了,输出类似下面的内容:
[INFO] [1629873136.345688064] [listener]:无法将 turtle2 转换为 turtle1:查找将
需要推断未来。要求的时间为 1629873136.345539,但最新数据
是在时间 1629873136.338804,从画面 [乌龟 1] 向上看变换到画面 [乌龟 2] 时
它会告诉你该帧不存在或数据在未来。
要理解为什么会出现这种情况,我们需要了解缓冲区是如何工作的。首先,每个监听器都有一个缓冲区,用于存储来自不同 tf2 广播器的所有坐标变换。其次,当广播者发送变换时,变换进入缓冲区需要一些时间(通常是几毫秒)。因此,当您在 "现在 "时间请求帧变换时,您需要等待几毫秒才能收到该信息。
2 修复监听节点
tf2 提供了一个很好的工具,可以等待变换可用。使用方法是在 lookupTransform()
.要解决这个问题,请按下图所示编辑代码(添加最后一个超时参数):
rclcpp::时间 现在 = 此->;获取时钟()->;现在();
尝试 {
t = tf_buffer_->;查找变换(
toFrameRel,
fromFrameRel,
现在,
50毫秒);
} 捕捉 (缢 tf2::转换异常 及样品; 从) {
"(《世界人权宣言》) lookupTransform()
可以接受四个参数,其中最后一个参数是可选的超时时间。在超时之前,它会阻塞一段时间。
3 检查结果
现在您可以构建软件包并运行启动文件。
ros2 launch learning_tf2_cpp turtle_tf2_demo_launch.py
您应该注意到 lookupTransform()
实际上会阻塞,直到两只海龟之间的变换可用(通常需要几毫秒)。一旦超时(本例中为 50 毫秒),只有在变换仍不可用时才会出现异常。
摘要
在本教程中,您将学习如何在特定时间戳获取变换,以及在使用 lookupTransform()
功能。