# 3dFFT to compute angle of arrival in FCMW radars

I have a simulated doppler-range map of a 1Tx - 4Tx (azimuthally displaced) FMCW radar and I am doing something wrong to calculate the angle of arrival (AoA).

The scenario is the following. The radar is looking at two small spheres (0.1 m each in diameter) positioned on the same plane of the radar. One sphere is at a distance of 10 meters away from the radar, and is located 2 meters on the left of the radar boresight. The second small sphere is located 7m away from the radar and 1 m to the right of the boresight of the radar. The 2DFFT range-doppler output is fine and makes sense with the scenario, as you might see from the picture, representing the first antenna (Rx0) 2D FFT output amplitude (10*np.log10(np.abs(FFToutput))), with Hann window applied.

The issue I have is when I want to apply a new FFT to compute the AoA of the signal. As far as I understood, I have to compute the FFT on the doppler-range FFT across the virtual antennas (in my case they are the 4 Rx antennas).

To compute this 3rd FFT, what I do is the following:

1. I start with an array of complex numbers representing the range-doppler output with Hann windowing (size [dim_va x dim_vel x dim_range], respectively dimensions of virtual antennas array -in my case only the 4 Rx's-, resolution of velocity, resolution of range, these last two based on the chosen 2D FFT size),
2. compute the probable objects position in the range-doppler map, with a 1D OS-CFAR. The CFAR is applied on the non-coherent sum of the the doppler-range complex vector (basically the sum of the doppler-range real parts across antennas), hence I have a 1D array dim_vel x dim_range long.
3. compute the max of the peak for every object candidate peak found in the previous step, so to have only a single point per "candidate object".
4. compute 256-points FFT on the matrix given by the doppler-range map across antennas, considering the candidate targets only: basically, for every peak (object candidate) found, I use its index to isolate the respective doppler-range cell for each antenna. I have now a 2D matrix of size dim_va x dim_candidates.
5. the maximum of the 3D FFTs (one per candidate target/object) should be the angle of arrival.

here is some Python code that should do the trick:

n_fft = 256 #size of fft
AoA = np.fft.fft(rv_tg_va, n_fft, axis=0)/rv_tg_va.shape[1] #rv_tg_va is the range-doppler complex array for the target candidates of size numberOfCandidates * n_fft
AoA = np.fft.fftshift(AoA)
# AoA_magnitude = 10.*np.log10(np.abs(AoA))
wavelength = 0.0039189 # 76.5 GHz
d = wavelength/2. # distance btw receivers
f = np.arcsin(np.linspace(-0.5*wavelength/d , 0.5*wavelength/d , AoA.shape[0]))
maxFFT_idx = np.argmax(AoA, axis=0) #where the angles are supposed to be