ROS话题(Topic)通信:自定义msg - 例程与讲解
在 ROS 通信协议中,数据是以约定好的结构传输的,即数据类型,比如Topic使用的msg,Service使用的srv,ROS 中的 std_msgs 封装了一些原生的数据类型,比如:Bool、Char、Float32、Int64、String等,但这些类型结构简单,常常不能满足我们的需要,这时我们可以使用自定义的消息类型。
比如我们创建一个自定义消息,定义一个机器人的ID,位置(x, y)。
一、创建RobotPose.msg
我们仍然使用前文创建的 topic_hello_world 功能包,结构如下:

在src的同级目录创建 msg 目录,在msg目录创建 RobotPose.msg 文件,内容如下:
string id
float64 x
float64 y
float64 angle
二、配置编译文件
需要对 CMakeLists.txt 作以下修改:
2.1 添加message_generation功能包
message_generation功能包,在构建时根据msg和srv生成消息和服务的接口文件(比如C++头文件和Python包),以便在 ROS 节点中使用。
find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsmessage_generation
)
注意这里需要同时在package.xml中添加以下内容:
<build_depend>message_generation</build_depend>
2.2 添加msg文件
添加自定义msg,该函数依赖message_generation功能包。
add_message_files(FILESRobotPose.msg
)
2.3 配置依赖并生成接口文件
添加处理msg或srv所需要的依赖,并生成接口文件,该函数依赖message_generation功能包。
generate_messages(DEPENDENCIESstd_msgs
)
2.4 添加message_runtime依赖
message_runtime 用于在运行时提供消息的序列化和反序列化支持。
这里注意,有时可能会看到没有显式添加 message_runtime 也能正常运行,这通常是因为其他依赖项(例如roscpp 或 std_msgs)可能已经隐含地包含了 message_runtime。在这种情况下,构建系统已经处理了消息生成的任务。
然而,为了确保你的软件包在所有情况下都能正常工作,最好显示添加 message_runtime 作为你的软件包的依赖项。这样可以确保你的消息定义在构建和运行时得到正确处理。
需要对 CMakeLists.txt 作以下修改:
catkin_package(CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
)
同时在package.xml中添加以下内容:
<exec_depend>message_runtime</exec_depend>
节外生枝的小知识:
catkin_package是在ROS软件包的CMakeLists.txt文件中用于配置Catkin软件包的一条命令。它主要用于描述ROS软件包的元信息,并在构建系统中定义软件包的依赖关系。以下是catkin_package的一般用途:
软件包元信息配置:
catkin_package允许你指定软件包的元信息,例如软件包的名称、版本、作者、描述等。这些信息将用于标识和描述你的ROS软件包。cmakeCopy codecatkin_package(NAME your_package_nameVERSION 0.1.0DESCRIPTION "Your package description"AUTHOR "Your Name")设置软件包的依赖项:
catkin_package允许你指定你的软件包依赖于其他ROS软件包的哪些部分。这些依赖项将在构建和运行时被解析和满足。cmakeCopy codecatkin_package(...CATKIN_DEPENDS roscpp std_msgs message_runtime)导出软件包的目标: 通过
${PROJECT_NAME}_EXPORTED_TARGETS这样的参数,你可以导出软件包的目标,以便其他软件包能够正确地依赖你的软件包,并包含所有必要的目标。cmakeCopy codecatkin_package(...EXPORTED_TARGETS ${PROJECT_NAME}_EXPORTED_TARGETS)总体而言,
catkin_package提供了一个中心化的地方,用于指定ROS软件包的基本信息和配置,以便构建系统和其他软件包能够正确地使用和依赖你的软件包。在ROS中,它是配置软件包最重要的命令之一。
三、实现发布者与订阅者(C++版)
3.1 源码
在创建的 topic_hello_world 包路径的 src 目录中创建 user_msg_pub.cpp 以实现发布者,编辑内容如下:
#include <ros/ros.h>
#include "topic_hello_world/RobotPose.h"int main(int argc, char **argv)
{ros::init(argc, argv, "user_msg_pub");ros::NodeHandle nh;ros::Publisher pose_pub = nh.advertise<topic_hello_world::RobotPose>("/robot_pose", 10);topic_hello_world::RobotPose pose;pose.id = "vbot";pose.x = 23.6;pose.y = 12.8;pose.angle = 90.0;while(ros::ok()){pose_pub.publish(pose);ROS_INFO("Pub robot: %s, pose(%lf, %lf, %lf)", pose.id.c_str(), pose.x, pose.y, pose.angle);ros::Duration(1).sleep();ros::spinOnce();}return 0;
}
创建 user_msg_sub.cpp 以实现订阅者,编辑内容如下:
#include <ros/ros.h>
#include "topic_hello_world/RobotPose.h"void robotPoseCallback(const topic_hello_world::RobotPose::ConstPtr &pose)
{ROS_INFO("Sub robot: %s, pose(%lf, %lf, %lf)", pose->id.c_str(), pose->x, pose->y, pose->angle);
}int main(int argc, char **argv)
{ros::init(argc, argv, "user_msg_sub");ros::NodeHandle nh;ros::Subscriber pose_sub = nh.subscribe<topic_hello_world::RobotPose>("/robot_pose", 10, robotPoseCallback);ros::spin();return 0;
}
修改 CMakeLists.txt ,只需添加如下内容:
add_executable(${PROJECT_NAME}_user_msg_pub src/user_msg_pub.cpp)
add_executable(${PROJECT_NAME}_user_msg_sub src/user_msg_sub.cpp)target_link_libraries(${PROJECT_NAME}_user_msg_pub${catkin_LIBRARIES}
)target_link_libraries(${PROJECT_NAME}_user_msg_sub${catkin_LIBRARIES}
)
3.2 编译运行
进入工作空间执行 catkin_make 命令编译工程,你可能会遇到如下错误:

