机器人系统ros2-开发实践08-了解如何使用 tf2 来访问坐标帧转换(Python)

tf2 库允许你在 ROS 节点中查询两个帧之间的转换。这个查询可以是阻塞的,也可以是非阻塞的,取决于你的需求。下面是一个基本的 Python 示例,展示如何在 ROS 节点中使用 tf2 查询帧转换。

本教程假设您已完成tf2 静态广播器教程 (Python)和tf2 广播器教程 (Python)。在上一个教程中,我们创建了一个learning_tf2_py包。机器人系统ros2-开发实践06-将静态坐标系广播到 tf2(Python)-定义机器人底座与其传感器或非移动部件之间的关系

步骤1:

1 编写监听节点

我们首先创建源文件。转到learning_tf2_py我们在上一教程中创建的包。在src/learning_tf2_py/learning_tf2_py目录中新建turtle_tf2_listener.py,用vscode 打开文件,将下面的代码贴入文件中。

代码如下:

import mathfrom geometry_msgs.msg import Twistimport rclpy
from rclpy.node import Nodefrom tf2_ros import TransformException
from tf2_ros.buffer import Buffer
from tf2_ros.transform_listener import TransformListenerfrom turtlesim.srv import Spawnclass FrameListener(Node):def __init__(self):super().__init__('turtle_tf2_frame_listener')# Declare and acquire `target_frame` parameterself.target_frame = self.declare_parameter('target_frame', 'turtle1').get_parameter_value().string_valueself.tf_buffer = Buffer()self.tf_listener = TransformListener(self.tf_buffer, self)# Create a client to spawn a turtleself.spawner = self.create_client(Spawn, 'spawn')# Boolean values to store the information# if the service for spawning turtle is availableself.turtle_spawning_service_ready = False# if the turtle was successfully spawnedself.turtle_spawned = False# Create turtle2 velocity publisherself.publisher = self.create_publisher(Twist, 'turtle2/cmd_vel', 1)# Call on_timer function every secondself.timer = self.create_timer(1.0, self.on_timer)def on_timer(self):# Store frame names in variables that will be used to# compute transformationsfrom_frame_rel = self.target_frameto_frame_rel = 'turtle2'if self.turtle_spawning_service_ready:if self.turtle_spawned:# Look up for the transformation between target_frame and turtle2 frames# and send velocity commands for turtle2 to reach target_frametry:t = self.tf_buffer.lookup_transform(to_frame_rel,from_frame_rel,rclpy.time.Time())except TransformException as ex:self.get_logger().info(f'Could not transform {to_frame_rel} to {from_frame_rel}: {ex}')returnmsg = Twist()scale_rotation_rate = 1.0msg.angular.z = scale_rotation_rate * math.atan2(t.transform.translation.y,t.transform.translation.x)scale_forward_speed = 0.5msg.linear.x = scale_forward_speed * math.sqrt(t.transform.translation.x ** 2 +t.transform.translation.y ** 2)self.publisher.publish(msg)else:if self.result.done():self.get_logger().info(f'Successfully spawned {self.result.result().name}')self.turtle_spawned = Trueelse:self.get_logger().info('Spawn is not finished')else:if self.spawner.service_is_ready():# Initialize request with turtle name and coordinates# Note that x, y and theta are defined as floats in turtlesim/srv/Spawnrequest = Spawn.Request()request.name = 'turtle2'request.x = float(4)request.y = float(2)request.theta = float(0)# Call requestself.result = self.spawner.call_async(request)self.turtle_spawning_service_ready = Trueelse:# Check if the service is readyself.get_logger().info('Service is not ready')def main():rclpy.init()node = FrameListener()try:rclpy.spin(node)except KeyboardInterrupt:passrclpy.shutdown()

2 代码说明:

TransformListener以帮助简化接收转换的任务。

from tf2_ros.transform_listener import TransformListener

在这里,我们创建一个TransformListener对象。创建侦听器后,它开始通过线路接收 tf2 转换,并将它们缓冲最多 10 秒。

self.tf_listener = TransformListener(self.tf_buffer, self)

最后,我们向侦听器查询特定的转换。我们lookup_transform使用以下参数调用方法:
提供rclpy.time.Time()只会为我们提供最新的可用转换。所有这些都包含在 try- except 块中以处理可能的异常

t = self.tf_buffer.lookup_transform(to_frame_rel,from_frame_rel,rclpy.time.Time())

3 新增启动入口点

要允许命令运行您的节点,您必须将入口点添加到src/learning_tf2_py 的setup.py ,在setup.py 文件里找到console_scripts,在括号之间添加以下行

'turtle_tf2_listener = learning_tf2_py.turtle_tf2_listener:main',

在这里插入图片描述

3.1 更新启动文件

使用文本编辑器打开目录中调用的启动文件src/learning_tf2_py/launch,向启动描述turtle_tf2_demo.launch.py添加两个新节点,添加启动参数,然后添加导入。生成的新的文件应如下所示:

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfigurationfrom launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='turtlesim',executable='turtlesim_node',name='sim'),Node(package='learning_tf2_py',executable='turtle_tf2_broadcaster',name='broadcaster1',parameters=[{'turtlename': 'turtle1'}]),DeclareLaunchArgument('target_frame', default_value='turtle1',description='Target frame name.'),Node(package='learning_tf2_py',executable='turtle_tf2_broadcaster',name='broadcaster2',parameters=[{'turtlename': 'turtle2'}]),Node(package='learning_tf2_py',executable='turtle_tf2_listener',name='listener',parameters=[{'target_frame': LaunchConfiguration('target_frame')}]),])

