关于热力图range heat map for zero Doppler数据来源的函数

求助,我想知道range heat map for zero Doppler数据是由哪个函数得到的,(类似这样的getAzimuthStaticHeatMap函数),我想知道在哪个DEMO里能看到,我查找了objectdetection.c,里面没有找到。

  • 你好,

    请参考\mmwave_sdk_03_05_00_04\packages\ti\datapath\dpc\dpu\aoaproc\src\aoaprocdsp.c里的函数AoAProcDSP_RangeAzimuthHeatmap。
  •  你好,AoAProcDSP_RangeAzimuthHeatmap函数如下:

    static inline int32_t AoAProcDSP_RangeAzimuthHeatmap(AOADspObj *aoaDspObj,
    volatile uint32_t *waitingTime)
    {
    volatile uint32_t startTimeWait;
    int32_t retVal = 0;
    cmplx16ImRe_t *radarCubeBase;
    DPU_AoAProcDSP_HW_Resources *res;
    DPU_AoAProcDSP_StaticConfig *DPParams;
    uint16_t rxAntIdx, rangeIdx, txAntIdx, rxAntIdxPing, txAntIdxPing, numAzimTxAnt;
    uint16_t nextTransferRxIdx, nextTransferRangeIdx, nextTransferTxIdx;
    uint32_t pingPongIdx, nextTransferIdx;
    uint8_t channel;
    cmplx16ImRe_t *inpBuf;
    cmplx16ImRe_t *bpmPingBuff;

    res = &aoaDspObj->res;
    DPParams = &aoaDspObj->params;
    radarCubeBase = (cmplx16ImRe_t *)res->radarCube.data;

    /*Use scratch1Buff to temporarily store ping data until pong data is available.
    Note that scratch1Buff is always bigger than pingBuf and scratch1Buff is only used on the
    angle estimation so it is safe to use it here. This is needed for BPM only.*/
    bpmPingBuff = (cmplx16ImRe_t *)res->scratch1Buff;

    /*Compute number of azimuth antennas. */
    numAzimTxAnt = DPParams->numTxAntennas;
    if(DPParams->numVirtualAntElev > 0 )
    {
    numAzimTxAnt--;
    }

    /* Reset ping/pong index */
    pingPongIdx = DPU_AOAPROCDSP_PING_IDX;

    /* Trigger first DMA.
    Note: EDMA ping/pong scheme should cover only azimuth antennas and must bring antenna data
    for consecutive TX antennas such that BPM can be decoded with one set of ping/pong buffers
    without the need to store extra ping/pong buffers.
    It should also support combinations of [1,2] TX antennas and [2,4] RX antennas.
    The scheme used here satisfies the requirements above and do not require reconfiguring the EDMA
    channels (except for source address). Therefore, once the DPU configures the EDMA channel, (one ping
    and one pong channel), the same channels can be used by the azimuth computation and AoA estimation
    by just changing the source addresses. */
    EDMA_setSourceAddress(res->edmaHandle,
    res->edmaPing.channel,
    (uint32_t) &radarCubeBase[0]);

    EDMA_startDmaTransfer(res->edmaHandle, res->edmaPing.channel);

    for (rangeIdx = 0; rangeIdx < DPParams->numRangeBins; rangeIdx++)
    {
    for (rxAntIdx = 0; rxAntIdx < DPParams->numRxAntennas; rxAntIdx++)
    {
    for (txAntIdx = 0; txAntIdx < numAzimTxAnt; txAntIdx++)
    {
    /* verify that previous DMA has completed */
    startTimeWait = Cycleprofiler_getTimeStamp();
    retVal = AoAProcDSP_waitInData (res, pingPongIdx);
    if(retVal != 0)
    {
    goto exit;
    }
    *waitingTime += Cycleprofiler_getTimeStamp() - startTimeWait;

    /*Find index in radar cube for next EDMA.*/
    nextTransferTxIdx = txAntIdx + 1;
    nextTransferRxIdx = rxAntIdx;
    nextTransferRangeIdx = rangeIdx;

    if(nextTransferTxIdx == numAzimTxAnt)
    {
    nextTransferTxIdx = 0;
    nextTransferRxIdx++;
    if(nextTransferRxIdx == DPParams->numRxAntennas)
    {
    nextTransferRxIdx = 0;
    nextTransferRangeIdx++;
    }
    }

    nextTransferIdx = (nextTransferTxIdx * DPParams->numRxAntennas * DPParams->numDopplerChirps +
    nextTransferRxIdx) * DPParams->numRangeBins + nextTransferRangeIdx;

    /*Last computation happens when nextTransferRangeIdx reaches numRangeBins.
    This indicates that, the current virtual antenna is the last one for (numRangeBins-1).
    Therefore, do not trigger next EDMA.*/
    if(nextTransferRangeIdx < DPParams->numRangeBins)
    {
    /* kick off next DMA */
    if (pingPongIdx == DPU_AOAPROCDSP_PONG_IDX)
    {
    channel = res->edmaPing.channel;
    }
    else
    {
    channel = res->edmaPong.channel;
    }

    EDMA_setSourceAddress(res->edmaHandle, channel,
    (uint32_t) &radarCubeBase[nextTransferIdx]);

    EDMA_startDmaTransfer(res->edmaHandle, channel);
    }

    inpBuf = (cmplx16ImRe_t *) &res->pingPongBuf[pingPongIdx * DPParams->numDopplerChirps];

    /* Remove static clutter? */
    if (aoaDspObj->dynLocalCfg.staticClutterCfg.isEnabled)
    {
    AoAProcDSP_clutterRemoval(DPParams, inpBuf);
    }

    if(DPParams->isBpmEnabled)
    {
    /*If BPM is enabled, need to store 2 sets of
    doppler bins (1 ping + 1 pong) so that BPM decoding can be done later on.
    The order of the EDMA assures that consecutive ping/pong buffers have the correct
    data for BPM decoding.*/

    if(pingPongIdx == DPU_AOAPROCDSP_PING_IDX)
    {
    memcpy((void*)&bpmPingBuff[0], inpBuf, DPParams->numDopplerChirps * sizeof(cmplx16ImRe_t));

    /*Store ping indexes to be used later when both ping and pong are available.*/
    rxAntIdxPing = rxAntIdx;
    txAntIdxPing = txAntIdx;
    }
    else
    {
    /*Decode BPM*/
    AoAProcDSP_azimuthHeatMapDecodeBPM(bpmPingBuff,/*Ping data*/
    inpBuf, /*Pong data*/
    DPParams->numDopplerChirps);

    /* Compute heatmap value from ping data*/
    AoAProcDSP_computeHeatMapVal(aoaDspObj,
    bpmPingBuff,
    rxAntIdxPing,
    txAntIdxPing,
    rangeIdx);

    /* Compute heatmap value from pong data*/
    AoAProcDSP_computeHeatMapVal(aoaDspObj,
    inpBuf,
    rxAntIdx,
    txAntIdx,
    rangeIdx);
    }
    }
    else
    {/*BPM not enabled*/

    AoAProcDSP_computeHeatMapVal(aoaDspObj,
    inpBuf,
    rxAntIdx,
    txAntIdx,
    rangeIdx);
    }

    pingPongIdx ^= 1;
    }/*txAntIdx*/
    } /* rxAntIdx */
    }/*rangeIdx*/

    exit:
    return retVal;
    }

    和下面的图的不一样,里面好像没有涉及到计算热力图Z值,下图中的就有

  • 你好,

    最终画图的显示转换是在GUI里做的。在visualizer GUI里有类似的代码。
  • 你好,
    请问visualizer GUI的源代码在哪里能下载呢?
    我想在本地完成heat map的计算,用的是这一段代码(在英文论坛里找到的):
    % range-azimuth static heat map, this is a 2D FFT array in range direction (x[numRangeBins][numVirtualAntAzim]), at doppler index 0, sized to azimuthStaticHeatMapSize elements of type cplx16ImRe_t
    function [Q, q] = getAzimuthStaticHeatMap(numTxAzimAnt, numRxAnt, numRangeBins, numAngleBins)
    datafile=fopen('azimuth.txt','r');
    [payload,~]=fscanf(datafile,'%d',inf);
    [r,c] = size(payload);
    if(r<c)
    payload = payload';
    end

    numVirtualAntenna = numTxAzimAnt * numRxAnt;
    q = payload;
    %q = q(1:2:end)+q(2:2:end)*256;
    %q(q>32767) = q(q>32767) - 65536;
    q = 1j*q(1:2:end)+q(2:2:end); %Imaginary first, real second
    q = reshape(q, numVirtualAntenna, numRangeBins);


    Q = fft(q, numAngleBins);

    %Near field corrected
    q1=q;
    q2=q;
    q1(5:8,:) = 0;
    q2(1:4,:) = 0;
    Q1 = fft(q1, numAngleBins);
    Q2 = fft(q2, numAngleBins);
    %Qcorr = Q1 + Q2.* nearEndCorr;

    figure('Name','Azimuth Static Heatmap')
    %Q = frame(frameIdx).azHeatmap.Q;
    NUM_ANGLE_BINS = size(Q,1);
    theta = asind([-NUM_ANGLE_BINS/2+1 : NUM_ANGLE_BINS/2-1]'*(2/NUM_ANGLE_BINS));
    range = rangeBin2Meters;
    posX = range' * sind(theta');
    posY = range' * cosd(theta');
    xlin=linspace(-floor(range(end)),ceil(range(end)),200);
    ylin=linspace(0,ceil(range(end)),200);
    [X,Y]=meshgrid(xlin,ylin);

    QQ = fftshift(abs(Q),1);
    QQ=QQ.';
    QQ=QQ(:,2:end);
    Z=griddata(posX,posY,QQ,X,Y,'linear');
    hAzimuthHeatmapPlot = surf(xlin,ylin,Z);
    shading INTERP
    view([0,90])
    axis('equal')
    axis([-ceil(range(end)) ceil(range(end)) 0 ceil(range(end))])
    xlabel('Range X-Axis [m]');
    ylabel('Range Y-Axis [m]');
    titleStr = sprintf('Frame %d, Azimuth Static Heatmap', frame(frameIdx).header.frameNumber);
    title(titleStr)
    return

    但是里面没有定义rangeBin2Meters,无法运行。
  • Chenming,

    如果你使用的是在在线版本的visualizer,你可以在Chrome浏览器访问相关地址后,按F12,看到相关源码。

    如果你使用的是离线版本的visualizer,请参考下面的论坛讨论,找到相关代码。

    e2e.ti.com/.../797254

  • 谢谢!已经找到了这段代码,原来是新版本用了js,还改了函数名