雷达编程实战之抗干扰与角度估计

雷达中经过混频的中频信号常常混有直流分量等一系列干扰源引入的固定频率杂波,我们称之位静态杂波,雷达信号处理需要把这些静态杂波滤除从而有效的提高信噪比,实现准确的目标检测功能。

目标的到达角估计作为常规车载雷达信号处理的末端,因为雷达阵列规模的限制等原因,是一个比较容易出错的环节,下文介绍了几种常见的到达角估计方法,并穿插介绍了俯仰角的一种计算方式,能够很好解决俯仰角错误估计导致的后续数据处理流程中将井盖与交通警示牌混淆的问题。俯仰角计算需要接收(发射)天线之间在水平面法线上有距离差。

目录

静态杂波滤除

到达角估计 


静态杂波滤除

信号处理算法中的静态杂波滤除主要有以下几种方法:

  • 零速通道置零法
  • 动目标显示(MTI)
  • 相量均值相消算法

零速通道置零法方法在2D-FFT(速度维FFT)后直接将零速附近通道置零,此操作意味着静止目标或者低速目标会直接消失,此操作意味着静止目标或者低速目标会直接消失,下图左中信号的直流分量幅值很高,目标的幅度被直流分量严重压制,在进行后续的CFAR处理之前最好能够将信号的直流分量去除,便于提高雷达的性能,右边是采用零通道置零法之后的R-V谱矩阵,可以看出,这种方法对直流分量有一定的抑制效果,但对目标的微多普勒信息有一定的损失。因此,采用这种最简单的方法需要考虑具体的应用场景。

MTI是指利用杂波抑制滤波器来抑制杂波,提高雷达信号的信杂比,以利于运动目标检测的技术。 

静止目标或者杂波在多Chirp数据间不会产生初始相位的变化,其均值会很大。如果目标是运动目标或者微动目标,由于目标运动会导致每个Chirp间的相位不同,其相量求和累加后会出现抵消(可以想象成正弦信号每个点相加为零),则其均值会很小,也就是说,对1DFFT结果中所有Chrip求得平均Chirp就可以得到静态杂波,然后用每Chirp减去刚才计算的均值chirp就可以得到目标回波信号,核心思想是求均值做差。我们项目中使用的是第三种方法,使用的是芯片中的硬核,具体的实现代码如下。

/********************************************P2 mean******************************************************/
#if 1
//					memset((uint8_t *)FFT1D_MEAN_ADDR,0,10*1024);
	BB_OPCLEAR(BB_CLEAR_P2);
	BB_OPGATE_EN(BB_GATE_P2);
	BB_P2_CFG0(NUM_ANT-1,USE_RANGE-1,NUM_CHIRP-1,P2_CFG0_DIV64,P2_CFG0_SUBMODE_CPX_SUM_MUL,P2_CFG0_MODE_ACC); //jumpCnt,interCnt,intraCnt,rsfBit,sub_mode,mode
	BB_P2_CFG1(USE_RANGE*NUM_BYTE32,NUM_BYTE32); //src0JumpInc,src0InterInc
	BB_P2_CFG2(bb_prep.cfg2.jumpInc,FFT1D_CACHE_ADDR); //src0IntraInc,src0BaseAddr
	BB_P2_CFG3(0,0); //src1JumpInc,src1InterInc
	BB_P2_CFG4(0,0); //src1IntraInc,src1BaseAddr
	BB_P2_CFG5(USE_RANGE*NUM_BYTE32,NUM_BYTE32); //dstJumpInc,dstInterInc
	BB_P2_CFG6(0,FFT1D_MEAN_ADDR); //dstIntraInc,dstBaseAddr
	BB_ISR_CLEAR(BB_ISR_P2_JUMP_END);
	BB_OPTRIG(BB_TRIG_P2);
	BB_waitISR(BB_ISR_P2_JUMP_END);
	BB_OPGATE_DIS(BB_GATE_P2);
	#if 0
		USART_Transmit_Bytes(&USART0,(uint8_t *)FFT1D_MEAN_ADDR,USE_RANGE*NUM_ANT*NUM_BYTE32);
	#endif
#endif

