机器人系统ros2-开发实践06-将静态坐标系广播到 tf2(Python)-定义机器人底座与其传感器或非移动部件之间的关系

发布静态变换对于定义机器人底座与其传感器或非移动部件之间的关系非常有用。例如,最容易推断激光扫描仪中心框架中的激光扫描测量结果。

1. 创建包

首先,我们将创建一个用于本教程和后续教程的包。调用的包learning_tf2_py将依赖于geometry_msgs、python3-numpy、rclpy、tf2_ros_py和turtlesim

cd ros2_study/src
ros2 pkg create --build-type ament_python --license Apache-2.0 -- learning_tf2_py

learning_tf2_py您的终端将返回一条消息,验证您的包及其所有必需文件和文件夹的创建。

在这里插入图片描述

2 编写静态广播节点

我们首先创建源文件。在src/learning_tf2_py/learning_tf2_py目录中输入以下命令来下载示例静态广播器代码:

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

这个有点慢,可能要等一会才下好

下载后可查看:

在这里插入图片描述

static_turtle_tf2_broadcaster.py 代码内容如下:

import math
import sysfrom geometry_msgs.msg import TransformStampedimport numpy as npimport rclpy
from rclpy.node import Nodefrom tf2_ros.static_transform_broadcaster import StaticTransformBroadcasterdef quaternion_from_euler(ai, aj, ak):ai /= 2.0aj /= 2.0ak /= 2.0ci = math.cos(ai)si = math.sin(ai)cj = math.cos(aj)sj = math.sin(aj)ck = math.cos(ak)sk = math.sin(ak)cc = ci*ckcs = ci*sksc = si*ckss = si*skq = np.empty((4, ))q[0] = cj*sc - sj*csq[1] = cj*ss + sj*ccq[2] = cj*cs - sj*scq[3] = cj*cc + sj*ssreturn qclass StaticFramePublisher(Node):"""Broadcast transforms that never change.This example publishes transforms from `world` to a static turtle frame.The transforms are only published once at startup, and are constant for alltime."""def __init__(self, transformation):super().__init__('static_turtle_tf2_broadcaster')self.tf_static_broadcaster = StaticTransformBroadcaster(self)# Publish static transforms once at startupself.make_transforms(transformation)def make_transforms(self, transformation):t = TransformStamped()t.header.stamp = self.get_clock().now().to_msg()t.header.frame_id = 'world't.child_frame_id = transformation[1]t.transform.translation.x = float(transformation[2])t.transform.translation.y = float(transformation[3])t.transform.translation.z = float(transformation[4])quat = quaternion_from_euler(float(transformation[5]), float(transformation[6]), float(transformation[7]))t.transform.rotation.x = quat[0]t.transform.rotation.y = quat[1]t.transform.rotation.z = quat[2]t.transform.rotation.w = quat[3]self.tf_static_broadcaster.sendTransform(t)def main():logger = rclpy.logging.get_logger('logger')# obtain parameters from command line argumentsif len(sys.argv) != 8:logger.info('Invalid number of parameters. Usage: \n''$ ros2 run learning_tf2_py static_turtle_tf2_broadcaster''child_frame_name x y z roll pitch yaw')sys.exit(1)if sys.argv[1] == 'world':logger.info('Your static turtle name cannot be "world"')sys.exit(2)# pass parameters and initialize noderclpy.init()node = StaticFramePublisher(sys.argv)try:rclpy.spin(node)except KeyboardInterrupt:passrclpy.shutdown()

2.1 代码解析:

第一行导入所需的包。首先,我们TransformStamped从导入geometry_msgs,它为我们将发布到转换树的消息提供了一个模板。

from geometry_msgs.msg import TransformStamped

然后rclpy导入,以便Node可以使用它的类。

import rclpy
from rclpy.node import Node

该tf2_ros包提供了一个StaticTransformBroadcaster使静态转换发布变得容易的方法。要使用StaticTransformBroadcaster,我们需要从tf2_ros模块导入它。

from tf2_ros.static_transform_broadcaster import StaticTransformBroadcaster

StaticFramePublisher构造函数用 name 初始化节点static_turtle_tf2_broadcaster。然后StaticTransformBroadcaster创建 ,它将在启动时发送一个静态转换。

    def __init__(self, transformation):super().__init__('static_turtle_tf2_broadcaster')self.tf_static_broadcaster = StaticTransformBroadcaster(self)# Publish static transforms once at startupself.make_transforms(transformation)

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


  • 我们需要给正在发布的转换一个时间戳,我们只需用当前时间来标记它,self.get_clock().now()
t.header.stamp = self.get_clock().now().to_msg()
  • 然后我们需要设置我们正在创建的链接的父框架的名称
t.header.frame_id = 'world'
  • 最后,我们需要设置我们正在创建的链接的子框架的名称
t.child_frame_id = transformation[1]

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

