最优控制-LQR轨迹追踪-Drcan-4 一、目标误差控制 1.建模
2.编程实现 LQR_Test_tracking_E_offset_MSD.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 clear all; close all; clc; m_sys = 1 ; b_sys = 0.5 ; k_sys = 1 ; A = [0 1 ;-k_sys/m_sys -b_sys/m_sys]; n = size (A,1 ); B = [0 ;1 /m_sys]; p = size (B,2 ); Ts = 0.1 ; C = zeros (1 ,size (A,2 )); D = 0 ; sys = ss(A,B,C,D); sys_d = c2d(sys,Ts); A = sys_d.a; B = sys_d.b; Q = [1 0 ;0 1 ]; S = [1 0 ;0 1 ]; R = 1 ; xd = [1 ;0 ]; AD = eye (n); x0 = [1 ;0 ]; x = x0; [xa] = [x;xd]; u = 0 ; k_steps = 100 ; x_history = zeros (n,k_steps); u_history = zeros (p,k_steps); Ca = [eye (n) -eye (n)]; Aa = [A zeros (n);zeros (n) AD]; Ba = [B;zeros (n,1 )]; Sa = transpose(Ca) * S * Ca; Qa = transpose(Ca) * Q * Ca; [F] = F1_LQR_Gain(Aa,Ba,Qa,R,Sa); for k = 1 : k_steps u = - F * xa; x = A * x + B * u; xa = [x;xd]; x_history(:,k+1 ) = x; u_history(:,k+1 ) = u; end subplot(2 ,1 ,1 ); hold ;plot (0 :length (x_history)-1 ,x_history(1 ,:));plot (0 :length (x_history)-1 ,x_history(2 ,:),'--' );grid on; legend ("x1" ,"x2" );subplot(2 ,1 ,2 ); for i = 1 :p stairs(u_history(i ,:)); hold ; end grid on; legend ("u" );
其中
F1_LQR_Gain.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 function [F] = F1_LQR_Gain (A,B,Q,R,S) ;n = size (A,1 ); p = size (B,2 ); P0 = S; max_iter= 200 ; P = zeros (n,n*max_iter); P(:,1 :n) = P0; P_k_min_1 = P0; tol = 1e-3 ; diff = Inf; F_N_min_k = Inf; k = 1 ; while diff > tol F_N_min_k_pre = F_N_min_k; F_N_min_k = inv(R+B'*P_k_min_1*B)*B'*P_k_min_1*A; P_k = (A-B*F_N_min_k)'*P_k_min_1*(A-B*F_N_min_k) + (F_N_min_k)'*R*(F_N_min_k) + Q; P(:,n*k-n+1 :n*k) = P_k; P_k_min_1 = P_k; diff = abs (max (F_N_min_k - F_N_min_k_pre)); k = k+1 ; if k > max_iter error("Maximum Number of Iterations Exceeded" ); end end fprintf('No. of Interation is %d \n' ,k); F = F_N_min_k; end
运行结果
系统在保证能耗小的情况下存在稳态误差,无法在满足性能指标足够好的情况下,同时保证目标的精确控制
二、稳态非零参考值控制 在(一)中,存在一个问题(Q1),性能指标函数中与权重矩阵R有关的是系统的直接输入 u[k],若权重矩阵R过大的时候,u[k]则会躺平,甚至趋于0,无法在保证性能指标足够好的情况下,同时又对目标进行精确的跟踪
为了解决这个问题,引出如下的控制方法:
1.建模
2.编程实现 LQR_Test_tracking_SS_U_MSD.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 clear all; close all; clc; m_sys = 1 ; b_sys = 0.5 ; k_sys = 1 ; A = [0 1 ;-k_sys/m_sys -b_sys/m_sys]; n = size (A,1 ); B = [0 ;1 /m_sys]; p = size (B,2 ); Ts = 0.1 ; C = zeros (1 ,size (A,2 )); D = 0 ; sys = ss(A,B,C,D); sys_d = c2d(sys,Ts); A = sys_d.a; B = sys_d.b; Q = [1 0 ;0 1 ]; S = [1 0 ;0 1 ]; R = 1 ; xd = [1 ;0 ]; AD = eye (n); x0 = [0 ;0 ]; x = x0; [xa] = [x;xd]; u0 = 1 ; u = u0; k_steps = 100 ; x_history = zeros (n,k_steps); x_history(:,1 ) = x; u_history = zeros (p,k_steps); u_history(:,1 ) = u; [Aa,Ba,Qa,Sa,R,ud] = F2_InputAugmentMatrix_SS_U(A,B,Q,R,S,xd); [F] = F1_LQR_Gain(Aa,Ba,Qa,R,Sa); for k = 1 : k_steps u = -F * xa + ud; x = A * x + B * u; xa = [x;xd]; x_history(:,k+1 ) = x; u_history(:,k+1 ) = u; end figure ('position' ,[150 150 1000 1000 ]);subplot(2 ,1 ,1 ); hold ;plot (0 :length (x_history)-1 ,x_history(1 ,:));plot (0 :length (x_history)-1 ,x_history(2 ,:),'--' );grid on; legend ("x1" ,"x2" );subplot(2 ,1 ,2 ); for i = 1 :p stairs(u_history(i ,:)); hold ; end grid on; legend ("u" );
其中
F2_InputAugmentMatrix_SS_U.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 function [Aa,Ba,Qa,Sa,R,ud] = F2_InputAugmentMatrix_SS_U (A,B,Q,R,S,xd) ; n = size (A,1 ); p = size (B,2 ); Ca = [eye (n) -eye (n)]; Aa = [A eye (n)-A;zeros (n) eye (n)]; Ba = [B;zeros (n,p)]; Sa = transpose(Ca) * S * Ca; Qa = transpose(Ca) * Q * Ca; R = R; ud = mldivide(B,(eye (n) - A)*xd); end
(1)运行结果 对于测试1 ,R=0.1,对于输入的功耗关注比重不大,因此系统超调较小
对于测试2 ,R=1,对于输入的功耗关注比重较大,因此系统超调较大,典型的欠阻尼系统
三、输入增量控制 在(二、稳态非零参考值控制)中,目标状态为一个常量定值Xd,但是若Xd非定值呢?如何解决
1.建模
2.编程实现 F3_InputAugmentMatrix_Delta_U.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function [Aa,Ba,Qa,Sa,R] = F3_InputAugmentMatrix_Delta_U (A,B,Q,R,S,AD) ; n = size (A,1 ); p = size (B,2 ); Ca = [eye (n) -eye (n) zeros (n,p)]; Aa = [A zeros (n) B;zeros (n) AD zeros (n,p); zeros (p,n) zeros (p,n) eye (p,p)]; Ba = [B;zeros (n,p);eye (p)]; Sa = transpose(Ca) * S * Ca; Qa = transpose(Ca) * Q * Ca; R = R; end
(1)目标状态xd仍为常量 LQR_Test_tracking_Delta_U_MSD_1.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 clear all; close all; clc; m_sys = 1 ; b_sys = 0.5 ; k_sys = 1 ; A = [0 1 ;-k_sys/m_sys -b_sys/m_sys]; n = size (A,1 ); B = [0 ;1 /m_sys]; p = size (B,2 ); Ts = 0.1 ; C = zeros (1 ,size (A,2 )); D = 0 ; sys = ss(A,B,C,D); sys_d = c2d(sys,Ts); A = sys_d.a; B = sys_d.b; Q = [1 0 ;0 1 ]; S = [1 0 ;0 1 ]; R = 2 ; xd = [1 ;0 ]; AD = eye (n); x0 = [0 ;0 ]; x = x0; u0 = 0 ; u = u0; [xa] = [x;xd;u]; k_steps = 100 ; x_history = zeros (n,k_steps); x_history(:,1 ) = x; u_history = zeros (p,k_steps); u_history(:,1 ) = u; [Aa,Ba,Qa,Sa,R] = F3_InputAugmentMatrix_Delta_U(A,B,Q,R,S,AD); [F] = F1_LQR_Gain(Aa,Ba,Qa,R,Sa); for k = 1 : k_steps Delta_u = -F * xa; u = Delta_u + u; x = A * x + B * u; xd = AD * xd; xa = [x;xd;u]; x_history(:,k+1 ) = x; u_history(:,k) = u; end figure ('position' ,[150 150 1000 1000 ]);subplot(2 ,1 ,1 ); hold ;plot (0 :length (x_history)-1 ,x_history(1 ,:));plot (0 :length (x_history)-1 ,x_history(2 ,:),'--' );grid on; legend ("x1" ,"x2" );subplot(2 ,1 ,2 ); for i = 1 :p stairs(u_history(i ,:)); hold ; end grid on; legend ("u" );
运行结果:
对于测试1 ,R = 0.1时,输入u[k]的变化幅度较大
对于测试2 ,R =1时,输入u[k]的变化幅度较小
(2)若目标状态非常数参考值,系统状态非匀速变化 LQR_Test_tracking_Delta_U_MSD_2.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 clear all; close all; clc; m_sys = 1 ; b_sys = 0.5 ; k_sys = 1 ; A = [0 1 ;-k_sys/m_sys -b_sys/m_sys]; n = size (A,1 ); B = [0 ;1 /m_sys]; p = size (B,2 ); Ts = 0.1 ; C = zeros (1 ,size (A,2 )); D = 0 ; sys = ss(A,B,C,D); sys_d = c2d(sys,Ts); A = sys_d.a; B = sys_d.b; Q = [1 0 ;0 1 ]; S = [1 0 ;0 1 ]; R = 1 ; xd = [0 ;0.2 ]; AD = c2d(ss([0 1 ;0 0 ],[0 ;0 ],[0 0 ],[0 ]),0.1 ).a; x0 = [0 ;0 ]; x = x0; u0 = 0 ; u = u0; [xa] = [x;xd;u]; k_steps = 200 ; x_history = zeros (n,k_steps); x_history(:,1 ) = x; u_history = zeros (p,k_steps); u_history(:,1 ) = u; [Aa,Ba,Qa,Sa,R] = F3_InputAugmentMatrix_Delta_U(A,B,Q,R,S,AD); [F] = F1_LQR_Gain(Aa,Ba,Qa,R,Sa); for k = 1 : k_steps if (k==50 ) xd = [xd(1 );-0.2 ]; elseif (k==100 ) xd = [xd(1 );0.2 ]; elseif (k==150 ) xd = [xd(1 );-0.2 ]; elseif (k==200 ) xd = [xd(1 );0.2 ]; end Delta_u = -F * xa; u = Delta_u + u; x = A * x + B * u; xd = AD * xd; xa = [x;xd;u]; x_history(:,k+1 ) = x; u_history(:,k) = u; end figure ('position' ,[150 150 1000 1000 ]);subplot(2 ,1 ,1 ); hold ;plot (0 :length (x_history)-1 ,x_history(1 ,:));plot (0 :length (x_history)-1 ,x_history(2 ,:),'--' );grid on; legend ("x1" ,"x2" );subplot(2 ,1 ,2 ); for i = 1 :p stairs(u_history(i ,:)); hold ; end grid on; legend ("u" );
运行结果
可以看到x2在0.2 -0.2 0.2 -0.2 之间变化 控制输入也在变化使得系统对状态轨迹进行跟踪