赞
踩
上一篇博客简单推导了离散系统下的
L
Q
R
LQR
LQR计算公式,并且留下了一个伏笔——如何使系统状态收敛到非0状态。这篇博客将围绕这个问题来展开,并秉持着想到什么写什么的原则来进行一系列freestyle。
skr~
经过了上篇博客的推导,可以理解我们得到的控制律,是根据代价函数的最优问题求解的。假设代价函数如下:
J
=
1
2
X
⃗
(
N
)
T
F
X
⃗
(
N
)
+
1
2
∑
k
=
0
N
−
1
(
X
⃗
(
k
)
T
Q
X
⃗
(
k
)
+
U
⃗
(
k
)
T
R
U
⃗
(
k
)
)
J = \frac{1}{2} \vec{X}(N)^{T}F\vec{X}(N)+\frac{1}{2}\sum_{k=0}^{N-1}{ (\vec{X}(k)^{T}Q\vec{X}(k) + \vec{U}(k)^{T}R\vec{U}(k)) }
J=21X
(N)TFX
(N)+21k=0∑N−1(X
(k)TQX
(k)+U
(k)TRU
(k))
其中是代价
J
J
J用于衡量控制律性能的指标,由于函数中每一项都是半正定的,因此可以得到
J
≥
0
J \ge0
J≥0
另外,代价函数中包括了末端向量
X
⃗
(
N
)
\vec{X}(N)
X
(N),过程向量
X
⃗
(
k
)
\vec{X}(k)
X
(k),系统输入
U
⃗
(
k
)
\vec{U}(k)
U
(k)。很明显,这其中唯一能由我们决定的是系统输入
U
⃗
(
k
)
\vec{U}(k)
U
(k)。因此我们对于代价函数进行最优计算的时候,实际上是设计一组系统输入序列
U
⃗
\vec{U}
U
,使得代价
J
J
J尽可能的小(因为J存在下限0,无上限
)。
上述的描述说明了,这在数学上是一条可以实现的最优路径。
那么应该如何计算最优的系统输入,使系统快速收敛于期望的系统状态向量。
这里其实就是系统能控性的判定。
下标写的好乱,大家伙儿看到有下标的就是增广后的就行,大家将就看,我也写的头昏脑涨,在这给大家拜个早年。
以同样以弹簧阻尼系统来搞,增广后的系统状态转移方程如下:
X
A
⃗
(
k
+
1
)
=
A
D
X
A
⃗
(
k
)
+
B
D
U
⃗
\vec{X_{A}}(k+1)=A_{D}\vec{X_{A}}(k)+B_{D}\vec{U}
XA
(k+1)=ADXA
(k)+BDU
其中,
A
D
=
[
1
T
0
0
−
k
T
m
1
−
c
T
m
0
0
0
0
1
0
0
0
0
1
]
A_{D}=
clear all;
T = 0.1;
%离散周期位1ms
m = 1;
%重量块质量为1kg
c = 0.2;
k = 0.5;
%阻尼系数和弹簧系数
A = [1 T;-k*T/m 1-c*T/m];
B = [0;T/m];
A_D = [A,zeros(2,2);zeros(2,2),eye(2)];
B_D = [B;zeros(2,1)];
%系统状态空间方程
n = 1000;
x = zeros(n,1);%位置
v = zeros(n,1);%速度
time = zeros(n,1); %时间
u = zeros(n,1); %系统输入
J = zeros(n,1); %代价
JT = zeros(n,1);%代价的导数
%记录状态数据,用来绘图的
X0 = [3;0];
Xd0 = [1;0];
Xa0 = [X0;Xd0];
%系统初始状态向量
Xk = X0;
XAk = Xa0;
%状态向量Xk和增广状态向量
P=zeros(n,16);
%P迭代矩阵,用于计算K
Ca = [eye(2),-eye(2)];
% erro = D A_D
P0 = Ca' * [1 0;0 1] * Ca;
%末端状态代价矩阵2x2
Q = Ca' * [1 0;0 1] * Ca;
%过程状态代价矩阵2x2
R = 1;
%过程输入代价矩阵1x1
K = zeros(n,4);
%全状态反馈矩阵 1x4
P(1,:) = P0(:)';
%初始化
for i = 2:n
tmpP = reshape(P(i-1,:),4,4);
K(n-i+1,:) = reshape( (B_D'*tmpP*B_D+R)\B_D'*tmpP*A_D,1,4);
tmpK = reshape(K(n-i+1,:),1,4);
P(i,:)= reshape( (A_D-B_D * tmpK)'* tmpP *(A_D-B_D * tmpK) + tmpK'*R*tmpK+Q ,1,16);
end
%从最后一个往前算P(k)
for i = 1:n
Kmatrix = reshape(K(i,:),1,4);
uk = - Kmatrix*XAk;
Xk = A*Xk + B*uk;
x(i) = Xk(1);
v(i) = Xk(2);
time(i) = i*T;
u(i) = uk;
XAk = A_D*XAk + B_D*uk;
end
%k->N时刻的最优代价
Xn = [x(n);v(n);Xd0];
Jn = 0.5 * Xn' * P0 * Xn;
J(n-1) = Jn;
for i = 2:n
tmpP = reshape(P(i-1,:),4,4);
tmpX = [x(n-i+1);v(n-i+1);Xd0];
J(n-i+1) = J(n-i+2) + 0.5 * tmpX' * Q * tmpX + u(n-i+1)' * R * u(n-i+1);
JT(n-i+1) = B_D'* tmpP * (A_D * tmpX + B_D * u(n-i+1)) + R * u(n-i+1);
end
plot_row = 5;
plot_column = 1;
subplot(plot_row,plot_column,1);
plot(time, x) % 绘制曲线
xlabel('t') % 添加x轴标签
ylabel('x') % 添加y轴标签
title('x-t') % 添加标题
grid on % 添加网格线
subplot(plot_row,plot_column,2);
plot(time,v) % 绘制曲线
xlabel('t') % 添加x轴标签
ylabel('v') % 添加y轴标签
title('v-t') % 添加标题
grid on % 添加网格线
subplot(plot_row,plot_column,3);
plot(time,u) % 绘制曲线
xlabel('t') % 添加x轴标签
ylabel('u') % 添加y轴标签
title('u-t') % 添加标题
grid on % 添加网格线
subplot(plot_row,plot_column,4);
plot(time,J) % 绘制曲线
xlabel('t') % 添加x轴标签
ylabel('J') % 添加y轴标签
title('J-t') % 添加标题
grid on % 添加网格线
subplot(plot_row,plot_column,5);
plot(time,JT) % 绘制曲线
xlabel('t') % 添加x轴标签
ylabel('JT ') % 添加y轴标签
title('JT-t') % 添加标题
grid on % 添加网格线
可以清楚的看到,位置并没有按照期望的停在1处,一开始我也以为是因为代码或者公式推导出现错误导致的。后来我才反应过来,这是因为
L
Q
R
LQR
LQR计算的最优,并不一定是期望点为最优。
系统也觉得这样就够了也开始摆了
。后续的话可能会继续围绕今天提到的 L Q R LQR LQR的几个问题继续去讨论,也可能写一些其他控制算法的博客,可能是 M P C MPC MPC,也可能是 S M C SMC SMC,或者出一些实战的控制系列博客。感谢阅读,敬请期待!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。