【Buzz】模塊源碼簡要分析

一  Buzz控制器

Buzz控制器

Buzz繼承實現了Argos中的控制器接口(如第一個案例中的buzz_controller_footbot控制器)。當啓動Argos模擬器時,會自動執行Buzz控制器的初始化方法,該方法主要獲取傳感器數據,讀取bytecode字節碼文件和debug調試文件,並將bytecode字節碼文件交給BVM模塊解析處理。Buzz控制器的ControlStep方法主要用於按步執行(執行頻率可以在.argos文件中配置),分爲四個過程:

1)processInMsg: 從sensors中讀取傳感器數據,更新鄰居節點信息,處理接收到的消息;

2)updateSensors: 更新傳感器數據,如位置、電量;

3)function_call: 調用用戶定義的step方法;

4)processOutMsgs: 通過actuator發送outmsg隊列中的消息,消息格式: robotid | 消息體長度 | 消息內容

二  BVM模塊

Buzz虛擬機主要用於在機器人平臺上執行通過Buzz語言生成的bytecode字節碼文件。BVM模塊會解析bytecode字節碼文件,存儲其中的相關指令和用戶定義的方法,以及內部模塊的一些方法(如neighbors/swarm/vstig/math/strings/obj等)。BVM還提供了方法調用堆棧、全局變量表、局部變量表、輸入輸出消息隊列等。

 如上圖,BVM從"Sensor data"讀取接收到的消息,放入到inmsgs消息隊列,並根據消息類型分發給相應的功能模塊(swarm/neighbor/vstig),這些模塊會解析並處理消息,處理消息時會用到BVM中的堆棧、解釋器等,然後將要發送的消息放入到outmsgs消息隊列,通過"Actuator data"發送出去。

三  neighbor模塊

鄰居節點數據存儲:<robotid, [distance, azimuth, elevation]>

數據來源

節點每step都會向鄰居節點廣播一條消息,消息內容爲本節點的robotid,如果有outmsgs隊列中有要發送的數據,則合併發送。

鄰居節點收到該消息後,檢測與消息發送者的distance,並更新上面的數據存儲。

方法

 1)listen(偵聽):BVM模塊將用戶定義的回調方法註冊到vm->listeners字段中,當每step中processInMsgsc處理接收到消息時,如果消息類型爲BROADCAST,則從vm->listeners中查詢對應的回調方法,並調用執行。

思考:vm->listeners爲字典結構<key, func>,是不是不能多個同一話題的偵聽?

2)broadcast(廣播):消息類型爲BROADCAST,消息放入到vm->outmsgs隊列中,每step都會將隊列中的消息發送出去。

3)ignore(取消):從vm->listeners回調函數列表中刪除回調函數。

4)map(座標變換):函數作爲參數,該函數用於對鄰居節點的數據進行轉換,並返回新的鄰居節點數據結構。

5)reduce(縮減):函數作爲參數,該函數用於對鄰居節點數據進行左摺疊/累積/縮小操作,函數最後計算出一個值。

四  swarm模塊

數據存儲

vm->swarms字典:<swarmid, 0/1>,存儲本節點知道的羣列表;

vm->swarmmembers字典:<robotid, [age,swarmed_list]>,存儲本節點所有鄰居節點所屬的羣列表

方法

 1)create(創建羣):本節點BVM將swarmid保存到vm->swarms字典中,數據結構爲<swarmid, 0/1>,後者表示本機器人是否屬於該羣。也可以從已有的羣中創建新羣:intersection(交集)/union(並集)/difference(差集)。

2)join(加羣):本節點BVM將vm->swarms字典中的標誌爲1,併發送消息<robotid, swarmid>,消息類型SWARM_JOIN。鄰居節點收到消息後,將節點與羣關係存儲到vm->swarmmembers字典中,數據結構爲<robotid, [age,swarmed_list]>。另外一種加羣方法爲select,不同的是:select 是有條件加羣,join 是無條件加羣。

3)leave(離羣):本節點BVM將vm->swarms字典中的標誌爲0,併發送消息<robotid, swarmid>,消息類型SWARM_LEAVE。鄰居節點收到消息後,更新vm->swarmmembers字典中的節點與羣關係。另外一種離羣方法爲unselect,不同的是:unselect 是有條件離羣,leave 是無條件離羣。

4)in(查詢):若判斷本節點是否屬於某個羣,則從本節點vm->swarms字典中的查詢標誌是否爲1;若判斷鄰居節點是否屬於某個羣,則從本節點的vm->swarmmembers字典中查詢。

5)exec(執行):屬於該羣的所有節點執行某個方法。

思考:如果一個節點屬於多個羣,那麼在exec執行任務時,如何處理?

BVM對羣的自動管理過程(如節點宕機時,如何主動判斷節點離羣?)

1)BVM每步都會調用一次update方法,該方法會檢查vm->swarmmembers字典中的鄰居節點的age是否超過限制(默認50),如果超齡,則從字典中刪除該節點的記錄。

2)BVM每10步發送一次SWARM_LIST消息,消息格式<robotid, swarmid_list>。鄰居節點收到該消息後,更新本節點BVM中的vm->swarmmembers字典,並將發送者的age置爲0。(age表示從上次更新到當前時間的經歷的步數)

五  vstig模塊

主要用於整個羣內的數據共享。

數據存儲 vm->vstigs :<vstigid, <key, [value,timestamp,robotid]>

方法

1)put (寫):當節點向共識寫新的數據時,本地BVM先更新本地共識數據,然後,將<vstigid,key,value,timestamp,robotid>消息放入vm->outmsgs隊列,消息類型爲VSTIG_PUT。鄰居節點收到該消息後,檢查消息的timestamp,如果timestamp比當前存儲的key的時間新,則數據有效並轉發;如果同樣的timestamp但不同的robotid說明出現了衝突,會調用用戶設置的onconglict方法(默認使用robotid大的數據有效),解決衝突後會調用用戶設置的onconflictlost方法。

2)get(讀):當節點從共識讀取數據時,如果本地有該key,則BVM會返回該key對應的數據;然後,BVM將<vstigid,key…>消息放入vm->outmsgs隊列,消息類型爲VSTIG_QUERY。鄰居節點收到該消息後,會查詢自己的共識數據,如果本地的數據較新,則會向發送者回復較新的數據,消息類型爲VSTIG_PUT;如果本地的數據較舊,BVM則會更新該條數據,並廣播給所有鄰居節點。該機制允許機器人斷開重連後自動更新數據。
 

 

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