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.

Compiler/OPT9221: Calculating depth from phase in de-aliasing mode

Part Number: OPT9221
Other Parts Discussed in Thread: OPT8241,

Tool/software: TI C/C++ Compiler

Hello TI!

We made our-self board based on your demo-board OPT8241.

I set long rang config for one. The main config parameters are:

ind_freq_data_en = false
use_dealiasing_mode = true
ma = 2
mb = 3
ka = 2
kb = 1
dealiased_ph_mask = 3
phy_test_enable = false
ind_freq_data_sel = false
illum_en_early = false
illum_mod_early = false
intg_duty_cycle = 18
mod_m1 = 20
mod_m_frac1 = 0
mod_m2 = 15
mod_m_frac2 = 0
mod_n1 = 2
mod_n2 = 2
mod_ps1 = 1
mod_ps2 = 0
tg_dis = false
pix_cnt_max = 133333
sub_frame_cnt_max = 2
quad_cnt_max = 6

I try to convert phase to depth.

Unambiguous range R = c/(2*f_eff) whre f_eff = GCD(f1, f2),  f1= 40 MHz,  f2 = 60MHz.

Conversion phase to map is:

d = phase*R*2^(5 - dealiased_ph_mask)  /  ( ma*mb*2^12 ) 

like formula (30) from datasheet but adopted to f1= 40 MHz,  f2 = 60MHz case.

By this way max distance is about 5m.

Where can be mistake?

Thanks!

  • Semenov,

    When dealiased_ph_mask is used, the output phase is masked and equation (26) from the OPT9221 datasheet must be used for calculation of depth.

    This does not lead to a reduction in the actual range of calculation, but the resolution. For instance, with the settings that you have provided, distance of 7.5 m would correspond to a phase output of 3072 LSBs. A distance of 5 m would correspond to a phase output of 2048 LSBs.

    I hope this makes it clear.

    Suramya
  • Suramya, Thank you for your answer!

    for my case I set dealiased_ph_mask = 3.

    But I got raw phase values from range 0 to 4095 it is seem ok.

    In datasheet it is written that output phase data are 12-bit, I do so:

    unsigned short phase = 0;
    
    // some code
    
    
    phase = phase <<4;
    phase = phase >>4;
    
    

    for erasing flags data.

    But how can I see that raw phase data have valid values?

    And Is it possible to use this formula for calculating depth:

    depth = phase*R/(2*f_eff)?

    if not, so why it is need to calculate firstly de-aliased phase, and only after depth?

    As I understand dealiased_ph_mask operates with phase data into the chip...

  • Hi Semenov,

    The calculations in the OPT9221 chipset are done based on the dealiased phase, which is why a direct formula for depth won't work.

    If you have a calibrate camera, a flat wall parallel to the camera should look flat and show the correct depth for each and every pixel. This ensures that the data you're getting is correct.

    Since OPT9221 gives out phase which is internally masked, you'll get different range of output for different dealiased_ph_mask. You may want ot check if the output you're getting is 0-4095 for a mask of 3. If that is the case, there must be some error in the register settings as a dealiased_ph_mask of 3 with ma and mb of 2 and 3 respectively cannot give a phase output of more than 3072.

    Suramya
  • Suramya, Thank you for tour answer!

    May be it is more clear for me.

    But for dealiased_ph_mask = 3,  max phase value is 2048

    temp = (4095 * 2* 3)>> (5 - 3) = 6144 = 1100000000000 (in binary )

    1100000000000 &111111111111 = 100000000000 =2048 (in decimal)

    so, is it right conversion for raw phase data:  (1)

    unsigned short phase = 0;
    
    // some code
    
    
    phase = phase <<4;
    phase = phase >>4;

    I checked values for register: 5C 02 0x101800; 5C 03 0x900C42    (2)

    use_dealiasing_mode = true

    ind_freq_data_en = false
    ma = 2
    mb = 3
    ka = 2
    kb = 1
    dealiased_ph_mask = 3

    Where do I make mistake (1), (2) or... ?

  • Semenov,

    Your calculations are correct. Sorry for the error.

    (1) For getting the phase, can't you do (phase & 0xfff) for removing the flag data? This shouldn't make a difference, but just to be sure that the handling of the bits is correct, please use the &.

    (2) I think the values are interchanged for 0x5c 0x2 and 0x5c 0x3. The settings look correct.

    Suramya
  • Suramya, Thank you for tour answer!

    I done as you advised me.

    unsigned short phase = 0;
    
    // some code
    
    
    phase = (phase&0xFFF);

    but any way phase values are more 2048 and it is seem have range [0, 4095]

    I checked my code and did not found anything wrong...

    // some code
    arrayDpt[i] = (unsigned short)phase;
    // some code
    
        imgDpt = cv::Mat::zeros(f_size.height, f_size.width, CV_16UC1);
    
    //some code
    
    memcpy((char*)imgDpt.data + 640 * fragment_gl, arrayDpt, 320 * sizeof (unsigned short)); 
    
    // copy frame fragment to openCV matrix
    
    // I output in log some 1 per 100 frames 
    
    printf("phase at cx, cy = %hu\n", imgDpt.at<unsigned short>(cy, cx) );

    where can be mistake?

    may be register description has mistake?

    And while ind_freq_data_en = true, phase values can be found in range [0, 4095] for f1 and f2 frequencies?

  • for example, R = 7.5 m, dealiased_ph_mask = 3. (if all is OK with raw phase data)
    so phase = 2047 corresponds distance 7.5 but using formula (26),
    distance will be ~2.5 m but not ~7.5m

    or may be Is there some intermediate formula when together with (26)  from phase = 2047 it is possible to get distance = 7.5m?

  • Semenov,

    With a dealiased_ph_mask of 3, under these settings, it seems that there is a loss of resolution and the maximum depth that can be computed is, indeed 2.5 m.If you calculate starting with a distance of 2.5 m, you'll get a dealiased phase of 2047. It's similar to the phase output of 7.5 m. 

    Beyond this value, phase is wrapping around (because of the mask). I suggest you to use a mask of 2 so that you don't see such a situation. 

    Suramya

  • Suramya, Thank you for tour answer!

    If I understood rightly, so:

    phase_mask phase max distance max
    5 4090 ~1.25m
    4 4093 ~2.5m
    3 2046 ~2.5m
    2 3071 ~7.5m
    1 1535 ~7.5 m
    0 767 ~7.5m

    1) And phase max defines number step bin for respective distance, Yes?

    2) Are phase values from range [0, 4095] for ind_freq_data_en = true for each frequency?

    3) I made nonlinearity and common offset calibrations with phase_mask = 3.

     Are calibrations values valid for case phase_mask = 2?

    4) I have sufficiently big noise level on second frequency, but on first one noise level is lesser.

    What can be the reasons of it?

  • Semenov,

    1) Yes, your understanding is correct.
    2) Phase values are from [0,4095] for each individual frequency. The mask is not used.
    3) You need to calibrate again for these calibrations.
    4) This shouldn't be the case. Noise should not be higher for the second modulation frequency. Could you share the raw data for the same (phase and amplitude values)?

    Suramya
  • Suramya, Thank you for tour answer!

    I shared the raw data in other my question.

    https://e2e.ti.com/support/sensors/f/1023/p/748490/2769914#2769914