Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Алгоритмы управления движущимся объектом

В качестве примера решим задачу, поставленную в п. 2.1.3. На форму Form1 необходимо поместить объекты Shape1 и Shape2, таймер Timer1 и 6 кнопок управления механизмами. Вид получившейся формы представлен на рисунке 2.4. Размеры Shape1 и Shape2 не имеют значения, так как в программе будет произведено их масштабирование.

Свойство Timer.Enabled необходимо выставить равным True, а свойство Form1.BorderStyle, равным bsSingle для предотвращения изменения размера формы самим пользователем.

 

Shape1
Shape2
Timer1
Button1
Button2
Button3
Button4
Button5
Button6

Рисунок 2.4 – Вид формы

 

Для того, чтобы решить задачу, поставленную в п. 2.1.3, необходимо организовать две математические модели для каждого механизма в отдельности. Параметры этих моделей организуем в записи (структуры). На языке Pascal:

 

type TMeh1 = record

Nx: shortint; // задание направления движения по оси x

      // (-1 - влево, 0 - стоп,+1 - вправо)

Ny: shortint; // задание направления движения по оси y

      // (-1 – вверх, 0 - стоп,+1 - вниз)

vx: real; // скорость по оси x

vy: real; // скорость по оси y

x1: real; // положение по оси x

y1: real; // положение по оси y

end;

 

type TMeh2 = record

Ny: shortint; // задание направления движения по оси y

      // (-1 – вверх, 0 - стоп,+1 - вниз)

vy: real; // скорость по оси y

y2: real; // положение по оси y

end;

 

Две глобальные переменные типа TMeh1 и TMeh2 будут являться математическими моделями механизма 1 и 2 соответственно:

var

Meh1: TMeh1;

Meh2: TMeh2;

D: real;

LeftMin, TopMin:integer;

 

Глобальная переменная D будет хранить итоговый масштаб пересчета метров в пиксели (2.2). Переменные LeftMin и LeftMax определяют минимальные расстояния до объекта Shape1, отображающее поведение механизма 1 (формула 2.3).

Ускорения, максимальные перемещения механизмов, максимальные скорости перемещения и геометрические размеры механизмов зададим в виде констант:

 

const

L = 10; // перемещение по горизонтали механизма 1, м

H = 5; // перемещение по горизонтали механизма 1, м

d1 = 1; // горизонтальный размер механизма 1, м

d2 = 0.7; // горизонтальный размер механизма 2, м

h1 = 3; // вертикальный размер механизма 1, м

h2 = 1; // вертикальный размер механизма 2, м

a1max = 1.5; // ускорение перемещения механизма 1, м/с2

a2max = 4; // ускорение перемещения механизма 2, м/с2

v1ust = 1; // установившаяся скорость механизма 1, м/с

v2ust = 0.6; // установившаяся скорость механизма 2, м/с

 

Начальные условия прописываются в обработчике событий «OnCreate» формы. Там же происходит вычисление масштаба D и определение размеров объектов Shape1 и Shape2.

 

procedure TForm1.FormCreate(Sender: TObject);

var

Xmax, Ymax, Dx, Dy: real;

begin

// начальные условия механизма 1

Meh1.Nx:=0;

Meh1.Ny:=0;

Meh1.vx:=0;

Meh1.vy:=0;

Meh1.x1:=0;

Meh1.y1:=0;

// начальные условия механизма 2

Meh2.Ny:=0;

Meh2.vy:=0;

Meh2.y2:=0;

// Вычисление масштаба отображения

Xmax:=L+d1+d2;

Ymax:=H+h1;

Dx:=(90-10)/100*Form1.ClientWidth/Xmax;

Dy:=(70-10)/100*Form1.ClientHeight/Ymax;

if (Dy>Dx) then

begin

D:=Dx;

end

else

begin

D:=Dy;

end;

// изменение размеров Shape

Shape1.Width:=round(D*d1);

Shape1.Height:=round(D*h1);

Shape2.Width:=round(D*d2);

Shape2.Height:=round(D*h2);

// Определение левой и верхней границы перемещения

LeftMin:=round(10/100*Form1.ClientWidth);

TopMin:=round(10/100*Form1.ClientHeight);

// отображение объектов Shape на форме

Risovanie();   

end;

 

Необходимо отметить, что для вычисления некоторых параметров объектов Shape и переменных LeftMin и TopMin целого типа применяется встроенная функция round(), которое округляет десятичные дроби до целого значения.

Для отображения Shape на форме согласно математическим моделям определим пользовательскую процедуру Risovanie, которая вычисляет формулы (2.3) и (2.4). Саму процедуру необходимо поместить впереди обработчика события Form1.OnCreate. Вызов же самой функции помещается в конце обработчика данного события (см. листинг выше).

 

