首页 > 编程语言 >tf坐标系广播羽监听的编程实现

tf坐标系广播羽监听的编程实现

时间:2023-08-01 15:44:48浏览次数:43  
标签:turtle turtle2 编程 transform listener tf ros 监听

创建功能包

cd ~/catkin_ws/src
catkin_create_pkg learning_tf roscpp rospy turtlesim tf

广播器和监听器代码

如何实现一个tf广播器
  1. 定义TF广播器(TransformBroadcaster)
  2. 创建坐标变换值
  3. 发布坐标变换(sendTransform)

turtle_tf_broadcaster.cpp
点击查看代码
/**
 * 该例程产生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;
};
如何实现一个TF监听器
  1. 定义TF监听器(TransformListener)
  2. 查找坐标变换(waitForTransform、lookupTransform)

turtle_tf_listener.cpp

点击查看代码
/**
 * 该例程监听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;

	// 请求产生turtle2
	ros::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;
};

配置CMakeLists.txt的编译规则

build中添加
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})

标签:turtle,turtle2,编程,transform,listener,tf,ros,监听
From: https://www.cnblogs.com/ruizi816/p/17596700.html

相关文章

  • netfilter中有哪些挂载点(hook points)?
    5个挂载点,挂载点有各种数据包处理的规则。 分别是:PREROUTINGINPUTFORWAROUTPUTPOSTROUTING 这些挂接点(hookpoints),是数据包处理的不同的阶段。 每个挂节点上,都可以挂载不同的包的处理规则,从而实现对数据包的处理和过滤。 ......
  • iTOP-i.MX6ULL开发板Qt 串口编程
    本章内容对应视频讲解链接(在线观看):QT上位机开发之串口助手(上)→B站搜索标题→【北京迅为】嵌入式学习之QT学习篇QT上位机开发之串口助手(下)→B站搜索标题→【北京迅为】嵌入式学习之QT学习篇本节我们使用Qt来编写一个简单的上位机。实验介绍:组装ui界面,使用Qt提供的串口类......
  • GO 编程模式:FUNCTIONAL OPTIONS
    在本篇文章中,我们来讨论一下FunctionalOptions这个编程模式。这是一个函数式编程的应用案例,编程技巧也很好,是目前在Go语言中最流行的一种编程模式。但是,在我们正式讨论这个模式之前,我们需要先来看看要解决什么样的问题。本文是全系列中第3/10篇:Go编程模式Go编程模式:切片,接口......
  • (Python编程)基本的内嵌技术
    ProgrammingPython,3rdEdition翻译最新版本见wiki:http://wiki.woodpecker.org.cn/moin/PP3eD欢迎参与翻译与修订。23.3.BasicEmbeddingTechniques23.3.基本的内嵌技术Asyoucanprobablytellfromtheprecedingoverview,thereismuchfl......
  • 记录每一天,流式编程 stream
    流式编程stream我以为遇到lambda已经够让我惊喜了,万万没想到stream的出现,才让我发现它才是函数式编程的主角。特点:无存储。stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/Ochannel等。对stream的任何修改都不会修......
  • 零基础应该如何学习计算机编程?
    一、编程的概念让我们简单介绍一下编程。编程是人与计算机之间的一种交流方式,通过编写一系列的程序指令,指导计算机执行相应的任务。专门从事编程工作的技术人员被称为程序员。在计算机领域,编程可以细分为许多技术方向。从整体上看,可以分为两类,即高层编程和低层编程。当......
  • RichEdit RTF格式文本的存储和读取 VC++
    Rtf格式文本的读写,向控件发送EM_STREAMIN和EM_STREAMOUT消息,控件把格式文本显示或从把显示内容转化为格式文本。接口是用户定义的回调函数,格式文本由参数DWORD_PTRdwCookie传递。从控件读出RTF文本,参数用string比较好,因为消息处理是根据文本的长度,多次调用回调函数,传出数......
  • 编程实现邮件地址有效性检测
    这个VB6COM组件提供了一项即时邮件查询的功能。它有效的避免了向一个不存在的账户发送邮件的情况。例如,在ASP页面里面检查用户输入的邮件地址是否正确,并避免在你的用户数据库里面存储相关的错误信息。主要内容工作原理让我们首先来看一下这个组件是如何进行工作的。首先给定一个E-......
  • (Python编程)目录工具
    ProgrammingPython,3rdEdition翻译最新版本见wiki:http://wiki.woodpecker.org.cn/moin/PP3eD欢迎参与翻译与修订。   4.3.DirectoryTools 4.3.目录工具Oneofthemorecommontasksintheshellutilitiesdomainisapplyinganoperationtoasetoffilesin......
  • python教程 入门学习笔记 第3天 编程基础常识 代码注释 变量与常量
    编程基础常识一、注释1、对代码的说明与解释,它不会被编译执行,也不会显示在编译结果中2、注释分为:单行注释和多行注释3、用#号开始,例如:#这是我的第一个python程序4、注释可以写在单独一行,也可以写在一句代码后面5、不想执行编译,又不能删除的代码,可以先用#注释掉,代码批量注释......