MPC - Andini Vira

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 26

PROGRAM REPORT

MODEL PREDICTIVE CONTROL


Biocybernetics Q

Written by:
Andini Vira Salsabilla Z.P
5023201065

Lecturer:
Dr. Achmad Arifin, S.T., M.Eng.

BIOMEDICAL ENGINEERING DEPARTMENT


FACULTY OF INTELLIGENT ELECTRICAL AND INFORMATICS
TECHNOLOGY
SEPULUH NOPEMBER INSTITUTE OF TECHNOLOGY SURABAYA
2023
CHAPTER 1
PROBLEM
CHAPTER 3
RESULTS
1. Result

Figure 1. System 1 output

Figure 2. System 2 output


unit MPC_13;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, TeEngine, Series, ExtCtrls, TeeProcs, Chart,
Math, ComCtrls, Spin, VclTee.TeeGDIPlus;

type
TForm1 = class(TForm)
btn1: TBitBtn;
btn2: TBitBtn;
btn5: TBitBtn;
btn6: TBitBtn;
lbl1: TLabel;
lbl2: TLabel;
lbl3: TLabel;
pgc1: TPageControl;
ts1: TTabSheet;
mmo1: TMemo;
cht1: TChart;
cht2: TChart;
ts2: TTabSheet;
cht3: TChart;
cht4: TChart;
lnsrsSeries3: TLineSeries;
lnsrsSeries4: TLineSeries;
lnsrsSeries1: TLineSeries;
lnsrsSeries2: TLineSeries;
rb1: TRadioButton;
rb2: TRadioButton;
pntsrsSeries1: TPointSeries;
pntsrsSeries2: TPointSeries;
lst1: TListBox;
lst2: TListBox;
ts3: TTabSheet;
cht5: TChart;
cht6: TChart;
cht7: TChart;
mmo2: TMemo;
mmo3: TMemo;
se1: TSpinEdit;
chk1: TCheckBox;
chk2: TCheckBox;
lbl8: TLabel;
lnsrsSeries5: TLineSeries;
pntsrsSeries3: TPointSeries;
pntsrsSeries4: TPointSeries;
lnsrsSeries6: TLineSeries;
pntsrsSeries5: TPointSeries;
lnsrsSeries7: TLineSeries;
lnsrsSeries8: TLineSeries;
btn3: TBitBtn;
lbl5: TLabel;
se2: TSpinEdit;
se3: TSpinEdit;
lbl6: TLabel;
procedure btn5Click(Sender: TObject);
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
procedure BacaDataStep;
procedure BacaDataImpulse;
procedure btn3Click(Sender: TObject);
procedure se2Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type Matrix = array[1..10, 1..10] of Real;
type Vector = array[1..10] of Real;
type Matrix1 = array[1..10] of Vector;

var
Form1: TForm1;
nc, np, Nsim1, baris,kolom,z,time,orde : Integer;
x1_step,x1_impulse,x1,x2 : array[0..5000] of Extended;
y1_step,y1_impulse,s_step,s_impulse : array[-5..5000] of Extended;
rw,k1,k2,k3,k4 : Extended;
A,B,C,I,M_inv,M,Mad,Mbd : array[0..2,0..2] of extended;
M_ka,M_kb,M_kc : array[0..2,0..2] of extended;
t,xdot,dt,x,u,xdotdot,u1 : real;
sgn_step,sgn_impulse,C4 : Real;
row,col,sample1,sample2 : Integer;
respon_step, respon_impulse,asli,dot : Real;
Ahat,Ae,Be1,Ce,h1,F,c1,v1,phit,phi : Matrix;
Bhat, Chat,C5 : Vector;

implementation

{$R *.dfm}

procedure TForm1.btn5Click(Sender: TObject);


begin
mmo1.Clear;
lnsrsSeries1.Clear;
lnsrsSeries2.Clear;
lnsrsSeries3.Clear;
lnsrsSeries4.Clear;
pntsrsSeries1.Clear;
pntsrsSeries2.Clear;
lst1.Clear;
lst2.Clear;
end;

procedure TForm1.se2Change(Sender: TObject);


begin

end;

procedure TForm1.btn1Click(Sender: TObject);


