盛 蔚,盧東輝
(北京航空航天大學 儀器科學與光電工程學院,北京 100191)
由于相關技術的局限性,無人機遠程技術支持領域的研究和發展存在著不足與空缺。目前,專業的方案較少,主要借助TeamViewer[1]、PCAnywhere[2]等通用遠程控制軟件獲取遠程計算機的控制權來實現,其優點是技術應用較成熟,但非定制的特點使其與無人機和配套軟件不協調,且傳輸數據量較大,因此專業性、功能性、實時性無法滿足要求。隨著云計算的發展[3-5],陸續有研究將其應用到物聯網[6]、智能農業[7]、電力系統[8]的遠程支持或監控領域,通過定制化開發,實現遠距離數據傳輸以及對相應事物的監控,發揮了云的通信、計算、存儲等優勢,但普遍沒有考慮傳輸實時性等問題,云在無人機遠程技術支持領域的應用仍存在一定空缺。
針對上述要求,本文提出一種基于云的無人機遠程技術支持系統,設計了系統流程和功能模塊。在C/S結構[9]下,用Windows Presentation Foundation(WPF)[10]開發支持網絡傳輸的無人機地面站軟件[11]客戶端,作為終端對無人機指令和數據進行操作和處理;用Python在阿里云上開發服務器端,監聽客戶端的操作請求和數據,并完成相關處理。通過云和網絡連接客戶端和遠程無人機,設計基于HTTP和TCP[12]的傳輸協議,傳輸操作信息和數據指令,實現目標功能。提出一種基于優先級的無人機數據自適應傳輸方法,通過劃分數據優先級、計算分配帶寬和預估數據量來調節數據頻率,實現重要數據的最優傳輸和次要數據的可靠傳輸。最后,實際測試驗證了本文設計的可行性,其滿足專業性、功能性和實時性等要求。
云計算(cloud computing)是基于互聯網的計算,憑借著遠超傳統計算服務的彈性擴展、靈活訪問資源、方便監控、穩定可靠等優勢[3-5],被廣泛應用于物聯網、通信等技術領域,可以為遠程技術支持帶來高速網絡傳輸、高開發效率、低運行成本等好處。本文選擇穩定可靠的阿里云計算平臺作為服務端開發平臺。
Python是一種面向對象高級程序語言,具有開發迅速、可擴展性強、兼容性好等優點[13],是服務器開發的熱門語言。aiohttp是基于異步協程IO庫的Python服務器框架,該框架利用asyncio的異步協程IO技術[14],協程是可控的程序上下文切換技術,在應對高并發問題時,相比進程、線程更加輕量和高效,因此非常適合本文數據量不大、邏輯簡單、高并發的傳輸背景。
WPF是基于.NET和Windows的用戶界面框架,編程語言為XAML和C#,XAML是用于實例化.NET對象的標記語言,負責構建WPF的用戶界面,C#是面向對象的高級程序設計語言,負責界面的后臺邏輯實現。WPF具備界面和邏輯分開、自動適應分辨率,處理速度快等優點,提高了客戶端開發的效率和質量[10]。
在常見的無人機系統中,無人機和地面控制站之間利用無線電鏈路傳輸控制站上的控制指令和無人機上的飛行數據,結合相關站上或機上的顯示與處理,即可實現對無人機的通信傳輸、參數調整、實時監視、飛行控制等功能。因此,無人機遠程技術支持系統的關鍵是在上述基礎上,利用云和網絡連接無人機和客戶端,遠距離傳輸無人機的飛行數據和技術支持方的控制指令,實現目標功能。
具體的系統流程如圖1所示,分為飛行數據回傳流程和控制指令上傳流程。前者中,無人機將飛行數據下傳給受支持者地面站,再利用TCP傳輸給云服務器和支持者地面站解析并顯示,實現遠程監視、參數檢查等功能;后者中,利用TCP將支持者地面站上產生的指令傳輸給云服務器端和受支持者地面站,最后通過無線電上傳給無人機從而實現調試、飛行控制等功能;另外,還包括用戶操作流程,地面站客戶端發起包含操作信息的HTTP請求,云服務器端做出相應的處理和應答。

