Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Модель манипулятора робота




Манипулятор робота на экране изображается в виде нескольких каркасных параллелепипедов (по одному для каждого сегмента манипулятора – "плечо", "локоть", "кисть", "пальцы"). Предполагается, что в местах соединения сегментов расположены шарниры и сегменты могут вращаться вокруг них. На рис. 2.2 и рис. 2.3 показаны манипуляторы с разным количеством сегментов.

 

   
Рис. 2.2.Двухсегментный манипулятор. Рис. 2.3.Манипулятор из 10 сегментов (плечо, локоть и 4 пальца).

 

Перед рисованием каждого сегмента надо выполнить модельное преобразование, обеспечивающее корректную ориентацию сегмента. При рисовании параллелепипеда его центр располагается в начале модельной системы координат, поэтому предварительно надо сместить модельную систему координат на половину длины сегмента. Если этого не сделать, то сегмент будет вращаться вокруг своего центра, а не вокруг шарнира.

После вызова glTranslated(), который задает положение шарнира, надо вызвать glRotated() для поворота сегмента. После этого надо выполнить перенос в обратном направлении для правильного позиционирования центра сегмента. В целом, для рисования одного сегмента надо вызвать следующие функции:

 

glTranslatef(-1.0, 0.0, 0.0);

glRotatef((float)shoulder_angle, 0.0, 0.0, 1.0);

glTranslatef(1.0, 0.0, 0.0);

auxWireBox(2.0, 0.4, 1.0);

 

Для рисования второго сегмента надо переместить модельную систему координат в позицию второго шарнира. Т.к. координатная система уже была повернута, то ось X направлена в направлении первого сегмента. Следовательно, для переноса модельной системы координат в точку второго шарнира надо произвести перенос вдоль оси X. После этого можно нарисовать второй сегмент (функциями, аналогичными использованным для рисования первого сегмента):

 

glTranslatef(1.0, 0.0, 0.0);

glRotatef((float)elbow_angle, 0.0, 0.0, 1.0);

glTranslatef(1.0, 0.0, 0.0);

auxWireBox(2.0, 0.4, 1.0);

 

Описанную процедуру можно продолжать повторять, чтобы нарисовать все сегменты манипулятора (плечо, локоть, кисть, пальцы). Рисование двух сегментов манипулятора с двумя степенями свободы показано в программе 2.3. Поворот сегментов осуществляется с помощью клавиш курсора.

 

#include <windows.h>

#include <GL/gl.h>

#include <GL/glu.h>

#include <GL/glaux.h>

 

void CALLBACK resize(int width, int height);

void CALLBACK display();

void CALLBACK elbowAdd();

void CALLBACK elbowSubtract();

void CALLBACK shoulderSubtract();

void CALLBACK shoulderAdd();

 

// Текущие углы поворота плеча и локтя

int shoulder = 0, elbow = 0;

 

void main()

{

// Создание экранного окна

auxInitDisplayMode(AUX_RGBA | AUX_DEPTH | AUX_DOUBLE);

auxInitPosition(50, 10, 400, 400);

auxInitWindow("Лекция 2, Программа 2.3");

 

// Включение ряда параметров OpenGL

glEnable(GL_ALPHA_TEST);

glEnable(GL_DEPTH_TEST);

glEnable(GL_COLOR_MATERIAL);

glEnable(GL_BLEND);

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glEnable(GL_LIGHTING);

 

// Включение максимального рассеянного освещения

float ambient[4] = { 1.0, 1.0, 1.0, 1 };

glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);

 

// Регистрация обработчиков событий

auxReshapeFunc(resize);

auxKeyFunc(AUX_LEFT, shoulderSubtract);

auxKeyFunc(AUX_RIGHT, shoulderAdd);

auxKeyFunc(AUX_UP, elbowAdd);

auxKeyFunc(AUX_DOWN, elbowSubtract);

 

// Вход в главный цикл GLAUX

auxMainLoop(display);

}

 

void CALLBACK resize(int width, int height)

{

glViewport(0, 0, width, height);

 

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluPerspective(60.0, (float)width/(float)height, 1.0, 20.0);

 

gluLookAt(0,0,10, 0,0,0, 0,1,0);

 

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

}

 

 