var
fak : Real;
k,j : Integer;
begin
mmo1.Clear;
//rw := StrToFloat(edt1.Text);
//nc := StrToInt(edt2.Text);
//np := StrToInt(edt3.Text);

nsim1 := 150;
dt := 0.001;
orde := 4;

//--------------------------- INPUT DATA MATRIKS --------------------


if rb1.Checked =True then
begin
A[0,0]:=0;
A[0,1]:=1;
A[0,2]:=0;
A[1,0]:=3;
A[1,1]:=0;
A[1,2]:=1;
A[2,0]:=0;
A[2,1]:=1;
A[2,2]:=0;

B[0,0]:=1;
B[0,1]:=1;
B[0,2]:=3;

C[0,0]:=0;
C[1,0]:=1;
C[2,0]:=0;

I[0,0]:=1;
I[0,1]:=0;
I[0,2]:=0;
I[1,0]:=0;
I[1,1]:=1;
I[1,2]:=0;
I[2,0]:=0;
I[2,1]:=0;
I[2,2]:=1;

row := 2;
col := 2;
end;

if rb2.Checked = True then


begin
A[0,0]:=0;
A[0,1]:=1;
A[1,0]:=-4;
A[1,1]:=0;

B[0,0]:=0;
B[0,1]:=1;

C[0,0]:=0;
C[1,0]:=1;

I[0,0]:=1;
I[0,1]:=0;
I[1,0]:=0;
I[1,1]:=1;

row:=1;
col:=1;
end;

//-------------------- BACA MATRIX A_HAT ------------------------


mmo1.Text := mmo1.Text+'State Space Matrix in Continous Time' +#13#10;
mmo1.Text := mmo1.Text+'A'+#13#10;
for baris := 0 to row do
begin
for kolom:=0 to col do
begin
mmo1.Text := mmo1.Text+floattostr(A[baris,kolom])+' ';
end;
mmo1.Text := mmo1.Text+#13#10;;
end;

//-------------- BACA VECTOR B_HAT----------------


mmo1.Text := mmo1.Text+#13#10;
mmo1.Text := mmo1.Text+'B:'+#13#10;
for baris := 0 to 0 do
begin
for kolom:=0 to col do
begin
mmo1.Text := mmo1.Text+floattostr(B[baris,kolom])+' ';
end;
mmo1.Text := mmo1.Text+#13#10;;
end;

//---------------------- BACA VECTOR C_HAT -----------------


mmo1.Text := mmo1.Text+#13#10;
mmo1.Text := mmo1.Text+'C:'+#13#10;
for baris := 0 to row do
begin
for kolom:=0 to 0 do
begin
mmo1.Text := mmo1.Text+floattostr(C[baris,kolom])+' ';
end;
mmo1.Text := mmo1.Text+#13#10;;
end;

//------------------ bikin matriks identitas ------------


for baris := 0 to row do
for kolom := 0 to col do
begin
if kolom <> baris then
begin
M_Inv[baris,kolom] := StrToFloat('0');
end
else
begin
M_Inv[baris,kolom] := StrToFloat('1');
end;
end;

//---------------- hitung I-TA/2--------------------


mmo1.Text := mmo1.Text+#13#10;
mmo1.Text := mmo1.Text+'I-TA/2:'+#13#10;
for baris := 0 to row do
begin
for kolom := 0 to col do
begin
M[baris,kolom]:=(I[baris,kolom]-(0.001/2*A[baris,kolom]));
mmo1.Text:= mmo1.Text+ FloatToStr(M[baris,kolom])+ ' ';
end;
mmo1.Text:= mmo1.Text+#13#10;
end;

//---------------- hitung Inverse I-TA/2-----------------


mmo1.Text := mmo1.Text+#13#10;
mmo1.Text := mmo1.Text+'Inverse I-TA/2:'+#13#10;
for k:=0 to row do
begin
fak := M[k,k];
for kolom:=0 to col do
begin
M[kolom,k]:=M[kolom,k]/fak;
M_Inv[kolom,k]:=M_Inv[kolom,k]/fak;
end;

for baris:=0 to row do


