```python
import math
import tkinter as tk
from tkinter import ttk, messagebox
from tkinter import Canvas

# Константы
G0 = 9.80665  # Стандартное ускорение свободного падения, м/с²
k_B = 1.38e-23  # Постоянная Болцмана, Дж/К
mu_0 = 4 * math.pi * 1e-7  # Магнитная проницаемость вакуума, Т·м/А

class PowerUnit:
    def __init__(self, power_density, efficiency, mass, energy_density=2.5e7, solar_area=10, solar_efficiency=0.3, nuclear_power_density=5000, nuclear_efficiency=0.9):
        """
        Параметры:
        - power_density: Плотность мощности батареи (Вт/кг)
        - efficiency: КПД преобразования энергии (0 < efficiency <= 1)
        - mass: Масса батареи (кг)
        - energy_density: Энергетическая плотность батареи (J/kg)
        - solar_area: Площадь солнечных панелей (м²)
        - solar_efficiency: КПД солнечных панелей (0 < solar_efficiency <= 1)
        - nuclear_power_density: Плотность мощности ядерных батарей (Вт/кг)
        - nuclear_efficiency: КПД преобразования энергии ядерных батарей (0 < nuclear_efficiency <= 1)
        """
        self.power_density = power_density
        self.efficiency = efficiency
        self.mass = mass
        self.energy_density = energy_density
        self.solar_area = solar_area
        self.solar_efficiency = solar_efficiency
        self.nuclear_power_density = nuclear_power_density
        self.nuclear_efficiency = nuclear_efficiency
        
        self.generated_power = self.calculate_generated_power()  # Общая мощность (Вт)
        self.battery_mass = 0  # Масса батареи для хранения необходимой энергии
        
    def calculate_generated_power(self):
        """
        Расчет общей мощности, генерируемой батареями и солнечными панелями.
        """
        # Солнечная мощность: P = A * eta_solar * E (где E = 1361 W/m²)
        E_solar = 1361  # Средняя солнечная радиация (Вт/м²)
        solar_power = self.solar_area * self.solar_efficiency * E_solar
        
        # Ядерная мощность: P = rho_nuclear * eta_nuclear * M
        nuclear_power = self.nuclear_power_density * self.nuclear_efficiency * self.mass
        
        # Мощность батареи: P = power_density * mass * efficiency
        battery_power = self.power_density * self.mass * self.efficiency
        
        # Общая мощность
        total_power = solar_power + nuclear_power + battery_power
        return total_power
    
    def get_power(self):
        return self.generated_power
    
    def calculate_energy_storage_mass(self, total_energy_required):
        """
        Расчет массы батареи для хранения общей необходимой энергии.
        """
        return total_energy_required / self.energy_density


class PlasmaThruster:
    def __init__(self, efficiency, V, mi, charge, thrust_method='energy_based', B_field=0, plasma_density=1e20, plasma_temperature=1e5):
        """
        Параметры:
        - efficiency: КПД тяги (0 < efficiency <= 1)
        - V: Ускоряющее напряжение (В)
        - mi: Масса иона (кг)
        - charge: Заряд иона (Кл)
        - thrust_method: Метод расчета тяги ('energy_based' или 'momentum_based')
        - B_field: Магнитное поле (Т) для конфинемента
        - plasma_density: Плотность плазмы (частиц/м³)
        - plasma_temperature: Температура плазмы (K)
        """
        self.efficiency = efficiency
        self.V = V
        self.mi = mi
        self.charge = charge
        self.thrust_method = thrust_method
        self.B_field = B_field
        self.plasma_density = plasma_density
        self.plasma_temperature = plasma_temperature
    
    def calculate_exhaust_velocity(self):
        """
        v_e = (q * V) / m_i
        """
        ve = (self.charge * self.V) / self.mi
        return ve
    
    def calculate_specific_impulse(self):
        """
        I_sp = v_e / g0
        """
        ve = self.calculate_exhaust_velocity()
        I_sp = ve / G0
        return I_sp
    
    def calculate_thrust_energy_based(self, power):
        """
        F = (2 * η * P) / v_e
        """
        ve = self.calculate_exhaust_velocity()
        if ve == 0:
            return 0
        F = (2 * self.efficiency * power) / ve
        return F
    
    def calculate_thrust_momentum_based(self, mass_flow_rate):
        """
        F = m_dot * v_e
        """
        ve = self.calculate_exhaust_velocity()
        F = mass_flow_rate * ve
        return F
    
    def calculate_power_consumption_energy_based(self, thrust):
        """
        P = (F * v_e) / (2 * η)
        """
        ve = self.calculate_exhaust_velocity()
        if self.efficiency == 0:
            return float('inf')
        P = (thrust * ve) / (2 * self.efficiency)
        return P
    
    def calculate_power_consumption_momentum_based(self, thrust):
        """
        P = 0.5 * m_dot * v_e^2
        """
        ve = self.calculate_exhaust_velocity()
        if ve == 0:
            return float('inf')
        m_dot = thrust / ve
        P = 0.5 * m_dot * ve ** 2
        return P
    
    def calculate_ionization_energy(self):
        """
        Расчет энергии ионизации:
        E_ionize = 0.5 * m_e * v_e^2 + phi
        Предполагается phi (энергия ионизации) = 15.76 eV для ксенона
        """
        phi = 15.76 * 1.602e-19  # Дж
        ve = self.calculate_exhaust_velocity()
        m_e = 9.109e-31  # кг
        E_ionize = 0.5 * m_e * ve ** 2 + phi
        return E_ionize
    
    def calculate_lorentz_force(self, current, length):
        """
        F = q (v x B)
        Для простоты предположим, что v перпендикулярно B и постоянна:
        F = q * v * B
        """
        ve = self.calculate_exhaust_velocity()
        F = self.charge * ve * self.B_field
        return F
    
    def calculate_pressure(self):
        """
        Идеальный газ для плазмы: P = n * k_B * T
        """
        P = self.plasma_density * k_B * self.plasma_temperature
        return P


class ThermalManagement:
    def __init__(self, emissivity=0.8, sigma=5.67e-8, area=10, T_env=300, phase_change_energy=1e6, PCM_mass=10, c_p=1000):
        """
        Параметры:
        - emissivity: Эмиссивность (dimensionless)
        - sigma: Постоянная Стефана-Болцмана (W/m²K⁴)
        - area: Площадь радиаторов (м²)
        - T_env: Температура окружающей среды (K)
        - phase_change_energy: Латентная теплота PCM (J/kg)
        - PCM_mass: Масса PCM (kg)
        - c_p: Удельная теплоемкость PCM (J/kg•K)
        """
        self.epsilon = emissivity
        self.sigma = sigma
        self.A = area
        self.T_env = T_env
        self.phase_change_energy = phase_change_energy
        self.PCM_mass = PCM_mass
        self.c_p = c_p
    
    def calculate_radiative_heat_transfer(self, T):
        """
        Q = epsilon * sigma * A * (T^4 - T_env^4)
        """
        Q = self.epsilon * self.sigma * self.A * (T ** 4 - self.T_env ** 4)
        return Q
    
    def calculate_phase_change_energy_absorbed(self):
        """
        Q = m * L
        """
        Q = self.PCM_mass * self.phase_change_energy
        return Q
    
    def calculate_heat_capacity(self, mass, delta_T):
        """
        Q = m * c_p * delta_T
        """
        Q = mass * self.c_p * delta_T
        return Q


class StructuralEngineering:
    def __init__(self, area=1, sigma_yield=250e6, E=70e9, I=1e-4, k=200, mass=100, length=5):
        """
        Параметры:
        - area: Площадь поперечного сечения (м²)
        - sigma_yield: Предел текучести материала (Па)
        - E: Модуль Юнга (Па)
        - I: Момент инерции (м⁴)
        - k: Жесткость пружины для анализа вибраций (Н/м)
        - mass: Масса структурного компонента (kg)
        - length: Длина балки (m)
        """
        self.A = area
        self.sigma_yield = sigma_yield
        self.E = E
        self.I = I
        self.k = k
        self.mass = mass
        self.length = length
    
    def calculate_stress(self, F):
        """
        sigma = F / A
        """
        sigma = F / self.A
        return sigma
    
    def check_yield_strength(self, F):
        """
        Проверить, что sigma < sigma_yield
        """
        sigma = self.calculate_stress(F)
        return sigma < self.sigma_yield
    
    def calculate_beam_deflection(self, F):
        """
        delta = (F * L^3) / (3 * E * I)
        """
        delta = (F * self.length ** 3) / (3 * self.E * self.I)
        return delta
    
    def calculate_natural_frequency(self):
        """
        f = (1 / (2 * pi)) * sqrt(k / m)
        """
        f = (1 / (2 * math.pi)) * math.sqrt(self.k / self.mass)
        return f


class ControlSystem:
    def __init__(self, Kp=1.0, Ki=0.1, Kd=0.05):
        """
        Параметры:
        - Kp: Пропорциональный коэффициент
        - Ki: Интегральный коэффициент
        - Kd: Дифференциальный коэффициент
        """
        self.Kp = Kp
        self.Ki = Ki
        self.Kd = Kd
        self.integral = 0
        self.previous_error = 0
    
    def compute(self, setpoint, measurement, delta_t):
        """
        Вычислить выход PID-контроллера
        """
        error = setpoint - measurement
        self.integral += error * delta_t
        derivative = (error - self.previous_error) / delta_t if delta_t > 0 else 0
        output = self.Kp * error + self.Ki * self.integral + self.Kd * derivative
        self.previous_error = error
        return output


class Rocket:
    def __init__(self, mass_initial, power_unit, thruster, thermal_management, structural_engineering, control_system, modules=1, payload_mass=500):
        """
        Параметры:
        - mass_initial: Начальная масса ракеты (kg)
        - power_unit: Экземпляр PowerUnit
        - thruster: Экземпляр PlasmaThruster
        - thermal_management: Экземпляр ThermalManagement
        - structural_engineering: Экземпляр StructuralEngineering
        - control_system: Экземпляр ControlSystem
        - modules: Количество модулей двигателя
        - payload_mass: Масса полезной нагрузки (kg)
        """
        self.mass_initial = mass_initial
        self.mass = mass_initial
        self.power_unit = power_unit
        self.thruster = thruster
        self.thermal_management = thermal_management
        self.structural_engineering = structural_engineering
        self.control_system = control_system
        self.modules = modules
        self.payload_mass = payload_mass
        self.total_power = self.power_unit.get_power() * self.modules
        self.ve = self.thruster.calculate_exhaust_velocity()
        self.I_sp = self.thruster.calculate_specific_impulse()
        self.total_thrust = 0
        self.mass_flow_rate = 0
        self.theta = 0  # Угол наклона, может быть расширен
    
    def step(self, delta_t, desired_thrust):
        """
        Выполнить один шаг симуляции.
        Параметры:
        - delta_t: Шаг времени (s)
        - desired_thrust: Желаемая тяга (N)
        Возвращает:
        - thrust: Тяга (N)
        - dm: Израсходованная масса пропеллента (kg)
        """
        # PID-контроллер для регулировки мощности
        current_thrust = self.total_thrust
        control_output = self.control_system.compute(desired_thrust, current_thrust, delta_t)
        
        # Регулируем общую мощность на основе выходного сигнала контроллера
        # Для простоты предполагается, что выходной сигнал напрямую влияет на мощность
        # В реальности это взаимодействует с мощностной электроникой
        adjusted_power = self.total_power + control_output
        adjusted_power = max(adjusted_power, 0)  # Мощность не может быть отрицательной
        self.total_power = adjusted_power
    
        # Расчет тяги в зависимости от метода
        if self.thruster.thrust_method == 'energy_based':
            thrust = self.thruster.calculate_thrust_energy_based(self.total_power)
            # m_dot = 2P / v_e^2
            if self.ve == 0:
                self.mass_flow_rate = 0
            else:
                self.mass_flow_rate = (2 * self.total_power) / (self.ve ** 2)
        elif self.thruster.thrust_method == 'momentum_based':
            # m_dot = F / v_e
            if self.ve == 0:
                self.mass_flow_rate = 0
            else:
                self.mass_flow_rate = desired_thrust / self.ve
            thrust = self.thruster.calculate_thrust_momentum_based(self.mass_flow_rate)
        else:
            thrust = 0
    
        self.total_thrust = thrust
    
        # Расход массы пропеллента
        dm = self.mass_flow_rate * delta_t
        if self.mass - dm < self.payload_mass + self.structural_engineering.mass:
            # Избежать снижения массы ниже массы полезной нагрузки и структурных компонентов
            dm = self.mass - (self.payload_mass + self.structural_engineering.mass)
            self.mass = self.payload_mass + self.structural_engineering.mass
        else:
            self.mass -= dm
    
        # Тепловые расчеты (пример, можно расширить)
        Q_generated = self.total_power * delta_t  # Генерация тепла
        Q_dissipated = self.thermal_management.calculate_radiative_heat_transfer(600)  # Предполагаемая температура 600K
        Q_PCM = self.thermal_management.calculate_phase_change_energy_absorbed()
        if Q_generated > Q_PCM:
            # Обработка перегрева, например, снижение тяги или другие меры
            pass
    
        # Структурные расчеты
        stress = self.structural_engineering.calculate_stress(thrust)
        if not self.structural_engineering.check_yield_strength(thrust):
            # Обработка структурного повреждения, например, прекращение симуляции или снижение тяги
            pass
    
        return thrust, dm
    
    def simulate(self, duration, delta_t, desired_thrust):
        """
        Выполнить симуляцию работы ракеты.
        Параметры:
        - duration: Общая продолжительность симуляции (s)
        - delta_t: Шаг времени (s)
        - desired_thrust: Желаемая тяга (N)
        Возвращает:
        - times, speeds, masses, thrusts, delta_v: Списки данных симуляции и Δv
        """
        times = []
        speeds = []
        masses = []
        thrusts = []
    
        velocity = 0.0
        time_elapsed = 0.0
    
        while time_elapsed <= duration and self.mass > self.payload_mass + self.structural_engineering.mass:
            thrust, dm = self.step(delta_t, desired_thrust)
            acceleration = thrust / self.mass if self.mass != 0 else 0  # a = F / m
            velocity += acceleration * delta_t
            time_elapsed += delta_t
    
            times.append(time_elapsed)
            speeds.append(velocity)
            masses.append(self.mass)
            thrusts.append(thrust)
    
        # Рассчитать изменение скорости с использованием Тсиолковского ракетного уравнения
        delta_v = self.I_sp * G0 * math.log(self.mass_initial / self.mass) if self.mass > 0 else 0
    
        return times, speeds, masses, thrusts, delta_v


class MHPEPS_Simulator(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("MHPEPS Симулятор")
        self.geometry("1200x800")
        self.create_widgets()
    
    def create_widgets(self):
        # Основной контейнер с разделением на левую (параметры) и правую (анимация) части
        main_frame = ttk.Frame(self)
        main_frame.pack(fill=tk.BOTH, expand=True)
    
        # Левая часть - Панель ввода с прокруткой
        input_frame = ttk.Frame(main_frame)
        input_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=False)
    
        # Создаем Canvas и Scrollbar для ввода параметров
        canvas = Canvas(input_frame, width=500, height=800)
        scrollbar = ttk.Scrollbar(input_frame, orient="vertical", command=canvas.yview)
        scrollable_frame = ttk.Frame(canvas)
    
        scrollable_frame.bind(
            "<Configure>",
            lambda e: canvas.configure(
                scrollregion=canvas.bbox("all")
            )
        )
    
        canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
    
        canvas.configure(yscrollcommand=scrollbar.set)
    
        canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
    
        # Правая часть - Анимация
        animation_frame = ttk.Frame(main_frame)
        animation_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
    
        # Кнопка для запуска анимации
        ttk.Button(animation_frame, text="Показать Анимацию Ракеты", command=self.show_animation).pack(pady=10)
    
        # Кнопка для запуска симуляции
        ttk.Button(input_frame, text="Запустить Симуляцию", command=self.run_simulation).pack(pady=20)
    
        # Создаем поля ввода параметров в scrollable_frame
        # PowerUnit Parameters
        ttk.Label(scrollable_frame, text="PowerUnit Параметры", font=("Helvetica", 12, "bold")).pack(pady=5)
        self.pu_power_density = self.create_labeled_entry(scrollable_frame, "Плотность Мощности (Вт/кг):", "3000")
        self.pu_efficiency = self.create_labeled_entry(scrollable_frame, "КПД Преобразования Энергии:", "0.95")
        self.pu_mass = self.create_labeled_entry(scrollable_frame, "Масса Батареи (кг):", "50")
        self.pu_energy_density = self.create_labeled_entry(scrollable_frame, "Энергетическая Плотность Батареи (J/kg):", "2.5e7")
        self.pu_solar_area = self.create_labeled_entry(scrollable_frame, "Площадь Солнечных Панелей (м²):", "20")
        self.pu_solar_efficiency = self.create_labeled_entry(scrollable_frame, "КПД Солнечных Панелей:", "0.3")
        self.pu_nuclear_power_density = self.create_labeled_entry(scrollable_frame, "Плотность Мощности Ядерных Батарей (Вт/кг):", "5000")
        self.pu_nuclear_efficiency = self.create_labeled_entry(scrollable_frame, "КПД Преобразования Энергии Ядерных Батарей:", "0.9")
    
        # PlasmaThruster Parameters
        ttk.Label(scrollable_frame, text="PlasmaThruster Параметры", font=("Helvetica", 12, "bold")).pack(pady=5)
        self.pt_efficiency = self.create_labeled_entry(scrollable_frame, "КПД Тяги (η):", "0.85")
        self.pt_voltage = self.create_labeled_entry(scrollable_frame, "Напряжение Ускорения (В):", "10000")
        self.pt_mi = self.create_labeled_entry(scrollable_frame, "Масса Иона (кг):", "2.18e-22")
        self.pt_charge = self.create_labeled_entry(scrollable_frame, "Заряд Иона (Кл):", "1.6e-19")
        self.thrust_method_var = tk.StringVar(value='energy_based')
        thrust_method_frame = ttk.Frame(scrollable_frame)
        thrust_method_frame.pack(fill=tk.X, pady=2)
        ttk.Label(thrust_method_frame, text="Метод Расчета Тяги:", width=35, anchor=tk.W).pack(side=tk.LEFT)
        ttk.Radiobutton(thrust_method_frame, text='На Энергии', variable=self.thrust_method_var, value='energy_based').pack(side=tk.LEFT)
        ttk.Radiobutton(thrust_method_frame, text='На Импульсе', variable=self.thrust_method_var, value='momentum_based').pack(side=tk.LEFT)
        self.pt_B_field = self.create_labeled_entry(scrollable_frame, "Магнитное Поле (T):", "0")
        self.pt_plasma_density = self.create_labeled_entry(scrollable_frame, "Плотность Плазмы (м⁻³):", "1e20")
        self.pt_plasma_temperature = self.create_labeled_entry(scrollable_frame, "Температура Плазмы (K):", "1e5")
    
        # ThermalManagement Parameters
        ttk.Label(scrollable_frame, text="ThermalManagement Параметры", font=("Helvetica", 12, "bold")).pack(pady=5)
        self.tm_emissivity = self.create_labeled_entry(scrollable_frame, "Эмиссивность:", "0.8")
        self.tm_area = self.create_labeled_entry(scrollable_frame, "Площадь Радиаторов (м²):", "10")
        self.tm_T_env = self.create_labeled_entry(scrollable_frame, "Температура Окружения (K):", "300")
        self.tm_PCM_energy = self.create_labeled_entry(scrollable_frame, "Латентная Теплота PCM (J/kg):", "1e6")
        self.tm_PCM_mass = self.create_labeled_entry(scrollable_frame, "Масса PCM (kg):", "10")
        self.tm_c_p = self.create_labeled_entry(scrollable_frame, "Удельная Теплоемкость PCM (J/kg•K):", "1000")
    
        # StructuralEngineering Parameters
        ttk.Label(scrollable_frame, text="StructuralEngineering Параметры", font=("Helvetica", 12, "bold")).pack(pady=5)
        self.se_area = self.create_labeled_entry(scrollable_frame, "Площадь Поперечного Сечения (м²):", "1")
        self.se_sigma_yield = self.create_labeled_entry(scrollable_frame, "Предел Текучести (Pa):", "250e6")
        self.se_E = self.create_labeled_entry(scrollable_frame, "Модуль Юнга (Pa):", "70e9")
        self.se_I = self.create_labeled_entry(scrollable_frame, "Момент Инерции (m⁴):", "1e-4")
        self.se_k = self.create_labeled_entry(scrollable_frame, "Жесткость Пружины (N/m):", "200")
        self.se_mass = self.create_labeled_entry(scrollable_frame, "Масса Структуры (kg):", "100")
        self.se_length = self.create_labeled_entry(scrollable_frame, "Длина Балки (m):", "5")
    
        # ControlSystem Parameters
        ttk.Label(scrollable_frame, text="ControlSystem Параметры", font=("Helvetica", 12, "bold")).pack(pady=5)
        self.cs_Kp = self.create_labeled_entry(scrollable_frame, "PID Kp:", "1.0")
        self.cs_Ki = self.create_labeled_entry(scrollable_frame, "PID Ki:", "0.1")
        self.cs_Kd = self.create_labeled_entry(scrollable_frame, "PID Kd:", "0.05")
    
        # Rocket Parameters
        ttk.Label(scrollable_frame, text="Rocket Параметры", font=("Helvetica", 12, "bold")).pack(pady=5)
        self.rocket_mass_initial = self.create_labeled_entry(scrollable_frame, "Начальная Масса Ракеты (kg):", "1500")
        self.rocket_payload_mass = self.create_labeled_entry(scrollable_frame, "Масса Полезной Нагрузки (kg):", "500")
        self.rocket_modules = self.create_labeled_entry(scrollable_frame, "Количество Модулей Двигателя:", "4")
    
        # Simulation Parameters
        ttk.Label(scrollable_frame, text="Simulation Параметры", font=("Helvetica", 12, "bold")).pack(pady=5)
        self.sim_duration = self.create_labeled_entry(scrollable_frame, "Продолжительность (s):", "1000")
        self.sim_delta_t = self.create_labeled_entry(scrollable_frame, "Шаг Времени (s):", "1")
        self.sim_desired_thrust = self.create_labeled_entry(scrollable_frame, "Желаемая Тяга (N):", "5000")
    
        # Initialize simulation data
        self.simulation_data = None
    
    def create_labeled_entry(self, parent, label_text, default_value):
        """
        Создание комплектов метки и поля ввода.
        """
        frame = ttk.Frame(parent)
        frame.pack(fill=tk.X, pady=2)
        label = ttk.Label(frame, text=label_text, width=35, anchor=tk.W)
        label.pack(side=tk.LEFT)
        entry = ttk.Entry(frame)
        entry.insert(0, default_value)
        entry.pack(side=tk.RIGHT, fill=tk.X, expand=True)
        return entry
    
    def run_simulation(self):
        try:
            # Получение и преобразование параметров
            pu_power_density = float(self.pu_power_density.get())
            pu_efficiency = float(self.pu_efficiency.get())
            pu_mass = float(self.pu_mass.get())
            pu_energy_density = float(self.pu_energy_density.get())
            pu_solar_area = float(self.pu_solar_area.get())
            pu_solar_efficiency = float(self.pu_solar_efficiency.get())
            pu_nuclear_power_density = float(self.pu_nuclear_power_density.get())
            pu_nuclear_efficiency = float(self.pu_nuclear_efficiency.get())
    
            pt_efficiency = float(self.pt_efficiency.get())
            pt_voltage = float(self.pt_voltage.get())
            pt_mi = float(self.pt_mi.get())
            pt_charge = float(self.pt_charge.get())
            thrust_method = self.thrust_method_var.get()
            pt_B_field = float(self.pt_B_field.get())
            pt_plasma_density = float(self.pt_plasma_density.get())
            pt_plasma_temperature = float(self.pt_plasma_temperature.get())
    
            tm_emissivity = float(self.tm_emissivity.get())
            tm_area = float(self.tm_area.get())
            tm_T_env = float(self.tm_T_env.get())
            tm_PCM_energy = float(self.tm_PCM_energy.get())
            tm_PCM_mass = float(self.tm_PCM_mass.get())
            tm_c_p = float(self.tm_c_p.get())
    
            se_area = float(self.se_area.get())
            se_sigma_yield = float(self.se_sigma_yield.get())
            se_E = float(self.se_E.get())
            se_I = float(self.se_I.get())
            se_k = float(self.se_k.get())
            se_mass = float(self.se_mass.get())
            se_length = float(self.se_length.get())
    
            cs_Kp = float(self.cs_Kp.get())
            cs_Ki = float(self.cs_Ki.get())
            cs_Kd = float(self.cs_Kd.get())
    
            rocket_mass_initial = float(self.rocket_mass_initial.get())
            rocket_payload_mass = float(self.rocket_payload_mass.get())
            rocket_modules = int(float(self.rocket_modules.get()))
    
            sim_duration = float(self.sim_duration.get())
            sim_delta_t = float(self.sim_delta_t.get())
            sim_desired_thrust = float(self.sim_desired_thrust.get())
    
            # Валидация параметров
            if any([
                pu_power_density <= 0,
                pu_efficiency <= 0 or pu_efficiency > 1,
                pu_mass <= 0,
                pu_energy_density <= 0,
                pu_solar_area < 0,
                pu_solar_efficiency < 0 or pu_solar_efficiency > 1,
                pu_nuclear_power_density < 0,
                pu_nuclear_efficiency < 0 or pu_nuclear_efficiency > 1,
                pt_efficiency <= 0 or pt_efficiency > 1,
                pt_voltage <= 0,
                pt_mi <= 0,
                pt_charge == 0,
                se_area <= 0,
                se_sigma_yield <= 0,
                se_E <= 0,
                se_I <= 0,
                se_k <= 0,
                se_mass <= 0,
                se_length <= 0,
                tm_emissivity <= 0 or tm_emissivity > 1,
                tm_area < 0,
                tm_T_env < 0,
                tm_PCM_energy <= 0,
                tm_PCM_mass < 0,
                rocket_mass_initial <= rocket_payload_mass + se_mass,
                rocket_modules <= 0,
                sim_duration <= 0,
                sim_delta_t <= 0,
                sim_desired_thrust < 0
            ]):
                raise ValueError("Пожалуйста, введите корректные положительные значения.")
    
            # Инициализация подсистем
            power_unit = PowerUnit(
                power_density=pu_power_density,
                efficiency=pu_efficiency,
                mass=pu_mass,
                energy_density=pu_energy_density,
                solar_area=pu_solar_area,
                solar_efficiency=pu_solar_efficiency,
                nuclear_power_density=pu_nuclear_power_density,
                nuclear_efficiency=pu_nuclear_efficiency
            )
    
            thruster = PlasmaThruster(
                efficiency=pt_efficiency,
                V=pt_voltage,
                mi=pt_mi,
                charge=pt_charge,
                thrust_method=thrust_method,
                B_field=pt_B_field,
                plasma_density=pt_plasma_density,
                plasma_temperature=pt_plasma_temperature
            )
    
            thermal_management = ThermalManagement(
                emissivity=tm_emissivity,
                sigma=5.67e-8,  # Постоянная Стефана-Болцмана
                area=tm_area,
                T_env=tm_T_env,
                phase_change_energy=tm_PCM_energy,
                PCM_mass=tm_PCM_mass,
                c_p=tm_c_p
            )
    
            structural_engineering = StructuralEngineering(
                area=se_area,
                sigma_yield=se_sigma_yield,
                E=se_E,
                I=se_I,
                k=se_k,
                mass=se_mass,
                length=se_length
            )
    
            control_system = ControlSystem(
                Kp=cs_Kp,
                Ki=cs_Ki,
                Kd=cs_Kd
            )
    
            # Инициализация ракеты
            rocket = Rocket(
                mass_initial=rocket_mass_initial,
                power_unit=power_unit,
                thruster=thruster,
                thermal_management=thermal_management,
                structural_engineering=structural_engineering,
                control_system=control_system,
                modules=rocket_modules,
                payload_mass=rocket_payload_mass
            )
    
            # Запуск симуляции
            times, speeds, masses, thrusts, delta_v = rocket.simulate(sim_duration, sim_delta_t, sim_desired_thrust)
            self.simulation_data = (times, speeds, masses, thrusts, delta_v)
    
            # Отображение результатов симуляции
            message = (
                f"Симуляция Завершена!\n\n"
                f"Общая Полученная Мощность: {power_unit.get_power() * sim_duration:.2e} W\n"
                f"Масса Батареи для Хранения Энергии: {power_unit.calculate_energy_storage_mass(power_unit.get_power() * sim_duration):.2f} kg\n"
                f"Изменение Скорости (Δv): {delta_v:.2f} m/s\n"
            )
            messagebox.showinfo("Симуляция Завершена", message)
        
        except ValueError as e:
            messagebox.showerror("Ошибка", str(e))
        except Exception as e:
            messagebox.showerror("Неизвестная Ошибка", f"Произошла ошибка: {str(e)}")
    
    def show_animation(self):
        if not hasattr(self, 'simulation_data') or not self.simulation_data:
            messagebox.showwarning("Нет Данных Симуляции", "Пожалуйста, сначала запустите симуляцию.")
            return
    
        # Создание окна для анимации
        anim_window = tk.Toplevel(self)
        anim_window.title("Анимация Ракеты")
        anim_window.geometry("800x600")
    
        # Canvas для анимации
        canvas = Canvas(anim_window, width=800, height=600, bg="black")
        canvas.pack(fill=tk.BOTH, expand=True)
    
        times, speeds, masses, thrusts, delta_v = self.simulation_data
        try:
            delta_t = float(self.sim_delta_t.get())
        except:
            delta_t = 1  # Значение по умолчанию, если ошибка
        max_distance = 700  # Максимальное расстояние на Canvas
        rocket_size = 20  # Размер ракеты
    
        # Расчет масштаба на основе общего перемещения
        total_displacement = sum([speed * delta_t for speed in speeds])
        if total_displacement == 0:
            scale = 1
        else:
            scale = min(max_distance / total_displacement, 1)  # Предотвращение масштаба > 1
    
        # Начальная позиция
        current_x = 50
        current_y = 300
    
        # Создание ракеты как треугольника (красный цвет для видимости)
        point1 = (current_x, current_y - rocket_size)
        point2 = (current_x, current_y + rocket_size)
        point3 = (current_x + rocket_size * 1.5, current_y)
        rocket_shape = canvas.create_polygon(point1, point2, point3, fill="red")
    
        # Текст отображающий тягу и массу
        info_text = canvas.create_text(current_x + rocket_size * 2, current_y,
                                       text=f"Тяга: {thrusts[0]:.2f} N\nМасса: {masses[0]:.2f} kg",
                                       fill="white", font=("Helvetica", 10), anchor=tk.W)
    
        # Инициализация текущих параметров для подсказки
        current_thrust = thrusts[0]
        current_mass = masses[0]
    
        # Инициализация переменной tooltip_window
        tooltip_window = None
    
        # Обработчик наведения курсора для отображения подсказки
        def show_tooltip(event):
            nonlocal current_thrust, current_mass, tooltip_window
            # Позиция курсора относительно экрана
            x_root = self.winfo_pointerx()
            y_root = self.winfo_pointery()
            # Позиция курсора относительно Canvas
            x = event.x
            y = event.y
            # Координаты ракеты
            coords = canvas.coords(rocket_shape)
            if not coords:
                return
            min_x = min(coords[::2])
            max_x = max(coords[::2])
            min_y = min(coords[1::2])
            max_y = max(coords[1::2])
    
            # Проверка, находится ли курсор над треугольником (простейшая проверка рамки)
            if min_x <= x <= max_x and min_y <= y <= max_y:
                if tooltip_window is None:
                    tooltip_window = tk.Toplevel(canvas)
                    tooltip_window.wm_overrideredirect(True)
                    tooltip_window.wm_geometry(f"+{x_root + 20}+{y_root + 20}")
                    label = ttk.Label(tooltip_window, text=f"Тяга: {current_thrust:.2f} N\nМасса: {current_mass:.2f} kg",
                                      background="yellow", relief='solid', borderwidth=1, justify='left')
                    label.pack(ipadx=1)
            else:
                if tooltip_window is not None:
                    tooltip_window.destroy()
                    tooltip_window = None
    
        canvas.bind("<Motion>", show_tooltip)
    
        # Анимационная функция
        def animate(index=0):
            nonlocal current_x, current_thrust, current_mass
            if index >= len(times):
                return
    
            current_thrust = thrusts[index]
            current_mass = masses[index]
            current_speed = speeds[index]
    
            # Расчет перемещения
            displacement = current_speed * delta_t * scale
            current_x += displacement
    
            if current_x > 750:
                current_x = 750  # Предотвращение выхода за Canvas
    
            # Перемещение ракеты
            move_x = displacement
            canvas.move(rocket_shape, move_x, 0)
            canvas.move(info_text, move_x, 0)
    
            # Обновление текста информации
            canvas.itemconfig(info_text, text=f"Тяга: {current_thrust:.2f} N\nМасса: {current_mass:.2f} kg")
    
            # Обновление подсказки, если она активна
            if tooltip_window is not None:
                tooltip_window.wm_geometry(f"+{self.winfo_pointerx() + 20}+{self.winfo_pointery() + 20}")
    
            # Отладочный вывод (можно удалить после проверки)
            print(f"Time: {times[index]:.1f}s, Thrust: {current_thrust:.2f}N, Mass: {current_mass:.2f}kg, Position X: {current_x:.2f}")
    
            # Запланировать следующий кадр анимации
            canvas.after(10, lambda: animate(index + 1))
    
        # Запуск анимации
        animate()


def main():
    app = MHPEPS_Simulator()
    app.mainloop()

if __name__ == "__main__":
    main()
```
Подставь реалистичные значения параметров ракеты, вес ракеты и т.д