当前位置: 首页 > news >正文

《ROS1学习笔记5——话题通信最佳实践之自定义消息话题》

文章目录

  • 1、关于话题
    • 1.1、前言
  • 2、自定义消息接口
    • 2.1、新建功能包
    • 2.2、自定义消息接口
      • 2.2.1、 新建msg
      • 2.2.2 、在package.xml添加依赖
      • 2.2.3、修改CMakeLists
    • 2.3、编译
  • 3、编写程序
    • 3.1、发布者
    • 3.2、订阅者
    • 3.3、配置CMakeLists
    • 3.4、编译且运行
      • 3.4.1、编译
      • 3.4.2、运行

1、关于话题

1.1、前言

在前面,我们学习了如何发布消息以及如何订阅消息,但都是基于ros里已经存在了的消息话题——海龟模拟器订阅和发布的话题。

我们可以看看海龟模拟器的相关话题,打开两个终端分别运行下面两句命令

roscore rosrun turtlesim turtlesim_node

在打开一个终端,运行

rostopic list


就会出现与现在正在运行的节点相关的话题:

1、/rosout和/rosout_agg是运行ros就存在的。

2、/turtle1/cmd_vel 是我们在笔记3(发布一个话题)中使用到的消息话题,向该消息话题发布信息能够控制海龟进行运动。
运行

rostopic info/turtle1/cmd_vel

可以看到该消息的相关信息,geometry_msgs/Twist是消息接口,也是我们在笔记3编写发布者代码时添加到头文件。

3、/turtle1/pose是我们在笔记四(订阅一个话题)中用到的话题接口,通过订阅该话题,我们能获取到海龟当前的x、y坐标。

2、自定义消息接口

2.1、新建功能包

在demo_ws/src目录下,新建一个功能包

catkin_create_pkg demo_topic roscpp rospy std_msgs geometry_msgs

message_generation是编译时所需的依赖
message_runtime是运行时所需的依赖

2.2、自定义消息接口

2.2.1、 新建msg

在功能包目录下新建msg文件夹,并新建Preson.msg文件(用驼峰命令法,首字母P必须大写)

string name uint8 sex uint8 age uint8 unkown=0uint8 male=1uint8 femake=0

2.2.2 、在package.xml添加依赖

添加下面两行配置代码:

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

message_genaation是编译依赖
message_runtime是运行依赖

2.2.3、修改CMakeLists

需要更改find_packagecatkin_package

将message_genaration添加进去。

将message_runtime添加进去

1、find_package(catkin REQUIRED COMPONENTS …)
核心作用:声明编译当前包时需要的依赖包

2、catkin_package(…)
核心作用:声明当前包被其他包依赖时,对方需要的信息(包括运行时依赖、头文件路径、库文件等)。其中 CATKIN_DEPENDS 明确指定了运行时依赖(当前包运行时需要的包,以及依赖当前包的其他包在编译 / 运行时也需要的包)。

通俗总结:

  • find_package 是 “我编译时需要什么”(给当前包的编译过程用)。
  • catkin_package 是 “别人用我时需要什么”(给依赖当前包的其他包用,同时也隐含了当前包运行时的需求)。

3、添加一个配置项,用于将自己新建的.msg文件编译成其他的文件

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

如下图位置所示,并且在上面也有相应的注释说明

generate_messages(DEPENDENCIES std_msgs)
触发消息生成过程:ROS 会根据 add_message_files 声明的 .msg 文件,自动生成对应语言(C++、Python 等)的代码(如头文件、类定义),供你的程序调用。

DEPENDENCIES std_msgs
表示当前自定义消息依赖于 std_msgs 包中的基础消息类型,如刚用到的uint8等

2.3、编译

回到功能空间目录下进行编译

catkin_make

编译成功后,可以检查demo_ws/devel/include目录下会生成一个demo_topic文件夹,文件夹下面有一个Person.h
这就是根据刚才的.msg文件生成的c++头文件,主要包括一些类、属性是定义

Person.h内容:

3、编写程序

3.1、发布者

#include<ros/ros.h>#include"demo_topic/Person.h"intmain(intargc,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<demo_topic::Person>("/person_info",10);// 设置循环的频率ros::Rateloop_rate(1);intcount=0;while(ros::ok()){// 初始化learning_topic::Person类型的消息demo_topic::Person person_msg;person_msg.name="Tom";person_msg.age=18;person_msg.sex=demo_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);//这里使用 name.c_str()是因为 ROS INFO函数输出%s时 并不是使用的std::string,所以需要额外从char 转为string// 按照循环频率延时loop_rate.sleep();}return0;}

