徐丞君
中國船舶第七一五研究所,浙江杭州 310012
被動定向聲納浮標是海軍反潛巡邏機[1]常用的一種搜索發現定位水下移動目標的武器設備,其具有作用距離遠、性價比高、隱蔽性強、部署靈活等優點。被動定向聲納浮標水聽器具有方向性[2],可以將被動接受到的水下目標信息進行耦合,使其包含全向信息與方向信息,隨后通過DSP板將得到的信息經過被動定向聲納浮標(Difar)算法計算即解復用以及互譜法,還原出目標的頻譜與方位信息,從而發現水下潛藏的目標及方位。
在海軍制式裝備中,被動定向聲納浮標算法一般運行在DSP(Digital Signal Processing)板上。但是DSP板的價格高、開發周期長[3],而且調試運行代碼也不易。一套運行于DSP板的Difar算法系統設備少則幾十萬,如此高昂的價格會嚴重影響模擬實驗訓練、數據回放需求方的采購數量,而PC平臺價格實惠,一臺幾萬的設備就可以達到相應的算力,同時由于在模擬實驗訓練、數據回放等情況下不會出現極端環境造成PC平臺宕機等問題,所以,如何在PC平臺搭建Difar算法處理系統是一個具有現實經濟意義的任務。本文著重研究了一種基于lib庫文件形式,即將底層函數通過宏定義隔離生成lib庫文件的方式,高效地實現了Difar算法從DSP板到PC平臺的移植。
被動定向浮標水聽器包含兩部分:一部分是全向水聽器,可以得到全向信號;另一部分是兩個正交的偶極子傳感器沿著浮標的X軸與Y軸方向進行布置,對應于X信號,Y信號。不失一般性,假設目標頻率為Freq的單頻信號,目標與Y正軸夾角為θ,則全向、東西、南北信號分別為:

其中,Omi——全向信號;
Freq——目標頻率;
t——時間。

其中,EW——X信號,即東西信號;
θ——目標與Y正軸夾角。

其中,NS——Y信號,即南北信號。
假設,導相頻率為φ,導頻頻率為φ/2,地理正北方向與Y軸正軸夾角為σ,則復合以后的信號為:

其中,sig——復合后的信號;
φ——導相頻率;
σ——地理正北方向與Y軸正軸夾角。
當DSP信號處理板接收到復合信號以后就進行Difar算法運行,即先將復合信號經過解復用,還原出原先的全向信號與東西信號、南北信號;接著通過互譜法得到目標頻率與方位,即假設求得的全向、東西、南北信號對應的頻率為FO(m),FEW(m),FNS(m),則全向與東西信號互功率譜為:

IEW——全向與東西信號頻率互譜求解后的結果。同理,全向與南北信號互功率譜為:

INS——全向與南北信號頻率互譜求解后的結果。則目標的方位與頻率之間關系為:

其中,?——INS(m)與IEW(m)之比的正切角。
Difar算法的程序框圖如圖1所示。首先,Difar算法需要先將被動定向浮標耦合得到的復合信號進行解復用,得到全向、東西、南北信號,然后進行互譜法,最后得到頻率與方位信息。

在將上一節的Difar算法用C語言實現過程中,會涉及到諸如FFT、數組拷貝、數學函數等接口的使用,而在Win系統VS開發環境與DSP如Ti6678板開發環境中,這些函數的接口調用方式是不同的。如數據搬移函數,在Ti6678開發環境下,包含兩種函數:
(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)
此兩個函數的使用區別為:當nx>= 8; nx %8 =0時,采用DSP_blk_move函數;否則采用DSP_blk_mov_cn函數。但是,在Win系統VS開發環境中,數據搬移函數[5]的聲明如下:
void* __cdeclmemcpy(
_Out_writes_bytes_all_(_Size) void* _Dst,
_In_reads_bytes_(_Size) void const* _Src,
_In_ size_t _Size
);
可見,此兩種平臺同一種功能的函數接口的形式完全不同。如果在Difar算法實現過程中直接調用相應平臺的接口函數的話,那么在移植過程中,會給程序員造成非常大的工作量以及很多不確定的困難,這對代碼的移植非常不利。所以,為了便于代碼從一個平臺移植到另一個平臺,可以將如上的函數接口進行封裝。封裝的該函數接口如下:
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
}
從封裝的函數接口VMovAptF可知,通過宏定義可以隔離不同系統之間的接口差異,從而將這些底層接口分別在DSP平臺和VC平臺生成不同的lib文件,供上層的Difar算法使用。
Difar算法程序實現流程圖如圖2所示。首先將Difar算法用到的底層函數進行lib庫文件形式封裝;然后再供Difar算法中的解復用,互譜法等算法調用;最后將結果送出進行顯示,實現Difar算法代碼在不同平臺之間的高效移植。

