對rostopic的一些新認識

學習使用ros的時候遇到的一個很“實際”的問題:一個節點怎樣通過topic向另一個節點發送消息呢?

其實已有教程通過寫簡單發佈器和訂閱器來介紹如何利用topic進行節點間通信了:ROS與Python入門教程-寫簡單發佈器和訂閱器

看起來一個很簡單的操作,我卻想不通一些問題:

在talker.py裏面實現了定義topic的publisher、定義了節點、發佈消息這三件事,爲什麼topic和node要在一個程序裏面定義,topic和node不應該是相對比較獨立的兩個東西嗎?

命令行裏面通過'rostopic pub'不是可以直接從topic發佈msg嗎?那麼應該可以把topic的定義單獨用一個程序實現,這樣的話應該可以單獨“啓動”一個topic,但是我卻沒找到這種方法。

難道topic是必須由一個node來發布?這樣的話node結束時topic不也沒了?一個topic不是應該可以有多個訂閱者和發佈者嗎?

(這個時候我對發佈者、話題、訂閱者的關係理解還比較抽象,認爲topic是一個“中間商”,發佈者和訂閱者不需要直接接觸,而是分別通過topic來發出和接收msg,topic就像是中間的一個buffer)

自己的理解和實際的現象產生了矛盾,使我很困惑。

於是嘗試去了解ros的通信原理。。。

在閱讀了兩篇文章後,才發現機制不是原來想象的那麼簡單。

ROS通信原理介紹

ROS 通訊層模型


還存在這樣一個東西:

Master node: master node 給ros系統中其他節點提供命名與註冊的服務。它跟蹤節點中的publisher與subscriber,service 的server與client,記錄其他節點的位置(uri標明,host與port),並將這些信息通知給需要建立鏈接的節點。

Master可以認爲是一個查詢表,各個節點可以查詢它要把消息發送到哪個節點。

我總結了一下差不多是這樣:master通過每個node在“查詢表”裏面註冊的topic信息來知道哪些node之間有需要傳輸數據的這種聯繫,然後告訴node如何去找自己需要傳輸數據的其他node,node知道目標node後,兩個node就之間建立tcp連接來傳輸數據(沒有中間商賺差價)

然而還是不知道怎麼實現一個topic對應多個訂閱者和發佈者的,topic是否是獨立於node的(比如發佈topic1的節點node1如果關閉了,topic1的另一個發佈者node2怎麼辦呢)

沒辦法,只有先看看實際是怎麼樣的一種情況。


於是我用talk.py和listener.py來做實驗。

實驗一:首先測試了多個發佈者對一個topic發佈消息以及多個訂閱者對一個topic訂閱消息(多開幾個terminal,運行兩個talker和兩個listener),沒有問題。

實驗二:看看topic沒有對應的發佈者和訂閱者會發生什麼——在talker.py的程序裏面把topic的名字改爲"chatter_1",在listener.py裏面把topic的名字改成"chatter_2",分別運行兩個節點,這時兩個節點當然不能通信,但是系統沒有報錯。這時運行rostopic list查看有哪些topic,發現列表裏面存在/chatter_1和/chatter_2這兩個節點。

實驗三:如果節點關閉了,對應的topic會怎麼樣。在實驗二的基礎上,先關閉talk.py節點,再運行rostopic list查看topic列表的變換,發現/chatter_1不見了,再關閉listener.py節點,查看topic列表,發現/chatter_2不見了。

實驗四:運行rostopic pub /chatter_3 /std_msg/String h 向chatter_3發佈 消息,運行rostopic list查看topic列表,發現有/chatter_3


結論:topic是不能獨立存在的,必須有node發佈或者訂閱纔會存在topic,而且只要有發佈者或者訂閱者topic就會存在,但如果發佈者和訂閱者都不存在了,topic也就不存在了。


關於rostopic pub對topic發佈msg其實原理也一樣,實際上會生成一個節點來向這個topic發佈消息。



雖然沒有node來訂閱這個/chatter_3但它卻有它的發佈者/rostopic_26077_153........






















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章