begin
if baris <> k then
begin
fak:=M[k,baris];
for kolom:=0 to col do
begin
M[kolom,baris]:= M[kolom,baris]-fak*M[kolom,k];
M_Inv[kolom,baris]:= M_Inv[kolom,baris]-fak*M_Inv[kolom,k];
end;
end;
end;
end;
for baris:=0 to row do
begin
for kolom:=0 to col do
begin
mmo1.Text := mmo1.Text+ FloatToStr(M_Inv[baris,kolom])+ ' ';
end;
mmo1.Text := mmo1.Text+#13#10;
end;

//--------------------- hitung I+TA/2--------------------------


mmo1.Text := mmo1.Text+#13#10;
mmo1.Text := mmo1.Text+'I+TA/2:'+#13#10;
for baris := 0 to row do
begin
for kolom := 0 to col do
begin
Mad[baris,kolom]:=I[baris,kolom]+(0.001/2*A[baris,kolom]);
mmo1.Text := mmo1.Text+ FloatToStr(Mad[baris,kolom])+ ' ';
end;
mmo1.Text := mmo1.Text+#13#10;
end;

//----------------------- Hitung AD ---------------------


mmo1.Text := mmo1.Text+#13#10;
mmo1.Text := mmo1.Text+#13#10;
mmo1.Text := mmo1.Text+'State Space Matrix in Continous Time'+#13#10;
mmo1.Text := mmo1.Text+'AD:'+#13#10;
for baris := 0 to row do
begin
for kolom := 0 to col do
begin
M_ka[kolom, baris] := 0;
for k := 0 to row do
begin
M_ka[kolom, baris] := M_ka[kolom, baris] + M_Inv[baris,k] *
Mad[k,kolom];
end;
mmo1.Text := mmo1.Text+ FloatToStr(M_ka[kolom, baris])+ ' ';
end;
mmo1.Text := mmo1.Text+#13#10;
end;

//----------------------- Hitung BD ---------------------


mmo1.Text := mmo1.Text+#13#10;
mmo1.Text := mmo1.Text+'BD:'+#13#10;
for baris := 0 to row do
for kolom := 0 to col do
begin
Mbd[kolom,baris]:=(0.001/(1-0.0005))*B[kolom,baris];
end;
for baris := 0 to 0 do
for kolom := 0 to col do
begin
M_kb[kolom, baris] := 0;
for k := 0 to 0 do
begin
M_kb[kolom, baris] := M_kb[kolom, baris] + M_Inv[baris,k] *
Mbd[k,kolom];
mmo1.Text := mmo1.Text+ FloatToStr(M_kb[kolom, baris])+ ' ';
end;
mmo1.Text := mmo1.Text+#13#10;
end;

//----------------------- Hitung CD ---------------------


mmo1.Text := mmo1.Text+#13#10;
mmo1.Text := mmo1.Text+'CD:'+#13#10;
for baris:= 0 to 0 do
begin
for kolom:= 0 to col do
begin
m_kc[kolom,baris]:= C[kolom,baris];
mmo1.Text := mmo1.text+floattostr(m_kc[kolom,baris])+' ';
end;
mmo1.Text := mmo1.Text+#13#10;
end;

//------------- Respon Discretize -----------------


for k:=0 to 3000 do
begin
if k>0 then
begin
u := 1;
u1 := 0;
end
else
begin
u := 0;
u1:=1;
end;

for baris :=0 to row do


begin
for kolom :=0 to col do
begin
x1_step[k+1]:= m_ka[kolom,baris]*x1_step[k];
x1_impulse[k+1]:= m_ka[kolom,baris]*x1_impulse[k];
end;
end;
for baris:=0 to 0 do
begin
for kolom:=0 to col do
begin
x1_step[k+1]:= x1_step[k+1]+m_kb[kolom,baris]*u;
x1_step[k+1]:=x1_step[k+1]*((1-0.0005)/(1+0.0005));
y1_step[k] := m_kc[kolom,baris]*x1_step[k];

x1_impulse[k+1]:= x1_impulse[k+1]+m_kb[kolom,baris]*u1;
x1_impulse[k+1]:=x1_impulse[k+1]*((1-0.0005)/(1+0.0005));
y1_impulse[k] := m_kc[kolom,baris]*x1_impulse[k];
end;
end;
lnsrsSeries1.AddXY(k/100,x1_step[k]);
lnsrsSeries2.AddXY(k/100,x1_impulse[k]);
end;

end;

procedure difeq(x,xdot,u:real);
begin
xdotdot:=-0.5*xdot-x+u; //plant model
end;

