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

演示一下如何编写 Publisher (发布者) 和 Subscriber (订阅者) 的代码吗?-02 - jack

这是一个非常经典的 ROS 入门场景。我们将创建一个“说话者”(Publisher)和一个“倾听者”(Subscriber)。

为了让你看得清晰,我将沿用上一轮假设的包名 my_robot_control

核心概念图解

在写代码之前,先理解数据流向:

  1. Publisher (Talker): 告诉 ROS Master 我要往某个话题(Topic)发数据。
  2. Topic: 就像一个广播频道(例如名为 /chatter)。
  3. Subscriber (Listener): 告诉 ROS Master 我要监听这个频道,一旦有数据,就调用我的回调函数处理。

第一步:编写 Publisher 代码 (talker.cpp)

~/catkin_ws/src/my_robot_control/src/ 目录下新建 talker.cpp

这个节点会每秒发送一条 "Hello ROS" 消息。

/*** 文件名: talker.cpp* 功能: 持续发布 std_msgs/String 类型的消息到 "chatter" 话题*/#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>int main(int argc, char **argv)
{// 1. 初始化节点,命名为 "talker"// 注意:节点名称必须在 ROS 网络中唯一ros::init(argc, argv, "talker");// 2. 创建节点句柄,它是管理节点资源的入口ros::NodeHandle nh;// 3. 创建 Publisher// 语法: nh.advertise<消息类型>("话题名称", 队列长度)// 队列长度 1000 意味着:如果网络堵塞,保留最近 1000 条消息,旧的丢弃ros::Publisher chatter_pub = nh.advertise<std_msgs::String>("chatter", 1000);// 4. 设置循环频率 (10Hz,即每秒 10 次)ros::Rate loop_rate(10);int count = 0;while (ros::ok()) // 当 ROS 正常运行时(比如没有按 Ctrl+C){// 5. 封装消息数据std_msgs::String msg;std::stringstream ss;ss << "Hello ROS " << count;msg.data = ss.str();// 打印到终端 (类似 printf)ROS_INFO("%s", msg.data.c_str());// 6. 正式发布消息chatter_pub.publish(msg);// 7. 处理回调 (虽然这里没有订阅,但保留是个好习惯)ros::spinOnce();// 8. 休眠直到达到 10Hz 的时间间隔loop_rate.sleep();++count;}return 0;
}

第二步:编写 Subscriber 代码 (listener.cpp)

在同一目录下新建 listener.cpp

这个节点会一直等待,一旦 /chatter 话题有消息,就触发回调函数打印出来。

/*** 文件名: listener.cpp* 功能: 订阅 "chatter" 话题并打印收到的内容*/#include "ros/ros.h"
#include "std_msgs/String.h"// 1. 回调函数 (Callback)
// 当有新消息到达时,ROS 会自动调用这个函数
// msg 是消息的常量指针,效率高
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{ROS_INFO("I heard: [%s]", msg->data.c_str());
}int main(int argc, char **argv)
{// 初始化节点,命名为 "listener"ros::init(argc, argv, "listener");ros::NodeHandle nh;// 2. 创建 Subscriber// 语法: nh.subscribe("话题名称", 队列长度, 回调函数)ros::Subscriber sub = nh.subscribe("chatter", 1000, chatterCallback);// 3. 进入自旋 (Blocking)// ros::spin() 会阻塞在这里,不断检查是否有消息到达。// 一旦有消息,它就去执行 chatterCallback,执行完回来继续等。ros::spin();return 0;
}

第三步:修改 CMakeLists.txt (最重要!)

代码写好了,必须告诉编译器如何编译这两个文件。打开 ~/catkin_ws/src/my_robot_control/CMakeLists.txt

你需要确保 find_package 中包含了 std_msgs(因为我们用了 String 消息)。

然后在 Build 区域添加以下内容:

## ... 前面的 find_package ...## 1. 编译 talker
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
# add_dependencies(talker ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})## 2. 编译 listener
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
# add_dependencies(listener ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

