ROS第 13 课 TF 坐标系广播与监听的编程 实现
文章目录
- 第 13 课 TF 坐标系广播与监听的编程 实现
- 1.机器人的坐标变换
- 2.创建功能包
- 3.编程方法
- 3.1 编写广播和监听程序
- 3.2 运行程序
第 13 课 TF 坐标系广播与监听的编程 实现
1.机器人的坐标变换
在进行编程前,先需要了解机器人的坐标变换。这里以运行海龟案例来进行解说,步骤如下:
- 输入指令“sudo apt-get install ros-melodic-turtle-tf”,安装功能包。

其中“melodic”对应的是ROS版本。 - 输入指令“roslaunch turtle_tf turtle_tf_demo.launch”,启动launch文件。

- 输入指令“rosrun turtlesim turtle_teleop_key”,运行海龟键盘控制节点。


- 输入指令“rosrun tf view_frames”,可视化框架。

在主目录下可以找到“frames.pdf”文件,如下图:

打开“frames.pdf”文件,可以看到当前系统TF坐标之间的位置关系,如下图:

2.创建功能包
下面,就开始创建功能包,步骤如下:
- 输入指令“cd catkin_ws/src/”,回车,进入工作空间。

- 输入指令“catkin_create_pkg tf_hiwonder rospy std_msgs”,回车,创建功能包。

3.编程方法
3.1 编写广播和监听程序
- 打开Linux命令行终端。
- 输入进入功能包所在目录的指令“roscd tf_hiwonder”,并按下回车。

- 输入指令“mkdir scripts”,并按下回车,新建用于存放Python脚本的文件夹“scripts”。

- 输入指令“cd scripts/”,并按下回车,进入用于存放Python脚本的文件夹“scripts”。

- 输入指令“vi turtle_tf_broadcaster.py”编辑程序,复制下面程序。如需修改,再按下“i”即可修改。修改完成,按下“Esc”,输入“:wq”保存并退出。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程监听turtlesim节点发布的乌龟位姿,并将其转换为tf转换消息广播出去# 导入tf模块,这是ROS中用于处理转换的库
import tf
# 导入rospy,这是Python编写ROS节点的主要库
import rospy
# 导入turtlesim包的Pose消息类型
import turtlesim.msg# 定义处理乌龟位姿消息的函数
def handle_turtle_pose(msg, turtlename):# 创建一个TransformBroadcaster对象,用于发送转换br = tf.TransformBroadcaster()# 发送转换,包括:# - 位置:根据乌龟的x、y坐标和固定的z坐标(0,因为turtlesim是2D的)# - 方向:将乌龟的角度转换成四元数,因为转换需要使用四元数来表示旋转# - 时间戳:当前的ROS时间# - 子坐标系:乌龟的名称# - 父坐标系:世界坐标系(通常称为"world")br.sendTransform((msg.x, msg.y, 0),tf.transformations.quaternion_from_euler(0, 0, msg.theta),rospy.Time.now(),turtlename,"world")# 程序的主入口
if __name__ == '__main__':# 初始化ROS节点,名为'turtle_tf_broadcaster'rospy.init_node('turtle_tf_broadcaster')# 获取私有命名空间下的'turtle'参数,这将确定我们关注的是哪个乌龟turtlename = rospy.get_param('~turtle')# 订阅乌龟的位姿话题,这个话题名称是通过拼接乌龟的名字动态确定的rospy.Subscriber('/%s/pose' % turtlename,turtlesim.msg.Pose,handle_turtle_pose,turtlename)# ROS的spin循环,这将保持你的程序不会退出直到节点被明确关闭rospy.spin()

