您正在阅读的是旧版本但仍受支持的 ROS 2 文档。 Jazzy.

编写静态广播器(C++)

目标 了解如何向 tf2 广播静态坐标框架。

辅导水平: 中级

时间 15 分钟

背景介绍

发布静态变换对于定义机器人底座与其传感器或非移动部件之间的关系非常有用。例如,在激光扫描仪中心的框架内进行激光扫描测量是最简单的推理方法。

这是一个涵盖静态变换基础知识的独立教程,由两部分组成。在第一部分中,我们将编写向 tf2 发布静态变换的代码。 在第二部分中,我们将讲解如何使用命令行 静态转换发布者 中的可执行工具 tf2_ros.

在接下来的两个教程中,我们将编写代码来重现来自 tf2 简介 教程。之后,下面的教程将重点介绍如何利用更高级的 tf2 功能扩展演示。

先决条件

在前面的教程中,您学习了如何 创建工作区创建软件包.

任务

1 创建软件包

首先,我们将创建一个软件包,这个软件包将用于本教程和后续教程。软件包名为 learning_tf2_cpp 将取决于 几何参数, rclcpp, tf2, tf2_ros海龟.本教程的代码存储在 这里.

打开一个新终端,然后 为您的 ROS 2 安装提供源代码 以便 玫瑰2 命令将起作用。导航至工作区的 来源 文件夹并创建一个新软件包:

ros2 pkg create --build-type ament_cmake --license Apache-2.0 --dependencies geometry_msgs rclcpp tf2 tf2_ros turtlesim -- learning_tf2_cpp

您的终端将返回一条信息,验证是否创建了软件包 learning_tf2_cpp 及其所有必要的文件和文件夹。

2 写入静态广播节点

让我们先创建源文件。在 src/learning_tf2_cpp/src 输入以下命令,下载静态广播员代码示例:

wget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_cpp/src/static_turtle_tf2_broadcaster.cpp

使用您喜欢的文本编辑器打开文件。

#include <内存>;

#include "geometry_msgs/msg/transform_stamped.hpp";
#include "rclcpp/rclcpp.hpp";
#include "tf2/LinearMath/Quaternion.h";
#include "tf2_ros/static_transform_broadcaster.h";

 静态框架发布者 :  rclcpp::节点
{
:
  不含糊 静态框架发布者(烧焦 * 变革[])
  : 节点("static_turtle_tf2_broadcaster";)
  {
    tf_static_broadcaster_ = 标准::共享<;tf2_ros::静态变换广播>;();

    // 启动时发布一次静态变换
    ->;make_transforms(变革);
  }

私人:
  空白 make_transforms(烧焦 * 变革[])
  {
    几何参数::信息::TransformStamped t;

    t.页眉.盖章 = ->;获取时钟()->;现在();
    t.页眉.frame_id = "世界";;
    t.子帧标识 = 变革[1];

    t..译文.x = 蚜虫(变革[2]);
    t..译文.y = 蚜虫(变革[3]);
    t..译文.z = 蚜虫(变革[4]);
    tf2::四元数 q;
    q.设置 RPY(
      蚜虫(变革[5]),
      蚜虫(变革[6]),
      蚜虫(变革[7]));
    t..自转.x = q.x();
    t..自转.y = q.y();
    t..自转.z = q.z();
    t..自转.w = q.w();

    tf_static_broadcaster_->;发送变换(t);
  }

  标准::共享_ptr<;tf2_ros::静态变换广播>; tf_static_broadcaster_;
};

int 主要(int 参数, 烧焦 * 参数[])
{
  汽车 记录仪 = rclcpp::get_logger("记录仪";);

  // 从命令行参数中获取参数
  如果 (参数 != 8) {
    RCLCPP_INFO(
      记录仪, 参数数量无效\n用法:";
      "$ ros2 run learning_tf2_cpp static_turtle_tf2_broadcaster ";
      "child_frame_name x y z roll pitch yaw";);
    返回 1;
  }

  // 由于变换的父帧是 "world",它是
  // 必须检查传递的帧名是否不同
  如果 (strcmp(参数[1], "世界";) == 0) {
    RCLCPP_INFO(记录仪, "您的静态乌龟名称不能是 '世界'";);
    返回 1;
  }

  // 传递参数并初始化节点
  rclcpp::启动(参数, 参数);
  rclcpp::后旋(标准::共享<;静态框架发布者>;(参数));
  rclcpp::关闭();
  返回 0;
}

2.1 检查代码

现在让我们来看看将静态乌龟姿势发布到 tf2 的相关代码。第一行包含所需的头文件。首先我们包含 geometry_msgs/msg/transform_stamped.hpp 访问 TransformStamped 消息类型,我们将把它发布到转换树中。

#include "geometry_msgs/msg/transform_stamped.hpp";

之后、 rclcpp 包括在内,因此其 rclcpp::Node 类可以使用。

#include "rclcpp/rclcpp.hpp";

tf2::Quaternion 是一个四元数类,它提供了将欧拉角转换为四元数的便捷函数,反之亦然。我们还包括 tf2_ros/static_transform_broadcaster.h 以使用 静态变换广播 以方便发布静态变换。

#include "tf2/LinearMath/Quaternion.h";
#include "tf2_ros/static_transform_broadcaster.h";

"(《世界人权宣言》) 静态框架发布者 类的构造函数将节点初始化为名称为 静态海龟_TF2_播音员.那就.....、 静态变换广播 会在启动时发送一个静态转换。

tf_static_broadcaster_ = 标准::共享<;tf2_ros::静态变换广播>;();

->;make_transforms(变革);

