- •Моделирование движения голономных механических систем в пакете Matlab
- •Введение
- •Основы программирования в системе Matlab
- •Работа с матрицами
- •Построение графиков
- •Дескрипторная графика [2] Графические объекты
- •Использование дескрипторов объектов
- •Функции для работы с графическими объектами
- •Установка свойств объекта
- •Определение осей или рисунка
- •Нахождение дескрипторов существующих объектов
- •Скрипты и функции
- •Полезные команды
- •Решение систем дифференциальных уравнений
- •Визуализация движения в Матлабе
- •Библиотека примитивов
- •Окружность
- •Заштрихованная кривая
- •Спираль
- •Пружина
- •Примеры моделирования голономных систем Диск с маятником
- •Визуализация динамики механической системы.
- •Уравнения равновесия системы
- •Динамические эффекты на примере диска с маятником
- •Цилиндр, катающийся в подвижном желобе
- •Заключение
- •Литература
Примеры моделирования голономных систем Диск с маятником
Однородный
диск массы
и радиуса
может вращаться вокруг горизонтальной
оси O,
расположенной на расстоянии
от центра масс. Спиральная пружина
жесткости c
соединяет диск с неподвижной осью. К
диску с помощью шарнира A
подвешен невесомый стержень длины
с точечным грузом B
массы
,
причем
.
Уравнения движения Лагранжа 2-го рода имеют вид:
Заданы численные значения параметров и начальных условий:
|
|
|
|
|
|
|
|
|
|
|
|
Для рассматриваемой голономной механической системы в качестве обобщенных координат приняты x, φ.
Визуализация динамики механической системы.
Далее рассматривается программа, которая будет производить следующие действия:
запрашивать у пользователя данные о численных параметрах системы и начальных условиях;
интегрировать заданные уравнения движения при введенных начальных условиях;
строить фазовые портреты;
визуализировать динамику системы.
Указанная программа состоит из нескольких файлов: 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';
Отображение на экране счетчика времени определяется следующими параметрами:
координатами (xlm*0.7,-xlm*0.9) текстовой строки;
вектором строк ([text1,text2,text3]), содержащих значение текущего момента времени;
цветом фона – значением свойства '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]);

кг
м
м
кг
Нм
рад
рад
с-1
м/с