Traveling in time (C++)

目标:了解 tf2 的高级时间旅行功能。

教程级别:中级

时间:10 分钟

背景

在上一篇教程中,我们讨论了 tf2 和时间的基础知识

本教程将带我们更进一步,揭示一个强大的 tf2 技巧:时间旅行。

简而言之,tf2 库的一个关键特性是它能够在时间和空间中转换数据。

这个 tf2 时间旅行功能可用于各种任务,例如长时间监控机器人的姿势或构建跟随领导者“脚步”的跟随机器人。

我们将使用该时间旅行功能查找时间上的变换,并编程“turtle2”以在“carrot1”后面 5 秒跟随。

时间旅行

首先,让我们回到上一个教程 使用时间 中结束的地方。

转到您的 learning_tf2_cpp 包。

现在,我们不会让第二只海龟去胡萝卜现在所在的位置,而是让第二只海龟去第一只胡萝卜 5 秒前所在的位置。

编辑 turtle_tf2_listener.cpp 文件中的 lookupTransform() 调用以

rclcpp::Time when = this->get_clock()->now() - rclcpp::Duration(5, 0);
t = tf_buffer_->lookupTransform(
    toFrameRel,
    fromFrameRel,
    when,
    50ms);

现在,如果你运行这个程序,在前 5 秒内,第二只乌龟不知道要去哪里,因为我们还没有 5 秒内胡萝卜的姿势历史记录。 但这 5 秒之后会发生什么?让我们试一试:

ros2 launch learning_tf2_cpp turtle_tf2_fixed_frame_demo.launch.py
../../../_images/turtlesim_delay1.png

现在您应该注意到您的乌龟像此屏幕截图中一样不受控制地四处移动。让我们尝试了解这种行为背后的原因。

  1. 在我们的代码中,我们向 tf2 询问了以下问题:“5 秒前 carrot1 的姿势相对于 5 秒前 turtle2 的姿势是什么?”。这意味着我们根据 5 秒前的位置以及 5 秒前第一个胡萝卜的位置来控制第二只乌龟。

  2. 但是,我们真正想问的是:“5 秒前 carrot1 的姿势相对于 turtle2 的当前位置是什么?”。

lookupTransform() 的高级 API

要向 tf2 询问该特定问题,我们将使用高级 API,该 API 使我们能够明确说明何时获取指定的变换。 这是通过使用附加参数调用 lookupTransform() 方法来完成的。 您的代码现在看起来像这样:

rclcpp::Time now = this->get_clock()->now();
rclcpp::Time when = now - rclcpp::Duration(5, 0);
t = tf_buffer_->lookupTransform(
    toFrameRel,
    now,
    fromFrameRel,
    when,
    "world",
    50ms);

lookupTransform() 的高级 API 有六个参数:

  1. 目标帧

  2. 转换到的时间

  3. 源帧

  4. 评估源帧的时间

  5. 不随时间变化的帧,在本例中为 world

  6. 等待目标帧可用的时间

总而言之,tf2 在后台执行以下操作。

在过去,它计算从 carrot1world 的变换。

world 帧中,tf2 时间从过去穿越到现在。

在当前时间,tf2 计算从 worldturtle2 的变换。

检查结果

让我们再次运行模拟,这次使用高级时间旅行 API:

ros2 launch learning_tf2_cpp turtle_tf2_fixed_frame_demo.launch.py
../../../_images/turtlesim_delay2.png

是的,第二只乌龟被引导到了 5 秒前第一只胡萝卜所在的位置!

摘要

在本教程中,您已经了解了 tf2 的一项高级功能。

您了解到 tf2 可以及时转换数据,并了解了如何使用 turtlesim 示例来实现这一点。

tf2 允许您回到过去,并使用高级 lookupTransform() API 在乌龟的旧姿势和当前姿势之间进行帧转换。