在这里,我们创建一个 TransformStamped 对象,它将是我们在填充后发送的信息。在传递实际变换值之前,我们需要给它提供适当的元数据。

  1. 我们需要给正在发布的变换加一个时间戳,然后用当前时间戳记、 this->get_clock()->now()

  2. 然后,我们需要设置所创建链接的父框架名称,本例中为 世界

  3. 最后,我们需要设置所创建链接的子框架名称

几何参数::信息::TransformStamped t;

t.页眉.盖章 = ->;获取时钟()->;现在();
t.页眉.frame_id = "世界";;
t.子帧标识 = 变革[1];

在这里,我们将填充乌龟的 6D 姿态(平移和旋转)。

t..译文.x = 蚜虫(变革[2]);
t..译文.y = 蚜虫(变革[3]);
t..译文.z = 蚜虫(变革[4]);
tf2::四元数 q;
q.设置 RPY(
  蚜虫(变革[5]),
  蚜虫(变革[6]),
  蚜虫(变革[7]));
t..自转.x = q.x();
t..自转.y = q.y();
t..自转.z = q.z();
t..自转.w = q.w();

最后,我们使用 发送变换( ) 功能。

tf_static_broadcaster_->;发送变换(t);

2.2 更新 package.xml

导航一级回到 src/learning_tf2_cpp 目录中的 CMakeLists.txtpackage.xml 文件已为您创建。

开放 package.xml 使用文本编辑器。

正如 创建软件包 教程,确保填写 <描述>;, <维护者>;许可证 标签

<描述>;学习 tf2  rclcpp</description>;
维护者 电子邮件="[email protected]";>;您的 名称维护人员</maintainer>;
许可证阿帕奇 许可证 2.0</license>;

确保保存文件。

2.3 CMakeLists.txt

将可执行文件添加到 CMakeLists.txt 并命名为 静态海龟_TF2_播音员,稍后将与 玫瑰2 运行.

add_executable(static_turtle_tf2_broadcaster src/static_turtle_tf2_broadcaster.cpp)
ament_target_dependencies(
   静态海龟_TF2_播音员
   几何参数
   rclcpp
   tf2
   tf2_ros
)

最后,添加 install(TARGETS...) 因此 玫瑰2 运行 能找到你的可执行文件:

install(TARGETS
   静态海龟_TF2_播音员
   DESTINATION lib/${PROJECT_NAME})

3 建

运行 rosdep 在工作区的根目录中,以便在构建前检查是否有缺失的依赖项:

rosdep install -i --from-path src --rosdistro humble -y

还是在工作区的根目录下,构建新软件包:

colcon build --packages-select learning_tf2_cpp

打开一个新终端,导航到工作区的根目录,然后获取设置文件:

install/setup.bash

4 运行

现在运行 静态海龟_TF2_播音员 节点:

ros2 run learning_tf2_cpp static_turtle_tf2_broadcaster mystaticturtle 0 0 1 0 0 0

这将为 神秘乌龟 漂浮在离地面 1 米高的地方。

现在,我们可以通过回显 tf_static 主题

ros2 topic echo /tf_static

如果一切顺利,您应该看到一个单一的静态变换

变换:
- 头
   盖章:
      sec: 1622908754
      Nanosec: 208515730
   frame_id: world
child_frame_id: mystaticturtle
转型:
   翻译:
      x: 0.0
      y:0.0
      z: 1.0
   轮换:
      x: 0.0
      y:0.0
      z: 0.0
      w:1.0

发布静态变换的正确方法

本教程旨在展示如何 静态变换广播 可用于发布静态转换。在实际开发过程中,您不必自己编写这些代码,而应使用专用的 tf2_ros 工具来实现。 tf2_ros 提供了一个名为 静态转换发布者 既可以作为命令行工具使用,也可以作为节点添加到启动文件中。

下面的命令使用以米为单位的 x/y/z 偏移量和以弧度为单位的滚动/俯仰/偏航量向 tf2 发布静态坐标变换。在 ROS 2 中,roll/pitch/yaw 分别指围绕 x/y/z 轴的旋转。

ros2 run tf2_ros static_transform_publisher --x x --y y --z z --yaw yaw --pitch pitch --roll --frame-id frame_id --child-frame-id child_frame_id

下面的命令使用以米为单位的 x/y/z 偏移和四元数形式的滚动/俯仰/偏航,向 tf2 发布静态坐标变换。

ros2 run tf2_ros static_transform_publisher --x x --y y --z z --qx qx --qy qy --qz qz --qw qw --frame-id frame_id --child-frame-id child_frame_id

静态转换发布者 既可作为手动使用的命令行工具,也可在 启动 文件,用于设置静态变换。例如

from launch import LaunchDescription
从 launch_ros.actions 导入 Node

def generate_launch_description():
    return LaunchDescription([
        节点(
             package='tf2_ros',
             executable='static_transform_publisher'、
             arguments = ['--x', '0', '--y', '0', '--z', '1', '--yaw', '0', '--pitch';,'0','--roll','0','--frame-id','world','--child-frame-id','mystaticturtle']。
        ),
    ])

请注意,除了 --frame-id--儿童帧--ID 是可选项;如果没有指定特定选项,则将假定其身份。

摘要

在本教程中,您将了解静态变换如何用于定义帧间的静态关系,例如 神秘乌龟 关于 世界 帧。此外,你们还了解了静态变换如何通过将数据与通用坐标框架相关联来帮助理解传感器数据(如激光扫描仪的数据)。最后,你们编写了自己的节点来向 tf2 发布静态变换,并学习了如何使用 静态转换发布者 执行文件和启动文件。