You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
Can someone help me with performing range fft on FMCW Radar ADC data?
24 views (last 30 days)
Show older comments
I have a dataset of raw ADC data from an FMCW Radar which is in the form where for each radar frame, its raw data (*.mat) has 4 dimension:
samples (128), chirps (255), receivers (4), transmitters (2). I am unable to perform range FFT analysis on such data. Can someone help me with the same?
12 Comments
William Rose
on 15 Feb 2024
Please post a sample .mat file. Please post the equation that describes how range is related to your signals. Please post the code you have written thus far. If the code gives an error, what is the error message?
You have described a .mat file with 2040 sets of 128 samples. Do you expect to get 2040 range estimates, i.e. one range estimate from each set of 128 samples? If the answer is no, then please explain how different sets of 128 samples combine to give a range estimate.
Pratham
on 20 Feb 2024
Edited: Walter Roberson
on 20 Feb 2024
I am attatching below a sample .mat file for your reference. I am actually refering to the dataset on this github repo to perform range fft analysis. The code I have written so far is :
function [range_profiles] = perform_range_fft(adcData, fs, c)
if ~isequal(size(adcData), [128, 255, 4, 2])
error('Data dimensions must be (samples, chirps, receivers, transmitters)');
end
% Create empty array for range profiles
range_profiles = zeros(size(adcData, 2), size(adcData, 3), size(adcData, 4));
% FFT parameters
N = size(adcData, 1); % Number of samples per chirp
% Loop through chirps, receivers, and transmitters
for chirp_index = 1:size(adcData, 2)
for receiver_index = 1:size(adcData, 3)
for transmitter_index = 1:size(adcData, 4)
% Extract single-antenna data for this chirp and receiver-transmitter pair
single_data = adcData(:, chirp_index, receiver_index, transmitter_index);
% Apply windowing (optional, uncomment if desired)
%window = hamming(N);
%single_data = single_data .* window;
% Perform FFT with zero-padding for improved resolution
fft_output = fft(single_data, length(single_data) * 2, 1);
% Shift result to center frequencies (optional)
fft_output = fftshift(fft_output);
% Calculate frequency axis (linearly mapped with zero-padding)
f_axis = linspace(-fs/2, fs/2 - fs/N, N * 2);
% Calculate range axis (convert frequency to range using speed of light)
range_axis = c / (f_axis);
% Take magnitude (absolute value) for range profile
range_profile = abs(fft_output);
% Store range profile
range_profiles(chirp_index, receiver_index, transmitter_index) = range_profile;
end
end
end
end
I am getting an error message at the line "range_axis=c/f_axis" :
Error using /
Matrix dimensions must agree.
Error in perform_range_fft (line 34)
range_axis = c / (f_axis);
I am trying to find out the range fft for all the provided files in the dataset.
William Rose
on 20 Feb 2024
Use
range_axis = c ./ (f_axis);
to fix the first error. Then you get another error:
Unable to perform assignment because the size of the left side is 1-by-1 and the size
of the right side is 256-by-1.
Error in perform_range_fft_wr (line 39)
range_profiles(chirp_index, receiver_index, transmitter_index) = range_profile;
This is an error because you are attempting to assign a 256x1 complex vector to a scalar value. I do not know what your intent is here.
single_data is a 128x1 complex vector. Why do you pad single_data with 128 zeros before computing the FFT?
William Rose
on 20 Feb 2024
Edited: William Rose
on 20 Feb 2024
[Edit: fix spelling errors]
Now I see that you answered my question about zero-padding in your comments: you zero pad to improve the range resolution. I am not convinced that this gives a real improvement in range resolution. You have not added any additional data, so how can it improve real resolution? Some people zero-pad time-domain signals, to improve frequency resolution. It is true that this will give you a finer grid along the frequency axis, which makes it look like you have improved the frequency resolution. What really happens is that the prior spectral data gets interpolated, in a slightly complicated way, to a finer grid. Therefore the apparent improvement in frequency resolution is illusory. I syspect this is true for radar signal procressing also, but I could bre wrong.
I wrote script radarRanging.m, to call your function. I modified your function "perform_range_fft", to avoid an error, and gave it a new name (I added "_wr"), to distinguish it from your original posting. Script radarRanging.m plots the 8 complex traces for chirp 1 (four receivers, two transmitters). The script reads the data from the file you posted earlier, 000003.mat. The script makes the figure below. I am not sure what the results mean, but I was curious to know what the traces look like. The script and your modified function are attached.
William Rose
on 20 Feb 2024
This paper, sections III.A,B,C, has important information for the signal processing.
Do you know if the frame you slected, 000003.mat, has a target in the field of view? If so, do you know its approximate range, velocity, angle?
Pratham
on 21 Feb 2024
I am attatching the camera captured image of 000003.mat file. I do not know anything about its approximate range, velocty or angle. These values are exactly what I am trying to find out. Because essentially I want to find out at what range this man on the cycle( in the image) is at and at what velocity is he moving infront of the camera.
William Rose
on 21 Feb 2024
Thanks.
I estimate the distance on the order of 12 m, because a standard parking lot stripe is a bout 20 feet. The radial velocity is about zero, because the bike is traveling perpendicular to the view. The angle to center of target is about 3 degrees left of center, assuming 120 degree horizontal field of view, which is roughly consistent with the stripes. The angular resolution is about 15 degrees, so this target angle is more or less zero.
Now your task is to see if the FFT of the data supports this.
Pratham
on 21 Feb 2024
I am trying to plot a graph of maginitude versus range after obtaining the range_profiles from perform_range_fft_wr file, but something does not seem right as the graph makes no sense at all. I am attatching both the code and graph below.
figure;
plot(range_axis, range_profile);
xlabel('Range (m)');
ylabel('Magnitude');
title('Range Profile (Chirp 1, Receiver 2, Transmitter 1)');
William Rose
on 21 Feb 2024
You need to convert the 4D file to a 3D file, by combining dimensions 3 and 4 into a isngle dimension 3. This will make the 2 transmitters and 4 recievers look like 8 receivers. See this image, from here.
Therefore you want the rearranged array to have the data as follows, along dimension 3:
[R1T1, R2T1, R3T1, R4T1, R1T2, R2T2, R3T2, R4T2].
You do not want
[R1T1, R1T2, R2T1, R2T2,...].
Original adcData has size (128,255,4,2). Let's make one, and combine dimensions 3 and 4, and check that it worked as desired.
adcData=zeros(128,255,4,2);
for i=1:4
for j=1:2
adcData(1,1,i,j)=10*i+j;
end
end
adcData3=reshape(adcData,[128,255,8]);
disp(squeeze(adcData3(1,1,:))')
11 21 31 41 12 22 32 42
This is the ordering we wanted. Therefore you should do
adcData3=reshape(adcData,[128,255,8]);
before starting with the 2D or 3D FFTs.
William Rose
on 21 Feb 2024
Edited: William Rose
on 21 Feb 2024
I would not expect the results from function perform_range_fft_wr.m to be correct. As I said in an earlier comment, a line near the end assigned a vector to a scalar, so I changed it to use only the first element of the vector, so that it would run. But, as I said, I don't know what your intent was. Gao et al., arxiv 2022, say "In this paper, we adopt the 3-DFFT [8] to obtain the 3D radar cube that is named the range-velocity-angle (RVA) heatmap” (top p.2), and they show a 3D FFT in their Figure 5. Therefore I think you need to make changes to the data analysis. Carefully read the references which they cite, including Gao et al., 2019.
Pratham
on 22 Feb 2024
If we reshape the adcData into 3 dimensions then the code provided would not work because we are iterating through three loops where we go through chirp_index,reciever_index and transmitter_index.
My final intent is to find out the range,velocity and angle of approach of the cycle.I have never worked on radar data before hence this is very new to me.
I have read through those cited papers, and from my understanding plotting the magnitudes of the range_profile that we obtained in the perform_range_fft_wr.m file should work right? What is the mistake due to which we are getting a wrong plot?
William Rose
on 23 Feb 2024
"I have never worked on radar data before hence this is very new to me. " That makes two of us.
"From my understanding, plotting the magnitudes of the range_profile that we obtained in the perform_range_fft_wr.m file should work, right?" I have a different understanding. I think the signal analysis in that function, as it appears above, does not implement the method of Gao et al. Therefore I am not surprised that the function above does not give the desired result.
I think I know what the issue is, but it's complicated. If you wish to discuss this further, please email me by clicking on the envelope icon that appears when you click on the "WR" next to my comments.
Answers (0)
See Also
Categories
Find more on Waveform Design and Signal Synthesis in Help Center and File Exchange
Tags
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)