MQTT應用開發(三) - 車聯網V2X服務端開發

在前面的兩篇博客中,我們已經完成了MQTT服務器的搭建,以及MQTT客戶端的開發,客戶端模擬了2輛車定時上報CAM消息,並且其中一輛車隨機生成DENM消息,彙報緊急剎車的事件。在V2X的應用場景中,我們需要把DENM消息轉發給一定範圍內的其他車輛。車輛可以通過DSRC接口或者LTE-V2X的PC5接口直接發送DENM,也可以通過服務端轉發。在這裏我將採用服務端轉發的方式,在服務端接收DENM消息,生成一個電子圍欄(GeoFence),並通知在電子圍欄內的其他車輛。

因爲需要對車輛上報的地理位置進行計算,以及生成地理電子圍欄,我採用Google的S2 Geometry庫來進行處理。在Github中下載S2的源代碼,https://github.com/google/s2geometry,然後按照官網的介紹進行編譯和安裝。注意如果用Python來調用接口的話,需要安裝swig,apt-get install swig。安裝之後,會在/usr/local/lib目錄下安裝一個libs2.so的文件,以及在python的site-packages裏面生成pywraps2.py以及_pywraps2.so這2個文件。需要注意的是,在Ubuntu環境,需要把libs2.so拷貝到/usr/lib目錄下,不然調用的時候會報錯。安裝完成後在Python裏面就可以import pywraps2 as s2來進行調用了,可以通過help(s2)來查看這個庫所提供的方法,也可以查看這個網頁http://s2geometry.io/devguide/basic_types

具體的流程如下:

  1. 每次接收到車輛的CAM信息上報,根據經緯度計算對應的level 30的Cell ID,存儲車輛VIN號與Cell ID的關於在Redis中(通過zadd的sorted list保存,每個元素的name是車輛的VIN,score是CellID),同時創建一個對應於車輛位置的S2Point實例,保存在本地緩存中。

  2. 每次接收到車輛的DENM消息,根據裏面的位置信息爲圓心,創建一個半徑爲200米的圓形電子圍欄S2Cap實例。計算這個圍欄覆蓋了多少個S2 level 12的Cell,把圍欄的ID和Cell ID的對應關係存儲在Redis中(用sadd命令保存爲set),並保存圍欄ID和S2Cap實例在本地緩存中。計算圍欄的Level 12 Cell ID的起止範圍,通過Redis的zrangebyscore來查找在這個起止範圍內的所有車輛(計算車輛的Level 30的Cell ID是否落在這個範圍中),對於滿足查詢條件的車輛,取出在本地緩存中保存的S2Point實例,用電子圍欄的S2Cap的Contains函數來判斷是否包含這個S2Point,如果包含,判斷這個車輛是否新進入這個電子圍欄,如是則轉發DENM信息。

  3. 當車輛上報CAM消息時,還需要計算車輛的Level30的Cell ID的Parent level 12的Cell ID,根據這個Level 12ID查詢是否有對應的電子圍欄,如果有則判斷車輛是否在電子圍欄範圍中或者離開電子圍欄(通過S2Cap Contains來判斷)

  4. 系統需要自動根據DENM消息的有效期來清除過期的電子圍欄。

具體的實現邏輯和代碼可以參見我在Gitee上的代碼庫,https://gitee.com/gzroy2000/IoT_V2X/tree/master/

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