Ćwiczenie 2.

 

Podstawy modelowania i symulacji

 

1.        RÓWNANIE RÓŻNICZKOWE

 

Większość obiektów dynamicznych da się opisać równaniem różniczkowym postaci:

 

any(n)+an-1y(n-1)+... +a1y1+a0y=u(t)

 

 

 

 

Każde równanie różniczkowe n-tego rzędu da się sprowadzić do układu n równań rzędu 1-go. Zróbmy następujące podstawienia:

y(t)=x1(t)

x’1=x2

x’2=x3

:

x’n-1=xn

wówczas:

Otrzymamy układ równań 1-go rzędu następującej postaci:

który w notacji macierzowjma następującą postać:

=

 

Takie równanie macierzowe zapiszemy teraz w postaci funkcji Matlaba:

 

row_rozn.m

 

function dx=row_rozn(t,x)

global  A B

dx=A*x+wymuszenie(t);

 

Funkcja reprezentująca wymuszenie (wektor sygnałów wejściowych będzie miała następującą postać:

 

wymuszenie.m

 

function u=wymuszenie(t)

if t >= 0

u = 1

else

u = 0

end

 

Aby numerycznie rozwiązać powyższe równanie różniczkowe w Matlabie (tzn. otrzymać wartości funkcji y dla odpowiadających im wartości chwil czasowych t należy użyć funkcji ode23 lub ode45. Skrypt rozwiązujący takie równanie powinien mieć następującą postać:

global A B

A=[  ]

B=[  ]

[t,y] = ode23(‘rów_różn’,[t0 tk],y0)

gdzie:  t,y – rozwiązania, wektory odpowiednio chwil czasowych i wartości funkcji,

            rów_różn’ – nazwa funkcji definiującej rozwiązywane równanie różniczkowe,

            t0, tk – przedział czasu, w którym ma być rozwiązywane równanie różniczkowe,

            y0 – warunki początkowe (wartość zmiennych x1xn w chwili t0.

 

Przykład:

Oscylator liniowy z tłumieniem (obciążnik na sprężynie)

   (przyjęto, iż nie występuje wymuszenie u=0)

 

Funkcja reprezentująca powyższy układ równań różniczkowych:

oscylator.m

 

function DX=oscylator(t,X)

global A

DX=A*X;

 

Skrypt rozwiązujący takie równanie:

 

global A ;

k=1;

m=1;

a=0.5;

A=[0 1 ; -k/m -a/m];

y0=[5 0];   (warunek początkowy dla położenia różny od 0, x1=5)

[t,y]=ode23('oscylator',[0 20], y0);

plot(t,y(:,1));

 

2.  WIZUALIZACJA SYMULOWANYCH PROCESÓW

 

Możliwości wizualizacji procesów symulowanych w Matlabie zostaną pokazane na przykładzie modelu sprężyny z obciążeniem. Wizualizowany obiekt przedstawiony został na poniższym rysunku

 

 

Rys. Wizualizowany model

 

Załóżmy, że mamy (otrzymane z eksperymenu symulacyjnego) dwa wektory: t reprezentujący kolejne chwile czasowe symulacji i wektor y odpowiadających tym chwilom wartości położenia środka obciążnika.

Najpierw należy odpowiednio przeskalować okno, w którym ma być przeprowadzana nasza wizualizacja:

ymax= 20;

ymin= -20;       % zakres na osi Y w którym może przemieszczać się obciążnik

xmax= 10;

xmin= -10;       % zakres na osi Y

axis([xmin  xmax  ymin  ymax];

Następnie zostaną określone początkowe współrzędne kolejnych wierzchołków obciążnika (prostokąta) dla osi X:

xp=[ -2  -2  2  2];

i dla osi Y:

yp=[ y(1)-1  y(1)+1  y(1)-1  y(1)+1];

Kolejnym etapem jest pierwsze narysowanie obciążnika (dodatkowo zmiennej idp zostanie przypisany identyfikator narysowanego prostokąta (obiektu patch):

idp=patch(xp, yp, r’, ‘erasemode’,’xor’)

Ostatnim etapem jest stworzenie pętli wyświetlającej nasz prostokąt w kolejnych punktach (zmiana współrzędnych wektora yp):

for i=1:length(t),

  yp=[ y(i)-1  y(i)+1  y(i)-1  y(i)+1];

  set(idp,’xdata’, xp, ‘ydata’, yp);    % zmiana współrzędnych w obiekcie o identyfikatorze idp

  drawnow;                                     % wyrysowanie prostokąta w nowym położeniu

  pause(0.05)

end

 

Aby być w pełni usatysfakcjonowanym należy naszą wizualizację uzupełnić o sprężynę:

ymax= 20;

ymin= -20;

xmax= 10;

xmin= -10;

axis([xmin  xmax  ymin  ymax];

xp=[ -2  -2  2  2];

yp=[ y(1)-1  y(1)+1  y(1)-1  y(1)+1];

v=0:0.1:6*pi;                                     

xs=sin(v)% współrzędne sinusa po zmiennej X

ys=(ymax-yp(2))/(6*pi)*v+yp(2);             % współrzędne sinusa po zmiennej Y

idp=patch(xp, yp, r’, ‘erasemode’,’xor’)

idl=line(xs, ys, erasemode’,’xor’)    %pierwsze narysowanie lini w kształcie sprężyny

for i=1:length(t),

  yp=[ y(i)-1  y(i)+1  y(i)-1  y(i)+1];

  set(idp,’xdata’, xp, ‘ydata’, yp);

  set(idl,’xdata’, xs, ‘ydata’, ys);

  drawnow;

  pause(0.05)

end