【古月居《ros入门21讲》学习笔记】10_话题消息的定义与使用

目录

说明:

1. 话题模型

2. 实现过程(C++)

自定义话题消息

Person.msg文件内容

Person.msg文件内容说明

编译配置

在package.xml文件中添加功能包依赖

在CMakeLists.txt中添加编译选项

编译生成语言相关文件

创建发布者代码(C++)

创建订阅者代码(C++)

配置代码编译规则

配置内容说明

编译并运行

编译

运行

扩展

3. 实现过程(Python)

创建发布者代码(Python)

创建订阅者代码(Python)

运行


说明:

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

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


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

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

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


1. 话题模型

image-20230525103444411

2. 实现过程(C++)

自定义话题消息

cd ~/catkin_ws/src/learning_topic
mkdir msg
cd msg
touch Person.msg

Person.msg文件内容
string name // 名字
uint8 sex   // 性别:分为3种,男、女、未知,下面以012宏定义做表示判断
uint8 age   // 年龄
​
uint8 unknown = 0 
uint8 male = 1    
uint8 female = 2
Person.msg文件内容说明

Person.msg文件里定义的内容跟语言无关的,这既不是c++,也不是python,这里面的string uint8表示在不同的程序里面扩展成对应该种程序的表示方法,可以类比单片机里无符号整型变量类型unsigned int来理解,缩写就是uint。

cd ~/catkin_ws/src/learning_topic
mkdir msg

注意:新建的这个文件夹名字不能随便命名,只能叫msg,否则编译会报错,CMakeList文件中有说明,要放在名叫msg文件夹中。

image-20230525105802095

cd msg
touch Person.msg

(注意:这里的文件名首字母P一定要大写!否则后面会报错)

打开Person.msg文件,把定义的内容复制到文件里并保存,

(注意:输入的内容中,注释不要,空格不能用tab键缩进,否则后面也会报错)

image-20230525143629177

编译配置

路径:~/catkin_ws/src/learning_topic

在package.xml文件中添加功能包依赖
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

build_depend:编译依赖

exec_depend:运行依赖

image-20230525134244239

在CMakeLists.txt中添加编译选项
find_package(......message_generation)

image-20230525142005844

add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std_msgs)

add_message_files: 把我们定义的Person.msg文件,做为我们定义的接口;

generate_messages:编译Person.msg文件的时候需要用到一些依赖于ROS已有的库或包,

我们这里用到的依赖是std_msgs,我们前面看到的string,uint8都是在std_msgs里面做定义的

image-20230525142153143

catkin_package(......message_runtime)

image-20230525142706463

编译生成语言相关文件
cd ~/catkin_ws
catkin_make

image-20230525144332516

编译成功之后可以在~/catkin_ws/devel/include/learning_topic下看到Person.msg文件编译生成的C++的头文件Person.h

image-20230525145008343

创建发布者代码(C++)

cd ~/catkin_ws/src/learning_topic/src
touch person_publisher.cpp

  • 初始化ROS节点;

  • 向ROS Master注册节点信息,包括发布消息的话题名,话题中的消息类型;

  • 创建消息数据;

  • 按照一定频率循环发布消息,

