This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
你好,工程师
使用AWR2944EVM的SDK,让板子工作在DDMA模式下。
1、参考文档“基于AWR2944的汽车雷达DDMA波形的原理和实现”page14,应该在作AzimuthFFT之前进行幅相补偿。SDK里的代码幅相补偿是在函数
azimPeakSamplem1 = *(uint16_t *)(&azimFFTMat[(m1Idx + DopIdxCurr * obj->cfarAzimFFTCfg.numAzimFFTBins) * obj->cfarAzimFFTCfg.azimFFTIOCfg.output.bytesPerSample]); azimPeakSample = *(uint16_t *)(&azimFFTMat[(AzimIdxCurr + DopIdxCurr * obj->cfarAzimFFTCfg.numAzimFFTBins) * obj->cfarAzimFFTCfg.azimFFTIOCfg.output.bytesPerSample]); azimPeakSamplep1 = *(uint16_t *)(&azimFFTMat[(p1Idx + DopIdxCurr * obj->cfarAzimFFTCfg.numAzimFFTBins) * obj->cfarAzimFFTCfg.azimFFTIOCfg.output.bytesPerSample]); currObjParams->azimPeakSamples[0] = azimPeakSamplem1; currObjParams->azimPeakSamples[1] = azimPeakSample; currObjParams->azimPeakSamples[2] = azimPeakSamplep1;
if(isValidObj){ /* Interpolate around peak */ peakIdxOffset = DPC_ObjDet_quadInterpAroundPeak(detObjList[objIdx].azimPeakSamples); /* Get the correct peak index */ peakIdx = detObjList[objIdx].azimIdx + peakIdxOffset; peakIdxRound = MATHUTILS_ROUND_FLOAT(peakIdx * scaleFac); if(peakIdxRound > lutSize/2){ peakIdxRound -= lutSize; } azimSinPhase = 2 * PI_ * ((float)peakIdxRound) / (lutSize * DX_DIVIDER);
/* First copy */ src = ((uint8_t *)dopplerFFTMat); src = src + (dopSubIdx * obj->dopplerDemodCfg.numBandsTotal + startIdxTxToCopy1) * cfg->staticCfg.numRxAntennas * bytesPerSample; dst = ((uint8_t *)destDetSubMat); dst = dst + (dopSubIdx * obj->dopplerDemodCfg.numBandsActive) * cfg->staticCfg.numRxAntennas * bytesPerSample; uint8_t * calib_dst = dst; //用于存储原来的初地址,用于校准 //uint8_t * calib_dst1 = dst; memcpy((void*)dst, (void *)src, cfg->staticCfg.numRxAntennas * bytesPerSample * numTxToCopy1); // memcpy(my2dFFTBuf+4096*demod_count+dopSubIdx*16*8,(void *)src,cfg->staticCfg.numRxAntennas * bytesPerSample * numTxToCopy1); /* Second copy */ if(numTxToCopy2 > 0){ src = ((uint8_t *)dopplerFFTMat); src = src + (dopSubIdx * obj->dopplerDemodCfg.numBandsTotal + startIdxTxToCopy2) * cfg->staticCfg.numRxAntennas * bytesPerSample; dst = ((uint8_t *)destDetSubMat); dst = dst + (dopSubIdx * obj->dopplerDemodCfg.numBandsActive) * cfg->staticCfg.numRxAntennas * bytesPerSample + cfg->staticCfg.numRxAntennas * bytesPerSample * numTxToCopy1; memcpy((void*)dst, (void *)src, cfg->staticCfg.numRxAntennas * bytesPerSample * numTxToCopy2); } // memcpy(my2dFFTBuf+4096*demod_count+dopSubIdx*128,(void *)calib_dst,128); int calib_ant_count; for(calib_ant_count=0;calib_ant_count<16;calib_ant_count++) { int32_t dst_curr_Im = *((int32_t*)calib_dst); //取虚部 int32_t dst_curr_Re = *((int32_t*)(calib_dst+4)); //取实部 int32_t dst_curr_Im_temp = dst_curr_Im; int32_t dst_curr_Re_temp = dst_curr_Re; dst_curr_Re = dst_curr_Re_temp*objDetObj->commonCfg.antennaCalibParams[2*calib_ant_count+1]-dst_curr_Im_temp*objDetObj->commonCfg.antennaCalibParams[2*calib_ant_count]; dst_curr_Im = dst_curr_Re_temp*objDetObj->commonCfg.antennaCalibParams[2*calib_ant_count]+dst_curr_Im_temp*objDetObj->commonCfg.antennaCalibParams[2*calib_ant_count+1]; memcpy(calib_dst+4,&dst_curr_Re,4); memcpy(calib_dst,&dst_curr_Im,4); calib_dst+=8;//指向下一个虚拟天线的值 }
你好
我把校准矩阵全置位0,发现已经检不出目标了,说明在cfar和local max检测之前已经使用了校准矩阵,请问dpc的处理流程是不是使用2DFFT的数据进行校准后(同时保留未校准的2DFFT数据),进行的角度维FFT,如果是这种情况就不需要在角度FFT前面额外加校准。
关于角度维FFT后的目标的能量值,我将能量值打印出来看了一下,当校准矩阵是0 1 0 1 01 .......时即不进行幅相校准时,目标的能量值为42000左右,这应该不是做完log2取对数后的结果,请问在进行角度维FFT时是否有对数据进行缩放?如果可以,请告诉我得到角度维FFT后能量值的具体步骤。
谢谢
你好
我把做为角度FFT后的数据和2DFFT之后的数据dump出来,使用matlab分析了一下,应该如上所说,在进行角度FFT之前进行了相位校准,同时保留了2DFFT的数据用于水平角和俯仰角的计算,直接使用2DFFT的数据和使用角度维FFT之后的数据分别进行1024点的插值,结果会有不同。为什么要使用角度维FFT得到的能量值求得的水平角和后面的由2DFFT数据经幅相校准得到的虚拟天线的值求俯仰角?由于角度维FFT结果的能量较abs(2DFFT)本来就存在误差,会使俯仰角存在误差?
另外,无法使用幅相校准矩阵将水平角在暗室正对角反时校准到零度的原因是在函数DPU_DopplerProcHWA_extractObjectList中,当AzimuthCurr = 0时,m1idx = -1%47 = -1导致后面memcpy时拷贝了错误的数据。将目标3个相邻天线上的值打印出来,会发现m1idx的能量值很低,不正确。将m1idx=-1时赋值为47已经可以在雷达正对角反时,经过幅相校准到0度了。
m1Idx = (AzimIdxCurr - 1) % obj->cfarAzimFFTCfg.numAzimFFTBins; p1Idx = (AzimIdxCurr + 1) % obj->cfarAzimFFTCfg.numAzimFFTBins; azimPeakSamplem1 = *(uint16_t *)(&azimFFTMat[(m1Idx + DopIdxCurr * obj->cfarAzimFFTCfg.numAzimFFTBins) * obj->cfarAzimFFTCfg.azimFFTIOCfg.output.bytesPerSample]); azimPeakSample = *(uint16_t *)(&azimFFTMat[(AzimIdxCurr + DopIdxCurr * obj->cfarAzimFFTCfg.numAzimFFTBins) * obj->cfarAzimFFTCfg.azimFFTIOCfg.output.bytesPerSample]); azimPeakSamplep1 = *(uint16_t *)(&azimFFTMat[(p1Idx + DopIdxCurr * obj->cfarAzimFFTCfg.numAzimFFTBins) * obj->cfarAzimFFTCfg.azimFFTIOCfg.output.bytesPerSample]);
你好,
关于这几个问题,我的理解如下,请参考
1. 你的理解是正确的,当前代码是在DPC_ObjDet_estimateXYZ中在求完水平到达角后再进行天线间的相位幅度矫正的,这和page 14中的图不一致。
2. P27 页中相关检测中的水平FFT和log2Abs计算是在HWA中完成的,这里HWA的Param设置参考函数DPU_DopplerProcHWA_configHwaCFARAzimFFT
有关HWA计算log2abs的方法和16 bits输出值的定义 可以参考
AWR294x Technical Reference Manual (Rev. A) (ti.com)
28.5.1.8 Core Computational Unit – FFT Engine – Magnitude and Log-Magnitude Post-Processing
3. 不太清楚你是在哪个位置读取水平角的,如果是在函数DPC_ObjDet_estimateXYZ以后读取的值,这个角度在这个函数中可能进行了重新计算。
4. 我理解在azimuth FFT之前进行天线的幅度相位补偿是可以的,出现的问题跟你的代码有问题。需要保证幅相矫正前后,数据的用小范围不发生变化。