编程实现ROS话题通信——手撕 turtlesim 节点

news2024/11/19 19:29:42

一、实验任务

任务要求如下:使用 C++ 编程实现1个ROS节点,订阅 turtlesim 例程中 turtle_teleop_key 节点发出的消息,并将此消息进行一定的转换后(自行定义,如将数值按适当比例缩小、运动方向变换等),再发布给 turtlesim_node 节点,并将接收的和转换后发布的消息内容实时输出打印到终端,运行时的计算图应如下图所示。

d910772e33b04b4a8fe1a4ff20041e79.png

二、实验原理

本人通过学习 talker 和 chatter 的代码,进行相应的修改。

在终端输入

catkin_create_pkgs rospy roscpp std_msgs #创建一个功能包

然后在功能包内的src文件夹下创建一个节点tranform_node,编写transform_node的cpp文件。

首先订阅turtle_teleop_key节点发布的cmd_vel的话题,编写回调函数,在回调函数中,对小海龟的坐标进行一个处理,我将小海龟的x轴和y轴进行了一个调换。在回调函数中,需要定义一下发布的消息类型transform,和cmd_vel保持一致,都是两组,分别是linear和anagular中的float x,float y和float z。

然后编写一个发布者,将transform消息发布出去,定义一个叫做cmd_vel_cov的话题,将这个话题中的transform消息发布出去。

通过ROS重映射,将turtlesim_node节点订阅的话题修改为cmd_vel_cov,就能实现任务的要求了

其中ROS重映射的知识可以参考这个链接:wiki.ros.org/Remapping Arguments

三、实验过程

如果不进行重映射,那么transform和turtlesim_node都是订阅的cmd_vel的话题,没有人订阅transform发布的cmd_vel_cov话题。

终端输入指令如下:

roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
rosrun tranform_node transform_node
rqt_graph

2535ca75f76f48998ce7aeea41a9b64e.png

rqt_graph如下所示:

c227d64a66e841eb96f905491ce9818c.png

根据ros重映射的知识,在终端输入:

rosrun turtlesim turtlesim_node /turtle1/cmd_vel:=/cmd_vel_cov

将turtlesim_node节点的订阅话题从cmd_vel改为cmd_vel_cov,这样就能让turtlesim_node节点订阅我设计的tranform节点发布的话题了,最终实现,turtle_teleop发布cmd_vel话题,tranform订阅cmd_vel话题,修改数据后再发布一个cmd_vel_cov的话题,turtlesim_node订阅cmd_vel_cov话题。

终端输入完整的指令如下:

roscore
rosrun turtlesim turtlesim_node /turtle1/cmd_vel:=/cmd_vel_cov
rosrun turtlesim turtle_teleop_key
rosrun tranform_node transform_node
rqt_graph

229a6c0afa83425f9bd7f36f29799825.png

rqt_graph如下所示:

157b937d740149cf8fcaa91bee2411f2.png

按照任务要求的截图如下:

980be2ad18f64bea90ff9d2159cd4532.png

四、代码实现

本人编写的 cpp 代码如下:

#include"ros/ros.h"//引用ros的头文件
#include"geometry_msgs/Twist.h"//引用小海龟的消息类型

ros::Publisher transform_pub;//定义一个话题的发布者transform_pub

void TransformCallback(const geometry_msgs::Twist msg)//定义一个回调函数,用于海龟/turtle1/cmd_vel话题的订阅
{
    geometry_msgs::Twist transform;//定义一个消息类型,用于处理cmd_vel的转换
    //数据处理:将海龟cmd_vel中数据(线速度和角速度)的x,y,z坐标进行旋转,将x轴变成y轴,y轴变成x轴
    transform.linear.x = msg.linear.y;
    transform.linear.y = msg.linear.x;
    transform.linear.z = msg.linear.z;
    transform.angular.x = msg.angular.y;
    transform.angular.y = msg.angular.x;
    transform.angular.z = msg.angular.z;
    //将处理后的数据发布出去
    transform_pub.publish(transform);
    //通过ROS_INFO和ROS_WARN在终端中输出海龟的运动信息
    ROS_INFO("坐标变换后,小海龟x轴线速度为%f,y轴线速度为%f,z轴线速度为%f,",transform.linear.x,transform.linear.y,transform.linear.z);
    ROS_WARN("坐标变换后,小海龟x轴角速度为%f,y轴角速度为%f,z轴角速度为%f,",transform.angular.x,transform.angular.y,transform.angular.z);

}


