I have simulated 3 scatterers for FMCW radar signal processing using Range Migration Algorithm.
The Range Migration algorithm steps are as follows:
- Applying Azimuth FFT on the raw data
- Apply "Matched Filter"
- Apply "Stolt Interpolation"
- Apply 2D Inverse Fourier Transform on the resulting signal
Starting Signal dechirped signal model with RVP term removed,
After Azimuth Fourier Transform,
What I am observing
What I should be observing:
Y-axis : Azimuth direction X-axis : Range direction
So it seems the scatterer in the final image is diffused along the azimuth direction? But I am not sure what might be causing this diffusion along the azimuth axis. Could someone suggest what I should be looking out for? In terms of system parameters ? Or it might be due a step I am performing incorrectly? A few potential directions to look at is very much appreciated.
The following code is meant for someone who wants to advice on how to tackle the signal processing problem without actually having to implement the code from scratch
Data generation code for reference:
c = 3e8 # speed of light constant B = 3.6e9 # Bandwidth pr = c/2/B # range resolution PRF = 2500/3 # Pulse repetition frequency PRI = 1/PRF # Pulse repetition Interval Tp = PRI # Pulse width Cr = B/Tp # Chirp rate Fc = 3.48*1e10 # Center frequency Fs = 25e6 # system sampling rate ts = 1/Fs # sampling interval Nrg = round(Fs * Tp) # Number of range samples t = np.linspace(-Nrg/2,Nrg/2,Nrg)*ts # Fast time radarVel = np.array([4,0,0]) # speed of aircraft in m/s pa = 0.054 # azimuth resolution # Derieved Parameters Rs = 118 # slant distance to scene center lamC = c/Fc # wavelength delTh = (lamC)/(2*pa) # integration angle L = Rs*delTh/sin(np.deg2rad(90)) # Synthetic Aperture Length (2.21) Ta = L/eucDist(radarVel) # Synthetic Aperture time (2.22) Naz = round(PRF * Ta /2) * 2 #Number of Azimuth samples (matter of convenience) tSeq = np.arange(0,Naz) * PRI # timings H = 34 radarPosc = np.array([0,np.sqrt((Rs**2)-(H**2)),H])# Radar Coords at Aperture center along the path radarPoss = radarPosc - (radarVel * Naz//2 * PRI) # Radar's Starting Position radarSeq = np.zeros((3,len(tSeq))) radarSeq[0,:] = radarPoss + tSeq * radarVel radarSeq[1,:] = radarPoss + tSeq * radarVel radarSeq[2,:] = radarPoss + tSeq * radarVel # Data generation raw = np.zeros((Naz,Nrg), dtype=np.complex_) KR = (4*pi/c)*(Fc+Cr*t) # Kr Spatial frequency (3.11) for n in range(Naz): for scat in scattererCoords: R = np.sqrt((radarSeq[1,n]-scat)**2 + (radarSeq[2,n]-scat)**2) x_comp = radarSeq[0,n]-scat + norm(radarVel)*t # includes the motion between the pulses phase = np.exp(1j*KR*np.sqrt(R**2 + x_comp**2)) # without RVP term tau = 2*np.sqrt(R**2 + x_comp**2)/c raw[n,:] += rect(t,Tp,tau) * phase
Range Migration Algorithm Procedure
# # 1D FT along azimuth track S = fftshift(fft(raw, axis=0),axes=0) # # Matched Filtering phi_mf = -Rs*KYY # Matched Filter S_mf = S * np.exp(1j*phi_mf) # Stolt interpolation kstart = KYY[Naz//2,:].min() kend = KYY[Naz//2,:].max() KYq = np.linspace(kstart, kend, int(Nrg)) # query points, create a uniformly sampled points S_st = np.zeros((len(KYY), len(KYq)), dtype = 'complex_') for i in range(Naz): S_st[i,:] = np.interp(KYq, KYY[i,:], S_mf[i,:], left = 0, right = 0) S_final =ifft2((S_st))
Edit: Have included the 1-d Azimuth plots which are in the range-time and azimuth frequency domain.
Close-up of the final processed image: