广义预测控制(GPC)实现滞后系统控制 - MATLAB

广义预测控制(GPC)MATLAB实现,用于控制具有滞后的系统。GPC是一种先进的控制策略,特别适合处理滞后系统。

一、GPC基本原理

1.1 系统模型

GPC使用CARIMA(受控自回归积分滑动平均)模型:

A(z⁻¹)y(t) = B(z⁻¹)u(t-1) + C(z⁻¹)e(t)/Δ

其中Δ = 1 - z⁻¹是差分算子。

1.2 GPC算法步骤

  1. 模型辨识(参数估计)
  2. Diophantine方程求解
  3. 预测输出计算
  4. 控制律求解(最小化代价函数)

二、完整GPC MATLAB程序

%% 广义预测控制(GPC)程序 - 用于滞后系统控制
% 文件名: gpc_control_system.m

clear all;
close all;
clc;

%% 第一部分:参数设置和系统定义
function main_gpc()
    % ========== 1.1 控制系统参数 ==========
    fprintf('================ GPC控制器设计 ================\n');
    
    % GPC参数
    N1 = 1;           % 最小预测时域(通常等于系统滞后+1)
    N2 = 10;          % 最大预测时域
    Nu = 3;           % 控制时域
    lambda = 1.0;     % 控制权重
    alpha = 0.1;      % 柔化因子
    
    % 系统参数(模拟一个滞后系统)
    % 系统模型:G(s) = K * e^(-θs) / (τs + 1)
    % 离散化后:A(z⁻¹)y(t) = B(z⁻¹)u(t-1)
    
    % 连续时间系统参数
    K = 1.5;          % 增益
    tau = 5.0;        % 时间常数
    theta = 3.0;      % 纯滞后时间
    
    % 离散化参数
    Ts = 1.0;         % 采样时间
    n_samples = 200;  % 仿真步数
    
    % ========== 1.2 系统模型生成 ==========
    fprintf('生成滞后系统模型...\n');
    
    % 方法1:使用传递函数生成滞后系统
    s = tf('s');
    G_continuous = K * exp(-theta*s) / (tau*s + 1);
    
    % 离散化
    G_discrete = c2d(G_continuous, Ts, 'zoh');
    [num, den] = tfdata(G_discrete, 'v');
    
    % 提取多项式系数
    A = den(:)';       % A(z⁻¹)系数
    B = num(:)';       % B(z⁻¹)系数
    
    % 添加噪声多项式C(z⁻¹) = 1(简化假设)
    C = [1];
    
    % 显示系统信息
    fprintf('离散系统传递函数:\n');
    fprintf('A(z⁻¹) = ');
    for i = 1:length(A)
        fprintf('%.4f z^{-%d} ', A(i), i-1);
        if i < length(A), fprintf('+ '); end
    end
    fprintf('\n');
    
    fprintf('B(z⁻¹) = ');
    for i = 1:length(B)
        fprintf('%.4f z^{-%d} ', B(i), i-1);
        if i < length(B), fprintf('+ '); end
    end
    fprintf('\n');
    
    % 计算系统滞后
    d = find(B ~= 0, 1) - 1;  % B多项式中第一个非零项的阶次
    fprintf('系统滞后: d = %d\n', d);
    
    % 调整N1为滞后+1
    N1 = d + 1;
    fprintf('设置 N1 = d+1 = %d\n', N1);
    
    % ========== 1.3 参考信号生成 ==========
    t = (0:n_samples-1)' * Ts;
    
    % 参考轨迹(设定值)
    reference = zeros(n_samples, 1);
    reference(1:50) = 0;
    reference(51:100) = 1;
    reference(101:150) = -0.5;
    reference(151:200) = 0.5;
    
    % 柔化参考轨迹
    ref_filtered = filter([alpha], [1, -(1-alpha)], reference);
    
    % ========== 1.4 初始化变量 ==========
    y = zeros(n_samples, 1);     % 系统输出
    u = zeros(n_samples, 1);     % 控制输入
    u_min = -2;                  % 控制输入下限
    u_max = 2;                   % 控制输入上限
    du_min = -0.5;               % 控制增量下限
    du_max = 0.5;                % 控制增量上限
    
    % 噪声参数
    noise_std = 0.01;            % 测量噪声标准差
    
    % 存储预测信息
    y_pred = zeros(N2-N1+1, n_samples);
    u_opt = zeros(Nu, n_samples);
    
    % ========== 第二部分:GPC核心算法 ==========
    fprintf('开始GPC控制仿真...\n');
    
    for k = 1:n_samples
        % 当前输出(添加测量噪声)
        if k > 1
            y(k) = simulate_system(A, B, u, y, k-1) + noise_std * randn;
        else
            y(k) = 0;
        end
        
        % 当前参考值
        if k + N2 <= n_samples
            R = ref_filtered(k+N1:k+N2);
        else
            % 如果超出范围,使用最后一个参考值
            R = ref_filtered(min(k+N1, n_samples):min(k+N2, n_samples));
            if length(R) < N2-N1+1
                R = [R; R(end)*ones(N2-N1+1-length(R), 1)];
            end
        end
        
        % ========== 2.1 Diophantine方程求解 ==========
        % 计算阶次
        na = length(A) - 1;
        nb = length(B) - 1;
        nc = length(C) - 1;
        
        % 扩展多项式 E和F
        E = cell(N2, 1);
        F = cell(N2, 1);
        
        % 计算AΔ = A(z⁻¹) * Δ,其中Δ = 1 - z⁻¹
        A_delta = conv(A, [1 -1]);
        
        for j = N1:N2
            % 求解Diophantine方程:C = E_j * AΔ + z^{-j} * F_j
            [E{j}, F{j}] = solve_diophantine(C, A_delta, j);
        end
        
        % ========== 2.2 计算G矩阵和自由响应 ==========
        % 计算G矩阵
        G = zeros(N2-N1+1, Nu);
        
        for i = 1:N2-N1+1
            j = N1 + i - 1;
            E_j = E{j};
            
            % 计算G_j = E_j * B
            G_j = conv(E_j, B);
            
            % 填充G矩阵
            for m = 1:Nu
                if m <= length(G_j)
                    G(i, m) = G_j(m);
                end
            end
        end
        
        % 计算自由响应f
        f = zeros(N2-N1+1, 1);
        
        % 过去输入和输出对未来的影响
        for i = 1:N2-N1+1
            j = N1 + i - 1;
            F_j = F{j};
            
            % 计算自由响应分量
            f_i = 0;
            
            % 来自F_j的部分
            for m = 1:min(length(F_j), k)
                f_i = f_i + F_j(m) * y(k-m+1);
            end
            
            % 来自过去控制增量的部分
            for m = 1:min(length(E{j}), k)
                % 计算Δu
                if k-m >= 1
                    du_past = u(k-m+1) - u(k-m);
                else
                    du_past = 0;
                end
                
                % 计算E_j * B * Δu
                EB = conv(E{j}, B);
                if m <= length(EB)
                    f_i = f_i + EB(m) * du_past;
                end
            end
            
            f(i) = f_i;
        end
        
        % ========== 2.3 求解最优控制 ==========
        if k > 1
            % 构造Hessian矩阵
            H = G' * G + lambda * eye(Nu);
            
            % 构造梯度向量
            g = G' * (f - R);
            
            % 无约束优化
            du_opt = -H \ g;
            
            % 约束处理(投影到可行域)
            du_opt(1) = max(min(du_opt(1), du_max), du_min);
            
            % 计算控制输入
            u(k) = u(k-1) + du_opt(1);
            
            % 输入约束
            u(k) = max(min(u(k), u_max), u_min);
            
            % 存储最优控制序列
            u_opt(:, k) = du_opt;
        else
            u(k) = 0;
        end
        
        % ========== 2.4 预测输出 ==========
        % 计算预测输出
        y_pred_vec = G * u_opt(1:Nu, max(k,1)) + f;
        y_pred(:, k) = y_pred_vec;
    end
    
    fprintf('GPC控制仿真完成。\n');
    
    % ========== 第三部分:结果可视化 ==========
    plot_gpc_results(t, y, u, reference, ref_filtered, y_pred, N1, N2);
    
    % ========== 第四部分:性能分析 ==========
    analyze_performance(t, y, reference, u);
    
    % ========== 第五部分:鲁棒性测试 ==========
    test_robustness(A, B, K, tau, theta, Ts, n_samples);
