Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ispolzovanie_Matlab_Dlya_Modelirovania_Dvizheni...docx
Скачиваний:
5
Добавлен:
01.05.2025
Размер:
1.4 Mб
Скачать

Примеры моделирования голономных систем Диск с маятником

Однородный диск массы и радиуса может вращаться вокруг горизонтальной оси O, расположенной на расстоянии от центра масс. Спиральная пружина жесткости c соединяет диск с неподвижной осью. К диску с помощью шарнира A подвешен невесомый стержень длины с точечным грузом B массы , причем .

Уравнения движения Лагранжа 2-го рода имеют вид:

Заданы численные значения параметров и начальных условий:

кг

м

м

кг

Нм

рад

рад

с-1

м/с

Для рассматриваемой голономной механической системы в качестве обобщенных координат приняты x, φ.

Визуализация динамики механической системы.

Далее рассматривается программа, которая будет производить следующие действия:

  1. запрашивать у пользователя данные о численных параметрах системы и начальных условиях;

  2. интегрировать заданные уравнения движения при введенных начальных условиях;

  3. строить фазовые портреты;

  4. визуализировать динамику системы.

Указанная программа состоит из нескольких файлов: Dinamika, Param, Kadr. Dinamika – основная функция, из которого происходит вызов вспомогательных скрипта Param и функции Kadr. Param предназначен для задания параметров системы, функция Kadr ­– для визуализации поведения механической системы.

Такое разделение функциональной нагрузки, во-первых, улучшает читаемость кода основной функции Dinamika, а во-вторых, позволяет использовать исходный код Param и Kadr для вызова их из другой функции аналогичной Dinamika, содержащей, например, линеаризованные уравнения движения исследуемой системы.

В функции Dinamika интегрируются уравнения движения и строятся фазовые портреты. Рассмотрим подробнее ее исходный код:

function DINAMIKA

% Система с двумя степенями свободы, обобщ. коорд q(1), q(2).

Для удобства необходимо определить параметры механической системы и некоторые служебные переменные как глобальные. В каждой из функций (Dinamika, Param, Kadr) после ключевого слова global необходимо указывать только используемые в этой функции глобальные переменные.

global m1 m2 r l c fi_z e M0 p p0 gam

global y0 tfin step text0 k_uskor Wit r1 r2

disp([pwd,'\DINAMIKA_2']); % pwd - текущая директория (папка)

God_date_time=fix(clock)

text0='Диск с маятником (нелин.)';

% Эти параметры передаются как глобальные :

Param_2; % Ввод параметров (начальное,конечное вркмя интегр.,массы, размеры и т.п.)

disp(' Ждите');

tic % Включение секундомера

Nfig=3; % Номер первого графика

addpath(genpath('Primitivs')); % Подключение поддиректории с ПРИМИТИВАМИ

tout=[t0:step:tfin]; % Вектор из временных точек (для ode45)

Abstol= 1.e-9*[ 1 1 1 1];

options = odeset('RelTol',1.e-9,'AbsTol',Abstol);

[t,y]=ode45(@f,tout,y0,options);

Последней командой интегрируется система дифференциальных уравнений движения диска с маятником. В качестве системы ДУ интегратору ode45 передаются выходные параметры дополнительной функции f(t,y), реализованной в файле Dinamika. Исходный код f(t, y) рассмотрен ниже. Результат интегрирования системы передается в матрицу [t,y]. Далее вычисляются производные dy/dt и заносятся в матрицу Yt:

lent=length(t); % длина массива t .

for i=1:lent,

yt(i,:)=f(t(i),y(i,:))' ;

end;

В программе вводятся обозначения: fi – , tet – , fit – , tett – , fitt – , tettt – .

fi=y(:,1);

tet=y(:,2);

fit=y(:,3);

tett=y(:,4);

fitt=yt(:,1);

tettt=yt(:,2);

После интегрирования системы ОДУ можно приступить к визуализации движения системы.

Следующей командой в вектор q записываются значения обобщенных координат: q(1,:)-значения координаты x, q(2,:)-значения координаты fi.

