ROS:话题消息(Message)的定义与使用

news2025/1/13 7:39:13

目录

  • 一、话题模型
  • 二、自定义话题消息
    • 2.1定义msg文件
    • 2.2在package.xml中添加功能包依赖
    • 2.3在CMakeLists.txt中添加编译选项
    • 2.4编译生成C++头文件或Python库
  • 三、创建代码并编译运行(C++)
    • 3.1创建代码
    • 3.2编译
  • 四、运行

一、话题模型

自定义一个消息类型“Person”,并完成发布订阅整个过程,Publisher进行发布个人信息,Subscriber来接收个人信息。Topic定义名为“person_info”
在这里插入图片描述

二、自定义话题消息

2.1定义msg文件

通过自定义msg文件来自定义话题消息。msg文件名为:Person.msg

在learning_topic的功能包根目录下,新建文件夹 msg
在这里插入图片描述
并创建新文件 Person.msg

touch Person.msg

在这里插入图片描述
将下面代码复制进入Person.msg

string name
uint8 sex
uint8 age

uint8 unknown = 0
uint8 male = 1
uint8 female = 2

在这里插入图片描述

msg文件定义使用自己的一套语言规则。
定义好msg数据接口后,就可以根据这个定义用C++或Python编译。

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

添加动态生成程序的功能包依赖。
打开package.xml文件,将下面代码拷到文件指定位置:

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

build_depend为编译依赖,这里依赖的是一个会动态产生message的功能包
exer_depend为执行依赖,这里依赖的是一个动态runtime运行的功能包
在这里插入图片描述

2.3在CMakeLists.txt中添加编译选项

因为在package.xml添加了功能包编译依赖,在CMakeList.txt里的find_package中也要加上对应的部分;
需要将定义的Person.msg作为消息接口,针对它做编译;
需要指明编译这个消息接口需要哪些ROS已有的包;
有了这两个配置才可将定义的msg编译成不同的程序文件
因为在package.xml添加了功能包执行依赖,在CMakeList.txt里的catkin_package中也要加上对应的部分;

find_package( ...... message_generation)

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

catkin_package( ...... message_runtime)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4编译生成C++头文件或Python库

到工作空间根目录,编译:

catkin_make

在这里插入图片描述
编译完成后,可以在 devel/include/learning_topic/ 下找到这个C++的头文件:
在这里插入图片描述

三、创建代码并编译运行(C++)

3.1创建代码

创建一个Publisher代码和一个Subscriber代码,通过程序调用生成的.h。
person_publisher.cpp

