一、准备工作二、Topic:发布者与订阅者2.1 编写发布者节点2.2 编写订阅者节点2.3 配置 CMakeLists.txt2.4 编译并运行三、Service:服务端与客户端3.1 定义服务接口3.2 编写服务端节点3.3 编写客户端节点3.4 添加构建配置3.5 运行并验证四、Topic 与 Service 的区别五、常见问题找不到功能包或节点找不到 AddTwoInts.h客户端调用失败
本文通过两个最小示例,介绍 ROS 1 中最常用的两种通信方式:
- Topic(话题):发布者持续发送消息,订阅者异步接收消息。
- Service(服务):客户端发送一次请求,服务端处理后返回响应。
一、准备工作
本文假设已经完成以下准备:
- 安装 ROS 1,并创建 Catkin 工作空间
~/catkin_ws。
- 创建功能包
beginner_tutorials。
- 功能包已依赖
roscpp、std_msgs和message_generation。
- 已创建服务定义文件
srv/AddTwoInts.srv。
进入功能包源码目录:
二、Topic:发布者与订阅者
Topic 适合持续、异步的数据传输。例如,传感器不断发布数据,其他节点按需订阅。
2.1 编写发布者节点
创建
src/talker.cpp:这段代码完成了四件事:
- 初始化 ROS 节点
talker。
- 创建
chatter话题的发布者。
- 以 10 Hz 的频率生成字符串消息。
- 调用
publish()将消息发送给订阅者。
2.2 编写订阅者节点
创建
src/listener.cpp:这段代码的执行过程是:
- 初始化 ROS 节点
listener。
- 订阅
chatter话题。
- 调用
ros::spin()进入事件循环。
- 收到消息后,由 ROS 调用
chatterCallback()。
2.3 配置 CMakeLists.txt
确认
CMakeLists.txt 包含以下配置:2.4 编译并运行
先编译工作空间:
打开三个终端,并分别执行:
订阅者终端将持续输出类似结果:
三、Service:服务端与客户端
Service 采用同步的请求/响应模型:客户端发送请求,服务端处理后返回结果。它适合偶发、需要明确返回值的操作,不适合持续传输数据。
本例实现一个整数加法服务:客户端发送两个整数,服务端返回它们的和。
3.1 定义服务接口
创建
srv/AddTwoInts.srv:分隔线
--- 上方是请求字段,下方是响应字段。3.2 编写服务端节点
创建
src/add_two_ints_server.cpp:服务端收到请求后,会执行
add(),计算两个整数之和并写入响应。3.3 编写客户端节点
创建
src/add_two_ints_client.cpp:3.4 添加构建配置
在
CMakeLists.txt 末尾添加:重新编译:
3.5 运行并验证
确保
roscore 正在运行,然后分别启动服务端和客户端:客户端输出:
服务端输出:
四、Topic 与 Service 的区别
对比项 | Topic | Service |
通信方式 | 发布/订阅 | 请求/响应 |
是否持续通信 | 通常持续 | 通常单次 |
是否等待结果 | 发布者不等待 | 客户端等待响应 |
节点关系 | 多对多 | 通常一对一调用 |
典型场景 | 传感器数据、状态广播、控制指令 | 参数查询、触发动作、一次性计算 |
选择原则
持续产生、允许异步处理的数据使用 Topic;需要发起一次操作并获得明确结果时使用 Service。
五、常见问题
找不到功能包或节点
确认当前终端已加载工作空间环境:
找不到 AddTwoInts.h
通常是服务代码尚未生成。检查
add_service_files()、generate_messages() 和 add_dependencies() 配置,然后重新执行 catkin_make。客户端调用失败
依次检查:
roscore是否正在运行。
- 服务端节点是否已经启动。
- 服务名是否为
/add_two_ints。
可使用以下命令查看当前服务:
- Author:felixfixit
- URL:http://www.felixmicrospace.top/article/ros_website_tutorial_publisher_subscriber
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!