q=[fi,tet]';

В переменные t0, q0 записываются начальное время и начальное положение системы.

t0=t(1); % Начальное время

q0=[q(1,1) q(2,1)]; % Начальное положение

Далее вызывается функция Kadr для визуализации динамики механической системы. Передача в качестве последнего входного параметра нулевого значения указывает на необходимость визуализации только начального положения системы.

Kadr_2(t0,q0,0); % Построение начального положения и неизменной части рисунка

len=length(t);

hold off;

Для рассматриваемого временного промежутка перерисовывается текущее положение системы. Для этого функции Kadr в качестве последнего входного параметра передается значение «1». Исходный код функции Kadr рассмотрен ниже.

tic

for i=1:len

t0=t(i); % Текущее время

q0=[q(1,i) q(2,i)]; % Текущее положение

Kadr_2(t0,q0,1); % Построение текущего положения при сохранении неизменной части рисунка

end;

toc

Вычисляется величина реакции.

% % Вычисление реакций :

alf=fi-tet-pi/6;

N=m2*(g*cos(tet)+l*tett.^2)-2*m2*e*(fitt.*cos(alf)-fit.^2.*sin(alf)) ;

Далее на экран выводятся некоторые графики, характеризующие поведение механической системы.

figure(Nfig);

plot(t,[y(:,1) y(:,2)]); % Графическое изображение результата

set(gca,'FontName','MS Sans Serif'); % Установка подходящего шрифта

title ('Обобщенные координаты');

xlabel('t (сек) '); % Метка по оси x

set(gca,'FontName','Arial'); % Установка подходящего шрифта

ylabel('fi,tet ');

legend('fi','tet');

grid on;

%================

Nfig=Nfig+1;

figure(Nfig);

plot(t,[y(:,3) y(:,4)]); % Графическое изображение результата

set(gca,'FontName','MS Sans Serif'); % Установка подходящего шрифта

title ('Обобщенные скорости');

xlabel('t (сек) '); % Метка по оси x

set(gca,'FontName','Arial'); % Установка подходящего шрифта

ylabel('fi_t,tet_t ');

legend('fi_t','tet_t');

grid on;

%================

Nfig=Nfig+1;

figure(Nfig);

plot(t,[yt(:,3), yt(:,4)]); % Графическое изображение результата

set(gca,'FontName','MS Sans Serif'); % Установка подходящего шрифта

title ('Обобщенные ускорения');

xlabel('t (сек) '); % Метка по оси x

set(gca,'FontName','Arial'); % Установка подходящего шрифта

ylabel('fi_t_t,tet_t_t ');

legend('fi_t_t','tet_t_t');

grid on;

%================

Nfig=Nfig+1;

figure(Nfig);

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

set(gca,'FontName','MS Sans Serif');

title ('Фазовый портрет 1');

xlabel('fi');

set(gca,'FontName','Arial');

ylabel('fit ');

grid on;

Nfig=Nfig+1;

figure(Nfig);

plot(y(:,2),y(:,4));

set(gca,'FontName','MS Sans Serif');

title ('Фазовый портрет 2');

xlabel('tet ');

set(gca,'FontName','Arial');

ylabel('tett ');

grid on;

Вычисляются и выводится на экран зависимость реакций от времени:

Nfig=Nfig+1;

figure(Nfig);

plot(t,N);

set(gca,'FontName','MS Sans Serif');

title ('Давление системы на плоскость');

xlabel('сек ');

ylabel('Н');

grid on;

Далее сравнивается поведение обобщенных координат и скоростей с соответствующими координатами и скоростями в линеаризованной системе.

figure(101);

plot(t,[y(:,1) y(:,2)]); % Графическое изображение результата

set(gca,'FontName','MS Sans Serif'); % Установка подходящего шрифта

title ('Сравнение. Обобщенные координаты (- - лин.,-- нелин.)');

xlabel('t (сек) '); % Метка по оси x

set(gca,'FontName','Arial'); % Установка подходящего шрифта

