摘要:為了解決由汽車而引起的能源、環境和安全問題,進行了車聯網的PC機監控中心以及Android手機客戶端的研究與設計。完成了PC機的Socket通信、電子地圖的加載與糾偏、后臺數據庫的設計。同時也完成了在Android操作系統下Socket通信和地圖的加載與糾偏問題。與硬件平臺進行聯合測試,驗證了監控中心和手機客戶端設計的有效性,且具有良好的魯棒性。本文網絡版地址:http://www.eepw.com.cn/article/245925.htm
關鍵詞:車聯網;socket通信;地圖糾偏;Android系統
DOI: 10.3969/j.issn.1005-5517.2014.4.003
引言
隨著汽車行業的快速發展,全球能源問題、環境問題和安全問題日益嚴重,解決問題的方式之一是建立汽車移動物聯網通信平臺。汽車移動物聯網分為感知層、網絡層和應用層三層。由感知層獲取采集車輛內部和外部的各種信息。網絡層主要是GPRS/3G無線網絡,將感知層得到的信息通過GPRS/3G無線網絡發送到上位機,應用層主要是接收網絡層傳輸過來的數據并進行處理[1],圖1為車聯網三層架構圖。
系統的應用層包括上位機監控中心和Android手機版本的客戶端,具備六大功能模塊:車輛基本信息、遠程監控、遠程控制、遠程故障診斷、尋車輔助、駕駛員疲勞狀態等。
上位機監控中心作為Socket服務器,要求具備公網IP和端口,可以被外網訪問。車載終端模塊作為Socket客戶端,當Socket連接建立之后,由車載終端將車輛的信息通過GPRS無線網絡傳給PC機,同時上位機監控中心也可以主動下發一些指令,查詢車載終端的狀態,要求車載終端上傳相關信息。
1 PC機監控中心設計
1.1 Socket通信設計
Socket分為服務器和客戶端兩部分,上位機作為服務器,使用VB中的Winsock控件,通過Socket實現與車載終端和手機客戶端的通信。
服務器端Winsock在接收客戶端連接之后,會檢測Winsock1.State的值,如果Winsock1沒有關閉的話則會將Winsock1關閉。當服務器與客戶端連接成功之后,服務器便開始接收客戶端的數據并且進行處理,同時還可以向客戶端發送數據和命令。
當打開了主窗體時,在Private Sub Form_Load()事件中自動加載Socket的監聽和連接,并且當點擊了各個功能模塊的按鈕時,上位機會通過Socket向車載終端下發查詢或者控制指令。
在PC機上位機程序中,需要設計兩個Socket連接,一個是用來與車載終端建立連接,另外一個是用來與Android手機建立連接。上位機Winsock1收到車載終端發送的數據之后,會進行處理并且存入到后臺數據庫。Android手機通過Winsock2從上位機獲取數據。當多個車載終端同時連接監控中心時,可以采用動態加載和卸載Winsock的方式,同一個端口監聽不同的連接請求,根據客戶端的IP地址來區分車載終端,端口號相同但連接的Index不同。
1.2 電子地圖的加載與糾偏
為了能夠在電腦上直觀地看到車輛的位置,在上位機設計了一個地圖加載界面,通過GPRS傳送的經度和緯度信息,顯示出車輛的當前位置。由于傳統的地理信息系統(GIS)技術復雜,建設和維護的成本高,本次設計采用調用在線地圖API(應用程序接口)的方式來實現地圖的加載,這樣一方面省去了繁瑣的測繪和地圖編制工作,另一方面也保證了地圖更新的實時性,地圖提供商會定期更新地圖,提高定位的有效性和精度[2]。
通過VB中的webbrowser控件,來加載一個后綴名為.htm的靜態網頁文件,可以實現電子地圖的加載。在靜態網頁中,編寫一個JavaScript函數,就可以在百度地圖上通過經度和緯度進行定位,并且可以實現電子地圖的放大、縮小和移動。
由于GPS的坐標與百度地圖加載的坐標是不匹配的。國際上采用的是WGS-84標準的地心坐標,國內發行的地圖必須要使用國家測繪局規定的GCJ-02進行加密,而百度地圖在此基礎上還使用百度公司的BD-09進行二次加密,因此GPS采集的經緯度和百度地圖并不匹配,需要進行坐標接口轉換,百度地圖也提供了進行坐標轉換的API接口函數。
在VB中利用webbrowser控件調用電子地圖并且實現坐標轉換的語句如下:
We b B r o w s e r 1 . D o c u m e n t . parentWindow.execScript \"map. panTo(new BMap.Point( \" jingdu \",\" weidu \"))\", \"javascript\"
We b B r o w s e r 1 . D o c u m e n t . parentWindow.execScript\"map. addOverlay(new BMap.Marker(new BMap.Point( \" jingdu \",\" weidu \")))\", \"javascript\"
We b B r o w s e r 1 . D o c u m e n t . parentWindow.execScript \"BMap. Convertor.translate(new BMap. Point( \" jingdu \",\" weidu \"),0,translateCallback)\", \"javascript\"
在上面的語句中,使用WebBrowser1.Navigate App.Path \"\BaiduMap.htm\"這個語句來加載已經編寫好的“BaiduMap.htm”地圖文件。調用坐標轉換函數時使用了new BMap.Point函數來新建坐標點,translateCallback為在靜態網頁文件中編寫的函數,該函數可以實現將指定點移到地圖中心、清除標注以及在指定坐標位置添加地標[3]。
1.3 后臺數據庫的設計
在VB中可以直接嵌入開發Access數據庫,通過“外接程序”中的“可視化數據管理器”可以直接創建Access數據庫,也可以加載或導入其他類型的數據庫。在VB中與數據庫的連接通常是使用ADO來實現的,在VB中操作后臺數據庫的步驟如下[4]:
(1)創建或導入數據庫,與數據庫建立連接。
(2)根據相應的命令讀取數據庫中的數據,并且在數據綁定控件中顯示。
(3)對獲取的對象進行增刪改查操作,并且將更新后的數據重新存入數據庫。
在數據庫的表格中,設計的字段主要有車主、車牌號、車型、經度、緯度、速度、前左車門、前右車門、后左車門、后右車門、前端蓋、后端蓋、故障代碼和駕駛員疲勞狀態等,在收到了GPRS發送過來的數據之后,根據協議進行解碼,將其中的數據分別存入對應的數據庫當中。向數據庫中新增數據的代碼如下:
Adodc1.Recordset.AddNew ’將數據寫入數據庫
Adodc1.Recordset(\"車主\") = chezhu
Adodc1.Recordset(\"車牌號\") = chepaihao
Adodc1.Recordset(\"車型\") = chexing
. . . . . .
Adodc1.Recordset.Update
上面的chezhu、chepaihao、chexing等變量都是獲得了車載終端數據的全局變量,利用這種方式可以將數據存入到數據庫對應的字段當中,便于查詢、使用和保存。
2 Android手機客戶端設計
2.1 Android中Socket通信設計
Android中提供了一個Socket的類,存在于“java. net.Socket”包中。首先要設定連接服務器的公網IP以及端口號,同時以輸入流InputStream()的形式來獲取從服務器傳過來的數據,然后從輸入流中讀取相應的數據存入緩沖區,最后讀取緩沖區即可以得到所需要的數據。把接收到的數據存在一個字符串里面,根據Android手機客戶端和PC上位機的協議進行數據的解碼,再把解碼后的數據存入到相應的字段當中,比如經度、緯度、速度、駕駛員疲勞狀態等等。
使用手機也可以向PC機發送數據和指令,比如點擊了“車輛監控”按鈕時,就需要向PC機發送指令,再通過PC機來控制車輛,從而達到手機監控車輛的效果。當手機需要向PC機發送數據時,建立Socket連接之后,是通過輸出流來實現的,先定義好所要發送的數據,再用outputStream. write()語句來將數據發送到Socket服務器。
由于Socket在連接通信的時候有可能會出現異常,所以系統要求加入用來捕捉和處理異常的try-catch語句。程序運行正常時,執行try{}里面的代碼;當出現異常時,執行catch里面的語句捕捉和處理異常。Android中Socket通信的部分代碼如下。
try{
Socket Socket = new Socket(\"125.21 6.144.177\",8091); //實例化Socket
InputStream indata = Socket. getInputStream(); //獲得從服務器傳過來的數據
byte[] buffer = new byte[indata. available()]; //緩沖區
i n d a t a . r e a d ( b u f f e r ) ;//讀取緩沖區
String msg = new String(buffer);//轉換字符串
System.out.println(msg); //將得到的數據進行輸出
String[] arr= msg.split(\",\"); //以“,”分割收到的數據,存入arr[]數組當中
OutputStream outputStream = Socket.getOutputStream(); //獲得輸出流,向服務器發送數據
byte[] buffer2 = new byte[1111] ;//定義要發送的數據
outputStream.write(buffer2, 0, 6);//開始發送數據
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace(); }
2.2 Android中電子地圖的加載與糾偏
近幾年隨著Android操作系統的興起,越來越多的地圖供應商都提供了Android地圖的SDK(軟件開發包),在Android中開發地圖加載的流程如下[5]:
Android程序在開發地圖時,需要在“AndroidManifest.xml”列表中添加多個應用權限,保證電子地圖能夠正確加載。
然后進行初始化設置,在“SetupMap”函數中,需要設置地圖視圖、設置縮放尺度、將指定坐標設置為地圖中點。
“MapView”類的“setTraffic”方法可以設置顯示地圖視圖的模式,地圖視圖的模式有衛星圖map.setSatellite(true)、一般地圖map.setTraffic(true)、街道圖map. setStreetView。“MapController”類的“setZoom”方法可以控制地圖的縮放尺度。由全球地圖(1)到街道地圖(21),數值越大地圖細節越詳細。
Android通過“Geopoint”類來定義坐標,“Geopoint”接受的兩個參數分別是“緯度”、“經度”值,需要以整數來表示。“Geopoint”接受的緯度和經度手機通過Socket從上位機獲取,然后通過實例化GeoPoint ()對象,在GeoPoint ()輸入緯度和經度即可以實現地圖的加載[6]。
G e o P o i n t p o i n t = n e w GeoPoint((int)(weidu),(int)(jingdu));
無論是Google地圖還是百度地圖,GPS坐標直接輸入加載處理的位置是有偏差的,論文使用百度地圖提供的在線API坐標轉換接口來實現糾偏,其語句為
G e o P o i n t p o i n t 2= C o o r d i n a t e C o n v e r t . bundleDecode(CoordinateConvert .
fromWgs84ToBaidu(point));進行轉換之后可以很好的解決坐標偏移的問題,測試結果表明定位誤差在5米以內。
為了在地圖上標示車輛所在的位置,需要添加一個定位圖標。在Android電子地圖中屬于覆蓋物,所有的覆蓋物都繼承“Overlay”類,本次設計自定義一個CustomItemizedOverlay子類,繼承ItemizedOverlay類,用來實現標注定位圖標和定位文字的功能。
3 系統的測試與結論
在設計好監控中心和手機客戶端之后,配合硬件進行測試,監控中心要具備公網IP,圖4和圖5為監控中心的部分界面展示,圖6為Android手機客戶端界面。
從以上測試結果可知,本次車聯網系統的設計達到了預期目標,系統總體運行流暢,上位機監控中心和Android手機能夠正確顯示車輛的基本信息、精確顯示車輛的位置、對車輛進行監控和控制、警示駕駛員是否疲勞等,便于車輛的管理、監控、調度、遠程診斷等,為我國的智能交通行業的發展提供有力的參考。