• 雷达编程实战之静态杂波滤除与到达角估计


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

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

    目录

    静态杂波滤除

    到达角估计 


    静态杂波滤除

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

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

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

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

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

    1. /********************************************P2 mean******************************************************/
    2. #if 1
    3. // memset((uint8_t *)FFT1D_MEAN_ADDR,0,10*1024);
    4. BB_OPCLEAR(BB_CLEAR_P2);
    5. BB_OPGATE_EN(BB_GATE_P2);
    6. 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
    7. BB_P2_CFG1(USE_RANGE*NUM_BYTE32,NUM_BYTE32); //src0JumpInc,src0InterInc
    8. BB_P2_CFG2(bb_prep.cfg2.jumpInc,FFT1D_CACHE_ADDR); //src0IntraInc,src0BaseAddr
    9. BB_P2_CFG3(0,0); //src1JumpInc,src1InterInc
    10. BB_P2_CFG4(0,0); //src1IntraInc,src1BaseAddr
    11. BB_P2_CFG5(USE_RANGE*NUM_BYTE32,NUM_BYTE32); //dstJumpInc,dstInterInc
    12. BB_P2_CFG6(0,FFT1D_MEAN_ADDR); //dstIntraInc,dstBaseAddr
    13. BB_ISR_CLEAR(BB_ISR_P2_JUMP_END);
    14. BB_OPTRIG(BB_TRIG_P2);
    15. BB_waitISR(BB_ISR_P2_JUMP_END);
    16. BB_OPGATE_DIS(BB_GATE_P2);
    17. #if 0
    18. USART_Transmit_Bytes(&USART0,(uint8_t *)FFT1D_MEAN_ADDR,USE_RANGE*NUM_ANT*NUM_BYTE32);
    19. #endif
    20. #endif
    21. /*********************************************P2 minus+FFT2DANT1*********************************************/
    22. #if 1
    23. 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
    24. BB_P2_CFG1(0,0); //src0JumpInc,src0InterInc
    25. BB_P2_CFG3(0,0); //src1JumpInc,src1InterInc
    26. BB_P2_CFG5(0,0); //dstJumpInc,dstInterInc
    27. BB_P2_CFG6(0,BB_FFT_BASE); //dstIntraInc,dstBaseAddr
    28. 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
    29. BB_FFT_ZP_Clear();
    30. 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
    31. bb_regb_str->FFT_SRC_ZP00=fft2d_zp.txNum_zp0[CFAR_TX];
    32. bb_regb_str->FFT_SRC_ZP01=fft2d_zp.txNum_zp1[CFAR_TX];
    33. bb_regb_str->FFT_SRC_ZP02=fft2d_zp.txNum_zp2[CFAR_TX];
    34. bb_regb_str->FFT_SRC_ZP03=fft2d_zp.txNum_zp3[CFAR_TX];
    35. BB_FFT_CMD0(FFT_CMD0_CLEAR_IBUF);
    36. BB_OPCLEAR(BB_CLEAR_FFT|BB_CLEAR_P2);
    37. BB_OPGATE_EN(BB_GATE_P2|BB_GATE_FFT);
    38. sP2_Cfg2 =(uint64_t)bb_prep.cfg2.jumpInc<//src0IntraInc,src0BaseAddr
    39. sP2_Cfg4 =(uint64_t)(FFT1D_MEAN_ADDR+USE_RANGE*NUM_BYTE32*CFAR_ANT);//src1IntraInc,src1BaseAddr
    40. sFFT_Cfg2 = (uint64_t)bb_prep.cfg2.jumpInc<
    41. for(uint32_t rangeNow=1;rangeNow<=USE_RANGE;rangeNow++){
    42. bb_regb_str->P2_CFG2 = sP2_Cfg2;
    43. bb_regb_str->P2_CFG4 = sP2_Cfg4;
    44. bb_regb_str->FFT_CFG2 = sFFT_Cfg2;
    45. BB_FFT_CMD0(FFT_CMD0_CLEAR_IBUF);
    46. BB_ISR_CLEAR(BB_ISR_FFT_UNLOAD_END);
    47. BB_OPTRIG(BB_TRIG_P2);
    48. sP2_Cfg2 =((uint64_t)bb_prep.cfg2.jumpInc)<//src0IntraInc,src0BaseAddr
    49. sP2_Cfg4 =(uint64_t)FFT1D_MEAN_ADDR+USE_RANGE*NUM_BYTE32*CFAR_ANT+rangeNow*NUM_BYTE32; //src1IntraInc,src1BaseAddr
    50. sFFT_Cfg2 = ((uint64_t)bb_prep.cfg2.jumpInc)<//dstIntraInc,dstBaseAddr
    51. BB_waitISR(BB_ISR_FFT_UNLOAD_END);
    52. }
    53. BB_OPGATE_DIS(BB_GATE_P2|BB_GATE_FFT);
    54. #if 0
    55. for(uint32_t chirpNow=0; chirpNow
    56. USART_Transmit_Bytes(&USART0,(uint8_t *)FFT2D_CACHE_ADDR+USE_RANGE*CFAR_ANT*NUM_BYTE32+chirpNow*bb_prep.cfg2.jumpInc,USE_RANGE*NUM_BYTE32);
    57. }
    58. #endif
    59. #if 0 //abs
    60. USART_Transmit_Bytes(&USART0,(uint8_t *)&head[0],8);
    61. for (uint32_t chirpNow = 0;chirpNow
    62. USART_Transmit_Bytes(&USART0,(uint8_t *)(FFT2D_CACHE_ADDR+BB_ABS_OFFSET+chirpNow*bb_prep.cfg2.jumpInc+10*NUM_BYTE32),30*NUM_BYTE32);
    63. }
    64. #endif
    65. #endif

    到达角估计 

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

    • 3DFFT
    • DBF
    • MUSIC与Capon

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

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

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

    1. 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
    2. BB_P2_CFG1(0,NUM_RX*USE_RANGE*NUM_BYTE32); //src0JumpInc,src0InterInc
    3. BB_P2_CFG3(0,0); //src1JumpInc,src1InterInc
    4. BB_P2_CFG5(0,0); //dstJumpInc,dstInterInc
    5. BB_P2_CFG6(0,BB_FFT_BASE); //dstIntraInc,dstBaseAddr
    6. BB_P2_CFG7(P2_CFG7_SRC0CONJ_DIS,P2_CFG7_SRC0LSF_RIGHT,0,
    7. P2_CFG7_SRC1CONJ_DIS,P2_CFG7_SRC1LSF_RIGHT,0,
    8. P2_CFG7_DSTCONJ_DIS,P2_CFG7_DSTLSF_RIGHT,0);
    9. 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
    10. 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
    11. BB_FFT_Cfg2(NUM_BYTE32,FFT4D_CACHE_ADDR); //dstIntraInc,dstBaseAddr
    12. BB_FFT_ZP_Clear();
    13. bb_regb_str->FFT_SRC_ZP00=(uint64_t)0x07;
    14. bb_regb_str->FFT_SRC_ZP01=(uint64_t)0;
    15. BB_OPGATE_EN(BB_GATE_P2|BB_GATE_FFT);
    16. for(uint32_t targetNow=0;targetNowtargetNum;targetNow++)
    17. {
    18. 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
    19. BB_P2_CFG4(NUM_ANGLE*NUM_BYTE32,STEERING_VEC_PF_ADDR+frameRst->target[targetNow].d3Idx*NUM_BYTE32); //src1IntraInc,src1BaseAddr
    20. //FFT4D
    21. BB_OPCLEAR(BB_CLEAR_FFT|BB_CLEAR_P2);
    22. BB_FFT_CMD0(FFT_CMD0_CLEAR_IBUF);
    23. BB_ISR_CLEAR(BB_ISR_FFT_UNLOAD_END);
    24. BB_OPTRIG(BB_TRIG_P2);
    25. BB_waitISR(BB_ISR_FFT_UNLOAD_END);
    26. #if 0
    27. USART_Transmit_Bytes(&USART0, (uint8_t*)FFT4D_CACHE_ADDR,NUM_ANGLE*NUM_BYTE32);
    28. #endif
    29. frameRst->target[targetNow].d4Idx = BB_FFT_STA0_curMaxIdx;
    30. }
    31. BB_OPGATE_DIS(BB_GATE_P2|BB_GATE_FFT);

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


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

    ©2023 Yang Li. All rights reserved.

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

  • 相关阅读:
    c语言中数组的介绍(以及三子棋扫雷游戏程序逻辑的介绍!血书25000字!!!!!)
    Unity-2D边缘检测(描边效果)
    HMS Core Discovery第13期回顾长文——构建手游中的真实世界
    华清远见上海中心22071班--11.14作业
    时代变了,199 美元的 iPhone 都可以想了?
    MS做题记录
    SpringBoot进阶教程(七十七)WebSocket
    【web-music】vue3 开发遇到的问题
    【Java基础系列】第14章 Java图形编程
    Appium 环境搭建安装 java sdk 和 Android SDK
  • 原文地址:https://blog.csdn.net/geek_liyang/article/details/133218267