end

%% 辅助函数定义

function y_k = simulate_system(A, B, u, y, k)
% 模拟系统输出
% A: 分母多项式系数
% B: 分子多项式系数
% u: 输入序列
% y: 输出序列
% k: 当前时刻

na = length(A) - 1;
nb = length(B) - 1;

% 计算输出
y_k = 0;

% 来自输入的贡献
for i = 1:min(nb+1, k+1)
    if k-i+2 >= 1
        y_k = y_k + B(i) * u(k-i+2);
    end
end

% 来自输出的贡献(负号因为方程是A*y = B*u)
for i = 2:min(na+1, k+1)
    if k-i+2 >= 1
        y_k = y_k - A(i) * y(k-i+2);
    end
end

% 除以A(1)
if A(1) ~= 0
    y_k = y_k / A(1);
end
end

function [E, F] = solve_diophantine(C, A_delta, j)
% 求解Diophantine方程:C = E * AΔ + z^{-j} * F
% C, A_delta: 多项式系数(按z^{-1}的升幂排列)
% j: 预测步长

% 多项式阶次
nc = length(C) - 1;
na_delta = length(A_delta) - 1;

% E的阶次为j-1
E_order = j - 1;
F_order = max(nc, na_delta + j - 1) - j;

% 构造方程组
n_eq = nc + 1;
n_vars = E_order + 1 + F_order + 1;