ylabel('fi,tet ');

legend('fi','tet');

grid on;

hold on;

figure(102);

plot(t,[y(:,3) y(:,4)]); % Графическое изображение результата

set(gca,'FontName','MS Sans Serif'); % Установка подходящего шрифта

title ('Сравнение. Обобщенные скорости (- - лин.,-- нелин.))');

xlabel('t (сек) '); % Метка по оси x

set(gca,'FontName','Arial'); % Установка подходящего шрифта

ylabel('fi_t,tet_t ');

legend('fi_t','tet_t');

grid on;

hold on;

toc % Выключение секундомера

disp('====================')

После окончания работы программы в окнах «Сравнение. Обобщенные координаты», «'Сравнение. Обобщенные скорости» отобразятся графики, соответствующие рассматриваемой нелинейной системы. Чтобы увидеть на этих же рисунках графики обобщенных координат и скоростей линейной системы, необходимо вызвать функцию Dinamika с линеаризованными уравнениями движения, в которой код вывода графиков сравнения заменен на следующий:

figure(101);

plot(t,[y(:,1) y(:,2)]); % Графическое изображение результата

set(gca,'FontName','MS Sans Serif'); % Установка подходящего шрифта

title ('Сравнение. Обобщенные координаты (- - лин.,-- нелин.)');

xlabel('t (сек) '); % Метка по оси x

set(gca,'FontName','Arial'); % Установка подходящего шрифта

ylabel('fi,tet ');

legend('fi','tet');

grid on;

hold on;

figure(102);

plot(t,[y(:,3) y(:,4)]); % Графическое изображение результата

set(gca,'FontName','MS Sans Serif'); % Установка подходящего шрифта

title ('Сравнение. Обобщенные скорости (- - лин.,-- нелин.))');

xlabel('t (сек) '); % Метка по оси x

set(gca,'FontName','Arial'); % Установка подходящего шрифта

ylabel('fi_t,tet_t ');

legend('fi_t','tet_t');

grid on;

hold on;

На этом примере также показано использование дескрипторов объектов. Благодаря тому что при создании графических окон (figure) были явно указаны значения их дескрипторов (константы 101 и 102), после отработки программы, по-прежнему можно обращаться к этим рисункам и редактировать их, если, конечно, не закрывать их.

В файле Dinamika определена еще одна функция с именем f, возвращающая в качестве выходных параметров вектор dydt, который содержит правые части нормализованных уравнений движения.

Входные переменные:

t – независимая переменная (время),

y – вектор фазовых переменных, в рассматриваемой задаче компонентами вектора являются .

function dydt = f(t,y)

global m1 m2 r l c fi_z e M0 p p0 gam

g=9.8; % м/сек

fi=y(1);

tet=y(2);

fit=y(3);

tett=y(4);

dydt(1)=fit;

dydt(2)=tett;

alf=fi-tet-pi/6;

A=[ (5/6*m1+4/3*m2)*r^2 , 2*m2*l*e*sin(alf) ; ...

2*e*sin(alf) , l ];

B=...

[2*m2*l*e*cos(alf)*tett^2+(m1*sin(fi)+2*m2*cos(fi-pi/6))*e*g-c*(fi-fi_z)+...

M0*sin((p*t+p0)*t+gam),...

-g*sin(tet)-2*e*cos(alf)*fit^2 ]';

xftt=A^(-1)*B; % Решение системы линейных алгебр. уравнений

dydt(3)=xftt(1);

dydt(4)=xftt(2);

dydt=dydt';

Для линейной системы код в функции f(t, y) записываются линеаризованные уравнения движения.

Ниже представлены полученные графики для линейной и нелинейной систем с одинаковыми параметрами системы и начальными условиями.

Линейная система

Нелинейная система

Для создания скрипта Param был создан файл param.m со следующим исходным кодом :

global m1 m2 r l c fi_z e M0 p0 p gam

global y0 tfin step t_pause k_uskor Wit r1 r2

Заданы следующие значения параметров по умолчанию :