int main(int argc, char **argv)
{
    setlocale(LC_ALL,"");//中文字符不乱码
    ros::init(argc, argv, "transform_node");//初始化transform_node节点
    
    ros::NodeHandle n;//定义节点管理者

    transform_pub = n.advertise<geometry_msgs::Twist>("/cmd_vel_cov",10);//发布一个叫做/cmd_vel_cov的话题

    ros::Subscriber turtle_sub = n.subscribe("/turtle1/cmd_vel", 10, TransformCallback);//通过回调函数订阅/turtle1/cmd_vel

    ros::spin();//进行循环
    return 0;
}

    

在之前创建包时系统自动创建的 CmakeLists.txt 文件末尾添加如下代码即可编译:

#添加可执行程序
add_executable(transform_node src/transform_node.cpp)
#链接库文件
target_link_libraries(transform_node ${catkin_LIBRARIES} )

此外,还可以结合 launch文件 进行节点的集成化运行。

<launch>

<node pkg="turtlesim" type="turtlesim_node" name="turtle1">
<remap from="/turtle1/cmd_vel" to="/cmd_vel_cov"/>
</node>

<node pkg="transform_node" type="transform_node" name="tranform" output="screen">
</node>
<node pkg="turtlesim" type="turtle_teleop_key" name="teleop_key" output="screen">
</node>

<param name="scale_linear" value="1" type="double"/>
<param name="scale_anagular" value="1" type="double"/>

</launch>

【对于launch文件的说明】

launch文件将之前实验实现的订阅与发布集成的节点transform_node,与ROS系统自带的turtlesim_node和turtlesim_teleop_key节点,合并写在一个launch启动文件中,最终实现在终端只运行roslaunch  [包名]   [launch文件名],对于本人编写的代码, roslaunch transform_node turtlesim.launch即可将全部功能实现,启动了所有节点(包括主节点),实现了话题通讯。

下面是运行launch文件的截图:

总结

 我们主要学习了ROS的通信机制,本人以话题通讯为例,结合小海龟的示例程序进行详细的讲解,并自行编写发布者订阅者的代码,还通过编写launch文件实现节点同步运行,最终实现了一个小海龟速度的转换节点。

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

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

相关文章

【CANN】SPI通信、I2C通信

文章目录 一、SPI通信1.SPI通信2.SPI通信原理3.CPOL时钟极性、CPHA时钟相位 二、I2C通信1、I2C通信2、I2C通信原理2.1、I2C的起始和结束条件2.2、数据传送格式 总结 一、SPI通信 1.SPI通信 SPI是英语Serial Peripheral interface的缩写&#xff0c;顾名思义就是串行外围设备接…

@Async注解的坑

问题描述 一个方法调用另一个方法(该方法使用Async注解)在同一个类文件中&#xff0c;该注解会失效&#xff01; 问题复现 TestAsyncController 类 import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Async; im…

el-table解决数据过少小于高度有留白的问题

问题:给el-table设置个高度,高度为500px,之后就添加如下4条数据,那么底部就没数据,直接就空白了,本文章就是为了解决这个问题,如果底部留白那么就添加几条空数据就行了.如果数据已达到高度了那么就不会留白了 1.效果 这个空列可以根据高度来决定添加几个空格子去铺满列表&…

基于头脑风暴算法优化概率神经网络PNN的分类预测 - 附代码

基于头脑风暴算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于头脑风暴算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于头脑风暴优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

数字三角形模型 笔记

方格取数 走两次的最大值 f[k][i1][i2]来表示 k i1 j1 i2 j2; 每一个状态可由四种状态转换来&#xff0c;分别为 第一条路走下&#xff0c;第二条路走下 第一条路走下&#xff0c;第二条路走右 第一条路走右&#xff0c;第二条路走下 第一条路走右&#xff0c;第二条…

一文了解多线程实现交替执行

本文已收录于专栏 《Java》 目录 背景介绍实现方式总结提升 背景介绍 有一个需求是要求多个线程去执行任务&#xff0c;需要每个线程都执行一次之后再继续执行&#xff0c;也就是说每个线程交替去执行任务。举个例子来说&#xff0c;有两个线程&#xff0c;一个输出字母&#x…

全球步入VUCA时代,FinOps如何成为云计算下一个关键性机会?

科技云报道原创。 俗话说&#xff0c;省下来的就是利润。在全球都处于VUCA的时代&#xff0c;更是如此。 近年来&#xff0c;随着云计算的广泛应用,云成本管理成为企业关注的重点。FinOps&#xff08;云成本优化&#xff09;作为一种新兴的云成本管理方式&#xff0c;吸引了行…

基于蝴蝶算法优化概率神经网络PNN的分类预测 - 附代码

基于蝴蝶算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于蝴蝶算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于蝴蝶优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…

