import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.animation import FuncAnimation
from mpl_toolkits.mplot3d import Axes3D
import ipywidgets as widgets
from IPython.display import display
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
plt.rcParams["font.family"] = "SimHei" # 设置中文字体
# 物理常数
c = 3e8 # 光速 (m/s)
class FDAArraySimulator:
def __init__(self, f0=10e9, delta_f=50e3, N=16):
"""
初始化FDA阵列仿真器
参数:
f0: 中心频率 (Hz)
delta_f: 频率增量 (Hz) - 关键FDA参数
N: 阵元数量
"""
self.f0 = f0
self.delta_f = delta_f
self.N = N
self.d = 0.5 * c / f0 # 阵元间距 (半波长)
# 仿真参数
self.theta = np.linspace(-90, 90, 181) # 方位角 (度)
self.R = np.linspace(100, 10000, 101) # 距离 (米)
self.time_points = np.linspace(0, 1e-3, 100) # 时间序列 (秒)
self.theta_rad = np.deg2rad(self.theta) # 转换为弧度
def calculate_fda_beam(self, t):
"""
计算FDA阵列因子,体现空间-时间耦合特性
参数:
t: 时间点 (秒)
返回:
归一化的阵列因子 (距离 × 角度)
"""
# 初始化阵列因子矩阵
AF = np.zeros((len(self.R), len(self.theta)), dtype=complex)
for m in range(self.N): # 遍历每个阵元
# 计算当前阵元的频率
f_m = self.f0 + m * self.delta_f
# 空间相位分量 (角度相关)
space_phase = 2 * np.pi * f_m * (m * self.d * np.sin(self.theta_rad)) / c
#体现角度依赖性(波束方向)
# 时间相位分量 (时间相关)
time_phase = 2 * np.pi * self.delta_f * m * t
#实现时间相关性(自动扫描特性)
# 距离相位分量 (距离相关)
range_phase = 2 * np.pi * f_m * self.R[:, None] / c
#引入距离依赖性(FDA独特特性)
# 综合阵列因子 - 体现空间-时间耦合
AF += np.exp(1j * (space_phase - range_phase + time_phase))
return np.abs(AF) / self.N # 归一化
def plot_spatio_temporal_coupling(self, t=0.5e-3):
"""
可视化空间-时间耦合特性
参数:
t: 时间点 (秒)
"""
fig = plt.figure(figsize=(15, 10))
# 计算波束方向图
beam_pattern = self.calculate_fda_beam(t)
# 1. 距离-角度热力图
plt.subplot(2, 2, 1)
plt.imshow(20 * np.log10(beam_pattern + 1e-10),
extent=[self.theta.min(), self.theta.max(),
self.R.min() / 1000, self.R.max() / 1000],
aspect='auto', cmap='jet', origin='lower')
plt.colorbar(label='增益 (dB)')
plt.xlabel('方位角 (度)')
plt.ylabel('距离 (km)')
plt.title(f'FDA空间-时间耦合特性 (t={t * 1000:.1f}ms)')
# 2. 固定距离的切面
plt.subplot(2, 2, 2)
fixed_range_idx = 50 # 选择中间距离
plt.plot(self.theta, 20 * np.log10(beam_pattern[fixed_range_idx, :] + 1e-10))
plt.xlabel('方位角 (度)')
plt.ylabel('增益 (dB)')
plt.title(f'固定距离{self.R[fixed_range_idx] / 1000:.1f}km的波束方向图')
plt.grid(True)
# 3. 固定角度的切面
plt.subplot(2, 2, 3)
fixed_angle_idx = 90 # 选择0度方向
plt.plot(self.R / 1000, 20 * np.log10(beam_pattern[:, fixed_angle_idx] + 1e-10))
plt.xlabel('距离 (km)')
plt.ylabel('增益 (dB)')
plt.title(f'固定方位角{self.theta[fixed_angle_idx]:.0f}°的波束方向图')
plt.grid(True)
# 4. 空间-时间耦合示意图
plt.subplot(2, 2, 4)
# 在固定距离和角度上观察增益随时间变化
fixed_range = 5000 # 固定距离5km
fixed_angle = 0 # 固定角度0度
r_idx = np.argmin(np.abs(self.R - fixed_range))
a_idx = np.argmin(np.abs(self.theta - fixed_angle))
# 计算时间序列上的增益变化
time_gain = []
for time_point in self.time_points:
beam = self.calculate_fda_beam(time_point)
time_gain.append(20 * np.log10(beam[r_idx, a_idx] + 1e-10))
plt.plot(self.time_points * 1000, time_gain)
plt.xlabel('时间 (ms)')
plt.ylabel('增益 (dB)')
plt.title(f'固定点(θ={fixed_angle}°, R={fixed_range / 1000:.1f}km)的增益随时间变化')
plt.grid(True)
plt.tight_layout()
plt.show()
def animate_auto_scanning(self):
"""
创建自动扫描特性的动画
"""
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
# 创建网格
T, R_grid = np.meshgrid(self.theta, self.R / 1000)
# 初始化空图
beam = self.calculate_fda_beam(0)
Z = 20 * np.log10(beam + 1e-10)
surf = ax.plot_surface(T, R_grid, Z, cmap=cm.jet, alpha=0.8)
# 设置坐标轴标签
ax.set_xlabel('方位角 (度)')
ax.set_ylabel('距离 (km)')
ax.set_zlabel('增益 (dB)')
ax.set_title('FDA自动扫描特性 (t=0 ms)')
ax.set_zlim(-40, 0)
# 更新函数用于动画
def update(frame):
ax.clear()
t = self.time_points[frame]
beam = self.calculate_fda_beam(t)
Z = 20 * np.log10(beam + 1e-10)
surf = ax.plot_surface(T, R_grid, Z, cmap=cm.jet, alpha=0.8)
ax.set_xlabel('方位角 (度)')
ax.set_ylabel('距离 (km)')
ax.set_zlabel('增益 (dB)')
ax.set_title(f'FDA自动扫描特性 (t={t * 1000:.1f} ms)')
ax.set_zlim(-40, 0)
return surf,
# 创建动画
ani = FuncAnimation(fig, update, frames=len(self.time_points), interval=50, blit=False)
plt.tight_layout()
plt.show()
return ani
def interactive_parameter_analysis(self):
"""
交互式参数分析界面
"""
style = {'description_width': 'initial'}
# 创建交互控件
delta_f_slider = widgets.FloatLogSlider(
value=self.delta_f, min=3, max=6, step=0.1,
description='频率增量Δf (Hz):',
readout_format='.0f', style=style
)
time_slider = widgets.FloatSlider(
value=0, min=0, max=1e-3, step=1e-5,
description='时间 t (s):',
readout_format='.5f', style=style
)
angle_slider = widgets.FloatSlider(
value=0, min=-90, max=90, step=1,
description='固定角度θ (度):', style=style
)
range_slider = widgets.FloatSlider(
value=5000, min=100, max=10000, step=100,
description='固定距离R (m):', style=style
)
# 更新函数
def update_plots(delta_f_val, t_val, fixed_angle, fixed_range):
# 临时创建新的仿真器实例
temp_simulator = FDAArraySimulator(
f0=self.f0,
delta_f=delta_f_val,
N=self.N
)
# 计算波束方向图
beam_pattern = temp_simulator.calculate_fda_beam(t_val)
# 创建图形
fig, axs = plt.subplots(1, 2, figsize=(15, 6))
# 1. 距离-角度热力图
im = axs[0].imshow(20 * np.log10(beam_pattern + 1e-10),
extent=[self.theta.min(), self.theta.max(),
self.R.min() / 1000, self.R.max() / 1000],
aspect='auto', cmap='jet', origin='lower')
fig.colorbar(im, ax=axs[0], label='增益 (dB)')
axs[0].set_xlabel('方位角 (度)')
axs[0].set_ylabel('距离 (km)')
axs[0].set_title(f'FDA波束方向图 (Δf={delta_f_val / 1000:.1f}kHz, t={t_val * 1000:.2f}ms)')
# 2. 固定角度和距离的增益变化
r_idx = np.argmin(np.abs(self.R - fixed_range))
a_idx = np.argmin(np.abs(self.theta - fixed_angle))
# 计算时间序列上的增益变化
time_gain = []
for time_point in self.time_points:
temp_beam = temp_simulator.calculate_fda_beam(time_point)
time_gain.append(20 * np.log10(temp_beam[r_idx, a_idx] + 1e-10))
axs[1].plot(self.time_points * 1000, time_gain)
axs[1].axvline(x=t_val * 1000, color='r', linestyle='--', label=f'当前时间: {t_val * 1000:.2f}ms')
axs[1].set_xlabel('时间 (ms)')
axs[1].set_ylabel('增益 (dB)')
axs[1].set_title(f'固定点(θ={fixed_angle}°, R={fixed_range / 1000:.1f}km)的增益随时间变化')
axs[1].grid(True)
axs[1].legend()
plt.tight_layout()
plt.show()
# 创建交互界面
widgets.interactive(
update_plots,
delta_f_val=delta_f_slider,
t_val=time_slider,
fixed_angle=angle_slider,
fixed_range=range_slider
)
# ========== 主执行函数 ==========
if __name__ == "__main__":
print("频控阵天线(FDA)波束特性仿真")
# 创建FDA仿真器实例
fda_simulator = FDAArraySimulator()
print("1. 空间-时间耦合特性")
fda_simulator.plot_spatio_temporal_coupling()
print("\n2. 自动扫描特性 (动画展示)")
fda_simulator.animate_auto_scanning()
print("\n3. 交互式参数分析")
fda_simulator.interactive_parameter_analysis()
最新发布