/*********************************************P2 minus+FFT2DANT1*********************************************/
#if 1
	BB_P2_CFG0(0,0,NUM_CHIRP-1,P2_CFG0_DIV1,P2_CFG0_SUBMODE_CPX_MINUS,P2_CFG0_MODE_ADD); //jumpCnt,interCnt,intraCnt,rsfBit,sub_mode,mode
	BB_P2_CFG1(0,0); //src0JumpInc,src0InterInc
	BB_P2_CFG3(0,0); //src1JumpInc,src1InterInc
	BB_P2_CFG5(0,0); //dstJumpInc,dstInterInc
	BB_P2_CFG6(0,BB_FFT_BASE); //dstIntraInc,dstBaseAddr
	BB_FFT_Cfg0(0,0,FFT2D_USE_A,FFT2D_USE_B,NUM_CHIRP-1,FFTPT_256,FFT_UNLOAD_EN,FFT_MODE_FORWARD); //rsfOutput,rsfInput,useA,useB,inPt,fftPt,unloadEn,mode   //useA>useB
	BB_FFT_ZP_Clear();
	BB_FFT_Cfg1(WIN_VEL1_ADDR,FFT_CFG1_OUTLSFEN_RIGHT,0,FFT_CFG1_INLSFEN_RIGHT,0,FFT_CFG1_WIN_SIZE_14BIT,FFT_CFG1_WIN_EN); //winBaseAddr,winSize,winEn
	bb_regb_str->FFT_SRC_ZP00=fft2d_zp.txNum_zp0[CFAR_TX];
	bb_regb_str->FFT_SRC_ZP01=fft2d_zp.txNum_zp1[CFAR_TX];
	bb_regb_str->FFT_SRC_ZP02=fft2d_zp.txNum_zp2[CFAR_TX];
	bb_regb_str->FFT_SRC_ZP03=fft2d_zp.txNum_zp3[CFAR_TX];
	BB_FFT_CMD0(FFT_CMD0_CLEAR_IBUF);
	BB_OPCLEAR(BB_CLEAR_FFT|BB_CLEAR_P2);
	BB_OPGATE_EN(BB_GATE_P2|BB_GATE_FFT);
	sP2_Cfg2 =(uint64_t)bb_prep.cfg2.jumpInc<<BB_BIT32_POS|(FFT1D_CACHE_ADDR+USE_RANGE*CFAR_ANT*NUM_BYTE32); //src0IntraInc,src0BaseAddr
	sP2_Cfg4 =(uint64_t)(FFT1D_MEAN_ADDR+USE_RANGE*NUM_BYTE32*CFAR_ANT);//src1IntraInc,src1BaseAddr
	sFFT_Cfg2 = (uint64_t)bb_prep.cfg2.jumpInc<<BB_BIT32_POS|(FFT2D_CACHE_ADDR+USE_RANGE*CFAR_ANT*NUM_BYTE32);
	for(uint32_t rangeNow=1;rangeNow<=USE_RANGE;rangeNow++){
		bb_regb_str->P2_CFG2 = sP2_Cfg2;
		bb_regb_str->P2_CFG4 = sP2_Cfg4;
		bb_regb_str->FFT_CFG2 = sFFT_Cfg2;

		BB_FFT_CMD0(FFT_CMD0_CLEAR_IBUF);
		BB_ISR_CLEAR(BB_ISR_FFT_UNLOAD_END);
		BB_OPTRIG(BB_TRIG_P2);
		sP2_Cfg2 =((uint64_t)bb_prep.cfg2.jumpInc)<<BB_BIT32_POS|(FFT1D_CACHE_ADDR+USE_RANGE*CFAR_ANT*NUM_BYTE32+rangeNow*NUM_BYTE32); //src0IntraInc,src0BaseAddr
		sP2_Cfg4 =(uint64_t)FFT1D_MEAN_ADDR+USE_RANGE*NUM_BYTE32*CFAR_ANT+rangeNow*NUM_BYTE32;	//src1IntraInc,src1BaseAddr
		sFFT_Cfg2 = ((uint64_t)bb_prep.cfg2.jumpInc)<<BB_BIT32_POS|(FFT2D_CACHE_ADDR+USE_RANGE*CFAR_ANT*NUM_BYTE32+rangeNow*NUM_BYTE32);//dstIntraInc,dstBaseAddr
		BB_waitISR(BB_ISR_FFT_UNLOAD_END);
	}
	BB_OPGATE_DIS(BB_GATE_P2|BB_GATE_FFT);
	#if 0
		for(uint32_t chirpNow=0; chirpNow<NUM_CHIRP; chirpNow++){
			USART_Transmit_Bytes(&USART0,(uint8_t *)FFT2D_CACHE_ADDR+USE_RANGE*CFAR_ANT*NUM_BYTE32+chirpNow*bb_prep.cfg2.jumpInc,USE_RANGE*NUM_BYTE32);
		}
	#endif
	#if 0 //abs
	USART_Transmit_Bytes(&USART0,(uint8_t *)&head[0],8);
	for (uint32_t chirpNow = 0;chirpNow<NUM_VEL;chirpNow++){
		USART_Transmit_Bytes(&USART0,(uint8_t *)(FFT2D_CACHE_ADDR+BB_ABS_OFFSET+chirpNow*bb_prep.cfg2.jumpInc+10*NUM_BYTE32),30*NUM_BYTE32);
	}
	#endif
#endif

到达角估计 

到达角估计有以下几种常见的方式:

  • 3DFFT
  • DBF
  • MUSIC与Capon

三维快速傅里叶变换算法是一种比较常见的算法,通过对雷达接收信号进行傅里叶变换,是通过MIMO多天线将角度信息转换到频域的方法。在频域中,可以通过对各个接收天线2DFFT后数据进行快速傅里叶变换从而得到目标的水平角,下面是它的Matlab代码实现,ADCBufCalib去除了速度维度的数据,只剩下了512点*16通道。

