仿真环境下的反无人机系统 —— Virtual_Simulation_of_an_Anti-UAV_Defense_System —— 反无仿真

地址:

https://github.com/KirillAleksandrovich/PERIMETER-Virtual_Simulation_of_an_Anti-UAV_Defense_System




image


image




image


image


image




阿拉伯文的源代码:

"""
ПЕРИМЕТР - Виртуальная симуляция системы защиты от БПЛА
Версия: 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()




image







posted on 2026-08-03 13:24  Angry_Panda  阅读(2)  评论(0)    收藏  举报

导航