传送门
前言
在前面第三篇的博客中,叙述了关于 L Q R LQR LQR非零期望的轨迹跟踪推导和实现。在最后的仿真实践中发现一个现象,当代价函数中的输入权重矩阵 R R R非0时,会使得状态向量与期望状态向量之间存在静态误差。当把输入权重矩阵 R R R置零时,则可以将静态误差消除,但此时系统输入 U U U将会出现非常大的起伏变化。这篇博客将围绕这个现象来讨论,如何以合适的方式来解决非零期望点静态误差的问题。
盘根溯源
线性系统的平衡点
X
⃗
(
k
+
1
)
=
A
X
⃗
(
k
)
\vec{X}(k+1)=A \vec{X}(k)
X(k+1)=AX(k)
显然在无输入的情况下,线性系统的平衡点只有
X
⃗
=
0
\vec{X}=0
X=0。因此当我们希望系统状态向量稳定在其他位置时,则需要有外部输入来保持。即
X
⃗
(
k
+
1
)
=
A
X
⃗
(
k
)
+
B
U
⃗
(
k
)
\vec{X}(k+1)=A \vec{X}(k)+B\vec{U}(k)
X(k+1)=AX(k)+BU(k)
在外部输入使得系统保持在某个非零稳定点后,系统的输入也将稳定在某个位置,使系统处于平衡状态,即使得
X
⃗
(
k
+
1
)
=
X
⃗
(
k
)
\vec{X}(k+1)=\vec{X}(k)
X(k+1)=X(k)
且
U
⃗
(
k
+
1
)
=
U
⃗
(
k
)
=
U
⃗
c
o
n
s
t
\vec{U}(k+1)=\vec{U}(k)=\vec{U}_{const}
U(k+1)=U(k)=Uconst
代价函数的形式
J
=
1
2
e
⃗
(
N
)
T
P
(
0
)
e
⃗
(
N
)
+
1
2
∑
k
=
0
N
−
1
(
e
⃗
(
k
)
T
Q
e
⃗
(
k
)
+
U
⃗
(
k
)
T
R
U
⃗
(
k
)
)
J = \frac{1}{2} \vec{e}(N)^{T}P(0)\vec{e}(N)+\frac{1}{2}\sum_{k=0}^{N-1}{ (\vec{e}(k)^{T}Q\vec{e}(k) + \vec{U}(k)^{T}R\vec{U}(k)) }
J=21e(N)TP(0)e(N)+21k=0∑N−1(e(k)TQe(k)+U(k)TRU(k))
从代价函数的形式以及上面关于线性系统平衡点的描述看,会出现一种情况:为了追求零误差所需要做出的系统输入
U
⃗
e
=
0
\vec{U}_{e=0}
Ue=0所对应的代价
J
e
=
0
J_{e=0}
Je=0并不是最优的(即不是最小的代价)。
因此,经过
L
Q
R
LQR
LQR计算的控制律
U
⃗
\vec{U}
U产生的控制结果就会出现静态误差(因为它认为这就是最优的)。
消除静态误差的思想
系统输入增量控制
既然系统输入会影响代价函数,进而使误差向量无法收敛为0,那么就不对它计算代价值,取代它的是系统输入的增量(即变化量)。
即增量输入满足以下定义:
U
⃗
(
k
)
=
U
⃗
(
k
−
1
)
+
Δ
U
⃗
(
k
)
\vec{U}(k) =\vec{U}(k-1) + \Delta \vec{U}(k)
U(k)=U(k−1)+ΔU(k)
其中,
Δ
U
⃗
(
k
)
\Delta \vec{U}(k)
ΔU(k)是系统在
k
k
k时刻的输入增量。
而我们希望的是在代价函数中由
k
k
k时刻的输入增量
Δ
U
⃗
(
k
)
\Delta \vec{U}(k)
ΔU(k)取代
k
k
k时刻的系统输入
U
⃗
(
k
)
\vec{U}(k)
U(k)。即新的代价函数形式为
J
=
1
2
e
⃗
(
N
)
T
P
(
0
)
e
⃗
(
N
)
+
1
2
∑
k
=
0
N
−
1
(
e
⃗
(
k
)
T
Q
e
⃗
(
k
)
+
Δ
U
⃗
(
k
)
T
R
Δ
U
⃗
(
k
)
)
J = \frac{1}{2} \vec{e}(N)^{T}P(0)\vec{e}(N)+\frac{1}{2}\sum_{k=0}^{N-1}{ (\vec{e}(k)^{T}Q\vec{e}(k) + \Delta \vec{U}(k)^{T}R\Delta \vec{U}(k)) }
J=21e(N)TP(0)e(N)+21k=0∑N−1(e(k)TQe(k)+ΔU(k)TRΔU(k))
与上一章中的推导思路相同,我们还需要找到
Δ
U
⃗
(
k
)
\Delta \vec{U}(k)
ΔU(k)如何影响误差向量
e
⃗
\vec{e}
e,即用状态空间方程的形式来描述他们之间的数学关系,才能使得代价函数的最优化计算成立。
方法也与上一章的方法相似,也是通过状态向量增广变化的方式来实现。
- 状态空间方程
X ⃗ ( k + 1 ) = A X ⃗ ( k ) + B U ⃗ ( k ) = A X ⃗ ( k ) + B U ⃗ ( k − 1 ) + B Δ U ⃗ ( k ) \vec{X}(k+1)=A \vec{X}(k)+B\vec{U}(k)=A \vec{X}(k)+B\vec{U}(k-1)+B\Delta\vec{U}(k) X(k+1)=AX(k)+BU(k)=AX(k)+BU(k−1)+BΔU(k)
很显然,状态空间方程中多出了一项 B U ⃗ ( k − 1 ) B\vec{U}(k-1) BU(k−1),需要将这一项进行增广变换来重新构造状态空间方程。 - 对向量进行增广变换
保留上一章轨迹跟踪的增广变换部分,新加入多出来的 B U ⃗ ( k − 1 ) B\vec{U}(k-1) BU(k−1),则有
X ⃗ b ( k ) = [ X ⃗ ( k ) X d ⃗ ( k ) U ⃗ ( k − 1 ) ] \vec{X}_{b}(k)=\begin{bmatrix}\vec{X}(k)\\\vec{X_{d}}(k)\\ \vec{U}(k-1)\end{bmatrix} Xb(k)= X(k)Xd(k)U(k−1) - 增广变换后的状态空间方程
X b ⃗ ( k + 1 ) = [ A 0 B 0 A D 0 0 0 I ] [ X ⃗ ( k ) X d ⃗ ( k ) U ⃗ ( k − 1 ) ] + [ B 0 I ] Δ U ⃗ ( k ) ⇒ X b ⃗ ( k + 1 ) = A b X b ⃗ ( k ) + B b Δ U ⃗ ( k ) \vec{X_{b}}(k+1) = \begin{bmatrix}A&0&B\\0&A_{D}&0\\0&0&I\end{bmatrix}\begin{bmatrix}\vec{X}(k)\\\vec{X_{d}}(k)\\ \vec{U}(k-1)\end{bmatrix}+\begin{bmatrix}B\\0\\I\end{bmatrix}\Delta\vec{U}(k)\\ \Rightarrow \vec{X_{b}}(k+1)=A_{b}\vec{X_{b}}(k)+B_{b}\Delta\vec{U}(k) Xb(k+1)= A000AD0B0I X(k)Xd(k)U(k−1) + B0I ΔU(k)⇒Xb(k+1)=AbXb(k)+BbΔU(k) - 误差向量与增广状态向量之间的转换
e ⃗ ( k ) = X ⃗ ( k ) − X d ⃗ ( k ) + 0 × U ⃗ ( k − 1 ) = [ I − I 0 ] [ X ⃗ ( k ) X d ⃗ ( k ) U ⃗ ( k − 1 ) ] = C b X ⃗ b ( k ) \vec{e}(k)=\vec{X}(k)-\vec{X_{d}}(k)+0\times \vec{U}(k-1)=\begin{bmatrix}I&-I&0\end{bmatrix}\begin{bmatrix}\vec{X}(k)\\\vec{X_{d}}(k)\\ \vec{U}(k-1)\end{bmatrix}=C_{b}\vec{X}_{b}(k) e(k)=X(k)−Xd(k)+0×U(k−1)=[I−I0] X(k)Xd(k)U(k−1) =CbXb(k) - 整理后得到新的代价函数形式
J = 1 2 X ⃗ b ( N ) T [ C b T P ( 0 ) C b ] X ⃗ b ( N ) + 1 2 ∑ k = 0 N − 1 ( X ⃗ b ( k ) T [ C b T Q C b ] X ⃗ b ( k ) + Δ U ⃗ ( k ) T R Δ U ⃗ ( k ) ) ⇒ J = 1 2 X ⃗ b ( N ) T P b ( 0 ) X ⃗ b ( N ) + 1 2 ∑ k = 0 N − 1 ( X ⃗ b ( k ) T Q b X ⃗ b ( k ) + Δ U ⃗ ( k ) T R Δ U ⃗ ( k ) ) J = \frac{1}{2} \vec{X}_{b}(N)^{T}[C_{b}^{T}P(0)C_{b}]\vec{X}_{b}(N)+\frac{1}{2}\sum_{k=0}^{N-1}{ ( \vec{X}_{b}(k)^{T}[C_{b}^{T}Q C_{b}]\vec{X}_{b}(k) + \Delta \vec{U}(k)^{T}R\Delta \vec{U}(k)) }\\ \Rightarrow J = \frac{1}{2} \vec{X}_{b}(N)^{T}P_{b}(0)\vec{X}_{b}(N)+\frac{1}{2}\sum_{k=0}^{N-1}{ ( \vec{X}_{b}(k)^{T}Q_{b}\vec{X}_{b}(k) + \Delta \vec{U}(k)^{T}R\Delta \vec{U}(k)) } J=21Xb(N)T[CbTP(0)Cb]Xb(N)+21k=0∑N−1(Xb(k)T[CbTQCb]Xb(k)+ΔU(k)TRΔU(k))⇒J=21Xb(N)TPb(0)Xb(N)+21k=0∑N−1(Xb(k)TQbXb(k)+ΔU(k)TRΔU(k)) - 根据
L
Q
R
LQR
LQR计算公式
K b ( N − k ) = ( B b T P b ( k − 1 ) B b + R ) − 1 B b T P b ( k − 1 ) A b P b ( k ) = ( [ A b − B b K b ( N − k ) ] T ⋅ P b ( k − 1 ) ⋅ [ A b − B b K b ( N − k ) ] + K b ( N − k ) T R K b ( N − k ) + Q b ) J b ∗ ( N − k ) = X ⃗ b T ( N − k ) P b ( k ) X ⃗ b ( N − k ) K_{b}(N-k) = (B_{b}^{T}P_{b}(k-1)B_{b}+R) ^{-1} B_{b}^{T}P_{b}(k-1)A_{b}\\ P_{b}(k) = ( [A_{b}-B_{b}K_{b}(N-k)]^{T} \cdot P_{b}(k-1) \cdot [A_{b}-B_{b}K_{b}(N-k)] + K_{b}(N-k)^{T} RK_{b}(N-k) + Q_{b}) \\ J_{b}^{*}(N-k) = \vec{X}_{b}^{T}(N-k) P_{b}(k) \vec{X}_{b}(N-k) Kb(N−k)=(BbTPb(k−1)Bb+R)−1BbTPb(k−1)AbPb(k)=([Ab−BbKb(N−k)]T⋅Pb(k−1)⋅[Ab−BbKb(N−k)]+Kb(N−k)TRKb(N−k)+Qb)Jb∗(N−k)=XbT(N−k)Pb(k)Xb(N−k) - 计算控制律
U ⃗ ( k ) = U ⃗ ( k − 1 ) − K b ( k ) X b ( k ) \vec{U}(k)=\vec{U}(k-1)-K_{b}(k)X_{b}(k) U(k)=U(k−1)−Kb(k)Xb(k)
稳态输入参考控制
在前面也提到过,假设在系统输入的作用下,系统状态向量保持在一个非零点
X
d
⃗
\vec{X_{d}}
Xd,将这种稳态输入称之为稳态输入向量
U
d
⃗
\vec{U_{d}}
Ud,且满足以下关系
X
⃗
(
k
+
1
)
=
X
d
⃗
=
A
X
⃗
(
k
)
+
B
U
⃗
(
k
)
=
A
X
d
⃗
+
B
U
d
⃗
①
⇒
(
I
−
A
)
X
⃗
d
=
B
U
⃗
d
\vec{X}(k+1)=\vec{X_{d}}=A\vec{X}(k)+B\vec{U}(k)=A\vec{X_{d}}+B\vec{U_{d}}\\ ①\Rightarrow (I-A)\vec{X}_{d}=B\vec{U}_{d}
X(k+1)=Xd=AX(k)+BU(k)=AXd+BUd①⇒(I−A)Xd=BUd
定义稳态输入误差
δ
U
⃗
(
k
)
\delta\vec{U}(k)
δU(k),其满足以下关系
②
U
⃗
(
k
)
=
δ
U
⃗
(
k
)
+
U
d
⃗
②\vec{U}(k) = \delta\vec{U}(k) + \vec{U_{d}}
②U(k)=δU(k)+Ud
代入系统状态空间方程
③
X
⃗
(
k
+
1
)
=
A
X
⃗
(
k
)
+
B
U
d
⃗
+
B
δ
U
⃗
(
k
)
③\vec{X}(k+1)=A \vec{X}(k)+B\vec{U_{d}}+B\delta\vec{U}(k)
③X(k+1)=AX(k)+BUd+BδU(k)
将①代入③中,得到
④
X
⃗
(
k
+
1
)
=
A
X
⃗
(
k
)
+
(
I
−
A
)
X
⃗
d
+
B
δ
U
⃗
(
k
)
④\vec{X}(k+1)=A \vec{X}(k)+ (I-A)\vec{X}_{d}+B\delta\vec{U}(k)
④X(k+1)=AX(k)+(I−A)Xd+BδU(k)
又根据轨迹跟踪推导的增广状态向量
X
c
⃗
(
k
)
=
[
X
⃗
(
k
)
X
d
⃗
(
k
)
]
\vec{X_{c}}(k)=\begin{bmatrix}\vec{X}(k)\\\vec{X_d}(k)\end{bmatrix}
Xc(k)=[X(k)Xd(k)],因此④可以增广变换为
X
⃗
c
(
k
+
1
)
=
[
A
I
−
A
0
A
D
]
[
X
⃗
(
k
)
X
d
⃗
(
k
)
]
+
[
B
0
]
δ
U
⃗
(
k
)
⑤
⇒
X
⃗
c
(
k
+
1
)
=
A
c
X
⃗
c
(
k
)
+
B
c
δ
U
⃗
(
k
)
\vec{X}_{c}(k+1)=\begin{bmatrix}A&I-A\\0&A_D\end{bmatrix}\begin{bmatrix}\vec{X}(k)\\\vec{X_d}(k)\end{bmatrix}+\begin{bmatrix}B\\0\end{bmatrix}\delta\vec{U}(k)\\ ⑤\Rightarrow \vec{X}_{c}(k+1)=A_{c}\vec{X}_{c}(k)+B_{c}\delta\vec{U}(k)
Xc(k+1)=[A0I−AAD][X(k)Xd(k)]+[B0]δU(k)⑤⇒Xc(k+1)=AcXc(k)+BcδU(k)
并且误差向量满足以下关系:
e
⃗
(
k
)
=
X
⃗
(
k
)
−
X
d
⃗
(
k
)
=
[
I
−
I
]
[
X
⃗
(
k
)
X
d
⃗
(
k
)
]
=
C
c
X
⃗
c
(
k
)
\vec{e}(k)=\vec{X}(k)-\vec{X_{d}}(k)=\begin{bmatrix}I&-I\end{bmatrix}\begin{bmatrix}\vec{X}(k)\\\vec{X_{d}}(k)\end{bmatrix}=C_{c}\vec{X}_{c}(k)
e(k)=X(k)−Xd(k)=[I−I][X(k)Xd(k)]=CcXc(k)
推导出这个新的增广状态空间方程,则可以将代价函数中的系统输入向量替换为稳态输入误差向量,以此达到消除静态误差的目的:
J
=
1
2
X
⃗
c
(
N
)
T
[
C
c
T
P
(
0
)
C
c
]
X
⃗
c
(
N
)
+
1
2
∑
k
=
0
N
−
1
(
X
⃗
c
(
k
)
T
[
C
c
T
Q
C
c
]
X
⃗
c
(
k
)
+
δ
U
⃗
(
k
)
T
R
δ
U
⃗
(
k
)
)
⇒
J
=
1
2
X
⃗
c
(
N
)
T
P
c
(
0
)
X
⃗
c
(
N
)
+
1
2
∑
k
=
0
N
−
1
(
X
⃗
c
(
k
)
T
Q
c
X
⃗
c
(
k
)
+
δ
U
⃗
(
k
)
T
R
δ
U
⃗
(
k
)
)
J = \frac{1}{2} \vec{X}_{c}(N)^{T}[C_{c}^{T}P(0)C_{c}]\vec{X}_{c}(N)+\frac{1}{2}\sum_{k=0}^{N-1}{ ( \vec{X}_{c}(k)^{T}[C_{c}^{T}Q C_{c}]\vec{X}_{c}(k) + \delta \vec{U}(k)^{T}R\delta \vec{U}(k)) }\\ \Rightarrow J = \frac{1}{2} \vec{X}_{c}(N)^{T}P_{c}(0)\vec{X}_{c}(N)+\frac{1}{2}\sum_{k=0}^{N-1}{ ( \vec{X}_{c}(k)^{T}Q_{c}\vec{X}_{c}(k) + \delta \vec{U}(k)^{T}R\delta \vec{U}(k)) }
J=21Xc(N)T[CcTP(0)Cc]Xc(N)+21k=0∑N−1(Xc(k)T[CcTQCc]Xc(k)+δU(k)TRδU(k))⇒J=21Xc(N)TPc(0)Xc(N)+21k=0∑N−1(Xc(k)TQcXc(k)+δU(k)TRδU(k))
$$
- 根据
L
Q
R
LQR
LQR计算公式
K c ( N − k ) = ( B c T P c ( k − 1 ) B c + R ) − 1 B c T P c ( k − 1 ) A c P c ( k ) = ( [ A c − B c K c ( N − k ) ] T ⋅ P c ( k − 1 ) ⋅ [ A c − B c K c ( N − k ) ] + K c ( N − k ) T R K c ( N − k ) + Q c ) J c ∗ ( N − k ) = X ⃗ c T ( N − k ) P c ( k ) X ⃗ c ( N − k ) K_{c}(N-k) = (B_{c}^{T}P_{c}(k-1)B_{c}+R) ^{-1} B_{c}^{T}P_{c}(k-1)A_{c}\\ P_{c}(k) = ( [A_{c}-B_{c}K_{c}(N-k)]^{T} \cdot P_{c}(k-1) \cdot [A_{c}-B_{c}K_{c}(N-k)] + K_{c}(N-k)^{T} RK_{c}(N-k) + Q_{c}) \\ J_{c}^{*}(N-k) = \vec{X}_{c}^{T}(N-k) P_{c}(k) \vec{X}_{c}(N-k) Kc(N−k)=(BcTPc(k−1)Bc+R)−1BcTPc(k−1)AcPc(k)=([Ac−BcKc(N−k)]T⋅Pc(k−1)⋅[Ac−BcKc(N−k)]+Kc(N−k)TRKc(N−k)+Qc)Jc∗(N−k)=XcT(N−k)Pc(k)Xc(N−k) - 计算控制律
U ⃗ ( k ) = U ⃗ d − K c ( k ) X c ( k ) \vec{U}(k)=\vec{U}_{d}-K_{c}(k)X_{c}(k) U(k)=Ud−Kc(k)Xc(k)
实践仿真
仿真代码 —— 系统输入增量控制
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_b = [A,zeros(2,2),B;zeros(2,2),eye(2),zeros(2,1);zeros(1,2),zeros(1,2),1];
B_b = [B;zeros(2,1);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];
u0 = 0;
Xb0 = [X0;Xd0;u0];
%系统初始状态向量
Xk = X0;
Xbk = Xb0;
uk = 0;
duk = 0;
%状态向量Xk和增广状态向量
P=zeros(n,25);
%P 5x5
Cb = [eye(2),-eye(2),zeros(2,1)];
% Cb 2x5
P0 = Cb' * [1 0;0 1] * Cb;
%末端状态代价矩阵2x2
Q = Cb' * [1 0;0 1] * Cb;
%过程状态代价矩阵2x2
R = 1;
%过程输入代价矩阵1x1
K = zeros(n,5);
%全状态反馈矩阵 1x5
P(1,:) = P0(:)';
%初始化
for i = 2:n
tmpP = reshape(P(i-1,:),5,5);
K(n-i+1,:) = reshape( (B_b'*tmpP*B_b+R)\B_b'*tmpP*A_b,1,5);
tmpK = reshape(K(n-i+1,:),1,5);
P(i,:)= reshape( (A_b-B_b * tmpK)'* tmpP *(A_b-B_b * tmpK) + tmpK'*R*tmpK+Q ,1,25);
end
%从最后一个往前算P(k)
for i = 1:n
Kmatrix = reshape(K(i,:),1,5);
duk = - Kmatrix*Xbk;
uk = uk+duk;
Xk = A*Xk + B*uk;
x(i) = Xk(1);
v(i) = Xk(2);
time(i) = i*T;
u(i) = uk;
Xbk = A_b*Xbk + B_b*duk;
end
figure(2);
plot_row = 3;
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 % 添加网格线
运行结果 —— 系统输入增量控制
- 对比实验,图左为输入增量式,图右为常规式。
在所有权重矩阵,系统参数都一样的情况下,输入增量方式的 L Q R LQR LQR能够消除静态误差,并且以几乎不变的系统输入完成这个目标。
仿真代码 —— 稳态输入参考控制
根据系统模型为
[
x
1
(
k
+
1
)
x
2
(
k
+
1
)
]
=
[
1
T
−
k
T
m
1
−
c
T
m
]
[
x
1
(
k
)
x
2
(
k
)
]
+
[
0
T
m
]
u
\begin{bmatrix} x_{1}(k+1)\\x_{2}(k+1)\end{bmatrix}=\begin{bmatrix} 1&T\\-\frac{kT}{m}&1-\frac{cT}{m}\end{bmatrix}\begin{bmatrix} x_{1}(k)\\x_{2}(k)\end{bmatrix}+\begin{bmatrix} 0\\\frac{T}{m}\end{bmatrix}u
[x1(k+1)x2(k+1)]=[1−mkTT1−mcT][x1(k)x2(k)]+[0mT]u
其中,
m
=
1
m=1
m=1,
c
=
0.2
c=0.2
c=0.2,
k
=
0.5
k=0.5
k=0.5,
T
=
0.1
T=0.1
T=0.1。
另
X
d
⃗
=
[
1
0
]
\vec{X_d}=\begin{bmatrix}1\\0\end{bmatrix}
Xd=[10],代入后可以得到
1
=
1
0
=
−
0.5
∗
0.1
1
×
1
+
0
+
0.1
×
U
d
⃗
1=1\\ 0=-\frac{0.5*0.1}{1}\times1+0+0.1\times\vec{U_{d}}
1=10=−10.5∗0.1×1+0+0.1×Ud
得到
U
d
⃗
=
0.5
\vec{U_d}=0.5
Ud=0.5。
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_c = [A,eye(2)-A;zeros(2,2),eye(2)];
B_c = [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];
u0 = 0;
Xc0 = [X0;Xd0];
%系统初始状态向量
Xk = X0;
Xck = Xc0;
ud = 0.5;
uk = 0;
duk = 0;
%状态向量Xk和增广状态向量
P=zeros(n,16);
%P 5x5
Cb = [eye(2),-eye(2)];
% Cb 2x5
P0 = Cb' * [1 0;0 1] * Cb;
%末端状态代价矩阵2x2
Q = Cb' * [1 0;0 1] * Cb;
%过程状态代价矩阵2x2
R = 1;
%过程输入代价矩阵1x1
K = zeros(n,4);
%全状态反馈矩阵 1x5
P(1,:) = P0(:)';
%初始化
for i = 2:n
tmpP = reshape(P(i-1,:),4,4);
K(n-i+1,:) = reshape( (B_c'*tmpP*B_c+R)\B_c'*tmpP*A_c,1,4);
tmpK = reshape(K(n-i+1,:),1,4);
P(i,:)= reshape( (A_c-B_c * tmpK)'* tmpP *(A_c-B_c * tmpK) + tmpK'*R*tmpK+Q ,1,16);
end
%从最后一个往前算P(k)
for i = 1:n
Kmatrix = reshape(K(i,:),1,4);
duk = - Kmatrix*Xck;
uk = ud+duk;
Xk = A*Xk + B*uk;
x(i) = Xk(1);
v(i) = Xk(2);
time(i) = i*T;
u(i) = uk;
Xck = A_c*Xck + B_c*duk;
end
figure(3);
plot_row = 3;
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 % 添加网格线
运行结果 —— 稳态输入参考控制
- 右边是稳态输入参考控制,左边是无特殊操作
结论
- 提出了关于消除 L Q R LQR LQR静态误差的设计思想,并且通过仿真验证这一结论。
- 无论哪种思路,要记住是如何推导的,也要理解他的思想。
- 两种思路都是替换掉代价函数系统输入项来消除静态误差,
告诉我们一个道理,如果她真的不适合你,趁早换了。(毒鸡汤)
- 输入增量控制的思路适用于期望可能频繁变换的场景,
告诉我们一个道理,如果有时候不能一步到位,慢慢积累也不失为一种办法。(毒鸡汤)
- 稳态输入参考的思路适用于期望点恒定的场景,
告诉我们一个道理,尽管一眼望到终点,但也难免路途坎坷。(毒鸡汤)
后续
- 好像关于 L Q R LQR LQR的内容已经没有太多能继续讨论的了,后续大大大大概率会往其他控制器拓展了。
- 后续想做一个系列——以平衡车为案例的控制实践,涉及内容包括机械设计、运动建模、控制仿真、程序编写、调试等,有兴趣的同学关注一波,也可以评论或者私信我交流。
敬请期待!