基于python的FMCW雷达工作原理仿真

这篇文章将介绍如何使用python来实现FMCW工作原理的仿真,第1章内容将介绍距离检测原理,第2章内容会介绍速度检测原理。

第1章

第1部分: 距离检测原理

调制的连续波雷达通常也被叫做调频连续波(FMCW)雷达是一个使用频率调制来测量目标的距离的系统。在频率调制中,电磁波的频率随时间线性增加。或者说,发射频率会以恒定速率改变。这种频率随着时间线性增加的信号被称为chirp。FMCW系统测量发射信号和反射信号频率的瞬时差异δf,这直接和反射的chirp的时间差成比例。这个时间差能用来计算目标的距离。

下图(左)显示了一个chirp频率随时间变化的表现,右边显示频率随时间线性增加的chirp的幅度随时间变化图。

雷达前面的单目标产生的中频信号是一个固定频率音调,这个频率由下式给出:

IF(frequency) = 2S*d / c

这里d是目标到雷达的距离,单位m,c是光速,m/s,S是chirp斜率,由chirp持续时间内带宽的变化率得到。因此,我们可以对中频信号做FFT得到频率,再通过测量频率来计算距离。

第2部分:Python仿真

第1步: 雷达参数设置,这一步会设置雷达系统的基本参数

python 复制代码
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                                   # Number ADC sampling points
vres = (c/fc)/(2*Nd*(Tchirp + endle_time))  # Speed resolution
Fs = Nr/Tchirp                              # Sampling rate

第2步: 发射信号, 假设发射的是cos信号,频率随时间线性变化

python 复制代码
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
plt.subplot(3,3,1)
plt.plot(t[0:Nr],Tx[0:Nr])
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.title('Tx Signal')
plt.subplot(3,3,2)
plt.plot(t[0:Nr],freq[0:Nr])
plt.xlabel('Time')
plt.ylabel('Frequency')
plt.title('Tx F-T')

r0 = r0 + v0*t

第3步: 接收信号, 接收波形可以从发射波形和时延计算

python 复制代码
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(3,3,3)
plt.plot(t[0:Nr],Rx[0:Nr])
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.title('Rx Signal')
plt.subplot(3,3,4)
plt.plot(t[0:Nr]+td[0:Nr],freqRx[0:Nr])
plt.xlabel('Time')
plt.ylabel('Frequency')
plt.title('Chirp F-T')

第4步: 中频信号,根据处理,假设中频信号可以用cos((2*pi*wt*t-2*pi*wr*t))表示

python 复制代码
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(3,3,5)
plt.plot(t[0:Nr],IFx[0:Nr])
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.title('IFx Signal')

第5步: 中频信号FFT, 这一步, 我们通过对中频信号做FFT计算中频信号的频率

python 复制代码
doppler = 10*np.log10(np.abs(np.fft.fft(IFx[0:Nr])))
frequency = np.fft.fftfreq(Nr, 1/Fs)
range = frequency*c/(2*slope)
plt.subplot(3,3,6)
plt.plot(range[0:int(Nr/2)],doppler[0:int(Nr/2)])
plt.xlabel('Frequency->Distance')
plt.ylabel('Amplitude')
plt.title('IF Signal FFT')

第6步: 时间频谱图, 这一步, 计算频谱随时间变化图

python 复制代码
# 2D plot
plt.subplot(3,3,7)
plt.specgram(IFx,Nr,Fs)
plt.xlabel('Time')
plt.ylabel('Frequency')
plt.title('Spectogram')

我们可以看到,在单个帧周期内,由于目标位移引起的中频信号频率变化在频谱图中很难区分,因此我们需要通过相位变化来检测小的位移和速度。

第2章

第1部分:速度检测原理

如第1章末尾所说,小尺度移动很难由距离频率关系检测,如下图所示,在帧周期内,不能在频谱中找到明显的移动。另外,如果多个目标在相同的距离,我们不能通过距离频率关系区分他们,因为他们在频谱中有着相同的中频频率。然而,我们可以通过测量中频信号的相位变化来检测这些小尺度移动,区分不同的目标。通过相位变化做速度估计的基本想法如下所示:

第1步: 速度维度数据提取

每个chirp提取一个采样点,对于Nd个chirp的帧,将会有Nd个点的列表。

python 复制代码
chirpamp = []
chirpnum = 1
while(chirpnum <= Nd):
    start = (chirpnum - 1)*Nr
    end = chirpnum*Nr
    chirpamp.append(IFx[start])
    chirpnum = chirpnum + 1

第2步: 对相位变化和速度做速度维度FFT

python 复制代码
doppler = 10*np.log10(np.abs(np.fft.fft(chirpamp)))
FFTfrequency = np.fft.fftfreq(Nd,1/Fs)
velocity = 5*np.arange(0,Nd)/3
plt.subplot(3,3,8)
plt.plot(velocity[0:int(Nd/2)],doppler[0:int(Nd/2)])
plt.xlabel('Velocity')
plt.ylabel('Amplitude')
plt.title('IF Velocity FFT')

第3步:2维FFT和速度距离关系

python 复制代码
mat2D = np.zeros((Nd,Nr))
i = 0
while(i < Nd):
    mat2D[i,:] = IFx[i*Nr:(i+1)*Nr]
    i = i + 1
# plt.matshow(mat2D)
# plt.title('Original data')
Z_fft2 = abs(np.fft.fft2(mat2D))
Data_fft2 = Z_fft2[0:int(Nd/2),0:int(Nr/2)]
plt.subplot(3,3,9)
plt.imshow(Data_fft2)
plt.xlabel('Range')
plt.ylabel('Velocity')
plt.title('Velocity-Range 2D FFT')

然后,设置结果显示和图片保存,就能得到仿真结果了。

python 复制代码
plt.tight_layout(pad=3,w_pad=0.05,h_pad=0.05)
#plt.savefig('simulate.png', bbox_inches='tight', pad_inches=0.3)   # 紧凑型,留白较少
plt.show()

最后,别忘了代码最开始导入库文件,这样才能保证代码运行正常。

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from numpy import fft
from mpl_toolkits.mplot3d import Axes3D
相关推荐
老刘莱国瑞4 分钟前
STM32 与 AS608 指纹模块的调试与应用
python·物联网·阿里云
湫ccc7 分钟前
《Opencv》基础操作详解(3)
人工智能·opencv·计算机视觉
Jack_pirate16 分钟前
深度学习中的特征到底是什么?
人工智能·深度学习
微凉的衣柜31 分钟前
微软在AI时代的战略布局和挑战
人工智能·深度学习·microsoft
火星机器人life44 分钟前
基于ceres优化的3d激光雷达开源算法
算法·3d
GocNeverGiveUp44 分钟前
机器学习1-简单神经网络
人工智能·机器学习
Schwertlilien1 小时前
图像处理-Ch2-空间域的图像增强
人工智能
虽千万人 吾往矣1 小时前
golang LeetCode 热题 100(动态规划)-更新中
算法·leetcode·动态规划
智慧化智能化数字化方案1 小时前
深入解读数据资产化实践指南(2024年)
大数据·人工智能·数据资产管理·数据资产入表·数据资产化实践指南
哦哦~9211 小时前
深度学习驱动的油气开发技术与应用
大数据·人工智能·深度学习·学习