机器人系统ros2-开发实践09-如何向 tf2 添加额外的坐标帧位置(Python)

在之前的教程中,我们通过编写tf2 广播器和tf2 监听器重新创建了乌龟演示。本教程将教您如何向转换树添加额外的固定和动态框架。事实上,在 tf2 中添加框架与创建 tf2 广播器非常相似,但此示例将向您展示 tf2 的一些附加功能。

对于许多与转换相关的任务,在局部框架内思考会更容易。例如,最容易推断激光扫描仪中心框架中的激光扫描测量结果。 tf2 允许您为系统中的每个传感器、链路或关节定义本地框架。从一帧转换到另一帧时,tf2 将处理引入的所有隐藏中间帧转换。

tf2树

tf2 建立了帧的树结构,因此不允许帧结构中出现闭环。这意味着一个框架只有一个父框架,但可以有多个子框架。目前,我们的 tf2 树包含三个帧:world、turtle1和turtle2。两个海龟框架是该world框架的子框架。如果我们想向 tf2 添加一个新框架,则现有的三个框架之一需要作为父框架,而新框架将成为其子框架。
在这里插入图片描述

比如在机械臂形态的机器人中,机器人安装的位置叫做基坐标系Base Frame,机器人安装位置在外部环境下的参考系叫做世界坐标系World Frame,机器人末端夹爪的位置叫做工具坐标系,外部被操作物体的位置叫做工件坐标系,在机械臂抓取外部物体的过程中,这些坐标系之间的关系也在跟随变化。

在这里插入图片描述
在移动机器人系统中,坐标系一样至关重要,比如一个移动机器人的中心点是基坐标系Base Link,雷达所在的位置叫做雷达坐标系laser link,机器人要移动,里程计会累积位置,这个位置的参考系叫做里程计坐标系odom,里程计又会有累积误差和漂移,绝对位置的参考系叫做地图坐标系map。
在这里插入图片描述

一层一层坐标系之间关系复杂,有一些是相对固定的,也有一些是不断变化的,看似简单的坐标系也在空间范围内变得复杂,良好的坐标系管理系统就显得格外重要。

在这里插入图片描述
关于坐标系变换关系的基本理论,在每一本机器人学的教材中都会有讲解,可以分解为平移和旋转两个部分,通过一个四乘四的矩阵进行描述,在空间中画出坐标系,那两者之间的变换关系,其实就是向量的数学描述。

1 编写固定帧广播器

在我们的海龟示例中,我们将添加一个新框架carrot1,它将成为turtle1.该框架将作为第二只乌龟的目标。

我们首先创建源文件。转到learning_tf2_py 我们在之前的教程中创建的包。在src/learning_tf2_py/learning_tf2_py目录中新建fixed_frame_tf2_broadcaster.py文件,然后用vccode 打开写入如下代码:

from geometry_msgs.msg import TransformStampedimport rclpy
from rclpy.node import Nodefrom tf2_ros import TransformBroadcasterclass FixedFrameBroadcaster(Node):def __init__(self):super().__init__('fixed_frame_tf2_broadcaster')self.tf_broadcaster = TransformBroadcaster(self)self.timer = self.create_timer(0.1, self.broadcast_timer_callback)def broadcast_timer_callback(self):t = TransformStamped()t.header.stamp = self.get_clock().now().to_msg()t.header.frame_id = 'turtle1't.child_frame_id = 'carrot1't.transform.translation.x = 0.0t.transform.translation.y = 2.0t.transform.translation.z = 0.0t.transform.rotation.x = 0.0t.transform.rotation.y = 0.0t.transform.rotation.z = 0.0t.transform.rotation.w = 1.0self.tf_broadcaster.sendTransform(t)def main():rclpy.init()node = FixedFrameBroadcaster()try:rclpy.spin(node)except KeyboardInterrupt:passrclpy.shutdown()

上面关键代码说明:

在这里,我们创建一个新的转换,从父级turtle1到新的子级carrot1。就框架而言,框架carrot1在 y 轴上偏移 2 米turtle1。

t = TransformStamped()t.header.stamp = self.get_clock().now().to_msg()
t.header.frame_id = 'turtle1'
t.child_frame_id = 'carrot1'
t.transform.translation.x = 0.0
t.transform.translation.y = 2.0
t.transform.translation.z = 0.0

添加节点入口:

在src/learning_tf2_py,用vscode 打开setup.py

在console_scripts 括号之间添加以下行’:

'fixed_frame_tf2_broadcaster = learning_tf2_py.fixed_frame_tf2_broadcaster:main',

在这里插入图片描述

编写启动文件

src/learning_tf2_py/launch目录中创建一个名为的新文件turtle_tf2_fixed_frame_demo.launch.py,代码内容如下:

import osfrom ament_index_python.packages import get_package_share_directoryfrom launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSourcefrom launch_ros.actions import Nodedef generate_launch_description():demo_nodes = IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('learning_tf2_py'), 'launch'),'/turtle_tf2_demo.launch.py']),)return LaunchDescription([demo_nodes,Node(package='learning_tf2_py',executable='fixed_frame_tf2_broadcaster',name='fixed_broadcaster',),])

此启动文件导入所需的包,然后创建一个demo_nodes变量来存储我们在上一教程的启动文件中创建的节点。

代码的最后一部分将carrot1使用我们的节点将我们的固定框架添加到turtlesim世界中fixed_frame_tf2_broadcaster。

