FMCW radar working principle simulation based on python — Chapter 1:Distance simulation
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
This article will introduce how to use python to implement the simulation of FMCW working principle, the first chapter content will introduce the principle of distance detection.
Part 1: Principle of distance detection
A modulated continuous wave radar also called as Frequency modulated continuous wave (FMCW) radar is a system that is able to measure the range of the target using a technique known as Frequency Modulation. In Frequency Modulation, the frequency of the electromagnetic wave is linearly increased with time. In other words, the transmitted frequency will change at a constant rate. This kind of signal whose frequency increases linearly with time is called a Chirp. The FMCW system measures the instantaneous difference between the transmitted and reflected signal frequencies δf, which is directly proportional to the time difference δt of the reflected chirp. The time difference can be used to calculate the range of the target.
The figure below (left) shows a frequency vs time representation of a chirp and the figure on the right shows an amplitude vs time plot for a chirp signal whose frequency increases linearly with time. A chirp is characterized by the start frequency ( fc), Bandwidth ( B) and duration ( Tc). The slope of a chirp defines the rate at which the chirp ramps up.
A single target in front of the radar produces an IF signal that is a constant frequency tone, the frequency being given by:
- d is the distance of the target from the radar in m
- c is the speed of light in m/s
- S is the slope of the chirp, given by the rate of change of bandwidth over the chirp duration:
Part 2: Python simulation
Step_1: Radar parameters setting
This step will set the basic parameters in a radar system,
#Radar parameters setting
maxR = 200 #Maximum range
rangeRes = 1 #Range resolution
maxV = 70 #Maximum speed
fc = 77e9 #Carrier frequency
c = 3e8 #Speed of light
r0 = 100 #Target distance
v0 = 70 #Target speed
B = c/(2*rangeRes) #Bandwidth
Tchirp = 5.5*2*maxR/c #Chirp time
endle_time = 6.3e-6
slope = B/Tchirp #Chirp slope
f_IFmax = (slope*2*maxR)/c #Maximum IF frequency
f_IF = (slope*2*r0)/c #Current IF frequency
Nd = 128 #Number of chirp
Nr = 1024 #Numnber ADC sampling points
vres = (c/fc)/(2*Nd*(Tchirp+endle_time)) #Speed resolution
Fs = Nr/Tchirp #Sampling rate
Step_2: Signal of Tx
Assuming that the Tx signal is a cosine signal whose frequency varies linearly with time,
t = np.linspace(0,Nd*Tchirp,Nr*Nd) #Time of Tx and Rx
angle_freq = fc*t+(slope*t*t)/2 #Tx signal angle speed
freq = fc + slope*t #Tx frequency
Tx = np.cos(2*np.pi*angle_freq) #Waveform of Tx
Step_3: Signal of Rx
The Rx waveform can be calculated from the Tx waveform and the delay time,
td = 2*r0/c
freqRx = fc + slope*(t)
Rx = np.cos(2*np.pi*(fc*(t-td) + (slope*(t-td)*(t-td))/2))
Step_4: IF signal
According to the processing, assuming the IF signal can be represented by cos((2*pi*wt*t-2*pi*wr*t)),
IF_angle_freq = fc*t+(slope*t*t)/2 - ((fc*(t-td) + (slope*(t-td)*(t-td))/2))
freqIF = slope*td
IFx = np.cos(-(2*np.pi*(fc*(t-td) + (slope*(t-td)*(t-td))/2))+(2*np.pi*angle_freq))
Step_5: FFT of IF signal
In this step, we calculate the frequency of IF signal by the FFT of IF signal,
IF_angle_freq = fc*t+(slope*t*t)/2 - ((fc*(t-td) + (slope*(t-td)*(t-td))/2))
freqIF = slope*td
IFx = np.cos(-(2*np.pi*(fc*(t-td) + (slope*(t-td)*(t-td))/2))+(2*np.pi*angle_freq))
Step_6: Spectrogram with time
In this step, Spectrogram with time change will be calculated.
We can see that the IF signal frequency change due to target displacement within a single FRAME cycle is difficult to distinguish within the spectrogram, so we need to detect small displacements and velocities by phase changes.
Full python source code:
import numpy as np
import matplotlib.pyplot as plt
from numpy import fft
from mpl_toolkits.mplot3d import Axes3D
#Radar parameters setting
maxR = 200
rangeRes = 1
maxV = 70
fc = 77e9
c = 3e8
r0 = 100
v0 = 70
B = c/(2*rangeRes)
Tchirp = 5.5*2*maxR/c
endle_time = 6.3e-6
slope = B/Tchirp
f_IFmax = (slope*2*maxR)/c
f_IF = (slope*2*r0)/c
Nd = 128
Nr = 1024
vres = (c/fc)/(2*Nd*(Tchirp+endle_time))
Fs = Nr/Tchirp
#Tx = np.zeros(1,len(t))
#Rx = np.zeros(1,len(t))
#Mix = np.zeros(1,len(t))
#Tx波函数参数
t = np.linspace(0,Nd*Tchirp,Nr*Nd) #发射信号和接收信号的采样时间
angle_freq = fc*t+(slope*t*t)/2 #角频率
freq = fc + slope*t #频率
Tx = np.cos(2*np.pi*angle_freq) #发射波形函数
plt.subplot(4,2,1)
plt.plot(t[0:1024],Tx[0:1024])
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.title('Tx Signal')
plt.subplot(4,2,3)
plt.plot(t[0:1024],freq[0:1024])
plt.xlabel('Time')
plt.ylabel('Frequency')
plt.title('Tx F-T')
r0 = r0+v0*t
#Rx波函数参数
td = 2*r0/c
tx = t
freqRx = fc + slope*(t)
Rx = np.cos(2*np.pi*(fc*(t-td) + (slope*(t-td)*(t-td))/2)) #接受波形函数
plt.subplot(4,2,2)
plt.plot(t[0:1024],Rx[0:1024])
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.title('Rx Signal')
plt.subplot(4,2,3)
plt.plot(t[0:1024]+td[0:1024],freqRx[0:1024])
plt.xlabel('Time')
plt.ylabel('Frequency')
plt.title('Chirp F-T')
#IF信号函数参数
IF_angle_freq = fc*t+(slope*t*t)/2 - ((fc*(t-td) + (slope*(t-td)*(t-td))/2))
freqIF = slope*td
IFx = np.cos(-(2*np.pi*(fc*(t-td) + (slope*(t-td)*(t-td))/2))+(2*np.pi*angle_freq))
plt.subplot(4,2,4)
plt.plot(t[0:1024],IFx[0:1024])
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.title('IFx Signal')
#Range FFT
doppler = 10*np.log10(np.abs(np.fft.fft(IFx[0:1024])))
frequency = np.fft.fftfreq(1024, 1/Fs)
range = frequency*c/(2*slope)
plt.subplot(4,2,5)
plt.plot(range[0:512],doppler[0:512])
plt.xlabel('Frequency->Distance')
plt.ylabel('Amplitude')
plt.title('IF Signal FFT')
#2D plot
plt.subplot(4,2,6)
plt.specgram(IFx,1024,Fs)
plt.xlabel('Time')
plt.ylabel('Frequency')
plt.title('Spectogram')
plt.tight_layout(pad=3, w_pad=0.05, h_pad=0.05)
plt.show()