procedure rk_pltA(x,xdot,u:real);
begin
difeq(x,xdot,u);
k1:=0.5*dt*xdotdot;

difeq(x+0.5*dt*(xdot+0.5*k1),xdot+k1,u+0.5*dt);
k2:=0.5*dt*xdotdot;

difeq(x+0.5*dt*(xdot+0.5*k1),xdot+k2,u+0.5*dt);
k3:=0.5*dt*xdotdot;

difeq(x+dt*(xdot+k3),xdot+2*k3,u+dt);
k4:=0.5*dt*xdotdot;
asli:=x+dt*(xdot+1/3*(k1+k2+k3));
dot:=xdot+1/3*(k1+2*k2+2*k3+k4);
end;

procedure TForm1.btn2Click(Sender: TObject);


var
i : Integer;
hasil_x1, hasil_xdot1 : Real;
hasil_x2, hasil_xdot2 : Real;
lama : Real;
begin
Nsim1 := 150;
dt := 0.1;
hasil_x1 := 0;
hasil_xdot1 := 0;
hasil_x2 := 0;
hasil_xdot2 := 0;
t := 0;
i := 0;

BacaDataStep;
BacaDataImpulse;

while i<=Nsim1 do
begin
if t>0 then
begin
sgn_step:=1;
sgn_impulse:=0;
end
else
begin
sgn_step:=0;
sgn_impulse:=1;
end;
//step
rk_pltA(hasil_x1,hasil_xdot1,sgn_step);
hasil_x1 := asli;
hasil_xdot1 := dot;
respon_step := hasil_x1;

//impulse
rk_pltA(hasil_x2,hasil_xdot2,sgn_impulse);
hasil_x2 := asli;
hasil_xdot2 := dot;
respon_impulse := s_impulse[i];
lnsrsSeries3.AddXY(t,respon_step);
lnsrsSeries4.AddXY(t,respon_impulse);
Inc(i);
t:=t+dt;
end;
for i:=1 to Nsim1-1 do
begin
pntsrsSeries1.AddXY(i*dt,s_step[i]);
pntsrsSeries2.AddXY(i*dt,s_impulse[i]);
lst1.Items.Add(FloatToStr(s_step[i]));
lst2.Items.Add(FloatToStr(s_impulse[i]));
end;
end;

procedure TForm1.BacaDataStep;
var
p,i:integer;
filename : textfile;
begin
assignfile(filename,'Step_state.txt');
reset(filename);
p:=1;
readln(filename) ;

while not eof(filename) do


begin
Readln(filename,x1[p],s_step[p]);
inc(p);
end;
closefile(filename);
sample1:= p;
end;

procedure TForm1.BacaDataImpulse;
var
p,i:integer;
filename : textfile;
begin
assignfile(filename,'Impulse_state.txt');
reset(filename);
p:=1;
readln(filename) ;

while not eof(filename) do


begin
Readln(filename,x2[p],s_impulse[p]);
inc(p);
end;
closefile(filename);
sample2:= p;
end;

procedure TForm1.btn3Click(Sender: TObject);


var
i1,j1, orde,length : integer;
t : real;
temp_mat : matrix;
key1,key : string;
row,col : integer;
rw : extended;
filename : textfile;
begin
rw := se1.Value*0.1;
Nsim1:=150;
dt:=0.1;
orde:=4;
length:=2;

nc := se2.Value;
np := se3.Value;

//======================= Baca File From Number 2


===================
assignfile(filename,'state space model.dat');
reset(filename);
mmo2.Text:=mmo2.Text+'A:'+#13#10;
key1:= 'Ahat matrix, Order:'+inttostr(length)+'x'+inttostr(length);
read(filename,key);
while key<>key1 do
readln(filename,key);
readln(filename,row);
readln(filename,col);

//----------read Ahat matrix---------------


for i1:= 1 to row do
begin
for j1:= 1 to col do
begin
read(filename, Ahat[i1,j1]);
mmo2.text:=mmo2.text+floattostr(Ahat[i1,j1])+' ';
end;
mmo2.Text:=mmo2.Text+#13#10;
readln(filename);
end;

mmo2.Text:= mmo2.Text+#13#10;
mmo2.Text:= mmo2.Text+#13#10;