成都爱尔周进院长解析高度近视可能引发哪些疾病

当代各类人群面对电脑、手机屏幕的时长显著增加&#xff0c;导致用眼过度、疲劳&#xff0c;视觉质量下降&#xff0c;近视人群越来越多。而当父母有一方为高度近视甚至可能将近视遗传给孩子。 目前&#xff0c;全球近视人数约25亿&#xff0c;中国近视人群人数多达6亿。据预测…

Unity--互动组件(Button)

1.组件的可交互 2.组件的过渡状态 3.组件的导航 4.组件的Event Button “”组件的可交互&#xff1a;“” Interactable&#xff1a; 该组件是否可点击&#xff08;设置为false时&#xff0c;将禁用交互&#xff0c;并且过渡状态将设置为禁用状态&#xff09;&#xff1b;…

基于RK3568的跑步机方案

I 方案简介 一、跑步机的来历 跑步机是家庭及健身房常备的健身器材&#xff0c;而且是当今家庭健身器材中最简单的一种&#xff0c;是家庭健身器的最佳选择。1965年北欧芬兰唐特力诞生了全球第一台家用的跑步机&#xff0c;设计师根据传速带的原理改变而成。 二、…

对红黑树的理解与实现(C++实现)

认识红黑树 在看到此篇文章之前最好还是先了解一下左右旋也就是AVL树的插入数据该如何处理。AVL树的插入详解-CSDN博客 红黑树&#xff0c;也属于是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是红色&#xff08;red&#xff09;…

小程序中如何设置多门店/多人/多商品价格库存等复杂场景设置

有些商家希望打造小程序平台&#xff0c;在这个平台上有多个商家入驻&#xff0c;他们分别售卖自己的商品。而有些商家有多个连锁店&#xff0c;连锁店的商品都是一样的&#xff0c;但不同的连锁店有不同的库存和价格。这些业务在采云小程序中是怎么支持的呢&#xff1f;下面具…

office365 outlook邮件无法删除

是否遇到过&#xff0c;office365邮件存储满了&#xff0c;删除邮件无法删除&#xff0c;即便用web方式登录到outlook&#xff0c;删除邮件当时是成功的&#xff0c;但一会儿就回滚回来了&#xff0c;已删除的邮件&#xff0c;你想清空&#xff0c;最后清理后还是回到原样。 请…

curl(八)时间和环境变量以及配置

一 时间 ① --connect-timeout 连接超时时间 ② -m | --max-time 数据最大传输时间 -m&#xff1a; 限制curl 完成时间(overall time limit)-m,--max-time <seconds> 整个交互完成的超时时间场景&#xff1a; 通过设置-m参数,可以避免请求时间过长而导致的超时错误…

纯CSS实现魔法渐变边框卡片

如图所示&#xff0c;这是一个很炫酷的卡片效果&#xff0c;关键效果在于卡片的边框呈渐变色变化着&#xff0c;在网页中有这样一个卡片相信可以极大的增强用户体验交互。本次文章将解读如何使用纯CSS实现这个炫酷的卡片效果。 基于上面的动图可以分析出以下是本次实现的主要几…

如何计算掩膜图中多个封闭图形的面积

import cv2def calMaskArea(image,idx):mask cv2.inRange(image, idx, idx)contours, hierarchy cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)for contour in contours:area cv2.contourArea(contour)print("图形的面积为", area) image是…

中国银行模拟器app,用java设计框架,图片网上找的,提供代码,仅供娱乐

回执单生成器的Java程序需要涉及到一些基本的Java编程技能&#xff0c;包括创建类、处理用户输入和格式化输出。下面是一个简单的示例代码&#xff0c;用于生成一个简易的回执单。这个程序将接收用户的输入&#xff0c;然后生成一个格式化的回执单。 请注意&#xff0c;这个示…

查看包是由哪个依赖引入的

问题&#xff1a;在Maven项目中&#xff0c;如何查看某个包是由pom.xml文件的哪个依赖引入的&#xff1f; 示例&#xff1a; mvn dependency:tree -Dverbose -Dincludesjakarta.validation:jakarta.validation-api或者&#xff1a; mvn dependency:tree -Dincludesvelocity:…

【python自动化】Playwright基础教程(十)元素拖拽元素坐标获取网页源码元素内文本

【python自动化】Playwright基础教程&#xff08;十&#xff09;元素拖拽&元素坐标&获取网页源码&元素内文本 本文目录 文章目录 【python自动化】Playwright基础教程&#xff08;十&#xff09;元素拖拽&元素坐标&获取网页源码&元素内文本playwright…