【古月居《ros入门21讲》学习笔记】16_tf坐标系广播与监听的编程实现

目录

说明:

1. 实现过程(C++)

创建功能包(C++)

创建tf广播器代码(C++)

创建tf监听器代码(C++)

配置tf监听器与广播器代码编译规则

编译并运行

编译

运行

2. 实现过程(Python)

创建tf广播器代码(Python)

创建tf监听器代码(Python)

运行效果


说明:

1. 本系列学习笔记基于B站:古月居《ROS入门21讲》课程,且使用的Ubuntu与ROS系统版本与课程完全一致;

虚拟机版本Linux系统版本ROS系统版本
VMware WorkStation Pro 16Ubuntu18.04Melodic

2. 课程中的所有示例代码均已跑通,且对Pyhon版本的代码也都做了运行验证,并附带验证过程(错误均已修正);

3. 本节是整个笔记的第16节,对应视频课程的第18节,请自行对应学习;

4. 整个系列笔记基本已经完结,但部分章节仍需润色修改 ,后面会陆续发布,请大家持续关注,      创作不易,感谢支持!


1. 实现过程(C++)

创建功能包(C++)

cd ~/catkin_ws/src
catkin_create_pkg learning_tf roscpp rospy tfturtlesim

image-20230606160521970

创建tf广播器代码(C++)

cd ~/catkin_ws/src/learning_tf/src
touch turtle_tf_broadcaster.cpp

  • 定义tf广播器(TransformBroadcaster);

  • 创建坐标变换值;

  • 发布坐标变换(sendTransform)

/*** 该例程产生tf数据,并计算、发布turtle2的速度指令*/
​
#include <ros/ros.h>
#include <tf/transform_broadcaster.h>
#include <turtlesim/Pose.h>
​
std::string turtle_name;
​
void poseCallback(const turtlesim::PoseConstPtr& msg)
{// 创建tf的广播器static tf::TransformBroadcaster br;
​// 初始化tf数据tf::Transform transform;transform.setOrigin( tf::Vector3(msg->x, msg->y, 0.0) );tf::Quaternion q;q.setRPY(0, 0, msg->theta);transform.setRotation(q);
​// 广播world与海龟坐标系之间的tf数据br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", turtle_name));
}
​
int main(int argc, char** argv)
{// 初始化ROS节点ros::init(argc, argv, "my_tf_broadcaster");
​// 输入参数作为海龟的名字if (argc != 2){ROS_ERROR("need turtle name as argument"); return -1;}
​turtle_name = argv[1];
​// 订阅海龟的位姿话题ros::NodeHandle node;ros::Subscriber sub = node.subscribe(turtle_name+"/pose", 10, &poseCallback);
​// 循环等待回调函数ros::spin();
​return 0;
};
​

image-20230606161054441

创建tf监听器代码(C++)

cd ~/catkin_ws/src/learning_tf/src
touch turtle_tf_listener.cpp

  • 定义tf监听器(TransformListener);

  • 查找坐标变换(waitForTransform、lookupTransform)

/*** 该例程监听tf数据,并计算、发布turtle2的速度指令*/
​
#include <ros/ros.h>
#include <tf/transform_listener.h>
#include <geometry_msgs/Twist.h>
#include <turtlesim/Spawn.h>
​
int main(int argc, char** argv)
{// 初始化ROS节点ros::init(argc, argv, "my_tf_listener");
​// 创建节点句柄ros::NodeHandle node;
​// 请求产生turtle2ros::service::waitForService("/spawn");ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");turtlesim::Spawn srv;add_turtle.call(srv);
​// 创建发布turtle2速度控制指令的发布者ros::Publisher turtle_vel = node.advertise<geometry_msgs::Twist>("/turtle2/cmd_vel", 10);
​// 创建tf的监听器tf::TransformListener listener;
​ros::Rate rate(10.0);while (node.ok()){// 获取turtle1与turtle2坐标系之间的tf数据tf::StampedTransform transform;try{listener.waitForTransform("/turtle2", "/turtle1", ros::Time(0), ros::Duration(3.0));listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform);}catch (tf::TransformException &ex) {ROS_ERROR("%s",ex.what());ros::Duration(1.0).sleep();continue;}
​// 根据turtle1与turtle2坐标系之间的位置关系,发布turtle2的速度控制指令geometry_msgs::Twist vel_msg;vel_msg.angular.z = 4.0 * atan2(transform.getOrigin().y(),transform.getOrigin().x());vel_msg.linear.x = 0.5 * sqrt(pow(transform.getOrigin().x(), 2) +pow(transform.getOrigin().y(), 2));turtle_vel.publish(vel_msg);
​rate.sleep();}return 0;
};