6) 输入指令“vi turtle_tf_listener.py”编辑程序,复制下面程序。如需修改,再按下“i”即可修改。修改完成,按下“Esc”,输入“:wq”保存并退出。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程监听turtle1的tf变换,并使turtle2向turtle1移动# 导入所需要的模块
import roslib
import rospy
import math
import tf # 用于处理ROS中的坐标变换
import geometry_msgs.msg # 导入消息类型,用于发布速度
import turtlesim.srv # 导入服务类型,用于创建新的乌龟# 程序的主入口
if __name__ == '__main__':# 初始化ROS节点,名为'turtle_tf_listener'rospy.init_node('turtle_tf_listener')# 创建一个TransformListener对象,用于接收坐标变换listener = tf.TransformListener()# 等待spawn服务变得可用rospy.wait_for_service('spawn')# 创建一个服务客户端,用于调用spawn服务以生成新的乌龟spawner = rospy.ServiceProxy('spawn', turtlesim.srv.Spawn)# 调用spawn服务,在(4, 2)坐标处生成新的乌龟,角度为0,名为'turtle2'spawner(4, 2, 0, 'turtle2')# 创建一个发布者,用于发布turtle2的速度turtle_vel = rospy.Publisher('turtle2/cmd_vel', geometry_msgs.msg.Twist, queue_size=1)# 设置循环的频率为10Hzrate = rospy.Rate(10.0)while not rospy.is_shutdown(): # 当ROS没有关闭时循环执行try:# 查询turtle2到turtle1的最新变换,返回平移和旋转信息(trans, rot) = listener.lookupTransform('/turtle2', '/turtle1', rospy.Time(0))# 如果在查询变换时发生异常,则继续下一次循环except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):continue# 根据turtle2和turtle1的相对位置计算出需要向turtle1移动的速度angular = 4 * math.atan2(trans[1], trans[0]) # 角速度linear = 0.5 * math.sqrt(trans[0] ** 2 + trans[1] ** 2) # 线速度cmd = geometry_msgs.msg.Twist() # 创建速度消息cmd.linear.x = linear # 设置线速度cmd.angular.z = angular # 设置角速度turtle_vel.publish(cmd) # 发布速度消息,使turtle2向turtle1移动rate.sleep() # 等待一段时间直到达到10Hz的循环频率

6) 输入指令“chmod +x turtle_tf_broadcaster.py”和“chmod +x turtle_tf_listener.py”,并按下回车,赋予文件可执行权限。


7) 输入指令“cd …”和“mkdir launch”,新建用于存放launch脚本的文件夹“launch”。


8) 输入指令“cd launch/”,并按下回车,进入用于存放Python脚本的文件夹“launch”。

9) 输入指令“vi start_tf_demo_py.launch”编辑程序,复制下面程序。如需修改,再按下“i”即可修改。修改完成,按下“Esc”,输入“:wq”保存并退出。

<launch><!-- Turtlesim Node--><node pkg="turtlesim" type="turtlesim_node" name="sim"/><node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen"/><node name="turtle1_tf_broadcaster" pkg="tf_hiwonder" type="turtle_tf_broadcaster.py" respawn="false" output="screen" ><param name="turtle" type="string" value="turtle1" /></node><node name="turtle2_tf_broadcaster" pkg="tf_hiwonder" type="turtle_tf_broadcaster.py" respawn="false" output="screen" ><param name="turtle" type="string" value="turtle2" /> </node><node pkg="tf_hiwonder" type="turtle_tf_listener.py" name="listener" /></launch>

3.2 运行程序
- 输入指令“source ./devel/setup.bash”,并按下回车,设置工作环境。

- 输入指令“roslaunch tf_hiwonder start_tf_demo_py.launch”,并按下回车,运行launch程序。

一只海龟自动行走到另一只海龟位置,显示如下图:

