#下面程序在参数调整后,效果图上没反应,通信信号、干扰信号和效果都是这样,请修改,但不要减少功能;请给出全部代码
import sys
import numpy as np
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QLabel, QSpinBox, \
QComboBox, QPushButton, QFormLayout
from PyQt5.QtCore import QTimer
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import matplotlib.patches as patches # ⬅️ 这一行是关键!
from scipy.special import erfc # ⬅️ 添加这一行
# 设置 Matplotlib 字体和样式
plt.rcParams.update({
'font.size': 12,
'axes.titlesize': 14,
'axes.labelsize': 12,
'xtick.labelsize': 12,
'ytick.labelsize': 12,
'legend.fontsize': 12,
'font.family': 'SimHei',
'axes.unicode_minus': False
})
class SatelliteCommunicationSimulator(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("卫星通信干扰仿真系统")
self.setGeometry(100, 100, 1200, 800)
# 应用全局字体样式
self.setStyleSheet("QWidget { font-size: 12pt; }")
# 初始化参数
self.init_parameters()
# 创建界面
self.init_ui()
# 初始化定时器
self.timer = QTimer(self)
self.timer.timeout.connect(self.update_simulation)
# 初始化显示
self.update_all_plots()
def init_parameters(self):
# 初始参数设置
self.frequency = 2400.0 # MHz
self.data_rate = 100.0 # kbps
self.signal_power = 20.0 # dBm
self.jamming_power = 30.0 # dBm
self.jamming_frequency = 2400.0 # MHz
self.jamming_type = "CW" # CW, FM, AM
self.jamming_mode = "ON" # ON, OFF
# 位置参数
self.aircraft1_pos = [100, 150]
self.aircraft2_pos = [400, 250]
self.satellite_pos = [250, 200]
self.jammer_pos = [150, 100]
# 时间轴和初始信号
self.time = np.linspace(0, 0.5, 200) # 显示 2 秒波形,500 个点
self.phase = 0 # 用于波形流动的相位偏移
self.data_signal = np.zeros_like(self.time)
self.jamming_signal = np.zeros_like(self.time)
self.combined_signal = np.zeros_like(self.time)
def init_ui(self):
central_widget = QWidget()
self.setCentralWidget(central_widget)
main_layout = QHBoxLayout(central_widget)
# 控制面板
control_panel = self.create_control_panel()
main_layout.addWidget(control_panel, 1)
# 显示区域
display_area = self.create_display_area()
main_layout.addWidget(display_area, 3)
def create_control_panel(self):
control_panel = QWidget()
layout = QVBoxLayout(control_panel)
# 通信参数设置
comm_group = QGroupBox("通信参数设置")
comm_layout = QFormLayout()
self.freq_spin = QSpinBox()
self.freq_spin.setRange(1000, 5000)
self.freq_spin.setValue(int(self.frequency))
self.freq_spin.setSuffix(" MHz")
comm_layout.addRow("频率:", self.freq_spin)
self.data_rate_spin = QSpinBox()
self.data_rate_spin.setRange(1, 1000)
self.data_rate_spin.setValue(int(self.data_rate))
self.data_rate_spin.setSuffix(" kbps")
comm_layout.addRow("数据速率:", self.data_rate_spin)
self.signal_power_spin = QSpinBox()
self.signal_power_spin.setRange(-50, 50)
self.signal_power_spin.setValue(int(self.signal_power))
self.signal_power_spin.setSuffix(" dBm")
comm_layout.addRow("信号功率:", self.signal_power_spin)
comm_group.setLayout(comm_layout)
layout.addWidget(comm_group)
# 干扰参数设置
jammer_group = QGroupBox("干扰参数设置")
jammer_layout = QFormLayout()
self.jamming_power_spin = QSpinBox()
self.jamming_power_spin.setRange(-50, 50)
self.jamming_power_spin.setValue(int(self.jamming_power))
self.jamming_power_spin.setSuffix(" dBm")
jammer_layout.addRow("干扰功率:", self.jamming_power_spin)
self.jamming_freq_spin = QSpinBox()
self.jamming_freq_spin.setRange(1000, 5000)
self.jamming_freq_spin.setValue(int(self.jamming_frequency))
self.jamming_freq_spin.setSuffix(" MHz")
jammer_layout.addRow("干扰频率:", self.jamming_freq_spin)
self.jamming_type_combo = QComboBox()
self.jamming_type_combo.addItems(["CW", "FM", "AM"])
self.jamming_type_combo.setCurrentText(self.jamming_type)
jammer_layout.addRow("干扰类型:", self.jamming_type_combo)
self.jamming_mode_combo = QComboBox()
self.jamming_mode_combo.addItems(["ON", "OFF"])
self.jamming_mode_combo.setCurrentText(self.jamming_mode)
jammer_layout.addRow("干扰模式:", self.jamming_mode_combo)
jammer_group.setLayout(jammer_layout)
layout.addWidget(jammer_group)
# 干扰效果数据显示
effect_group = QGroupBox("干扰效果数据")
effect_layout = QVBoxLayout()
self.snr_label = QLabel("信噪比(SNR): 0.0 dB")
self.ebno_label = QLabel("Eb/No: 0.0 dB")
self.ber_label = QLabel("误码率(BER): 0.00e+00")
effect_layout.addWidget(self.snr_label)
effect_layout.addWidget(self.ebno_label)
effect_layout.addWidget(self.ber_label)
effect_group.setLayout(effect_layout)
layout.addWidget(effect_group)
# 控制按钮
button_layout = QHBoxLayout()
self.start_btn = QPushButton("开始仿真")
self.start_btn.clicked.connect(self.start_simulation)
button_layout.addWidget(self.start_btn)
self.stop_btn = QPushButton("停止仿真")
self.stop_btn.clicked.connect(self.stop_simulation)
button_layout.addWidget(self.stop_btn)
self.reset_btn = QPushButton("重置仿真")
self.reset_btn.clicked.connect(self.reset_simulation)
button_layout.addWidget(self.reset_btn)
layout.addLayout(button_layout)
layout.addStretch()
return control_panel
def create_display_area(self):
display_widget = QWidget()
layout = QVBoxLayout(display_widget)
# 创建matplotlib图形
self.figure = Figure(figsize=(10, 8), dpi=100)
self.canvas = FigureCanvas(self.figure)
layout.addWidget(self.canvas)
# 创建三个子图
self.ax_deployment = self.figure.add_subplot(2, 2, 1)
self.ax_commu = self.figure.add_subplot(2, 2, 2)
self.ax_jammer = self.figure.add_subplot(2, 2, 3)
self.ax_effect = self.figure.add_subplot(2, 2, 4)
self.figure.tight_layout()
return display_widget
def update_all_plots(self):
self.update_deployment_plot()
self.update_waveform_plots()
self.update_effect_data()
def update_deployment_plot(self):
self.ax_deployment.clear()
self.ax_deployment.set_xlim(0, 500)
self.ax_deployment.set_ylim(0, 400)
self.ax_deployment.set_title("卫星通信部署示意")
self.ax_deployment.set_xlabel("X坐标")
self.ax_deployment.set_ylabel("Y坐标")
self.ax_deployment.grid(True)
# 绘制飞机、卫星、干扰机等
aircraft1 = patches.Circle(self.aircraft1_pos, 15, color='blue', alpha=0.7)
self.ax_deployment.add_patch(aircraft1)
self.ax_deployment.text(self.aircraft1_pos[0], self.aircraft1_pos[1] - 20, "飞机1", ha='center', va='center')
aircraft2 = patches.Circle(self.aircraft2_pos, 15, color='green', alpha=0.7)
self.ax_deployment.add_patch(aircraft2)
self.ax_deployment.text(self.aircraft2_pos[0], self.aircraft2_pos[1] - 20, "飞机2", ha='center', va='center')
satellite = patches.Circle(self.satellite_pos, 20, color='red', alpha=0.7)
self.ax_deployment.add_patch(satellite)
self.ax_deployment.text(self.satellite_pos[0], self.satellite_pos[1] - 25, "卫星", ha='center', va='center')
jammer = patches.Circle(self.jammer_pos, 15, color='orange', alpha=0.7)
self.ax_deployment.add_patch(jammer)
self.ax_deployment.text(self.jammer_pos[0], self.jammer_pos[1] - 20, "干扰机", ha='center', va='center')
# 绘制连接线
self.ax_deployment.plot([self.aircraft1_pos[0], self.satellite_pos[0]],
[self.aircraft1_pos[1], self.satellite_pos[1]], 'b-', linewidth=1, alpha=0.7)
self.ax_deployment.plot([self.satellite_pos[0], self.aircraft2_pos[0]],
[self.satellite_pos[1], self.aircraft2_pos[1]], 'g-', linewidth=1, alpha=0.7)
if self.jamming_mode == "ON":
self.ax_deployment.plot([self.jammer_pos[0], self.satellite_pos[0]],
[self.jammer_pos[1], self.satellite_pos[1]], 'r--', linewidth=1, alpha=0.7)
self.canvas.draw()
def update_waveform_plots(self):
self.ax_commu.clear()
self.ax_commu.plot(self.time, self.data_signal, 'b-', linewidth=1.5, label="通信信号")
self.ax_commu.set_title("通信信号")
self.ax_commu.set_xlabel("时间 (s)")
self.ax_commu.set_ylabel("幅度")
self.ax_commu.legend()
self.ax_commu.grid(True)
self.ax_jammer.clear()
self.ax_jammer.plot(self.time, self.jamming_signal, 'r-', linewidth=1.5, label="干扰信号")
self.ax_jammer.set_title("干扰信号")
self.ax_jammer.set_xlabel("时间 (s)")
self.ax_jammer.set_ylabel("幅度")
self.ax_jammer.legend()
self.ax_jammer.grid(True)
self.ax_effect.clear()
self.ax_effect.plot(self.time, self.combined_signal, 'g-', linewidth=1.5, label="混合信号")
self.ax_effect.set_title("混合信号")
self.ax_effect.set_xlabel("时间 (s)")
self.ax_effect.set_ylabel("幅度")
self.ax_effect.legend()
self.ax_effect.grid(True)
self.canvas.draw()
def update_effect_data(self):
snr = self.signal_power - self.jamming_power
ebno = snr
linear_ebno = 10 ** (ebno / 10)
ber = 0.5 * erfc(np.sqrt(linear_ebno / 2)) # ⬅️ 修改这里
self.snr_label.setText(f"信噪比(SNR): {snr:.1f} dB")
self.ebno_label.setText(f"Eb/No: {ebno:.1f} dB")
self.ber_label.setText(f"误码率(BER): {ber:.2e}")
def start_simulation(self):
if not self.timer.isActive():
self.timer.start(100)
def stop_simulation(self):
if self.timer.isActive():
self.timer.stop()
def reset_simulation(self):
self.freq_spin.setValue(int(self.frequency))
self.data_rate_spin.setValue(int(self.data_rate))
self.signal_power_spin.setValue(int(self.signal_power))
self.jamming_power_spin.setValue(int(self.jamming_power))
self.jamming_freq_spin.setValue(int(self.jamming_frequency))
self.jamming_type_combo.setCurrentText(self.jamming_type)
self.jamming_mode_combo.setCurrentText(self.jamming_mode)
self.update_all_plots()
def update_simulation(self):
freq = self.frequency / 100
jamming_freq = self.jamming_frequency / 100
data_amp = 10 ** (self.signal_power / 20)
jamming_amp = 10 ** (self.jamming_power / 20)
# 动态生成信号
self.phase += 0.1 # 模拟波形流动
self.data_signal = data_amp * np.sin(2 * np.pi * freq * self.time + self.phase)
if self.jamming_mode == "ON":
if self.jamming_type == "CW":
self.jamming_signal = jamming_amp * np.sin(2 * np.pi * jamming_freq * self.time + self.phase)
elif self.jamming_type == "FM":
self.jamming_signal = jamming_amp * np.sin(2 * np.pi * jamming_freq * self.time + 5 * np.sin(2 * np.pi * 10 * self.time))
elif self.jamming_type == "AM":
self.jamming_signal = jamming_amp * (1 + 0.5 * np.sin(2 * np.pi * 10 * self.time)) * np.sin(2 * np.pi * jamming_freq * self.time)
else:
self.jamming_signal = np.zeros_like(self.time)
self.combined_signal = self.data_signal + self.jamming_signal
self.update_all_plots()
def main():
app = QApplication(sys.argv)
app.setStyle('Fusion')
simulator = SatelliteCommunicationSimulator()
simulator.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()