/*** 该例程将发布/person_info话题,自定义消息类型learning_topic::Person*/#include <ros/ros.h>
#include "learning_topic/Person.h"
​
int main(int argc, char **argv)
{// ROS节点初始化ros::init(argc, argv, "person_publisher");
​// 创建节点句柄ros::NodeHandle n;
​// 创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度10ros::Publisher person_info_pub = n.advertise<learning_topic::Person>("/person_info", 10);
​// 设置循环的频率ros::Rate loop_rate(1);
​int count = 0;while (ros::ok()){// 初始化learning_topic::Person类型的消息learning_topic::Person person_msg;person_msg.name = "Tom";person_msg.age  = 18;person_msg.sex  = learning_topic::Person::male;
​// 发布消息person_info_pub.publish(person_msg);
​ROS_INFO("Publish Person Info: name:%s  age:%d  sex:%d", person_msg.name.c_str(), person_msg.age, person_msg.sex);
​// 按照循环频率延时loop_rate.sleep();}
​return 0;
}

image-20230525152240349

创建订阅者代码(C++)

cd ~/catkin_ws/src/learning_topic/src
touch person_subscriber.cpp

初始化ROS节点;

订阅需要的话题;

循环等待话题消息,接收到消息后进入回调函数;

在回调函数中完成消息处理。

/*** 该例程将订阅/person_info话题,自定义消息类型learning_topic::Person*/#include <ros/ros.h>
#include "learning_topic/Person.h"
​
// 接收到订阅的消息后,会进入消息回调函数
void personInfoCallback(const learning_topic::Person::ConstPtr& msg)
{// 将接收到的消息打印出来ROS_INFO("Subcribe Person Info: name:%s  age:%d  sex:%d", msg->name.c_str(), msg->age, msg->sex);
}
​
int main(int argc, char **argv)
{// 初始化ROS节点ros::init(argc, argv, "person_subscriber");
​// 创建节点句柄ros::NodeHandle n;
​// 创建一个Subscriber,订阅名为/person_info的topic,注册回调函数personInfoCallbackros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);
​// 循环等待回调函数ros::spin();
​return 0;
}

image-20230525154634297

配置代码编译规则

将下面6行内容复制到CMakeLists.txt文件中,

add_executable(person_publisher src/person_publisher.cpp)
target_link_libraries(person_publisher ${catkin_LIBRARIES})
add_dependencies(person_publisher ${PROJECT_NAME}_generate_messages_cpp)
​
add_executable(person_subscriber src/person_subscriber.cpp)
target_link_libraries(person_subscriber ${catkin_LIBRARIES})
add_dependencies(person_subscriber ${PROJECT_NAME}_generate_messages_cpp)
配置内容说明

add_executable:

将person_publisher.cpp和person_subscriber.cpp代码文件编译成person_publisher与person_subscriber可执行文件;

target_link_libraries:

把编译生成的可执行文件person_publisher与person_subscriber跟ROS相关的一些库做连接的,比如调用的C++的接口;

add_dependencies:

有一些代码是动态生成的,而可执行文件也需要与动态生成的程序产生依赖关系,所以这个就是用来动态的和刚才生成的头文件Person.h产生依赖关系的;

复制到CMakeLists.txt文件中的位置如下:

image-20230525155453179

编译并运行

编译
cd ~/catkin_ws
catkin_make

image-20230525160916698

运行
roscore
rosrun learning_topic person_subscriber
rosrun learning_topic person_publisher

第一步:打开ROS Master;

第二步:运行订阅者person_subscriber,让其先等待着发布者发布消息数据,

第三步:运行发布者person_publisher,让其发布消息数据,

image-20230525162541324

扩展

如果把启动ROS_Master的roscore关掉,发布者与订阅者依然在发布和接收消息数据,此时ROS_Master的结束对两者并无影响,

因为ROS_Master是帮助节点建立连接的,一旦连接创立,ROS_Master在这里的作用就不再存在了,但关掉ROS_Master后,

如果有第三个节点要加入进来的话,是无法再建立连接的。

image-20230526155216489

3. 实现过程(Python)

创建发布者代码(Python)

cd ~/catkin_ws/src/learning_topic/scripts
touch person_publisher.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程将发布/person_info话题,自定义消息类型learning_topic::Person
​
import rospy
from learning_topic.msg import Person
​
def velocity_publisher():# ROS节点初始化rospy.init_node('person_publisher', anonymous=True)
​# 创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度10person_info_pub = rospy.Publisher('/person_info', Person, queue_size=10)
​#设置循环的频率rate = rospy.Rate(10) 
​while not rospy.is_shutdown():# 初始化learning_topic::Person类型的消息person_msg = Person()person_msg.name = "Tom";person_msg.age  = 18;person_msg.sex  = Person.male;
​# 发布消息person_info_pub.publish(person_msg)rospy.loginfo("Publsh person message[%s, %d, %d]", person_msg.name, person_msg.age, person_msg.sex)
​# 按照循环频率延时rate.sleep()
​
if __name__ == '__main__':try:velocity_publisher()except rospy.ROSInterruptException:pass

image-20230526161126127

创建订阅者代码(Python)

cd ~/catkin_ws/src/learning_topic/scripts
touch person_subscriber.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程将订阅/person_info话题,自定义消息类型learning_topic::Person
​
import rospy
from learning_topic.msg import Person
​
def personInfoCallback(msg):rospy.loginfo("Subcribe Person Info: name:%s  age:%d  sex:%d", msg.name, msg.age, msg.sex)
​
def person_subscriber():# ROS节点初始化rospy.init_node('person_subscriber', anonymous=True)
​# 创建一个Subscriber,订阅名为/person_info的topic,注册回调函数personInfoCallbackrospy.Subscriber("/person_info", Person, personInfoCallback)
​# 循环等待回调函数rospy.spin()
​
if __name__ == '__main__':person_subscriber()

image-20230526162129583

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

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

person_subscriber.py文件操作同上,python文件不需要编译,直接运行即可。

image-20230526162441381

运行

roscore
rosrun learning_topic person_subscriber.py
rosrun learning_topic person_publisher.py

第一步:打开ROS Master;

第二步:运行订阅者person_subscriber.py,让其先等待着发布者发布消息数据,

第三步:运行发布者person_publisher.py,让其发布消息数据,

image-20230526163111027

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

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

相关文章

关于最近Facebook的未经用户同意收集使用个人信息,

最近收到深圳市通信管理局的违法违规APP处置通知大概如下: 并且详细列举了 facebook sdk 在未经用户允许前调用的 TelephonyManager.getNetworkOperatorName(); 方法,获取运营商名称. 解决方法, 首先 在用户没有点击允许隐私条款前 不要调用任何Facebook sdk 方法,比如: Fac…

智慧科研助力科研数据的分析处理

如今&#xff0c;科研领域的发展日新月异&#xff0c;数据量也越来越大。这时&#xff0c;智慧科研可视化技术不仅为科研人员提供了快速高效的数据分析手段&#xff0c;而且为科研工作的推进提供了新的思路和方法。通过可视化手段&#xff0c;我们可以将各种数据、信息、知识以…

助力企业实现更简单的数据库管理,ATOMDB 与 TDengine 完成兼容性互认

为加速数字化转型进程&#xff0c;当下越来越多的企业开始进行新一轮数据架构改造升级。在此过程中&#xff0c;全平台数据库管理客户端提供了一个集中管理和操作数据库的工具&#xff0c;提高了数据库管理的效率和便利性&#xff0c;减少了人工操作的复杂性和错误率&#xff0…

带大家做一个,易上手的家常土豆片

还是先从冰箱里那一块猪瘦肉 搞一点蒜和生姜 切成小块 装进一个碗里 这里一点就够了 一条绿皮辣椒 切片 三个左右干辣椒 随便切两刀 让它小一点就好了 一起装一个碗 一大一小两个土豆切片 猪肉切片 起锅烧油 然后 下肉翻炒 等肉变颜色捞出来 然后放入土豆 和小半碗水 让…

【漏洞复现】万户协同办公平台ezoffice SendFileCheckTemplateEdit.jsp接口存在SQL注入漏洞 附POC

漏洞描述 万户ezOFFICE协同管理平台是一个综合信息基础应用平台。 万户协同办公平台ezoffice SendFileCheckTemplateEdit.jsp接口存在SQL注入漏洞。 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩序,尊重社会公德,不得利用网络从事危害…

HTML-标签之文字排版、图片、链接、音视频

1、标签语法 HTML超文本标记语言——HyperText Markup Language 超文本是链接标记也叫标签&#xff0c;带尖括号的文本 2、HTML基本骨架 HTML基本骨架是网页模板 html&#xff1a;整个网页head&#xff1a;网页头部&#xff0c;存放给浏览器看的代码&#xff0c;例如CSSbody…

抖音本地生活服务商申请入口门槛过高,该怎么办?

近年来&#xff0c;短视频平台的举起让直播带货和本地生活服务行业逐渐兴起&#xff0c;并且以其便捷、高效的特点受到了广大用户的欢迎。很多创业者也加入了本地生活服务商的行列中&#xff0c;但有消息传出&#xff0c;抖音本地生活服务商申请入口可能会关闭&#xff0c;由于…

从0到字节跳动30W年薪,我在测试行业“混”的第5个年头····

一些碎碎念 什么都做了&#xff0c;和什么都没做其实是一样的&#xff0c;走出“瞎忙活”的安乐窝&#xff0c;才是避开弯路的最佳路径。希望我的经历能帮助到有需要的朋友。 在测试行业已经混了5个年头了&#xff0c;以前经常听到开发对我说&#xff0c;天天的点点点有意思没…

Linux系统部署Tale个人博客并发布到公网访问

文章目录 前言1. Tale网站搭建1.1 检查本地环境1.2 部署Tale个人博客系统1.3 启动Tale服务1.4 访问博客地址 2. Linux安装Cpolar内网穿透3. 创建Tale博客公网地址4. 使用公网地址访问Tale 前言 今天给大家带来一款基于 Java 语言的轻量级博客开源项目——Tale&#xff0c;Tale…

博捷芯:半导体芯片切割,一道精细工艺的科技之门

在半导体制造的过程中&#xff0c;芯片切割是一道重要的环节&#xff0c;它不仅决定了芯片的尺寸和形状&#xff0c;还直接影响到芯片的性能和使用效果。随着科技的不断进步&#xff0c;芯片切割技术也在不断发展&#xff0c;成为半导体制造领域中一道精细工艺的科技之门。 芯片…

【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析

文章目录 行为型模式1、模板方法模式&#xff08;1&#xff09;概述&#xff08;2&#xff09;结构&#xff08;3&#xff09;案例实现&#xff08;4&#xff09;优缺点&#xff08;5&#xff09;适用场景&#xff08;6&#xff09;JDK源码解析&#xff08;7&#xff09;模板方…

制造业如何做生产设备管理、分析生产数据?

本文将为大家讲解&#xff1a;1、设备管理的现状与问题&#xff1b;2、设备管理系统功能&#xff1b;3、制造业企业如何做生产设备管理、分析生产数据&#xff1f;4、制造业设备管理的价值。 想要管理好设备&#xff0c;设备档案管理、巡检、报修、保养、分析预警等问题都是必须…

封装进度条onUploadProgress+axios取消请求的上传组件

目录 定时模拟进度条 方法 A.axios B.xhr 取消请求 完整代码 A.自定义上传组件 B.二次封装组件 情况 增加cancelToken不生效&#xff0c;刷新页面 进度条太快->设置浏览器网速 定时模拟进度条 startUpload() {if (!this.file) return;const totalSize this.fil…

NV040C语音芯片:让自助ATM机使用更加安全快捷

近年来&#xff0c;移动支付方式的兴起、银行加强线上化服务、数字人民币项目推进等因素的影响&#xff0c;人们使用ATM机的频率呈现小幅度的下降趋势。然而&#xff0c;自助ATM机并未从我们的视野中消失&#xff0c;它们仍然在金融领域发挥着重要的作用。未来&#xff0c;ATM机…

Wish防关联是什么?Wish要怎样避免违规封店?

四大跨境电商平台之一wish&#xff0c;做跨境电商的很多人可能都听过wish。随着wish不断完善平台制度&#xff0c;对于多账号运营的卖家要求越来越严厉&#xff0c;wish和亚马逊、eBay等其它跨境电商平台一样&#xff0c;不支持一个卖家开设多个账号多家店铺。 但是对于各位卖家…

【力扣:526】优美的排列

状态压缩动态规划 原理如下&#xff1a; 遍历位图可以得到所有组合序列&#xff0c;将这些序列的每一位看作一个数&#xff0c;取序列中1总量的值作为每轮遍历的位&#xff0c;此时对每个这样的位都能和所有数进行匹配&#xff0c;因为一开始就取的是全排列&#xff0c;并且我们…

[Java] 阿里一面~说一下ArrayList 与 LinkedList 区别

文章目录 是否保证线程安全底层数据结构插入和删除是否受元素位置的影响是否支持快速随机访问内存空间占用&#xff1a; 是否保证线程安全 ArrayList 和 LinkedList 都是不同步的&#xff0c;也就是不保证线程安全&#xff1b; 底层数据结构 ● ArrayList 底层使用的是 Obje…

Transformers实战——文本相似度

文章目录 一、改写文本分类1.导入相关包2.加载数据集3.划分数据集4.数据集预处理5.创建模型6.创建评估函数7.创建 TrainingArguments8.创建 Trainer9.模型训练10.模型评估11.模型预测 二、交互/单塔模式1.导入相关包2.加载数据集3.划分数据集4.数据集预处理5.创建模型&#xff…

Anaconda超简单安装教程,超简洁!!!(Windows环境下,亲测有效)

写下这篇文章的动机&#xff0c;是今天在装Anaconda的时候&#xff0c;本来想搜点教程按照教程一步一步安装的&#xff0c;但没想到&#xff0c;所谓“保姆级”教程呀&#xff0c;“最详细”之类的&#xff0c;好复杂。然后一些本应该详细说的反而一笔带过了。所以今天我想把我…

个人成长|普通人要想摆脱贫穷,一定要注意这3点

哈喽呀&#xff0c;你好&#xff0c;我是雷工。 身为普通人&#xff0c;没有背景&#xff0c;没有资源&#xff0c;也没有人脉&#xff0c;在什么都没有的情况下如何才能摆脱贫穷&#xff0c;让生活过得更好。 要想自我蜕变&#xff0c;摆脱贫穷&#xff0c;就必须注意以下3点。…