这将声明一个target_frame启动参数,为我们将生成的第二只海龟启动一个广播器,以及将订阅这些转换的坐标侦监听器。

3 构建

在工作区的根目录中运行rosdep以检查是否缺少依赖项。

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

在这里插入图片描述

仍然在工作区的根目录中构建您的包:

colcon build --packages-select learning_tf2_py

在这里插入图片描述

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

. install/setup.bash

4 运行

现在您已准备好开始完整的海龟演示:
在工作区的根目录执行

ros2 launch learning_tf2_py turtle_tf2_demo.launch.py

看到有两个海龟,另外一个会向其中一个自动靠齐

在这里插入图片描述

您应该会看到海龟模拟卡上有两只海龟。在第二个终端窗口中键入以下命令:

ros2 run turtlesim turtle_teleop_key

在这里插入图片描述

要查看是否有效,只需使用箭头键围绕第一只乌龟行驶(确保您的终端窗口处于活动状态,而不是模拟器窗口),您将看到第二只乌龟紧随第一只乌龟!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/689596.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构十三:八大排序算法

排序算法(sorting algorithm)是用于对一组数据按照特定顺序进行排列。排序算法有着广泛的应用,因为有序数据通常能够被更高效地查找、分析和处理。排序算法中的数据类型可以是整数、浮点数、字符或字符串等。排序的判断规则可根据需求设定&am…

SpringBoot内置插件的使用(jackson和lombok)

文章目录 引言I lombok(自动为属性生成构造器)II jacksonsee also引言 idea2021.2.2 已经捆绑安装jackson和lombok插件 I lombok(自动为属性生成构造器) Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。 https://p…

Leedcode题目:移除链表元素

题目: 这个题目就是要我们将我们的链表中的值是val的节点删除。 我们题目提供的接口是 传入了指向一个链表的第一个节点的指针,和我们要删除的元素的值val,不只要删除第一个, 思路 我们这里可以创建一个新的链表,…

算法设计与分析 例题解答 解空间与搜索

1.请画出用回溯法解n3的0-1背包问题的解空间树和当三个物品的重量为{20, 15, 10},价值为{20, 30, 25},背包容量为25时搜索空间树。 答: 解空间树: 搜索空间树: 2. 考虑用分支限界解0-1背包问题 给定n种物品和一背包…

程序员代码面试指南题目解析(一)

题目一:如何仅用递归函数和栈操作逆序一个栈 题目要求: 一个栈依次压入 1、2、3、4、5,那么从栈顶到栈底分别为5、4、3、2、1。将这个栈 转置后,从栈顶到栈底为 1、2、3、4、5,也就是实现栈中元素的逆序,但…

【Python系列】字节串与字典字节串

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

在Linux上安装并运行RabbitMQ

目录 准备CentOS服务器 下载rabbit-server和erlang文件 启动RabbitMQ服务 准备CentOS服务器 两个命令,选一个能用的,查看CentOS服务器的版本 lsb_release -a下载rabbit-server和erlang文件 参考文章:http://t.csdnimg.cn/t8BbM 1、创建新…

MySQL innodb_buffer_pool_size 相关常用语句

对于MySQL速度慢的问题,除了优化 SQL 以外,应该必须优先想到的即使 MySQL 数据库的 innodb_buffer_pool_size 配置问题。 一般来说,innodb_buffer_pool_size 的默认大小都是很小的,尤其是 win 下其默认大小更是只有离谱的 8M。Li…

【C/C++笔试练习】DNS设置文件、应用层、Dos攻击、DNS服务、DNS、子网划分、http状态、路由设置、TCP连接、HTTP状态码、剪花布条、客似云来

文章目录 C/C笔试练习选择部分(1)DNS设置文件(2)应用层(3)Dos攻击(4)DNS服务(5)DNS(6)子网划分(7)http状态&am…

ios 开发如何给项目安装第三方库,以websocket库 SocketRocket 为例

1.brew 安装 cococapods $ brew install cocoapods 2、找到xcode项目 的根目录,如图,在根目录下创建Podfile 文件 3、在Podfile文件中写入 platform :ios, 13.0 use_frameworks! target chat_app do pod SocketRocket end project ../chat_app.x…

Flink DataSink介绍

介绍 Flink DataSink是Apache Flink框架中的一个重要组件,它定义了数据流经过一系列处理后最终的输出位置。以下是关于Flink DataSink的详细介绍: 概念:DataSink主要负责对经过Flink处理后的流进行一系列操作,并将计算后的数据结…

GPT-SoVits:语音克隆,语音融合

首发网站 https://tianfeng.space 前言 零样本文本到语音(TTS): 输入 5 秒的声音样本,即刻体验文本到语音转换。少样本 TTS: 仅需 1 分钟的训练数据即可微调模型,提升声音相似度和真实感。跨语言支持&…