% 系数矩阵
M = zeros(n_eq, n_vars);

% 填充矩阵
for i = 1:n_eq
    % E的贡献
    for k = 1:min(E_order+1, i)
        if i-k+1 <= na_delta+1
            M(i, k) = A_delta(i-k+1);
        end
    end
    
    % F的贡献(延迟j步)
    if i >= j
        M(i, E_order+1 + (i-j)) = 1;
    end
end

% 右侧向量
b = C(:);

% 求解最小二乘解
x = M \ b;

% 提取E和F
E = x(1:E_order+1)';
F = x(E_order+2:end)';

% 确保多项式正确(截断接近零的系数)
E(abs(E) < 1e-10) = 0;
F(abs(F) < 1e-10) = 0;
end

function plot_gpc_results(t, y, u, reference, ref_filtered, y_pred, N1, N2)
% 绘制GPC控制结果

figure('Position', [100, 100, 1200, 800]);

% 1. 输出响应
subplot(3, 2, 1);
plot(t, y, 'b-', 'LineWidth', 2); hold on;
plot(t, reference, 'r--', 'LineWidth', 1.5);
plot(t, ref_filtered, 'g-.', 'LineWidth', 1);
xlabel('时间 (s)');
ylabel('输出');
title('系统输出响应');
legend('实际输出', '设定值', '柔化设定值', 'Location', 'best');
grid on;

% 2. 控制输入
subplot(3, 2, 2);
stairs(t, u, 'b-', 'LineWidth', 1.5);
xlabel('时间 (s)');
ylabel('控制输入');
title('控制输入信号');
grid on;

% 3. 跟踪误差
subplot(3, 2, 3);
error = y - ref_filtered;
plot(t, error, 'r-', 'LineWidth', 1.5);
xlabel('时间 (s)');
ylabel('跟踪误差');
title('跟踪误差');
grid on;
hold on;
plot(t, zeros(size(t)), 'k--');
ylim([-0.2, 0.2]);

% 4. 预测输出(特定时刻)
subplot(3, 2, 4);
time_idx = 80;  % 选择一个时刻显示预测
if time_idx <= length(t)
    pred_horizon = N1:N2;
    plot(pred_horizon, y_pred(:, time_idx), 'bo-', 'LineWidth', 1.5, 'MarkerSize', 6);
    hold on;
    plot(pred_horizon, ref_filtered(time_idx+pred_horizon-1), 'r--', 'LineWidth', 1.5);
    xlabel('预测步数');
    ylabel('输出');
    title(sprintf('时刻 t=%.1f 的预测输出', t(time_idx)));
    legend('预测输出', '参考轨迹', 'Location', 'best');
    grid on;
end

% 5. 控制输入变化率
subplot(3, 2, 5);
du = diff(u);
plot(t(2:end), du, 'm-', 'LineWidth', 1.5);
xlabel('时间 (s)');
ylabel('Δu');
title('控制输入变化率');
grid on;
hold on;
plot(t, zeros(size(t)), 'k--');

% 6. 相位图
subplot(3, 2, 6);
plot(y(2:end), du, 'b.', 'MarkerSize', 8);
xlabel('输出 y(t)');
ylabel('控制变化 Δu(t)');
title('相位图');
grid on;

sgtitle('广义预测控制(GPC)仿真结果', 'FontSize', 14, 'FontWeight', 'bold');
end

function analyze_performance(t, y, reference, u)
% 分析控制性能

% 计算性能指标
error = y - reference;

% 1. 均方根误差
RMSE = sqrt(mean(error.^2));

% 2. 最大绝对误差
max_error = max(abs(error));

% 3. 积分绝对误差
IAE = trapz(t, abs(error));

% 4. 积分平方误差
ISE = trapz(t, error.^2);

% 5. 控制能量
control_energy = trapz(t, u.^2);

% 6. 控制变化能量
du = diff(u);
control_variation_energy = trapz(t(2:end), du.^2);

