Загрузка данных


% Решение задачи оптимального управления (Вариант 14)
% ИСПРАВЛЕННАЯ ВЕРСИЯ: Гарантия того, что время идет вперед (tf > t0)

function solve_optimal_control_v14_fixed()
    % Ищем параметр p, где конечное время tf = 1 + p^2. 
    % Если мы ожидаем tf около 3 сек, то p_guess около 1.41 (т.к. 1 + 1.41^2 ~ 3)
    p_guess = 1.5; 
    
    % Создаем сетку для нормализованного времени tau от 0 до 1
    tau = linspace(0, 1, 100);
    
    % Задаем структуру начального приближения для bvp4c
    solinit = bvpinit(tau, @guess_func, p_guess);

    % Настройки решателя
    options = bvpset('RelTol', 1e-4, 'AbsTol', 1e-6, 'NMax', 5000);

    disp('Идет поиск оптимального решения (в прямом времени)...');
    try
        % Решение краевой задачи
        sol = bvp4c(@ode_system, @boundary_conditions, solinit, options);
        
        % Извлечение результатов с учетом нашей подстановки tf = 1 + p^2
        p_opt = sol.parameters; 
        T_opt = 1 + p_opt^2; % Найденное оптимальное время tf
        
        t = 1 + sol.x * (T_opt - 1); % Возврат к реальному времени t (t0 = 1)
        
        x1 = sol.y(1, :);
        x2 = sol.y(2, :);
        psi1 = sol.y(3, :);
        psi2 = sol.y(4, :);
        
        % Расчет оптимального управления
        u = zeros(size(t));
        for i = 1:length(t)
            u(i) = (psi2(i) - 2*psi1(i)) / (0.4 * x2(i)^2 + 1e-6);
        end
        
        fprintf('Решение успешно найдено!\n');
        fprintf('Оптимальное конечное время tf = %.4f сек\n', T_opt);
        
        % Построение графиков
        figure('Name', 'Оптимальное управление: Вариант 14', 'Color', 'w');
        
        subplot(3,1,1);
        plot(t, x1, 'b-', t, x2, 'r-', 'LineWidth', 1.5);
        title(sprintf('Фазовые траектории (Оптимальное время t_f = %.3f)', T_opt));
        xlabel('Время t'); ylabel('x(t)');
        legend('x_1(t)', 'x_2(t)', 'Location', 'best');
        grid on;
        
        subplot(3,1,2);
        plot(t, psi1, 'b--', t, psi2, 'r--', 'LineWidth', 1.5);
        title('Сопряженные переменные \psi(t)');
        xlabel('Время t'); ylabel('\psi(t)');
        legend('\psi_1(t)', '\psi_2(t)', 'Location', 'best');
        grid on;
        
        subplot(3,1,3);
        plot(t, u, 'g', 'LineWidth', 1.5);
        title('Оптимальное управление u(t)');
        xlabel('Время t'); ylabel('u(t)');
        grid on;
        
    catch ME
        disp('Ошибка при решении:');
        disp(ME.message);
    end
end

% -----------------------------------------------------------------------
function dydtau = ode_system(~, y, p)
    % Вычисляем реальное T из параметра p
    T = 1 + p^2;
    
    x1 = y(1); x2 = y(2);
    psi1 = y(3); psi2 = y(4);
    
    u = (psi2 - 2*psi1) / (0.4 * x2^2 + 1e-6);
    
    dx1_dt = -17*x1 - 50*x2 - 2*u;
    dx2_dt = 3*x1 + 8*x2 + u;
    dpsi1_dt = 0.6*x1 + 17*psi1 - 3*psi2;
    dpsi2_dt = 0.4*x2*u^2 + 50*psi1 - 8*psi2;
    
    t0 = 1; 
    dt_dtau = T - t0;
    
    dydtau = dt_dtau * [dx1_dt; dx2_dt; dpsi1_dt; dpsi2_dt];
end

% -----------------------------------------------------------------------
function res = boundary_conditions(ya, yb, p)
    % ya - t=1, yb - t=tf
    x1_0 = ya(1);
    psi2_0 = ya(4);
    
    x1_f = yb(1);
    x2_f = yb(2);
    psi1_f = yb(3);
    psi2_f = yb(4);
    
    u_f = (psi2_f - 2*psi1_f) / (0.4 * x2_f^2 + 1e-6);
    H_f = -(0.3*x1_f^2 + 0.2*x2_f^2*u_f^2) + psi1_f*(-17*x1_f - 50*x2_f - 2*u_f) + psi2_f*(3*x1_f + 8*x2_f + u_f);
    
    res = [
        x1_0 - 0;      
        psi2_0 - 0;    
        x1_f - 1;      
        x2_f - 1;      
        H_f            
    ];
end

% -----------------------------------------------------------------------
function y_guess = guess_func(tau)
    % Немного изменим начальное приближение, чтобы помочь решателю
    x1 = tau;           
    x2 = tau; 
    psi1 = 1;           
    psi2 = 1;
    
    y_guess = [x1; x2; psi1; psi2];
end