圖1 系統流程
針對專業性要求,本文采用C/S結構對系統進行定制化設計,如圖2所示,由客戶端和服務器端組成。
其中,客戶端由以下功能模塊組成:
(1)操作模塊:提供人為操作的功能界面,包括登錄、連接、退出等連接操作和注冊、修改密碼等賬戶操作,將操作信息用HTTP發給服務器端,并處理返回的結果。
(2)傳輸模塊:發起和維持與服務器端之間的TCP傳輸,將地面站中的數據和指令發送給服務器端,接收和解析來自服務器端的數據和指令。
(3)地面站基礎功能模塊:維持與無人機的通信連接,作為數據指令傳輸通道;以圖形界面、虛擬儀表等形式顯示無人機狀態信息;提供參數調整等界面;提供飛行控制功能包括控制指令、飛行搖桿和任務規劃等。
服務器端由以下模塊組成:
(1)主模塊:服務器端主程序;接收和處理客戶端登錄等操作的HTTP請求并返回結果;接收和轉發無人機數據和指令的TCP消息,并進行權限控制;連接和處理數據庫,處理用戶身份驗證和操作記錄讀寫。
(2)存儲模塊:利用數據庫實現數據存儲功能,主要存儲賬戶、密碼等用戶信息和用戶操作、結果等記錄。
下面對客戶端和服務器端的設計與實現方法,優先級無人機數據自適應傳輸方法等關鍵技術進行重點闡述。
針對功能需求和專業性要求,設計客戶端為用戶進行操作的運行在聯網PC上的軟件,根據角色不同,分為飛行現場的受支持端和技術支持人員的支持端。本文使用WPF技術基于無人機地面站軟件開發客戶端,復用其站-機通信、地圖與儀表顯示、參數調試等功能,并加入遠程支持的相關功能。

圖2 系統功能結構
客戶端界面包括遠程支持、用戶注冊和修改密碼等子界面,如圖3所示,利用XAML語言調用控件并定制樣式,實現了用戶名、可連接對象和登錄等顯示框和按鈕,按照MVC模式,在上述控件中通過事件機制在后臺邏輯來實現相應的功能。

圖3 客戶端用戶界面
客戶端的程序流程圖如圖4所示,用戶填入信息后點擊登錄,客戶端程序發起TCP連接,并用HTTP登錄請求將賬號和密碼發送給服務端:收到反饋為登錄成功,則進入下一步;收到登錄失敗或等待超時,則返回上一步。登錄成功后,開始向服務端定時發送HTTP輪詢請求,并解析返回的輪詢結果,顯示結果中的用戶狀態和可連接用戶列表。根據用戶狀態:
(1)登錄狀態,選擇一名可連接用戶點擊連接,用HTTP連接請求將賬戶和口令發給服務端:收到反饋為連接成功,則開始往TCP傳輸隊列中讀寫無人機數據和指令;收到連接失敗,則返回上一步。
(2)連接狀態,繼續往傳輸隊列讀寫數據和指令。
(3)斷開狀態,結束讀寫并退出程序。
點擊斷開,程序向服務端發送HTTP斷開請求:收到反饋為退出成功,則退出程序;收到退出失敗,則繼續處于連接狀態。