g=9.8; % м/сек

m1=1; % Масса диска (кг)

m2=0.2; % Масса груза (кг)

r=0.2; % Радиус диска

l=0.2; % Длина стержня (м)

c=1.95 ; % Жесткость спиральной пружины (Нм)

fi_z=0; %(-0.20102564102564 в пол. равн. fi=0)

e=r/sqrt(3);

M0=0; 0.02; % Амплитуда момента, приложенного к диску

p0= 4.6887; % Циклическая частота момента, приложенного к диску

gam=pi/2; % Начальная фаза

t0=0; % Начальное время интегрирования (сек)

y0=' 0.52094380244489+0.2 , 0+0.3 , pi/36 , 0 ' ; % Начальные условия - положение равновесия

tfin= 10; % Конечное время интегрирования (сек)

step= 0.1; 0.05; % Шаг выдачи результатов интегрирования (сек)

Задаются значения по умолчанию для параметров спиральной пружины:

Wit=2; % Кол-во витков в исходном состоянии

r1=e/20; % Полярная координата внутреннего конца пружины

r2=e/3; % Полярная координата внешнего конца пружины

Далее у пользователя запрашиваются численные параметры системы. Если пользователь ничего не вводит, используются ранее заданные значения по умолчанию.

inp=input(['Введите массу диска m1 (',num2str(m1),') : ']);

if isempty(inp)

disp([' масса диска m1 = ', num2str(m1)]) ;

inp=m1;

end;

m1=inp;

inp=input(['Введите массу груза m2 (',num2str(m2),') : ']);

if isempty(inp)

disp([' масса груза m2 = ', num2str(m2)]) ;

inp=m2;

end;

m2=inp;

inp=input(['Введите радиус диска r (',num2str(r),') : ']);

if isempty(inp)

disp([' радиус диска r = ', num2str(r)]) ;

inp=r;

end;

r=inp;

inp=input(['Введите длину стержня l (',num2str(l),') : ']);

if isempty(inp)

disp([' длина стержня l = ', num2str(l)]) ;

inp=l;

end;

l=inp;

inp=input(['Введите жесткость пружины c (',num2str(c),') : ']);

if isempty(inp)

disp([' жесткость пружины c = ', num2str(c)]) ;

inp=c;

end;

c=inp;

inp=input(['Введите fi_z пружины (',num2str(fi_z),') : ']);

if isempty(inp)

disp([' fi_z = ', num2str(fi_z)]) ;

inp=fi_z;

end;

fi_z=inp;

y0_inp=input( ' Задайте нач. условия интегрирования fi, tet, dfi/dt, dtet/dt : ' , 's' );

if isempty(y0_inp)

disp( [ ' начальные условия : ', y0 ] ) ;

y0_inp=y0;

end;

y0=str2num(y0_inp)';

inp=input('Введите величину промежутка интегрирования tfin : ');

if isempty(inp)

disp([' величина промежутка интегрирования tfin = ', num2str(tfin) ,' сек']) ;

inp=tfin;

end;

tfin=inp;

inp=input('Задайте шаг выдачи результатов интегрирования (сек) step : ');

if isempty(inp)

disp([' шаг выдачи результатов step = ', num2str(step) ,' сек']) ;

inp=step;

end;

step=inp;

t_pause=step; %(сек) Пауза между кадрами по умолчанию

k_uskor0=1;

k_uskor=input([...

'Задай коэф. ускорения/замедления ( >1 / <1) показа кадров ('...

,num2str(k_uskor),') : ']);

if isempty(k_uskor)

k_uskor=k_uskor0;

disp( [ ' коэф. ускорения/замедления = ', num2str(k_uskor) ] ) ;

disp('Программа Param2 выполнена')

disp('--------------------------------')

end;

Для записи исходного кода функции Kadr рекомендуется создать файл kadr.m в одной директории с Param.m и Dinamika.m.

Входные параметры:

t – текущее время,

x – текущее положение системы,