t.transform.translation.x = float(transformation[2])
t.transform.translation.y = float(transformation[3])
t.transform.translation.z = float(transformation[4])
quat = quaternion_from_euler(float(transformation[5]), float(transformation[6]), float(transformation[7]))t.transform.rotation.x = quat[0]
t.transform.rotation.y = quat[1]
t.transform.rotation.z = quat[2]
t.transform.rotation.w = quat[3]

最后,我们使用该sendTransform()函数广播静态变换。

self.tf_static_broadcaster.sendTransform(t)

2.2 更新package.xml

3.构建编译

最好rosdep在构建之前在工作区的根目录中运行以检查缺少的依赖项:

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

在这里插入图片描述

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

colcon build --packages-select learning_tf2_py

在这里插入图片描述
打开一个新终端,导航到工作区的根目录,然后获取安装文件:

. install/setup.bash

在这里插入图片描述

4. 运行

现在运行static_turtle_tf2_broadcaster节点:

ros2 run learning_tf2_py static_turtle_tf2_broadcaster mystaticturtle 0 0 1 0 0 0

这设置了海龟姿势广播,使其mystaticturtle漂浮在距地面 1 米的高度。

tf_static我们现在可以通过回显主题来检查静态转换是否已发布

ros2 topic echo /tf_static

如果一切顺利你应该看到一个静态转换

transforms:
- header:stamp:sec: 1622908754nanosec: 208515730frame_id: world
child_frame_id: mystaticturtle
transform:translation:x: 0.0y: 0.0z: 1.0rotation:x: 0.0y: 0.0z: 0.0w: 1.0

上面代码展示如何StaticTransformBroadcaster用于发布静态转换的原理。在实际的开发过程中,您不必自己编写此代码,而应该使用专用tf2_ros工具来执行此操作。 tf2_ros提供了一个名为 的可执行文件static_transform_publisher,可以用作命令行工具或可以添加到启动文件中的节点来使用

例如:

使用以米为单位的 x/y/z 偏移和以弧度为单位的横滚/俯仰/偏航将静态坐标变换发布到 tf2。在我们的例子中,横滚/俯仰/偏航分别指的是绕 x/y/z 轴的旋转。

ros2 run tf2_ros static_transform_publisher --x x --y y --z z --yaw yaw --pitch pitch --roll 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

static_transform_publisher被设计为手动使用的命令行工具,以及在launch文件中使用以设置静态转换