这是因为上文提到的message_generation功能包,在它编译自定义msg生成对应接口文件之前,编译了c++源文件,但这时头文件RobotPose.h还没有生成,所以报错了。
到这里你有没有发现,如果各功能包间有依赖关系,他们的编译是有先后顺序的,那我们怎么控制这个先后顺序呢?答案是:不需要。哈哈,CMake已经替我们做了,我们只需告诉它哪个模块需要什么依赖,CMake内部会自动分析项目中的依赖关系,并根据这些依赖关系计算一个拓扑排序。然后,CMake会按照这个顺序处理各个功能包,以确保在构建过程中满足所有依赖关系。
我们可以在 CMakeLists.txt中使用 add_dependencies() 来添加这个依赖关系,语法如下:
add_dependencies(target_name dependency_target_name)
其中,target_name 是要添加依赖关系的目标名称,dependency_target_name 是要添加的依赖目标名称。
例如,如果你有一个名为 my_node 的目标,你想要添加一个名为 my_dependency 的库作为其依赖项,可以使用以下命令:
add_dependencies(my_node my_dependency)
所以,为解决上述报错,我们在 topic_hello_world/CMakeLists.txt中添加如下内容:
# 注意他们要放在add_executable之后,即先告诉CMake是哪个节点,再告诉CMake它需要什么依赖
add_dependencies(${PROJECT_NAME}_user_msg_pub ${PROJECT_NAME}_generate_messages_cpp)
add_dependencies(${PROJECT_NAME}_user_msg_sub ${PROJECT_NAME}_generate_messages_cpp)
其中,第一项是我们生成的节点,第二项 ${PROJECT_NAME}_generate_messages_cpp 是一个用于生成消息类型的C++文件的宏,它的作用是根据 .msg 和 .srv 文件生成对应的 .h 和 .cpp 文件。
3.3 节外生枝的小知识:
在ROS软件包的构建过程中,除了
${PROJECT_NAME}_generate_messages_cpp,还有一些其他与消息生成和编译相关的宏。这些宏通常都是与 Catkin 工具链和 ROS 构建系统的一部分。以下是一些常见的与消息生成相关的宏:
${PROJECT_NAME}_generate_messages: 这个宏表示生成所有与消息相关的任务。通常,在调用catkin_package(...)时,CATKIN_DEPENDS部分会包含${PROJECT_NAME}_generate_messages,以确保在构建软件包时执行消息生成任务。catkin_package(CATKIN_DEPENDS roscpp std_msgs message_runtime${PROJECT_NAME}_generate_messages )
${PROJECT_NAME}_generate_messages_py: 类似于${PROJECT_NAME}_generate_messages_cpp,这个宏用于指定生成与消息相关的Python代码的路径。当你的ROS软件包包含使用Python编写的节点或服务时,可能会用到这个宏。
${PROJECT_NAME}_EXPORTED_TARGETS: 这个宏用于导出所有与软件包相关的目标,包括消息生成任务。通常,在调用catkin_package(...)时,EXPORTED_TARGETS部分会包含${PROJECT_NAME}_EXPORTED_TARGETS,以确保其他软件包能够正确地依赖你的软件包,并包括所有必要的目标。cmakeCopy codecatkin_package(...INCLUDE_DIRS includeLIBRARIES ${PROJECT_NAME}_libraryCATKIN_DEPENDS roscpp std_msgs message_runtimeDEPENDS system_libEXPORTED_TARGETS ${PROJECT_NAME}_EXPORTED_TARGETS )请注意,具体的宏可能会受到ROS版本、Catkin工具链版本和软件包的配置选项的影响。上述宏的名称中的
${PROJECT_NAME}部分会根据你的软件包的名称而变化。
3.4 编译成功后,使用如下命令依次启动发布者和订阅者。
1. 启动ros master
roscore
2. 启动发布者
rosrun topic_hello_world topic_hello_world_user_msg_pub
3. 启动订阅者
rosrun topic_hello_world topic_hello_world_user_msg_sub
结果如下:

目前为止,Topic Hello World 的自定义msg已经成功了。
四、实现发布者与订阅者(Python版)
4.1 源码
在 topic_hello_world 包路径下的 scripts 目录中,创建 user_msg_pub.py 以实现发布者,编辑内容如下:
#! /usr/bin pythonimport rospy
from topic_hello_world.msg import RobotPosedef main():rospy.init_node("user_msg_pub")pub = rospy.Publisher("/robot_pose", RobotPose, queue_size=10)msg = RobotPose()msg.id = "vbot"msg.x = 52.1msg.y = 12.6msg.angle = 180.0while not rospy.is_shutdown():pub.publish(msg)rospy.loginfo("Pub robot: {}, pose({}, {}, {})".format(msg.id, msg.x, msg.y, msg.angle))rospy.sleep(1)if __name__ == "__main__":main()
在scrips中创建 user_msg_sub.py 以实现订阅者,编辑内容如下:
#! /usr/bin pythonimport rospy
from topic_hello_world.msg import RobotPosedef robotPoseCallback(msg):rospy.loginfo("Sub robot: {}, pose({}, {}, {})".format(msg.id, msg.x, msg.y, msg.angle))def main():rospy.init_node("user_msg_sub")rospy.Subscriber("/robot_pose", RobotPose, robotPoseCallback, queue_size=10)rospy.spin()if __name__ == "__main__":main()
修改 CMakeLists.txt ,只需添加如下内容:
catkin_install_python(PROGRAMSscripts/user_msg_pub.pyscripts/user_msg_sub.pyDESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
4.2 编译运行
进入工作空间执行 catkin_make 命令编译工程,编译成功后,使用如下命令依次启动发布者和订阅者。
1. 启动ros master(如果已启动,无需再启动)
roscore
2. 启动发布者
rosrun topic_hello_world user_msg_pub.py
3. 启动订阅者
rosrun topic_hello_world user_msg_sub.py
结果如下:

相关文章:
ROS话题(Topic)通信:自定义msg - 例程与讲解
在 ROS 通信协议中,数据是以约定好的结构传输的,即数据类型,比如Topic使用的msg,Service使用的srv,ROS 中的 std_msgs 封装了一些原生的数据类型,比如:Bool、Char、Float32、Int64、String等&am…...
【Vue配置项】 computed计算属性 | watch侦听属性
目录 前言 computed计算属性 什么是计算属性? Vue的原有属性是什么? 得到的全新的属性是什么? 计算属性怎么用? 计算属性的作用是什么? 为什么说代码执行率高了? computed计算属性中的this指向 co…...
linux 查看命令使用说明
查看命令的使用说明的命令有三种,但并不是每个命令都可以使用这三种命令去查看某个命令的使用说明,如果一种不行就使用另外一种试一试。 1.whatis 命令 概括命令的作用 2.命令 --help 命令的使用格式和选项的作用 3.man 命令 命令的作用和选项的详细…...
ceph修复pg inconsistent( scrub errors)
异常情况 1、收到异常情况如下: OSD_SCRUB_ERRORS 12 scrub errors PG_DAMAGED Possible data damage: 1 pg inconsistentpg 6.d is activeremappedinconsistentbackfill_wait, acting [5,7,4]2、查看详细信息 登录后复制 #ceph health detail HEALTH_ERR 12 scrub errors…...
【论文精读】VOYAGER: An Open-Ended Embodied Agent with Large Language Models
Understanding LSTM Networks 前言Abstract1 Introduction2 Method2.1 Automatic Curriculum2.2 Skill Library2.3 Iterative Prompting Mechanism 3 Experiments3.1 Experimental Setup3.2 Baselines3.3 Evaluation Results3.4 Ablation Studies3.5 Multimodal Feedback from …...
Linux安装DMETL5与卸载
Linux安装DMETL5与卸载 环境介绍1 DM8数据库配置1.1 DM8数据库安装1.2 初始化达梦数据库1.3 创建DMETL使用的数据库用户 2 配置DMETL52.1 解压DMETL5安装包2.2 安装调度器2.3 安装执行器2.4 安装管理器2.5 启动dmetl5 调度器2.6 启动dmetl5 执行器2.7 启动dmetl5 管理器2.8 查看…...
Office Word 中的宏
Office Word 中的宏 简介宏的使用将自定义创建的宏放入文档标题栏中的“自定义快速访问工具栏”插入指定格式、内容的字符选中word中的指定文字查找word中的指定文字A,并替换为指定文字B插入文本框并向内插入文字word 表格中的宏操作遍历表格中的所有内容批量设置表…...
qt中d指针
在Qt中,d指针是一种常见的设计模式,也称为"PIMPL"(Private Implementation)或者"Opaque Pointer"。它主要用于隐藏类的实现细节,提供了一种封装和隔离的方式,以便在不影响公共接口的情…...
交易者最看重什么?anzo Capital这点最重要!
交易者最看重什么?有人会说技术,有人会说交易策略,有人会说盈利,但anzo Capital认为Vishal 最看重的应该是眼睛吧! 29岁的Vishal Agraval在9年前因某种原因失去了视力,然而,他的失明并未能阻…...
window 搭建 MQTT 服务器并使用
1. 下载 安装 mosquitto 下载地址: http://mosquitto.org/files/binary/ win 使用 win32 看自己电脑下载相应版本: 一直安装: 记住安装路径:C:\Program Files\mosquitto 修改配置文件: allow_anonymous false 设置…...
Prometheus+Ansible+Consul实现服务发现
一、简介 1、Consul简介 Consul 是基于 GO 语言开发的开源工具,主要面向分布式,服务化的系统提供服务注册、服务发现和配置管理的功能。Consul 提供服务注册/发现、健康检查、Key/Value存储、多数据中心和分布式一致性保证等功能。 在没有使用 consul 服…...
【原创】java+swing+mysql校园活动管理系统设计与实现
前言: 本文介绍了一个校园活动管理系统的设计与实现。该系统基于JavaSwing技术,采用C/S架构,使用Java语言开发,以MySQL作为数据库。系统实现了活动发布、活动报名、活动列表查看等功能,方便了校园活动的发布和管理&am…...
vscode中vue项目引入的组件的颜色没区分解决办法
vscode中vue项目引入的组件的颜色没区分解决办法 图中引入组件和其他标签颜色一样没有区分,让开发者不易区分,很蓝瘦 这个就很直观,解决办法就是你当前的vscode版本不对,你得去找找其他版本,我的解决办法就是去官网历…...
uniapp: 实现pdf预览功能
目录 第一章 实现效果 第二章 了解并解决需求 2.1 了解需求 2.2 解决需求 2.2.1 方法一 2.2.2 方法二 第三章 资源下载 第一章 实现效果 第二章 了解并解决需求 2.1 了解需求 前端需要利用后端传的pdf临时路径实现H5端以及app端的pdf预览首先我们别像pc端一样&#…...
【Pytorch笔记】7.torch.nn (Convolution Layers)
我们常用torch.nn来封装网络,torch.nn为我们封装好了很多神经网络中不同的层,如卷积层、池化层、归一化层等。我们会把这些层像是串成一个牛肉串一样串起来,形成网络。 先从最简单的,都有哪些层开始学起。 Convolution Layers -…...
MySQL内部组件与日志详解
MySQL的内部组件结构 MySQL 可以分为 Server 层和存储引擎层两部分。 Server 层主要包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等)&am…...
【LeetCode】94. 二叉树的中序遍历
94. 二叉树的中序遍历 难度:简单 题目 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 示例 1: 输入:root [1,null,2,3] 输出:[1,3,2]示例 2: 输入:root [] 输出:[]示…...
IP-guard WebServer 命令执行漏洞复现
简介 IP-guard是一款终端安全管理软件,旨在帮助企业保护终端设备安全、数据安全、管理网络使用和简化IT系统管理。在旧版本申请审批的文件预览功能用到了一个开源的插件 flexpaper,使用的这个插件版本存在远程命令执行漏洞,攻击者可利用该漏…...
TensorFlow案例学习:图片风格迁移
准备 官方教程: 任意风格的快速风格转换 模型下载地址: https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2 学习 加载要处理的内容图片和风格图片 # 用于将图像裁剪为方形def crop_center(image):# 图片原始形状shape image…...
解密网络世界的秘密——Wireshark Mac/Win中文版网络抓包工具
在当今数字化时代,网络已经成为了人们生活和工作中不可或缺的一部分。然而,对于网络安全和性能的监控和分析却是一项重要而又复杂的任务。为了帮助用户更好地理解和解决网络中的问题,Wireshark作为一款强大的网络抓包工具,应运而生…...
HunyuanVideo-Foley与Java后端集成:构建高并发音效生成服务
HunyuanVideo-Foley与Java后端集成:构建高并发音效生成服务 1. 场景需求与技术挑战 在线教育平台面临一个共同痛点:海量视频课程需要配乐,但人工配乐成本高、效率低。一个中等规模的平台每月新增课程可能达到上万节,传统音乐制作…...
CCF-CSP 39-2 水印检查(watermark)【C++】
题目 https://sim.csp.thusaac.com/contest/39/problem/1https://sim.csp.thusaac.com/contest/39/problem/1 思路参考: 80分 暴力求解,遍历所有可能的k,检验是否满足条件,可得80分 时间复杂度:O(L*n^2)࿰…...
N_m3u8DL-RE流媒体下载器:多协议解析技术突破与下载效率提升
N_m3u8DL-RE流媒体下载器:多协议解析技术突破与下载效率提升 【免费下载链接】N_m3u8DL-RE 跨平台、现代且功能强大的流媒体下载器,支持MPD/M3U8/ISM格式。支持英语、简体中文和繁体中文。 项目地址: https://gitcode.com/GitHub_Trending/nm3/N_m3u8D…...
5步掌握Loop:让Mac窗口管理效率提升10倍的免费开源方案
5步掌握Loop:让Mac窗口管理效率提升10倍的免费开源方案 【免费下载链接】Loop MacOS窗口管理 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop 在数字工作环境中,窗口管理已成为影响效率的隐形瓶颈。Mac用户每天平均需要执行200次窗口操作…...
突破设备边界:开源串流解决方案Sunshine革新跨设备游戏共享体验
突破设备边界:开源串流解决方案Sunshine革新跨设备游戏共享体验 【免费下载链接】Sunshine Sunshine: Sunshine是一个自托管的游戏流媒体服务器,支持通过Moonlight在各种设备上进行低延迟的游戏串流。 项目地址: https://gitcode.com/GitHub_Trending/…...
3分钟搭建你的CS比赛分析系统:CS Demo Manager终极指南 [特殊字符]
3分钟搭建你的CS比赛分析系统:CS Demo Manager终极指南 🎮 【免费下载链接】cs-demo-manager Companion application for your Counter-Strike demos. 项目地址: https://gitcode.com/gh_mirrors/cs/cs-demo-manager 你是否曾经打完一场精彩的CS比…...
SDMatte效果深度评测:复杂发丝与透明物体的抠图表现
SDMatte效果深度评测:复杂发丝与透明物体的抠图表现 1. 开篇:当AI遇到抠图难题 抠图技术发展了几十年,但遇到复杂发丝和透明物体时,传统方法往往束手无策。直到AI技术的介入,这个老大难问题才有了突破性进展。SDMatt…...
微信聊天记录永久保存:WeChatExporter开源工具全流程指南
微信聊天记录永久保存:WeChatExporter开源工具全流程指南 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 问题:数据丢失的三重警示 2023年某科技…...
通义千问3-Reranker-0.6B实战应用:智能客服问答排序系统搭建
通义千问3-Reranker-0.6B实战应用:智能客服问答排序系统搭建 1. 智能客服问答排序系统概述 在智能客服系统中,如何从海量知识库中快速找到最匹配用户问题的答案,是提升用户体验的关键。传统基于关键词匹配的方法往往难以理解用户真实意图&a…...
macOS效率革命:3个全局快捷键让Finder目录操作提速300%
macOS效率革命:3个全局快捷键让Finder目录操作提速300% 【免费下载链接】OpenInTerminal ✨ Finder Toolbar app for macOS to open the current directory in Terminal, iTerm, Hyper or Alacritty. 项目地址: https://gitcode.com/gh_mirrors/op/OpenInTerminal…...