procedure Risovanie();

begin

Form1.Shape1.Left:=round(D*Meh1.x1+LeftMin);

Form1.Shape1.Top:=round(D*Meh1.y1+TopMin);

Form1.Shape2.Left:=round(D*(Meh1.x1+d1)+LeftMin);

Form1.Shape2.Top:=round(D*(Meh1.y1+Meh2.y2)+TopMin);

end;

 

Для моделирования перемещения механизмов только при нажатии соответствующих кнопок, используем событие «OnMouseDown» для обработки именно нажатия кнопки, и событие «OnMouseUp» для обработки отпускания кнопки. В первом типе обработчиков необходимо задать направление движения (переменные Meh1.Nx, Meh1.Ny, Meh2.Ny), а во вторых событиях обнулить управляющие переменные. Листинг обработчиков этих событий показан ниже:

 

procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Meh1.Nx:=+1; // движение механизма 1 вправо

end;

 

procedure TForm1.Button2MouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Meh1.Nx:=-1; // движение механизма 1 влево

end;

 

procedure TForm1.Button3MouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Meh1.Ny:=-1; // движение механизма 1 вверх

end;

 

procedure TForm1.Button4MouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Meh1.Ny:=+1; // движение механизма 1 вниз

end;

 

procedure TForm1.Button5MouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Meh2.Ny:=-1; // движение механизма 2 вверх

end;

 

procedure TForm1.Button6MouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Meh2.Ny:=+1; // движение механизма 2 вниз

end;

 

procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Meh1.Nx:=0; // остановка механизма 1

end;

 

procedure TForm1.Button2MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Meh1.Nx:=0; // остановка механизма 1

end;

 

procedure TForm1.Button3MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Meh1.Ny:=0; // остановка механизма 1

end;

 

procedure TForm1.Button4MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Meh1.Ny:=0; // остановка механизма 1

end;

 

procedure TForm1.Button5MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Meh2.Ny:=0; // остановка механизма 2

end;

 

procedure TForm1.Button6MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Meh2.Ny:=0; // остановка механизма 2

end;

 

В обработчике события «OnTimer» объекта Timer1 необходимо реализовать алгоритм движения механизмов с учетом ускорения, замедления, ограничения максимальных перемещений и управляющих переменных.

Диаграмма движения механизма 1 по оси x представлена на рисунке 2.5. При нажатии на кнопку управляющая переменная Nx выставляется равным +1. После этого ускорение принимается равное a1max. Начинается равноускоренное движение с возрастающей скоростью. При достижении скорости значения v1ust, ускорение принимается равное 0 и механизм 1 движется с постоянной скоростью. После отпускания кнопки переменная Nx становится равной 0, знак ускорения принимается обратным знаку скорости. В последствии скорость уменьшается до значения, близкого к нулю и механизм останавливается. Алгоритм программы движения по оси x приведен на рисунке 2.6.

Нажатие кнопки
Отпускание кнопки
Meh1.Nx = +1
Meh1.Nx = 0
 a = +a1max
 a = 0
 a = -a1max
v = +v1ust
 t
Рисунок 2.5 – Диаграмма движения

 

 
Начало
 
Meh1.Nx = 0
 да
 нет
 Кнопка нажата
 
Meh1.Nx = +1
 да
 нет
 вправо
 влево
a:= +a1max
a:= -a1max
 
Meh1.vx >= v1ust
 нет
 да
a:= 0
 
Meh1.vx <= -v1ust
 нет
 да
a:= 0
 Ограничение скорости
 
 нет
 да
a:= 0 Meh1.vx:=0
 Ограничение положения слева и справа с учетом заданного направления
2
1
 Кнопка отпущена
3
 на след. стр.
1
2
3
4
5
6
7
8
 ((Meh1.x1>=L) and (Meh1.Nx>=0)) or ((Meh1.x1<=0) and (Meh1.Nx<=0))

 
2
Meh1.vx:=Meh1.vx + a∙∆t Meh1.x1:=Meh1.x1 + Meh1.vx ∙∆t
 Решение дифференциальных уравнений
 Алгоритм движения   механизма 1 по оси y
 Алгоритм движения   механизма 2 по оси y
Risovanie();
 Изменение положения Shape на форме
 
Конец
 
2
 Ветка алгоритма, когда кнопка отпущена
 
 
Meh1.vx > 0
 да
 нет
 вправо
 влево
a:= -a1max
a:= +a1max
 
Meh1.vx <= 0.01×v1ust
 нет
 да