% 7. 超调量
[overshoot, overshoot_idx] = max(y - reference);
overshoot_percentage = (overshoot / max(abs(reference))) * 100;

% 8. 调节时间(进入±5%误差带的时间)
ref_range = max(reference) - min(reference);
error_band = 0.05 * ref_range;

settling_time_idx = find(abs(error) < error_band, 1);
if ~isempty(settling_time_idx)
    settling_time = t(settling_time_idx);
else
    settling_time = t(end);
end

% 显示性能指标
fprintf('\n========== 控制性能分析 ==========\n');
fprintf('均方根误差 (RMSE): %.4f\n', RMSE);
fprintf('最大绝对误差: %.4f\n', max_error);
fprintf('积分绝对误差 (IAE): %.4f\n', IAE);
fprintf('积分平方误差 (ISE): %.4f\n', ISE);
fprintf('控制能量: %.4f\n', control_energy);
fprintf('控制变化能量: %.4f\n', control_variation_energy);
fprintf('超调量: %.2f%%\n', overshoot_percentage);
fprintf('调节时间 (5%%): %.2f s\n', settling_time);

% 创建性能分析图
figure('Position', [100, 100, 1000, 600]);

% 误差统计
subplot(2, 3, 1);
histogram(error, 30, 'FaceColor', 'blue', 'EdgeColor', 'black');
xlabel('误差');
ylabel('频次');
title('误差分布直方图');
grid on;

% 自相关函数
subplot(2, 3, 2);
autocorr(error, 50);
title('误差自相关函数');

% 功率谱密度
subplot(2, 3, 3);
[pxx, f] = pwelch(error, [], [], [], 1/(t(2)-t(1)));
semilogy(f, pxx, 'b-', 'LineWidth', 1.5);
xlabel('频率 (Hz)');
ylabel('功率谱密度');
title('误差功率谱密度');
grid on;

% 控制信号分析
subplot(2, 3, 4);
plot(t, u, 'b-', 'LineWidth', 1.5);
xlabel('时间 (s)');
ylabel('控制输入');
title('控制输入信号');
grid on;

% 误差随时间变化
subplot(2, 3, 5);
plot(t, error, 'r-', 'LineWidth', 1.5);
hold on;
plot(t, error_band*ones(size(t)), 'g--', 'LineWidth', 1);
plot(t, -error_band*ones(size(t)), 'g--', 'LineWidth', 1);
xlabel('时间 (s)');
ylabel('误差');
title('跟踪误差');
grid on;

% 性能指标汇总
subplot(2, 3, 6);
axis off;
text(0.1, 0.9, '性能指标汇总:', 'FontSize', 12, 'FontWeight', 'bold');
text(0.1, 0.75, sprintf('RMSE: %.4f', RMSE), 'FontSize', 10);
text(0.1, 0.65, sprintf('最大误差: %.4f', max_error), 'FontSize', 10);
text(0.1, 0.55, sprintf('IAE: %.4f', IAE), 'FontSize', 10);
text(0.1, 0.45, sprintf('ISE: %.4f', ISE), 'FontSize', 10);
text(0.1, 0.35, sprintf('超调: %.1f%%', overshoot_percentage), 'FontSize', 10);
text(0.1, 0.25, sprintf('调节时间: %.2f s', settling_time), 'FontSize', 10);

sgtitle('GPC控制性能分析', 'FontSize', 14, 'FontWeight', 'bold');
end

function test_robustness(A_nominal, B_nominal, K_nominal, tau_nominal, theta_nominal, Ts, n_samples)
% 鲁棒性测试:参数变化对控制性能的影响

fprintf('\n========== 鲁棒性测试 ==========\n');

% 测试不同的参数变化
param_variations = [0.5, 0.8, 1.0, 1.2, 1.5];  % 参数变化比例

% 存储性能指标
performance_metrics = zeros(length(param_variations), 4);

figure('Position', [100, 100, 1200, 800]);
colors = {'r', 'g', 'b', 'm', 'c'};

