经典预测控制算法:动态矩阵控制(DMC)下篇——仿真实验(含Matlab源码)

news2024/12/24 9:22:30

目录

  • 前文链接
  • 基础DMC算法
    • Matlab源码
    • 代码解析
    • 仿真结果展示
  • 参数对性能的影响
    • 参数P对性能影响
      • Matlab源码
      • 仿真结果
    • 参数M对性能影响
      • Matlab源码
      • 仿真结果
    • 参数q对性能影响
      • Matlab源码
      • 仿真结果
    • 参数lamda对性能影响
      • Matlab源码
      • 仿真结果
    • 讨论
  • 算法改进效果验证
    • 阶梯式动态矩阵控制与基础DMC对比
      • Matlab源码
      • 仿真结果
    • 反馈校正环节截断误差改进
      • Matlab源码
      • 仿真结果
    • 对象存在纯迟延时控制器参数优化
      • Matlab源码
      • 仿真结果

前文链接

经典预测控制算法:动态矩阵控制(DMC)上篇——理论推导
经典预测控制算法:动态矩阵控制(DMC)中篇——算法改进

基础DMC算法

Matlab源码

clear;clc;                              % 清除缓存变量,清除命令行信息
dt=1;                                   % 采样周期
%################################ 基本DMC #####################################%
%% 被控对象参数
K=1;                                    % 开环增益
T=215;                                  % 惯性时间
%% DMC参数
N=2000;                                 % 建模时域
P=500;                                  % 预测时域
M=1;                                    % 控制时域
q=1;                                    % Q矩阵(预测输出与期望值误差权矩阵)中的一个权值
lamda=1;                                % λ(LAMDA)矩阵(控制增量权矩阵)中的一个权值
h=1;                                    % H矩阵(预测与实际输出误差校正系数矩阵)中的一个系数
%% 根据DMC参数计算DMC参数矩阵
Q=q*eye(P);                             % 生成Q矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
H=h*ones(P,1);                          % 生成反馈校正H矩阵
S=zeros(P,P);                           % 生成移位矩阵S
for i=1:P-1
    S(i,i+1)=1;                         % 次对角线元素为1
end
S(P,P-1)=0; S(P,P)=1;                   % 右下角元素为1
%% 阶跃响应模型
num=K;                                  % 传递函数的分子部分
den=[T 1];                              % 传递函数的分母部分
sys=tf(num,den);                        % 构成传递函数
a=step(sys,0:dt:N);                     % 参数依次为要施加阶跃输入的传递函数,起始时间:步长(周期):截止时间
%% 离线计算控制律前一部分的矩阵
A=zeros(P,M);                           % 生成动态矩阵A,A是P行M列
for i=1:M                               % 从1到M列
    for j=i:P                           % 从i到P行
        A(j,i)=a(j-i+1,1);
    end
end
C(1,1)=1;
for i=2:M
    C(1,i)=0;                           % 生成C矩阵
end
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 仿真参数设置
SimuStepCount=2999;                     % 总仿真步数
sp=1;                                   % 设定值
SP=sp*ones(P,1);                        % 设定值向量
%% 开始仿真
Y_DMC=zeros(SimuStepCount+1,1);         % 保存每一步对象输出
U_DMC=zeros(SimuStepCount+1,1);         % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);             % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC(i+1,1)=y;                     % 存储到Y_DMC
    U_DMC(i,1)=u;                       % 存储到U_DMC
end
U_DMC(SimuStepCount+1,1)=U_DMC(SimuStepCount,1);
%% 绘图
n=size(Y_DMC,1);
subplot(2,1,1);
t=1:1:n;
plot(t,Y_DMC(1:n),'r');
title('y')
subplot(2,1,2);
plot(t,U_DMC(1:n),'b--');
title('u')

代码解析

  DMC算法要设置各种参数,设置参数之后,还要计算相关的参数矩阵,导致上面的代码看上去很长,其实关键的控制量计算几行就可以实现(for循环中的内容)。
  上面代码中设置参数的部分我们直接跳过,变量名与之前文章中的符号都是对应的。
  被控对象为一个不带纯迟延环节的一阶惯性对象,用传递函数来表示是 K T s + 1 \frac{K}{Ts+1} Ts+1K,matlab中的tf()函数可以将分子和分母表示的多项式(从最高次项一直到常数也就是0次项)转换为传递函数形式,例如下面代码会生成一个 A s + 1 B s 2 + C s + 1 \frac{As+1}{Bs^2+Cs+1} Bs2+Cs+1As+1形式的传递函数:

num=[A 1];
den=[B C 1];
sys=tf(num,den);

  step()函数可以生成DMC需要的阶跃响应模型,我们在参数中提供之前生成的传递函数,以及起始结束时间和步长,函数返回的结果就是单位阶跃输入下的阶跃响应模型 a \bm{a} a
  得到 a \bm{a} a之后就可以计算动态矩阵 A \bm{A} A了, A \bm{A} A再结合已经确定的参数矩阵,就可以计算出控制律中前半部分。这一点之前文章中也提到过,控制律不需要每一步完全重新计算,只有后半部分需要每一步重新计算,这里固定的前半部分我用变量D表示。
  接下来终于到了仿真中关键的循环部分,Y_DMC和U_DMC用来存储每一步的输出和控制量,Y_P0为 y ~ P 0 \bm{\widetilde{y}_{P0}} y P0,Y_P1为 y ~ P 1 \bm{\widetilde{y}_{P1}} y P1,Y_COR为 y ~ COR \bm{\widetilde{y}_\text{COR}} y COR。上篇中提到过,为了让程序第一个时刻可以走下去,第一个时刻先将这些预测值,控制量等全部初始化为0。有人会较真,预测值必须初始化为0吗?澄清一下,预测值初始化为1甚至1000000都可以,由于这里仿真的时候对象输出是从0开始变化的,所以初始化为0保证了第一个时刻预测值和实际值的误差 e e e不会太大,导致不必要的控制过程波动,因为第一步的 e e e很大,会导致最初的几个时刻反复大幅度地修正预测值。实际中,例如实际的锅炉温度在500℃左右,那么几个预测值初始化在500℃显然更好。
  在进入for循环前,理论上应该先求一次y_P1:

y=0;                                    % 对象当前输出
y_P1=y_P0+a(1:P,1)*du; % ############## 理论上应该在这个位置求一次初始的y_P1
for i=1:1:SimuStepCount

  由于第一个时刻前du为0,所以y_P1和y_P0是相等的,这里就省略了这一行代码,严格按照算法的流程,应该是有这一行的。
  进入for循环,现在是 k k k时刻,先计算 e e e,然后计算修正后的预测值 y ~ COR \bm{\widetilde{y}_\text{COR}} y COR,移位后得到对 k + 1 k+1 k+1时刻未施加控制增量的预测值 y ~ P 0 \bm{\widetilde{y}_{P0}} y P0,求解控制律得到du,叠加在之前的控制量u之上,得到 k k k时刻的控制量施加给对象,同时计算施加du之后的预测值,再次强调一下,标蓝的文字都是在 k k k时刻的计算过程,得到的是 k k k时刻的控制量,但是 k k k时刻控制量作用到对象之后, k + 1 k+1 k+1时刻才能收到对象反馈值,时序非常关键,哪个时刻发生了哪些事一定不要弄混!y_P1=y_P0+a(1:P,1)*du;这一行倒是无所谓,放在 k k k时刻计算出控制律后,或者放在求 e e e之前都可以,只不过放在计算控制律之后表示求y_P1发生在 k k k时刻,放在求 e e e之前表示求y_P1发生在 k + 1 k+1 k+1时刻。放在求 e e e之前的话这段代码就变成这样:

for i=1:1:SimuStepCount
    % DMC计算部分
    y_P1=y_P0+a(1:P,1)*du;
    e=Y_DMC(i,1)-y_P1(1,1);
    y_COR=y_P1+H*e;
    y_P0=S*y_COR;
    du=D*(SP-y_P0);
    u=du+u;

  这里体现了算法和编程的区别,算法的推导一定要求严谨,不能缺少步骤,步骤的顺序更不能随意调换,而实际的编程一些步骤缺少或者步骤间调换顺序并不会影响计算。
  如果是实际的被控对象,计算出每一步的控制量u就可以,但仿真需要我们自己实现被控对象从输入到输出的过程。

dx=K/T*u+(-1/T)*y;                  % 计算dx
y=y+dx*dt;                          % 计算输出

  传递函数表示的是连续的被控对象,计算机的控制都是离散的。(类似于数学中积分的概念,人工计算可以计算连续函数的积分,计算机计算只能将函数切割成一小段一小段累加来得到积分值。)在控制过程中我们要将被控对象进行离散化,这里使用的是离散相似法中的分环节离散的方式,关于被控对象离散化可以参考相关资料,一阶对象只需要修改上面代码的K和T即可。
  Y_DMC(i+1,1)=y;和U_DMC(i,1)=u;这里刻意明确了一下索引,y是 k + 1 k+1 k+1时刻的对象反馈,u是 k k k时刻的控制量。
  循环结束,我们得到了整个控制过程的对象输出和控制量,绘图就可以观察结果。

仿真结果展示

在这里插入图片描述

参数对性能的影响

参数P对性能影响

Matlab源码

clear;clc;                              % 清除缓存变量,清除命令行信息
dt=1;                                   % 采样周期
%################################ 基本DMC P=500 #####################################%
%% 被控对象参数
K=1;                                    % 开环增益
T=215;                                  % 惯性时间
%% DMC参数
N=2000;                                 % 建模时域
P=500;                                  % 预测时域
M=1;                                    % 控制时域
q=1;                                    % Q矩阵(预测输出与期望值误差权矩阵)中的一个权值
lamda=1;                                % λ(LAMDA)矩阵(控制增量权矩阵)中的一个权值
h=1;                                    % H矩阵(预测与实际输出误差校正系数矩阵)中的一个系数
%% 根据DMC参数计算DMC参数矩阵
Q=q*eye(P);                             % 生成Q矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
H=h*ones(P,1);                          % 生成反馈校正H矩阵
S=zeros(P,P);                           % 生成移位矩阵S
for i=1:P-1
    S(i,i+1)=1;                         % 次对角线元素为1
end
S(P,P-1)=0; S(P,P)=1;                   % 右下角元素为1
%% 阶跃响应模型
num=K;                                  % 传递函数的分子部分
den=[T 1];                              % 传递函数的分母部分
sys=tf(num,den);                        % 构成传递函数
a=step(sys,0:dt:N);                     % 参数依次为要施加阶跃输入的传递函数,起始时间:步长(周期):截止时间
%% 离线计算控制律前一部分的矩阵
A=zeros(P,M);                           % 生成动态矩阵A,A是P行M列
for i=1:M                               % 从1到M列
    for j=i:P                           % 从i到P行
        A(j,i)=a(j-i+1,1);
    end
end
C(1,1)=1;
for i=2:M
    C(1,i)=0;                           % 生成C矩阵
end
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 仿真参数设置
SimuStepCount=2999;                     % 总仿真步数
sp=1;                                   % 设定值
SP=sp*ones(P,1);                        % 设定值向量
%% 开始仿真
Y_DMC=zeros(SimuStepCount+1,1);         % 保存每一步对象输出
U_DMC=zeros(SimuStepCount+1,1);         % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC(i+1,1)=y;                     % 存储到Y_DMC
    U_DMC(i,1)=u;                       % 存储到U_DMC
end
U_DMC(SimuStepCount+1,1)=U_DMC(SimuStepCount,1);
%% ################################ 基本DMC P=400 #####################################%
P=400;                                  % 预测时域
%% 根据DMC参数计算DMC参数矩阵
Q=q*eye(P);                             % 生成Q矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
H=h*ones(P,1);                          % 生成反馈校正H矩阵
S=zeros(P,P);                           % 生成移位矩阵S
for i=1:P-1
    S(i,i+1)=1;                         % 次对角线元素为1
end
S(P,P-1)=0; S(P,P)=1;                   % 右下角元素为1
%% 离线计算控制律前一部分的矩阵
A=zeros(P,M);                           % 生成动态矩阵A,A是P行M列
for i=1:M                               % 从1到M列
    for j=i:P                           % 从i到P行
        A(j,i)=a(j-i+1,1);
    end
end
C(1,1)=1;
for i=2:M
    C(1,i)=0;                           % 生成C矩阵
end
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 仿真参数设置
SP=sp*ones(P,1);                        % 设定值向量
%% 开始仿真
Y_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步对象输出
U_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC2(i+1,1)=y;                    % 存储到Y_DMC
    U_DMC2(i,1)=u;                      % 存储到U_DMC
end
U_DMC2(SimuStepCount+1,1)=U_DMC2(SimuStepCount,1);
%% ################################ 基本DMC P=300 #####################################%
P=300;                                  % 预测时域
%% 根据DMC参数计算DMC参数矩阵
Q=q*eye(P);                             % 生成Q矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
H=h*ones(P,1);                          % 生成反馈校正H矩阵
S=zeros(P,P);                           % 生成移位矩阵S
for i=1:P-1
    S(i,i+1)=1;                         % 次对角线元素为1
end
S(P,P-1)=0; S(P,P)=1;                   % 右下角元素为1
%% 离线计算控制律前一部分的矩阵
A=zeros(P,M);                           % 生成动态矩阵A,A是P行M列
for i=1:M                               % 从1到M列
    for j=i:P                           % 从i到P行
        A(j,i)=a(j-i+1,1);
    end