圖4 客戶端程序流程
代碼實現中,將System.NET類庫中的Socket和TcpClient類封裝成RemoteSupport類,提供發起、維持及斷開TCP通信的功能。在地面站軟件的數據指令收發程序中調用這個類,當受支持方收到無人機下傳或支持者發出的數據和指令時,通過事件發布函數,執行RemoteSupport類的發送函數,實現向服務端發送的功能,關鍵代碼如下:
//發送控制指令的事件訂閱
this.DataSendEvent += MainWindow_DataSendEvent;
//將控制指令字節流寫入TCP
MainWindow_DataSendEvent(byte[] bytes)
{
RemoteSupport.WriteTcp(bytes);
}
在收到服務端下傳的數據和指令時,執行RemoteSupport類的數據接收函數,再通過事件發布函數傳給地面站解包處理程序(支持方)或者轉發給飛控(受支持方),實現遠程下傳接收功能,關鍵代碼如下:
//收到服務端數據的事件訂閱
RemoteSupport.DataReceivedEvent+=RemoteSupport_DataReceivedEvent;
//下傳接收處理函數
RemoteSupport_DataReceivedEvent(byte[] bytes)
{
//根據是否支持方處理接收數據
DataProcessSupport(bytes);
}
聲明NewWebClient類繼承自System.NET類庫中的WebClient類,提供收發HTTP請求和回復的功能。當進行登錄、連接等操作時,客戶端將相關信息放入HTTP協議后以POST方式發送給服務端并解析回復,關鍵代碼如下:
//發送信息接收回復
byte[]response=newWebClient.UploadValues(URL,"POST",formData);
針對功能需求和專業性要求,設計服務器端為運行在阿里云服務器上,接收客戶端請求并完成相應處理,存儲用戶信息和操作記錄的程序。
服務器端用Python開發,程序流程圖如圖5所示,啟動后創建線程,主線程運行后,讀取待連接和連接列表,創建傳輸線程并讀寫連接雙方的Socket套接字,根據口令驗證結果實現不同權限的數據指令傳輸直至收到退出請求為止。
TCP線程運行后,監聽TCP請求,在收到連接請求時,接收并保存Socket套接字中的用戶信息和數據。關鍵代碼如下:
//開啟TCP監聽
TcpListener.bind(IP,Port)
TcpListener.listen(10)
//獲取TCP請求中的套接字信息
sock,addr=TcpListener.accept()
HTTP線程運行后,監聽HTTP請求,收到請求時,利用aiohttp異步處理框架解析請求并根據HTTP協議中的操作類型進入相應的處理函數:
(1)登錄請求,解析請求并利用數據庫驗證用戶的賬號密碼等信息。驗證通過,存入登錄用戶列表并返回登錄成功;不通過,則返回登錄失敗。
(2)輪詢請求,獲取登錄用戶列表中該用戶的狀態和可連接的用戶名單,返回給客戶端。
(3)連接請求,解析請求中的連接雙方賬號,檢查雙方狀態,若雙方在線,將雙方存入待連接列表中,等主線程完成連接后返回連接成功;否則返回連接失敗。
(4)退出請求,解析請求中的用戶賬號,若處于連接狀態,關閉連接后從連接列表中刪去用戶信息,并返回退出成功;如果處于登錄狀態,則從登錄用戶列表刪去用戶信息,并返回退出成功;其余情況返回退出失敗。
(5)注冊賬戶請求,解析請求中待注冊的賬號和密碼,讀取數據庫判斷該用戶是否存在,若不存在,則將注冊信息寫入數據庫并返回注冊成功;否則返回注冊失敗。
關鍵代碼如下:
//創建web服務器
app = web.Application(loop=loop)

圖5 服務端程序流程
//將處理函數注冊進應用路徑
app.router.add_route(′POST′,′/remote/Login′,Login)
//創建HTTP監聽服務。
srv=yieldfrom loop.Createserver(handler,ip, port)
本文用MySQL建立“無人機遠程技術支持系統數據庫”,由用戶信息表和操作記錄表組成。用戶信息見表1,用來存儲和管理用戶信息。表中No是用戶編號,是主鍵;Name和Password是用戶姓名和密碼,提供處理用戶注冊、登陸、修改密碼等請求時的驗證功能;ModifyTime是用戶修改信息的時間;LoginTime是上次登錄系統的時間。
操作記錄見表2,用來存儲和管理用戶操作記錄。表中No是操作記錄編號,是表主鍵并自動加1;Action是注冊、登陸、連接等操作;Result是操作結果,1表示操作成功,0表示失敗;UserNo是用戶編號,是該表連接用戶信息表的外鍵。