例如:

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(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和之外的所有参数–child-frame-id都是可选的

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

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

相关文章

【机器学习】集成学习在信用评分领域实例

集成学习在信用评分领域的应用与实践 一、引言二、集成学习的概念与原理三、集成学习在信用评分中的应用实例四、总结与展望 一、引言 在当今金融数字化快速发展的时代,信用评分成为银行、金融机构等评估个人或企业信用风险的重要工具。然而,单一的信用评…

WebRTC 中的 ICE 实现

WebRTC 中的 ICE 实现 WebRTC 中的 ICE 实现Candidate 种类与优先级ICE 策略P2P 连接完全锥型 NATIP 限制锥型 NAT端口限制锥型 NAT对称型 NATNAT 类型检测如何进行 NAT 穿越 网络中继TURN 协议中转数据WebRTC 使用 TURN 协议STUN/TURN 服务器的安装与部署 WebRTC 中的 ICE 实现…

如何打破数据管理僵局,释放数据资产价值?[AMT企源案例]

引言 数据是企业信息运作的核心和基础,是影响企业决策的关键要素,而主数据是数据中的最基础和公共的部分。面临长期以来的数据治理缺失导致的杂论局面,如何有条不紊推进主数据管理,让数据资产“活”起来?S集团的做法非…

torch_geometric安装(CPU版本)

①打开官方安装网址:https://pytorch-geometric.readthedocs.io/en/2.3.0/install/installation.html ②对根据Pytorch选择相应版本。此前一直用CUDA不成功,这次使用CPU版本(因为不用对应cuda,pytorchcudageometric三者对应起来很…

[数据结构]动画详解单链表

💖💖💖欢迎来到我的博客,我是anmory💖💖💖 又和大家见面了 欢迎来到动画详解数据结构系列 用通俗易懂的动画的动画使数据结构可视化 先来自我推荐一波 个人网站欢迎访问以及捐款 推荐阅读 如何低…

微服务思想以及实现

文章目录 前言一、什么时候需要拆分微服务1. 创业型项目2. 大型项目 二、怎么拆1. 拆分目标2. 拆分方式 三、微服务之间远程调用1. 实现方式2. 手动发送Http请求(RestTemplate)3. 服务注册中心3.1 原理3.2 Nacos注册中心3.3 服务注册3.4 服务发现(Discov…

Open CASCADE 教程 – AIS:自定义呈现

文章目录 开始 (Getting Started)呈现构建器 (Presentation builders)基元数组 (Primitive arrays)基元外观 (Primitive aspects)二次构建器 (Quadric builders)计算选择 (Computing selection)突出显示选择所有者 (Highlighting selection owner)突出显示的方法 (Highlighting…

day10-Set集合

1.Set 那接下来我们来看Collection单列集合体系的第二部分 Set集合。 1.1 Set集合概述和特点 Set集合特点 1.可以去除重复 2.存取顺序不一致 3.没有带索引的方法,所以不能使用普通fori循环遍历,也不能通过索引来获取,删除Set集合里面的元…

【大数据】HDFS、HBase操作教程(含指令和JAVA API)

目录 1.前言 2.HDFS 2.1.指令操作 2.2.JAVA API 3.HBase 3.1.指令操作 3.2.JAVA API 1.前言 本文是作者大数据专栏系列的其中一篇,前文中已经详细聊过分布式文件系统HDFS和分布式数据库HBase了,本文将会是它们的实操讲解。 HDFS相关前文&#x…

哈希算法在区块链中的应用

哈希算法是区块链技术的核心组件之一,它确保了区块链数据的不可篡改性和安全性。在本文中,我们将探讨哈希算法的基本原理,以及它在区块链中的具体应用。 哈希算法的基本原理 哈希算法是一种数学函数,它接收输入(或“消…

【Apache Doris】周FAQ集锦:第 3 期

【Apache Doris】周FAQ集锦:第 3 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目! 在这个栏目中,每周将筛选社区反馈的热门问题和话题,重点回答并进行深入探讨。旨在为广大用户和…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-15.5讲 GPIO中断实验-通用中断驱动编写

前言: 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

Golang | Leetcode Golang题解之第77题组合

题目&#xff1a; 题解&#xff1a; func combine(n int, k int) (ans [][]int) {// 初始化// 将 temp 中 [0, k - 1] 每个位置 i 设置为 i 1&#xff0c;即 [0, k - 1] 存 [1, k]// 末尾加一位 n 1 作为哨兵temp : []int{}for i : 1; i < k; i {temp append(temp, i)}t…

uniapp音乐播放整理

一、前置知识点 1.1 音频组件控制-uni.createInnerAudioContext() 创建并返回内部 audio 上下文 innerAudioContext 对象。 主要用于当前音乐播放&#xff1b; 1.1.1 innerAudioContext属性 属性类型说明只读平台差异说明srcString音频的数据链接&#xff0c;用于直接播放…

vue的css深度选择器 deep /deep/

作用及概念 当 <style> 标签有 scoped 属性时&#xff0c;它的 CSS 只作用于当前组件中的元素&#xff0c;父组件的样式将不会渗透到子组件。在vue中是这样描述的&#xff1a; 处于 scoped 样式中的选择器如果想要做更“深度”的选择&#xff0c;也即&#xff1a;影响到子…

vscode+clangd阅读Linux内核源码

1. 禁用或卸载官方C/C插件. 2. 安装clangd插件 3. 清除之前的产物 4. 生成.config文件 5.编译生成内核镜像 6.编译内核模块 7.编译设备树文件 8.生成compile_commands.json文件 运行上述命令后&#xff0c;在内核源码根目录生成了compile_commands.json文件 9.设置clangd插…

Verlog-串口发送-FPGA

Verlog-串口发送-FPGA 引言&#xff1a; ​ 随着电子技术的不断进步&#xff0c;串口通信已成为嵌入式系统和计算机外设中一种广泛使用的异步通信方式。串口通信因其简单性、可靠性以及对硬件资源的低要求&#xff0c;在数据传输领域扮演着重要角色。在FPGA&#xff08;现场可编…

读天才与算法:人脑与AI的数学思维笔记25_涌现理论

1. 人工智能新闻 1.1. 人工智能新闻报道算法的核心是如何将未经处理的原始数据转换成新闻报道 1.2. 很少有记者为美联社决定使用机器来帮助报道这些新闻持反对意见 1.2.1. 像“Wordsmith”这样的算法&#xff0c;具有自动化的洞察力、科学的叙事能力&#xff0c;现在正被应用…

LINUX 精通 1——2.1.1 网络io与io多路复用select/poll/epoll

LINUX 精通 1 day12 20240509 算法刷题&#xff1a; 2道高精度 耗时 107min 课程补20240430 耗时&#xff1a;99 min day 13 20240512 耗时&#xff1a;200min 课程链接地址 前言 杂 工作5-10年 够用 费曼&#xff1a;不要直接抄&#xff0c;自己写&#xff1b;不要一个…

【WEEK11】 【DAY6】员工管理系统第七部分【中文版】

2024.5.11 Saturday 接上文【WEEK11】 【DAY5】员工管理系统第六部分【中文版】 目录 10.8.删除及404处理10.8.1.修改list.html10.8.2.修改EmployeeController.java10.8.3.重启10.8.4. 404页面处理10.8.4.1.把404.html文件移入10.8.4.2.重启并运行 10.8.5.退出登录状态10.8.5.1…