end
C(1,1)=1;
for i=2:M
    C(1,i)=0;                           % 生成C矩阵
end
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 仿真参数设置
SP=sp*ones(P,1);                        % 设定值向量
%% 开始仿真
Y_DMC3=zeros(SimuStepCount+1,1);        % 保存每一步对象输出
U_DMC3=zeros(SimuStepCount+1,1);        % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC3(i+1,1)=y;                    % 存储到Y_DMC
    U_DMC3(i,1)=u;                      % 存储到U_DMC
end
U_DMC3(SimuStepCount+1,1)=U_DMC3(SimuStepCount,1);
%% 绘图
n=size(Y_DMC,1);
subplot(2,1,1);
t=1:1:n;
plot(t,Y_DMC(1:n),'r');
hold on;
plot(t,Y_DMC2(1:n),'b--');
hold on;
plot(t,Y_DMC3(1:n),'k-.');
legend('P=500','P=400','P=300')
title('y')
subplot(2,1,2);
plot(t,U_DMC(1:n),'r');
hold on;
plot(t,U_DMC2(1:n),'b--');
hold on;
plot(t,U_DMC3(1:n),'k-.');
legend('P=500','P=400','P=300')
title('u')

仿真结果

在这里插入图片描述

参数M对性能影响

Matlab源码

clear;clc;                              % 清除缓存变量,清除命令行信息
dt=1;                                   % 采样周期
%################################ 基本DMC M=1 #####################################%
%% 被控对象参数
K=1;                                    % 开环增益
T=215;                                  % 惯性时间
%% DMC参数
N=2000;                                 % 建模时域
P=500;                                  % 预测时域
M=1;                                    % 控制时域
q=1;                                    % Q矩阵(预测输出与期望值误差权矩阵)中的一个权值
lamda=1;                                % λ(LAMDA)矩阵(控制增量权矩阵)中的一个权值
h=1;                                    % H矩阵(预测与实际输出误差校正系数矩阵)中的一个系数
%% 根据DMC参数计算DMC参数矩阵
Q=q*eye(P);                             % 生成Q矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
H=h*ones(P,1);                          % 生成反馈校正H矩阵
S=zeros(P,P);                           % 生成移位矩阵S
for i=1:P-1
    S(i,i+1)=1;                         % 次对角线元素为1
end
S(P,P-1)=0; S(P,P)=1;                   % 右下角元素为1
%% 阶跃响应模型
num=K;                                  % 传递函数的分子部分
den=[T 1];                              % 传递函数的分母部分
sys=tf(num,den);                        % 构成传递函数
a=step(sys,0:dt:N);                     % 参数依次为要施加阶跃输入的传递函数,起始时间:步长(周期):截止时间
%% 离线计算控制律前一部分的矩阵
A=zeros(P,M);                           % 生成动态矩阵A,A是P行M列
for i=1:M                               % 从1到M列
    for j=i:P                           % 从i到P行
        A(j,i)=a(j-i+1,1);
    end
end
C(1,1)=1;
for i=2:M
    C(1,i)=0;                           % 生成C矩阵
end
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 仿真参数设置
SimuStepCount=2999;                     % 总仿真步数
sp=1;                                   % 设定值
SP=sp*ones(P,1);                        % 设定值向量
%% 开始仿真
Y_DMC=zeros(SimuStepCount+1,1);         % 保存每一步对象输出
U_DMC=zeros(SimuStepCount+1,1);         % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC(i+1,1)=y;                     % 存储到Y_DMC
    U_DMC(i,1)=u;                       % 存储到U_DMC
end
U_DMC(SimuStepCount+1,1)=U_DMC(SimuStepCount,1);
%% ################################ 基本DMC M=2 #####################################%
M=2;
%% 根据DMC参数计算DMC参数矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
%% 离线计算控制律前一部分的矩阵
A=zeros(P,M);                           % 生成动态矩阵A,A是P行M列
for i=1:M                               % 从1到M列
    for j=i:P                           % 从i到P行
        A(j,i)=a(j-i+1,1);
    end
end
C(1,1)=1;
for i=2:M
    C(1,i)=0;                           % 生成C矩阵
end
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 开始仿真
Y_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步对象输出
U_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC2(i+1,1)=y;                    % 存储到Y_DMC
    U_DMC2(i,1)=u;                      % 存储到U_DMC
end
U_DMC2(SimuStepCount+1,1)=U_DMC2(SimuStepCount,1);
%% ################################ 基本DMC M=5 #####################################%
M=5;
%% 根据DMC参数计算DMC参数矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
%% 离线计算控制律前一部分的矩阵
A=zeros(P,M);                           % 生成动态矩阵A,A是P行M列
for i=1:M                               % 从1到M列
    for j=i:P                           % 从i到P行
        A(j,i)=a(j-i+1,1);
    end
end
C(1,1)=1;
for i=2:M
    C(1,i)=0;                           % 生成C矩阵
end
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 开始仿真
Y_DMC3=zeros(SimuStepCount+1,1);        % 保存每一步对象输出
U_DMC3=zeros(SimuStepCount+1,1);        % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC3(i+1,1)=y;                    % 存储到Y_DMC
    U_DMC3(i,1)=u;                      % 存储到U_DMC
end
U_DMC3(SimuStepCount+1,1)=U_DMC3(SimuStepCount,1);
%% 绘图
n=size(Y_DMC,1);
subplot(2,1,1);
t=1:1:n;
plot(t,Y_DMC(1:n),'r');
hold on;
plot(t,Y_DMC2(1:n),'b--');
hold on;
plot(t,Y_DMC3(1:n),'k-.');
legend('M=1','M=2','M=5')
title('y')
subplot(2,1,2);
plot(t,U_DMC(1:n),'r');
hold on;
plot(t,U_DMC2(1:n),'b--');
hold on;
plot(t,U_DMC3(1:n),'k-.');
legend('M=1','M=2','M=5')
title('u')

仿真结果

在这里插入图片描述

参数q对性能影响

Matlab源码

clear;clc;                              % 清除缓存变量,清除命令行信息
dt=1;                                   % 采样周期
%################################ 基本DMC q=1 #####################################%
%% 被控对象参数
K=1;                                    % 开环增益
T=215;                                  % 惯性时间
%% DMC参数
N=2000;                                 % 建模时域
P=500;                                  % 预测时域
M=1;                                    % 控制时域
q=1;                                    % Q矩阵(预测输出与期望值误差权矩阵)中的一个权值
lamda=1;                                % λ(LAMDA)矩阵(控制增量权矩阵)中的一个权值
h=1;                                    % H矩阵(预测与实际输出误差校正系数矩阵)中的一个系数
%% 根据DMC参数计算DMC参数矩阵
Q=q*eye(P);                             % 生成Q矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
H=h*ones(P,1);                          % 生成反馈校正H矩阵
S=zeros(P,P);                           % 生成移位矩阵S
for i=1:P-1
    S(i,i+1)=1;                         % 次对角线元素为1