for i = 1:length(param_variations)
    factor = param_variations(i);
    
    % 修改系统参数
    K = K_nominal * factor;
    tau = tau_nominal * factor;
    theta = theta_nominal * factor;
    
    fprintf('测试参数变化: %.1f倍\n', factor);
    
    % 重新生成系统
    s = tf('s');
    G_continuous = K * exp(-theta*s) / (tau*s + 1);
    G_discrete = c2d(G_continuous, Ts, 'zoh');
    [num, den] = tfdata(G_discrete, 'v');
    
    A = den(:)';
    B = num(:)';
    C = [1];
    
    % 运行GPC控制(简化版本)
    [t, y, u, reference] = run_gpc_simple(A, B, C, Ts, n_samples);
    
    % 计算性能指标
    error = y - reference;
    RMSE = sqrt(mean(error.^2));
    IAE = trapz(t, abs(error));
    max_error = max(abs(error));
    control_energy = trapz(t, u.^2);
    
    performance_metrics(i, :) = [RMSE, IAE, max_error, control_energy];
    
    % 绘制响应曲线
    subplot(2, 3, 1);
    plot(t, y, 'Color', colors{i}, 'LineWidth', 1.5, 'DisplayName', sprintf('%.1f倍', factor));
    if i == 1
        hold on;
        plot(t, reference, 'k--', 'LineWidth', 1.5, 'DisplayName', '设定值');
        xlabel('时间 (s)');
        ylabel('输出');
        title('不同参数下的输出响应');
        grid on;
        legend('show', 'Location', 'best');
    end
end

% 绘制性能指标对比
metrics_names = {'RMSE', 'IAE', '最大误差', '控制能量'};

for j = 1:4
    subplot(2, 3, j+1);
    bar(performance_metrics(:, j), 'FaceColor', [0.2, 0.4, 0.8]);
    set(gca, 'XTickLabel', arrayfun(@(x) sprintf('%.1f', x), param_variations, 'UniformOutput', false));
    xlabel('参数变化倍数');
    ylabel(metrics_names{j});
    title(sprintf('%s vs 参数变化', metrics_names{j}));
    grid on;
end

sgtitle('GPC鲁棒性测试', 'FontSize', 14, 'FontWeight', 'bold');
end

function [t, y, u, reference] = run_gpc_simple(A, B, C, Ts, n_samples)
% 简化版GPC运行函数(用于鲁棒性测试)

% 初始化
t = (0:n_samples-1)' * Ts;
y = zeros(n_samples, 1);
u = zeros(n_samples, 1);

% 参考信号
reference = zeros(n_samples, 1);
reference(1:50) = 0;
reference(51:100) = 1;
reference(101:150) = -0.5;
reference(151:200) = 0.5;

% GPC参数
N1 = 2;
N2 = 8;
Nu = 2;
lambda = 1.0;