flag – флаг, указывающий, какую функцию – f0 или f1 – вызывать для визуализации движения системы.

function Kadr(t,x,flag);

switch flag;

case 0;

f0(t,x); % Первоначальное построение (для t=0 с помощью программ line, plot, fill строится полностью графический образ)

case 1;

f1(t,x); % Построение переменной части (перерисовка).

otherwise

error('Негодный флаг= ',num2str(flag));

end;

Ниже приведен код функции f0 с комментариями. Данная функция определена в файле Kadr и предназначена для построения постоянной и переменной части графического образа системы в начальный момент времени. Постоянная часть изображения (в данном случае опора) не изменяется при движении системы в отличие от переменной части изображения (н-р, маятник, спиральная пружина).

function f0(t,x)

global r l e Wit r1 r2 x_op y_op text0 text1 text2 text3 xlm h_fig h_disk h_opor h_OC h_AB h_A h_B h_C h_spir h_txt

Создается графическое окно (figure) со следующими параметрами:

  • Position – положение верхнего левого угла, ширина и высота окна (измеряется в пикселях).

  • NumberTitle – флаг, определяющий будет ли название окна начинаться со строки «Figure».

  • Color – цвет фона, задается трехмерным вектором значений (от 0 до 1) интенсивности красной, зеленой и синей составляющих выбранного цвета (например, [1, 1, 0]) или предопределенным именем Matlab (например, ‘y’ или ‘yellow’).

  • Tag – название окна рисунка.

  • Resize – флаг, определяющий возможность изменения размера окна рисунка с помощью компьютерной мышки.

  • Name – название, отображаемое на окне рисунка.

h_fig=figure('Position',[50 50 800 600],...

'NumberTitle','off','Color',[1 1 1],'Tag','fig_Disk',...

'Resize','on','Name',text0);

Далее задается размер осей.

xlm=0.4;

xlim([-xlm xlm]) % Задание "размера" оси х

Чтобы исключить изменение масштаба изображения в ходе визуализации, необходимо нарисовать линии.

line([-xlm xlm],[0 0],'LineWidth',1,'Color','w');

line([0 0],[-xlm xlm],'LineWidth',1,'Color','w');

Задание. Попробуйте запустить программу без отрисовки этих линий. Как изменяется изображение? Чем объясняется это изменение?

В переменную text2 сохраняется текущее значение переменной t (время):

text1='t= '; text2=num2str(t); text3=' sec';

Отображение на экране счетчика времени определяется следующими параметрами:

  1. координатами (xlm*0.7,-xlm*0.9) текстовой строки;

  2. вектором строк ([text1,text2,text3]), содержащих значение текущего момента времени;

  3. цветом фона – значением свойства 'BackgroundColor' (в данном примере оно равно [.7 .9 .7]).

h_txt=text(xlm*0.7,-xlm*0.9,[text1,text2,text3],...

'BackgroundColor',[.7 .9 .7]);

Устанавливаются свойства текущих осей:

set(gca,'Tag','Osi')

set(gca,'ActivePositionProperty','position')

set(gca,'Box','off')

set(gca,'XColor','w') % Оси x назначается белый цвет

set(gca,'YColor','w') % Оси y назначается белый цвет

Предотвращение искажения размеров по направлениям осей x, y:

axis('equal')

В дальнейшем выводимые изображения необходимо добавлять к текущему:

hold on;

fi=x(1); tet=x(2); % Начальное значение fi,tet

sfi=sin(fi);cfi=cos(fi);

stet=sin(tet);ctet=cos(tet);

Далее происходит отрисовка диска с использование описанного во второй главе примитива Okr_.

xC=-e*sfi; % Координаты центра диска

yC=e*cfi; % Координаты центра диска

[x_,y_]=Okr_(xC,yC,r);

h_disk=line(x_,y_,'LineWidth',4,'Color','r');

С помощью соответствующего примитива изображается неподвижная опора.

xo=0; yo=0; % Координаты центра шарнира

a=0.04; % Боковая сторона треугольника

h=a*sqrt(3)/2; % Высота треугольника