Node(package='learning_tf2_py',executable='fixed_frame_tf2_broadcaster',name='fixed_broadcaster',
),

编译:

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

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

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

colcon build --packages-select learning_tf2_py

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

. install/setup.bash

运行

现在您可以启动海龟广播演示:

ros2 launch learning_tf2_py turtle_tf2_fixed_frame_demo.launch.py

这里跟上面教程一样,初始化两个乌龟,其中一个乌龟会向另外一个乌龟靠齐

在这里插入图片描述
新carrot1框架出现在转换树中

在这里插入图片描述
如果你驾驶第一只乌龟,你应该注意到,即使我们添加了一个新框架,其行为与之前的教程相比并没有改变。这是因为添加额外的帧不会影响其他帧,并且我们的侦听器仍在使用之前定义的帧。

因此,如果我们希望第二只乌龟而不是第一只乌龟跟随胡萝卜,我们需要更改 的值target_frame。这可以通过两种方式完成。一种方法是target_frame直接从控制台将参数传递给启动文件:

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

在这里插入图片描述

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

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

相关文章

自回归模型的优缺点及改进方向

在学术界和人工智能产业中,关于自回归模型的演进与应用一直是一个引发深入讨论和多方观点交锋的热门议题。尤其是Yann LeCun,这位享誉全球的AI领域学者、图灵奖的获得者,以及被誉为人工智能领域的三大巨擘之一,他对于自回归模型持…

Linux:进程概念(三.详解进程:进程状态、优先级、进程切换与调度)

上次讲了进程这些内容:Linux:进程概念(二.查看进程、父进程与子进程、进程状态详解) 文章目录 1.Linux中的进程状态1.1前台进程和后台进程运行状态睡眠状态磁盘休眠状态停止状态kill指令—向进程发送信号 死亡状态 2.僵尸进程2.1僵…

Java入门基础学习笔记16——运算符

package cn.ensource.operator;public class OperatorDemo1 {public static void main(String[] args) {// 目标:掌握基本的算术运算符的使用int a 10;int b 2;System.out.println(a b);System.out.println(a - b);System.out.println(a * b); // 20System.out.…

springboot项目打包部署

springboot打包的前提条件jdk必须17以后不然本地运行不来(我用的jdk是22) 查看自己电脑jdk版本可以参考(完美解决Windows10下-更换JDK环境变量后,在cmd下执行仍java -version然出现原来版本的JDK的问题-CSDN博客) 1、…

全栈开发之路——前端篇(9)插槽、常用api和全局api

全栈开发一条龙——前端篇 第一篇:框架确定、ide设置与项目创建 第二篇:介绍项目文件意义、组件结构与导入以及setup的引入。 第三篇:setup语法,设置响应式数据。 第四篇:数据绑定、计算属性和watch监视 第五篇 : 组件…

【生信技能树】数据挖掘全流程

R包的安装,每次做分析的时候先运行这段代码把R包都安装好了,这段代码不需要任何改动,每次分析直接运行。 options("repos""https://mirrors.ustc.edu.cn/CRAN/") if(!require("BiocManager")) install.packag…

OpenGL入门第四步:摄像机视角变换与交互

OpenGL入门第一步:创建窗口、重写虚函数-CSDN博客 OpenGL入门第二步:颜色、纹理设置(解析)-CSDN博客 OpenGL入门第三步:矩阵变换、坐标系统-CSDN博客 目录 函数解析 具体代码 函数解析 相机视角变换需要与鼠标键盘进行交互,需要重写鼠标和键盘响应函数。 初始化 …

企业微信hook接口协议,ipad协议http,群发消息(每天每人一次)

群发消息(每天每人一次) 参数名必选类型说明uuid是String每个实例的唯一标识,根据uuid操作具体企业微信vids是long要发送的人或者群ididisroom是bool是否是群消息 请求示例 {"uuid":"xxxxxxxx","vids": [&qu…

敏感信息提取插件-CaA(三)

0x01 简介 CaA是一个基于BurpSuite Java插件API开发的流量收集和分析插件。它的主要作用就是收集HTTP协议报文中的参数、路径、文件、参数值等信息,并统计出现的频次,为使用者积累真正具有实战意义的Fuzzing字典。除此之外,CaA还提供了独立的…

大文件传输的好帮手Libarchive:功能强大的开源归档文件处理库

在数字化时代,文件的存储和传输对于企业的日常运作至关重要。但是,服务器中的压缩文件往往无法直接查看或预览,这给用户带来了不便。为了解决这一问题,在线解压功能的开发变得尤为重要。接下来,小编将介绍一个能够实现…

利用IP地址查询解决被“薅羊毛”的方法

在互联网时代,随着各种网络诈骗手段的不断更新和演变,“薅羊毛”成为了一种常见的网络犯罪行为。其中,利用查询IP地址进行欺诈活动已经成为一种普遍的手段。当个人或组织的IP地址被不法分子查询后,可能会面临虚假注册、盗取个人信…

开放式耳机哪个品牌好?性能超强的五款耳机推荐!速来码住!

运动已经融入了我们的日常生活,组团徒步、爬山、跑步、骑行等项目都收到了很人的喜爱。运动加耳机的组合也成了年轻人热爱的方式,在激烈运动的过程中往往会照成颠簸,在佩戴耳机上稳固性和舒适性就变得很重要了,因此开放式蓝牙耳机…