//-----------read Bhat vektor------------


key1:= 'Bhat Vector, Order:'+inttostr(length);
read(filename,key);
while key<>key1 do
readln(filename,key);
readln(filename,row);
for i1:= 1 to row do
begin
readln(filename, Bhat[i1]);
mmo2.text:=mmo2.text+floattostr(Bhat[i1])+#13#10;
end;

mmo2.Text:=mmo2.Text+#13#10;
mmo2.Text:=mmo2.Text+'C:'+#13#10;

//------------read Chat vektor-------------------


key1:= 'Chat Vector, Order:'+inttostr(length);
read(filename,key);
while key<>key1 do
readln(filename,key);
readln(filename,row);
for i1:= 1 to col do
begin
read(filename, Chat[i1]);
mmo2.text:=mmo2.text+floattostr(Chat[i1])+' ';
mmo2.Text:=mmo2.Text;
end;
closefile(filename);
end;

end.

2. Answer :

3. Answer :
The time state 𝑥(𝑡)of the Plant is not known in general. The observer inputs are system input
𝑢(𝑡)

Picture 5. General Diagram


and output (via sensors) 𝑦(𝑡), and the observer output is the state estimate 𝑥̂(𝑡). The
observer is contructed using the equation,

Picture 6. The model and coreection term

As continuous system in this diagram.

Picture 7. The Complete diagram

In the observer form, the state variable estimate 𝑥̂𝑚 (𝑘 + 1) consists of two terms. The
first term is the original model and the second term is the correction term based on the
error between the measured output

𝑥̃𝑚 (𝑘 + 1) = 𝐴𝑚 𝑥̃𝑚 (𝑘) − 𝐾𝑜𝑏 𝐶𝑚 𝑥̂𝑚 (𝑘)


= (𝐴𝑚 − 𝐾𝑜𝑏 𝐶𝑚 )𝑥̃𝑚 (𝑘).

And the predicted output using the estimate 𝑥̂𝑚 (𝑘 + 1). To choose the observer gain 𝐾𝑜𝑏 ,
we examine the closed-loop error equation. By substituting 𝑦(𝑘) = 𝐶𝑚𝑋𝑚 (𝑘) into the
observer equation, with the definition of error state 𝑥̂𝑚 (𝑘) = 𝑥𝑚 (𝑘) − 𝑥̂𝑚 (𝑘), we obtain
that, and we can use initial error 𝑥̂𝑚 (0) we have.

𝑥̃𝑚 (𝑘) = (𝐴𝑚 − 𝐾𝑜𝑏 𝐶𝑚 )𝑘 𝑥̃𝑚 (0).

Since the open-loop prediction is.

𝑥̃𝑚 (𝑘 + 1) = 𝐴𝑚 (𝑥𝑚 (𝑘) − 𝑥̂𝑚 (𝑘))


= 𝐴𝑚 𝑥̃𝑚 (𝑘).

With a given non zero initial error 𝑥̂𝑚 (0), we have

𝑥̃𝑚 (𝑘) = 𝐴𝑚 𝑘 𝑥̃𝑚 (0).

By comparing the observer and open-loop error prediction, 𝐾𝑜𝑏 can be used to
manipulate the convergence rate of the error. A commonly used approach is to place the
closed-loop eigenvalues of the error system matrix 𝐴𝑚 − 𝐾𝑜𝑏 𝐶𝑚 at a desired location of
the complex plane, in case of single output.

Eigen Value (𝐴𝑚 − 𝐾𝑜𝑏 𝐶𝑚 ) should be at pole location of Observer (actual closed-loop
characteristics polynomial).

Det of Eiigsen (𝐴𝑚 − 𝐾𝑜𝑏 𝐶𝑚 ) = (𝑙𝑎𝑚𝑏𝑎 − 𝑝𝑜𝑙𝑒)(𝑙𝑎𝑚𝑏𝑎 − 𝑝𝑜𝑙𝑒2) . Choosing the


observer gain 𝐾𝑜𝑏 by using this placement.

𝐷𝑒𝑡(𝜆I − 𝐴𝑚 − 𝐾𝑜𝑏 𝐶𝑚 ) = 𝜆 − 𝑝𝑜𝑙𝑒1)(𝜆 − 𝑝𝑜𝑙𝑒2)

You might also like