void CALLBACK display()

{

// Очистка буфера кадра

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 

glColor3f(1.0, 1.0, 1.0);

 

glPushMatrix();

glTranslatef(-1.0, 0.0, 0.0);

glRotatef((float)shoulder, 0.0, 0.0, 1.0);

glTranslatef(1.0, 0.0, 0.0);

auxWireBox(2.0, 0.4, 1.0); // плечо

 

glTranslatef(1.0, 0.0, 0.0);

glRotatef((float)elbow, 0.0, 0.0, 1.0);

glTranslatef(1.0, 0.0, 0.0);

auxWireBox(2.0, 0.4, 1.0); // локоть

glPopMatrix();

 

// Копирование содержимого буфера кадра на экран

glFlush();

auxSwapBuffers();

}

 

void CALLBACK elbowAdd()

{

elbow = (elbow + 5) % 360;

}

 

void CALLBACK elbowSubtract()

{

elbow = (elbow - 5) % 360;

}

 

void CALLBACK shoulderAdd()

{

shoulder = (shoulder + 5) % 360;

}

 

void CALLBACK shoulderSubtract()

{

shoulder = (shoulder - 5) % 360;

}

Программа 2.3. Модель манипулятора робота.

 

Сводка результатов

Для создания плавной анимации применяется метод "двойная буферизация". При этом используются два буфера кадра: один показывается на экране, а в другом, невидимом, выполняется рисование следующего кадра.

В макете консольной программы, написанной с помощью библиотеки GLAUX, используются функции обратной связи. Чаще всего это функция отображения сцены, фоновая функция и функция реакции на изменение размеров окна. Кроме того, можно определить функции-обработчики событий от клавиатуры и мыши.

При создании анимации с несколькими движущимися объектами важно правильно построить композицию преобразований модельной системы координат. В лекции приведены два примера подобных моделей.

 

Упражнения

Упражнение 1

Внесите в программу 2.1 изменения, описанные в п.2.1, чтобы по нажатию левой кнопки мыши менялся цвет вращающегося чайника.

Упражнение 2

В программу из упр.1 добавьте обработчик нажатия правой кнопки мыши для включения/выключения вращения. Сделайте обработчики для клавиш курсора "стрелка вверх" и "стрелка вниз" (коды клавиш AUX_LEFT и AUX_UP), чтобы увеличивать и уменьшать скорость вращения. С помощью обработчика клавиши "пробел" (код AUX_SPACE) обеспечьте циклическое переключение осей вращения между тремя координатными осями.

Подсказка: можно завести глобальную переменную-флаг, обозначающую, включено вращение или нет. Переключение флага следует выполнять в обработчике события. В зависимости от состояния флага в функции фоновой обработки должно или не должно выполняться увеличение угла поворота. Аналогичные приемы используйте при написании обработчиков остальных событий.

Упражнение 3

В программу 2.2 добавьте отображение спутника планеты и наклоните ось вращения планеты под углом 45 градусов к плоскости ее орбиты.

Упражнение 4

Сделайте вариант программы 2.2 с 4-мя планетами и 3-мя спутниками. Для сохранения/восстановления позиции и ориентации координатных систем пользуйтесь функциями glPushMatrix() и glPopMatrix(). Чтобы нарисовать несколько спутников у одной планеты, сохраняйте параметры координатной системы перед рисованием каждого спутника и восстанавливайте их после рисования спутника. Чтобы разобраться с положением координатных осей, можете применить функцию рисования осей из 4-го упражнения к 1-й лекции.

Упражнение 5

Измените программу 2.3 так, чтобы она рисовала манипулятор из 10-ти сегментами (рис. 2.3). Для поворота всех сегментов применяйте две клавиши курсора "стрелка вверх/вниз". Текущий сегмент (который будет поворачиваться этими клавишами) должен быть выделен цветом. Переключение текущего сегмента должно производиться циклически по нажатию пробела.

Подсказка: для сохранения и восстановления позиции и ориентации координатной системы, связанной с кистью манипулятора, применяйте функции glPushMatrix() и glPopMatrix(). При рисовании пальцев перед позиционированием каждого пальца сохраняйте текущую видовую матрицу, а после рисования – восстанавливайте ее.


Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...