end
S(P,P-1)=0; S(P,P)=1;                   % 右下角元素为1
%% 阶跃响应模型
num=K;                                  % 传递函数的分子部分
den=[T 1];                              % 传递函数的分母部分
sys=tf(num,den);                        % 构成传递函数
a=step(sys,0:dt:N);                     % 参数依次为要施加阶跃输入的传递函数,起始时间:步长(周期):截止时间
%% 离线计算控制律前一部分的矩阵
A=zeros(P,M);                           % 生成动态矩阵A,A是P行M列
for i=1:M                               % 从1到M列
    for j=i:P                           % 从i到P行
        A(j,i)=a(j-i+1,1);
    end
end
C(1,1)=1;
for i=2:M
    C(1,i)=0;                           % 生成C矩阵
end
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 仿真参数设置
SimuStepCount=2999;                     % 总仿真步数
sp=1;                                   % 设定值
SP=sp*ones(P,1);                        % 设定值向量
%% 开始仿真
Y_DMC=zeros(SimuStepCount+1,1);         % 保存每一步对象输出
U_DMC=zeros(SimuStepCount+1,1);         % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC(i+1,1)=y;                     % 存储到Y_DMC
    U_DMC(i,1)=u;                       % 存储到U_DMC
end
U_DMC(SimuStepCount+1,1)=U_DMC(SimuStepCount,1);
%% ################################ 基本DMC q=0.0001 #####################################%
q=0.0001;
%% 根据DMC参数计算DMC参数矩阵
Q=q*eye(P);                             % 生成Q矩阵
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 开始仿真
Y_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步对象输出
U_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC2(i+1,1)=y;                    % 存储到Y_DMC
    U_DMC2(i,1)=u;                      % 存储到U_DMC
end
U_DMC2(SimuStepCount+1,1)=U_DMC2(SimuStepCount,1);
%% ################################ 基本DMC q=0.00005 #####################################%
q=0.00005;
%% 根据DMC参数计算DMC参数矩阵
Q=q*eye(P);                             % 生成Q矩阵
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 开始仿真
Y_DMC3=zeros(SimuStepCount+1,1);        % 保存每一步对象输出
U_DMC3=zeros(SimuStepCount+1,1);        % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC3(i+1,1)=y;                    % 存储到Y_DMC
    U_DMC3(i,1)=u;                      % 存储到U_DMC
end
U_DMC3(SimuStepCount+1,1)=U_DMC3(SimuStepCount,1);
%% 绘图
n=size(Y_DMC,1);
subplot(2,1,1);
t=1:1:n;
plot(t,Y_DMC(1:n),'r');
hold on;
plot(t,Y_DMC2(1:n),'b--');
hold on;
plot(t,Y_DMC3(1:n),'k-.');
legend('q=1','q=0.0001','q=0.00005')
title('y')
subplot(2,1,2);
plot(t,U_DMC(1:n),'r');
hold on;
plot(t,U_DMC2(1:n),'b--');
hold on;
plot(t,U_DMC3(1:n),'k-.');
legend('q=1','q=0.0001','q=0.00005')
title('u')

仿真结果

在这里插入图片描述

参数lamda对性能影响

Matlab源码

clear;clc;                              % 清除缓存变量,清除命令行信息
dt=1;                                   % 采样周期
%################################ 基本DMC lamda=1 #####################################%
%% 被控对象参数
K=1;                                    % 开环增益
T=215;                                  % 惯性时间
%% DMC参数
N=2000;                                 % 建模时域
P=500;                                  % 预测时域
M=1;                                    % 控制时域
q=1;                                    % Q矩阵(预测输出与期望值误差权矩阵)中的一个权值
lamda=1;                                % λ(LAMDA)矩阵(控制增量权矩阵)中的一个权值
h=1;                                    % H矩阵(预测与实际输出误差校正系数矩阵)中的一个系数
%% 根据DMC参数计算DMC参数矩阵
Q=q*eye(P);                             % 生成Q矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
H=h*ones(P,1);                          % 生成反馈校正H矩阵
S=zeros(P,P);                           % 生成移位矩阵S
for i=1:P-1
    S(i,i+1)=1;                         % 次对角线元素为1
end
S(P,P-1)=0; S(P,P)=1;                   % 右下角元素为1
%% 阶跃响应模型
num=K;                                  % 传递函数的分子部分
den=[T 1];                              % 传递函数的分母部分
sys=tf(num,den);                        % 构成传递函数
a=step(sys,0:dt:N);                     % 参数依次为要施加阶跃输入的传递函数,起始时间:步长(周期):截止时间
%% 离线计算控制律前一部分的矩阵
A=zeros(P,M);                           % 生成动态矩阵A,A是P行M列
for i=1:M                               % 从1到M列
    for j=i:P                           % 从i到P行
        A(j,i)=a(j-i+1,1);
    end
end
C(1,1)=1;
for i=2:M
    C(1,i)=0;                           % 生成C矩阵
end
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 仿真参数设置
SimuStepCount=2999;                     % 总仿真步数
sp=1;                                   % 设定值
SP=sp*ones(P,1);                        % 设定值向量
%% 开始仿真
Y_DMC=zeros(SimuStepCount+1,1);         % 保存每一步对象输出
U_DMC=zeros(SimuStepCount+1,1);         % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC(i+1,1)=y;                     % 存储到Y_DMC
    U_DMC(i,1)=u;                       % 存储到U_DMC
end
U_DMC(SimuStepCount+1,1)=U_DMC(SimuStepCount,1);
%% ################################ 基本DMC lamda=10000 #####################################%
lamda=10000;
%% 根据DMC参数计算DMC参数矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 开始仿真
Y_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步对象输出
U_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC2(i+1,1)=y;                    % 存储到Y_DMC
    U_DMC2(i,1)=u;                      % 存储到U_DMC
end
U_DMC2(SimuStepCount+1,1)=U_DMC2(SimuStepCount,1);
%% ################################ 基本DMC lamda=50000 #####################################%
lamda=50000;
%% 根据DMC参数计算DMC参数矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 开始仿真
Y_DMC3=zeros(SimuStepCount+1,1);        % 保存每一步对象输出
U_DMC3=zeros(SimuStepCount+1,1);        % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC3(i+1,1)=y;                    % 存储到Y_DMC
    U_DMC3(i,1)=u;                      % 存储到U_DMC
