Apollo 3.5 Cyber - Service Discovery 模塊
注意:要先看完Transport模塊,才比較好看懂下面在說甚麼
Transport模塊的介紹
https://blog.csdn.net/weixin_44450715/article/details/86479466
https://blog.csdn.net/weixin_44450715/article/details/86314193
問:Service Discovery 模塊有甚麼用的?是要靠它去發現其他node(可理解為在ros中的ros node或fastrtps中的participant),然後才能通訊嗎?
答:不是,這並不是Service Discovery 模塊的工作,那是在fastrtps的內部做的。Service Discovery 模塊做的比較算是監察節點變動及處理相關變動的工作
問:那這個Service Discovery 模塊主要是靠甚麼方法去實現其功能呢
答:通過rtps實現。當創建一個Node::Reader
, Node::Writer
, etc 時,會建立一個對應的監察節點(只用來做service discovery,跟transport模塊中rtps模式下真正用作傳message數據的節點是不同的節點,只有role attribute是一樣)。當新監察節點加入時,它要發一段消息到指定channel(用來給監察節點交流的channel)說自已來了,那其他人就會知道有新節點了,在節點離開時也一樣。
問:那後加入的節點是怎知道先加入節點的存在呢
答:https://fast-rtps.docs.eprosima.com/en/latest/pubsub.html?highlight=DURABILITY_TRANSIENT_LOCAL
靠rtps的qos去做到,當用了Keep-All
跟Transient Local
時,每個新節點加入時會拿到之前的全部記錄
QosHistoryPolicy::HISTORY_KEEP_ALL
QosDurabilityPolicy::DURABILITY_TRANSIENT_LOCAL
以上為cyber的設定
以下為解釋
Keep-All: Store all samples in memory.
Transient Local (Default): When a new subscriber joins, its History is filled with past samples.
個人感想:感覺這實現有點問題,如果某process出現嚴重錯誤,連destructor內部的代碼也crash了。那Service Discovery
模塊中的記錄就會錯,過份依賴節點自身去管理了。個人覺得可以另外加入一個選舉機制,選出一個節點去定期檢查現存
節點的存活。
感謝@jungleni指正
有新的节点加入时,已经挂掉的process,与它相关资源都已经没了(比如fastrtps的publisher),这个时候,该publisher的历史消息不会推送给新加入的节点。
Service Discovery 模塊主要負責:
- 當你在Transport模塊把所有回調註冊好後,如果
Transport::CreateReceiver
及Transport::CreateTransmitter
時中設定的mode是OptionalMode::HYBRID
,那它會默認不調用回調的,直到你告訴它可以打開了,他才會打開(因為OptionalMode::HYBRID
中是會從shm
,rtps
,intra
三個實現中自動選擇所有
適用的實現。那它就要知道當前channel中的其他節點是同一個主機
,同一個process
的嗎,才能找出要用甚麼實現) 那就需要Service Discovery模塊就是去找出同一channel中的其他Participant跟我是甚麼關係
- 根據Service Discovery 模塊的監察,去把transport模塊中的相應回調打開或關閉
- 監察節點網絡 (Graph structure,就每個節點為一個vertex,而其相關channel為edge)的狀況,把現在的狀況存在內部,並提供一個接口去給其他模塊用。
以下是hybrid mode如何選實現的邏輯
4. have node in same process, enable intra
5. have node in different process, enable shm
6. have node in different host, enable rtps
message CommunicationMode {
optional OptionalMode same_proc = 1 [default = INTRA]; // INTRA SHM RTPS
optional OptionalMode diff_proc = 2 [default = SHM]; // SHM RTPS
optional OptionalMode diff_host = 3 [default = RTPS]; // RTPS
};
Service Discovery 模塊下的TopologyManager
, ServiceManager
, NodeManager
, ChannelManager
Service Discovery 模塊用三個specific manager去管理節點網絡的不同資訊。
ServiceManager
專注於service節點的存活,並提供查詢接口
我還沒有寫service模塊是甚麼,你可以大概想成一般server。由一個channel收數據,由回調處理好,最後把結果發到另一個channel。
NodeManager
就簡單監察所有節點的存活,並提供查詢接口
ChannelManager
就專注於節點間的關係及節點網絡的圖結構,並提供查詢接口
TopologyManager
會管理ServiceManager
, NodeManager
, ChannelManager
的lifecycle, 另外負責在監察到Participant退出後(Participant的概念可看https://eprosima-fast-rtps.readthedocs.io/en/latest/introduction.html),讓ServiceManager
, NodeManager
, ChannelManager
去做內部狀況更新及調用回調。TopologyManager
的實現方法和其他三個specific manager有點不一樣,它是監察Participant
的變動事件,而不是某channel
的訊息內容,提供一個更高層的監察。
Service Discovery 模塊會在甚麼時候被用到呢
cyber/init.cc
清理一切
void Clear() {
...
service_discovery::TopologyManager::CleanUp();
...
}
cyber/node/node_channel_impl.h
node監察節點的創建及刪除是在這做的
explicit NodeChannelImpl(const std::string& node_name) {
...
if (is_reality_mode_) {
nod