fi_=0; % Угловое положение треугольника

str=a/4; % Длина штриха

[x_op,y_op]=Opora_(xo,yo,a,h,fi_,str);

h_opor=line(x_op,y_op,'LineWidth',2,'Color','k');

hold on;

Отрисовывается отрезок OC

h_OC=line([0 xC],[0 yC],'LineWidth',2,'Color','k');

С использованием маркера '.' указывается центр диска:

h_C=line(xC,yC, 'Marker','.','MarkerSize',20,'Color','k');

hold on;

Далее на рисунок добавляется отрезок AB.

xA=xC-r*cfi; yA=yC-r*sfi;

xB=xA+l*stet; yB=yA-l*ctet;

h_AB=line([xA xB],[yA yB],'LineWidth',2,'Color','c');

Маркер 'o' используется для построения небольшого круга в точке A:

h_A=line(xA,yA, 'Marker','o','MarkerSize',6,'Color','k','LineWidth',2);

Для изображения груза B использован маркер '.':

h_B=line(xB,yB, 'Marker','.','MarkerSize',40,'Color','r');

hold on;

Наконец, с использованием примитива строится спиральная пружина. В качестве параметров функции Spiral_ передаются глобальные переменные r1,r2,fi1,fi2 (полярные координаты концов спиральной пружины) и Wit (количество витков), заданные в скрипте Param.

fi1=0; fi2=fi+pi/2;

[x_,y_]=Spiral_(r1,r2,fi1,fi2,Wit);

h_spir=line(x_,y_,'LineWidth',1,'Color','k');

Для перерисовки только переменной части изображения используется функция f1. Такой подход позволяет ускорить показ кадров по сравнению с полной перерисовкой всего изображения. Осуществляется частичная перерисовка изменением свойств существующих графических объектов с помощью стандартной функции set.

function f1(t,x)

global r l e t_pause Wit r1 r2 x_op y_op

global h_disk h_opor h_OC h_AB h_A h_B h_C h_spir h_txt text1 text2 text3 xlm

fi=x(1); tet=x(2); % Текущее значение fi,tet

sfi=sin(fi);cfi=cos(fi);

stet=sin(tet);ctet=cos(tet);

Высчитываются координаты объектов, которые изменили положение (диск, отрезок AB, спиральная пружина), для текущего момента времени.

% Диск

xC=-e*sfi; % Координаты центра диска

yC=e*cfi; % Координаты центра диска

[x_disk,y_disk]=Okr_(xC,yC,r);

%% Отрезок AB

xA=xC-r*cfi; yA=yC-r*sfi;

xB=xA+l*stet; yB=yA-l*ctet;

% Спиральная пружина

fi1=0; fi2=fi+pi/2; % Wit=3;

[x_sp,y_sp]=Spiral_(r1,r2,fi1,fi2,Wit);

На экране обновляется счетчик целых значений переменной t:

if round(t)-t==0

delete(h_txt);

text2=num2str(t);

h_txt=text(xlm*0.7,-xlm*0.9,[text1,text2,text3],...

'BackgroundColor',[.7 .9 .7] ); %Координаты показа t=

end;

Следующей командой регулируется ускорение (замедление) показа движения системы:

pause(t_pause); % Ускорение/замедление показа

Необходимо присвоить новые значения координат x, y соответствующим свойствам существующих объектов.

set(h_disk,'XData',x_disk);

set(h_disk,'YData',y_disk);

set(h_opor,'XData',x_op);

set(h_opor,'YData',y_op);

set(h_spir,'XData',x_sp);

set(h_spir,'YData',y_sp);

set(h_A,'XData',xA);

set(h_A,'YData',yA);

set(h_B,'XData',xB);

set(h_B,'YData',yB);

set(h_C,'XData',xC);

set(h_C,'YData',yC);

set(h_OC,'XData',[0 xC]);

set(h_OC,'YData',[0 yC]);

set(h_AB,'XData',[xA xB]);

set(h_AB,'YData',[yA yB]);

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]