end
U_DMC3(SimuStepCount+1,1)=U_DMC3(SimuStepCount,1);
%% 绘图
n=size(Y_DMC,1);
subplot(2,1,1);
t=1:1:n;
plot(t,Y_DMC(1:n),'r');
hold on;
plot(t,Y_DMC2(1:n),'b--');
hold on;
plot(t,Y_DMC3(1:n),'k-.');
legend('lamda=1','lamda=10000','lamda=50000')
title('y')
subplot(2,1,2);
plot(t,U_DMC(1:n),'r');
hold on;
plot(t,U_DMC2(1:n),'b--');
hold on;
plot(t,U_DMC3(1:n),'k-.');
legend('lamda=1','lamda=10000','lamda=50000')
title('u')

仿真结果

在这里插入图片描述

讨论

  对照仿真结果,结合公式推导,我们就可以进一步理解各个参数的作用。
  参数P增大,首先会使得动态矩阵 A \bm{A} A的行数增加, 导致控制律前半部分的值增大, 但是参数P增大,又会使得控制律后半部分设定值SP与预测值y_P0的差构成向量末尾出现更多的0(可以想象到,P足够大时,设定值与预测值到后面必然会相等,导致继续增大P会使得SP-y_P0末尾出现越来越多的0),所以从控制律公式分析,不好确定P对控制效果的影响。于是我们从仿真结果来看,P的增加导致控制量给的更稳了,对于被控对象来说,这就意味着到达设定值的过程变慢了。
  参数M增大,会使得动态矩阵 A \bm{A} A的列数增加, 导致控制律前半部分的值增大, 而M对控制律后半部分没有影响,那么会使得根据控制律得到的控制增量增大,也就是说,从控制律公式来看,M增大应该会使得控制量变化更明显,相应地被控对象到达设定值时间会加快。从仿真结果来看,和我们的推测是一致的,M增大时,一开始的控制量会给得更猛。
  参数q和参数lamda从它们的定义中就知道,q越大,被控对象到达设定值会越快,控制量变化会更剧烈,lamda越大,控制量变化会更受限制,使得控制过程更稳定,被控对象到达设定值变慢,仿真结果也是完全对应的。但是还有一个小细节,如果把我的代码里q改成2,3或者lamda改成2,3,会看到几条几乎重合的曲线,实际上你把曲线放大放大再放大,可能要到小数点后四五位,确实也能看到符合上述结论,然后你就明白我上面的q和lamda为什么要设置这么大/这么小了,这提醒了我们,q和lamda确实可以影响控制效果,但是要能够真正“明显”地看到影响,需要先对动态矩阵 A \bm{A} A以及控制律前半部分的数量级有个估计,进而确定q和lamda在什么数量级。实际上这太麻烦了,实际中q和lamda一般都设成1就懒得调了,如果需要,再自行解决吧O(∩_∩)O。

算法改进效果验证

阶梯式动态矩阵控制与基础DMC对比

  下面的代码如果把M改成1,可以看到DMC和SDMC结果是完全一致的,这里M设置为5方便观察效果,从仿真结果可以看出SDMC将控制量规划为阶梯形式后,削弱了控制量,控制过程更平缓(之前说过,SDMC更重要的作用是取消求逆环节来加快运算速度,用其他编程语言实现SDMC时,可以打印一下运算时间,MATLAB两种算法计算速度都很快,个人认为参考意义不大就没有打印运算时间)。

Matlab源码

clear;clc;                              % 清除缓存变量,清除命令行信息
dt=1;                                   % 采样周期
%################################ 基本DMC #####################################%
%% 被控对象参数
K=1;                                    % 开环增益
T=215;                                  % 惯性时间
%% DMC参数
N=2000;                                 % 建模时域
P=500;                                  % 预测时域
M=5;                                    % 控制时域
q=1;                                    % Q矩阵(预测输出与期望值误差权矩阵)中的一个权值
lamda=1;                                % λ(LAMDA)矩阵(控制增量权矩阵)中的一个权值
h=1;                                    % H矩阵(预测与实际输出误差校正系数矩阵)中的一个系数
%% 根据DMC参数计算DMC参数矩阵
Q=q*eye(P);                             % 生成Q矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
H=h*ones(P,1);                          % 生成反馈校正H矩阵
S=zeros(P,P);                           % 生成移位矩阵S
for i=1:P-1
    S(i,i+1)=1;                         % 次对角线元素为1
end
S(P,P-1)=0; S(P,P)=1;                   % 右下角元素为1
%% 阶跃响应模型
num=K;                                  % 传递函数的分子部分
den=[T 1];                              % 传递函数的分母部分
sys=tf(num,den);                        % 构成传递函数
a=step(sys,0:dt:N);                     % 参数依次为要施加阶跃输入的传递函数,起始时间:步长(周期):截止时间
%% 离线计算控制律前一部分的矩阵
A=zeros(P,M);                           % 生成动态矩阵A,A是P行M列
for i=1:M                               % 从1到M列
    for j=i:P                           % 从i到P行
        A(j,i)=a(j-i+1,1);
    end
end
C(1,1)=1;
for i=2:M
    C(1,i)=0;                           % 生成C矩阵
end
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 仿真参数设置
SimuStepCount=2999;                     % 总仿真步数
sp=1;                                   % 设定值
SP=sp*ones(P,1);                        % 设定值向量
%% 开始仿真
Y_DMC=zeros(SimuStepCount+1,1);         % 保存每一步对象输出
U_DMC=zeros(SimuStepCount+1,1);         % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC(i+1,1)=y;                     % 存储到Y_DMC
    U_DMC(i,1)=u;                       % 存储到U_DMC
end
U_DMC(SimuStepCount+1,1)=U_DMC(SimuStepCount,1);
%% ################################ SDMC #####################################%
beita=0.9;
%% 根据DMC参数计算DMC参数矩阵
beita_all=0;
for i=1:M
    lam(i,1) = beita^(i-1);
    beita_all=beita_all+beita^(2*i-2);
end
G=A*lam;
D=G'*Q/((G'*Q*G)+lamda*beita_all);
%% 开始仿真
Y_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步对象输出
U_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC2(i+1,1)=y;                    % 存储到Y_DMC
    U_DMC2(i,1)=u;                      % 存储到U_DMC
end
U_DMC2(SimuStepCount+1,1)=U_DMC2(SimuStepCount,1);
%% 绘图
n=size(Y_DMC,1);
subplot(2,1,1);
t=1:1:n;
plot(t,Y_DMC(1:n),'r');
hold on;
plot(t,Y_DMC2(1:n),'b--');
legend('DMC','SDMC')
title('y')
subplot(2,1,2);
plot(t,U_DMC(1:n),'r');
hold on;
plot(t,U_DMC2(1:n),'b--');
legend('DMC','SDMC')
title('u')

仿真结果

