信号处理_Matlab
- AD数据
- 幅相校准
- 1DFFT
- 2DFFT
由射频前端发射、接收信号,至获得目标径向距离、径向速度、径向角度、RCS等目标属性信息,这个过程,我们谓之,FMCW毫米波雷达信号处理流程。
VCO为压控振荡器(Voltage Controlled Oscillator),产生调频信号通过发射天线在视场角内发射调频信号,接收目标反射的信号通过混频器(mixer)之后,经过带通滤波器,产生中频信号。我们本篇博客,通过对AD采样之后的数据进行处理,来模拟在硬件板卡上的信号处理流程。
AD数据
通过板卡上的调试通信口(串口,网口等),将在暗室内采集到的目标多帧AD数据发送到上位机中,保存为flash_data_0.bin文件,通过下述代码打开文件并将数据导入。
%% data
clear all;
fid = fopen('.\data\flash_data_0.bin', 'rb');
[RecDataBuff] = fread(fid);
fclose(fid);
下面准备后续信号处理流程需要的参数。我们采集的数据是采用了4发4收16个虚拟通道,每个通道对进入的中频信号采样了512个点,一个点2Byte,一个虚拟通道1KByte数据,16个虚拟通道一chrip数据为16KByte,64chrip数据组成一帧数据。我们提前将各通道之间的福相误差(以第一个通道为基准)存储在amp_calib.mat和phase_calib.mat中(16*1double),导入之后根据一帧数据的结构形成一个512(point)x64(chrip)x16(ANT) complex double格式的数组calib_Ap。
%% param
numChirp = 64;
numPT = 512;
numANT = 16;
Head = 0;
numByte = 2;
len = numPT*numChirp*numANT*numByte;
frameNum = floor(length(RecDataBuff)/(len+Head));
load('amp_calib.mat');
load('phase_calib.mat');
sAmp=amp_calib(1:16);
sPhase=phase_calib(1:16);
commonCfg.numSamp = numPT;
commonCfg.numAnt = numANT;
commonCfg.numChirp = numChirp;
calib_Ap = (sAmp.*exp(1j * sPhase)).';
calib_Ap = repmat(reshape(repmat(calib_Ap, commonCfg.numSamp, 1), [commonCfg.numSamp, 1, commonCfg.numAnt]), 1, commonCfg.numChirp, 1);
然后我们将之前导入的AD数据根据采集数据的板卡做一些调整,将每一帧的数据还原回来。包括字节序(大小端)的调整等。将其存储到ADCBuf(512x64x16 double)。
%% ADdata
for frameNow = 1:frameNum
FlashReadBuf =RecDataBuff((frameNow-1)*(len+Head)+Head+1:frameNow*(len+Head));
for i=1:len/8
FrameDataBuff((i-1)*4+1) = bitshift(FlashReadBuf((i-1)*8+7),8)+FlashReadBuf((i-1)*8+8);
FrameDataBuff((i-1)*4+2) = bitshift(FlashReadBuf((i-1)*8+5),8)+FlashReadBuf((i-1)*8+6);
FrameDataBuff((i-1)*4+3) = bitshift(FlashReadBuf((i-1)*8+3),8)+FlashReadBuf((i-1)*8+4);
FrameDataBuff((i-1)*4+4) = bitshift(FlashReadBuf((i-1)*8+1),8)+FlashReadBuf((i-1)*8+2);
end
for i=1:length(FrameDataBuff)
if(FrameDataBuff(i)>32767)
FrameDataBuff(i) = FrameDataBuff(i)-65536;
end;
end
for k=1:numChirp
for j=1:numANT
ADCBuf(:,k,j)=FrameDataBuff(1+numPT*(j-1)+numPT*numANT*(k-1):numPT*j+numPT*numANT*(k-1));
end
end
figure(3);
plot(ADCBuf(:,:,1));
hold on;
for j=2:numANT
plot(ADCBuf(:,:,j)+1024*(j-1));
end
hold off;
ylim([-1024 1024*numANT]);
disp(frameNow);
将对16(4T4R)个虚拟通道的中频信号,进行采样的AD数据画图,结果如下。
幅相校准
前文提到的amp_calib.mat和phase_calib.mat为事先准备好的幅相校准所需用的参考值。这个参考值也可以简单通过对暗室目标的AD数据进行下面的运算来获取。
for k=1:numAnt
calibAmp(k) = dtmp(1) / dtmp(k);
end
for k=1:numAnt
calibPhase(k) = dtmp(1) - dtmp(k);
end
我们用这个校准参数也很简单,就是将准备好的ADCBuf与calib_Ap点乘即可。
%% calib
ADCBufCalib=ADCBuf.*calib_Ap;
1DFFT
我们下边对一帧数据中的一chrip的AD数据按列做FFT运算(针对16个虚拟通道,分别做512个点距离维的FFT),输出结果为FFT1D_Buf(512x16 complex double)。然后将FFT1D_Buf中的前10个点(距离单元)置零(消除直流分量的影响),对FFT1D_Buf中的数据按行(不同天线,角度维)分别进行128点(16+112)和(4+124)的FFT(补偿测距的精度),然后对两个FFT的结果进行abs运算得到FFT3D_BufABS和FFT3D_BufABS1,然后对两个abs结果左右两半部分进行交换。
%% FFT1D
FFT1D_Buf=fft(squeeze(ADCBufCalib(:,1,:)));
FFT1D_Buf(1:10,:)=0;
FFT3D_Buf=fft(FFT1D_Buf,128,2);
FFT3D_BufABS=abs(FFT3D_Buf);
FFT3D_Buf1=fft(FFT1D_Buf(:,1:4),128,2);
FFT3D_BufABS1=abs(FFT3D_Buf1);
figure(4);
meshz(fftshift(FFT3D_BufABS,2));
figure(5);
meshz(fftshift(FFT3D_BufABS1,2));
下面左边是FFT3D_BufABS,右边是FFT3D_BufABS1。
2DFFT
我们下边对第一个通道的,64chrip(一帧)数据按列做FFT运算(针对第一个通道,分别对64Chrip数据做512点距离维的FFT),取前256个FFT结果点(共轭对称)得到FFT1D_Buf(256x64 complex double),然后对FFT1D_Buf进行取均值运算,得到每一行(64chrip)均值的列向量。
FFT1D_Buf=fft(squeeze(ADCBuf(:,:,1)));
FFT1D_Buf=FFT1D_Buf(1:numPT/2,:);
FFT1D_Mean=mean(FFT1D_Buf,2);
figure(11);
plot(abs(FFT1D_Mean));
FFT1D_Mean图如下:
然后使用FFT1D_Buf中每一天线通道不同的chrip数据减去FFT1D_Mean数据(消除直流分量以及随机噪声,若针对静止物体,因各chrip数据相位不同,不要此操作),然后沿着速度维(按照行向量)进行FFT操作,再进行abs运算求模,最后将零频分量移动到数组中心。
FFT1D_Old=FFT1D_Mean;
for chirpNow=1:numChirp
FFT1D_Minus(:,chirpNow)=FFT1D_Buf(:,chirpNow)-FFT1D_Old;
end
FFT2D_Buf=fft(FFT1D_Minus,[],2);
FFT2D_ABS=abs(FFT2D_Buf);
figure(2)
meshz(fftshift(FFT2D_ABS,2));
pause(0.1);
end
disp('over');
figure(2)图如下(静止目标):