仿真环境下的反无人机系统 —— Virtual_Simulation_of_an_Anti-UAV_Defense_System —— 反无仿真
地址:
https://github.com/KirillAleksandrovich/PERIMETER-Virtual_Simulation_of_an_Anti-UAV_Defense_System





阿拉伯文的源代码:
"""
ПЕРИМЕТР - Виртуальная симуляция системы защиты от БПЛА
Версия: 1 Professional
Разработчик: Фешев Кирилл
Назначение: Тренажер для отработки действий при угрозах БПЛА
"""
import tkinter as tk
from tkinter import ttk, messagebox
import math
import random
import time
from datetime import datetime
class DroneEntity:
"""
Класс для моделирования беспилотного летательного аппарата (БПЛА)
Содержит все параметры и поведение дрона в симуляции
"""
def __init__(self, drone_id, drone_type="Разведывательный", start_x=0, start_y=0):
# Идентификационные параметры
self.id = drone_id
self.type = drone_type # Разведывательный - разведка, Ударный - ударный, Роевой - роевой
self.status = "active" # active, neutralized, escaped
# Позиционные параметры (в метрах от центра объекта)
self.position_x = start_x
self.position_y = start_y
self.altitude = random.randint(50, 300) # высота в метрах
# Параметры движения
self.speed = random.randint(80, 150) # км/ч
self.heading = random.uniform(0, 360) # курс в градусах
self.flight_time = 0 # время полета в секундах
# Тактические параметры
self.threat_level = self.calculate_threat_level()
self.detection_count = 0 # сколько раз был обнаружен
self.approach_direction = None # направление подлета
self.distance_to_target = 0 # расстояние до цели
def calculate_threat_level(self):
"""Рассчитывает уровень угрозы в зависимости от типа дрона"""
threat_matrix = {
"Разведывательный": 4, # Разведывательный - средняя угроза
"Ударный": 9, # Ударный - высокая угроза
"Роевой": 7 # Роевой - высокая угроза из-за количества
}
return threat_matrix.get(self.type, 5)
def update_position(self, time_delta=1.0):
"""
Обновляет позицию дрона на основе его скорости и курса
time_delta - время в секундах с последнего обновления
"""
if self.status != "active":
return
# Преобразуем скорость из км/ч в м/с
speed_mps = (self.speed * 1000) / 3600
speed_mps *= 2.0 # Умеренное ускорение для демонстрации
# ВСЕГДА летим к цели (Лахта Центр) с высокой вероятностью
target_angle = math.degrees(math.atan2(-self.position_y, -self.position_x))
angle_diff = (target_angle - self.heading + 180) % 360 - 180
# 95% вероятность движения прямо к цели
if random.random() < 0.95:
self.heading += angle_diff * 0.4 # Более агрессивный поворот к цели
# Вычисляем новые координаты
self.position_x += math.cos(math.radians(self.heading)) * speed_mps * time_delta
self.position_y += math.sin(math.radians(self.heading)) * speed_mps * time_delta
# Рассчитываем расстояние до цели
self.distance_to_target = math.sqrt(self.position_x ** 2 + self.position_y ** 2)
# Увеличиваем время полета
self.flight_time += time_delta
# Определяем направление подлета
self.determine_approach_direction()
def determine_approach_direction(self):
"""Определяет с какого направления летит дрон"""
# Используем координаты дрона относительно объекта (Лахта Центр)
x, y = self.position_x, self.position_y
# В системе координат программы:
# Север - отрицательные Y (вверх от центра)
# Юг - положительные Y (вниз от центра)
# Восток - положительные X (вправо от центра)
# Запад - отрицательные X (влево от центра)
# Вычисляем угол от центра к дрону
angle = math.degrees(math.atan2(y, x))
# Нормализуем угол от 0 до 360 градусов
if angle < 0:
angle += 360
# Определяем направление по углу с промежуточными направлениями:
if 337.5 <= angle or angle < 22.5:
self.approach_direction = "ВОСТОК" # Справа от центра
elif 22.5 <= angle < 67.5:
self.approach_direction = "ЮГО-ВОСТОК"
elif 67.5 <= angle < 112.5:
self.approach_direction = "ЮГ" # Сверху от центра
elif 112.5 <= angle < 157.5:
self.approach_direction = "ЮГО-ЗАПАД"
elif 157.5 <= angle < 202.5:
self.approach_direction = "ЗАПАД" # Слева от центра
elif 202.5 <= angle < 247.5:
self.approach_direction = "СЕВЕРО-ЗАПАД"
elif 247.5 <= angle < 292.5:
self.approach_direction = "СЕВЕР" # Снизу от центра
else: # 292.5 <= angle < 337.5
self.approach_direction = "СЕВЕРО-ВОСТОК"
class RadarSystem:
"""
Класс системы обнаружения БПЛА
Имитирует работу радарной станции с заданными характеристиками
"""
def __init__(self, position_x, position_y, detection_range=1500):
# Позиция радара (обычно в центре охраняемого объекта)
self.position_x = position_x
self.position_y = position_y
# Тактико-технические характеристики
self.detection_range = detection_range # дальность обнаружения в метрах
self.azimuth_accuracy = 0.5 # точность по азимуту в градусах
self.range_accuracy = 5.0 # точность по дальности в метрах
# Статус системы
self.status = "operational"
self.detected_targets = []
self.detection_history = []
def scan_for_drones(self, drone_list):
"""
Сканирует воздушное пространство и обнаруживает дроны
Возвращает список обнаруженных целей
"""
detected_drones = []
for drone in drone_list:
if drone.status == "active":
# Вычисляем расстояние до дрона
distance = math.sqrt(
(drone.position_x - self.position_x) ** 2 +
(drone.position_y - self.position_y) ** 2
)
# Проверяем находится ли дрон в зоне обнаружения
if distance <= self.detection_range:
# В демо-версии всегда обнаруживаем если в зоне
detected_drones.append(drone)
drone.detection_count += 1
# Записываем в историю обнаружений
detection_record = {
'timestamp': time.time(),
'drone_id': drone.id,
'distance': distance,
'direction': drone.approach_direction
}
self.detection_history.append(detection_record)
self.detected_targets = detected_drones
return detected_drones
class ElectronicWarfareSystem:
"""
Класс системы радиоэлектронной борьбы (РЭБ)
Обеспечивает нейтрализацию БПЛА различными методами
"""
def __init__(self, position_x, position_y, engagement_range=800):
self.position_x = position_x
self.position_y = position_y
self.engagement_range = engagement_range # дальность воздействия в метрах
# Параметры системы
self.power_level = 100 # уровень мощности в %
self.status = "standby" # standby, active, cooling
self.engagement_history = []
# Методы воздействия и их эффективность
self.jamming_methods = {
"gps_jamming": 0.95, # Подавление GPS - эффективность 95%
"control_jamming": 0.90, # Подавление каналов управления - 90%
"video_jamming": 0.85, # Подавление видеопотока - 85%
"swarm_disruption": 0.80 # Разрыв связи в рое - 80%
}
def engage_target(self, target_drone, method="auto"):
"""
Воздействие на цель выбранным методом РЭБ
Возвращает True если цель нейтрализована
"""
if self.status != "standby":
return False
if target_drone.status != "active":
return False
# Проверяем находится ли цель в зоне поражения
distance_to_target = math.sqrt(
(target_drone.position_x - self.position_x) ** 2 +
(target_drone.position_y - self.position_y) ** 2
)
if distance_to_target > self.engagement_range:
return False
# Автоматический выбор метода воздействия
if method == "auto":
method = self.select_optimal_method(target_drone)
# В ДЕМО-ВЕРСИИ - ВСЕГДА УСПЕШНОЕ ВОЗДЕЙСТВИЕ
success = True
if success:
target_drone.status = "neutralized"
# Записываем в историю
engagement_record = {
'timestamp': time.time(),
'drone_id': target_drone.id,
'method': method,
'distance': distance_to_target,
'success': True
}
self.engagement_history.append(engagement_record)
return True
return False
def select_optimal_method(self, drone):
"""Выбирает оптимальный метод воздействия на основе типа дрона"""
method_selection = {
"Разведывательный": "gps_jamming", # Для разведки - подавление навигации
"Ударный": "control_jamming", # Для ударных - подавление управления
"Роевой": "swarm_disruption" # Для роев - разрыв связи
}
return method_selection.get(drone.type, "control_jamming")
class ThreatAnalysisSystem:
"""
Система анализа угроз и выработки рекомендаций
Оценивает обстановку и предлагает оптимальные действия
"""
def __init__(self):
self.threat_assessments = []
self.recommendations_log = []
self.sector_analysis = {
"СЕВЕР": {"threat_level": 0, "drones_count": 0, "terrain": "Приморское шоссе"},
"СЕВЕРО-ВОСТОК": {"threat_level": 0, "drones_count": 0, "terrain": "СЗЗ Лахта Центра"},
"ВОСТОК": {"threat_level": 0, "drones_count": 0, "terrain": "БЦ Атлантик Сити"},
"ЮГО-ВОСТОК": {"threat_level": 0, "drones_count": 0, "terrain": "ЮВ подъезд"},
"ЮГ": {"threat_level": 0, "drones_count": 0, "terrain": "Финский залив"},
"ЮГО-ЗАПАД": {"threat_level": 0, "drones_count": 0, "terrain": "ЮЗ подъезд"},
"ЗАПАД": {"threat_level": 0, "drones_count": 0, "terrain": "пос. Ольгино"},
"СЕВЕРО-ЗАПАД": {"threat_level": 0, "drones_count": 0, "terrain": "СЗ подъезд"}
}
def analyze_threats(self, detected_drones):
"""
Анализирует текущую угрозу и выдает рекомендации
"""
# Сбрасываем анализ секторов
for sector in self.sector_analysis:
self.sector_analysis[sector]["threat_level"] = 0
self.sector_analysis[sector]["drones_count"] = 0
# Анализируем каждый обнаруженный дрон
total_threat_level = 0
active_threats = 0
recommendations = []
for drone in detected_drones:
if drone.status == "active":
# Обновляем анализ по секторам
sector = drone.approach_direction
if sector in self.sector_analysis:
self.sector_analysis[sector]["drones_count"] += 1
self.sector_analysis[sector]["threat_level"] += drone.threat_level
# Суммируем общий уровень угрозы
total_threat_level += drone.threat_level
active_threats += 1
# Генерируем рекомендации для конкретного дрона
drone_recommendation = self.generate_drone_recommendation(drone)
if drone_recommendation not in recommendations:
recommendations.append(drone_recommendation)
# Генерируем общие рекомендации
general_recommendations = self.generate_general_recommendations(total_threat_level, active_threats)
recommendations.extend(general_recommendations)
# Сохраняем анализ
assessment = {
'timestamp': datetime.now(),
'total_threat': total_threat_level,
'active_threats': active_threats,
'recommendations': recommendations,
'sector_analysis': self.sector_analysis.copy()
}
self.threat_assessments.append(assessment)
return recommendations
def generate_drone_recommendation(self, drone):
"""Генерирует рекомендации для конкретного дрона"""
base_message = f"БПЛА-{drone.id} ({drone.type}) - {drone.approach_direction}"
if drone.distance_to_target < 500:
return f"🚨 {base_message} - КРИТИЧЕСКАЯ БЛИЗОСТЬ! Немедленная нейтрализация!"
elif drone.threat_level >= 8:
return f"🚨 {base_message} - ВЫСОКАЯ УГРОЗА! Срочное применение РЭБ"
elif drone.threat_level >= 5:
return f"⚠️ {base_message} - Средняя угроза. Подготовить РЭБ"
else:
return f"ℹ️ {base_message} - Наблюдение. Дистанция: {int(drone.distance_to_target)}м"
def generate_general_recommendations(self, total_threat, active_threats):
"""Генерирует общие рекомендации по ситуации"""
recommendations = []
# Анализ по секторам
max_threat_sector = max(self.sector_analysis.items(),
key=lambda x: x[1]["threat_level"])
sector_name, sector_data = max_threat_sector
if sector_data["threat_level"] > 0:
rec = f"🎯 Главная угроза: {sector_name} ({sector_data['terrain']}) - {sector_data['drones_count']} БПЛА"
recommendations.append(rec)
# Общие рекомендации на основе активных угроз
if active_threats == 0:
recommendations.append("✅ Все угрозы нейтрализованы. Ситуация под контролем")
elif total_threat >= 15:
recommendations.append("🚨 КРИТИЧЕСКАЯ СИТУАЦИЯ! Задействовать все системы РЭБ!")
recommendations.append("📞 Уведомить командование о массированной атаке")
elif total_threat >= 8:
recommendations.append("⚠️ ВЫСОКАЯ УГРОЗА! Немедленно активировать РЭБ")
elif total_threat >= 3:
recommendations.append("🔶 СРЕДНЯЯ УГРОЗА! Привести РЭБ в готовность")
else:
recommendations.append("🔹 НИЗКАЯ УГРОЗА. Продолжать мониторинг")
# Добавляем рекомендацию по использованию РЭБ если есть активные цели
if active_threats > 0:
recommendations.append("🎯 Для нейтрализации нажмите 'Активировать РЭБ'")
return recommendations
class EBWSimulatorGUI:
"""
Главный класс графического интерфейса системы РЭБ
Обеспечивает визуализацию и управление симуляцией
"""
def __init__(self, root_window):
self.root = root_window
self.root.title("СИСТЕМА РЭБ - Лахта Центр | Версия 1 Professional")
self.root.geometry("1600x900") # УВЕЛИЧЕНО ДЛЯ ЛУЧШЕГО ВИДА
self.root.configure(bg='#0a0a0a')
# Инициализация систем
self.initialize_systems()
# Переменные симуляции
self.simulation_time = 0
self.drone_counter = 1
self.simulation_running = True
self.neutralized_count = 0 # СЧЕТЧИК НЕЙТРАЛИЗОВАННЫХ БПЛА
# Создание интерфейса
self.create_interface()
# Запуск основного цикла симуляции
self.start_simulation()
def initialize_systems(self):
"""Инициализация всех компонентов системы"""
# Основные системы
self.radar_system = RadarSystem(0, 0, 1500) # Радар с дальностью 1.5 км
self.ew_system = ElectronicWarfareSystem(0, 0, 800) # Система РЭБ с дальностью 800м
self.threat_analyzer = ThreatAnalysisSystem() # Анализатор угроз
# База данных дронов
self.active_drones = []
# Статистика
self.detection_statistics = {"total": 0, "neutralized": 0}
def create_interface(self):
"""Создание графического интерфейса пользователя"""
# Основной контейнер
main_container = ttk.Frame(self.root)
main_container.pack(fill='both', expand=True, padx=10, pady=10)
# Левая часть - тактический экран
self.create_tactical_display(main_container)
# Правая часть - панели управления и информации
self.create_control_panels(main_container)
def create_tactical_display(self, parent):
"""Создание тактического экрана с картой"""
tactical_frame = ttk.LabelFrame(parent, text="ТАКТИЧЕСКАЯ ОБСТАНОВКА", padding=10)
tactical_frame.pack(side='left', fill='both', expand=True, padx=(0, 10))
# Холст для отрисовки - УВЕЛИЧЕН
self.tactical_canvas = tk.Canvas(tactical_frame, width=900, height=700,
bg='#001122', highlightthickness=1,
highlightbackground='#00ff00')
self.tactical_canvas.pack(fill='both', expand=True)
def create_control_panels(self, parent):
"""Создание панелей управления и информации"""
right_panel = ttk.Frame(parent)
right_panel.pack(side='right', fill='y')
# Панель статуса системы
self.create_status_panel(right_panel)
# Панель управления
self.create_control_panel(right_panel)
# Панель рекомендаций (УВЕЛИЧЕНА)
self.create_recommendations_panel(right_panel)
# Панель статистики нейтрализации (УМЕНЬШЕНА)
self.create_neutralization_stats_panel(right_panel)
# Панель информации о целях (ПЕРЕМЕЩЕНА ВЫШЕ)
self.create_targets_panel(right_panel)
# Панель анализа секторов
self.create_sector_analysis_panel(right_panel)
def create_status_panel(self, parent):
"""Панель статуса системы"""
status_frame = ttk.LabelFrame(parent, text="СТАТУС СИСТЕМЫ", padding=10)
status_frame.pack(fill='x', pady=(0, 10))
self.time_label = ttk.Label(status_frame, text="Время: 00:00",
font=('Arial', 10, 'bold'))
self.time_label.pack(anchor='w')
self.radar_status = ttk.Label(status_frame, text="Радар: АКТИВЕН",
foreground='green')
self.radar_status.pack(anchor='w')
self.ew_status = ttk.Label(status_frame, text="РЭБ: ГОТОВ",
foreground='green')
self.ew_status.pack(anchor='w')
self.threat_level = ttk.Label(status_frame, text="Уровень угрозы: НИЗКИЙ",
font=('Arial', 11, 'bold'))
self.threat_level.pack(anchor='w')
self.drones_count = ttk.Label(status_frame, text="Обнаружено БПЛА: 0")
self.drones_count.pack(anchor='w')
self.active_threats = ttk.Label(status_frame, text="Активных угроз: 0")
self.active_threats.pack(anchor='w')
def create_control_panel(self, parent):
"""Панель управления симуляцией"""
control_frame = ttk.LabelFrame(parent, text="УПРАВЛЕНИЕ СИМУЛЯЦИЕЙ", padding=10)
control_frame.pack(fill='x', pady=(0, 10))
# Кнопки управления
ttk.Button(control_frame, text="Добавить БПЛА",
command=self.add_random_drone).pack(fill='x', pady=2)
ttk.Button(control_frame, text="Активировать РЭБ",
command=self.activate_ew_system).pack(fill='x', pady=2)
# УБРАНА КНОПКА "Сценарий: Одиночная атака"
ttk.Button(control_frame, text="Сценарий: Групповая атака",
command=self.run_group_attack_scenario).pack(fill='x', pady=2)
ttk.Button(control_frame, text="Сценарий: Роевая атака",
command=self.run_swarm_attack_scenario).pack(fill='x', pady=2)
ttk.Button(control_frame, text="Сброс симуляции",
command=self.reset_simulation).pack(fill='x', pady=2)
def create_recommendations_panel(self, parent):
"""Панель рекомендаций системы"""
rec_frame = ttk.LabelFrame(parent, text="РЕКОМЕНДАЦИИ СИСТЕМЫ", padding=10)
rec_frame.pack(fill='x', pady=(0, 10))
# Текстовое поле для рекомендаций - УВЕЛИЧЕНО
self.recommendations_text = tk.Text(rec_frame, height=8, width=45, # УМЕНЬШЕНО ДО 8 СТРОК
bg='#001100', fg='#00ff00',
font=('Arial', 9))
scrollbar = ttk.Scrollbar(rec_frame, orient='vertical',
command=self.recommendations_text.yview)
self.recommendations_text.configure(yscrollcommand=scrollbar.set)
self.recommendations_text.pack(side='left', fill='both', expand=True)
scrollbar.pack(side='right', fill='y')
def create_neutralization_stats_panel(self, parent):
"""ПАНЕЛЬ СТАТИСТИКИ """
stats_frame = ttk.LabelFrame(parent, text="СТАТИСТИКА НЕЙТРАЛИЗАЦИИ", padding=10)
stats_frame.pack(fill='x', pady=(0, 10))
# Текстовое поле для статистики
self.stats_text = tk.Text(stats_frame, height=4, width=40, # МЕНЬШЕ ВЫСОТА
bg='#110011', fg='#ff00ff',
font=('Arial', 9)) # МЕНЬШИЙ ШРИФТ
self.stats_text.pack(fill='both', expand=True)
def create_targets_panel(self, parent):
"""Панель информации о целях"""
targets_frame = ttk.LabelFrame(parent, text="ОБНАРУЖЕННЫЕ ЦЕЛИ", padding=10)
targets_frame.pack(fill='x', pady=(0, 10))
# Таблица целей
columns = ("ID", "Тип", "Угроза", "Направление", "Дистанция", "Статус")
self.targets_table = ttk.Treeview(targets_frame, columns=columns,
show='headings', height=6)
for col in columns:
self.targets_table.heading(col, text=col)
self.targets_table.column(col, width=70)
scrollbar_targets = ttk.Scrollbar(targets_frame, orient='vertical',
command=self.targets_table.yview)
self.targets_table.configure(yscrollcommand=scrollbar_targets.set)
self.targets_table.pack(side='left', fill='both', expand=True)
scrollbar_targets.pack(side='right', fill='y')
def create_sector_analysis_panel(self, parent):
"""Панель анализа угроз по секторам"""
sector_frame = ttk.LabelFrame(parent, text="АНАЛИЗ СЕКТОРОВ", padding=10)
sector_frame.pack(fill='x')
self.sector_text = tk.Text(sector_frame, height=6, width=40,
bg='#000022', fg='#00ffff',
font=('Arial', 9))
self.sector_text.pack(fill='both', expand=True)
def add_random_drone(self):
"""Добавляет случайный БПЛА на границе зоны обнаружения"""
drone_types = ["Разведывательный", "Ударный", "Роевой"]
selected_type = random.choice(drone_types)
# Случайная позиция на границе зоны обнаружения
angle = random.uniform(0, 2 * math.pi)
distance = 1400 # 1.4 км от центра
start_x = math.cos(angle) * distance
start_y = math.sin(angle) * distance
new_drone = DroneEntity(self.drone_counter, selected_type, start_x, start_y)
# СРАЗУ НАПРАВЛЯЕМ ДРОН К ЦЕНТРУ (Лахта Центр)
target_angle = math.degrees(math.atan2(-start_y, -start_x))
new_drone.heading = target_angle
self.active_drones.append(new_drone)
self.drone_counter += 1
print(f"Добавлен {selected_type} БПЛА с направления: {new_drone.approach_direction}")
def activate_ew_system(self):
"""Активирует систему РЭБ против всех обнаруженных целей"""
detected_drones = self.radar_system.detected_targets
if not detected_drones:
messagebox.showinfo("РЭБ", "Нет обнаруженных целей для нейтрализации")
return
neutralized_count = 0
for drone in detected_drones:
if drone.status == "active":
success = self.ew_system.engage_target(drone)
if success:
neutralized_count += 1
self.neutralized_count += 1 # ОБНОВЛЯЕМ СЧЕТЧИК
# Статистика теперь в отдельной панели
self.update_neutralization_stats()
def update_neutralization_stats(self):
"""Обновляет панель статистики нейтрализации"""
self.stats_text.delete(1.0, tk.END)
active_drones = [d for d in self.active_drones if d.status == "active"]
neutralized_drones = [d for d in self.active_drones if d.status == "neutralized"]
stats_info = f"СТАТИСТИКА НЕЙТРАЛИЗАЦИИ:\n\n"
stats_info += f"Всего БПЛА: {len(self.active_drones)}\n"
stats_info += f"Активных: {len(active_drones)}\n"
stats_info += f"Нейтрализовано: {len(neutralized_drones)}\n"
stats_info += f"Общий счет: {self.neutralized_count}\n"
self.stats_text.insert(tk.END, stats_info)
def run_group_attack_scenario(self):
"""Запускает сценарий групповой атаки - БПЛА атакуют Лахта Центр"""
self.reset_simulation()
# Несколько БПЛА с разных направлений, ВСЕ АТАКУЮТ ЛАХТА ЦЕНТР
drones_data = [
(1, "Ударный", 1200, 0), # Восток - атакует центр
(2, "Разведывательный", -1200, 0), # Запад - атакует центр
(3, "Ударный", 0, 1200), # Юг - атакует центр
(4, "Разведывательный", 0, -1200), # Север - атакует центр
]
for drone_id, drone_type, x, y in drones_data:
drone = DroneEntity(drone_id, drone_type, x, y)
# Направляем дроны прямо к центру (Лахта Центр)
target_angle = math.degrees(math.atan2(-y, -x))
drone.heading = target_angle
self.active_drones.append(drone)
messagebox.showinfo("Сценарий", "Запущен сценарий: Координированная групповая атака на Лахта Центр")
def run_swarm_attack_scenario(self):
"""Запускает сценарий роевой атаки - БПЛА появляются со ВСЕХ сторон"""
self.reset_simulation()
# Роевая атака со ВСЕХ направлений
num_drones = 8
for i in range(num_drones):
# Случайное направление по всему кругу
angle = random.uniform(0, 2 * math.pi)
distance = 1300 + random.uniform(-100, 100)
start_x = math.cos(angle) * distance
start_y = math.sin(angle) * distance
drone = DroneEntity(i + 1, "Роевой", start_x, start_y)
# Направляем к центру (Лахта Центр)
target_angle = math.degrees(math.atan2(-start_y, -start_x))
drone.heading = target_angle
self.active_drones.append(drone)
messagebox.showinfo("Сценарий", "Запущен сценарий: Роевая атака со всех направлений на Лахта Центр")
def reset_simulation(self):
"""Полностью сбрасывает симуляцию"""
self.active_drones = []
self.simulation_time = 0
self.drone_counter = 1
self.detection_statistics = {"total": 0, "neutralized": 0}
self.neutralized_count = 0 # СБРАСЫВАЕМ СЧЕТЧИК
self.update_neutralization_stats() # ОБНОВЛЯЕМ СТАТИСТИКУ
messagebox.showinfo("Сброс", "Симуляция сброшена к начальному состоянию")
def start_simulation(self):
"""Запускает основной цикл симуляции"""
self.update_simulation()
self.root.after(50, self.start_simulation) # 20 обновлений в секунду
def update_simulation(self):
"""Основной цикл обновления симуляции"""
# Обновляем время
self.simulation_time += 0.1
# Обновляем позиции всех дронов
for drone in self.active_drones:
drone.update_position(0.1)
# Обнаружение дронов радаром
detected_drones = self.radar_system.scan_for_drones(self.active_drones)
# Анализ угроз и получение рекомендаций
recommendations = self.threat_analyzer.analyze_threats(detected_drones)
# Обновление интерфейса
self.update_tactical_display()
self.update_status_panel(detected_drones)
self.update_recommendations_panel(recommendations)
self.update_targets_table(detected_drones)
self.update_sector_analysis_panel()
self.update_neutralization_stats() # ОБНОВЛЯЕМ СТАТИСТИКУ
def update_tactical_display(self):
"""Обновляет тактический экран"""
self.tactical_canvas.delete("all")
# Масштаб для отображения (1 пиксель = 5 метров)
scale_factor = 0.2
# Рисуем зону обнаружения радара
radar_range_pixels = self.radar_system.detection_range * scale_factor
self.tactical_canvas.create_oval(
450 - radar_range_pixels, 350 - radar_range_pixels, # ЦЕНТР СМЕЩЕН ИЗ-ЗА УВЕЛИЧЕНИЯ
450 + radar_range_pixels, 350 + radar_range_pixels,
outline='#00ff00', dash=(4, 2), width=2
)
# Рисуем зону поражения РЭБ
ew_range_pixels = self.ew_system.engagement_range * scale_factor
self.tactical_canvas.create_oval(
450 - ew_range_pixels, 350 - ew_range_pixels,
450 + ew_range_pixels, 350 + ew_range_pixels,
outline='#ff0000', dash=(2, 2), width=1
)
# Рисуем Лахта Центр в центре
self.tactical_canvas.create_rectangle(445, 345, 455, 355,
fill='#0066cc', outline='white', width=2)
self.tactical_canvas.create_text(450, 335, text="ЛАХТА ЦЕНТР",
fill='white', font=('Arial', 10, 'bold'))
# Рисуем направления (упрощенные основные направления)
directions = {
"СЕВЕР": (450, 150, "СЕВЕР\nПриморское шоссе"),
"ЮГ": (450, 550, "ЮГ\nФинский залив"),
"ЗАПАД": (150, 350, "ЗАПАД\nпос. Ольгино"),
"ВОСТОК": (750, 350, "ВОСТОК\nБЦ Атлантик Сити")
}
for dir_name, (x, y, text) in directions.items():
self.tactical_canvas.create_text(x, y, text=text,
fill='#00ff00', font=('Arial', 9))
# Рисуем все дроны
for drone in self.active_drones:
x = 450 + drone.position_x * scale_factor # ЦЕНТР СМЕЩЕН
y = 350 + drone.position_y * scale_factor
# Выбираем цвет в зависимости от типа дрона
if drone.status == "neutralized":
color = '#666666' # Серый - нейтрализован
elif drone.type == "Ударный":
color = '#ff0000' # Красный - ударный
elif drone.type == "Разведывательный":
color = '#ffff00' # Желтый - разведывательный
else:
color = '#ff00ff' # Фиолетовый - роевой
# Размер маркера
size = 8 if drone.type == "Ударный" else 6
# Рисуем дрон
self.tactical_canvas.create_oval(x - size, y - size, x + size, y + size,
fill=color, outline='white')
# Подпись
status_text = "НЕЙТР" if drone.status == "neutralized" else f"БПЛА-{drone.id}"
self.tactical_canvas.create_text(x, y - 15, text=status_text,
fill=color, font=('Arial', 8))
def update_status_panel(self, detected_drones):
"""Обновляет панель статуса"""
# Время в формате ММ:СС
minutes = int(self.simulation_time // 60)
seconds = int(self.simulation_time % 60)
time_str = f"Время: {minutes:02d}:{seconds:02d}"
self.time_label.config(text=time_str)
# Статус обнаружения
active_drones = [d for d in detected_drones if d.status == "active"]
self.drones_count.config(text=f"Обнаружено БПЛА: {len(detected_drones)}")
self.active_threats.config(text=f"Активных угроз: {len(active_drones)}")
# Общий уровень угрозы
total_threat = sum(drone.threat_level for drone in active_drones)
if len(active_drones) > 0 and any(d.distance_to_target < 300 for d in active_drones):
threat_text = "Уровень угрозы: КРИТИЧЕСКИЙ"
color = 'red'
elif total_threat >= 10:
threat_text = "Уровень угрозы: ОЧЕНЬ ВЫСОКИЙ"
color = 'red'
elif total_threat >= 5:
threat_text = "Уровень угрозы: ВЫСОКИЙ"
color = 'orange'
elif total_threat >= 2:
threat_text = "Уровень угрозы: СРЕДНИЙ"
color = 'yellow'
elif len(active_drones) > 0:
threat_text = "Уровень угрозы: НИЗКИЙ"
color = 'green'
else:
threat_text = "Уровень угрозы: ОТСУТСТВУЕТ"
color = 'blue'
self.threat_level.config(text=threat_text, foreground=color)
def update_recommendations_panel(self, recommendations):
"""Обновляет панель рекомендаций"""
self.recommendations_text.delete(1.0, tk.END)
if recommendations:
for recommendation in recommendations:
self.recommendations_text.insert(tk.END, f"• {recommendation}\n\n")
else:
self.recommendations_text.insert(tk.END, "✅ Нет активных рекомендаций\nСитуация под контролем")
def update_targets_table(self, detected_drones):
"""Обновляет таблицу обнаруженных целей"""
# Очищаем таблицу
for item in self.targets_table.get_children():
self.targets_table.delete(item)
# Заполняем новыми данными
for drone in detected_drones:
self.targets_table.insert("", "end", values=(
drone.id,
drone.type,
drone.threat_level,
drone.approach_direction,
f"{int(drone.distance_to_target)}м",
drone.status
))
def update_sector_analysis_panel(self):
"""Обновляет панель анализа секторов"""
self.sector_text.delete(1.0, tk.END)
for sector, data in self.threat_analyzer.sector_analysis.items():
threat_level = data["threat_level"]
drones_count = data["drones_count"]
terrain = data["terrain"]
if drones_count > 0:
status_text = f"{sector} ({terrain}):\n"
status_text += f" БПЛА: {drones_count} | Угроза: {threat_level}\n"
if threat_level >= 8:
status_text += " 🚨 ВЫСОКАЯ УГРОЗА!\n"
elif threat_level >= 4:
status_text += " ⚠️ Средняя угроза\n"
else:
status_text += " ✅ Низкая угроза\n"
status_text += "\n"
self.sector_text.insert(tk.END, status_text)
else:
self.sector_text.insert(tk.END, f"{sector} ({terrain}): ✅ ЧИСТО\n\n")
# ЗАПУСК ПРОГРАММЫ
if __name__ == "__main__":
root = tk.Tk()
app = EBWSimulatorGUI(root)
root.mainloop()
中文翻译后的代码:
"""
边界防护 - 无人机防御系统虚拟仿真
版本: 1 专业版
开发者: 相关仿真开发团队
用途: 无人机威胁场景下应对操作训练模拟器
"""
import tkinter as tk
from tkinter import ttk, messagebox
import math
import random
import time
from datetime import datetime
class DroneEntity:
"""
无人机实体建模类
包含仿真中无人机的所有参数与行为逻辑
"""
def __init__(self, drone_id, drone_type="侦察型", start_x=0, start_y=0):
# 标识参数
self.id = drone_id
self.type = drone_type # 侦察型 / 攻击型 / 蜂群型
self.status = "active" # active 活跃, neutralized 已拦截, escaped 逃逸
# 位置参数(米,以目标中心为原点)
self.position_x = start_x
self.position_y = start_y
self.altitude = random.randint(50, 300) # 飞行高度 米
# 运动参数
self.speed = random.randint(80, 150) # 速度 km/h
self.heading = random.uniform(0, 360) # 航向 度
self.flight_time = 0 # 已飞行时间 秒
# 战术参数
self.threat_level = self.calculate_threat_level()
self.detection_count = 0 # 被雷达发现次数
self.approach_direction = None # 来袭方向
self.distance_to_target = 0 # 到目标距离
def calculate_threat_level(self):
"""根据无人机类型计算威胁等级"""
threat_matrix = {
"侦察型": 4,
"攻击型": 9,
"蜂群型": 7
}
return threat_matrix.get(self.type, 5)
def update_position(self, time_delta=1.0):
"""更新无人机位置"""
if self.status != "active":
return
speed_mps = (self.speed * 1000) / 3600
speed_mps *= 2.0
target_angle = math.degrees(math.atan2(-self.position_y, -self.position_x))
angle_diff = (target_angle - self.heading + 180) % 360 - 180
if random.random() < 0.95:
self.heading += angle_diff * 0.4
self.position_x += math.cos(math.radians(self.heading)) * speed_mps * time_delta
self.position_y += math.sin(math.radians(self.heading)) * speed_mps * time_delta
self.distance_to_target = math.sqrt(self.position_x ** 2 + self.position_y ** 2)
self.flight_time += time_delta
self.determine_approach_direction()
def determine_approach_direction(self):
"""判断来袭方向"""
x, y = self.position_x, self.position_y
angle = math.degrees(math.atan2(y, x))
if angle < 0:
angle += 360
if 337.5 <= angle or angle < 22.5:
self.approach_direction = "东"
elif 22.5 <= angle < 67.5:
self.approach_direction = "东南"
elif 67.5 <= angle < 112.5:
self.approach_direction = "南"
elif 112.5 <= angle < 157.5:
self.approach_direction = "西南"
elif 157.5 <= angle < 202.5:
self.approach_direction = "西"
elif 202.5 <= angle < 247.5:
self.approach_direction = "西北"
elif 247.5 <= angle < 292.5:
self.approach_direction = "北"
else:
self.approach_direction = "东北"
class RadarSystem:
"""雷达探测系统"""
def __init__(self, position_x, position_y, detection_range=1500):
self.position_x = position_x
self.position_y = position_y
self.detection_range = detection_range
self.azimuth_accuracy = 0.5
self.range_accuracy = 5.0
self.status = "operational"
self.detected_targets = []
self.detection_history = []
def scan_for_drones(self, drone_list):
"""扫描空域并发现无人机"""
detected_drones = []
for drone in drone_list:
if drone.status == "active":
distance = math.sqrt(
(drone.position_x - self.position_x) ** 2 +
(drone.position_y - self.position_y) ** 2
)
if distance <= self.detection_range:
detected_drones.append(drone)
drone.detection_count += 1
record = {
'timestamp': time.time(),
'drone_id': drone.id,
'distance': distance,
'direction': drone.approach_direction
}
self.detection_history.append(record)
self.detected_targets = detected_drones
return detected_drones
class ElectronicWarfareSystem:
"""电子干扰/反制系统"""
def __init__(self, position_x, position_y, engagement_range=800):
self.position_x = position_x
self.position_y = position_y
self.engagement_range = engagement_range
self.power_level = 100
self.status = "standby"
self.engagement_history = []
self.jamming_methods = {
"gps_jamming": 0.95,
"control_jamming": 0.90,
"video_jamming": 0.85,
"swarm_disruption": 0.80
}
def engage_target(self, target_drone, method="auto"):
"""对目标实施电子反制"""
if self.status != "standby" or target_drone.status != "active":
return False
dist = math.sqrt(
(target_drone.position_x - self.position_x) ** 2 +
(target_drone.position_y - self.position_y) ** 2
)
if dist > self.engagement_range:
return False
if method == "auto":
method = self.select_optimal_method(target_drone)
success = True
if success:
target_drone.status = "neutralized"
record = {
'timestamp': time.time(),
'drone_id': target_drone.id,
'method': method,
'distance': dist,
'success': True
}
self.engagement_history.append(record)
return True
return False
def select_optimal_method(self, drone):
"""根据无人机类型选择最优反制手段"""
method_map = {
"侦察型": "gps_jamming",
"攻击型": "control_jamming",
"蜂群型": "swarm_disruption"
}
return method_map.get(drone.type, "control_jamming")
class ThreatAnalysisSystem:
"""威胁分析与决策建议系统"""
def __init__(self):
self.threat_assessments = []
self.recommendations_log = []
self.sector_analysis = {
"北": {"threat_level": 0, "drones_count": 0, "terrain": "滨海高速"},
"东北": {"threat_level": 0, "drones_count": 0, "terrain": "拉赫塔中心西北区"},
"东": {"threat_level": 0, "drones_count": 0, "terrain": "大西洋城商务中心"},
"东南": {"threat_level": 0, "drones_count": 0, "terrain": "东南入口"},
"南": {"threat_level": 0, "drones_count": 0, "terrain": "芬兰湾"},
"西南": {"threat_level": 0, "drones_count": 0, "terrain": "西南入口"},
"西": {"threat_level": 0, "drones_count": 0, "terrain": "奥尔吉诺村"},
"西北": {"threat_level": 0, "drones_count": 0, "terrain": "西北入口"}
}
def analyze_threats(self, detected_drones):
"""分析威胁并生成建议"""
for sec in self.sector_analysis:
self.sector_analysis[sec]["threat_level"] = 0
self.sector_analysis[sec]["drones_count"] = 0
total_threat = 0
active_cnt = 0
recs = []
for d in detected_drones:
if d.status == "active":
sec = d.approach_direction
if sec in self.sector_analysis:
self.sector_analysis[sec]["drones_count"] += 1
self.sector_analysis[sec]["threat_level"] += d.threat_level
total_threat += d.threat_level
active_cnt += 1
r = self.gen_drone_rec(d)
if r not in recs:
recs.append(r)
gen_recs = self.gen_general_recs(total_threat, active_cnt)
recs.extend(gen_recs)
assessment = {
'timestamp': datetime.now(),
'total_threat': total_threat,
'active_threats': active_cnt,
'recommendations': recs,
'sector_analysis': self.sector_analysis.copy()
}
self.threat_assessments.append(assessment)
return recs
def gen_drone_rec(self, drone):
"""单架无人机处置建议"""
base = f"无人机-{drone.id}({drone.type}) - {drone.approach_direction}"
if drone.distance_to_target < 500:
return f"🚨 {base} - 距离极近!立即拦截!"
elif drone.threat_level >= 8:
return f"🚨 {base} - 高威胁!立即启动反制"
elif drone.threat_level >= 5:
return f"⚠️ {base} - 中威胁。准备反制系统"
else:
return f"ℹ️ {base} - 持续监视。距离:{int(drone.distance_to_target)}米"
def gen_general_recs(self, total_threat, active_cnt):
"""全局处置建议"""
recs = []
if not self.sector_analysis:
return recs
max_sec = max(self.sector_analysis.items(), key=lambda x: x[1]["threat_level"])
sec_name, sec_data = max_sec
if sec_data["threat_level"] > 0:
recs.append(f"🎯 主要威胁方向:{sec_name}({sec_data['terrain']})- {sec_data['drones_count']} 架无人机")
if active_cnt == 0:
recs.append("✅ 威胁已清除,态势可控")
elif total_threat >= 15:
recs.append("🚨 态势危急!启动全部反制系统!")
recs.append("📞 上报指挥中心:大规模无人机袭击")
elif total_threat >= 8:
recs.append("⚠️ 高威胁!立即激活反制设备")
elif total_threat >= 3:
recs.append("🔶 中威胁。反制系统待命")
else:
recs.append("🔹 低威胁。持续监视")
if active_cnt > 0:
recs.append("🎯 点击【启动反制】拦截目标")
return recs
class EBWSimulatorGUI:
"""主界面"""
def __init__(self, root_window):
self.root = root_window
self.root.title("反无人机系统 | 拉赫塔中心 专业版 v1")
self.root.geometry("1600x900")
self.root.configure(bg='#0a0a0a')
self.initialize_systems()
self.simulation_time = 0
self.drone_counter = 1
self.simulation_running = True
self.neutralized_count = 0
self.create_interface()
self.start_simulation()
def initialize_systems(self):
self.radar_system = RadarSystem(0, 0, 1500)
self.ew_system = ElectronicWarfareSystem(0, 0, 800)
self.threat_analyzer = ThreatAnalysisSystem()
self.active_drones = []
self.detection_statistics = {"total": 0, "neutralized": 0}
def create_interface(self):
main_container = ttk.Frame(self.root)
main_container.pack(fill='both', expand=True, padx=10, pady=10)
self.create_tactical_display(main_container)
self.create_control_panels(main_container)
def create_tactical_display(self, parent):
tactical_frame = ttk.LabelFrame(parent, text="战术态势", padding=10)
tactical_frame.pack(side='left', fill='both', expand=True, padx=(0, 10))
self.tactical_canvas = tk.Canvas(tactical_frame, width=900, height=700,
bg='#001122', highlightthickness=1,
highlightbackground='#00ff00')
self.tactical_canvas.pack(fill='both', expand=True)
def create_control_panels(self, parent):
right_panel = ttk.Frame(parent)
right_panel.pack(side='right', fill='y')
self.create_status_panel(right_panel)
self.create_control_panel(right_panel)
self.create_recommendations_panel(right_panel)
self.create_neutralization_stats_panel(right_panel)
self.create_targets_panel(right_panel)
self.create_sector_analysis_panel(right_panel)
def create_status_panel(self, parent):
sf = ttk.LabelFrame(parent, text="系统状态", padding=10)
sf.pack(fill='x', pady=(0, 10))
self.time_label = ttk.Label(sf, text="时间:00:00", font=('Arial', 10, 'bold'))
self.time_label.pack(anchor='w')
self.radar_status = ttk.Label(sf, text="雷达:正常工作", foreground='green')
self.radar_status.pack(anchor='w')
self.ew_status = ttk.Label(sf, text="反制系统:就绪", foreground='green')
self.ew_status.pack(anchor='w')
self.threat_level = ttk.Label(sf, text="威胁等级:无", font=('Arial', 11, 'bold'))
self.threat_level.pack(anchor='w')
self.drones_count = ttk.Label(sf, text="已发现无人机:0")
self.drones_count.pack(anchor='w')
self.active_threats = ttk.Label(sf, text="活跃威胁:0")
self.active_threats.pack(anchor='w')
def create_control_panel(self, parent):
cf = ttk.LabelFrame(parent, text="仿真控制", padding=10)
cf.pack(fill='x', pady=(0, 10))
ttk.Button(cf, text="添加无人机", command=self.add_random_drone).pack(fill='x', pady=2)
ttk.Button(cf, text="启动反制", command=self.activate_ew_system).pack(fill='x', pady=2)
ttk.Button(cf, text="场景:编队攻击", command=self.run_group_attack_scenario).pack(fill='x', pady=2)
ttk.Button(cf, text="场景:蜂群攻击", command=self.run_swarm_attack_scenario).pack(fill='x', pady=2)
ttk.Button(cf, text="重置仿真", command=self.reset_simulation).pack(fill='x', pady=2)
def create_recommendations_panel(self, parent):
rf = ttk.LabelFrame(parent, text="系统建议", padding=10)
rf.pack(fill='x', pady=(0, 10))
self.recommendations_text = tk.Text(rf, height=8, width=45,
bg='#001100', fg='#00ff00', font=('Arial', 9))
scrollbar = ttk.Scrollbar(rf, orient='vertical', command=self.recommendations_text.yview)
self.recommendations_text.configure(yscrollcommand=scrollbar.set)
self.recommendations_text.pack(side='left', fill='both', expand=True)
scrollbar.pack(side='right', fill='y')
def create_neutralization_stats_panel(self, parent):
stf = ttk.LabelFrame(parent, text="拦截统计", padding=10)
stf.pack(fill='x', pady=(0, 10))
self.stats_text = tk.Text(stf, height=4, width=40,
bg='#110011', fg='#ff00ff', font=('Arial', 9))
self.stats_text.pack(fill='both', expand=True)
def create_targets_panel(self, parent):
tf = ttk.LabelFrame(parent, text="目标信息", padding=10)
tf.pack(fill='x', pady=(0, 10))
cols = ("ID", "类型", "威胁", "方向", "距离", "状态")
self.targets_table = ttk.Treeview(tf, columns=cols, show='headings', height=6)
for c in cols:
self.targets_table.heading(c, text=c)
self.targets_table.column(c, width=70)
scrollbar = ttk.Scrollbar(tf, orient='vertical', command=self.targets_table.yview)
self.targets_table.configure(yscrollcommand=scrollbar.set)
self.targets_table.pack(side='left', fill='both', expand=True)
scrollbar.pack(side='right', fill='y')
def create_sector_analysis_panel(self, parent):
secf = ttk.LabelFrame(parent, text="方向态势", padding=10)
secf.pack(fill='x')
self.sector_text = tk.Text(secf, height=6, width=40,
bg='#000022', fg='#00ffff', font=('Arial', 9))
self.sector_text.pack(fill='both', expand=True)
def add_random_drone(self):
"""随机添加一架无人机"""
types = ["侦察型", "攻击型", "蜂群型"]
t = random.choice(types)
angle = random.uniform(0, 2 * math.pi)
dist = 1400
x = math.cos(angle) * dist
y = math.sin(angle) * dist
d = DroneEntity(self.drone_counter, t, x, y)
d.heading = math.degrees(math.atan2(-y, -x))
self.active_drones.append(d)
self.drone_counter += 1
def activate_ew_system(self):
"""启动反制"""
targets = self.radar_system.detected_targets
if not targets:
messagebox.showinfo("反制系统", "暂无可拦截目标")
return
cnt = 0
for d in targets:
if d.status == "active":
if self.ew_system.engage_target(d):
cnt += 1
self.neutralized_count += 1
self.update_neutralization_stats()
def update_neutralization_stats(self):
self.stats_text.delete(1.0, tk.END)
total = len(self.active_drones)
active = len([d for d in self.active_drones if d.status == "active"])
neut = len([d for d in self.active_drones if d.status == "neutralized"])
txt = f"拦截统计:\n\n"
txt += f"总目标:{total}\n"
txt += f"活跃:{active}\n"
txt += f"已拦截:{neut}\n"
txt += f"累计计数:{self.neutralized_count}"
self.stats_text.insert(tk.END, txt)
def run_group_attack_scenario(self):
"""编队攻击场景"""
self.reset_simulation()
data = [
(1, "攻击型", 1200, 0),
(2, "侦察型", -1200, 0),
(3, "攻击型", 0, 1200),
(4, "侦察型", 0, -1200),
]
for did, t, x, y in data:
d = DroneEntity(did, t, x, y)
d.heading = math.degrees(math.atan2(-y, -x))
self.active_drones.append(d)
messagebox.showinfo("场景", "已启动:编队协同攻击")
def run_swarm_attack_scenario(self):
"""蜂群攻击场景"""
self.reset_simulation()
for i in range(8):
angle = random.uniform(0, 2 * math.pi)
dist = 1300 + random.uniform(-100, 100)
x = math.cos(angle) * dist
y = math.sin(angle) * dist
d = DroneEntity(i + 1, "蜂群型", x, y)
d.heading = math.degrees(math.atan2(-y, -x))
self.active_drones.append(d)
messagebox.showinfo("场景", "已启动:全方位蜂群攻击")
def reset_simulation(self):
self.active_drones = []
self.simulation_time = 0
self.drone_counter = 1
self.detection_statistics = {"total": 0, "neutralized": 0}
self.neutralized_count = 0
self.update_neutralization_stats()
messagebox.showinfo("重置", "仿真已重置")
def start_simulation(self):
self.update_simulation()
self.root.after(50, self.start_simulation)
def update_simulation(self):
self.simulation_time += 0.1
for d in self.active_drones:
d.update_position(0.1)
detected = self.radar_system.scan_for_drones(self.active_drones)
recs = self.threat_analyzer.analyze_threats(detected)
self.update_tactical_display()
self.update_status_panel(detected)
self.update_recommendations_panel(recs)
self.update_targets_table(detected)
self.update_sector_analysis_panel()
self.update_neutralization_stats()
def update_tactical_display(self):
self.tactical_canvas.delete("all")
scale = 0.2
cx, cy = 450, 350
# 雷达范围
rr = self.radar_system.detection_range * scale
self.tactical_canvas.create_oval(cx - rr, cy - rr, cx + rr, cy + rr,
outline='#00ff00', dash=(4, 2), width=2)
# 反制范围
er = self.ew_system.engagement_range * scale
self.tactical_canvas.create_oval(cx - er, cy - er, cx + er, cy + er,
outline='#ff0000', dash=(2, 2), width=1)
# 保护目标
self.tactical_canvas.create_rectangle(cx - 5, cy - 5, cx + 5, cy + 5,
fill='#0066cc', outline='white', width=2)
self.tactical_canvas.create_text(cx, cy - 15, text="拉赫塔中心",
fill='white', font=('Arial', 10, 'bold'))
# 方向标注
dirs = {
"北": (cx, cy - 200, "北\n滨海高速"),
"南": (cx, cy + 200, "南\n芬兰湾"),
"西": (cx - 300, cy, "西\n奥尔吉诺村"),
"东": (cx + 300, cy, "东\n商务中心")
}
for k, (x, y, txt) in dirs.items():
self.tactical_canvas.create_text(x, y, text=txt, fill='#00ff00', font=('Arial', 9))
# 绘制无人机
for d in self.active_drones:
x = cx + d.position_x * scale
y = cy + d.position_y * scale
if d.status == "neutralized":
color = '#666666'
elif d.type == "攻击型":
color = '#ff0000'
elif d.type == "侦察型":
color = '#ffff00'
else:
color = '#ff00ff'
size = 8 if d.type == "攻击型" else 6
self.tactical_canvas.create_oval(x - size, y - size, x + size, y + size,
fill=color, outline='white')
tag = f"U{d.id}" if d.status == "active" else "已拦截"
self.tactical_canvas.create_text(x, y - 15, text=tag, fill=color, font=('Arial', 8))
def update_status_panel(self, detected):
m = int(self.simulation_time // 60)
s = int(self.simulation_time % 60)
self.time_label.config(text=f"时间:{m:02d}:{s:02d}")
active = [d for d in detected if d.status == "active"]
self.drones_count.config(text=f"已发现无人机:{len(detected)}")
self.active_threats.config(text=f"活跃威胁:{len(active)}")
total_threat = sum(d.threat_level for d in active)
near = any(d.distance_to_target < 300 for d in active) if active else False
if near:
t = "威胁等级:极度危险"
c = "red"
elif total_threat >= 10:
t = "威胁等级:极高"
c = "red"
elif total_threat >= 5:
t = "威胁等级:高"
c = "orange"
elif total_threat >= 2:
t = "威胁等级:中等"
c = "yellow"
elif active:
t = "威胁等级:低"
c = "green"
else:
t = "威胁等级:无"
c = "blue"
self.threat_level.config(text=t, foreground=c)
def update_recommendations_panel(self, recs):
self.recommendations_text.delete(1.0, tk.END)
if recs:
for r in recs:
self.recommendations_text.insert(tk.END, f"• {r}\n\n")
else:
self.recommendations_text.insert(tk.END, "✅ 无处置建议\n态势安全可控")
def update_targets_table(self, detected):
for i in self.targets_table.get_children():
self.targets_table.delete(i)
for d in detected:
self.targets_table.insert("", "end", values=(
d.id, d.type, d.threat_level,
d.approach_direction, f"{int(d.distance_to_target)}米", d.status
))
def update_sector_analysis_panel(self):
self.sector_text.delete(1.0, tk.END)
for sec, data in self.threat_analyzer.sector_analysis.items():
tl = data["threat_level"]
cnt = data["drones_count"]
ter = data["terrain"]
if cnt > 0:
line = f"{sec}({ter}):\n"
line += f" 无人机:{cnt} 威胁值:{tl}\n"
if tl >= 8:
line += " 🚨 高威胁\n"
elif tl >= 4:
line += " ⚠️ 中威胁\n"
else:
line += " ✅ 低威胁\n"
line += "\n"
self.sector_text.insert(tk.END, line)
else:
self.sector_text.insert(tk.END, f"{sec}({ter}):✅ 安全\n\n")
if __name__ == "__main__":
root = tk.Tk()
app = EBWSimulatorGUI(root)
root.mainloop()

本博客是博主个人学习时的一些记录,不保证是为原创,个别文章加入了转载的源地址,还有个别文章是汇总网上多份资料所成,在这之中也必有疏漏未加标注处,如有侵权请与博主联系。
如果未特殊标注则为原创,遵循 CC 4.0 BY-SA 版权协议。
posted on 2026-08-03 13:24 Angry_Panda 阅读(2) 评论(0) 收藏 举报
浙公网安备 33010602011771号