image-20230606162405983

配置tf监听器与广播器代码编译规则

add_executable(turtle_tf_broadcaster src/turtle_tf_broadcaster.cpp)
target_link_libraries(turtle_tf_broadcaster ${catkin_LIBRARIES})
​
add_executable(turtle_tf_listener src/turtle_tf_listener.cpp)
target_link_libraries(turtle_tf_listener ${catkin_LIBRARIES})

image-20230606165523395

编译并运行

编译
cd ~/catkin_ws
catkin_make
source devel/setup.bash(如已配置 **.bashrc**文件,则此步不需要,配置方法在publisher的章节里)

image-20230606173417459

运行
roscore
rosrun turtlesim turtlesim_node

下面我们传入参数 第1个参数:因为在turtle_tf_broadcaster.cpp定义节点时使用了"my_tf_broadcaster"的名字,所以后面使用__name:=传入新的名字代 替"my_tf_broadcaster",以此来避免名字重复(ROS中的节点名字不能重复),如此就能重复跑这个程序了。

第2个参数:turtle名称 turtle1 和 turtle2。

rosrun learning_tf turtle_tf_broadcaster __name:=turtle1_tf_broadcaster /turtle1
rosrun learning_tf turtle_tf_broadcaster __name:=turtle2_tf_broadcaster /turtle2
rosrun learning_tf turtle_tf_listener

上面完成后,会有一只海龟在中心点,另一只海龟在左下方,并且左下方的海龟会跑向中间的那只海龟

image-20230607105934024

打开键盘控制节点,通过键盘控制中心点那只海龟,另只海龟也会自动的跟随前面的那只海龟同步去运动

rosrun turtlesim turtle_teleop_key

image-20230607110507433

2. 实现过程(Python)

创建tf广播器代码(Python)

cd ~/catkin_ws/src/learning_tf
mkdir scripts
cd scripts
touch turtle_tf_broadcaster.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程将请求/show_person服务,服务数据类型learning_service::Person
​
import roslib
roslib.load_manifest('learning_tf')
import rospy
​
import tf
import turtlesim.msg
​
def handle_turtle_pose(msg, turtlename):br = tf.TransformBroadcaster()br.sendTransform((msg.x, msg.y, 0),tf.transformations.quaternion_from_euler(0, 0, msg.theta),rospy.Time.now(),turtlename,"world")
​
if __name__ == '__main__':rospy.init_node('turtle_tf_broadcaster')turtlename = rospy.get_param('~turtle')rospy.Subscriber('/%s/pose' % turtlename,turtlesim.msg.Pose,handle_turtle_pose,turtlename)rospy.spin()
​
​

image-20230607111815061

创建tf监听器代码(Python)

cd ~/catkin_ws/src/learning_tf/scripts
touch turtle_tf_listener.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程将请求/show_person服务,服务数据类型learning_service::Person
​
import roslib
roslib.load_manifest('learning_tf')
import rospy
import math
import tf
import geometry_msgs.msg
import turtlesim.srv
​
if __name__ == '__main__':rospy.init_node('turtle_tf_listener')
​listener = tf.TransformListener()
​rospy.wait_for_service('spawn')spawner = rospy.ServiceProxy('spawn', turtlesim.srv.Spawn)spawner(4, 2, 0, 'turtle2')
​turtle_vel = rospy.Publisher('turtle2/cmd_vel', geometry_msgs.msg.Twist,queue_size=1)
​rate = rospy.Rate(10.0)while not rospy.is_shutdown():try:(trans,rot) = listener.lookupTransform('/turtle2', '/turtle1', rospy.Time(0))except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):continue
​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 = linearcmd.angular.z = angularturtle_vel.publish(cmd)
​rate.sleep()
​
​

image-20230607112048252