/**
 * 该例程将发布/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,队列长度10
    ros::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;
}

person_subscriber.cpp

/**
 * 该例程将订阅/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,注册回调函数personInfoCallback
    ros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);

    // 循环等待回调函数
    ros::spin();

    return 0;
}

在这里插入图片描述

3.2编译

先配置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)

新增了一个添加依赖项,因为代码涉及到动态生成,我们需要将可执行文件与动态生成的程序产生依赖关系。
在这里插入图片描述
编译

cd ~/catkin_ws
catkin_make

四、运行

source在前面已设置自动source。

roscore
rosrun learning_topic person_subscriber

在这里插入图片描述

rosrun learning_topic person_publisher

在这里插入图片描述

可以看到运行成功,subscriber接收到了publisher的person信息:
在这里插入图片描述

注:如果将roscore关掉,可以看到subscriber和publisher依然在接发。roscore代表了ROS Master,它帮助subscriber和publisher建立通信连接,连接建立后退出舞台也没什么问题了。
但是关闭ROS Master就不能管理这个连接了。同时也无法看到rqt_graph。

参考视屏:古月居ROS入门21讲
在这里插入图片描述

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

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

相关文章

python接口测试之测试报告

在本文章中&#xff0c;主要使用jenkins和编写的自动化测试代码&#xff0c;来生成漂亮的测试报告&#xff0c;关于什么是CI这些我就不详细的介绍了&#xff0c;这里我们主要是实战为主。 首先搭建java的环境&#xff0c;这个这里不做介绍。搭建好java的环境后&#xff0c;在h…

Python:Python编程:从入门到实践__超清版:Python标准库:线程

Python线程与安全 实现线程安全有多重方式&#xff0c;常见的包括&#xff1a;锁&#xff0c;条件变量&#xff0c;原子操作&#xff0c;线程本地存储等。 &#x1f49a; 1. 锁2. 条件变量3. 通过 join 阻塞当前线程4. 采用 sleep 来休眠一段时间5. 原子操作5.1 使用 threading…

【I2C】Linux I2C子系统分析

文章目录 一、I2C体系架构二、主要的结构体1. i2c_adapter2. i2c_algorithm3. i2c_driver4. i2c_client4.1 方式一&#xff1a;通过I2C bus number静态方式来创建4.2 方式二&#xff1a;通过Device Tree来创建4.3 方式三&#xff1a;直接通过i2c_new_device来创建4.3 方式四&am…

openEuler22.03制作openstack平台使用的镜像

系列文章目录 第一章 openEuler22.03制作openstack平台使用的镜像 文章目录 系列文章目录前言一、virt-manager上的准备工作1、网卡类型切换为virtio2、IDE驱动设置成Virtio3、Display设置成vnc3、虚拟机系统分区 二、安装普通工具包三、安装云化工具包1、安装工具包2、修改配…

数字化转型,企业为什么要转型?如何转型?

数字化转型是利用数字化技术&#xff08;例如云计算、大数据、人工智能、物联网、区块链等&#xff09;和能力来驱动组织商业模式创新和商业生态系统重构的途径和方法即是数字化转型。其目的是实现企业业务的转型、创新、增长。 核心强调了两点&#xff0c;其一是数字化技术的应…

每日一练 | 华为认证真题练习Day51

1、如下图所示&#xff0c;IPSec传输模式中AH的头部应该插入到以下哪个位置&#xff1f; A. 1 B. 2 C. 3 D. 4 2、以下哪种远程登录方式最安全&#xff1f; A. Telnet B. Stelnet v100 C. Stelnet v2 D. Stelnet v1 3、以下业务模块的ACL默认动作为permit的是&#xff1…

玩转 ChatGPT,看这条就够了,Prompt 最全中文合集

Prompt 最全中文合集 玩转 ChatGPT&#xff0c;看这条就够了&#xff01; &#x1f680; 简化流程&#xff1a;ChatGPT Shortcut 提供了快捷指令表&#xff0c;可以快速筛选和搜索适用于不同场景的提示词&#xff0c;帮助用户简化使用流程。 &#x1f4bb; 提高生产力&#…

CSDN打出各种数学符号和数学公式

目录 1、基本四则运算2、指数对数3、根号、省略号、向量4、大&#xff08;小&#xff09;于等于号5、特殊符号、希腊字母符号6、累加累乘7、矩阵8、更改公式中的颜色 我们在用CSDN打出各种数学符号和数学公式时&#xff0c;需要学习一些关于LaTex的语法&#xff0c;在此做一个记…

java数组学习

一、数组的概述 1.数组的理解:数组(Array),是多个相同类型数据按一定顺序排列的集合&#xff0c; 并使用一个名字命名&#xff0c;并通过编号的方式对这些数据进行统一管理。 2.数组相关的概念: >数组名 >元素 >角标、下标、索引 >数组的长度&#xff1a;元素…

联通云数据库CUDB:基于openGauss打造新一代自主创新云原生数据库

总体概述 联通云彰显央企担当&#xff0c;围绕国家对信息技术基础软件的政策要求&#xff0c;开展数据库自主研发。在openGauss开源社区版软件基础上&#xff0c;聚焦政企市场&#xff0c;坚持内核创新&#xff0c;完善工具生态&#xff0c;基于海量云存储能力、存算分离架构…

React中的懒加载以及在Ice中实践

您好&#xff0c;如果喜欢我的文章&#xff0c;可以关注我的公众号「量子前端」&#xff0c;将不定期关注推送前端好文~ 前言 对于页面性能优化&#xff0c;组件懒加载是个比较不错的方案&#xff0c;并且在整个项目打包后&#xff0c;如果未做代码分割&#xff0c;构建出的文…

代理ip的优势、用途及注意事项

随着互联网的高速发展&#xff0c;代理ip的名气和地位也随着水涨船高。那么是什么让它们被我们所知悉的呢&#xff1f;下面我们就代理ip的优势、用途和注意事项来分析一下它为什么能迎合着互联网的发展而壮大自己的。 一、优势 每一个脱颖而出的产品必然有它的优势&#xff0c;…

Axure教程—菜单(中继器)

本文将教大家如何用AXURE中的中继器制作菜单&#xff08;自动折叠其他菜单&#xff09; 一、效果介绍 如图&#xff1a; 预览地址&#xff1a;https://iuek50.axshare.com 下载地址&#xff1a;https://download.csdn.net/download/weixin_43516258/87854640?spm1001.2014.30…

知识图谱简介

什么是知识图谱&#xff1f; 参考&#xff1a;知识图谱1、知识图谱2 本质上&#xff0c;知识图谱主要目标是用来描述真实世界中存在的各种实体和概念&#xff0c;以及他们之间的关系&#xff0c;因此可以认为是一种语义网络。 主要作用&#xff1a;通过数据&#xff0c;建立图…

智能自动化助力业务升级:探究低代码开发和业务流程自动化

当我们开始探索业务流程自动化&#xff08;BPA&#xff09;时&#xff0c;就证明我们已经真正进入到企业数字化转型的核心领域了——企业越来越关注如何通过创新技术来提高效率、降低成本并实现业务流程的自动化。在这个背景下&#xff0c;低代码开发平台和业务流程自动化成为了…

vue 滚动加载

在 Vue中&#xff0c;如果一个组件是一个 button&#xff0c;那就可以直接调用 input &#xff08;&#xff09;方法&#xff0c;将组件的 button放入到v-ui中。 然而在v-ui中&#xff0c;一个组件可能不止一个 button&#xff0c;而这些 button还需要从浏览器加载到 DOM树中。…

一个投喂ChatGPT大内容的小技巧

大家好&#xff0c;我是五竹。心血来潮整理了一份手册&#xff1a;《ChatGPT学习指南》并且将为小白们持续更新和GPT相关的资源和教程&#xff0c;专注于打造一部最好的GPT入门指南&#xff0c;欢迎大家转发、收藏、点赞支持&#xff01;谨防失联&#xff01; 至今还有很多人都…

渗透测试适合小白学习吗会让人感觉到无聊吗?

渗透测试是一项复杂的技能&#xff0c;需要具备扎实的计算机知识&#xff0c;对网络和系统安全有深入的理解和认识。对于初学者来说&#xff0c;建议先学习计算机网络、操作系统、编程语言等相关基础知识&#xff0c;了解渗透测试的概念、流程和常用工具。同时&#xff0c;需要…

HMR API及其原理

很久之前&#xff0c;遇到一个面试题&#xff1a;【在代码变更之后&#xff0c;如何实时看到更新后的页面效果呢&#xff1f;】 在传统的方案中&#xff0c;我们可以通过 live reload 也就是自动刷新页面的方式来解决的&#xff0c;不过随着前端工程的日益庞大&#xff0c;开发…

CSS3+HTML5

1、HTML5 2、HTML5标签 链接标签 <a href"https://www.baidu.com">打开百度&#xff0c;你就知道&#xff01;</a> 链接的属性与作用 属性1&#xff1a;href 作用&#xff1a;用于指定链接目标的url地址&#xff0c;当为标签应用href属性时…