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.
Hi,
I would like to confirm my interpretation of the range FFT that uses complex ADC samples at its input is correct.
Below I am sharing the range FFT output I obtained for one chirp. As you can see there are negative and positive frequencies. I understand the entire frequency range displayed in this plot carries useful information where each frequency bin (be it positive or negative) corresponds to a valid range bin. Therefore, the minimum frequency (which is about -1.22 MHz) in the below plot will correspond to range bin zero, and the highest frequency (i.e. +1.22 MHz in the same plot) will correspond to the maximum range bin. In order to make the frequency - range bin translation, first I will add 1.22 MHz to all of the frequencies displayed below so that the -1.22 MHz is offset to 0 MHz (i.e. the smallest range bin at 0 meters to the radar). After this step, the maximum frequency will be 2.44 MHz. I will then convert each frequency (f) to its corresponding range in meters (d) as follows:
d = (fc/2S)
where,
c : speed of light in m/sec
S : frequency slope in MHz/sec
(I performed a quick sanity check by converting 2.44 MHz to its range bin, which works out to be 6.79 meters and is inline with my expected maximum range)
Can you please confirm whether my approach above is correct?
Thank you for your help and support.
Regards,
Cagri
That is not correct. The negative frequency is already being removed. So the range FFT output (without fftshift) should cover from DC to ADC sampling rate. And in range, will cover from range 0 to max range.
Best,
Zigang
Hi Zigang,
I am trying to understand the error you mentioned in your message.
I included a new snapshot below where the green trace is without the fftshift and the red one is with fftshift (to correctly display the FFT output) What I understand from your message is to discard the negative frequency data in the green curve and to only use the data in the positive frequency range (where the maximum frequency is half of the sampling frequency as shown - my sampling frequency is 2.5 MHz by the way) When I calculate the maximum range for the positive half of the green trace, it is half of the maximum range I should be getting. Therefore, this tells me there is something wrong and the entire frequency range (i.e. positive and negative ones) need to be taken into account.
This brings me to the red trace shown below, where DC component indicated with 'A' has been shifted to the minimum frequency (i.e. -1.25 MHz) as indicated (through deploying fftshift function on the green trace) I also indicated point 'B' to show where the negative frequency components appear after the fftshift. Since I use the entire frequency range in the red plot, this is equal to my sampling rate 2.5 MHz as indicated, and will give me the maximum range as expected.
Because the DC component has shifted to the minimum negative frequency in the red trace, this frequency needs to be mapped to 0 Hz, which means the maximum positive frequency in the red trace maps to 2.5 MHz.
My guess is we are both saying the same thing but in different ways. Perhaps I should just ask the following to clarify:
When I feed N complex ADC values to FFT and obtain N complex output values, I do not discard half of the complex output values (as in the "real only" input to FFT case) as all of these values map to a particular range bin. All of the complex FFT output values I obtain will cover the full sampling frequency range. Is this correct?
Thank you for your help.
Regards,
Cagri
HI,
Yes, all ADC sample should be used for range FFT and FFTSHIFT should not be used after FFT function. IF the red curve is more close to your expected spectrum. Then there must be some error in your data parsing.
Can you explain how did you get your raw ADC data? Is it from radar studio and DCA1000 for raw data capture?
Best,
Zigang
Hi Zigang,
We agree on the fact that the complete FFT output needs to be used since all my ADC samples fed into the FFT are complex. That is the most crucial part.
By the way, I use Pythons scipy fft for my development and that may be the reason why we have a disagreement on the FFTSHIFT. It is simply a result of how the scipy fft package orders the fft results I think. (The FFTSHIFT provided by scipy simply reorders the frequency components for better visualization)
I use the mmWave Studio v02.01.01.00 and DCA100EVM for capturing my raw ADC samples. I use Complex 1x format.
I am working on formally collected and labelled data in my research and following is a snapshot of an instance where there is a human subject standing right in front of the radar (i.e. azimuth boresight angle is zero degrees) at about 1 meters. (This is the ground truth information from the actual data collection) In this particular data collection in a controlled environment, there was no other human subjects or other objects at 1 meter range either.
I plotted the following with the FFTSHIFT I have been talking about using the complete output of the FFT. Notice the x-axis values I computed using the shifted frequency bins. I circled the range bins with high magnitude in blue. As you can see, the range FFT data with the FFTSHIFT I used perfectly agrees with what I expect. Had I not used the FFTSHIFT after obtaining the FFT output (i.e. kept the negative frequency locations as they were without stitching them to the back of the positive frequency range), the human subject would appear at around 4.5 meters, which is not correct. (Assuming the minimum negative frequency corresponds to 0 m distance from the radar)
I actually looked at other instances of the same data collection session where the subject moves between different reference points (from 1 meter to over 4 meter ranges), and all of the range plots actually agree with the ground truth data I have. So given the data evidence I have, my current interpretation of the FFT output and the frequency bin to range bin conversions seem to be accurate.
I am also thinking about your insight on NOT having to use the FFTSHIFT and leaving all the negative and positive frequency bins where they are. If that is the case, between 0 to 3.5 meter range the results will be the same. However, objects between 3.5 meters and 7 meters, will appear in the negative range. Therefore, an object at 4 meters will be plotted at -3 meters, and an offset adjustment will be needed (i.e. actual range = maximum range + negative range value) to get the correct range reading.
By the way, if FFTSHIFT was not used, how would you interpret a negative range value? If you can kindly provide an expression for a range mapping for that case, that may provide more clarity for my understanding.
Regards,
Cagri
Hi Zigang,
I think I figured out the misunderstanding in our discussion thread, and it is related to what each of us means by FFTSHIFT.
The FFTSHIFT I have been referring to all along is the one that is part of Python's scipy package, and following is what it does.
The fft function in scipy does generate the complex output with DC at the first location as you have described and that output is not reordered at all.
When I try to generate the corresponding frequency bin values to plot on the x-axis, I use the following two functions in scipy:
STEP 1 - I first generate a set of axis values using the built in fftfreq() function which accepts the number of fft bins I have generated and the sampling period as I have indicated below.
freqAxis = fftfreq(N, 1/fs)
After this step, the generated values in freqAxis are as follows where b = fs/N (frequency resolution)
[0, b, 2b, 3b, ..... (N/2 - 1)b, -(N/2)b, -(N/2-1)b, -(N/2-2)b, -(N/2-3)b, ....., -b]
STEP 2 - As you can see, freqAxis generated above is not in the same order as the fft output that was generated earlier. The second half of freqAxis is negative and needs to be swapped with the first half to ensure axis continuity through correct frequency value ordering extending from the negative frequencies to positive frequencies.
The above remapping is achieved by the fftshift() built in function of scipy (which is different to what you were referring to as FFTSHIFT)
freqAxisReordered = fftshift(freqAxis)
After the above step my new frequency bin axis looks as follows. I use this new x-axis to plot my fft output values without ordering them.
[-(N/2)b, -(N/2-1)b, ......, -3b, -2b, -b, 0, b, 2b, 3b, ..... (N/2 - 1)b]
With the above clarification, I think we are now in agreement. My processing pipeline seems to work as expected, and the only issue was related to the visualization of the results. Please let me know if this all makes sense.
Thank you for your help and support in addressing my questions once again.
Regards,
Cagri
Hi, Cagri:
It could be the definition of built-in FFT function are different. But I agreed that your range FFT output picture showing in the last return looks correct to me.
Best,
Zigang