
- •Моделирование движения голономных механических систем в пакете Matlab
- •Введение
- •Основы программирования в системе Matlab
- •Работа с матрицами
- •Построение графиков
- •Дескрипторная графика [2] Графические объекты
- •Использование дескрипторов объектов
- •Функции для работы с графическими объектами
- •Установка свойств объекта
- •Определение осей или рисунка
- •Нахождение дескрипторов существующих объектов
- •Скрипты и функции
- •Полезные команды
- •Решение систем дифференциальных уравнений
- •Визуализация движения в Матлабе
- •Библиотека примитивов
- •Окружность
- •Заштрихованная кривая
- •Спираль
- •Пружина
- •Примеры моделирования голономных систем Диск с маятником
- •Визуализация динамики механической системы.
- •Уравнения равновесия системы
- •Динамические эффекты на примере диска с маятником
- •Цилиндр, катающийся в подвижном желобе
- •Заключение
- •Литература
Уравнения равновесия системы
Рассмотрим исходный код программы, предназначенной для:
нахождения положения равновесия,
линеаризации дифференциальных уравнений в окрестности найденного положения равновесия,
составления характеристического уравнения
нахождения его корней.
Для работы программы необходимо:
запрограммировать с применением символьных вычислений дифференциальные уравнения в функции sys=Difur() (см. ниже);
выполнить программу для получения уравнений равновесия в командном окне;
скопировать их из командного окна в функцию F = Ur_rav(q);
повторно выполнить программу.
Для инициализации глобальных величин в этом примере (см. global ниже) необходимо выполнить рассмотренный в предыдущем разделе скрипт Param.
Код программы:
function Lin_rav_kor
syms q1 q2 q1t q2t q1tt q2tt X t
global q00 % Значение по умолчанию
disp([pwd,'\Lin_rav_kor']); % pwd - текущая директория (папка)
God_date_time=fix(clock)
disp('А ты присвоил числовые значения глобальным величинам ?');
disp(' ');
disp(...
'Для присвоения надо перед ПЕРВЫМ выполнением этой программы 1 раз за сеанс')
disp(' выполнить Param_2');
disp(' ');
SW=input(...
'Для выполнения программы Param_2 введи 1,иначе - другой символ : ');
if SW==1
Param_2;
end;
disp(' ');
disp('Для получения уравнений равновесия введи 1 , если уравнения ');
SW=input(...
'равновесия уже занесены в Ur_rav(q), введи другой символ : ');
if isempty(SW)
SW=2;
end;
sys=Difur(); % Получение левых частей уравнений (прав. части равны нулю)
disp(' ');
Алгебраические уравнения для нахождения положений равновесия получаются подстановкой в дифференциальные уравнения нулевых скоростей и ускорений.
disp('Т.к. автоматически передать УРАВНЕНИЯ РАВНОВЕСИЯ в функцию Ur_rav ')
disp('не удается, их следует заносить в эту прог. вручную')
disp(' из командного окна посредством (Ctr/C, Ctr/V)')
disp('Надо также удалить из уравнений члены (силы и моменты),')
disp('явно зависящие от времени.')
disp(' ');
sys_rav=subs(sys,{q1,q2,q1t,q2t,q1tt,q2tt},{'q(1)','q(2)',0,0,0,0});
disp('УРАВНЕНИЯ РАВНОВЕСИЯ :')
disp(sys_rav);
disp(...
'После занесения уравнений равновесия в функцию Ur_rav (см. конец программы)')
disp(' повторно запустить программу')
if SW==1 return,end; % Остановка вычислений при отсутствии уравнений равновесия
% q0 = [0.3; 0.1]; % Стартовые значения обобщенных координат при нахождении
% корней системы уравнений равновесия
disp(...
'Для численного решения уравнений равновесия необходимо указать стартовую точку')
disp(...
'(2 числа), начиная с которой итерациями ищется решение.')
disp(' ')
disp(...
'Для нахождения стартовой точки можно использовать линиями уровня уравнений системы')
disp(' ');
SW=input(...
'Если хочешь построить линии уровня введи 1 , иначе - другой символ : ');
if SW==1
Level_line;
disp(...
'Определив визуально стартовые точки, запомни их и повторно запусти головную программу.')
SW=input('Нажми Ввод');
return;
end;
inp=input(...
'Введи стартовые значения (например, 0.3 0.1 ) : ','s'); %Ввод без [ ]
if isempty(inp)
q0=q00;
else
q0=str2num(inp)';
q00=q0;
end;
options=optimset('Display','off'); % Показ хода решения 'iter'
[q,fval] = fsolve(@Ur_rav,q0,options); % Call optimizer
% format long
q10=q(1); q20=q(2);
disp(' ')
disp([...
'Положение равновесия : q10 = ',num2str(q(1)),' , q20 = ',num2str(q(2)) ]);
disp(' ')
Далее линеаризуются уравнения движения в окрестности положения равновесия:
q1t='q1t'; % Освобождение переменных
q2t='q2t';
q1tt='q1tt';
q2tt='q2tt';
A1=diff(sys,q1tt); % Производная по обобщенному ускорению d2q1/dt^2
B1=diff(sys,q1t); % Производная по обобщенной скорости dq1/dt
C1=diff(sys,q1); % Производная по обобщенной координате q1
A2=diff(sys,q2tt);% Производная по обобщенному ускорению d2q2/dt^2
B2=diff(sys,q2t); % Производная по обобщенной скорости dq2/dt
C2=diff(sys,q2); % Производная по обобщенной координате q2
Вычисляются значения производных в положении равновесия:
A10=vpa(subs(A1,{q1,q2,q1t,q2t,q1tt,q2tt},{q10,q20,0,0,0,0}),6);
B10=vpa(subs(B1,{q1,q2,q1t,q2t,q1tt,q2tt},{q10,q20,0,0,0,0}),6);
C10=vpa(subs(C1,{q1,q2,q1t,q2t,q1tt,q2tt},{q10,q20,0,0,0,0}),6);
ABC1=[A10 B10 C10];
ABC1_=vpa(ABC1*[X^2;X;1],6);
ABC1__=vpa(ABC1*[q1tt;q1t;q1],6);
A20=vpa(subs(A2,{q1,q2,q1t,q2t,q1tt,q2tt},{q10,q20,0,0,0,0}),6);
B20=vpa(subs(B2,{q1,q2,q1t,q2t,q1tt,q2tt},{q10,q20,0,0,0,0}),6);
C20=vpa(subs(C2,{q1,q2,q1t,q2t,q1tt,q2tt},{q10,q20,0,0,0,0}),6);
ABC2=[A20 B20 C20];
ABC2__=vpa(ABC2*[q2tt;q2t;q2],6);
disp ('Линеаризованная в окрестности положения равновесия система диф.');
disp('уравнений (без сил и моментов, явно зависящих от времени) :')
ABC__=[ABC1__ ABC2__];
disp(ABC__);
% ABC=[ABC1 ABC2]
ABC2_=vpa(ABC2*[X^2;X;1],6);
ABC_=[ABC1_ ABC2_];
disp('Характеристическое уравнение линеаризованной системы :')
XAR_ur=det(ABC_);
disp(vpa(XAR_ur,6));
X=solve(XAR_ur,X);
disp(' ')
disp(' Корни характеристического уравнения :')
disp (vpa(X,6))
disp('====================');
В вышерассмотренной программе используются три вспомогательные функции –Difur, Ur_rav, Level_line. Функция Difur предназначена для получения системы двух уравнений в символьном виде. Выходными параметрами этой функции являются левые части дифференциальных уравнений в символьном виде, выраженные
через q1,q2,q1t,q2t,q1tt,q2tt и глобальные величины.
function sys=Difur()
global m1 m2 r l c e M0 p p0 gam
g=9.8; % м/сек
syms d2fi dfi fi_ d2tet dtet tet t ...
q1 q2 q1t q2t q1tt q2tt
% Удобнее сначала записать уравнения движения в содержательных обозначениях,
% а затем заменить общепринятыми q1,q2,q1t,q2t,q1tt,q2tt
alf=fi_-tet -pi/6;
ur1=(5/6*m1+4/3*m2)*r^2*d2fi +2*m2*l*e*(sin(alf)*d2tet-cos(alf)*dtet^2)...
- (m1*sin(fi_)+2*m2*cos(fi_-pi/6))*e*g+c*fi_ ...
-M0*sin((p*t+p0)*t+gam); % Первое уравнение (левая часть)
ur2=2*e*(sin(alf)*d2fi+dfi^2*cos(alf))+l*d2tet+g*sin(tet); % Второе уравнение
sys1=[ur1;ur2]; % Система 2-х ур-ий
% Переход к q1,q2,q1t,q2t,q1tt,q2tt :
sys=subs(sys1,{fi_,tet,dfi,dtet,d2fi,d2tet},{q1,q2,q1t,q2t,q1tt,q2tt});
Во вспомогательную функцию Ur_rav необходимо записать уравнения равновесия без учета членов, явно зависящих от времени, по шаблону F=[ уравнение равновесия 1 ; уравнение равновесия2];
function F = Ur_rav(q)
F = [ (39*q(1))/20 - (49*3^(1/2)*((2*cos(q(1) - pi/6))/5 + sin(q(1))))/75;
(49*sin(q(2)))/5];
Функция Level_line предназначена для построения поверхности по числовым значениям в узлах.
function Level_line
limx=[-5,5]; limy=[-5,5]; % Границы области построения линий уровня
stepx=0.1; stepy=0.1; % Шаг сетки по x и по y
x=limx(1) : stepx : limx(2); % сетка по x
y=limy(1) : stepy : limy(2); % сетка по y
[x_,y_]=meshgrid(x,y); % Вспомогательные матрицы для программ 3D-графики
% Вычисление ф-ции в узлах :
lenx=length(x);
leny=length(y);
for i= 1:lenx
for j= 1:leny
q=[x(i),y(j)];
F = Ur_rav(q);
z1(i,j)=F(1); % Первое уравнение равновесия (по столбцам, как в форт. )
z2(i,j)=F(2); % Второе уравнение равновесия (по столбцам, как в форт. )
end; end;
mesh(x_,y_,z1); % График левой части первого уравнения равновесия
set(gca,'FontName','MS Sans Serif'); % Установка подходящего шрифта
title('Зависимость левой части 1-го ур-ия от q1,q2')
xlabel('q1')
ylabel('q2')
zlabel('f1')
figure
[C,h] = contour(x_,y_,z1); % Линии уровня левой части 1-го уравнения равновесия
set(gca,'FontName','MS Sans Serif'); % Установка подходящего шрифта
set(h,'ShowText','on')
colormap cool
title('Линии уровня левой части 1-го ур-ия')
figure
mesh(x_,y_,z2); % График левой части 2-го уравнения равновесия
set(gca,'FontName','MS Sans Serif'); % Установка подходящего шрифта
title('Зависимость левой части 2-го ур-ия от q1,q2')
xlabel('q1')
ylabel('q2')
zlabel('f2')
figure
[C,h] = contour(x_,y_,z2); % Линии уровня левой части 2-го уравнения равновесия
set(gca,'FontName','MS Sans Serif'); % Установка подходящего шрифта
title('Линии уровня левой части 2-го ур-ия')
set(h,'ShowText','on')
colormap cool
set(gca,'FontName','MS Sans Serif'); % Установка подходящего шрифта