在这里插入图片描述

反馈校正环节截断误差改进

  其实大家从上面一副图中就可以看到,DMC出现了一个明显的“小尖尖”,刚好是在第500步(与预测时域相等)出现的,这就是中篇中提到的截断误差累积导致的。采用改进的移位矩阵,我们可以看到截断误差明显减小了。

Matlab源码

clear;clc;                              % 清除缓存变量,清除命令行信息
dt=1;                                   % 采样周期
%################################ 基本DMC #####################################%
%% 被控对象参数
K=1;                                    % 开环增益
T=215;                                  % 惯性时间
%% DMC参数
N=2000;                                 % 建模时域
P=500;                                  % 预测时域
M=5;                                    % 控制时域
q=1;                                    % Q矩阵(预测输出与期望值误差权矩阵)中的一个权值
lamda=1;                                % λ(LAMDA)矩阵(控制增量权矩阵)中的一个权值
h=1;                                    % H矩阵(预测与实际输出误差校正系数矩阵)中的一个系数
%% 根据DMC参数计算DMC参数矩阵
Q=q*eye(P);                             % 生成Q矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
H=h*ones(P,1);                          % 生成反馈校正H矩阵
S=zeros(P,P);                           % 生成移位矩阵S
for i=1:P-1
    S(i,i+1)=1;                         % 次对角线元素为1
end
S(P,P-1)=0; S(P,P)=1;                   % 右下角元素为1
%% 阶跃响应模型
num=K;                                  % 传递函数的分子部分
den=[T 1];                              % 传递函数的分母部分
sys=tf(num,den);                        % 构成传递函数
a=step(sys,0:dt:N);                     % 参数依次为要施加阶跃输入的传递函数,起始时间:步长(周期):截止时间
%% 离线计算控制律前一部分的矩阵
A=zeros(P,M);                           % 生成动态矩阵A,A是P行M列
for i=1:M                               % 从1到M列
    for j=i:P                           % 从i到P行
        A(j,i)=a(j-i+1,1);
    end
end
C(1,1)=1;
for i=2:M
    C(1,i)=0;                           % 生成C矩阵
end
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 仿真参数设置
SimuStepCount=2999;                     % 总仿真步数
sp=1;                                   % 设定值
SP=sp*ones(P,1);                        % 设定值向量
%% 开始仿真
Y_DMC=zeros(SimuStepCount+1,1);         % 保存每一步对象输出
U_DMC=zeros(SimuStepCount+1,1);         % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC(i+1,1)=y;                     % 存储到Y_DMC
    U_DMC(i,1)=u;                       % 存储到U_DMC
end
U_DMC(SimuStepCount+1,1)=U_DMC(SimuStepCount,1);
%% ################################ 改进移位矩阵 #####################################%
%% 反馈校正环节改进:如果a存在截断误差,移位矩阵需要调整
kesai=(a(P,1)-a(P-1,1))/(a(P-1,1)-a(P-2,1));
if (kesai>0)&&(kesai<1)
    S(P,P-1)=0-kesai;S(P,P)=1+kesai;
end
%% 开始仿真
Y_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步对象输出
U_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    dx=K/T*u+(-1/T)*y;                  % 计算dx
    y=y+dx*dt;                          % 计算输出
    Y_DMC2(i+1,1)=y;                    % 存储到Y_DMC
    U_DMC2(i,1)=u;                      % 存储到U_DMC
end
U_DMC2(SimuStepCount+1,1)=U_DMC2(SimuStepCount,1);
%% 绘图
n=size(Y_DMC,1);
subplot(2,1,1);
t=1:1:n;
plot(t,Y_DMC(1:n),'r');
hold on;
plot(t,Y_DMC2(1:n),'b--');
legend('DMC','改进移位矩阵')
title('y')
subplot(2,1,2);
plot(t,U_DMC(1:n),'r');
hold on;
plot(t,U_DMC2(1:n),'b--');
legend('DMC','改进移位矩阵')
title('u')

仿真结果

在这里插入图片描述

对象存在纯迟延时控制器参数优化

  要在自己的离散化中加入纯迟延过程,可以参照下面的代码,增加一个“缓冲序列”,在经过tao步后才输出没有纯迟延时当前步数的值。可以看到,优化参数后,提升了控制性能。

Matlab源码

clear;clc;                              % 清除缓存变量,清除命令行信息
dt=1;                                   % 采样周期
%################################ 存在纯迟延时用原始控制器参数 #####################################%
%% 被控对象参数
K=1;                                    % 开环增益
T=215;                                  % 惯性时间
%% DMC参数
N=2000;                                 % 建模时域
P=500;                                  % 预测时域
M=3;                                    % 控制时域
q=1;                                    % Q矩阵(预测输出与期望值误差权矩阵)中的一个权值
lamda=1;                                % λ(LAMDA)矩阵(控制增量权矩阵)中的一个权值
h=1;                                    % H矩阵(预测与实际输出误差校正系数矩阵)中的一个系数
%% 根据DMC参数计算DMC参数矩阵
Q=q*eye(P);                             % 生成Q矩阵
LAMDA=lamda*eye(M);                     % 生成LAMDA矩阵
H=h*ones(P,1);                          % 生成反馈校正H矩阵
S=zeros(P,P);                           % 生成移位矩阵S
for i=1:P-1
    S(i,i+1)=1;                         % 次对角线元素为1
end
S(P,P-1)=0; S(P,P)=1;                   % 右下角元素为1
%% 阶跃响应模型
num=K;                                  % 传递函数的分子部分
den=[T 1];                              % 传递函数的分母部分
tao=150;                                % 迟延时间
sys=tf(num,den,'iodelay',tao); 
a=step(sys,0:dt:N);                     % 参数依次为要施加阶跃输入的传递函数,起始时间:步长(周期):截止时间

%% 离线计算控制律前一部分的矩阵
A=zeros(P,M);                           % 生成动态矩阵A,A是P行M列
for i=1:M                               % 从1到M列
    for j=i:P                           % 从i到P行
        A(j,i)=a(j-i+1,1);
    end
end
C(1,1)=1;
for i=2:M
    C(1,i)=0;                           % 生成C矩阵
