徐丞君
中國船舶第七一五研究所,浙江杭州 310012
被動定向聲納浮標是海軍反潛巡邏機[1]常用的一種搜索發(fā)現(xiàn)定位水下移動目標的武器設備,其具有作用距離遠、性價比高、隱蔽性強、部署靈活等優(yōu)點。被動定向聲納浮標水聽器具有方向性[2],可以將被動接受到的水下目標信息進行耦合,使其包含全向信息與方向信息,隨后通過DSP板將得到的信息經(jīng)過被動定向聲納浮標(Difar)算法計算即解復用以及互譜法,還原出目標的頻譜與方位信息,從而發(fā)現(xiàn)水下潛藏的目標及方位。
在海軍制式裝備中,被動定向聲納浮標算法一般運行在DSP(Digital Signal Processing)板上。但是DSP板的價格高、開發(fā)周期長[3],而且調(diào)試運行代碼也不易。一套運行于DSP板的Difar算法系統(tǒng)設備少則幾十萬,如此高昂的價格會嚴重影響模擬實驗訓練、數(shù)據(jù)回放需求方的采購數(shù)量,而PC平臺價格實惠,一臺幾萬的設備就可以達到相應的算力,同時由于在模擬實驗訓練、數(shù)據(jù)回放等情況下不會出現(xiàn)極端環(huán)境造成PC平臺宕機等問題,所以,如何在PC平臺搭建Difar算法處理系統(tǒng)是一個具有現(xiàn)實經(jīng)濟意義的任務。本文著重研究了一種基于lib庫文件形式,即將底層函數(shù)通過宏定義隔離生成lib庫文件的方式,高效地實現(xiàn)了Difar算法從DSP板到PC平臺的移植。
被動定向浮標水聽器包含兩部分:一部分是全向水聽器,可以得到全向信號;另一部分是兩個正交的偶極子傳感器沿著浮標的X軸與Y軸方向進行布置,對應于X信號,Y信號。不失一般性,假設目標頻率為Freq的單頻信號,目標與Y正軸夾角為θ,則全向、東西、南北信號分別為:
其中,Omi——全向信號;
Freq——目標頻率;
t——時間。
其中,EW——X信號,即東西信號;
θ——目標與Y正軸夾角。
其中,NS——Y信號,即南北信號。
假設,導相頻率為φ,導頻頻率為φ/2,地理正北方向與Y軸正軸夾角為σ,則復合以后的信號為:
其中,sig——復合后的信號;
φ——導相頻率;
σ——地理正北方向與Y軸正軸夾角。
當DSP信號處理板接收到復合信號以后就進行Difar算法運行,即先將復合信號經(jīng)過解復用,還原出原先的全向信號與東西信號、南北信號;接著通過互譜法得到目標頻率與方位,即假設求得的全向、東西、南北信號對應的頻率為FO(m),F(xiàn)EW(m),F(xiàn)NS(m),則全向與東西信號互功率譜為:
IEW——全向與東西信號頻率互譜求解后的結果。同理,全向與南北信號互功率譜為:
INS——全向與南北信號頻率互譜求解后的結果。則目標的方位與頻率之間關系為:
其中,?——INS(m)與IEW(m)之比的正切角。
Difar算法的程序框圖如圖1所示。首先,Difar算法需要先將被動定向浮標耦合得到的復合信號進行解復用,得到全向、東西、南北信號,然后進行互譜法,最后得到頻率與方位信息。
在將上一節(jié)的Difar算法用C語言實現(xiàn)過程中,會涉及到諸如FFT、數(shù)組拷貝、數(shù)學函數(shù)等接口的使用,而在Win系統(tǒng)VS開發(fā)環(huán)境與DSP如Ti6678板開發(fā)環(huán)境中,這些函數(shù)的接口調(diào)用方式是不同的。如數(shù)據(jù)搬移函數(shù),在Ti6678開發(fā)環(huán)境下,包含兩種函數(shù):
(1)void DSP_blk_mov_cn(const short* restrict x, short *restrict r, int nx)
(2)void DSP_blk_move(short* restrict x, short *restrict r, int nx)
此兩個函數(shù)的使用區(qū)別為:當nx>= 8; nx %8 =0時,采用DSP_blk_move函數(shù);否則采用DSP_blk_mov_cn函數(shù)。但是,在Win系統(tǒng)VS開發(fā)環(huán)境中,數(shù)據(jù)搬移函數(shù)[5]的聲明如下:
void* __cdeclmemcpy(
_Out_writes_bytes_all_(_Size) void* _Dst,
_In_reads_bytes_(_Size) void const* _Src,
_In_ size_t _Size
);
可見,此兩種平臺同一種功能的函數(shù)接口的形式完全不同。如果在Difar算法實現(xiàn)過程中直接調(diào)用相應平臺的接口函數(shù)的話,那么在移植過程中,會給程序員造成非常大的工作量以及很多不確定的困難,這對代碼的移植非常不利。所以,為了便于代碼從一個平臺移植到另一個平臺,可以將如上的函數(shù)接口進行封裝。封裝的該函數(shù)接口如下:
void VMovAptF(float* pfInput, float* pfOutput, int nDataLen)
{
#ifdef TI6678
int nDataLenTmp = 0;
nDataLenTmp = nDataLen*2;
if( (0 == (int)pfInput%8)&&( 0 == (int) pfOutput %8)&&( 0 == (int) nDataLen %8) )
{
DSP_blk_move((short*)pfInput, (short*)pfOutput, nDataLenTmp);
}
else
{
DSP_blk_move_cn((short*)pfInput, (short*)pfOutput, nDataLenTmp);
}
#endif
#ifdef VC
memcpy(pfOutput, pfInput, nDataLen*4);
#endif
}
從封裝的函數(shù)接口VMovAptF可知,通過宏定義可以隔離不同系統(tǒng)之間的接口差異,從而將這些底層接口分別在DSP平臺和VC平臺生成不同的lib文件,供上層的Difar算法使用。
Difar算法程序?qū)崿F(xiàn)流程圖如圖2所示。首先將Difar算法用到的底層函數(shù)進行l(wèi)ib庫文件形式封裝;然后再供Difar算法中的解復用,互譜法等算法調(diào)用;最后將結果送出進行顯示,實現(xiàn)Difar算法代碼在不同平臺之間的高效移植。
在Intel x86硬件服務器平臺進行驗證,CPU為i7-4770、內(nèi)存為32G、32核,操作系統(tǒng)為Windows,開發(fā)工具為Visual Studio 2010。
第一步:在VS中創(chuàng)建新項目,選擇創(chuàng)建靜態(tài)庫模式;
第二步:將封裝的函數(shù)置于AdaptFB.cpp中,同時創(chuàng)建包含函數(shù)聲明的文件AdaptFB.h;
第三步:編譯該項目,生成AdaptFb.lib文件;
第四步:在VS中新建空項目,然后在該項目中添加AdaptFB.h與lib庫文件,在main函數(shù)文件中,添加#pragmacomment(lib, "AdaptFB.lib")。該語句表示引用AdaptFB.lib庫,此時可以將Difar算法代碼直接移植過來。
將Difar代碼直接復制到Win系統(tǒng)的VS2010的新建項目中,主要需要修改如下部分,然后進行微調(diào),就可以實現(xiàn)代碼移植:
(1)由于DSP板不同核間通過內(nèi)存共享方式實現(xiàn)數(shù)據(jù)通信,而在Win系統(tǒng)的VS2010中,一個核的代碼可以移植到一個項目中,多個核的代碼則對應多個項目的代碼,不同項目之間沒有內(nèi)存共享機制,故不同項目之間進行數(shù)據(jù)交互,需要修改為:通過調(diào)用[6]。
HANDLE
WINAPI
CreateThread(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_ __drv_aliasesMem LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_opt_ LPDWORD lpThreadId
);
函數(shù)創(chuàng)建多個線程,采用UDP或者TCP方式進行網(wǎng)絡通信,從而實現(xiàn)不同項目之間的數(shù)據(jù)交互。如果一次數(shù)據(jù)長度超過65,536 Byte,則需要將一次數(shù)據(jù)分成多次進行收發(fā)。
(2)由于DSP板中可以指定指針變量存儲的地址空間以及大小,而Win系統(tǒng)的VS2010中不行,所以對于代碼中的此類指針變量需要定義相應的數(shù)組,將指針變量引用到相應的數(shù)組即可。
(3)調(diào)用Sleep函數(shù)時,該函數(shù)的參數(shù)需要進行多次嘗試,選擇一個最佳的值。
用模擬器投遞一枚浮標,頻率為300 Hz,方位為70°。將浮標的信號輸入Difar算法中,處理結果如圖3所示。
從圖3中可以看出,在頻率299.9 Hz處有一根亮線,表明Difar算法計算得到的頻率為299.9 Hz,與實際的設置的頻率300 Hz相差0.1 Hz。對于方位,預設值為70°,而Difar算法計算結果為69.8°,兩者相差0.2°,這在允許范圍之內(nèi)。故移植后的代碼Difar算法計算該情況正確。
接下來投遞一枚浮標,頻率為400Hz,方位為200°。將浮標的信號輸入Difar算法中,處理結果如圖4所示。
同理,從圖4中可以看到,399.6 Hz處有根亮線,表明Difar算法計算的頻率結果為399.6 Hz,與預設400 Hz,相差0.4 Hz。此種情況的頻率相差比上述情況的要大,原因在于頻率越高,在相同屏幕數(shù)據(jù)點數(shù)的情況下,頻率分辨率越低,所以屬于正常情況。而方位相差0.1°,在允許的范圍之內(nèi),故移植代碼計算該情況亦正確。
其他驗證情況見表1所示。
表1 驗證結果
從上圖分析可以看出,Difar算法在Win系統(tǒng)VS2010平臺下的計算結果與預設值是一致的,即預設值與實驗值之間的誤差在合理范圍之內(nèi)。將Difar算法從DSP到VS平臺的移植,大部分工作也僅僅在于生成底層接口函數(shù)lib庫,修改不同模塊之間數(shù)據(jù)交互的方式,而不需要對Difar算法進行修改與驗證,這使算法的移植節(jié)省了很大工作量。由此可見,基于lib庫文件形式,通過宏定義隔離消除不同操作系統(tǒng)底層函數(shù)聲明的差異形式實現(xiàn)Difar算法在不同系統(tǒng)上的高效移植是可行的。鑒于DSP板高昂的價格,以及PC電腦低廉的價格,此項工作具有十分重要的經(jīng)濟價值與現(xiàn)實意義。
本文對被動定向聲納浮標(Difar)算法原理進行了簡單介紹,對不同系統(tǒng)之間底層接口函數(shù)進行l(wèi)ib庫文件的封裝思路與方法進行了詳細的介紹;同時指出了Difar算法直接調(diào)用lib庫封裝后的底層函數(shù),可以高效地從DSP板到Win操作系統(tǒng)的代碼移植;最后進行了仿真實驗驗證。實驗結果表明,基于lib庫文件形式的Difar算法移植是高效的,同時,PC機與DSP板相比,價格上有顯著優(yōu)勢,表明本文提出的高效的代碼移植工作是非常有意義的,可在其他浮標算法移植過程中進行推廣使用。但是該方法涉及到不同數(shù)據(jù)之間的交互需要通過多線程的方式進行,需要調(diào)用Sleep函數(shù),而該函數(shù)參數(shù)不容易確定,取值小了會造成后續(xù)計算來不及,取值大了會多耗時,這方面需要進一步研究改進。