表1 用戶信息表Users_Table

表2 操作記錄表Action_Table
以用戶登錄時的賬號密碼檢驗為例,關鍵代碼如下:
//連接數據庫
db=pymysql.connect(host="",user="",password="",db="remote")
//獲取游標、執行SQL語句
db.cursor.execute(sql)
//根據查詢結果判斷密碼是否正確
result=cursor.fetchone()
IsRight = (result==password) ? true:false
//關閉連接
db.close()
系統中傳輸的數據可分為以下3類:控制指令數據Ic、飛行狀態數據Iu以及系統操作數據Is,如果按混合產生的順序傳輸會導致重要數據等待傳輸的時間過長,影響系統實時性。為了保證重要數據的傳輸性能,需要根據實時性要求劃分數據優先級,用不同的隊列進行傳輸。Ic是人為產生的飛行控制、載荷控制等指令,由于無人機的控制特性與要求,實時性要求最高;Iu是無人機的飛行狀態、載荷狀態等數據,實時性要求僅次于Ic;Is是遠程技術支持系統操作數據,與飛行任務無直接關聯,實時性要求最低。由此可定義數據傳輸的優先級為:Ic>Iu>Is。
根據上述數據的特點,分別設計了TCP數據指令傳輸協議和HTTP操作信息傳輸協議。
數據指令傳輸協議用來傳輸Ic、Iu。如表3所示,協議包括幀頭、幀長度、類型編號、數據內容、校驗位、幀尾6個部分。其中,幀頭、幀長和幀尾保障TCP流式傳輸中單個數據包的完整性,校驗位保證正確性。ID用來區分協議的類型,數據內容用來承載數據或指令。

表3 數據指令協議幀結構
操作信息傳輸協議利用HTTP的請求-響應模型,具有簡單、靈活、無連接的特點,協議中URL用來表示登錄、連接等操作的類型,請求體用來搭載Is數據。以注冊賬號的代碼為例:
//URL標記為注冊
URL="http://1.1.1.1:9090/remote/Register";
//用POST的方式上傳注冊信息
newWebClient.UploadValues(URL,"POST",Register)
優先級傳輸方法保證了重要數據的最優傳輸,但當系統維持多個遠程技術支持時,單個可用帶寬b將減小,導致傳輸延遲增大甚至擁塞,這對低優先級數據的影響尤為明顯。在時隙T內完成全部數據的傳輸,需滿足下式
Ic+Iu+Is≤b×T
(1)
進一步分析數據傳輸情況可知:Ic和Is由人為操作產生,由于人為操作具有發生時的突變性和發生后的連續性,因此,下一時隙的數據量可由最近一次突變后歷史時隙的數據發送情況來預估;Iu由飛控采集模擬量轉換為數字量后按一定頻率fu發送,根據經驗,fu在5 Hz-50 Hz內可調。因此可以通過計算可用帶寬和預估Ic、Is數據量來調整頻率fu,優化帶寬占用,保證次要數據的可靠、實時傳輸。
云服務器固定帶寬為B,可用帶寬系數為β,遠程支持組數為m,系統采用平均的帶寬分配策略,則單個遠程支持的可用帶寬b可由下式計算
b=β×B/m
(2)
下一時隙的Iu數據量可由下式計算
Iu=fu×du×T
(3)
其中,du為Iu的單包數據量,根據前文設計的傳輸協議確定。

(4)
其中,Ii=qi×d,qi為服務器端記錄的收到包數,d為Ic和Is單包數據量。
求解上式的關鍵在于最近一次突變后的有效時隙數n和計算權重wi。以Is為例,定義時隙間的數據量變化率如下
(5)

(6)
設完成傳輸對預估的影響因子為ks∈(0.5,1),則未完成的影響因子為1-ks。那么,權重計算公式如下

