How to add intgeral action to Full state feedback control with two inputs two ouputs system

15 views (last 30 days)
How to add integral action to Full state feedback control with two inputs and two outputs system. The system is fourth-order.

Answers (1)

Pavl M.
Pavl M. on 4 Dec 2024 at 10:24
Edited: Pavl M. on 5 Dec 2024 at 8:41
Good and valued: Solution ver. 1,
clc
clear all
close all
%% consider a 2 input, 2 output system,
nstates = 4;
ninputs = 2;
noutputs = 2;
A1=[0 0 -178 178;0 0 590 -500;-256 256 0 0; 0 -1 0 0.0000666];
B1=[8 -5;48 -63;-0.01 2.5; 0 0];
C1=[1 0 0 0;0 0 0 1];
D1=[0 0; 0 0];
Ts = 10e-3; % Sampling time in s
% Aa=[0 0 -178 178;0 0 590 -500;-256 256 0 0; 0 -1 0 0.0000666];
% Ba=[8 -5;48 -63;-0.01 2.5; 0 0];
% Ca=[1 0 0 0;0 0 0 1];
% Da = [0 0; 0 0];
% % you can use 'rss' and 'ssdata' to get random A, B, C, D matrices
% sys = rss(2,2,2) % to generate a random 2x2 system
% [A,B,C,D] = ssdata(sys); % to provide A, B, C, D matrices for this system
[num1 den1] = ss2tf(A1,B1,C1,D1,1) % iu = 1
num1 = 2×5
1.0e+06 * 0 0.0000 0.0000 -3.4081 0.0004 0 0 -0.0000 0.0000 3.3956
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
den1 = 1×5
1.0e+06 * 0.0000 -0.0000 -0.1971 0.0000 -4.1011
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
[num2 den2] = ss2tf(A1,B1,C1,D1,2); % iu = 2
%First input to first output only:
sys1 = tf(num1(1,:),den1) %contin
sys1 = 8 s^3 + 1.779 s^2 - 3.408e06 s + 386.3 ------------------------------------------------------ s^4 - 6.66e-05 s^3 - 1.971e05 s^2 + 13.09 s - 4.101e06 Continuous-time transfer function.
%Second input to second output only:
sys2 = tf(num2(2,:),den2); %contin
%First input to second output only:
sys3 = tf(num1(2,:),den1); %continuous
%Second input to first output only:
sys4 = tf(num2(1,:),den2); %continuous
[A, B, C, D] = tf2ss(num1(1,:),den1)
A = 4×4
1.0e+06 * 0.0000 0.1971 -0.0000 4.1011 0.0000 0 0 0 0 0.0000 0 0 0 0 0.0000 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
B = 4×1
1 0 0 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
C = 1×4
1.0e+06 * 0.0000 0.0000 -3.4081 0.0004
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
D = 0
asys = ss(A,B,C,D)
asys = A = x1 x2 x3 x4 x1 6.66e-05 1.971e+05 -13.09 4.101e+06 x2 1 0 0 0 x3 0 1 0 0 x4 0 0 1 0 B = u1 x1 1 x2 0 x3 0 x4 0 C = x1 x2 x3 x4 y1 8 1.779 -3.408e+06 386.3 D = u1 y1 0 Continuous-time state-space model.
opt2 = c2dOptions('Method','tustin','ThiranOrder',4,'DelayModeling','state');
%dsys=c2d(asys,Ts,opt2)
% observer model
%poles_obsv = exp(Ts*[-700 -310 -100 -90]);
poles_obsv = [-700 -310 -100 -90];
L=place(asys.a',asys.c',poles_obsv);
L=L';
Ah = asys.A;
bh = [asys.B L];
%cTh = eye(nstates);
%dh = [0 0;0 0;0 0;0 0];
%asysh=ss(Ah,bh,cTh,dh);
%figure
%step(asysh)
%add a state variable for the integral of the output error. This has the effect of adding an integral term to our controller which is known to reduce steady-state error.
%model for integral action
Ai = [[asys.A zeros(nstates,1)];-asys.C 0];
bi = [asys.B;0];
br = [zeros(nstates,1);1];
ci = [asys.C 0];
di = [0];
asysi=ss(Ai,bi,ci,di);
%Other augmentation scheme:
% Plant augmentation
Aaug=[asys.A zeros(nstates,1); zeros(1,nstates+1)];
Aaug(nstates+1,nstates)=1;
Baug=[asys.B;0];
Caug=eye(nstates+1);
Daug=zeros(nstates+1,1);
Plantcs=ss(Aaug,Baug,Caug,Daug);
% feedback controller
p1 = -800 + 800i;
p2 = -800 - 800i;
p3 = -400 - 400i;
%p1 = -110;
%p2 = -310;
%p3 = -500;
p4 = -400 + 400i;
p5 = -90;
%poles_k = exp(Ts*[p1 p2 p3 p4 p5]);
poles_k = [p1 p2 p3 p4 p5];
K = place(asysi.a,asysi.b,poles_k)
K = 1×5
1.0e+17 * 0.0000 -0.0000 -0.0000 2.9661 -0.0000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Ko = place(asys.A,asys.B,[p1 p2 p3 p4])
Ko = 1×4
1.0e+11 * 0.0000 0.0000 0.0154 4.0960
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
s4 = size(asys.A,1);
Z = [zeros([1,s4]) 1];
N = (1\([asys.A,asys.B;asys.C,asys.D]))*Z';
Nx = N(1:s4);
Nu = N(s4+1);
Nbar=Nu + Ko*Nx
Nbar = 2.4000e+03
%observer design:
At = [ asys.A-asys.B*Ko asys.B*Ko
zeros(size(asys.A)) asys.A-L*asys.C ];
Bt = [ asys.B*Nbar
zeros(size(asys.B)) ];
Ct = [ asys.C zeros(size(asys.C)) ];
%If you'd like to eliminate steady state error as much use Nbar:
% compute Nbar
%poles_k_d = exp(Ts.*poles_k)
%K_d = place(dsysi.a,dsysi.b,poles_k_d)
Ki=K(nstates+1);
K=K(1:nstates);
s4 = size(asys.A,1);
Z = [zeros([1,s4]) 1];
N = (1\([asys.A,asys.B;asys.C,asys.D]))*Z';
Nx = N(1:s4);
Nu = N(s4+1);
Nbarq=Nu + K*Nx
Nbarq = 2.5043e+03
%Well performing (adjusted) system:
syso = ss(At,Bt,Ct,0);
isstable(syso)
ans = logical
1
syso2 = minreal(syso)
4 states removed. syso2 = A = x1 x2 x3 x4 x1 -2400 -2.88e+06 -1.536e+09 -4.096e+11 x2 1 0 0 0 x3 0 1 0 0 x4 0 0 1 0 B = u1 x1 2400 x2 0 x3 0 x4 0 C = x1 x2 x3 x4 y1 8 1.779 -3.408e+06 386.3 D = u1 y1 0 Continuous-time state-space model.
%isminphase(syso)
f = 3;
t = 0:Ts:f;
figure
step(syso2,[0 f])
title('Continuous With observer flat(cold) start')
sysod = c2d(syso2,Ts,opt2)
sysod = A = x1 x2 x3 x4 x1 -0.9962 -390.2 -6.724e+04 -7.685e+06 x2 1.876e-05 -0.9512 -336.2 -3.842e+04 x3 9.381e-08 0.0002439 -0.6811 -192.1 x4 4.69e-10 1.22e-06 0.001595 0.0394 B = u1 x1 0.04503 x2 0.0002251 x3 1.126e-06 x4 5.629e-09 C = x1 x2 x3 x4 y1 -0.1448 -1977 -8.128e+05 2.966e+08 D = u1 y1 -1.738 Sample time: 0.01 seconds Discrete-time state-space model.
isstable(sysod)
ans = logical
1
u = 0.001*ones(size(t));
x0 = [0.01 0 0 0];
figure
lsim(sysod,zeros(size(t)),t,[x0]);
title('Discrete sampled with observer and conditions hot start')
xlabel('Time (sec)')
ylabel('Output')
res_agent = sysod;
figure
w = logspace(2,6,1000);
bode(res_agent,w),grid
figure
rlocus(res_agent)
figure
nyquist(res_agent)
ms = minreal(res_agent);
Gcc = ms;
zms = zero(ms) % closed-loop zeros
zms = 4×1
-1.0000 -1.8838 -0.5310 1.0000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
pms = pole(ms)
pms =
-0.7561 + 0.1951i -0.7561 - 0.1951i -0.5385 + 0.3077i -0.5385 - 0.3077i
tsim = 1;
setpointamp = 1; %
setpointapptime = 0.001; %
defaultsetpointpos = 0; %
Conf = RespConfig(Bias=defaultsetpointpos,Amplitude=setpointamp,Delay=setpointapptime)
Conf =
RespConfig with properties: Bias: 0 Amplitude: 1 Delay: 1.0000e-03 InitialState: [] InitialParameter: []
%figure
%step(Gcc,[0 tsim], Conf)
%title('Plant+Controller Closed Loop system step response')
[wngcc,zetagcc,pgcc] = damp(Gcc)
wngcc = 4×1
266.5610 266.5610 289.9608 289.9608
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
zetagcc = 4×1
0.1792 0.1792 0.0853 0.0853
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
pgcc =
-0.5385 + 0.3077i -0.5385 - 0.3077i -0.7561 + 0.1951i -0.7561 - 0.1951i
sigma(Gcc)
margin(Gcc)
diskmargin(Gcc)
ans = struct with fields:
GainMargin: [1 1] PhaseMargin: [0 0] DiskMargin: 0 LowerBound: 0 UpperBound: 0 Frequency: NaN WorstPerturbation: [1x1 ss]
stepinfo(Gcc)
ans = struct with fields:
RiseTime: 0 TransientTime: 0.2000 SettlingTime: 0.7500 SettlingMin: -1.8775 SettlingMax: 2.3386 Overshoot: 1.0331e+08 Undershoot: 8.2937e+07 Peak: 2.3386 PeakTime: 0.0200
disp('Whether the system is stable, minimum phase and proper:')
Whether the system is stable, minimum phase and proper:
isstable(sysod)
ans = logical
1
isminphase(tfdata(tf(sysod),'v'))
ans = logical
0
isproper(sysod)
ans = logical
1
Qc= ctrb(A,B)
Qc = 4×4
1.0e+05 * 0.0000 0.0000 1.9711 0.0001 0 0.0000 0.0000 1.9711 0 0 0.0000 0.0000 0 0 0 0.0000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
controllab = rank(Qc)
controllab = 4
hasdelay(sysod)
ans = logical
0
%tdc3 = totaldelay(sysod)
%sysndc3 = absorbDelay(sysod)
isallpass(tfdata(tf(sysod),'v'))
ans = logical
0
%Less important:
%sys_cl = ss(Ai-bi*[K Ki],br,ci,di)
%[a,b] = ss2tf(sys_cl.A,sys_cl.B,sys_cl.C,sys_cl.D)
%[A,B,C,D] = tf2ss(Nbar*a,b)
%sys_cl = ss(A,B,C,D)
%figure
%step(sys_cl,t)
%discrete system
%hold on
%sys_cld = c2d(sys_cl,Ts)
%figure
%step(sys_cld)
%title('Discrete sampled System')
%In similar approach to continue for 1-2, 2-1, 2-2 SISO parts of the MIMO.
%Contact me more if you need more tailored, specific service, solution,
%product development.
%Constructed by
%https://independent.academia.edu/PMazniker
%+380990535261, https://join.skype.com/invite/oXnJhbgys7oW
%https://diag.net/u/u6r3ondjie0w0l8138bafm095b
%https://github.com/goodengineer
%https://orcid.org/0000-0001-8184-8166
%https://willwork781147312.wordpress.com/portfolio/cp/
%https://www.youtube.com/channel/UCC__7jMOAHak0MVkUFtmO-w
%https://nanohub.org/members/130066
%https://pangian.com/user/hiretoserve/
%https://substack.com/profile/191772642-paul-m

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!