a:= 0 Meh1.vx:=0
 
Meh1.vx >= -0.01×v1ust
 нет
 да
a:= 0 Meh1.vx:=0
 
3

Рисунок 2.6 – Алгоритм управления движением

 

Алгоритм движения по другим осям будет аналогичным с учетом ограничений движения механизма 1 по оси y 0<Meh1.y1<H и механизма 2 по оси y 0<Meh2.y2<h1.

Алгоритм, приведенный на рисунке 2.6, достаточно сложный для реализации в программе вследствие многочисленных ветвлений. Для того, чтобы не запутаться при реализации программы необходимо правильно устанавливать отступы, показывая вложения команд, и не забывать сразу прописывать обе ветки ветвления. Для примера приведена последовательность написания программы для блоков 1-9 (рисунок 2.6).

1. Установка шаблона обработчика события «OnTimer». Выбрать объект «Timer1» на форме. В инспекторе объектов выбрать вкладку «Events». Два раза кликнуть левой кнопкой мыши на строчку «OnTimer»:

 

procedure TForm1.Timer1Timer(Sender: TObject);

begin

 

end;

 

2. Объявление локальной переменной «a»:

 

procedure TForm1.Timer1Timer(Sender: TObject);

var

a:real;

begin

 

end;

 

3. Блок сравнения 1 (рисунок 2.6). Сразу необходимо прописать заготовки двух веток «begin-end» через else. Одинаковыми отступами показываем, что обе ветки имеют одинаковую вложенность.

 

procedure TForm1.Timer1Timer(Sender: TObject);

var

a:real;

begin

if Meh1.Nx=0 then

begin // кнопка отпущена

end

else

begin // кнопка нажата

end;

end;

 

4. Блок сравнения 2 реализуется в ветке, когда кнопка нажата. Отступом показываем, что этот блок вложен в предыдущий.

 

begin

if Meh1.Nx=0 then

begin // кнопка отпущена

end

else

begin // кнопка нажата

if Meh1.Nx=+1 then

begin // да

end

  else

begin // нет

end;

end;

end;

 

6. Блок вычисления ускорения 3, блок сравнения 4 и блок обнуления ускорения 5:

 

begin

if Meh1.Nx=0 then

begin // кнопка отпущена

end

else

begin // кнопка нажата

if Meh1.Nx=+1 then

begin // да

end

  else

begin // нет

a:=-a1max;

if Meh1.vx<=-v1ust then

begin // да

   a:=0;

end; { // пустую ветку else можно не писать

   else

begin // нет

end; }

end;

end;

end;

 

7. Блок вычисления ускорения 6, блок сравнения 7 и блок обнуления ускорения 8:

 

begin

if Meh1.Nx=0 then

begin // кнопка отпущена

end

else

begin // кнопка нажата

if Meh1.Nx=+1 then

begin // да

a:=+a1max;

if Meh1.vx>=v1ust then

begin // да

   a:=0;

end;

end

  else

begin // нет

a:=-a1max;

if Meh1.vx<=-v1ust then

begin // да

   a:=0;

end; { // пустую ветку else можно не писать

   else

begin // нет

end; }

end;

end;

end;

 

Аналогично оформляем остальные ветки алгоритма. Для движения по оси x программа будет выглядеть следующим образом:

 

begin

  if Meh1.Nx=0 then

begin // кнопка отпущена

if Meh1.vx>0 then

begin // да вправо

a:=-a1max;

if Meh1.vx<=0.01*v1ust then

begin // да

   a:=0;

   Meh1.vx:=0;

end;

end

  else

begin // нет влево

 a:=+a1max;

if Meh1.vx>=-0.01*v1ust then

begin // да

   a:=0;

   Meh1.vx:=0;

end;

end;

end

else

begin // кнопка нажата

if Meh1.Nx=+1 then

begin // да

a:=+a1max;

if Meh1.vx>=v1ust then

begin // да

   a:=0;

end;

end

  else

begin // нет

a:=-a1max;

if Meh1.vx<=-v1ust then

begin // да

   a:=0;

end; { // пустую ветку else можно не писать

   else

begin // нет

end; }

end;

end;

// ограничение положения слева и справа

if ((Meh1.x1>=L) and (Meh1.Nx>=0)) or ((Meh1.x1<=0) and (Meh1.Nx<=0)) then

begin // да

a:=0;

Meh1.vx:=0;

end;

// решение дифф. уравнений по оси x механизма 1

Meh1.vx:=Meh1.vx + a*0.01;

  Meh1.x1:=Meh1.x1 + Meh1.vx*0.01;

 

 

// Изменение положения Shape на форме

Risovanie();