% 主要控制循环
for k = 1:n_samples
    % 系统输出
    if k > 1
        y(k) = simulate_system(A, B, u, y, k-1);
    end
    
    if k > 5  % 开始控制
        % 计算参考轨迹
        R = zeros(N2-N1+1, 1);
        for i = 1:N2-N1+1
            idx = min(k+N1+i-2, n_samples);
            R(i) = reference(idx);
        end
        
        % 简化GPC计算(使用固定G矩阵)
        G = [B(1), 0; B(1)+A(2)*B(1), B(1)];
        
        % 自由响应(简化)
        f = y(k) * ones(N2-N1+1, 1);
        
        % 控制律
        H = G' * G + lambda * eye(Nu);
        du_opt = -H \ (G' * (f - R));
        
        % 应用控制
        if k < n_samples
            u(k) = u(k-1) + du_opt(1);
            u(k) = max(min(u(k), 2), -2);  % 饱和限制
        end
    end
end
end

%% 第三部分:高级GPC功能

function gpc_with_online_identification()
% 带有在线辨识的GPC

fprintf('\n========== 带在线辨识的GPC ==========\n');

% 参数
n_samples = 300;
Ts = 1.0;

% 真实系统(未知,需要辨识)
A_true = [1, -1.5, 0.7];
B_true = [0, 0.8, 0.3];  % 滞后为1

% 初始模型估计(可能不准确)
A_est = [1, -1.2, 0.6];
B_est = [0, 1.0, 0.2];
C_est = [1];

% 初始化
t = (0:n_samples-1)' * Ts;
y = zeros(n_samples, 1);
u = zeros(n_samples, 1);

% 参考信号
reference = 0.5 * sin(0.05 * t) + 0.3 * cos(0.1 * t);

% RLS参数
na = length(A_true) - 1;
nb = length(B_true) - 1;
nc = length(C_est) - 1;

theta_est = zeros(na + nb + 1, 1);  % 参数向量
P = 1000 * eye(na + nb + 1);        % 协方差矩阵
lambda_rls = 0.98;                  % 遗忘因子

% 数据向量
phi = zeros(na + nb + 1, 1);

% GPC参数
N1 = 2;
N2 = 10;
Nu = 3;
lambda_gpc = 0.5;

% 主循环
for k = 1:n_samples
    % ========== 1. 系统输出(真实系统) ==========
    if k > 1
        % 计算真实输出(模拟真实系统)
        y_k = 0;
        for i = 1:min(nb+1, k)
            if k-i+1 >= 1
                y_k = y_k + B_true(i) * u(k-i+1);
            end
        end
        for i = 2:min(na+1, k)
            if k-i+1 >= 1
                y_k = y_k - A_true(i) * y(k-i+1);
            end
        end
        y(k) = y_k + 0.01 * randn;  % 添加噪声
    end
    
    % ========== 2. 在线辨识(RLS) ==========
    if k > max(na, nb) + 1
        % 构建数据向量
        phi = [-y(k-1:-1:k-na); u(k-1:-1:k-nb-1)];
        
        % RLS更新
        K = P * phi / (lambda_rls + phi' * P * phi);
        theta_est = theta_est + K * (y(k) - phi' * theta_est);
        P = (1/lambda_rls) * (P - K * phi' * P);
        
        % 提取估计的参数
        A_est = [1; theta_est(1:na)]';
        B_est = [0; theta_est(na+1:end)]';  % 假设滞后为1
    end
    
    % ========== 3. GPC控制计算 ==========
    if k > max(na, nb) + 5
        % 使用估计的模型计算控制
        
        % Diophantine方程求解
        A_delta = conv(A_est, [1 -1]);
        
        % 计算G矩阵
        G = zeros(N2-N1+1, Nu);
        
        for j = N1:N2
            [E_j, F_j] = solve_diophantine(C_est, A_delta, j);
            
            % 计算G_j = E_j * B_est
            G_j = conv(E_j, B_est);
            
            i = j - N1 + 1;
            for m = 1:min(Nu, length(G_j))
                G(i, m) = G_j(m);
            end
        end
        
        % 计算自由响应
        f = zeros(N2-N1+1, 1);
        
        for i = 1:N2-N1+1
            j = N1 + i - 1;
            [~, F_j] = solve_diophantine(C_est, A_delta, j);
            
            % 自由响应计算
            f_i = 0;
            for m = 1:min(length(F_j), k)
                f_i = f_i + F_j(m) * y(k-m+1);
            end
            f(i) = f_i;
        end
        
        % 参考轨迹
        R = zeros(N2-N1+1, 1);
        for i = 1:N2-N1+1
            idx = min(k+N1+i-2, n_samples);
            R(i) = reference(idx);
        end
        
        % 求解控制律
        H = G' * G + lambda_gpc * eye(Nu);
        du_opt = -H \ (G' * (f - R));
        
        % 应用控制
        if k < n_samples
            u(k) = u(k-1) + du_opt(1);
            u(k) = max(min(u(k), 2), -2);
        end
    else
        % 初始阶段使用简单控制
        if k > 1
            u(k) = 0.1 * (reference(k) - y(k));
        end
    end
end

% 绘制结果
figure('Position', [100, 100, 1200, 600]);

subplot(2, 2, 1);
plot(t, y, 'b-', 'LineWidth', 1.5); hold on;
plot(t, reference, 'r--', 'LineWidth', 1.5);
xlabel('时间 (s)');
ylabel('输出');
title('带在线辨识的GPC控制');
legend('系统输出', '参考信号', 'Location', 'best');
grid on;

subplot(2, 2, 2);
stairs(t, u, 'g-', 'LineWidth', 1.5);
xlabel('时间 (s)');
ylabel('控制输入');
title('控制输入');
grid on;

subplot(2, 2, 3);
error = y - reference;
plot(t, error, 'r-', 'LineWidth', 1.5);
xlabel('时间 (s)');
ylabel('跟踪误差');
title('跟踪误差');
grid on;

subplot(2, 2, 4);
% 显示参数收敛
na_est = na;
nb_est = nb;
theta_true = [A_true(2:end)'; B_true(2:end)'];
plot(1:length(theta_est), theta_est, 'b.-', 'LineWidth', 1.5, 'MarkerSize', 10);
hold on;
plot(1:length(theta_true), theta_true, 'r--', 'LineWidth', 1.5);
xlabel('参数索引');
ylabel('参数值');
title('参数估计收敛');
legend('估计值', '真实值', 'Location', 'best');
grid on;

sgtitle('带在线辨识的自适应GPC控制', 'FontSize', 14, 'FontWeight', 'bold');
end

%% 第四部分:GPC控制器设计工具

function gpc_design_tool()
% GPC控制器设计工具

fprintf('\n========== GPC控制器设计工具 ==========\n');

% 用户选择系统类型
fprintf('选择系统类型:\n');
fprintf('1. 一阶滞后系统\n');
fprintf('2. 二阶滞后系统\n');
fprintf('3. 高阶滞后系统\n');
fprintf('4. 非最小相位系统\n');
fprintf('5. 自定义系统\n');

choice = 1;  % 默认选择

% 根据选择生成系统
switch choice
    case 1
        % 一阶滞后系统
        K = 1.0;
        tau = 5.0;
        theta = 2.0;
        sys_type = '一阶滞后系统';
        
    case 2
        % 二阶滞后系统
        K = 1.0;
        tau1 = 3.0;
        tau2 = 7.0;
        theta = 1.0;
        sys_type = '二阶滞后系统';
        
    case 3
        % 高阶滞后系统
        K = 1.0;
        tau = [2, 4, 6];
        theta = 3.0;
        sys_type = '高阶滞后系统';
        
    case 4
        % 非最小相位系统
        sys_type = '非最小相位系统';
        
    case 5
        % 自定义系统
        sys_type = '自定义系统';
end

fprintf('选择的系统: %s\n', sys_type);

% GPC参数设计
fprintf('\nGPC参数设计:\n');

% 基于系统特性设计参数
if choice == 1
    % 一阶系统
    N2 = ceil(5 * tau / Ts);  % 覆盖5倍时间常数
    Nu = max(2, ceil(N2/3));
    lambda = 0.5;
    
elseif choice == 2
    % 二阶系统
    N2 = ceil(8 * max(tau1, tau2) / Ts);
    Nu = max(3, ceil(N2/4));
    lambda = 1.0;
    
else
    % 默认参数
    N2 = 10;
    Nu = 3;
    lambda = 1.0;
end

fprintf('预测时域 N2 = %d\n', N2);
fprintf('控制时域 Nu = %d\n', Nu);
fprintf('控制权重 λ = %.2f\n', lambda);

% 显示稳定性分析
analyze_stability(N2, Nu, lambda);

% 生成控制器代码
generate_gpc_code(N1, N2, Nu, lambda);
end

function analyze_stability(N2, Nu, lambda)
% 稳定性分析

fprintf('\n稳定性分析:\n');

% 计算条件数(粗略的稳定性指标)
% 对于GPC,条件数越小通常稳定性越好

% 模拟G矩阵(假设为单位矩阵简化计算)
G = randn(N2, Nu);
H = G' * G + lambda * eye(Nu);

cond_number = cond(H);
fprintf('Hessian矩阵条件数: %.2f\n', cond_number);

if cond_number < 1000
    fprintf('稳定性: 良好\n');
elseif cond_number < 10000
    fprintf('稳定性: 中等\n');
else
    fprintf('稳定性: 需要注意\n');
    fprintf('建议: 增加λ或减少Nu\n');
end

% 极点分析(概念性)
fprintf('\n极点分析:\n');
fprintf('GPC的稳定性取决于闭环极点的位置\n');
fprintf('适当的选择N2, Nu, λ可以保证稳定性\n');
end

function generate_gpc_code(N1, N2, Nu, lambda)
% 生成GPC控制器代码

fprintf('\n========== GPC控制器代码生成 ==========\n');

code = sprintf([...
    '%% GPC控制器函数\n' ...
    'function [u_opt, du_opt] = gpc_controller(y, u_prev, reference, A, B, C)\n' ...
    '%% GPC控制器核心函数\n' ...
    '%% 输入:\n' ...
    '%%   y - 当前输出\n' ...
    '%%   u_prev - 上一时刻控制输入\n' ...
    '%%   reference - 参考信号向量\n' ...
    '%%   A, B, C - 系统多项式\n' ...
    '%% 输出:\n' ...
    '%%   u_opt - 最优控制输入\n' ...
    '%%   du_opt - 最优控制增量\n' ...
    '\n' ...
    '%% GPC参数\n' ...
    'N1 = %d;      %% 最小预测时域\n' ...
    'N2 = %d;      %% 最大预测时域\n' ...
    'Nu = %d;      %% 控制时域\n' ...
    'lambda = %.2f; %% 控制权重\n' ...
    '\n' ...
    '%% 1. Diophantine方程求解\n' ...
    'A_delta = conv(A, [1 -1]);\n' ...
    'G = zeros(N2-N1+1, Nu);\n' ...
    'f = zeros(N2-N1+1, 1);\n' ...
    '\n' ...
    'for j = N1:N2\n' ...
    '    %% 求解Diophantine方程\n' ...
    '    [E_j, F_j] = solve_diophantine(C, A_delta, j);\n' ...
    '    \n' ...
    '    %% 计算G矩阵元素\n' ...
    '    G_j = conv(E_j, B);\n' ...
    '    i = j - N1 + 1;\n' ...
    '    for m = 1:min(Nu, length(G_j))\n' ...
    '        G(i, m) = G_j(m);\n' ...
    '    end\n' ...
    '    \n' ...
    '    %% 计算自由响应\n' ...
    '    f_i = 0;\n' ...
    '    for m = 1:min(length(F_j), length(y))\n' ...
    '        f_i = f_i + F_j(m) * y(end-m+1);\n' ...
    '    end\n' ...
    '    f(i) = f_i;\n' ...
    'end\n' ...
    '\n' ...
    '%% 2. 构造参考轨迹\n' ...
    'R = reference(N1:N2);\n' ...
    '\n' ...
    '%% 3. 求解最优控制\n' ...
    'H = G'' * G + lambda * eye(Nu);\n' ...
    'du_opt_vec = -H \\ (G'' * (f - R));\n' ...
    '\n' ...
    '%% 4. 应用控制\n' ...
    'du_opt = du_opt_vec(1);\n' ...
    'u_opt = u_prev + du_opt;\n' ...
    '\n' ...
    '%% 5. 约束处理(可选)\n' ...
    'u_max = 2.0;\n' ...
    'u_min = -2.0;\n' ...
    'du_max = 0.5;\n' ...
    'du_min = -0.5;\n' ...
    '\n' ...
    'du_opt = max(min(du_opt, du_max), du_min);\n' ...
    'u_opt = max(min(u_opt, u_max), u_min);\n' ...
    'end\n' ...
    ], N1, N2, Nu, lambda);

fprintf('生成的GPC控制器代码:\n');
fprintf('%s\n', code);

% 保存到文件
filename = 'gpc_controller.m';
fid = fopen(filename, 'w');
fprintf(fid, '%s', code);
fclose(fid);

fprintf('代码已保存到文件: %s\n', filename);
end

%% 主程序运行

% 运行主GPC程序
fprintf('开始运行GPC控制程序...\n');
main_gpc();

% 运行带在线辨识的GPC
% gpc_with_online_identification();

% 运行GPC设计工具
% gpc_design_tool();

fprintf('\n程序运行完成!\n');

三、程序使用说明

3.1 基本使用方法

% 1. 直接运行主程序
run('gpc_control_system.m');

% 2. 自定义系统参数
% 修改以下参数:
K = 2.0;        % 系统增益
tau = 3.0;      % 时间常数
theta = 2.0;    % 滞后时间
Ts = 0.5;       % 采样时间

% 3. 调整GPC参数
N1 = 2;         % 最小预测时域
N2 = 15;        % 最大预测时域
Nu = 4;         % 控制时域
lambda = 0.8;   % 控制权重

3.2 应用于不同系统

% 对于不同的滞后系统,修改系统模型:

% 例1:一阶滞后系统
sys = tf(1.5, [5, 1], 'InputDelay', 3);

% 例2:二阶滞后系统
sys = tf(2.0, conv([2, 1], [3, 1]), 'InputDelay', 2);

% 例3:非最小相位系统
sys = tf([-0.5, 1], [4, 1], 'InputDelay', 1);

参考代码 gpc预测控制,广义预测控制m程序,实现对滞后系统的控制 www.youwenfan.com/contentcno/96489.html

四、GPC算法特点

  1. 预测能力:基于模型预测未来输出
  2. 约束处理:可处理输入输出约束
  3. 滞后补偿:内置滞后处理能力
  4. 鲁棒性:对模型失配有较好鲁棒性
  5. 多目标优化:可同时优化跟踪性能和控制能量

五、性能调优建议

  1. 预测时域选择

    • N2应覆盖系统主要动态
    • 对于滞后系统,N1 = d+1(d为滞后)
  2. 控制时域选择

    • Nu通常为2-5
    • 较小的Nu减少计算量但可能降低性能
  3. 控制权重调整

    • λ增大:控制更平滑,但响应变慢
    • λ减小:响应更快,但控制可能剧烈
  4. 柔化因子

    • α=0:无柔化,跟踪快但可能超调
    • α增大:柔化增强,跟踪平稳

这个GPC程序包提供了完整的滞后系统控制解决方案,包括:

  • 基础GPC算法实现
  • 在线参数辨识
  • 鲁棒性分析
  • 性能评估工具
  • 代码生成功能

用户可以根据具体应用需求调整参数和修改系统模型。

posted @ 2025-12-24 09:48  yijg9998  阅读(8)  评论(0)    收藏  举报