3.2、订阅者

#include<ros/ros.h>#include"demo_topic/Person.h"// 接收到订阅的消息后,会进入消息回调函数voidpersonInfoCallback(constdemo_topic::Person::ConstPtr&msg){// 将接收到的消息打印出来ROS_INFO("Subcribe Person Info: name:%s age:%d sex:%d",msg->name.c_str(),msg->age,msg->sex);}intmain(intargc,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();return0;}

3.3、配置CMakeLists

add_executable(person_pub src/person_pub.cpp)target_link_libraries(person_pub${catkin_LIBRARIES})add_dependencies(person_pub${PROJECT_NAME}_generate_messages_cpp)add_executable(person_sub src/person_sub.cpp)target_link_libraries(person_sub${catkin_LIBRARIES})add_dependencies(person_sub${PROJECT_NAME}_generate_messages_cpp)

3.4、编译且运行

3.4.1、编译

编译成功后,进度条跑到100%,并且devel目录下出现两可执行文件

3.4.2、运行

需要注意的是,修改后的环境变量只会在当前终端中生效。
比如,你此时打开了三个终端:
终端1运行roscore
终端2运行订阅话题:rosrun demo_topic person_sub
终端2运行发布话题:rosrun demo_topic person_pub
你必须在终端2和3运行rosrun命令前,运行source devel/setup.bash更改环境变量,才能让代码成功跑起来。
1、更改环境变量

source devel/setup.bash

2、启动ROS

roscore

3、运行订阅话题

rosrun demo_topic person_sub

4、运行发布话题

rosrun demo_topic person_pub

此时代码就成功运行起来了。

http://www.jsqmd.com/news/1353362/

相关文章:

  • 2026 年土工布厂家哪家专业:独家解析**精选 - 思溯深度专栏
  • 多任务推理式AI修图:从语义理解到协同编辑的技术演进
  • FingerJetFX OSE指纹特征提取架构深度解析与性能优化实战
  • AC自动机+矩阵快速幂优化DP
  • OpenMTP:macOS用户的终极Android文件传输解决方案
  • DBeaver驱动包终极指南:一站式解决所有JDBC驱动配置难题
  • 2026.8月厦门防水补漏维修,卫生间,阳台,外墙,屋顶,地下室漏水根治测评 - 超人防水
  • 为什么选择aspire-biencoder-compsci-spec?5大核心优势解析
  • 3步掌握Notepad--多行编辑:让文本处理效率飙升300%
  • Apache Doris实时数仓实战:从架构解析到部署调优全指南
  • Unity回合制战斗框架TBST:从网格寻路到AI决策的完整解决方案
  • 如何快速将PowerShell脚本封装为EXE:终极图形化工具指南
  • 筑宅安房屋修缮|汉中防水补漏专业公司,解决雨季房屋渗水漏水 - 筑宅安
  • ComfyUI中文工作流终极指南:21类AI绘图模板快速上手
  • AI Agent工具调用实战:超越官方范式的四种高可用设计模式
  • 5分钟快速掌握路径规划算法:从机器人导航到自动驾驶的完整指南
  • 北京法人变更找哪家公司好?教你挑选靠谱工商财税代办机构 - 同梦
  • Sketch-Toolbox开发指南:如何为插件管理器贡献代码
  • 基于Minimax M2.5大模型构建特斯拉股票分析AI Agent实战
  • QQ空间历史数据备份终极指南:5分钟轻松找回你的数字记忆
  • DeepSTARR性能评估:模型参数、FLOPs与预测速度的全面测试
  • 2026年实力之选:聚焦环保型异丙醇领域,佛山市常兴新材料有限公司的硬核实力解析 - 优企名品
  • C语言速成指南:从核心概念到实战项目,掌握底层编程精髓
  • 厦门全屋漏水别瞎修!9大渗水场景一次讲透,省心修缮不踩坑 - 宅安选房屋修缮
  • GESP C++八级最远点对问题解析与算法实现
  • Input Leap终极教程:5分钟掌握开源跨平台KVM软件
  • 3步解锁123云盘VIP功能:完全免费的全能解决方案
  • 5分钟实现音乐自由:洛雪音乐聚合音源终极配置指南
  • GPT-imagev2灰度实测:中文多模态AI的图像生成与API集成指南
  • 3小时快速搭建本地AI写作助手:KoboldAI完整部署指南