机器人系统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.hqwc.cn/news/691582.html

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

相关文章

EasyRecovery(易恢复) 使用测试及详细使用方法

你有没有因为数据丢失懊悔不已,EasyRecovery(易恢复),来自美国拥有38年数据恢复的软件,只有收费版,重要事情说三遍,EasyRecovery 没有免费版,可以成功找回删除的部分文件&#xff0c…

璩静霸道言论引发百度风波随笔

从5月9日晚开始有关“百度副总裁璩静已从公司离职”的消息,仅两天时间就几乎布满互联网所有知名自媒体平台,可谓兹事体大,无异于互联网发生了一场八级地震,波及面之广,匪夷所思! 百度截图 尽管笔者一直密切…

A Dexterous Hand-Arm Teleoperation System

A Dexterous Hand-Arm Teleoperation System Based on Hand Pose Estimation and Active Vision解读 摘要1. 简介2.相关工作2.1 机器人遥操作2.2 主动视觉(Active Vision) 3. 硬件设置4. 基于视觉的机器人手部姿态估计4.1 Transteleop4.2 Dataset 5. 主动…

【图解计算机网络】TCP 重传、滑动窗口、流量控制、拥塞控制

TCP 重传、滑动窗口、流量控制、拥塞控制 TCP 重传超时重传快速重传 滑动窗口流量控制拥塞控制慢启动拥塞避免拥塞发生快速恢复 TCP 重传 TCP重传是当发送的报文发生丢失的时候,重新发送丢失报文的一种机制,它是保证TCP协议可靠性的一种机制。 TCP重传…

AJ65SBT2B-64DA 三菱CC-Link D/A转换模块

AJ65SBT2B-64DA 是将数字值(16位有符号BIN数据)转换为模拟值(电压或电流)的模块。 AJ65SBT2B-64DA参数说明:4通道;输入分辨率0~12000,-12000~12000,-16000~16000;输出DC-10~10V,DC0~20mA;转换速…

掌握未来搜索的钥匙:深入解析 Milvus 向量搜索引擎的终极指南!

在大数据时代,向量搜索技术愈发重要。作为一个开源的向量相似性搜索引擎,Milvus 提供了基于向量的相似性搜索功能,广泛应用于机器学习、人工智能等领域。本文将深入介绍 Milvus 的基本概念,包括其介绍、主要作用、使用方法及注意事…

pair对组创建

创建方式1: pair<type,type> p(value1,value2); pair<string, int> p("Tom", 20); cout << "name:" << p.first << "age:" << p.second << endl; 创建方式2: pair<type,type> pmake_pair(v…

树莓派4B-搭建一个本地车牌识别服务器

实现目标&#xff1a; 一、设备自启后能够获得服务的ip与端口号&#xff0c;用于计算机连接设备&#xff1b; 二、计算机可以通过服务ip与端口访问设备服务&#xff1b; 三、上传需要处理的数据&#xff0c;返回结果反馈给用户&#xff1b; 四、上传到服务器的数据不会导致设备…

Oracle 数据库

前言 今天开始学习 Oracle 数据库&#xff0c;这是实习公司要求的&#xff0c;虽然还没开始实习&#xff0c;但是事先熟练到岗之后就不需要再花费时间学习了。有了 MySQL 的基础&#xff0c;学习 Oracle 应该问题不大&#xff0c;不过 MySQL 一些进阶的内容依然需要再精进一下。…

数据链路层(详细版)【02】

接 数据链路层&#xff08;详细版&#xff09;【01】 文章目录 四、以太网MAC层&#xff08;一&#xff09;MAC地址组成&#xff08;1&#xff09;48位MAC地址格式&#xff08;2&#xff09;单播地址 & 多播地址 & 广播地址&#xff08;3&#xff09;全球管理 & 本…

十二、Redis主从复制

与其他的中间件存在同样的问题&#xff0c;在单机的情况&#xff0c;随着业务的增长&#xff0c;会面临着灾备、性能方面的压力。Redis在这方面提供了一主一从、一主多从的结构。这种结构同时也是实现读写分离功能的基础。即主节点提供写能力&#xff0c;从节点提供读能力。为了…

vue3.0(六) toRef,toValue,toRefs和toRow,markRaw

文章目录 toReftoValuetoRefstoRowmarkRawtoRef和toRefs的区别toRaw 和markRaw的用处 toRef toRef 函数可以将一个响应式对象的属性转换为一个独立的 ref 对象。返回的是一个指向源对象属性的 ref 引用&#xff0c;任何对该引用的修改都会同步到源对象属性上。使用 toRef 时需…