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

添加框架(Python)

目标 学习如何在 tf2 中添加额外帧。

辅导水平: 中级

时间 15 分钟

背景介绍

在之前的教程中,我们通过编写一个 tf2 广播公司 和一个 tf2 监听器.本教程将教您如何在变换树中添加额外的固定帧和动态帧。事实上,在 tf2 中添加帧与创建 tf2 广播器非常相似,但本示例将向您展示 tf2 的一些附加功能。

对于许多与变换相关的任务,在局部框架内进行思考更为容易。例如,在以激光扫描仪为中心的框架内推理激光扫描测量是最简单的。tf2 可以为系统中的每个传感器、链接或关节定义一个局部框架。当从一个框架转换到另一个框架时,tf2 会处理所有引入的隐藏中间框架转换。

tf2 树

tf2 采用树形框架结构,因此不允许在框架结构中形成闭环。这意味着一个框架只有一个父框架,但可以有多个子框架。目前,我们的 tf2 树包含三个帧: 世界, 乌龟1乌龟2.这两个乌龟框架是 世界 帧。如果我们想在 tf2 中添加一个新框架,现有的三个框架中必须有一个是父框架,而新框架将成为它的子框架。

././././_images/turtlesim_frames.png

任务

1 编写固定框架广播节目

在我们的乌龟示例中,我们将添加一个新框架 胡萝卜1的子代。 乌龟1.这个框架将作为第二只乌龟的目标。

首先创建源文件。转到 学习_tf2_py 软件包。在 src/learning_tf2_py/learning_tf2_py 目录,输入以下命令下载固定框架广播代码:

wget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.py

现在打开名为 fixed_frame_tf2_broadcaster.py.

 几何_msgs.msg 舶来品 TransformStamped

舶来品 rclpy
 rclpy.node 舶来品 节点

 tf2_ros 舶来品 改造播音员


 固定框架广播(节点):

   捍卫 启动(自我):
       棒极了().启动('fixed_frame_tf2_broadcaster';)
       自我.tf_broadcaster = 改造播音员(自我)
       自我.定时器 = 自我.创建计时器(0.1, 自我.广播定时器回调)

   捍卫 广播定时器回调(自我):
       t = TransformStamped()

       t.页眉.盖章 = 自我.获取时钟().现在().to_msg()
       t.页眉.frame_id = 'turtle1';
       t.子帧标识 = 'carrot1';
       t..译文.x = 0.0
       t..译文.y = 2.0
       t..译文.z = 0.0
       t..自转.x = 0.0
       t..自转.y = 0.0
       t..自转.z = 0.0
       t..自转.w = 1.0

       自我.tf_broadcaster.发送变换(t)


捍卫 主要():
    rclpy.启动()
    网站 = 固定框架广播()
    尝试:
        rclpy.后旋(网站)
    除开 键盘中断:
        通过

    rclpy.关闭()

代码与 tf2 广播员教程示例非常相似,唯一的区别是这里的变换不会随时间而改变。

1.1 检查代码

让我们来看看这段代码中的关键行。在这里,我们从父代的 乌龟1 给新孩子 胡萝卜1.......。 胡萝卜1 帧的 Y 轴偏移 2 米。 乌龟1 镜框

t = TransformStamped()

t.页眉.盖章 = 自我.获取时钟().现在().to_msg()
t.页眉.frame_id = 'turtle1';
t.子帧标识 = 'carrot1';
t..译文.x = 0.0
t..译文.y = 2.0
t..译文.z = 0.0

1.2 添加入口

玫瑰2 运行 命令来运行您的节点,您必须将入口点添加到 setup.py 位于 src/learning_tf2_py 目录)。

控制台脚本 括号:

'fixed_frame_tf2_broadcaster = learning_tf2_py.fixed_frame_tf2_broadcaster:main';,

1.3 编写启动文件

现在,让我们为这个示例创建一个启动文件。用文本编辑器新建一个名为 turtle_tf2_fixed_frame_demo.launch.pysrc/learning_tf2_py/launch 目录,并添加以下几行:

舶来品 os

 ament_index_python.packages 舶来品 获取软件包共享目录

 启动 舶来品 启动说明
 launch.actions 舶来品 包含启动描述
 launch.launch_description_sources 舶来品 PythonLaunchDescriptionSource

 launch_ros.actions 舶来品 节点


捍卫 生成发射描述():
    演示节点 = 包含启动描述(
        PythonLaunchDescriptionSource([os..加入(
            获取软件包共享目录('learning_tf2_py'), 'launch';),
            '/turtle_tf2_demo.launch.py';]),
        )

    返回 启动说明([
        演示节点,
        节点(
            包装='learning_tf2_py',
            可执行='fixed_frame_tf2_broadcaster';,
            名字='fixed_broadcaster';,
        ),
    ])

这个启动文件会导入所需的软件包,然后创建一个 演示节点 变量,该变量将存储我们在上一教程的启动文件中创建的节点。

代码的最后一部分将添加我们固定的 胡萝卜1 使用我们的 固定框架_TF2_播音员 节点。

节点(
    包装='learning_tf2_py',
    可执行='fixed_frame_tf2_broadcaster';,
    名字='fixed_broadcaster';,
),

1.4 建设

运行 rosdep 在工作区的根目录下,检查是否存在缺失的依赖项。

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

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

colcon build --packages-select learning_tf2_py

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

install/setup.bash

1.5 运行

现在可以开始海龟广播员演示了:

ros2 launch learning_tf2_py turtle_tf2_fixed_frame_demo.launch.py