在Intel x86硬件服務器平臺進行驗證,CPU為i7-4770、內存為32G、32核,操作系統為Windows,開發工具為Visual Studio 2010。
第一步:在VS中創建新項目,選擇創建靜態庫模式;
第二步:將封裝的函數置于AdaptFB.cpp中,同時創建包含函數聲明的文件AdaptFB.h;
第三步:編譯該項目,生成AdaptFb.lib文件;
第四步:在VS中新建空項目,然后在該項目中添加AdaptFB.h與lib庫文件,在main函數文件中,添加#pragmacomment(lib, "AdaptFB.lib")。該語句表示引用AdaptFB.lib庫,此時可以將Difar算法代碼直接移植過來。
將Difar代碼直接復制到Win系統的VS2010的新建項目中,主要需要修改如下部分,然后進行微調,就可以實現代碼移植:
(1)由于DSP板不同核間通過內存共享方式實現數據通信,而在Win系統的VS2010中,一個核的代碼可以移植到一個項目中,多個核的代碼則對應多個項目的代碼,不同項目之間沒有內存共享機制,故不同項目之間進行數據交互,需要修改為:通過調用[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
);
函數創建多個線程,采用UDP或者TCP方式進行網絡通信,從而實現不同項目之間的數據交互。如果一次數據長度超過65,536 Byte,則需要將一次數據分成多次進行收發。
(2)由于DSP板中可以指定指針變量存儲的地址空間以及大小,而Win系統的VS2010中不行,所以對于代碼中的此類指針變量需要定義相應的數組,將指針變量引用到相應的數組即可。
(3)調用Sleep函數時,該函數的參數需要進行多次嘗試,選擇一個最佳的值。
用模擬器投遞一枚浮標,頻率為300 Hz,方位為70°。將浮標的信號輸入Difar算法中,處理結果如圖3所示。
從圖3中可以看出,在頻率299.9 Hz處有一根亮線,表明Difar算法計算得到的頻率為299.9 Hz,與實際的設置的頻率300 Hz相差0.1 Hz。對于方位,預設值為70°,而Difar算法計算結果為69.8°,兩者相差0.2°,這在允許范圍之內。故移植后的代碼Difar算法計算該情況正確。
接下來投遞一枚浮標,頻率為400Hz,方位為200°。將浮標的信號輸入Difar算法中,處理結果如圖4所示。
同理,從圖4中可以看到,399.6 Hz處有根亮線,表明Difar算法計算的頻率結果為399.6 Hz,與預設400 Hz,相差0.4 Hz。此種情況的頻率相差比上述情況的要大,原因在于頻率越高,在相同屏幕數據點數的情況下,頻率分辨率越低,所以屬于正常情況。而方位相差0.1°,在允許的范圍之內,故移植代碼計算該情況亦正確。
其他驗證情況見表1所示。



表1 驗證結果
從上圖分析可以看出,Difar算法在Win系統VS2010平臺下的計算結果與預設值是一致的,即預設值與實驗值之間的誤差在合理范圍之內。將Difar算法從DSP到VS平臺的移植,大部分工作也僅僅在于生成底層接口函數lib庫,修改不同模塊之間數據交互的方式,而不需要對Difar算法進行修改與驗證,這使算法的移植節省了很大工作量。由此可見,基于lib庫文件形式,通過宏定義隔離消除不同操作系統底層函數聲明的差異形式實現Difar算法在不同系統上的高效移植是可行的。鑒于DSP板高昂的價格,以及PC電腦低廉的價格,此項工作具有十分重要的經濟價值與現實意義。
本文對被動定向聲納浮標(Difar)算法原理進行了簡單介紹,對不同系統之間底層接口函數進行lib庫文件的封裝思路與方法進行了詳細的介紹;同時指出了Difar算法直接調用lib庫封裝后的底層函數,可以高效地從DSP板到Win操作系統的代碼移植;最后進行了仿真實驗驗證。實驗結果表明,基于lib庫文件形式的Difar算法移植是高效的,同時,PC機與DSP板相比,價格上有顯著優勢,表明本文提出的高效的代碼移植工作是非常有意義的,可在其他浮標算法移植過程中進行推廣使用。但是該方法涉及到不同數據之間的交互需要通過多線程的方式進行,需要調用Sleep函數,而該函數參數不容易確定,取值小了會造成后續計算來不及,取值大了會多耗時,這方面需要進一步研究改進。