馬希超,魏志強,葛 珊
(中國電子科技集團公司第三研究所,北京 100015)
隨著無人直升機在偵察、監(jiān)視、消防及安保等領(lǐng)域的推廣應(yīng)用,無人機載光電吊艙的重要性日漸凸顯[1-2]。作為無人機的關(guān)鍵載荷之一,光電吊艙通常集成可見光相機、紅外熱像儀等傳感器,在采集并記錄實時視頻圖像的同時,可實現(xiàn)手動搜索、自動跟蹤及掃描等功能[3-4]。通常,光電吊艙裝載在無人直升機上,通過有線或無線傳輸鏈路與地面操控臺通信,下傳實時視頻流和設(shè)備狀態(tài)信息,并接收操控指令。運行于地面操控臺的顯控軟件用于實時解碼和顯示下傳的視頻,并實現(xiàn)人機交互[5]。
除光電吊艙本身的設(shè)備性能外,顯控軟件的設(shè)計和性能也對設(shè)備的使用體驗具有重要作用[6]。良好的軟件設(shè)計可最大程度地發(fā)揮硬件設(shè)備的性能,提高設(shè)備的易用性和靈活性。顯控軟件在運行中需同時處理視頻流的接收、解碼及顯示,設(shè)備狀態(tài)的接收、解析及顯示,控制指令的產(chǎn)生和發(fā)送,軟件界面人機交互,外設(shè)操縱桿動作響應(yīng)等多項任務(wù)。由于顯控軟件需要同時處理的流程和任務(wù)繁多,因此必須合理設(shè)計規(guī)劃多線程執(zhí)行方式,保證各項流程的實時并行處理。
為此,設(shè)計并實現(xiàn)了一種基于C++語言和Qt框架的無人機載光電吊艙顯控軟件,通過對多線程結(jié)構(gòu)和數(shù)據(jù)傳遞流程的合理設(shè)計,實現(xiàn)了軟件的高效、可靠、穩(wěn)定運行,同時具有友好易用的人機交互界面。
根據(jù)光電吊艙的設(shè)備功能、傳輸鏈路的連接形式以及實際使用的需要,顯控軟件應(yīng)具備如下功能:通過UDP 網(wǎng)絡(luò)通信方式接收包含視頻流的數(shù)據(jù)包,并從中提取可見光視頻流和紅外視頻流;實時解碼并顯示可見光視頻和紅外視頻;通過串口接收設(shè)備狀態(tài)數(shù)據(jù),并進行解析顯示;通過串口發(fā)送設(shè)備控制指令;響應(yīng)軟件界面的人機交互操作;響應(yīng)外設(shè)操縱桿的動作,并轉(zhuǎn)換為設(shè)備控制指令;其他軟件功能,如視頻記錄、數(shù)據(jù)記錄等。
根據(jù)功能要求進行軟件的功能模塊設(shè)計,如圖1 所示。各模塊的具體功能,如表1 所示。
圖1 功能模塊圖
表1 軟件模塊功能表
光電吊艙下傳的視頻流數(shù)據(jù)中既包含可見光視頻流也包含紅外視頻流,通過數(shù)據(jù)包幀頭的狀態(tài)字進行區(qū)分。因此,視頻流接收模塊需對數(shù)據(jù)包進行解析,將提取出的兩路視頻流分別存入各自的數(shù)據(jù)緩存中??梢?,光視頻解碼模塊和紅外視頻解碼模塊分別從各自的數(shù)據(jù)緩存中讀取視頻流數(shù)據(jù),通過解碼得到原始YUV 格式圖像,再經(jīng)過格式轉(zhuǎn)換得到可顯示的RGB 圖像數(shù)據(jù)并傳遞至顯示模塊,進而在軟件界面上實現(xiàn)實時顯示。
光電吊艙通過串口下傳設(shè)備狀態(tài)信息,由串口收發(fā)模塊接收并解析后,通過顯示模塊以字符或圖形方式顯示到軟件界面上。人機交互模塊和操縱桿響應(yīng)模塊捕獲操作人員通過軟件界面或操縱桿進行的操作動作,并生成對應(yīng)的控制指令,然后由串口收發(fā)模塊發(fā)送給光電吊艙。
軟件的開發(fā)環(huán)境為Visual Studio 2015,編程語言為C++,采用Qt 5.11作為圖形界面設(shè)計開發(fā)框架。軟件的界面設(shè)計如圖2 所示。
圖2 軟件界面設(shè)計
軟件界面分為傳感器控制、吊艙控制、記錄儀/激光控制、系統(tǒng)狀態(tài)顯示及軟件啟動控制等5 個主要區(qū)域,通過合理的功能分區(qū)提高軟件的易用性。此外,視頻顯示為單獨窗口,可切換可見光和紅外顯示,便于在多屏設(shè)備上實現(xiàn)分屏顯示。
軟件采用多線程方式實現(xiàn)各個功能模塊的并行處理,線程設(shè)計如圖3 所示。
圖3 線程設(shè)計
按照Qt 的規(guī)定,軟件界面的顯示和交互只能在主線程執(zhí)行,因此主線程運行顯示模塊和人機交互模塊。軟件啟動后,主線程開始運行,創(chuàng)建5 個子線程,以并行方式運行其余5 個功能模塊。線程之間的數(shù)據(jù)通信采用Qt 的signal/slot(即信號/槽)機制實現(xiàn)。該機制靈活安全,可有效避免大量采用全局變量可能引起的線程沖突和代碼混亂。在軟件停止運行前,主線程停止并銷毀各子線程,釋放占用的資源。
各個線程的創(chuàng)建均在功能模塊的類內(nèi)實現(xiàn)。以可見光視頻解碼模塊為例,首先定義解碼器類Decoder。該類繼承自QObject,具有signal/slot 機制。定義該類所需的成員變量和成員函數(shù),如開始解碼startDecoding、停止解碼stopDecoding 等。此外,需定義一個線程變量,即QThread thread,線程的起止函數(shù)分別為void start()和void stop()。在Decoder 類的構(gòu)造函數(shù)中需包含以下處理:
connect(&thread, &QThread::started, this,&Decoder::startDecoding);
connect(&thread, &QThread::finished, this,&Decoder::stopDecoding);
moveToThread(&thread);
上述代碼首先將線程的啟動信號started 和Decoder 的開始執(zhí)行函數(shù)startDecoding 相關(guān)聯(lián),將線程的停止信號finished 和Decoder 的結(jié)束執(zhí)行函數(shù)stopDecoding 相關(guān)聯(lián),然后將Decoder 類移動到線程thread 中執(zhí)行。這樣對于Decoder 類的對象如tvDecoder,在需要啟動解碼器時,只需啟動線程thread.start()。線程將發(fā)送啟動信號started,進而觸發(fā)startDecoding 函數(shù),開始在thread 線程中執(zhí)行。當需要停止解碼器時,只需調(diào)用thread.quit(),線程會發(fā)送停止信號finished,并觸發(fā)stopDecoding 函數(shù)執(zhí)行相關(guān)的釋放操作。
類內(nèi)線程創(chuàng)建處理不影響模塊類的各項功能實現(xiàn),簡化了程序設(shè)計,使得程序結(jié)構(gòu)清晰易懂。
軟件設(shè)計開發(fā)完成后,與光電吊艙配合搭載于某型無人直升機。吊艙與地面操控臺的通信采用無線傳輸鏈路,最大支持8 Mb/s 的傳輸速率。經(jīng)多次掛飛實驗驗證,軟件運行穩(wěn)定,可同時解碼并顯示可見光視頻和紅外視頻(視頻截圖如圖4 和圖5 所示),延遲較低,無明顯卡頓現(xiàn)象,同時設(shè)備狀態(tài)和控制指令收發(fā)正常,軟件無閃退、報錯等現(xiàn)象。
圖4 可見光視頻截圖
圖5 紅外視頻截圖
本文設(shè)計了一種用于無人機載光電吊艙地面操控臺的顯控軟件,可通過網(wǎng)絡(luò)通信接收視頻流數(shù)據(jù)并解碼顯示,通過串口收發(fā)設(shè)備狀態(tài)和控制指令。軟件采用C++語言和Qt 框架編程實現(xiàn),采用多線程架構(gòu),通過功能模塊類內(nèi)創(chuàng)建線程,并充分發(fā)揮signal/slot 機制的靈活性,使得程序結(jié)構(gòu)清晰易懂。經(jīng)掛飛實驗驗證,本軟件運行穩(wěn)定,各項功能正常有效,無閃退、報錯等現(xiàn)象。