学习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]