end
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 仿真参数设置
SimuStepCount=2999;                     % 总仿真步数
sp=1;                                   % 设定值
SP=sp*ones(P,1);                        % 设定值向量
%% 开始仿真
Y_DMC=zeros(SimuStepCount+1,1);         % 保存每一步对象输出
U_DMC=zeros(SimuStepCount+1,1);         % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
YDealyArray=zeros(floor(tao/dt),1);     % 保存迟延的队列,长度为实际迟延除以采样周期
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    y=YDealyArray(tao,1);               % 实际输出取延迟后的Y,队列的最后一项   
    % 实现纯迟延过程
    dx=K/T*u+(-1/T)*YDealyArray(1,1);   % 按照没有纯迟延计算dx,队列中第一项YDealyArray(1,1)是没有纯迟延对象的前一时刻输出
    temp=YDealyArray(1,1)+dx*dt;        % 按照没有纯迟延计算输出
    for j=floor(tao/dt):-1:2            % 根据迟延逐个移动队列,实现经过tao时间后再输出没有延迟时计算输出    
        YDealyArray(j,1)=YDealyArray(j-1,1);
    end
    YDealyArray(1,1)=temp;
    % 存储数据
    Y_DMC(i+1,1)=y;                    % 存储到Y_DMC
    U_DMC(i,1)=u;                      % 存储到U_DMC
end
U_DMC(SimuStepCount+1,1)=U_DMC(SimuStepCount,1);
Q_0=Q;
P_0=P;
N_0=N;
%% ################################ 存在纯迟延时用优化后控制器参数 #####################################%
tao=150;                                % 迟延时间
if tao>0 
   N=N_0+tao;                                 % 建模时域
   Q=[zeros(tao,tao) zeros(tao,P_0);zeros(P_0,tao) Q_0];
   P=P_0+tao;
end
sys=tf(num,den,'iodelay',tao); 
a=step(sys,0:dt:N);                     % 参数依次为要施加阶跃输入的传递函数,起始时间:步长(周期):截止时间
%% 控制律求解参数的改进:如果带纯迟延需要改进P和Q
%% 根据DMC参数计算DMC参数矩阵
H=h*ones(P,1);                          % 生成反馈校正H矩阵
S=zeros(P,P);                           % 生成移位矩阵S
for i=1:P-1
    S(i,i+1)=1;                         % 次对角线元素为1
end
S(P,P-1)=0; S(P,P)=1;                   % 右下角元素为1
SP=sp*ones(P,1);                        % 设定值向量
%% 离线计算控制律前一部分的矩阵
A=zeros(P,M);                           % 生成动态矩阵A,A是P行M列
for i=1:M                               % 从1到M列
    for j=i:P                           % 从i到P行
        A(j,i)=a(j-i+1,1);
    end
end
C(1,1)=1;
for i=2:M
    C(1,i)=0;                           % 生成C矩阵
