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.

TDA3: Radar Usecase Startup and Teardown

Part Number: TDA3

We would like to switch radar mode (use case) close to instantaneous as possible. Starting and stopping a radar usecase take 20 seconds operating through serial console window with multiple menu options. Ideally, starting up a radar use case should be supported through network control interface and should be as fast as it can be. Imagine there is a black out interval of 20 seconds before the car is able to see the environment again, that is not acceptable. I understand the vision SDK is not design for real-time mode switch, but can that time be reduced to acceptable level?

Thanks,

--Khai

  • Khai,

    in your usecase mode change, does the change involve a usecase flow change or only a change in the front end radar configuration?

    You can update the usecase to have both data flows and use the gate link for which portion of the usecase to flow the data through and merge link before the usecase output is . that way every mode change does not require a full usecase teardown and restart.

    You can refer to Processor SDK Vision , usecase: vision_sdk\apps\src\rtos\usecases\fast_boot_iss_capture_isp_simcop_pd_display for Gate link usage.

    Every mode switch would be only stopping , reconfiguring the AWR1243, setting the gate appropriately as to which usecase flow needs to run and then restarting the AWR1243. This would save mode switch time.

    Thanks and Regards,
    Piyali
  • Hi Piyali,

    What I would like to accomplish is to specify new chirp config when request radar mode change from network_ctrl interface. I am not sure if changing chirp config params require changing Link input params or not.

    If I use per Stanley’s suggestion in ChainsCommon_ar12xxChangeParameters() to change AWR chirp config, do I need to still tear down the Chain or call the affective Links'_Control functions to provide new parameters since FrameCfg contains parameters such as Loop Count and Range Bins?

    The goal is still to minimize radar mode switch time.

    Thanks,

    --Khai
  • Khai,

    When you are changing the chirp parameters, does this change the radar cube size in your configuration? If no, then the ChainsCommon_ar12xxChangeParameters is sufficient.

    Thanks and Regards,
    Piyali
  • Yes,

    The size of the cube will changed as dictated in the FrameCfg.

    Thanks,

    --Khai

  • Hi Piyali,

    The cube size needs to be set on the fly to the PkDetect link. How can that be done?

    Thanks,

    --KHai

  • Khai,

    You can work with 2 profiles for your usecase.
    One with the first configuration and first radar cube size and then the second with the second configuration and radar cube size.

    The FFT, peak detect and beam forming can hold up to 4 separate configurations corresponding to the 4 different profiles.

    You would also need to enable chirp profile in the AWR1243 configuration. This basically sends the profile number being used for every Rx antenna chirp. The FFT alg function then reads the profile and can use the appropriate radar cube dimensions.
    This information is passed to the next link of the peak detection as a meta data and then the peak detection can refer to its configuration corresponding to the 1st or 2nd profile.

    In your case you would be sending profile 1 when you are in the first mode and then once you switch using ChainsCommon_ar12xxChangeParameters, then the AWR1243 can start sending the data corresponding to profile 2. Given the CP data would change the processing chain can figure out which dimensions to use.

    You would need to initialize the algorithm functions with both profile information during create phase.

    Thanks and regards,
    Piyali
  • Hi Piyali,

    I understand what you are saying. I was able to switch on the fly while streaming between two pre-defined Bsp_Ar12xxConfigObj that contain everything there is to configure the AWR. Within it, only rlProfileCfg_t  and rlFrameCfg_t have different config params for the two radar modes.

    At the moment, the only parameter that is different between the two radar modes defined in the two Bsp_Ar12xxConfigObj is the doppler FFT size with one being 128 and the other being 64. The 4 RDM total frame size for 4RX @ 128 x 256 x 16 x 4 (4 bytes per complex sample) is 524288 bytes while the 4RX @ 64 x 256 x 16 x 4 is 262144 bytes. However, when mode switch happens, the total output bytes are the same for both radar modes. That means the cube size change didn't get into the Chain processing flow correctly. Below is my the ChainsCommon_ar12xxChangeParameters() function:

    Thanks,

    --Khai

    Int32 ChainsCommon_ar12xxChangeParameters(UInt32 algId, ChainsCommon_Ar12xxConfigOut *pCfgOut)
    {
    Int32 retVal = SYSTEM_LINK_STATUS_SOK;
    #if defined(AWR1243_METAWAVE_LRR_CONFIG)
    UInt32 numchirps;
    Vps_printf(" CHAINS: AR12xx Stopping Radar Sensor ...\n\r");
    retVal = Bsp_ar12xxStopRadar();
    UTILS_assert(SYSTEM_LINK_STATUS_SOK == retVal);
    Vps_printf(" CHAINS: AR12xx Radar Stopped ...\n\r");

    if (Bsp_ar12xxGetDeviceRevision() == 1U)
    {
    /* This sleep is required else the Radar re-start fails. Fixed in 0.8 DFP
    * with async event for stop frame. Worst case delay assumed with buffer.
    */
    Vps_printf(" CHAINS: Sleeping till frame is done ...\n\r");
    if (gChainsCommon_ar12xxFrameType == 1U)
    {
    UInt32 timeToSleep = 0U, i = 0U;
    for (i = 0U ; i < pCfgOut->numRadars ; i++)
    {
    if (timeToSleep < pCfgOut->radarParams[i].ar12xxConfig.frameCfgArgs->framePeriodicity)
    {
    timeToSleep = pCfgOut->radarParams[i].ar12xxConfig.frameCfgArgs->framePeriodicity;
    }
    }
    /* Normal Frame */
    BspOsal_sleep(CHAINS_AR1243_TIME_5NS_TO_MS(timeToSleep));
    }
    else
    {
    UInt32 timeToSleep = 0U, i = 0U;
    for (i = 0U ; i < pCfgOut->numRadars ; i++)
    {
    UInt32 time;
    time = pCfgOut->radarParams[i].ar12xxConfig.advFrameCfgArgs.frameSeq.subFrameCfg[0].subFramePeriodicity +
    pCfgOut->radarParams[i].ar12xxConfig.advFrameCfgArgs.frameSeq.subFrameCfg[1].subFramePeriodicity +
    pCfgOut->radarParams[i].ar12xxConfig.advFrameCfgArgs.frameSeq.subFrameCfg[2].subFramePeriodicity +
    pCfgOut->radarParams[i].ar12xxConfig.advFrameCfgArgs.frameSeq.subFrameCfg[3].subFramePeriodicity;
    if (timeToSleep < time)
    {
    timeToSleep = time;
    }
    }
    /* Advanced Frame */
    BspOsal_sleep(CHAINS_AR1243_TIME_5NS_TO_MS(timeToSleep));
    }
    }

    // Khai: The parameter changes below depends on the radarMode requested
    // over the network_ctrl interface

    /* Change the parameters as required. This is application specific. The consumer of this
    * function can choose to modify any parameter of their choice here corresponding to any Radar Device.
    * Below is just an example of setting one parameter of one Radar.
    */
    pCfgOut->radarParams[0].numTxAntenna[0] = pCfgOut->radarParams[0].ar12xxConfig.frameCfgArgs->chirpEndIdx + 1U;
    pCfgOut->radarParams[0].numRxAntenna[0] = Chains_ar12xxCountOnes(
    (UInt32)pCfgOut->radarParams[0].ar12xxConfig.dataFmtCfgArgs.rxChannelEn);
    pCfgOut->radarParams[0].radarWidth[0] = pCfgOut->radarParams[0].ar12xxConfig.profileCfgArgs[0].numAdcSamples;
    pCfgOut->radarParams[0].radarHeight[0] = pCfgOut->radarParams[0].ar12xxConfig.frameCfgArgs->numLoops;
    pCfgOut->radarParams[0].currProfileId = 0;

    numchirps = pCfgOut->radarParams[0].ar12xxConfig.frameCfgArgs->numLoops;
    ChainsCommon_CalcResolution(&pCfgOut->radarParams[0].ar12xxConfig.profileCfgArgs[0],
    &pCfgOut->radarParams[0].rangeRes[0],
    &pCfgOut->radarParams[0].velocityRes[0], numchirps);
    Vps_printf("ChainsCommon_ar12xxConfig: numChirps: %d", numchirps);
    Vps_printf("ChainsCommon_ar12xxChangeParameters:=======================> rangeBins: %d, nChirps: %d, rRes: %f, vRes: %f",
    pCfgOut->radarParams[0].radarWidth[0], pCfgOut->radarParams[0].radarHeight[0],
    pCfgOut->radarParams[0].rangeRes[0], pCfgOut->radarParams[0].velocityRes[0]);

    Vps_printf(" CHAINS: Reconfiguring AWR1243 Chirps Params...\n\r");
    retVal = Bsp_ar12xxConfigParams(BSP_AR12XX_CONFIG_PROFILE_PARAM |
    BSP_AR12XX_CONFIG_CHIRP_PARAM |
    BSP_AR12XX_CONFIG_FRAME_PARAM, 0U);
    Vps_printf(" CHAINS: Reconfigured Parameters Done...\n\r");

    Vps_printf(" CHAINS: AR12xx Re-starting Radar Sensor ...\n\r");
    retVal = Bsp_ar12xxStartRadar();
    UTILS_assert(SYSTEM_LINK_STATUS_SOK == retVal);
    Vps_printf(" CHAINS: AR12xx Radar Started ...\n\r");

    // POC: Remove the #else condition below for a complete radar reconfiguration
    #else
    /* Performing Dynamic Chirp Configuration of a single Radar */
    static UInt32 currProfile = 1U;
    const UInt32 radarNum = 0U;
    Int32 j = 0;
    rlDynChirpCfg_t dynChirp = {
    .reserved0 = (rlUInt8_t) 0,
    .chirpSegSel = (rlUInt8_t) 0,
    .programMode = (rlUInt16_t) 0,
    .chirpRow = {0}
    };
    // Khai: chirp reconfig on the fly switching between profile 0 and 1 at the moment
    Vps_printf(" CHAINS: AR12xx Chirp Reconfig Started ...\n\r");
    Vps_printf(" CHAINS: AR12xx Profile Id %d ...\n\r", currProfile);
    pCfgOut->radarParams[radarNum].currProfileId = currProfile;
    memcpy(&dynChirp.chirpRow, &pCfgOut->radarParams[radarNum].chirpRow[currProfile * 16], sizeof(rlChirpRow_t) * 16);
    retVal = Bsp_ar12xxReconfigChirp(radarNum, &dynChirp, 1);
    UTILS_assert(SYSTEM_LINK_STATUS_SOK == retVal);
    for ( j = 0; j < pCfgOut->radarParams[radarNum].ar12xxConfig.numChirpCfgArgs; j++)
    {
    pCfgOut->radarParams[radarNum].ar12xxConfig.chirpCfgArgs[j].profileId = currProfile;
    }
    Vps_printf(" CHAINS: AR12xx Chirp Reconfig Done ...\n\r");
    currProfile = (currProfile + 1) % pCfgOut->radarParams[radarNum].ar12xxConfig.numProfileCfgArgs;
    #endif
    return retVal;
    }

  • Hi Piyali,
    Thanks for the call this morning. I just ran the test with your suggested code change. It still didn't work when I send a command from network_ctrl to request mode switch. Looks like the EVE still doesn't know about us switching mode. Don't we need to somehow indicate to the EVE that we want it to use profile[1] param upon mode switch? How does it know. To me that part of the code we also need to modify.

    Looks like this block of code (which is currently commented out in #else) in chains_common_ar12xx.c is also needed for it to work? I don't necessarily know what dynChirp.chirpRow is for, however.
    Thanks,
    --Khai

    #else
    /* Performing Dynamic Chirp Configuration of a single Radar */
    static UInt32 currProfile = 1U;
    const UInt32 radarNum = 0U;
    Int32 j = 0;
    rlDynChirpCfg_t dynChirp = {
    .reserved0 = (rlUInt8_t) 0,
    .chirpSegSel = (rlUInt8_t) 0,
    .programMode = (rlUInt16_t) 0,
    .chirpRow = {0}
    };
    // Khai: chirp reconfig on the fly switching between profile 0 and 1 at the moment
    Vps_printf(" CHAINS: AR12xx Chirp Reconfig Started ...\n\r");
    Vps_printf(" CHAINS: AR12xx Profile Id %d ...\n\r", currProfile);
    pCfgOut->radarParams[radarNum].currProfileId = currProfile;
    memcpy(&dynChirp.chirpRow, &pCfgOut->radarParams[radarNum].chirpRow[currProfile * 16], sizeof(rlChirpRow_t) * 16);
    retVal = Bsp_ar12xxReconfigChirp(radarNum, &dynChirp, 1);
    UTILS_assert(SYSTEM_LINK_STATUS_SOK == retVal);
    for ( j = 0; j < pCfgOut->radarParams[radarNum].ar12xxConfig.numChirpCfgArgs; j++)
    {
    pCfgOut->radarParams[radarNum].ar12xxConfig.chirpCfgArgs[j].profileId = currProfile;
    }
    Vps_printf(" CHAINS: AR12xx Chirp Reconfig Done ...\n\r");
    currProfile = (currProfile + 1) % pCfgOut->radarParams[radarNum].ar12xxConfig.numProfileCfgArgs;
    #endif

  • Khai,

    After switching the modes can you please check if the CP data in the data that you are recieving from AWR1243 has a modified profile?

    You would need to check the first 32 bit of the data buffer. the format for CP is as below:

    The EVE FFT has the logic to understand which profile the data belongs to:

    currProfile = ((*(UInt32*)inBufAddr) >> 2U) & 0xFU;

    This is what it uses to find the radar cube dimensions for the current frame it has recieved.

    Thanks and Regards,

    Piyali

  • Hi Piyali,

    Before today's change where I had 2 separate profiles maintained in memory, Although it didn't get down to the EVE on mode switch during run time, at least when rebuilt the code with radar mode 2 (4x64x256 x 4bytes/sample), the EVE will get the correct cube size where the RDM frame size would be 1/4 MBs. 

    After today's code change, the EVE although get the cube size correctly where the currProfile param in the FFT is changed upon mode switch (I also printed out the FFT output cube size and it's correct), Network_TX however, always output buffer size is 0.5 MBs whether mode 1 is mode 2 is requested. I am not sure why it behaves as such. Do you have any idea?

    Thanks,

    --Khai

  • Hi Piyali,

    I am still puzzling how does EVE know to process profile 1 config upon mode switch request with the changes we made. I know there are now two profiles in the same ProfileCfg_t but still someone has to tell the EVE that we want it to use profile chirp config to process the frame data. I don't see this connection.
    Regards,
    --Khai
  • Another question i have is that now that we lumped the 2 independent profiles maintained in memory into 1, it looks like we can also do the same thing for FrameCfg_t and ChirpCfg_t based on the bigger ar12xx config object below with RED highlighted fields:

    Bsp_Ar12xxConfigObj gAr12xx_config =
    {
    .rfChanCfgArgs = {
    .rxChannelEn = (rlUInt16_t) (1<<CHAINS_RADAR_NUM_RX_ANTENNA) -1,
    .txChannelEn = (rlUInt16_t) (1<<CHAINS_RADAR_NUM_TX_ANTENNA) - 1,
    .cascading = (rlUInt16_t) 0x0,
    .bReserved = (rlUInt16_t) 0x0
    },
    .adcOutCfgArgs = {
    .fmt = {
    .b2AdcBits = CHAINS_AR1243_DATA_FORMAT_CONFIG,
    .b6Reserved1 = (rlUInt32_t) 0x0,
    .b8FullScaleReducFctr = (rlUInt32_t) 0x0,
    .b2AdcOutFmt = RL_ADC_FORMAT_COMPLEX_1X,
    .b14Reserved2 = (rlUInt32_t) 0x0
    },
    .reserved = (rlUInt16_t) 0x0
    },
    .dataFmtCfgArgs = {
    .rxChannelEn = (rlUInt16_t) (1<<CHAINS_RADAR_NUM_RX_ANTENNA) - 1,
    .adcBits = (rlUInt16_t) CHAINS_AR1243_DATA_FORMAT_CONFIG,
    .adcFmt = (rlUInt16_t) RL_ADC_FORMAT_COMPLEX_1X,
    .iqSwapSel = (rlUInt8_t) RL_DEV_I_FIRST,
    .chInterleave = (rlUInt8_t) RL_DEV_CH_NON_INTERLEAVED,
    .reserved = (rlUInt32_t) 0x0
    },
    .rfLpModeCfgArgs = {
    .reserved0 = (rlUInt16_t) 0,
    .lpAdcMode = (rlUInt16_t) RL_ADC_MODE_REGULAR
    },
    .chirpCfgArgs = gAr1243ChirpCfgArgs_RadarMode1,
    .numChirpCfgArgs = sizeof(gAr1243ChirpCfgArgs_RadarMode1)/sizeof(rlChirpCfg_t),
    .profileCfgArgs = gAr1243ProfileArgs_RadarMode1,
    .numProfileCfgArgs = sizeof(gAr1243ProfileArgs_RadarMode1)/sizeof(rlProfileCfg_t),
    .frameCfgArgs = &gAr1243FrmArgs_RadarMode1,
    .numFrameCfgArgs = sizeof(gAr1243FrmArgs_RadarMode1)/sizeof(rlFrameCfg_t),

    Is my thinking correct?

    Thanks,

    --Khai

  • Khai,

    Frame configuration should be one entry, others can be multiple entries.
    As discussed, EVE knows it is 2nd profile because the chirp config has profile ID 1.

    We fixed this problem today by using mulitple profiles and chirp configurations. During mode switch only chirp and frame configs are updated.

    The network Tx link was updated to use the output of FFT to set the size appropriately as when using 2 profiles the max size of the buffers are allocated. Blindly taking the whole buffer is not required, only effective size is required as given by the FFT metadata output

    Thanks and Regards,
    Piyali
  • Thank You much, Piyali. This Has resolved my problems