注意:给turtle_tf_broadcaster.py 和 turtle_tf_listener.py文件赋予作为程序文件执行的权限,

点击turtle_tf_broadcaster.py文件,右键,属性,权限,勾选(允许作为程序文件执行),

turtle_tf_listener.py文件操作同上,在ROS-Melodic版本中,python文件不需要编译,直接运行即可。

image-20230607112635115

运行效果

roscore
rosrun turtlesim turtlesim_node
​
rosrun learning_tf turtle_tf_broadcaster.py __name:=turtle1_tf_broadcaster _turtle:=turtle1
rosrun learning_tf turtle_tf_broadcaster.py __name:=turtle2_tf_broadcaster _turtle:=turtle2
rosrun learning_tf turtle_tf_listener.py
​
rosrun turtlesim turtle_teleop_key

image-20230607113817681

image-20230607113919029


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

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

相关文章

基于STC12C5A60S2系列1T 8051单片机的IIC总线器件24C02记录单片机上电次数应用

基于STC12C5A60S2系列1T 8051单片机的IIC总线器件24C02记录单片机上电次数应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍液晶显示器LCD1602简单介绍IIC通信简单介…

微信小程序生成二维码并保存到本地方法

微信小程序生成二维码请保存到本地方法 官方weapp-qrcode插件 github链接 功能完成样子 wxml <view class"qrcode"><canvas style"width: 275px; height: 275px;" canvas-idmyQrcode></canvas> </view> <view class" …

day66

今日回顾内容 web框架 django 路由控制 视图层 web框架 一、什么是web框架 Web框架&#xff08;Web framework&#xff09;是一种开发框架&#xff0c;用来支持动态网站、网络应用和网络服务的开发。这大多数的web框架提供了一套开发和部署网站的方式&#xff0c;也为web行…

resty-http库爬虫程序代码示例

lua -- 导入需要的库 local http require "resty.http" local io require "io" -- 创建一个客户端 local client http.new() -- 设置HTTP客户端的 client:set_proxy(proxy_host, proxy_port) -- 执行HTTP GET请求&#xff0c;获取网页内容 local res…

C语言数据结构之顺序表(上)

前言&#xff1a; ⭐️此篇博文主要分享博主在学习C语言的数据结构之顺序表的知识点时写的笔记&#xff0c;若有错误&#xff0c;还请佬指出&#xff0c;一定感谢&#xff01;制作不易&#xff0c;若觉得内容不错可以点赞&#x1f44d;收藏❤️&#xff0c;这是对博主最大的认可…

source: command not found错误的解决方法

偶遇的一个问题&#xff0c;因为在网上没有找到对应的解决办法&#xff0c;可能是属于个案&#xff0c;在此记录备忘&#xff0c;同时供大家参考。 问题现象&#xff1a; 执行命令 source /etc/profile时报错&#xff1a; bash: “source: command not found... 问题定位和…

内衣洗衣机和手洗哪个干净?小型洗衣机质量排名

这两年内衣洗衣机可以称得上较火的小电器&#xff0c;小小的身躯却有大大的能力&#xff0c;一键可以同时启动洗、漂、脱三种全自动为一体化功能&#xff0c;在多功能和性能的提升上&#xff0c;还可以解放我们双手的同时将衣物给清洗干净&#xff0c;让越来越多小伙伴选择一款…

如何恢复已删除的照片 ?适用于 Windows 的Android 数据恢复软件值得尝试

“我丢失了 Android 手机上的照片&#xff0c;有人告诉我使用恢复程序来找回所有手机数据。我使用的是 Windows 10 和华为 手机&#xff0c;对于 Windows最有效的 Android 数据恢复是什么&#xff1f;” Android 恢复程序用于检索丢失或删除的文件&#xff0c;如照片、联系人、…

SimpleCG小游戏开发系列(1)--扫雷

一、前言 前面我们学习了SimpleCG的游戏开发框架,从本篇开始,我们用一系列小游戏的开发来加深对框架的了解.我们先以windows的经典游戏--扫雷,作为首个例子。游戏预览如下 二、框架搭建 因为游戏程序的大体框架差不多&#xff0c;所以我们可以搭建一个通用的主程序。如下所示&a…

导致Facebook广告投放不成功的原因