end;

 

Можно запустить программу и убедиться в работоспособности перемещения механизма 1 влево и вправо с ускорением.

Полный листинг обработчика события «OnTimer» с обработкой всех перемещений:

 

procedure TForm1.Timer1Timer(Sender: TObject);

var

a:real;

begin

if Meh1.Nx=0 then

begin // кнопка отпущена

if Meh1.vx>0 then

begin // да вправо

a:=-a1max;

if Meh1.vx<=0.01*v1ust then

begin // да

   a:=0;

   Meh1.vx:=0;

end;

end

  else

begin // нет влево

a:=+a1max;

if Meh1.vx>=-0.01*v1ust then

begin // да

   a:=0;

   Meh1.vx:=0;

end;

end;

end

else

begin // кнопка нажата

if Meh1.Nx=+1 then

begin // да

a:=+a1max;

if Meh1.vx>=v1ust then

begin // да

   a:=0;

end;

end

  else

begin // нет

a:=-a1max;

if Meh1.vx<=-v1ust then

begin // да

   a:=0;

end; { // пустую ветку else можно не писать

   else

begin // нет

end; }

end;

end;

// ограничение положения слева и справа

if ((Meh1.x1>=L) and (Meh1.Nx>=0)) or ((Meh1.x1<=0) and (Meh1.Nx<=0)) then

begin // да

a:=0;

Meh1.vx:=0;

end;

// решениe дифф. уравнений по оси x механизма 1

Meh1.vx:=Meh1.vx + a*0.01;

Meh1.x1:=Meh1.x1 + Meh1.vx*0.01;

// -------------------- Механизм 1 по оси y -----------------------------------

if Meh1.Ny=0 then

begin // кнопка отпущена

if Meh1.vy>0 then

begin // да

a:=-a1max;

if Meh1.vy<=0.01*v1ust then

begin // да

   a:=0;

   Meh1.vy:=0;

end;

end

  else

begin // нет

a:=+a1max;

if Meh1.vy>=-0.01*v1ust then

begin // да

   a:=0;

   Meh1.vy:=0;

end;

end;

end

else

begin // кнопка нажата

if Meh1.Ny=+1 then

begin // да

a:=+a1max;

if Meh1.vy>=v1ust then

begin // да

   a:=0;

end;

end

  else

  begin // нет

a:=-a1max;

if Meh1.vy<=-v1ust then

begin // да

   a:=0;

end;

end;

end;

// ограничение положения слева и справа

if ((Meh1.y1>=H) and (Meh1.Ny>=0)) or ((Meh1.y1<=0) and (Meh1.Ny<=0)) then

begin // да

a:=0;

Meh1.vy:=0;

end;

// решениe дифф. уравнений по оси y механизма 1

Meh1.vy:=Meh1.vy + a*0.01;

Meh1.y1:=Meh1.y1 + Meh1.vy*0.01;

// -------------------- Механизм 2 по оси y -----------------------------------

if Meh2.Ny=0 then

begin // кнопка отпущена

if Meh2.vy>0 then

begin // да

a:=-a2max;

if Meh2.vy<=0.01*v2ust then

begin // да

   a:=0;

   Meh2.vy:=0;

end;

end

  else

begin // нет

a:=+a2max;

if Meh2.vy>=-0.01*v2ust then

begin // да

   a:=0;

   Meh2.vy:=0;

end;

end;

end

else

begin // кнопка нажата

if Meh2.Ny=+1 then

begin // да

a:=+a2max;

if Meh2.vy>=v2ust then

begin // да

   a:=0;

end;

end

  else

begin // нет

a:=-a2max;

if Meh2.vy<=-v2ust then

begin // да

   a:=0;

end;

end;

end;

// ограничение положения слева и справа

if ((Meh2.y2>=(h1-h2)) and (Meh2.Ny>=0)) or ((Meh2.y2<=0) and (Meh2.Ny<=0)) then

begin // да

a:=0;

Meh2.vy:=0;

end;

// решениe дифф. уравнений по оси y механизма 1

Meh2.vy:=Meh2.vy + a*0.01;

Meh2.y2:=Meh2.y2 + Meh2.vy*0.01;

 

// Изменение положения Shape на форме

Risovanie();

end;

 



<== предыдущая лекция | следующая лекция ==>
Расчет координат связанных объектов | Федеральная служба исполнения наказаний
Поделиться с друзьями:


Дата добавления: 2018-10-15; Мы поможем в написании ваших работ!; просмотров: 202 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Свобода ничего не стоит, если она не включает в себя свободу ошибаться. © Махатма Ганди
==> читать все изречения...

2368 - | 2116 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.014 с.