第四步:编译与运行

  1. 编译
cd ~/catkin_ws
catkin_make

(确保没有报错,如果有 "undefined reference",检查 CMakeLists.txt 是否保存)
2. 运行 (需要打开 3 个终端窗口)

  • 终端 1 (Master):
roscore
  • 终端 2 (Listener/Subscriber):
source ~/catkin_ws/devel/setup.bash
rosrun my_robot_control listener

(此时它会卡住等待,这是正常的)

  • 终端 3 (Talker/Publisher):
source ~/catkin_ws/devel/setup.bash
rosrun my_robot_control talker

结果
你会看到终端 3 不断打印 "Hello ROS 0", "Hello ROS 1"...
同时,终端 2 会同步打印 "I heard: [Hello ROS 0]"...


关键点总结

概念 Publisher (Talker) Subscriber (Listener)
主动性 主动发送数据 被动等待数据
核心对象 ros::Publisher ros::Subscriber
循环方式 while(ros::ok()) + loop_rate.sleep() ros::spin() (死循环等待)
关键函数 .publish(msg) callback(msg)

接下来,你想了解如何定义自己的“自定义消息”(比如发送一个包含 姓名(string) 和 年龄(int) 的消息),还是想了解如何使用 roslaunch 一次性启动这两个节点?

http://www.rkmt.cn/news/126036.html

相关文章:

  • 如何利用WebRTC实现实时远程操控Linly-Talker?
  • 数字人创业新方向:基于Linly-Talker的SaaS服务构想
  • 一张人脸照片+文本生动数字人?Linly-Talker做到了
  • Open-AutoGLM场景化部署十大坑点(前3名企业避坑实录首次公开)
  • Axios HTTP请求超时时间参数配置教程
  • GitHub 热榜项目 - 日榜(2025-12-20)
  • 【解密Open-AutoGLM隐私引擎】:90%开发者忽略的4个安全盲区及应对策略
  • 还在为大模型落地难发愁?:Open-AutoGLM在智能客服中的4步实施法
  • 解决机器人“完美难题”:智能拣选与码放技术
  • 传送带异物检测玻璃碴子检测数据集VOC+YOLO格式156张1类别
  • Linly-Talker与Stable Diffusion结合的可能性探索
  • JavaSE——键盘录入
  • 写给未来的自己:一名测试开发工程师的十年之约
  • (独家披露)Open-AutoGLM与大模型协同创新路径图(仅限内部交流版)
  • 2025年广东半导体产业园选址公司权威推荐榜单:新材料产业园选址/预制菜产业园选址/人工智能产业园选址咨询机构精选 - 品牌推荐官
  • 如何在不牺牲性能的前提下实现Open-AutoGLM级数据保护?:一线专家实战经验分享
  • 2025年海口知名的消防排烟防火阀公司排行榜,卡式风机盘管/吊顶式空调机组/直膨式空调机组/消防排烟防火阀设计找哪家 - 品牌推荐师
  • Linly-Talker能否实现语音打断与即时响应?
  • 2025海外游学机构TOP5权威推荐:达美游学,甄选优质行学伙伴助力青少年国际视野腾飞 - 工业推荐榜
  • 【Open-AutoGLM调参实战指南】:掌握模型动态优化的5大核心技巧
  • 开关磁阻电机(SRM)仿真:从Matlab到Maxwell
  • 【大模型效率提升300%的秘密】:Open-AutoGLM协同优化的7个关键技术点
  • 环境不稳定?容器化治理方案
  • 【AI工程化新里程碑】:Open-AutoGLM在工业质检中的7个关键优化步骤
  • conda命令效率翻倍:你可能不知道的10个技巧
  • 【第67套】邮电之首,难度骤降。
  • Hadoop数据统计:描述性分析指南
  • JavaSE——标识符
  • 【一天一个黑客小知识】2025终极指南:十大黑客攻防技术从入门到精通,零基础直通大师
  • 9个AI工具,助你轻松搞定本科论文!