end
D=C*inv(A'*Q*A+LAMDA)*A'*Q;             % 得到控制律前一部分的矩阵
%% 开始仿真
Y_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步对象输出
U_DMC2=zeros(SimuStepCount+1,1);        % 保存每一步控制量
y_P1=zeros(P,1);                        % 当前时刻施加一个控制增量后未来P步预测值
y_P0=zeros(P,1);                        % 当前时刻没有施加控制增量未来P步预测值
y_COR=zeros(P,1);                       % 校正后的y_P1
YDealyArray=zeros(floor(tao/dt),1);     % 保存迟延的队列,长度为实际迟延除以采样周期
du=0;                                   % k时刻计算出的控制增量
u=0;                                    % k时刻计算出的控制量
y=0;                                    % 对象当前输出
for i=1:1:SimuStepCount
    % DMC计算部分
    e=y-y_P1(1,1);                      % 计算实际值与预测值误差
    y_COR=y_P1+H*e;                     % 误差反馈校正
    y_P0=S*y_COR;                       % 校正后预测值作为下一时刻未叠加控制增量的预测值
    du=D*(SP-y_P0);                     % 由控制律计算下一个时刻控制增量
    y_P1=y_P0+a(1:P,1)*du;              % 预测下一时刻施加du后输出
    u=du+u;                             % 这里的u在k时刻算出并施加到对象后,k+1时刻才能得到反馈效果    
    % u作用到对象后计算对象输出(如果是实际对象,程序只需要算出u即可,这里是仿真,对象输出也要计算)
    y=YDealyArray(tao,1);               % 实际输出取延迟后的Y,队列的最后一项   
    % 实现纯迟延过程
    dx=K/T*u+(-1/T)*YDealyArray(1,1);   % 按照没有纯迟延计算dx,队列中第一项YDealyArray(1,1)是没有纯迟延对象的前一时刻输出
    temp=YDealyArray(1,1)+dx*dt;        % 按照没有纯迟延计算输出
    for j=floor(tao/dt):-1:2            % 根据迟延逐个移动队列,实现经过tao时间后再输出没有延迟时计算输出    
        YDealyArray(j,1)=YDealyArray(j-1,1);
    end
    YDealyArray(1,1)=temp;
    % 存储数据
    Y_DMC2(i+1,1)=y;                    % 存储到Y_DMC
    U_DMC2(i,1)=u;                      % 存储到U_DMC
end
U_DMC2(SimuStepCount+1,1)=U_DMC2(SimuStepCount,1);
%% 绘图
n=size(Y_DMC,1);
subplot(2,1,1);
t=1:1:n;
plot(t,Y_DMC(1:n),'r');
hold on;
plot(t,Y_DMC2(1:n),'b--');
legend('存在纯迟延时用原始控制器参数','存在纯迟延时用改进控制器参数')
title('y')
subplot(2,1,2);
plot(t,U_DMC(1:n),'r');
hold on;
plot(t,U_DMC2(1:n),'b--');
legend('存在纯迟延时用原始控制器参数','存在纯迟延时用改进控制器参数')
title('u')

仿真结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1970528.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分散存储的艺术:探索主流数据库分库分表解决方案

摘要&#xff1a; 随着大数据时代的到来&#xff0c;单一数据库系统越来越难以满足日益增长的数据存储和处理需求。分库分表技术应运而生&#xff0c;成为解决这一问题的有效手段。本文将深入探讨主流的数据库分库分表中间件&#xff0c;分析它们的设计理念、实现原理以及应用场…

企业定制AI智能名片微信小程序在私域流量运营中的应用与策略

摘要&#xff1a;随着2022年私域运营市场步入冷静期&#xff0c;企业逐渐从盲目模仿向精准化、个性化的运营模式转变。在这一背景下&#xff0c;企业定制AI智能名片微信小程序凭借其独特的智能化、便捷化特性&#xff0c;成为企业构建私域流量池、深化用户关系、实现高效转化的…

问答:OKR入门

通过使命、愿景和价值观来创建正确的公司文化&#xff0c;以及如何开始使用OKR。以下是对您提出的问题的回答。 让团队加入的最佳方式是什么&#xff1f; 这需要高管的认同和领导力。对于中小型企业来说&#xff0c;从高管团队开始。对于大公司来说&#xff0c;可以在单个业务部…

spring boot + vue3 接入钉钉实现扫码登录

1&#xff1a;准备工作 1.1&#xff1a;进入钉钉开放平台创建开发者应用。应用创建和类型介绍&#xff0c;参考下方。 应用类型介绍 - 钉钉开放平台 (dingtalk.com) 应用能力介绍 - 钉钉开放平台 (dingtalk.com) 扫码登录第三方网站 - 钉钉开放平台 (dingtalk.com) 1.2&…

DLT相机标定算法

本教程介绍了直接线性变换 (DLT)&#xff0c;这是一种用于解决以下类型方程组的通用方法&#xff1a; 这种类型的方程经常出现在射影几何中。一个非常重要的例子是场景中的 3D 点与它们在相机图像平面上的投影之间的关系。这就是为什么我们要使用此设置来激发 DLT 的使用。 NSD…

二百五十二、OceanBase——Linux上安装OceanBase数据库(二):新用户配置ssh免密登录

一、目的 在OBD页面上部署OceanBase数据库时发现&#xff0c;需要把新用户也要配置ssh免密登录 二、前提 root用户已经设置免密登录 三、配置步骤 1 切换到新用户obadmin [roothurys23 ~]# su obadmin 2 执行命令生成秘钥文件 [obadminhurys23 oceanbase]$ ssh-keygen …

动态规划:基础篇

目录 1. 斐波那契数(LeetCode509) 解法1&#xff1a;动态规划(基础版) 解法2&#xff1a;动态规划(优化版) 2. 爬楼梯(方案个数)(斐波那契数列扩展)(LeetCode70) 解法1&#xff1a;动态规划(基础版) 解法2&#xff1a;动态规划(优化版) 3. 爬楼梯(最小花费)(LeetCode746…

品牌进行网络控价的原因和方法

品牌的控价管理是一项关乎其生存与发展的关键举措。在当今竞争激烈的市场环境中&#xff0c;价格的稳定与合理不仅影响着品牌的形象和声誉&#xff0c;更是直接关系到品牌的市场份额和盈利能力。 那些不重视控价管理的品牌&#xff0c;往往会陷入一片混乱。参差不齐的价格使得消…

Delphi5实现文件拷贝程序

效果图 opendialog、savedialog组件 对于类似TOpenDialog和TSaveDialog的功能&#xff0c;在Delphi 5中&#xff0c;你可能需要这样做&#xff1a; 查找或创建&#xff1a;首先&#xff0c;在Delphi 5的组件面板中查找是否有现成的文件对话框组件&#xff08;拖拉组件下来到f…

【通俗理解】概率图模型——从概率到图形的直观映射

【通俗理解】概率图模型——从概率到图形的直观映射 概率与图形的类比 你可以把概率看作是一个“烹饪配方”&#xff0c;它告诉我们每个成分&#xff08;事件&#xff09;出现的可能性。而图形则是一个“食谱的图表”&#xff0c;它直观地展示了这些成分之间的关系和依赖。 概率…

深入探索:GPT系列模型揭秘

Transformer发展 之 GPT系列模型结构 我按照Transformer的发展路线来学习入门 Transformer–BERT—GPT—DETR—ViT—Swin ViT / DeiT 上一篇写了Transformer&#xff0c;听了李宏毅和李沐老师的课一下子就懂了&#xff0c;今天学习GPT-123 核心思想&#xff1a; GPT和BERT的…

服务器数据恢复—SAN环境下LUN被重复映射导致写操作不互斥的数据恢复案例

服务器存储数据恢复环境&#xff1a; 一台存储中有一组由6块硬盘组成的RAID6&#xff0c;划分为若干LUN&#xff0c;MAP到不同业务的SOLARIS操作系统服务器上。 服务器存储故障&#xff1a; 由于业务变化需要增加一台服务器&#xff0c;在存储在线的状态下将该存储中的某个LUN映…

打造沉浸式展厅空间,哪些高科技手段必不可少?

在人生的旅途中&#xff0c;我们或许会踏遍千山万水&#xff0c;将大地的壮丽景色尽收眼底。然而&#xff0c;总有一些地方&#xff0c;如同深邃的海底两万里&#xff0c;或是浩瀚无垠的宇宙银河&#xff0c;遥不可及&#xff0c;这时我们便可以在展厅的沉浸式空间中&#xff0…

Postman请求问题 connect ECONNREFUSED 127.0.0.1:80解决方法

问题描述&#xff1a; 解决方法&#xff1a; &#xff08;1&#xff09;点击file-settings &#xff08;2&#xff09;点击Proxy&#xff0c;并将右边的Use the system proxy 取消选中 &#xff08;3&#xff09;勾选use custom proxy configuration 这个8080是默认的&#xf…

MySQL学习(17):SQL编程:存储过程

1.什么是存储过程 存储过程是事先经过编译并存储在数据库中的一段 SQL语句的集合。 存储过程的特点&#xff1a; &#xff08;1&#xff09;封装&#xff0c;复用 &#xff08;2&#xff09;可以接收参数&#xff0c;可以返回数据 2.存储过程语法 2.1创建 create procedu…

查看Keepalived 的 VIP 有效、高可用、单播和组播

VIP&#xff08;虚拟 IP&#xff09; VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09; 验证 VIP 是否有效 1、没有部署之前&#xff0c;PING要设置的VIP地址&#xff0c;不通 ping 10.119.108.602、部署之后&#xff0c;所有节点进行PING要设置的VIP地址&a…

代码实现yolov3主干网络,可以直接运行

1. 主干网head版本1 import torch from torch import nn import torch.nn.functional as F class ConvBnLeakRelu(nn.Module):def __init__(self,in_ch,out_ch,k3,s1):super().__init__()self.layernn.Sequential(nn.Conv2d(in_ch, out_ch, kernel_sizek, paddingk // 2,stride…

H264记录和翻译

官方中文文档&#xff1a; &#x1f4ce;H.264_ITU官方中文版.pdf 官方下载地址&#xff1a; https://www.itu.int/rec/T-REC-H.264/en JM源码&#xff1a; https://iphome.hhi.de/suehring/tml/download/ 博客参考学习&#xff1a;H.264官方软件JM源代码简单分析-解码器ld…

真免费!10 款必备的语言类 AI 大模型

好多小伙伴反映&#xff0c;买了好多AI工具&#xff0c;但并不好用&#xff0c;今天我给你推荐10个好用且免费的语言类AI大模型。 以后就别去花冤枉钱了。 排名不分先后。 各有所长&#xff0c;大家收藏自行去测试甄选适合自己的AI工具。 — 1 — 文心一言 文心一言是百度…

Android12 显示框架之getSurface

目录&#xff1a;Android显示终极宝典 在上篇文章中&#xff0c;我们讲到了应用通过createSurface()在surfaceflinger内生成了一个Layer&#xff0c;并且获取到了该Layer的Handle且将其和其他信息保存到了SurfaceControl。应用拿到了这个SurfaceControl&#xff0c;那么接下来…