设置转换

在本指南中,我们将介绍 Nav2 所需的必要转换。这些转换允许 Nav2 解释来自各种来源(例如传感器和里程计)的信息,方法是将它们转换为坐标系以供使用。下面是机器人的完整转换树,但我们将从更简单的东西开始。

../../_images/tf_full_tree.png

在本教程中,我们将首先简要介绍 ROS 中的转换。其次,我们将使用 TF2 静态发布者的简单命令行演示来查看其实际运行情况。最后,我们将概述 Nav2 运行所需发布的必要转换。

变换简介

Note

本指南的此部分内容改编自 ROS (1) 导航文档中的 Setting Up You Robot using tf” 教程。 许多 ROS 软件包要求使用 TF2 ROS 软件包发布机器人的变换树。变换树定义了不同坐标系之间的关系,包括平移、旋转和相对运动。为了更具体,让我们以一个简单的机器人为例,该机器人有一个移动底座,底座顶部安装有一个激光传感器。

该机器人有两个定义的坐标系:一个对应于机器人移动底座的中心点,另一个对应于安装在底座顶部的激光器的中心点。我们将连接到移动底座的坐标系称为 base_link ,将连接到激光器的坐标系称为 base_laser 。请注意,下一节将更多地讨论这些坐标系的命名和约定。

此时,我们假设我们有一些来自激光器的数据,这些数据是以距离激光器中心点的距离测量的形式提供的。换句话说,我们在 base_laser 坐标系中有一些数据。

现在,假设我们想要获取这些数据并使用它来帮助移动基座避开世界上的障碍物。为了成功做到这一点,我们需要一种方法将我们从 base_laser 框架接收到的激光扫描转换为 base_link 框架。本质上,我们需要定义“base_laser”和“base_link”坐标系之间的关系。

../../_images/simple_robot.png

在定义这种关系时,我们假设我们拥有的唯一数据是激光器安装在移动基座中心点前方 10 厘米处和上方 20 厘米处。这为我们提供了一个将 base_link 框架与 base_laser 框架相关联的平移偏移量。具体来说,我们知道要从 base_link 框架获取数据到 base_laser 框架,我们必须应用(x:0.1m,y:0.0m,z:0.2m)的平移,而横向地,要从 base_laser 框架获取数据到 base_link 框架,我们必须应用相反的平移(x:-0.1m,y:0.0m,z:-0.20m)。

我们可以选择自己管理这种关系,这意味着在必要时存储和应用框架之间的适当平移,但随着坐标框架数量的增加,这会变得非常麻烦。幸运的是,我们不必自己做这项工作。相反,我们将使用 TF2 定义“base_link”和“base_laser”之间的关系,并让它为我们管理两个坐标系之间的变换。这在处理非静态变换时特别有用,例如一组相对于彼此移动的框架,如地图框架中的机器人基架。

要使用 TF2 定义和存储 base_linkbase_laser 框架之间的关系,我们需要将它们添加到变换树中。从概念上讲,变换树中的每个节点对应于一个坐标系,每个边对应于从当前节点移动到其子节点所需应用的变换。TF2 使用树结构来保证只有一次遍历将任何两个坐标系链接在一起,并假设树中的所有边都是从父节点指向子节点。

../../_images/tf_robot.png

为了为我们的简单示例创建变换树,我们将创建两个节点:一个用于 base_link 坐标系,一个用于 base_laser 坐标系。为了在它们之间创建边,我们首先需要确定哪个节点是父节点,哪个节点是子节点。请记住 - 这种区别很重要,因为 TF2 假设所有变换都是从父节点移动到子节点。

让我们选择 base_link 坐标系作为父节点,因为当其他部件/传感器添加到机器人时,通过遍历 base_link 框架将它们与 base_laser 框架关联是最有意义的。这意味着与连接 base_linkbase_laser 的边相关联的变换应该是 (x: 0.1m, y: 0.0m, z: 0.2m)。

设置好这个变换树后,将 base_laser 框架中接收到的激光扫描转换为 base_link 框架就像调用 TF2 库一样简单。我们的机器人现在可以使用此信息推断 base_link 框架中的激光扫描,并安全地规划其环境中的障碍物。

静态变换发布器演示

Warning

如果您是 ROS 2 新手或尚未拥有工作环境,请花一些时间使用官方 ROS 2 安装文档 中的资源正确设置您的机器

现在让我们尝试使用 TF2 提供的 static_transform_publisher 工具发布一个非常简单的变换。我们将发布从链接 base_link 到链接 base_laser 的变换,平移量为 (x: 0.1m, y: 0.0m, z: 0.2m)。请注意,我们将根据本教程前面的图表构建变换。

打开命令行并执行以下命令:

ros2 run tf2_ros static_transform_publisher 0.1 0 0.2 0 0 0 base_link base_laser

这样,我们现在成功地在 TF2 中将 base_link 发布到 base_laser 变换。现在让我们通过 tf2_echo 检查它是否正常工作。打开一个单独的命令行窗口并执行以下操作:

ros2 run tf2_ros tf2_echo base_link base_laser

您应该能够观察到类似于下面的重复输出。

At time 0.0
- Translation: [0.100, 0.000, 0.200]
- Rotation: in Quaternion [0.000, 0.000, 0.000, 1.000]

这就是这个简短的演示 - 我们能够使用 TF2 库成功发布从“base_link”到“base_laser”的转换。请注意,我们不建议在实际机器人项目中使用上述演示发布转换,这只是一个快速演示,用于查看 TF2 的实际操作。对于真正的机器人系统,我们将创建一个 URDF 文件,该文件嵌入此信息以及有关您的机器人的更多信息,以便使用 robot_state_publisher 而不是 static_transform_publisher。有更合适和实用的方法来实现这一点,将在 设置 URDF 教程中讨论。

See also

如果您想了解有关 TF2 的更多信息以及如何创建自己的变换发布器,请前往官方 TF2 文档

结论

在本教程中,我们讨论了变换的概念及其在 Nav2 中的使用方式。

在上一节中,我们还探索了如何使用 TF2 的 static_transform_publisher 来发布我们的变换。您可以使用它来为 Nav2 设置变换,但这通常不是最好的方法。在大多数机器人项目中,我们使用机器人状态发布器,因为它更易于使用,并且随着机器人变得越来越复杂,它的扩展性也很好。我们将在下一个教程 设置 URDF 中讨论机器人状态发布器 (URDF) 及其设置方法。

最后,我们还讨论了 Nav2 的三个已发布转换要求以及设置它们时需要牢记的必要 REP。