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

news/2024/7/23 23:21:24 标签: 机器人, 自动驾驶, 人工智能, ROS

一、实验任务

任务要求如下:使用 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.niftyadmin.cn/n/5177040.html

相关文章

Apache Airflow (五) :DAG调度触发时间

&#x1f3e1; 个人主页&#xff1a;IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 &#x1f6a9; 私聊博主&#xff1a;加入大数据技术讨论群聊&#xff0c;获取更多大数据资料。 &#x1f514; 博主个人B栈地址&#xff1a;豹哥教你大数据的个人空间-豹…

Centos8上部署Zabbix5.0

1.关闭Selinux及防火墙&#xff0c;避免Web页面无法访问。 setenforce 0 vim /etc/selinux/config 修改“SELINUX”等号后的内容为disabled SELINUXdisabled\\关闭并关闭开机自启 systemctl stop firewalld systemctl disable firewalld 2.配置Centos8本地yum源。 mkdir /mn…

【Linux】你是否还在为安装虚拟机而烦恼?这篇博客将告诉你如何快速搭建Linux环境

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…

Js面试题:说一下js的模块化?

作用&#xff1a; 一个模块就是实现某个特定功能的文件&#xff0c;在文件中定义的变量、函数、类都是私有的&#xff0c;对其他文件不可见。 为了解决引入多个js文件时&#xff0c;出现 命名冲突、污染作用域 等问题 AMD&#xff1a; 浏览器端模块解决方案 AMD即是“异步模块定…

5G:HARQ协议

简介 5G中有两种重传机制&#xff1a;MAC层的HARQ机制&#xff0c;以及RLC层的ARQ&#xff08;只针对AM&#xff08;aknowledgement mode确认模式&#xff09;数据传输&#xff09;机制。 HARQ HARQ&#xff08;HybridAutomatic Repeat reQuest混合自动重传请求&#xff09;&a…

2023测试工程师必看系列:用JMeter+ANT进行接口自动化测试,并生成HTML测试报告

【文章末尾给大家留下了大量的福利】 小伙伴们&#xff0c;用python做接口自动化是不是写代码比较繁琐&#xff0c;而且没有python代码基础的小伙伴根本无从下手对吧&#xff01;今天我们来学习一下如何使用JMeter工具实现接口自动化测试。 01 安装 1、安装JDK&#xff0c;…

ArrayList 扩容 讲解 小白易懂版本

ArrayList 扩容 讲解 小白易懂版本 注意本文使用的是 java 11 首先我们假设有一个空数组&#xff0c;现在要开始添加第一个元素 public boolean add(E e) {//modCount&#xff1a; 这个就是记录修改的次数&#xff0c;比如我们增加或删除元素会对数组的结构造成修改&#xf…

A2Attention模型介绍

A2Attention的核心思想是首先将整个空间的关键特征收集到一个紧凑的集合中&#xff0c;然后自适应地将其分布到每个位置&#xff0c;这样后续的卷积层即使没有很大的接收域也可以感知整个空间的特征。第一级的注意力集中操作有选择地从整个空间中收集关键特征&#xff0c;而第二…