FFT1D_Buf=fft(squeeze(ADCBufCalib(:,1,:)));
FFT1D_Buf(1:10,:)=0;
FFT3D_Buf=fft(FFT1D_Buf,128,2);
FFT3D_BufABS=abs(FFT3D_Buf);    
figure(4);
meshz(fftshift(FFT3D_BufABS,2));

DBF是一种基于阵列信号处理的雷达到达角估计算法。DBF本质是构造视场范围内的各个角度的导向矢量,并用这些导向矢量分别去和阵列的回波信号相乘以得到各个角度下的能量值,通过寻找其中的极大值(目标所处方向的回波与导向矢量相干叠加,这些方向的能量会得到增强,而噪声是非相干的,能量得到增强的方向,对应极大值的位置,也即信号的方向)来得到实际回波的方向而达到测角的目的。我们可以利用这种方式来使用根据测得水平角的导向矢量与2DFFT水平角通道乘加增强之后,再对垂直通道进行4DFFT,选择出的最大值可以对应目标的俯仰角。下面是其用硬核实现的代码。 

BB_P2_CFG0(0,NUM_ANT_V-1,NUM_RX-1,P2_CFG0_DIV1,P2_CFG0_SUBMODE_CPX_SUM_MUL,P2_CFG0_MODE_MAC); //jumpCnt,interCnt,intraCnt,rsfBit,sub_mode,mode
BB_P2_CFG1(0,NUM_RX*USE_RANGE*NUM_BYTE32); //src0JumpInc,src0InterInc
BB_P2_CFG3(0,0); //src1JumpInc,src1InterInc
BB_P2_CFG5(0,0); //dstJumpInc,dstInterInc
BB_P2_CFG6(0,BB_FFT_BASE); //dstIntraInc,dstBaseAddr
BB_P2_CFG7(P2_CFG7_SRC0CONJ_DIS,P2_CFG7_SRC0LSF_RIGHT,0,
P2_CFG7_SRC1CONJ_DIS,P2_CFG7_SRC1LSF_RIGHT,0,
P2_CFG7_DSTCONJ_DIS,P2_CFG7_DSTLSF_RIGHT,0);
BB_FFT_Cfg0(0,0,FFT4D_USE_A,FFT4D_USE_B,NUM_ANT_V-1,FFTPT_128,FFT_UNLOAD_EN,FFT_MODE_FORWARD); //rsfOutput,rsfInput,useA,useB,inPt,fftPt,unloadEn,mode   //useA>useB
BB_FFT_Cfg1(WIN_RANGE_ADDR,FFT_CFG1_OUTLSFEN_RIGHT,0,FFT_CFG1_INLSFEN_RIGHT,0,FFT_CFG1_WIN_SIZE_14BIT,FFT_CFG1_WIN_DIS); //winBaseAddr,winSize,winEn
BB_FFT_Cfg2(NUM_BYTE32,FFT4D_CACHE_ADDR); //dstIntraInc,dstBaseAddr
BB_FFT_ZP_Clear();
bb_regb_str->FFT_SRC_ZP00=(uint64_t)0x07;
bb_regb_str->FFT_SRC_ZP01=(uint64_t)0;
BB_OPGATE_EN(BB_GATE_P2|BB_GATE_FFT);
for(uint32_t targetNow=0;targetNow<frameRst->targetNum;targetNow++)
{
	BB_P2_CFG2(USE_RANGE*NUM_BYTE32,FFT2D_CACHE_ADDR+frameRst->target[targetNow].d1Idx*NUM_BYTE32+frameRst->target[targetNow].d2Idx*bb_prep.cfg2.jumpInc); //src0IntraInc,src0BaseAddr
	BB_P2_CFG4(NUM_ANGLE*NUM_BYTE32,STEERING_VEC_PF_ADDR+frameRst->target[targetNow].d3Idx*NUM_BYTE32); //src1IntraInc,src1BaseAddr
	//FFT4D
	BB_OPCLEAR(BB_CLEAR_FFT|BB_CLEAR_P2);
	BB_FFT_CMD0(FFT_CMD0_CLEAR_IBUF);
	BB_ISR_CLEAR(BB_ISR_FFT_UNLOAD_END);
	BB_OPTRIG(BB_TRIG_P2);
	BB_waitISR(BB_ISR_FFT_UNLOAD_END);

	#if 0
		USART_Transmit_Bytes(&USART0, (uint8_t*)FFT4D_CACHE_ADDR,NUM_ANGLE*NUM_BYTE32);
	#endif
	frameRst->target[targetNow].d4Idx = BB_FFT_STA0_curMaxIdx;
}
BB_OPGATE_DIS(BB_GATE_P2|BB_GATE_FFT);

MUSIC与Capon:这两种方法对于大规模数据的处理速度较慢,这里就暂不介绍了,有兴趣的朋友可以自己找些资料研究一下。


十六宿舍 原创作品,转载必须标注原文链接。

©2023 Yang Li. All rights reserved.

欢迎关注 『十六宿舍』,大家喜欢的话,给个👍,更多关于嵌入式相关技术的内容持续更新中。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值