这是 ROS2 话题(Topic)通信最关键的底层机制。
一、核心结论(3 句背下来)
- 如果发布者不更新数据,订阅者就读不到新数据!
- 订阅者读取数据后,原数据不会被清除!
- 话题 = 广播机制,不是队列、不是缓存、不是信箱。
二、详细详解(彻底讲透)
1. 发布者不更新 → 订阅者能读到吗?
不能!
ROS2 话题是发布 - 推送模式(Publish-Subscribe):
- 只有发布者发一次,订阅者才会收到一次
- 发布者停止发送 → 数据流立刻断了
- 订阅者不会读到旧数据,只会收不到任何数据
比喻:
话题 =电台广播
- 电台说话(发布)→ 你听到(订阅)
- 电台闭嘴(不发布)→ 你听不到任何声音
- 你不会重复听到上一句话
2. 订阅者读完数据,数据会被清除吗?
绝对不会!
原因:
- 话题是广播,不是消息队列
- 数据会发给所有订阅者,不限数量
- 一个订阅者读了,不影响其他订阅者
- 数据不会因为被读过就消失
正确机制:
发布者发一帧数据 → DDS 网络广播 →所有订阅者同时收到 → 数据保留在发布端历史缓存(由 QoS 决定)
比喻:
你在教室说话(发布)全班同学都听到(多个订阅者)你说的话不会因为有人听了就消失
三、ROS2 话题底层机制(精华)
plaintext
发布者 -----广播-----> DDS网络 ↙ ↓ ↘ 订阅者1 订阅者2 订阅者3- 发布者发一次,全网订阅者都收到
- 不发就没有数据
- 数据不会被 “消费掉”,不会被删除
- 多个订阅者互不影响
四、那如果我想读到 “最后一次数据” 呢?
默认不行!但可以通过QoS: Durability = TRANSIENT_LOCAL实现。
开启后:
- 发布者关闭、不发布
- 新订阅者加入,仍能收到最后一帧数据
但这不属于默认行为!默认 QoS 是VOLATILE(不缓存,不发给后来者)。
五、最容易混淆的对比(一定要看)
表格
| 通信方式 | 发布者不发 | 订阅者读过后 | 多订阅者 |
|---|---|---|---|
| ROS2 话题(Topic) | 收不到数据 | 数据不删除 | 全部收到 |
| 消息队列(MQ) | 能读旧数据 | 读取后删除 | 只有一个能收到 |
| 服务(Service) | 无请求无响应 | 一次性 | 一对一 |
六、最终终极总结
- ROS2 话题是广播推送模式,发布者不推送,订阅者就没有数据可读。
- 订阅者读取数据后,数据不会被清除,可以被其他订阅者继续接收。
- 话题不做 “消息消费”,只做 “数据广播”。
- 默认不缓存历史数据,只有配置 QoS 才能保存最后一帧。