- 如需终止程序,可按下快捷键“Ctrl+C”。
相关文章:
ROS第 13 课 TF 坐标系广播与监听的编程 实现
文章目录 第 13 课 TF 坐标系广播与监听的编程 实现1.机器人的坐标变换2.创建功能包3.编程方法3.1 编写广播和监听程序3.2 运行程序 第 13 课 TF 坐标系广播与监听的编程 实现 1.机器人的坐标变换 在进行编程前,先需要了解机器人的坐标变换。这里以运行海龟案例来…...
flask 与小程序 菜品详情和分享功能
mina/pages/food/info.wxml <import src"../../wxParse/wxParse.wxml" /> <view class"container"> <!--商品轮播图--> <view class"swiper-container"><swiper class"swiper_box" autoplay"{{autop…...
C语言通过MSXML6.0读写XML文件(同时支持char[]和wchar_t[]字符数组)
开发环境:Visual Studio 2010 运行环境:Windows XP SP3 第一节 读取XML文件(使用wchar_t[]字符数组) 读取XML文件可使用IXMLDOMDocument_load函数。 /* 这个程序只能在C编译器下编译成功, 请确保源文件的扩展名为c */ #define …...
在react中说说对受控组件和非受控组件的理解?以及应用场景
在react中说说对受控组件和非受控组件的理解?以及应用场景 回答思路:说说受控组件-->说说非受控组件-->应用场景受控组件:非受控组件应用场景 回答思路:说说受控组件–>说说非受控组件–>应用场景 受控组件ÿ…...
【算法练习Day50】下一个更大元素II接雨水
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:练题 🎯长路漫漫浩浩,万事皆有期待 文章目录 下一个更大元素II接雨水单调…...
深耕文档型数据库12载,SequoiaDB再开源
1月15日,巨杉数据库举行SequoiaDB新特性及开源项目发布活动。本次活动回顾了巨杉数据库深耕JSON文档型数据库12年的发展历程与技术演进,全面解读了SequoiaDB包括在高可用、安全、实时、易用性四个方向的技术特性,宣布了2024年面向技术社区的开…...
json解析
1什么是json JSON(JavaScript Object Notation,JS对象简谱)是一种轻量级的数据交换格式。它是基于ECMAScript(欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰…...
【AI】深度学习在编码中的应用(8)
接上文,本文来梳理和学习智能编码中, 基于残差编码的框架。 智能图像编解码器的成功也推动了智能视频编解码器的发展。传统的视频压缩方法依靠预测编码对运动信息和残差信息分别进行编码。根据时-空域冗余消除方式和阶段不同,现有相关方法可…...
什么是VUE 创建第一个VUE实例
一、什么是Vue 概念:Vue (读音 /vjuː/,类似于 view) 是一套 构建用户界面 的 渐进式 框架 Vue2官网:Vue.js 1.什么是构建用户界面 基于数据渲染出用户可以看到的界面 2.什么是渐进式 所谓渐进式就是循序渐进,不一定非得把Vu…...
进程间协同:从进程启动、同步与互斥到进程间通信
进程间协同的目的 在操作系统中,进程是计算机进行任务分配和调度的基本单位。在计算机系统中,有很多任务是无法由单个进程独立完成的,需要多个进程共同参与并协作完成。这就像在现实生活中,有些工作需要一个团队来完成࿰…...
【驱动】TI AM437x(内核调试-06):网卡(PHY和MAC)、七层OSI
1、网络基础知识 1.1 七层OSI 第一层:物理层。 1)需求: 两个电脑之间如何进行通信? 具体就是一台发比特流,另一台能够收到。于是就有了物理层:主要是定义设备标准,如网线的额接口类型、管线的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流,就是从1/0…...
Java基础面试题 Object
Java基础面试题 Object 文章目录 Java基础面试题 ObjectObjectObject 类的常见方法有哪些? 和 equals() 的区别hashCode() 有什么用?为什么要有 hashCode?为什么重写 equals() 时必须重写 hashCode() 方法? 文章来自Java Guide 用…...
5G_射频测试_接收机测量(五)
7.2 Reference sensitivity level 接收灵敏度是表示接收机能解析出信号的最小功率(和接收机noise figure相关所以RX lineup的大部分工作就是在调整Gain达到最佳NF)The throughput shall be ≥ 95%(BER:bit error rate 并不是L3ca…...
ESP32-HTTP_webServer库(Arduino)
ESP32-HTTP 介绍 ESP32是一款功能强大的微控制器,具有丰富的网络和通信功能。其中之一就是支持HTTP协议,这使得ESP32可以用于创建Web服务器。 HTTP是什么? HTTP(Hyper Text Transfer Protocol),即超文本传…...
无法找到mfc100.dll的解决方法分享,如何快速修复mfc100.dll文件
在日常使用电脑时,我们可能会碰到一些系统错误提示,比如“无法找到mfc100.dll”的信息。这种错误通常会阻碍代码的执行或某些应用程序的启动。为了帮助您解决这一问题,本文将深入探讨其成因,并提供几种不同的mfc100.dll解决方案。…...
[VulnHub靶机渗透]:billu_b0x 快速通关
🍬 博主介绍👨🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏 == 养成习惯(一键三连)😋 🎉欢迎关注💗一起学习👍一起讨论⭐️一起进步…...
Docker安装开源Blog(Typecho)
前言 首先这个镜像是centos7.9进行安装PHP环境,然后挂载目录去运行的,镜像大概300MB左右,没学过PHP,没办法给Dockerfile文件 参考文章:Docker安装Typecho | D-y Blog感知不强,图一乐https://www.wlul.top…...
【Qt-license】误操作qt下载导致只能安装商业版试用十天,无法安装社区版
背景: 原本是为了学习qml,需要下载一个design studio,而这个需要比较新版的安装程序,但新版的安装程序官方都是online安装。于是从官网找下载链接。毕竟是英文的,又心急,误打误撞中我选择了商业版试用。 其…...
数据操作——缺失值处理
缺失值处理 缺失值的处理思路 如果想探究如何处理无效值, 首先要知道无效值从哪来, 从而分析可能产生的无效值有哪些类型, 在分别去看如何处理无效值 什么是缺失值 一个值本身的含义是这个值不存在则称之为缺失值, 也就是说这个值本身代表着缺失, 或者这个值本身无意义, 比如…...
【刷题笔记4】
动态规划题目汇总 斐波那契数列:1,1,2,3,5,8,13…… 递归一把解决三类问题:1.数据定义是按照递归的(斐波那契数列)。2.问题解法是按递归算法实现的。 3.数据…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