您应该注意到,新的 胡萝卜1 帧出现在转换树中。

.././././_images/turtlesim_frames_carrot.png

如果你驾驶第一只乌龟四处走动,你应该会注意到,尽管我们添加了一个新的帧,但其行为与之前的教程相比并没有变化。这是因为增加一帧并不会影响其他帧,我们的监听器仍在使用之前定义的帧。

因此,如果我们想让第二只乌龟跟随胡萝卜而不是第一只乌龟,就需要更改 target_frame.这有两种方法。一种方法是通过 target_frame 参数直接从控制台调入启动文件:

ros2 launch learning_tf2_py turtle_tf2_fixed_frame_demo.launch.py target_frame:=carrot1

第二种方法是更新启动文件。为此,打开 turtle_tf2_fixed_frame_demo.launch.py 文件,并添加 target_frame': 胡萝卜1 参数通过 启动参数 争论。

捍卫 生成发射描述():
    演示节点 = 包含启动描述(
        ...,
        启动参数={'target_frame': 'carrot1';}.项目(),
        )

现在重建软件包,重启 turtle_tf2_fixed_frame_demo.launch.py然后,你会看到第二只乌龟跟着胡萝卜走,而不是第一只乌龟!

././././_images/carrot_static.png

2 编写动态帧广播器

我们在本教程中发布的额外帧是一个固定帧,与父帧相比不会随时间变化。不过,如果您想发布一个移动帧,可以编写代码使广播器随时间改变帧。让我们改变我们的 胡萝卜1 帧,使其相对于 乌龟1 帧。转到 学习_tf2_py 软件包。在 src/learning_tf2_py/learning_tf2_py 输入以下命令,下载动态帧广播器代码:

wget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/dynamic_frame_tf2_broadcaster.py

现在打开名为 dynamic_frame_tf2_broadcaster.py:

舶来品 算术

 几何_msgs.msg 舶来品 TransformStamped

舶来品 rclpy
 rclpy.node 舶来品 节点

 tf2_ros 舶来品 改造播音员


 动态帧广播(节点):

    捍卫 启动(自我):
        棒极了().启动('dynamic_frame_tf2_broadcaster';)
        自我.tf_broadcaster = 改造播音员(自我)
        自我.定时器 = 自我.创建计时器(0.1, 自我.广播定时器回调)

    捍卫 广播定时器回调(自我):
        秒钟, _ = 自我.获取时钟().现在().秒_纳秒()
        x = 秒钟 * 算术.pi

        t = TransformStamped()
        t.页眉.盖章 = 自我.获取时钟().现在().to_msg()
        t.页眉.frame_id = 'turtle1';
        t.子帧标识 = 'carrot1';
        t..译文.x = 10 * 算术.罪过(x)
        t..译文.y = 10 * 算术.系数(x)
        t..译文.z = 0.0
        t..自转.x = 0.0
        t..自转.y = 0.0
        t..自转.z = 0.0
        t..自转.w = 1.0

        自我.tf_broadcaster.发送变换(t)


捍卫 主要():
    rclpy.启动()
    网站 = 动态帧广播()
    尝试:
        rclpy.后旋(网站)
    除开 键盘中断:
        通过

    rclpy.关闭()

2.1 检查代码

我们没有固定定义 x 和 y 偏移量,而是使用了 sin()cos() 在当前时间上的功能,使 胡萝卜1 是不断变化的。

秒钟, _ = 自我.获取时钟().现在().秒_纳秒()
x = 秒钟 * 算术.pi
...
t..译文.x = 10 * 算术.罪过(x)
t..译文.y = 10 * 算术.系数(x)

2.2 添加入口

玫瑰2 运行 命令来运行您的节点,您必须将入口点添加到 setup.py 位于 src/learning_tf2_py 目录)。

控制台脚本 括号:

'dynamic_frame_tf2_broadcaster = learning_tf2_py.dynamic_frame_tf2_broadcaster:main';,

2.3 编写启动文件

要测试这段代码,请创建一个新的启动文件 turtle_tf2_dynamic_frame_demo.launch.pysrc/learning_tf2_py/launch 目录,并粘贴以下代码:

舶来品 os

 ament_index_python.packages 舶来品 获取软件包共享目录

 启动 舶来品 启动说明
 launch.actions 舶来品 包含启动描述
 launch.launch_description_sources 舶来品 PythonLaunchDescriptionSource

 launch_ros.actions 舶来品 节点


捍卫 生成发射描述():
    演示节点 = 包含启动描述(
        PythonLaunchDescriptionSource([os..加入(
            获取软件包共享目录('learning_tf2_py'), 'launch';),
            '/turtle_tf2_demo.launch.py';]),
       启动参数={'target_frame': 'carrot1';}.项目(),
       )

    返回 启动说明([
        演示节点,
        节点(
            包装='learning_tf2_py',
            可执行='dynamic_frame_tf2_broadcaster';,
            名字='dynamic_broadcaster';,
        ),
    ])

2.4 建设

运行 rosdep 在工作区的根目录下,检查是否存在缺失的依赖项。

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

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

colcon build --packages-select learning_tf2_py

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

install/setup.bash

1.5 运行

现在可以开始动态帧演示了:

ros2 launch learning_tf2_py turtle_tf2_dynamic_frame_demo.launch.py

你应该看到,第二只乌龟正跟着胡萝卜的位置不断变化。

.././././_images/carrot_dynamic.png

摘要

在本教程中,您了解了 tf2 变换树、其结构和功能。您还了解到在局部框架内思考是最简单的方法,并学会了为局部框架添加额外的固定框架和动态框架。