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

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





Манипулятор робота на экране изображается в виде нескольких каркасных параллелепипедов (по одному для каждого сегмента манипулятора – "плечо", "локоть", "кисть", "пальцы"). Предполагается, что в местах соединения сегментов расположены шарниры и сегменты могут вращаться вокруг них. На рис. 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- 2021 megalektsii.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.