Facebook是全球最大的社交媒体平台之一&#xff0c;也是众多跨境卖家选择广告投放的首选平台&#xff0c;但也还是会有很多跨境卖家在Facebook上推广效果不佳。那么本文小编讲一下导致Facebook广告投放不成功的原因以及相应解决方法。 1、受众群体太少 Facebook有个要求就是广告…

Java之顺序栈实现数制转换问题

一、前言&#xff1a; 这是怀化学院的&#xff1a;Java数据结构中的一道中等编程题(此方法为博主自己研究&#xff0c;问题基本解决&#xff0c;若有bug欢迎下方评论&#xff0c;我会第一时间改进代码&#xff0c;谢谢&#xff01;) 后面其他编程题只要我写完成功&#xff0c;会…

数字人担任展会虚拟主持人,如何释放大会新活力?

近日&#xff0c;虚拟主持人谷小雨解锁新身份&#xff0c;作为第二届全球数字贸易博览会的“数字新闻官”为大众播报展会的热门新闻话题&#xff0c;带领大众探索未来数字贸易的无限可能。 *图片源于网络 随着元宇宙的概念更多地深入各领域&#xff0c;数字人多次以虚拟主持人或…

iframe内存泄露问题

场景 左边导航栏&#xff0c;顶部tab标签&#xff0c;下面的iframe是点击导航菜单生成的&#xff0c;顶部的tab标签对应每一个打开的菜单名称&#xff0c;可以点击关闭 问题 内存泄漏 解决 const delIframeDom document.getElementById(menuId);if (delIframeDom) {delI…

MySQL双主双从数据库集群搭建

1 引言 在之前的文章中提到过相关搭建方法&#xff0c;具体请参考《MySQL主从数据库搭建》这篇文章&#xff0c;本文主要讲述双主双从&#xff0c;双主多从集群的搭建方式。 这里要问一个问题&#xff0c;为什么MySQL要搭建数据库集群呢&#xff1f;我想应该有以下几点原因&…

面试题:Spring 中获取 Bean 的方式有哪些?

文章目录 前言1、在初始化时保存ApplicationContext对象2、通过Spring提供的工具类获取ApplicationContext对象3、实现接口ApplicationContextAware&#xff08;推荐&#xff09;4、继承自抽象类ApplicationObjectSupport5、继承自抽象类WebApplicationObjectSupport6、使用Bea…

【Python深度学习第二版】学习笔记之——什么是深度学习

机器学习是将输入&#xff08;比如图像&#xff09;映射到目标&#xff08;比如标签“猫”&#xff09;的过程。 这一过程是通过观察许多输入和目标的示例来完成的。 深度神经网络通过一系列简单的数据变换&#xff08;层&#xff09;来实现这种输入到目标的映射&#xff0c;这…

日期对象与节点操作

1.日期对象 1.1实例化 // 实例化const date new Date()console.log(date);// 返回指定时间const date1 new Date(2022-5-1 08:30:00)console.log(date1);1.2日期对象方法 1.3时间戳 三种获取时间戳的方法 const date new Date()console.log(date.getTime());console.log(ne…

MaskDINO环境搭建与模型测试

1、环境搭建 1、构建虚拟环境安装torch conda create -n mmdetsam python3.8 -y conda activate mmdetsampip install torch1.10.0cu102 torchvision0.11.0cu102 torchaudio0.10.0 -f https://download.pytorch.org/whl/torch_stable.html -i http://mirrors.aliyun.com/pypi…

【计算机网络学习之路】序列化,反序列化和初识协议

文章目录 前言一. 序列化和反序列化1.自己实现2. JSON 二. 初识协议结束语 前言 本系列文章是计算机网络学习的笔记&#xff0c;欢迎大佬们阅读&#xff0c;纠错&#xff0c;分享相关知识。希望可以与你共同进步。 本篇博文讲解应用层的序列化和反序列化&#xff0c;还有见一…

uniapp页面使用多个echarts出现数据渲染错乱问题解决

首先&#xff0c;uniapp当中使用echarts是在通过使用renderjs的script模板的前提下实现的&#xff0c;在官方提供的案例当中&#xff0c;核心代码是这一部分&#xff1a; 但如果将其封装为组件&#xff0c;并在一个页面当中引用多次来生成多个charts图标&#xff0c;那么这个时…