(7)
Ic的預估同理,由于其優先級最高,Si恒等于1,ks恒等于1,則其計算權重為:w1=W,wi=(1-W)/(n-1),i=2,3,…,n。
算法步驟如下:
步驟1 確定服務器固定帶寬B,單包數據量dc、du、ds等常數,初始化β,W,perM,ks,fu和T等參數。
步驟2 按優先級順序和fu約束預處理產生的數據包,放入相應的傳輸隊列并標記序號。
步驟3 傳輸數據,記錄時隙T內3個隊列各自的發送包數pi和收到包數qi,再根據式(5)和式(6)計算數據變化率perc,i,pers,i和傳輸完成情況Sc,i,Ss,i,并更新對應的nc,ns。
步驟4 根據Sc,i,Ss,i,nc,ns和式(7)分別計算Ic和Is的過去時隙權重wc,i,ws,i。

步驟6 獲取當前在線遠程支持組數m,根據式(2)計算單個可用帶寬b。

步驟8 根據Iu,du和式(3)計算下一時隙的fu。若fu<5 Hz,進入步驟9,其余情況返回步驟2。
步驟9 取fu=5 Hz,若fu無法滿足任務要求,適當增大時隙到T=(1+λ)T,其中λ∈(0,1)為時隙調整因子。返回步驟2。
從以下方面對本文設計的無人機遠程技術支持系統進行實際飛行驗證。
(1)在兩臺計算機上啟動無人機地面站軟件,一臺作為支持者客戶端,另一臺連接無人機作為受支持者客戶端,注冊賬號后登錄服務器,選擇對方進行連接,開始遠程技術支持。依次驗證各個功能,如圖6所示,支持者端的地面站軟件可以觀察到和受支持者端一致的飛行姿態、位置、航點等數據;遠程無人機可以收到并執行支持端發送的調試參數和起飛等指令。表明系統運行穩定,實現了目標功能,滿足專業性和功能性要求。

圖6 系統測試截圖
(2)在上述實驗中,分別在受支持者和支持者客戶端用DateTime函數記錄了5000條協議數據包的發送時間SendTime和收到時間RecvTime,計算每個包傳輸用時的結果為:用時最大為36 ms,最小為9 ms,平均為13 ms。如圖7所示,對連續100個包的傳輸用時畫折線圖可知,用時較為穩定。由于人為連續操作軟件的最快反應時間在幾百毫秒左右,大于傳輸用時,因此傳輸對操作的延時影響很小,滿足實時性要求。

圖7 傳輸用時變化
(3)為模擬多組遠程技術支持并發,實驗中限制可用帶寬為15 000 bit/s,初始化算法參數,其中時隙T為1 s,Iu的初始頻率fu為25 Hz。分別在啟用和未啟用基于優先級的無人機數據自適應傳輸方法下,重復相同操作。如圖8所示,當帶寬受限時,該方法隨著Ic和Is數據量的變化自動調節fu,調節效果如圖9所示,以時隙內收到包數與發送包數的比例計算傳輸成功率,相比未啟用方法,該方法提高了數據傳輸成功率,尤其是低優先級數據。計算各隊列及全部數據的平均傳輸用時,如圖10所示,相比未開啟方法,該方法的傳輸用時更小,這在低優先級數據上尤為明顯。表明系統在多組并發導致可用帶寬減少的情況中,通過調整數據頻率仍能保證數據的傳輸性能,滿足實時性要求。

圖8 數據頻率調節效果

圖9 傳輸成功率對比

圖10 平均傳輸用時對比
本文針對無人機需求,設計并實現了基于云的無人機遠程技術支持系統。定制化開發了云服務器端和客戶端,利用云和網絡完成遠距離通信,并在此基礎上實現飛行監控、參數調整等多種遠程支持功能,相比通用遠程支持工具,專業性、功能性和實時性更好;根據數據傳輸特點,提出一種基于優先級的無人機數據自適應傳輸方法,相比常規傳輸方法,保證了重要數據的傳輸性能,在可用帶寬減少的情況下傳輸實時性和可靠性更好。通過實際飛行實驗,驗證了該系統運行正常,滿足功能需求和性能要求。