Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Проектирование реализации операций бизнес-процесса «Движение библиотечного фонда» (ДИАГРАММА ПОСЛЕДОВАТЕЛЬНОСТИ)

Содержание:

ВВЕДЕНИЕ

Цель работы - разработка регламента выполнения процесса «Движение библиотечного фонда».

Задачи работы:

- развернутое описание предметной области

- диаграмма прецедентов

- диаграмма классов

- диаграмма деятельности

- диаграмма последовательности

- диаграмма компонентов и развертывания

1 РАЗВЕРНУТОЕ ОПИСАНИЕ ПРЕДМЕТНОЙ ОБЛАСТИ

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

В настоящее время библиотека предприятия содержит техническую и учебную литературу, которая необходима сотрудникам для качественного выполнения поставленного перед ними задания. Фонд библиотеки составляет 40 тысяч книг.

Непосредственным объектом автоматизации является отдел комплектования (ОК) библиотеки предприятия, который осуществляет: комплектование фонда библиотеки в строгом соответствии с запросами отделов и профилем предприятия; техническую обработку новых поступлений книг (с помощью традиционной технологии штрих-кодировки); ведение библиотечного учета.

Основой формирования библиотечного фонда библиотеки является процесс комплектования. Комплектование ведется на основе прямых договоров с издательствами, книготоргующими организациями, фирмами.

Все документы, которые поступили в библиотеку, принимаются ОК по сопроводительным документам (накладным) и штемпелюются. После приема и обработки сопроводительного документа ОК передает его в бухгалтерию. Исключение документов из библиотечного фонда оформляется по акту списания, с обоснованием причины, по которой документ выбывает из фонда. В ОК акт списания формируется на основе документа «Список книг» переданного отделом книгохранения. Документы, которые выбыли, исключаются из всех учетных форм и делается соответствующая запись в акте списания и соответствующих учетных формах.

Формой ведения индивидуального учета документов является «Инвентарная книга».

Формой суммарного учета является «Книга суммарного учета библиотечного фонда». Сведения о движении фонда фиксируются в трех её частях:

– часть 1 – «Поступление в фонд»;

– часть 2 – «Выбытие из фонда»;

– часть 3 – «Итоги движения фонда».

Сведения о поступивших в фонд библиотеки документах фиксируются в первой части.

Сведения о выбывших из фонда библиотеки документах отражаются во второй части с указанием причин выбытия.

Сведения о поступивших и выбывших за год из фонда библиотеки документах отражаются в третьей части.

Накладные, а также акты приема, списания и пожертвования, после обработки и формирования в ОК передаются в бухгалтерию.

Отдел комплектования является одним из основных структурных подразделений библиотеки предприятия. ОК осуществляет заказ, прием и учет поступающей в фонд библиотеки литературы, а также её списание.

Работа по решению данной задачи в отделе комплектования ведется тремя сотрудниками заведующим отделом комплектования библиотеки и ведущими библиотекарями, которые являются пользователями разрабатываемой автоматизированной системы.

На текущий момент в рамках задачи «Учёт библиотечного фонда», реализуются следующие функциональные задачи:

– индивидуальный учёт библиотечного фонда;

– суммарный учёт библиотечного фонда;

  • учет балансовой стоимости библиотечного фонда.

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

Формой ведения индивидуального учета документов является «Инвентарная книга».

При списании документов выполняется внесение данных согласно документу «Список книг». Номер акта списания отражается в документах «Инвентарная книга» и третьей части КСУБФ.

Под функциональной задачей «Суммарный учёт» понимается ведение учёта библиотечного фонда группами (партиями), поступающих или выбывающих книг, по одному сопроводительному документу (накладной).

Формой суммарного учета является «Книга суммарного учета библиотечного фонда». Сведения о движении фонда фиксируются в трех её частях:

– часть 1 – «Поступление в фонд»;

– часть 2 – «Выбытие из фонда»;

– часть 3 – «Итоги движения фонда».

Формами ведения учета балансовой стоимости книг являются «Акт прихода», «Акт списання», а также «Акт пожертвования». Балансовая стоимость фонда впоследствии будет отражаться в бухгалтерском учете предприятия.

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

Модернизация задачи предполагает изменение соответствующего ПО:

  • создание экранных форм («Акт прихода», «Акт пожертвования»);
  • усовершенствование экранных форм («Акт списания» (добавление новых кнопок с возможностью формирования документа, вывода на печать и его сохранения), «Причины выбытия» (разработка полей для записи кода), «Сотрудники» (введение дополнительных полей о сотруднике, таких как: телефон, домашний адрес, членство в комиссии, для возможности определения входа сотрудника в постоянно действующую комиссию предприятия по проверке сохранности фонда)).

2 ДИАГРАММЫ UML

2.1 ДИАГРАММА ПРЕЦЕДЕНТОВ

Диаграмма прецедентов для задачи «Движение библиотечного фонда» представлена на рисунке 2.1.

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

На диаграмме представлены:

  • актеры (пользователь разрабатываемой ИС, им могут быть – Заведующий отделом комплектования, ведущие библиотекари)
  • прецеденты (три основные из них – формирование отчетов, формирование библиотечного фонда, формирование справочников).

Пользователь является инициатором всех действий осуществляемых с системой. Прецеденты:

  • формирование отчетов (инициируется пользователем, реализация данной функциональности системы возможна в шести аспектах поведения – вариантах использования, в зависимости от того какой из них выберет пользователь. При выборе определенного варианта его реализация (напр., формирование КСУБФ (Поступление в фонд)) становится возможной только при выполнении обязательного условия (прецедента выбор года, за который будет формироваться данный документ)- прецедента соединенного с базовым связью «include» – включает);
  • формирование библиотечного фонда (инициируется пользователем, реализация данной функциональности системы возможна в двух аспектах поведения – вариантах использования, в зависимости от того какой из них выберет пользователь; реализация выбранного варианта использования осуществляется логически по тем же связям что и для прецедента формирование отчетов);
  • формирование справочников (инициируется пользователем, реализация данной функциональности системы возможна в восьми аспектах поведения – вариантах использования, в зависимости от того какой из них выберет пользователь; реализация выбранного варианта использования осуществляется логически по тем же связям что и для прецедента формирование отчетов).

20

Рисунок 2.1 – Диаграмма прецедентов модернизированной задачи «Движение библиотечного фонда» ИС библиотеки предприятия

2.2 ДИАГРАММА КЛАССОВ

Для представления формализованного описания логической структуры задачи используется методология объектно-ориентированного проектирования UML. UML – это графический язык визуализации, специфицирования и документирования.

Концептуальная модель UML включает в себя три составные части:

  • основные строительные блоки языка;
  • правила их сочетания;
  • строительные блоки UML.

UML включает три вида строительных блоков:

  • сущности;
  • отношения;
  • диаграммы.

Диаграмма в UML – это графическое представление набора элементов.

В результате построения диаграммы классов был разработан ряд классов, представленных в таблице 2.1 соединенные связями, указанными в таблице 2.2.

Таблица 2.1 – Классы, использованные при построении диаграммы классов

№ п/п

Наименование класса

Примечание

1

Сотрудники

Сотрудник отдела комплектования библиотеки предприятия

2

Книги

Информация о книгах, которые находятся в библиотечном фонде

3

Экземпляры

Информация об экземплярах книг библиотечного фонда

4

Акты списания

Информация об актах списания книг

5

Причины списания

Информация о причинах списания книг

6

Издательства

Информация об издательствах книг

7

Тип литературы

Информация о типах литературы

8

Языки книги

Информация о языках книги

9

Авторы

Информация об авторах книг

10

Партии

Информация о поступивших партиях книг

Таблица 2.2 – Отношения между классами

№ п/п

Класс

Вид связи

Класс

Кардинальность

1

Книги

Агрегация

Экземпляры

1:M

2

Языки книги

Агрегация

Книги

1:М

3

Тип литературы

Агрегация

Книги

1:М

4

Сотрудники

Агрегация

Акты списания

1:М

5

Партии

Агрегация

Экземпляры

1:М

6

Акты списания

Агрегация

Экземпляры

1:М

7

Издательства

Агрегация

Экземпляры

1:М

8

Причины списания

Агрегация

Акты списания

1:М

9

Книги

Агрегация

Авторы

1:М(М:М?)

Диаграмма классов для задачи «Движение библиотечного фонда» представлена на рисунке 2.2

Диаграмма классов логически построена на основе будущих форм разрабатываемой ИС. «Взаимодействие» с формами осуществляется с помощью кнопок, каждая из которых поддерживается методом соответствующего класса. Напр. форма Книги.

В программе она вызывается следующим образом:

Нажатие на кнопку Каталог книг – появляется форма с перечнем книг. Можно выбрать кнопки - добавить книгу, изменить, удалить книгу.

Добавить книгу – отображаются все поля, которые отражены в классе «Книги». Поле автор – специальная кнопка, которая вызывает форму авторы – т.о. можно выбрать автора из появившегося перечня авторов. Такие же поля Тип литературы и Язык книги.

Кнопки «Сохранение данных» и «Отмена» не отражены в реализации класса «Книги».

Рисунок 2.2 – Диаграмма классов для задачи «Движение библиотечного фонда»

2.3 ДИАГРАММА ДЕЯТЕЛЬНОСТИ

Для представления формализованного описания логической структуры задачи используется метод объектно-ориентированного проектирования UML.

К диаграммам поведения можно отнести следующие диаграммы:

  • деятельности (Activity diagram);
  • состояний (State Machine diagram);
  • вариантов использования (Use case diagram).

Диаграмма деятельности для прецедента «Формирование библиотечного фонда» задачи «Движение библиотечного фонда» представлена на рисунке 2.3.

Реализация прецедента «Формирование библиотечного фонда» возможна тремя поведенческими аспектами:

Выбор кнопки Каталог книг, Каталог экземпляров книг или Выход.

При открытии формы Каталог книг (см. описание диаграммы классов) главная форма остается открытой и возможен возврат к главной форме без закрытия формы Каталог книг.

Рисунок 2.3 – Диаграмма деятельности для прецедента «Формирование библиотечного фонда» задачи «Движение библиотечного фонда»

2.4 ДИАГРАММА ПОСЛЕДОВАТЕЛЬНОСТИ

Для представления формализованного описания логической структуры задачи используется метод объектно-ориентированного проектирования UML.

В унифицированном языке моделирования UML существуют два вида диаграмм, которые помогают документировать и описывать эти взаимодействия: диаграмма последовательности взаимодействия и диаграмма сотрудничества объектов. Обе они известны как диаграммы взаимодействия. Для данной задачи была разработана диаграмма последовательности, представленная на рисунке 2.4.

На диаграмме приведены основные этапы реализации функциональной задачи индивидуального учета библиотечного фонда путем формирования документа «Инвентарная книга».

Последовательность при выполнении данной задачи:

  • осуществление входа в систему;
  • введение логина и пароля;
  • вход в форму «Инвентарная книга»;
  • введение номера партии;
  • сохранение результатов;
  • печать документа.

Рисунок 2.4 – Диаграмма последовательности для прецедента «Формирование «Инвентарной книги»» задачи «Движение библиотечного фонда»

2.5 ДИАГРАММА КОМПОНЕНТОВ И РАЗВЕРТЫВАНИЯ

Диаграмма компонентов, в отличие от прежде рассмотренных диаграмм, описывает особенности физического представления системы. Она позволяет определить архитектуру системы, которая разрабатывается, установив зависимости между программными компонентами, в роли которых может выступать исходный и выполняемый код. Основными графическими элементами диаграммы компонентов есть компоненты, интерфейсы и зависимости между ними.

Диаграмма развертывания предназначена для визуализации элементов и компонентов программы, существующих лишь на этапе ее исполнения. При этом представляются только компоненты-экземпляры программы, являющиеся исполнимыми файлами или динамическими библиотеками. Те компоненты, которые не используются на этапе исполнения, на диаграмме развертывания не показываются. Компоненты с исходными текстами программ могут присутствовать только на диаграмме компонентов. На диаграмме развертывания они не указываются.

Структурно программа реализована следующим образом:

Данные хранятся в таблицах БД MySQL.

Проект программы представлен 3-мя пакетами:

1) Вспомогательные классы

2) Классы реализации форм (пакет View).

3) библиотеки (jasperreports и др.)

Исполняемый файл Library.jar

Диаграмма компонентов, разработанная для данной задачи, реализована в двух вариантах и представлена на рисунке

- (1-ый вариант)

Логическое упрощенное представление реализации программы. Возможно даже не полное отражение и соответствие со структурой программы (см.выше), а просто возможно ли такое представление программы?

- (2-ой вариант)

Логически совпадает с существующей структурой программы (см.выше).

Данные хранятся в таблицах БД MySQL.(пакет Model)

Вспомогательные классы (пакет Control )

Классы реализации форм (пакет View).

Исполняемый файл Library.jar

Можно ли соединить DB MySQL с соответ-щим пакетом Model?

Разработка диаграммы развертывания осуществляется для моделирования требуемых устройств (сервер, рабочая станция клиента), драйвера (для работы с БД), процессов (реализуемых классами) и связи между ними.

Диаграмма развертывания, разработанная для данной задачи, представлена на рисунке:

(Программа основана на архитектуре клиент-сервер. В локальной сети: ПК сервер, ПК клиент, коммутатор)

Рисунок 2.5 − Диаграмма компонентов для задачи «Движение библиотечного фонда»

Рисунок 2.6− Диаграмма компонентов для задачи «Движение библиотечного фонда»

Рисунок 2.7 − Диаграмма развертывания для задачи «Движение библиотечного фонда»

Рисунок 2.8 − Диаграмма развертывания для задачи «Движение библиотечного фонда»

35

ЗАКЛЮЧЕНИЕ

Движение фонда – процесс поступления, перестановки и выбытия документов, итоги которого отражаются в учетной документации.

Итоги движения фондов подводятся в «Книге суммарного учета библиотечного фонда» (или другом регистре суммарного учета, принятом в библиотеке) на основании данных суммарного учета о поступлении и выбытии документов.

Итоговые данные имеют четыре обязательных показателя: состояло на начало года, поступило за год, выбыло за год, состоит на конец года.

Итоговые данные по электронным сетевым документам удаленного доступа представляются следующими показателями учетных единиц: состояло на начало года, оформлено в доступ в течение года, доступ прекращен в течение года, состоит на конец года.

Сведения об итоговых данных фиксируются в форме государственной статистической отчетности №6-НК и представляются для целей государственной статистической отчетности.

Итоговые данные об обменном фонде и электронных сетевых локальных документов включаются в общие показатели библиотечного фонда.

Итоговые данные электронных сетевых документов удаленного доступа отражаются путем добавления к общим показателям библиотечного фонда через «+» количества пакетов и количества (в скобках) включенных в них документов.

СПИСОК ЛИТЕРАТУРЫ

  1. В.П. Агальцов. Базы данных. - Издательство «Мир», 2002 г. - 376 с.
  2. А. Горев, Р. Ахаян. Эффективная работа с СУБД. - Издательство «СПБ», 1997 г. - 445 с.
  3. Омельченко Л. Самоучитель Visual FoxPro 6.0. Издательство - «Петербург», 2000 г. - 512 с.
  4. ГОСТ Р ИСО/МЭК 12207/99. Государственный стандарт РФ. Информационная технология. Процессы жизненного цикла информационных систем. Издание официальное. - М., 1999
  5. Схемы алгоритмов, программ, данных и систем. Условные обозначения и правила выполнения. ГОСТ 19.701-90 (ИСО 5807-85) / Государственный комитет СССР по управлению качеством продукции и стандартам, 01.01.1992.
  6. Автоматизированные информационные системы, базы и банки данных. Вводный курс: Учебное пособие, М.: Гелиос АРВ, 2007. - 368 с., ил
  7. Астелс, Дэвид; Миллер Гранвилл; Новак, Мирослав, Практическое руководство по экстремальному программированию, Пер. с англ. - М.: Издательский дом "Вильямс", 2008. - 320 с.: ил. - Парал. тит. англ

ПРИЛОЖЕНИЕ А - ЛИСТИНГ ПО

demo = uicontrol(fig_1,'String','Demo','callback',@demo_button_press,...

'Position',[20 5 60 20]);

rnd_demo = uicontrol(fig_1,'String','Random Move','callback',@rnd_demo_button_press,...

'Position',[100 5 80 20]);

clr_trail = uicontrol(fig_1,'String','Clr Trail','callback',@clr_trail_button_press,...

'Position',[200 5 60 20]);

%

home = uicontrol(fig_1,'String','Home','callback',@home_button_press,...

'Position',[280 5 70 20]);

%

% Kinematics Panel

%

K_p = uipanel(fig_1,...

'units','pixels',...

'Position',[20 45 265 200],...

'Title','Kinematics','FontSize',11);

%

% Angle Range Default Name

% Theta 1: 320 (-160 to 160) 90 Waist Joint

% Theta 2: 220 (-110 to 110) -90 Shoulder Joint

% Theta 3: 270 (-135 to 135) -90 Elbow Joint

% Theta 4: 532 (-266 to 266) 0 Wrist Roll

% Theta 5: 200 (-100 to 100) 0 Wrist Bend

% Theta 6: 532 (-266 to 266) 0 Wrist Swivel

t1_home = 90; % offset to define the "home" position as UP.

t2_home = -90;

t3_home = -90;

LD = 105; % Left, used to set the GUI.

HT = 18; % Height

BT = 156; % Bottom

%% GUI buttons for Theta 1. pos is: [left bottom width height]

t1_slider = uicontrol(K_p,'style','slider',...

'Max',160,'Min',-160,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t1_slider_button_press,...

'Position',[LD BT 120 HT]);

t1_min = uicontrol(K_p,'style','text',...

'String','-160',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t1_max = uicontrol(K_p,'style','text',...

'String','+160',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t1_text = uibutton(K_p,'style','text',... % Nice program Doug. Need this

'String','\theta_1',... % due to no TeX in uicontrols.

'Position',[LD-100 BT 20 HT]); % L, B, W, H

% t1_text = uicontrol(K_p,'style','text',... % when matlab fixes uicontrol

% 'String','t1',... % for TeX, then I can use this.

% 'Position',[LD-100 BT 20 HT]); % L, B, W, H

t1_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t1_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 2.

BT = 126; % Bottom

t2_slider = uicontrol(K_p,'style','slider',...

'Max',115,'Min',-115,'Value',0,... % Mech. stop limits !

'SliderStep',[0.05 0.2],...

'callback',@t2_slider_button_press,...

'Position',[LD BT 120 HT]);

t2_min = uicontrol(K_p,'style','text',...

'String','-110',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t2_max = uicontrol(K_p,'style','text',...

'String','+110',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t2_text = uibutton(K_p,'style','text',...

'String','\theta_2',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t2_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t2_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 3.

BT = 96; % Bottom

t3_slider = uicontrol(K_p,'style','slider',...

'Max',135,'Min',-135,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t3_slider_button_press,...

'Position',[LD BT 120 HT]);

t3_min = uicontrol(K_p,'style','text',...

'String','-135',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t3_max = uicontrol(K_p,'style','text',...

'String','+135',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t3_text = uibutton(K_p,'style','text',...

'String','\theta_3',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t3_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t3_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 4.

BT = 66; % Bottom

t4_slider = uicontrol(K_p,'style','slider',...

'Max',266,'Min',-266,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t4_slider_button_press,...

'Position',[LD BT 120 HT]);

t4_min = uicontrol(K_p,'style','text',...

'String','-266',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t4_max = uicontrol(K_p,'style','text',...

'String','+266',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t4_text = uibutton(K_p,'style','text',...

'String','\theta_4',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t4_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t4_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 5.

BT = 36; % Bottom

t5_slider = uicontrol(K_p,'style','slider',...

'Max',100,'Min',-100,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t5_slider_button_press,...

'Position',[LD BT 120 HT]);

t5_min = uicontrol(K_p,'style','text',...

'String','-100',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t5_max = uicontrol(K_p,'style','text',...

'String','+100',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t5_text = uibutton(K_p,'style','text',...

'String','\theta_5',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t5_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t5_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 6.

BT = 6; % Bottom

t6_slider = uicontrol(K_p,'style','slider',...

'Max',266,'Min',-266,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t6_slider_button_press,...

'Position',[LD BT 120 HT]);

t6_min = uicontrol(K_p,'style','text',...

'String','-266',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t6_max = uicontrol(K_p,'style','text',...

'String','+266',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t6_text = uibutton(K_p,'style','text',...

'String','\theta_6',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t6_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t6_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% Slider for Theta 1 motion.

%

function t1_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t1_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t2old = T_Old(2); t3old = T_Old(3); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

pumaANI(slider_value+t1_home,t2old,t3old,t4old,t5old,t6old,10,'n')

end

%

%% Slider for Theta 2 motion.

%

function t2_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t2_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t3old = T_Old(3); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

pumaANI(t1old,slider_value+t2_home,t3old,t4old,t5old,t6old,10,'n')

end

%

%% Slider for Theta 3 motion.

function t3_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t3_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t2old = T_Old(2); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

pumaANI(t1old,t2old,slider_value+t3_home,t4old,t5old,t6old,10,'n')

end

%

%% Slider for Theta 4 motion.

function t4_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t4_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t5old = T_Old(5); t6old = T_Old(6);

pumaANI(t1old,t2old,t3old,slider_value,t5old,t6old,10,'n')

end

%

%% Slider for Theta 5 motion.

function t5_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t5_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t4old = T_Old(4); t6old = T_Old(6);

pumaANI(t1old,t2old,t3old,t4old,slider_value,t6old,10,'n')

end

%

%% Slider for Theta 6 motion.

function t6_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t6_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t4old = T_Old(4); t5old = T_Old(5);

pumaANI(t1old,t2old,t3old,t4old,t5old,slider_value,10,'n')

end

%

%% Edit box for Theta 1 motion.

%

function t1_edit_button_press(h,dummy)

user_entry = check_edit(h,-160,160,0,t1_edit);

set(t1_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t2old = T_Old(2); t3old = T_Old(3); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

%

pumaANI(user_entry+t1_home,t2old,t3old,t4old,t5old,t6old,10,'n')

end

%

%% Edit box for Theta 2 motion.

%

function t2_edit_button_press(h,dummy)

user_entry = check_edit(h,-110,110,0,t2_edit);

set(t2_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t3old = T_Old(3); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

%

pumaANI(t1old,user_entry+t2_home,t3old,t4old,t5old,t6old,10,'n')

end

%% Edit box for Theta 3 motion.

%

function t3_edit_button_press(h,dummy)

user_entry = check_edit(h,-135,135,0,t3_edit);

set(t3_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t2old = T_Old(2); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

%

pumaANI(t1old,t2old,user_entry+t3_home,t4old,t5old,t6old,10,'n')

end

%%

%% Edit box for Theta 4 motion.

%

function t4_edit_button_press(h,dummy)

user_entry = check_edit(h,-266,266,0,t4_edit);

set(t4_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t5old = T_Old(5); t6old = T_Old(6);

%

pumaANI(t1old,t2old,t3old,user_entry,t5old,t6old,10,'n')

end

%% Edit box for Theta 5 motion.

%

function t5_edit_button_press(h,dummy)

user_entry = check_edit(h,-100,100,0,t5_edit);

set(t5_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t4old = T_Old(4); t6old = T_Old(6);

%

pumaANI(t1old,t2old,t3old,t4old,user_entry,t6old,10,'n')

end

%%

%% Edit box for Theta 6 motion.

%

function t6_edit_button_press(h,dummy)

user_entry = check_edit(h,-266,266,0,t6_edit);

set(t6_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t4old = T_Old(4); t5old = T_Old(5);

%

pumaANI(t1old,t2old,t3old,t4old,t5old,user_entry,10,'n')

end

%%

function user_entry = check_edit(h,min_v,max_v,default,h_edit)

% This function will check the value typed in the text input box

% against min and max values, and correct errors.

%

% h: handle of gui

% min_v min value to check

% max_v max value to check

% default is the default value if user enters non number

% h_edit is the edit value to update.

%

user_entry = str2double(get(h,'string'));

if isnan(user_entry)

errordlg(['You must enter a numeric value, defaulting to ',num2str(default),'.'],'Bad Input','modal')

set(h_edit,'string',default);

user_entry = default;

end

%

if user_entry < min_v

errordlg(['Minimum limit is ',num2str(min_v),' degrees, using ',num2str(min_v),'.'],'Bad Input','modal')

user_entry = min_v;

set(h_edit,'string',user_entry);

end

if user_entry > max_v

errordlg(['Maximum limit is ',num2str(max_v),' degrees, using ',num2str(max_v),'.'],'Bad Input','modal')

user_entry = max_v;

set(h_edit,'string',user_entry);

end

end

%

%% Demo button's callback

function demo_button_press(h,dummy)

%

% disp('pushed demo bottom');

% R = 500;

% x = 1000;

n = 2; % demo ani steps

num = 30; % home to start, and end to home ani steps

% j = 1;

% M = 1000;

for t = 0:.1:7*pi

Px = 30*t*cos(t);

Py = 1200-300*t*(t)/(50*pi);

Pz = 30*t*sin(t);

[theta1,theta2,theta3,theta4,theta5,theta6] = PumaIK(Px,Py,Pz);

if t==0 %move to start of demo

pumaANI(theta1,theta2,theta3-180,0,0,0,num,'n')

end

% Theta 4, 5 & 6 are zero due to plotting at wrist origen.

pumaANI(theta1,theta2,theta3-180,0,0,0,n,'y')

set(t1_edit,'string',round(theta1)); % Update slider and text.

set(t1_slider,'Value',round(theta1));

set(t2_edit,'string',round(theta2));

set(t2_slider,'Value',round(theta2));

set(t3_edit,'string',round(theta3-180));

set(t3_slider,'Value',round(theta3-180));

end

gohome

% pumaANI(90,-90,-90,0,0,0,num,'n')

end

%

%

%%

function home_button_press(h,dummy)

%disp('pushed home bottom');

gohome

end

%

%%

function clr_trail_button_press(h,dummy)

%disp('pushed clear trail bottom');

handles = getappdata(0,'patch_h'); %

Tr = handles(9);

%

setappdata(0,'xtrail',0); % used for trail tracking.

setappdata(0,'ytrail',0); % used for trail tracking.

setappdata(0,'ztrail',0); % used for trail tracking.

%

set(Tr,'xdata',0,'ydata',0,'zdata',0);

end

%

%

function rnd_demo_button_press(h, dummy)

%disp('pushed random demo bottom');

% a = 10; b = 50; x = a + (b-a) * rand(5)

% Angle Range Default Name

% Theta 1: 320 (-160 to 160) 90 Waist Joint

% Theta 2: 220 (-110 to 110) -90 Shoulder Joint

% Theta 3: 270 (-135 to 135) -90 Elbow Joint

% Theta 4: 532 (-266 to 266) 0 Wrist Roll

% Theta 5: 200 (-100 to 100) 0 Wrist Bend

% Theta 6: 532 (-266 to 266) 0 Wrist Swival

t1_home = 90; % offsets to define the "home" postition as UP.

t2_home = -90;

t3_home = -90;

theta1 = -160 + 320*rand(1); % offset for home

theta2 = -110 + 220*rand(1); % in the UP pos.

theta3 = -135 + 270*rand(1);

theta4 = -266 + 532*rand(1);

theta5 = -100 + 200*rand(1);

theta6 = -266 + 532*rand(1);

n = 50;

pumaANI(theta1+t1_home,theta2+t2_home,theta3+t3_home,theta4,theta5,theta6,n,'y')

set(t1_edit,'string',round(theta1)); % Update slider and text.

set(t1_slider,'Value',round(theta1));

set(t2_edit,'string',round(theta2));

set(t2_slider,'Value',round(theta2));

set(t3_edit,'string',round(theta3));

set(t3_slider,'Value',round(theta3));

set(t4_edit,'string',round(theta4));

set(t4_slider,'Value',round(theta4));

set(t5_edit,'string',round(theta5));

set(t5_slider,'Value',round(theta5));

set(t6_edit,'string',round(theta6));

set(t6_slider,'Value',round(theta6));

end

%%

%Here are the functions used for this robot example:

%

%%

% When called this function will simply initialize a plot of the Puma 762

% robot by plotting it in it's home orientation and setting the current

% angles accordingly.

function gohome()

pumaANI(90,-90,-90,0,0,0,20,'n') % show it animate home

%PumaPOS(90,-90,-90,0,0,0) %drive it home, no animate.

set(t1_edit,'string',0);

set(t1_slider,'Value',0); %At the home position, so all

set(t2_edit,'string',0); %sliders and input boxes = 0.

set(t2_slider,'Value',0);

set(t3_edit,'string',0);

set(t3_slider,'Value',0);

set(t4_edit,'string',0);

set(t4_slider,'Value',0);

set(t5_edit,'string',0);

set(t5_slider,'Value',0);

set(t6_edit,'string',0);

set(t6_slider,'Value',0);

setappdata(0,'ThetaOld',[90,-90,-90,0,0,0]);

end

%%

% This function will load the 3D CAD data.

%

function loaddata

% Loads all the link data from file linksdata.mat.

% This data comes from a Pro/E 3D CAD model and was made with cad2matdemo.m

% from the file exchange. All link data manually stored in linksdata.mat

[linkdata]=load('linksdata.mat','s1','s2', 's3','s4','s5','s6','s7','A1');

%Place the robot link 'data' in a storage area

setappdata(0,'Link1_data',linkdata.s1);

setappdata(0,'Link2_data',linkdata.s2);

setappdata(0,'Link3_data',linkdata.s3);

setappdata(0,'Link4_data',linkdata.s4);

setappdata(0,'Link5_data',linkdata.s5);

setappdata(0,'Link6_data',linkdata.s6);

setappdata(0,'Link7_data',linkdata.s7);

setappdata(0,'Area_data',linkdata.A1);

end

%

%%

% Use forward kinematics to place the robot in a specified configuration.

%

function PumaPOS(theta1,theta2,theta3,theta4,theta5,theta6)

s1 = getappdata(0,'Link1_data');

s2 = getappdata(0,'Link2_data');

s3 = getappdata(0,'Link3_data');

s4 = getappdata(0,'Link4_data');

s5 = getappdata(0,'Link5_data');

s6 = getappdata(0,'Link6_data');

s7 = getappdata(0,'Link7_data');

A1 = getappdata(0,'Area_data');

%

a2 = 650;

a3 = 0;

d3 = 190;

d4 = 600;

Px = 5000;

Py = 5000;

Pz = 5000;

t1 = theta1;

t2 = theta2;

t3 = theta3 %-180;

t4 = theta4;

t5 = theta5;

t6 = theta6;

%

% Forward Kinematics

T_01 = tmat(0, 0, 0, t1);

T_12 = tmat(-90, 0, 0, t2);

T_23 = tmat(0, a2, d3, t3);

T_34 = tmat(-90, a3, d4, t4);

T_45 = tmat(90, 0, 0, t5);

T_56 = tmat(-90, 0, 0, t6);

%T_01 = T_01;

T_02 = T_01*T_12;

T_03 = T_02*T_23;

T_04 = T_03*T_34;

T_05 = T_04*T_45;

T_06 = T_05*T_56;

%

Link1 = s1.V1;

Link2 = (T_01*s2.V2')';

Link3 = (T_02*s3.V3')';

Link4 = (T_03*s4.V4')';

Link5 = (T_04*s5.V5')';

Link6 = (T_05*s6.V6')';

Link7 = (T_06*s7.V7')';

handles = getappdata(0,'patch_h'); %

L1 = handles(1);

L2 = handles(2);

L3 = handles(3);

L4 = handles(4);

L5 = handles(5);

L6 = handles(6);

L7 = handles(7);

%

set(L1,'vertices',Link1(:,1:3),'facec', [0.717,0.116,0.123]);

set(L1, 'EdgeColor','none');

set(L2,'vertices',Link2(:,1:3),'facec', [0.216,1,.583]);

set(L2, 'EdgeColor','none');

set(L3,'vertices',Link3(:,1:3),'facec', [0.306,0.733,1]);

set(L3, 'EdgeColor','none');

set(L4,'vertices',Link4(:,1:3),'facec', [1,0.542,0.493]);

set(L4, 'EdgeColor','none');

set(L5,'vertices',Link5(:,1:3),'facec', [0.216,1,.583]);

set(L5, 'EdgeColor','none');

set(L6,'vertices',Link6(:,1:3),'facec', [1,1,0.255]);

set(L6, 'EdgeColor','none');

set(L7,'vertices',Link7(:,1:3),'facec', [0.306,0.733,1]);

set(L7, 'EdgeColor','none');

end

%%

% This function computes the Inverse Kinematics for the Puma 762 robot

% given X,Y,Z coordinates for a point in the workspace. Note: The IK are

% computed for the origin of Coordinate systems 4,5 & 6.

function [theta1,theta2,theta3,theta4,theta5,theta6] = PumaIK(Px,Py,Pz)

theta4 = 0;

theta5 = 0;

theta6 = 0;

sign1 = 1;

sign3 = 1;

nogo = 0;

noplot = 0;

% Because the sqrt term in theta1 & theta3 can be + or - we run through

% all possible combinations (i = 4) and take the first combination that

% satisfies the joint angle constraints.

while nogo == 0;

for i = 1:1:4

if i == 1

sign1 = 1;

sign3 = 1;

elseif i == 2

sign1 = 1;

sign3 = -1;

elseif i == 3

sign1 = -1;

sign3 = 1;

else

sign1 = -1;

sign3 = -1;

end

a2 = 650;

a3 = 0;

d3 = 190;

d4 = 600;

rho = sqrt(Px^2+Py^2);

phi = atan2(Py,Px);

K = (Px^2+Py^2+Pz^2-a2^2-a3^2-d3^2-d4^2)/(2*a2);

c4 = cos(theta4);

s4 = sin(theta4);

c5 = cos(theta5);

s5 = sin(theta5);

c6 = cos(theta6);

s6 = sin(theta6);

theta1 = (atan2(Py,Px)-atan2(d3,sign1*sqrt(Px^2+Py^2-d3^2)));

c1 = cos(theta1);

s1 = sin(theta1);

theta3 = (atan2(a3,d4)-atan2(K,sign3*sqrt(a3^2+d4^2-K^2)));

c3 = cos(theta3);

s3 = sin(theta3);

t23 = atan2((-a3-a2*c3)*Pz-(c1*Px+s1*Py)*(d4-a2*s3),(a2*s3-d4)*Pz+(a3+a2*c3)*(c1*Px+s1*Py));

theta2 = (t23 - theta3);

c2 = cos(theta2);

s2 = sin(theta2);

s23 = ((-a3-a2*c3)*Pz+(c1*Px+s1*Py)*(a2*s3-d4))/(Pz^2+(c1*Px+s1*Py)^2);

c23 = ((a2*s3-d4)*Pz+(a3+a2*c3)*(c1*Px+s1*Py))/(Pz^2+(c1*Px+s1*Py)^2);

r13 = -c1*(c23*c4*s5+s23*c5)-s1*s4*s5;

r23 = -s1*(c23*c4*s5+s23*c5)+c1*s4*s5;

r33 = s23*c4*s5 - c23*c5;

theta4 = atan2(-r13*s1+r23*c1,-r13*c1*c23-r23*s1*c23+r33*s23);

r11 = c1*(c23*(c4*c5*c6-s4*s6)-s23*s5*c6)+s1*(s4*c5*c6+c4*s6);

r21 = s1*(c23*(c4*c5*c6-s4*s6)-s23*s5*c6)-c1*(s4*c5*c6+c4*s6);

r31 = -s23*(c4*c5*c6-s4*s6)-c23*s5*c6;

s5 = -(r13*(c1*c23*c4+s1*s4)+r23*(s1*c23*c4-c1*s4)-r33*(s23*c4));

c5 = r13*(-c1*s23)+r23*(-s1*s23)+r33*(-c23);

theta5 = atan2(s5,c5);

s6 = -r11*(c1*c23*s4-s1*c4)-r21*(s1*c23*s4+c1*c4)+r31*(s23*s4);

c6 = r11*((c1*c23*c4+s1*s4)*c5-c1*s23*s5)+r21*((s1*c23*c4-c1*s4)*c5-s1*s23*s5)-r31*(s23*c4*c5+c23*s5);

theta6 = atan2(s6,c6);

theta1 = theta1*180/pi;

theta2 = theta2*180/pi;

theta3 = theta3*180/pi;

theta4 = theta4*180/pi;

theta5 = theta5*180/pi;

theta6 = theta6*180/pi;

if theta2>=160 && theta2<=180

theta2 = -theta2;

end

if theta1<=160 && theta1>=-160 && (theta2<=20 && theta2>=-200) && theta3<=45 && theta3>=-225 && theta4<=266 && theta4>=-266 && theta5<=100 && theta5>=-100 && theta6<=266 && theta6>=-266

nogo = 1;

theta3 = theta3+180;

break

end

if i == 4 && nogo == 0

h = errordlg('Point unreachable due to joint angle constraints.','JOINT ERROR');

waitfor(h);

nogo = 1;

noplot = 1;

break

end

end

end

end

%

%%

function pumaANI(theta1,theta2,theta3,theta4,theta5,theta6,n,trail)

% This function will animate the Puma 762 robot given joint angles.

% n is number of steps for the animation

% trail is 'y' or 'n' (n = anything else) for leaving a trail.

%

%disp('in animate');

a2 = 650; %D-H paramaters

a3 = 0;

d3 = 190;

d4 = 600;

% Err2 = 0;

%

ThetaOld = getappdata(0,'ThetaOld');

%

theta1old = ThetaOld(1);

theta2old = ThetaOld(2);

theta3old = ThetaOld(3);

theta4old = ThetaOld(4);

theta5old = ThetaOld(5);

theta6old = ThetaOld(6);

%

t1 = linspace(theta1old,theta1,n);

t2 = linspace(theta2old,theta2,n);

t3 = linspace(theta3old,theta3,n);% -180;

t4 = linspace(theta4old,theta4,n);

t5 = linspace(theta5old,theta5,n);

t6 = linspace(theta6old,theta6,n);

n = length(t1);

for i = 2:1:n

% Forward Kinematics

%

T_01 = tmat(0, 0, 0, t1(i));

T_12 = tmat(-90, 0, 0, t2(i));

T_23 = tmat(0, a2, d3, t3(i));

T_34 = tmat(-90, a3, d4, t4(i));

T_45 = tmat(90, 0, 0, t5(i));

T_56 = tmat(-90, 0, 0, t6(i));

%

% % T_67 = [ 1 0 0 0

% % 0 1 0 0

% % 0 0 1 188

% % 0 0 0 1];

%T_01 = T_01; % it is, but don't need to say so.

T_02 = T_01*T_12;

T_03 = T_02*T_23;

T_04 = T_03*T_34;

T_05 = T_04*T_45;

T_06 = T_05*T_56;

% T_07 = T_06*T_67;

%

s1 = getappdata(0,'Link1_data');

s2 = getappdata(0,'Link2_data');

s3 = getappdata(0,'Link3_data');

s4 = getappdata(0,'Link4_data');

s5 = getappdata(0,'Link5_data');

s6 = getappdata(0,'Link6_data');

s7 = getappdata(0,'Link7_data');

%A1 = getappdata(0,'Area_data');

Link1 = s1.V1;

Link2 = (T_01*s2.V2')';

Link3 = (T_02*s3.V3')';

Link4 = (T_03*s4.V4')';

Link5 = (T_04*s5.V5')';

Link6 = (T_05*s6.V6')';

Link7 = (T_06*s7.V7')';

% Tool = T_07;

% if sqrt(Tool(1,4)^2+Tool(2,4)^2)<514

% Err2 = 1;

% break

% end

%

handles = getappdata(0,'patch_h'); %

L1 = handles(1);

L2 = handles(2);

L3 = handles(3);

L4 = handles(4);

L5 = handles(5);

L6 = handles(6);

L7 = handles(7);

Tr = handles(9);

%

set(L1,'vertices',Link1(:,1:3),'facec', [0.717,0.116,0.123]);

set(L1, 'EdgeColor','none');

set(L2,'vertices',Link2(:,1:3),'facec', [0.216,1,.583]);

set(L2, 'EdgeColor','none');

set(L3,'vertices',Link3(:,1:3),'facec', [0.306,0.733,1]);

set(L3, 'EdgeColor','none');

set(L4,'vertices',Link4(:,1:3),'facec', [1,0.542,0.493]);

set(L4, 'EdgeColor','none');

set(L5,'vertices',Link5(:,1:3),'facec', [0.216,1,.583]);

set(L5, 'EdgeColor','none');

set(L6,'vertices',Link6(:,1:3),'facec', [1,1,0.255]);

set(L6, 'EdgeColor','none');

set(L7,'vertices',Link7(:,1:3),'facec', [0.306,0.733,1]);

set(L7, 'EdgeColor','none');

% store trail in appdata

if trail == 'y'

x_trail = getappdata(0,'xtrail');

y_trail = getappdata(0,'ytrail');

z_trail = getappdata(0,'ztrail');

%

xdata = [x_trail T_04(1,4)];

ydata = [y_trail T_04(2,4)];

zdata = [z_trail T_04(3,4)];

%

setappdata(0,'xtrail',xdata); % used for trail tracking.

setappdata(0,'ytrail',ydata); % used for trail tracking.

setappdata(0,'ztrail',zdata); % used for trail tracking.

%

set(Tr,'xdata',xdata,'ydata',ydata,'zdata',zdata);

end

drawnow

end

setappdata(0,'ThetaOld',[theta1,theta2,theta3,theta4,theta5,theta6]);

end

%%

%

%

%%

function InitHome

% Use forward kinematics to place the robot in a specified

% configuration.

% Figure setup data, create a new figure for the GUI

set(0,'Units','pixels')

dim = get(0,'ScreenSize');

fig_1 = figure('doublebuffer','on','Position',[0,35,dim(3)-200,dim(4)-110],...

'MenuBar','none','Name',' 3D Puma Robot Graphical Demo',...

'NumberTitle','off','CloseRequestFcn',@del_app);

hold on;

%light('Position',[-1 0 0]);

light % add a default light

daspect([1 1 1]) % Setting the aspect ratio

view(135,25)

xlabel('X'),ylabel('Y'),zlabel('Z');

title('WWU Robotics Lab PUMA 762');

axis([-1500 1500 -1500 1500 -1120 1500]);

plot3([-1500,1500],[-1500,-1500],[-1120,-1120],'k')

plot3([-1500,-1500],[-1500,1500],[-1120,-1120],'k')

plot3([-1500,-1500],[-1500,-1500],[-1120,1500],'k')

plot3([-1500,-1500],[1500,1500],[-1120,1500],'k')

plot3([-1500,1500],[-1500,-1500],[1500,1500],'k')

plot3([-1500,-1500],[-1500,1500],[1500,1500],'k')

s1 = getappdata(0,'Link1_data');

s2 = getappdata(0,'Link2_data');

s3 = getappdata(0,'Link3_data');

s4 = getappdata(0,'Link4_data');

s5 = getappdata(0,'Link5_data');

s6 = getappdata(0,'Link6_data');

s7 = getappdata(0,'Link7_data');

A1 = getappdata(0,'Area_data');

%

a2 = 650;

a3 = 0;

d3 = 190;

d4 = 600;

Px = 5000;

Py = 5000;

Pz = 5000;

%The 'home' position, for init.

t1 = 90;

t2 = -90;

t3 = -90;

t4 = 0;

t5 = 0;

t6 = 0;

% Forward Kinematics

T_01 = tmat(0, 0, 0, t1);

T_12 = tmat(-90, 0, 0, t2);

T_23 = tmat(0, a2, d3, t3);

T_34 = tmat(-90, a3, d4, t4);

T_45 = tmat(90, 0, 0, t5);

T_56 = tmat(-90, 0, 0, t6);

% Each link fram to base frame transformation

T_02 = T_01*T_12;

T_03 = T_02*T_23;

T_04 = T_03*T_34;

T_05 = T_04*T_45;

T_06 = T_05*T_56;

% Actual vertex data of robot links

Link1 = s1.V1;

Link2 = (T_01*s2.V2')';

Link3 = (T_02*s3.V3')';

Link4 = (T_03*s4.V4')';

Link5 = (T_04*s5.V5')';

Link6 = (T_05*s6.V6')';

Link7 = (T_06*s7.V7')';

% points are no fun to watch, make it look 3d.

L1 = patch('faces', s1.F1, 'vertices' ,Link1(:,1:3));

L2 = patch('faces', s2.F2, 'vertices' ,Link2(:,1:3));

L3 = patch('faces', s3.F3, 'vertices' ,Link3(:,1:3));

L4 = patch('faces', s4.F4, 'vertices' ,Link4(:,1:3));

L5 = patch('faces', s5.F5, 'vertices' ,Link5(:,1:3));

L6 = patch('faces', s6.F6, 'vertices' ,Link6(:,1:3));

L7 = patch('faces', s7.F7, 'vertices' ,Link7(:,1:3));

A1 = patch('faces', A1.Fa, 'vertices' ,A1.Va(:,1:3));

Tr = plot3(0,0,0,'b.'); % holder for trail paths

%

setappdata(0,'patch_h',[L1,L2,L3,L4,L5,L6,L7,A1,Tr])

%

setappdata(0,'xtrail',0); % used for trail tracking.

setappdata(0,'ytrail',0); % used for trail tracking.

setappdata(0,'ztrail',0); % used for trail tracking.

%

set(L1, 'facec', [0.717,0.116,0.123]);

set(L1, 'EdgeColor','none');

set(L2, 'facec', [0.216,1,.583]);

set(L2, 'EdgeColor','none');

set(L3, 'facec', [0.306,0.733,1]);

set(L3, 'EdgeColor','none');

set(L4, 'facec', [1,0.542,0.493]);

set(L4, 'EdgeColor','none');

set(L5, 'facec', [0.216,1,.583]);

set(L5, 'EdgeColor','none');

set(L6, 'facec', [1,1,0.255]);

set(L6, 'EdgeColor','none');

set(L7, 'facec', [0.306,0.733,1]);

set(L7, 'EdgeColor','none');

set(A1, 'facec', [.8,.8,.8],'FaceAlpha',.25);

set(A1, 'EdgeColor','none');

%

setappdata(0,'ThetaOld',[90,-90,-90,0,0,0]);

%

end

%%

function T = tmat(alpha, a, d, theta)

% tmat(alpha, a, d, theta) (T-Matrix used in Robotics)

% The homogeneous transformation called the "T-MATRIX"

% as used in the Kinematic Equations for robotic type

% systems (or equivalent).

%

% This is equation 3.6 in Craig's "Introduction to Robotics."

% alpha, a, d, theta are the Denavit-Hartenberg parameters.

%

% (NOTE: ALL ANGLES MUST BE IN DEGREES.)

%

alpha = alpha*pi/180; %Note: alpha is in radians.

theta = theta*pi/180; %Note: theta is in radians.

c = cos(theta);

s = sin(theta);

ca = cos(alpha);

sa = sin(alpha);

T = [c -s 0 a; s*ca c*ca -sa -sa*d; s*sa c*sa ca ca*d; 0 0 0 1];

end

%%

function del_app(varargin)

%This is the main figure window close function, to remove any

% app data that may be left due to using it for geometry.

%CloseRequestFcn

% here is the data to remove:

% Link1_data: [1x1 struct]

% Link2_data: [1x1 struct]

% Link3_data: [1x1 struct]

% Link4_data: [1x1 struct]

% Link5_data: [1x1 struct]

% Link6_data: [1x1 struct]

% Link7_data: [1x1 struct]

% Area_data: [1x1 struct]

% patch_h: [1x9 double]

% ThetaOld: [90 -182 -90 -106 80 106]

% xtrail: 0

% ytrail: 0

% ztrail: 0

% Now remove them.

rmappdata(0,'Link1_data');

rmappdata(0,'Link2_data');

rmappdata(0,'Link3_data');

rmappdata(0,'Link4_data');

rmappdata(0,'Link5_data');

rmappdata(0,'Link6_data');

rmappdata(0,'Link7_data');

rmappdata(0,'ThetaOld');

rmappdata(0,'Area_data');

rmappdata(0,'patch_h');

rmappdata(0,'xtrail');

rmappdata(0,'ytrail');

rmappdata(0,'ztrail');

delete(fig_1);

end

%%

function [hout,ax_out] = uibutton(varargin)

%uibutton: Create pushbutton with more flexible labeling than uicontrol.

% Usage:

% uibutton accepts all the same arguments as uicontrol except for the

% following property changes:

%

% Property Values

% ----------- ------------------------------------------------------

% Style 'pushbutton', 'togglebutton' or 'text', default =

% 'pushbutton'.

% String Same as for text() including cell array of strings and

% TeX or LaTeX interpretation.

% Interpreter 'tex', 'latex' or 'none', default = default for text()

%

% Syntax:

% handle = uibutton('PropertyName',PropertyValue,...)

% handle = uibutton(parent,'PropertyName',PropertyValue,...)

% [text_obj,axes_handle] = uibutton('Style','text',...

% 'PropertyName',PropertyValue,...)

%

% uibutton creates a temporary axes and text object containing the text to

% be displayed, captures the axes as an image, deletes the axes and then

% displays the image on the uicontrol. The handle to the uicontrol is

% returned. If you pass in a handle to an existing uicontol as the first

% argument then uibutton will use that uicontrol and not create a new one.

%

% If the Style is set to 'text' then the axes object is not deleted and the

% text object handle is returned (as well as the handle to the axes in a

% second output argument).

%

% See also UICONTROL.

% Version: 1.6, 20 April 2006

% Author: Douglas M. Schwarz

% Email: dmschwarz=ieee*org, dmschwarz=urgrad*rochester*edu

% Real_email = regexprep(Email,{'=','*'},{'@','.'})

% Detect if first argument is a uicontrol handle.

keep_handle = false;

if nargin > 0

h = varargin{1};

if isscalar(h) && ishandle(h) && strcmp(get(h,'Type'),'uicontrol')

keep_handle = true;

varargin(1) = [];

end

end

% Parse arguments looking for 'Interpreter' property. If found, note its

% value and then remove it from where it was found.

interp_value = get(0,'DefaultTextInterpreter');

arg = 1;

remove = [];

while arg <= length(varargin)

v = varargin{arg};

if isstruct(v)

fn = fieldnames(v);

for i = 1:length(fn)

if strncmpi(fn{i},'interpreter',length(fn{i}))

interp_value = v.(fn{i});

v = rmfield(v,fn{i});

end

end

varargin{arg} = v;

arg = arg + 1;

elseif ischar(v)

if strncmpi(v,'interpreter',length(v))

interp_value = varargin{arg+1};

remove = [remove,arg,arg+1];

end

arg = arg + 2;

elseif arg == 1 && isscalar(v) && ishandle(v) && ...

any(strcmp(get(h,'Type'),{'figure','uipanel'}))

arg = arg + 1;

else

error('Invalid property or uicontrol parent.')

end

end

varargin(remove) = [];

% Create uicontrol, get its properties then hide it.

if keep_handle

set(h,varargin{:})

else

h = uicontrol(varargin{:});

end

s = get(h);

if ~any(strcmp(s.Style,{'pushbutton','togglebutton','text'}))

delete(h)

error('''Style'' must be pushbutton, togglebutton or text.')

end

set(h,'Visible','off')

% Create axes.

parent = get(h,'Parent');

ax = axes('Parent',parent,...

'Units',s.Units,...

'Position',s.Position,...

'XTick',[],'YTick',[],...

'XColor',s.BackgroundColor,...

'YColor',s.BackgroundColor,...

'Box','on',...

'Color',s.BackgroundColor);

% Adjust size of axes for best appearance.

set(ax,'Units','pixels')

pos = round(get(ax,'Position'));

if strcmp(s.Style,'text')

set(ax,'Position',pos + [0 1 -1 -1])

else

set(ax,'Position',pos + [4 4 -8 -8])

end

switch s.HorizontalAlignment

case 'left'

x = 0.0;

case 'center'

x = 0.5;

case 'right'

x = 1;

end

% Create text object.

text_obj = text('Parent',ax,...

'Position',[x,0.5],...

'String',s.String,...

'Interpreter',interp_value,...

'HorizontalAlignment',s.HorizontalAlignment,...

'VerticalAlignment','middle',...

'FontName',s.FontName,...

'FontSize',s.FontSize,...

'FontAngle',s.FontAngle,...

'FontWeight',s.FontWeight,...

'Color',s.ForegroundColor);

% If we are creating something that looks like a text uicontrol then we're

% all done and we return the text object and axes handles rather than a

% uicontrol handle.

if strcmp(s.Style,'text')

delete(h)

if nargout

hout = text_obj;

ax_out = ax;

end

return

end

% Capture image of axes and then delete the axes.

frame = getframe(ax);

delete(ax)

% Build RGB image, set background pixels to NaN and put it in 'CData' for

% the uicontrol.

if isempty(frame.colormap)

rgb = frame.cdata;

else

rgb = reshape(frame.colormap(frame.cdata,:),[pos([4,3]),3]);

end

size_rgb = size(rgb);

rgb = double(rgb)/255;

back = repmat(permute(s.BackgroundColor,[1 3 2]),size_rgb(1:2));

isback = all(rgb == back,3);

rgb(repmat(isback,[1 1 3])) = NaN;

set(h,'CData',rgb,'String','','Visible',s.Visible)

% Assign output argument if necessary.

if nargout

hout = h;

end

%%

end

end

demo = uicontrol(fig_1,'String','Demo','callback',@demo_button_press,...

'Position',[20 5 60 20]);

rnd_demo = uicontrol(fig_1,'String','Random Move','callback',@rnd_demo_button_press,...

'Position',[100 5 80 20]);

clr_trail = uicontrol(fig_1,'String','Clr Trail','callback',@clr_trail_button_press,...

'Position',[200 5 60 20]);

%

home = uicontrol(fig_1,'String','Home','callback',@home_button_press,...

'Position',[280 5 70 20]);

%

% Kinematics Panel

%

K_p = uipanel(fig_1,...

'units','pixels',...

'Position',[20 45 265 200],...

'Title','Kinematics','FontSize',11);

%

% Angle Range Default Name

% Theta 1: 320 (-160 to 160) 90 Waist Joint

% Theta 2: 220 (-110 to 110) -90 Shoulder Joint

% Theta 3: 270 (-135 to 135) -90 Elbow Joint

% Theta 4: 532 (-266 to 266) 0 Wrist Roll

% Theta 5: 200 (-100 to 100) 0 Wrist Bend

% Theta 6: 532 (-266 to 266) 0 Wrist Swivel

t1_home = 90; % offset to define the "home" position as UP.

t2_home = -90;

t3_home = -90;

LD = 105; % Left, used to set the GUI.

HT = 18; % Height

BT = 156; % Bottom

%% GUI buttons for Theta 1. pos is: [left bottom width height]

t1_slider = uicontrol(K_p,'style','slider',...

'Max',160,'Min',-160,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t1_slider_button_press,...

'Position',[LD BT 120 HT]);

t1_min = uicontrol(K_p,'style','text',...

'String','-160',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t1_max = uicontrol(K_p,'style','text',...

'String','+160',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t1_text = uibutton(K_p,'style','text',... % Nice program Doug. Need this

'String','\theta_1',... % due to no TeX in uicontrols.

'Position',[LD-100 BT 20 HT]); % L, B, W, H

% t1_text = uicontrol(K_p,'style','text',... % when matlab fixes uicontrol

% 'String','t1',... % for TeX, then I can use this.

% 'Position',[LD-100 BT 20 HT]); % L, B, W, H

t1_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t1_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 2.

BT = 126; % Bottom

t2_slider = uicontrol(K_p,'style','slider',...

'Max',115,'Min',-115,'Value',0,... % Mech. stop limits !

'SliderStep',[0.05 0.2],...

'callback',@t2_slider_button_press,...

'Position',[LD BT 120 HT]);

t2_min = uicontrol(K_p,'style','text',...

'String','-110',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t2_max = uicontrol(K_p,'style','text',...

'String','+110',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t2_text = uibutton(K_p,'style','text',...

'String','\theta_2',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t2_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t2_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 3.

BT = 96; % Bottom

t3_slider = uicontrol(K_p,'style','slider',...

'Max',135,'Min',-135,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t3_slider_button_press,...

'Position',[LD BT 120 HT]);

t3_min = uicontrol(K_p,'style','text',...

'String','-135',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t3_max = uicontrol(K_p,'style','text',...

'String','+135',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t3_text = uibutton(K_p,'style','text',...

'String','\theta_3',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t3_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t3_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 4.

BT = 66; % Bottom

t4_slider = uicontrol(K_p,'style','slider',...

'Max',266,'Min',-266,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t4_slider_button_press,...

'Position',[LD BT 120 HT]);

t4_min = uicontrol(K_p,'style','text',...

'String','-266',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t4_max = uicontrol(K_p,'style','text',...

'String','+266',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t4_text = uibutton(K_p,'style','text',...

'String','\theta_4',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t4_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t4_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 5.

BT = 36; % Bottom

t5_slider = uicontrol(K_p,'style','slider',...

'Max',100,'Min',-100,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t5_slider_button_press,...

'Position',[LD BT 120 HT]);

t5_min = uicontrol(K_p,'style','text',...

'String','-100',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t5_max = uicontrol(K_p,'style','text',...

'String','+100',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t5_text = uibutton(K_p,'style','text',...

'String','\theta_5',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t5_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t5_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 6.

BT = 6; % Bottom

t6_slider = uicontrol(K_p,'style','slider',...

'Max',266,'Min',-266,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t6_slider_button_press,...

'Position',[LD BT 120 HT]);

t6_min = uicontrol(K_p,'style','text',...

'String','-266',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t6_max = uicontrol(K_p,'style','text',...

'String','+266',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t6_text = uibutton(K_p,'style','text',...

'String','\theta_6',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t6_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t6_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% Slider for Theta 1 motion.

%

function t1_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t1_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t2old = T_Old(2); t3old = T_Old(3); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

pumaANI(slider_value+t1_home,t2old,t3old,t4old,t5old,t6old,10,'n')

end

%

%% Slider for Theta 2 motion.

%

function t2_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t2_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t3old = T_Old(3); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

pumaANI(t1old,slider_value+t2_home,t3old,t4old,t5old,t6old,10,'n')

end

%

%% Slider for Theta 3 motion.

function t3_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t3_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t2old = T_Old(2); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

pumaANI(t1old,t2old,slider_value+t3_home,t4old,t5old,t6old,10,'n')

end

%

%% Slider for Theta 4 motion.

function t4_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t4_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t5old = T_Old(5); t6old = T_Old(6);

pumaANI(t1old,t2old,t3old,slider_value,t5old,t6old,10,'n')

end

%

%% Slider for Theta 5 motion.

function t5_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t5_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t4old = T_Old(4); t6old = T_Old(6);

pumaANI(t1old,t2old,t3old,t4old,slider_value,t6old,10,'n')

end

%

%% Slider for Theta 6 motion.

function t6_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t6_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t4old = T_Old(4); t5old = T_Old(5);

pumaANI(t1old,t2old,t3old,t4old,t5old,slider_value,10,'n')

end

%

%% Edit box for Theta 1 motion.

%

function t1_edit_button_press(h,dummy)

user_entry = check_edit(h,-160,160,0,t1_edit);

set(t1_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t2old = T_Old(2); t3old = T_Old(3); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

%

pumaANI(user_entry+t1_home,t2old,t3old,t4old,t5old,t6old,10,'n')

end

%

%% Edit box for Theta 2 motion.

%

function t2_edit_button_press(h,dummy)

user_entry = check_edit(h,-110,110,0,t2_edit);

set(t2_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t3old = T_Old(3); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

%

pumaANI(t1old,user_entry+t2_home,t3old,t4old,t5old,t6old,10,'n')

end

%% Edit box for Theta 3 motion.

%

function t3_edit_button_press(h,dummy)

user_entry = check_edit(h,-135,135,0,t3_edit);

set(t3_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t2old = T_Old(2); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

%

pumaANI(t1old,t2old,user_entry+t3_home,t4old,t5old,t6old,10,'n')

end

%%

%% Edit box for Theta 4 motion.

%

function t4_edit_button_press(h,dummy)

user_entry = check_edit(h,-266,266,0,t4_edit);

set(t4_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t5old = T_Old(5); t6old = T_Old(6);

%

pumaANI(t1old,t2old,t3old,user_entry,t5old,t6old,10,'n')

end

%% Edit box for Theta 5 motion.

%

function t5_edit_button_press(h,dummy)

user_entry = check_edit(h,-100,100,0,t5_edit);

set(t5_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t4old = T_Old(4); t6old = T_Old(6);

%

pumaANI(t1old,t2old,t3old,t4old,user_entry,t6old,10,'n')

end

%%

%% Edit box for Theta 6 motion.

%

function t6_edit_button_press(h,dummy)

user_entry = check_edit(h,-266,266,0,t6_edit);

set(t6_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t4old = T_Old(4); t5old = T_Old(5);

%

pumaANI(t1old,t2old,t3old,t4old,t5old,user_entry,10,'n')

end

%%

function user_entry = check_edit(h,min_v,max_v,default,h_edit)

% This function will check the value typed in the text input box

% against min and max values, and correct errors.

%

% h: handle of gui

% min_v min value to check

% max_v max value to check

% default is the default value if user enters non number

% h_edit is the edit value to update.

%

user_entry = str2double(get(h,'string'));

if isnan(user_entry)

errordlg(['You must enter a numeric value, defaulting to ',num2str(default),'.'],'Bad Input','modal')

set(h_edit,'string',default);

user_entry = default;

end

%

if user_entry < min_v

errordlg(['Minimum limit is ',num2str(min_v),' degrees, using ',num2str(min_v),'.'],'Bad Input','modal')

user_entry = min_v;

set(h_edit,'string',user_entry);

end

if user_entry > max_v

errordlg(['Maximum limit is ',num2str(max_v),' degrees, using ',num2str(max_v),'.'],'Bad Input','modal')

user_entry = max_v;

set(h_edit,'string',user_entry);

end

end

%

%% Demo button's callback

function demo_button_press(h,dummy)

%

% disp('pushed demo bottom');

% R = 500;

% x = 1000;

n = 2; % demo ani steps

num = 30; % home to start, and end to home ani steps

% j = 1;

% M = 1000;

for t = 0:.1:7*pi

Px = 30*t*cos(t);

Py = 1200-300*t*(t)/(50*pi);

Pz = 30*t*sin(t);

[theta1,theta2,theta3,theta4,theta5,theta6] = PumaIK(Px,Py,Pz);

if t==0 %move to start of demo

pumaANI(theta1,theta2,theta3-180,0,0,0,num,'n')

end

% Theta 4, 5 & 6 are zero due to plotting at wrist origen.

pumaANI(theta1,theta2,theta3-180,0,0,0,n,'y')

set(t1_edit,'string',round(theta1)); % Update slider and text.

set(t1_slider,'Value',round(theta1));

set(t2_edit,'string',round(theta2));

set(t2_slider,'Value',round(theta2));

set(t3_edit,'string',round(theta3-180));

set(t3_slider,'Value',round(theta3-180));

end

gohome

% pumaANI(90,-90,-90,0,0,0,num,'n')

end

%

%

%%

function home_button_press(h,dummy)

%disp('pushed home bottom');

gohome

end

%

%%

function clr_trail_button_press(h,dummy)

%disp('pushed clear trail bottom');

handles = getappdata(0,'patch_h'); %

Tr = handles(9);

%

setappdata(0,'xtrail',0); % used for trail tracking.

setappdata(0,'ytrail',0); % used for trail tracking.

setappdata(0,'ztrail',0); % used for trail tracking.

%

set(Tr,'xdata',0,'ydata',0,'zdata',0);

end

%

%

function rnd_demo_button_press(h, dummy)

%disp('pushed random demo bottom');

% a = 10; b = 50; x = a + (b-a) * rand(5)

% Angle Range Default Name

% Theta 1: 320 (-160 to 160) 90 Waist Joint

% Theta 2: 220 (-110 to 110) -90 Shoulder Joint

% Theta 3: 270 (-135 to 135) -90 Elbow Joint

% Theta 4: 532 (-266 to 266) 0 Wrist Roll

% Theta 5: 200 (-100 to 100) 0 Wrist Bend

% Theta 6: 532 (-266 to 266) 0 Wrist Swival

t1_home = 90; % offsets to define the "home" postition as UP.

t2_home = -90;

t3_home = -90;

theta1 = -160 + 320*rand(1); % offset for home

theta2 = -110 + 220*rand(1); % in the UP pos.

theta3 = -135 + 270*rand(1);

theta4 = -266 + 532*rand(1);

theta5 = -100 + 200*rand(1);

theta6 = -266 + 532*rand(1);

n = 50;

pumaANI(theta1+t1_home,theta2+t2_home,theta3+t3_home,theta4,theta5,theta6,n,'y')

set(t1_edit,'string',round(theta1)); % Update slider and text.

set(t1_slider,'Value',round(theta1));

set(t2_edit,'string',round(theta2));

set(t2_slider,'Value',round(theta2));

set(t3_edit,'string',round(theta3));

set(t3_slider,'Value',round(theta3));

set(t4_edit,'string',round(theta4));

set(t4_slider,'Value',round(theta4));

set(t5_edit,'string',round(theta5));

set(t5_slider,'Value',round(theta5));

set(t6_edit,'string',round(theta6));

set(t6_slider,'Value',round(theta6));

end

%%

%Here are the functions used for this robot example:

%

%%

% When called this function will simply initialize a plot of the Puma 762

% robot by plotting it in it's home orientation and setting the current

% angles accordingly.

function gohome()

pumaANI(90,-90,-90,0,0,0,20,'n') % show it animate home

%PumaPOS(90,-90,-90,0,0,0) %drive it home, no animate.

set(t1_edit,'string',0);

set(t1_slider,'Value',0); %At the home position, so all

set(t2_edit,'string',0); %sliders and input boxes = 0.

set(t2_slider,'Value',0);

set(t3_edit,'string',0);

set(t3_slider,'Value',0);

set(t4_edit,'string',0);

set(t4_slider,'Value',0);

set(t5_edit,'string',0);

set(t5_slider,'Value',0);

set(t6_edit,'string',0);

set(t6_slider,'Value',0);

setappdata(0,'ThetaOld',[90,-90,-90,0,0,0]);

end

%%

% This function will load the 3D CAD data.

%

function loaddata

% Loads all the link data from file linksdata.mat.

% This data comes from a Pro/E 3D CAD model and was made with cad2matdemo.m

% from the file exchange. All link data manually stored in linksdata.mat

[linkdata]=load('linksdata.mat','s1','s2', 's3','s4','s5','s6','s7','A1');

%Place the robot link 'data' in a storage area

setappdata(0,'Link1_data',linkdata.s1);

setappdata(0,'Link2_data',linkdata.s2);

setappdata(0,'Link3_data',linkdata.s3);

setappdata(0,'Link4_data',linkdata.s4);

setappdata(0,'Link5_data',linkdata.s5);

setappdata(0,'Link6_data',linkdata.s6);

setappdata(0,'Link7_data',linkdata.s7);

setappdata(0,'Area_data',linkdata.A1);

end

%

%%

% Use forward kinematics to place the robot in a specified configuration.

%

function PumaPOS(theta1,theta2,theta3,theta4,theta5,theta6)

s1 = getappdata(0,'Link1_data');

s2 = getappdata(0,'Link2_data');

s3 = getappdata(0,'Link3_data');

s4 = getappdata(0,'Link4_data');

s5 = getappdata(0,'Link5_data');

s6 = getappdata(0,'Link6_data');

s7 = getappdata(0,'Link7_data');

A1 = getappdata(0,'Area_data');

%

a2 = 650;

a3 = 0;

d3 = 190;

d4 = 600;

Px = 5000;

Py = 5000;

Pz = 5000;

t1 = theta1;

t2 = theta2;

t3 = theta3 %-180;

t4 = theta4;

t5 = theta5;

t6 = theta6;

%

% Forward Kinematics

T_01 = tmat(0, 0, 0, t1);

T_12 = tmat(-90, 0, 0, t2);

T_23 = tmat(0, a2, d3, t3);

T_34 = tmat(-90, a3, d4, t4);

T_45 = tmat(90, 0, 0, t5);

T_56 = tmat(-90, 0, 0, t6);

%T_01 = T_01;

T_02 = T_01*T_12;

T_03 = T_02*T_23;

T_04 = T_03*T_34;

T_05 = T_04*T_45;

T_06 = T_05*T_56;

%

Link1 = s1.V1;

Link2 = (T_01*s2.V2')';

Link3 = (T_02*s3.V3')';

Link4 = (T_03*s4.V4')';

Link5 = (T_04*s5.V5')';

Link6 = (T_05*s6.V6')';

Link7 = (T_06*s7.V7')';

handles = getappdata(0,'patch_h'); %

L1 = handles(1);

L2 = handles(2);

L3 = handles(3);

L4 = handles(4);

L5 = handles(5);

L6 = handles(6);

L7 = handles(7);

%

set(L1,'vertices',Link1(:,1:3),'facec', [0.717,0.116,0.123]);

set(L1, 'EdgeColor','none');

set(L2,'vertices',Link2(:,1:3),'facec', [0.216,1,.583]);

set(L2, 'EdgeColor','none');

set(L3,'vertices',Link3(:,1:3),'facec', [0.306,0.733,1]);

set(L3, 'EdgeColor','none');

set(L4,'vertices',Link4(:,1:3),'facec', [1,0.542,0.493]);

set(L4, 'EdgeColor','none');

set(L5,'vertices',Link5(:,1:3),'facec', [0.216,1,.583]);

set(L5, 'EdgeColor','none');

set(L6,'vertices',Link6(:,1:3),'facec', [1,1,0.255]);

set(L6, 'EdgeColor','none');

set(L7,'vertices',Link7(:,1:3),'facec', [0.306,0.733,1]);

set(L7, 'EdgeColor','none');

end

%%

% This function computes the Inverse Kinematics for the Puma 762 robot

% given X,Y,Z coordinates for a point in the workspace. Note: The IK are

% computed for the origin of Coordinate systems 4,5 & 6.

function [theta1,theta2,theta3,theta4,theta5,theta6] = PumaIK(Px,Py,Pz)

theta4 = 0;

theta5 = 0;

theta6 = 0;

sign1 = 1;

sign3 = 1;

nogo = 0;

noplot = 0;

% Because the sqrt term in theta1 & theta3 can be + or - we run through

% all possible combinations (i = 4) and take the first combination that

% satisfies the joint angle constraints.

while nogo == 0;

for i = 1:1:4

if i == 1

sign1 = 1;

sign3 = 1;

elseif i == 2

sign1 = 1;

sign3 = -1;

elseif i == 3

sign1 = -1;

sign3 = 1;

else

sign1 = -1;

sign3 = -1;

end

a2 = 650;

a3 = 0;

d3 = 190;

d4 = 600;

rho = sqrt(Px^2+Py^2);

phi = atan2(Py,Px);

K = (Px^2+Py^2+Pz^2-a2^2-a3^2-d3^2-d4^2)/(2*a2);

c4 = cos(theta4);

s4 = sin(theta4);

c5 = cos(theta5);

s5 = sin(theta5);

c6 = cos(theta6);

s6 = sin(theta6);

theta1 = (atan2(Py,Px)-atan2(d3,sign1*sqrt(Px^2+Py^2-d3^2)));

c1 = cos(theta1);

s1 = sin(theta1);

theta3 = (atan2(a3,d4)-atan2(K,sign3*sqrt(a3^2+d4^2-K^2)));

c3 = cos(theta3);

s3 = sin(theta3);

t23 = atan2((-a3-a2*c3)*Pz-(c1*Px+s1*Py)*(d4-a2*s3),(a2*s3-d4)*Pz+(a3+a2*c3)*(c1*Px+s1*Py));

theta2 = (t23 - theta3);

c2 = cos(theta2);

s2 = sin(theta2);

s23 = ((-a3-a2*c3)*Pz+(c1*Px+s1*Py)*(a2*s3-d4))/(Pz^2+(c1*Px+s1*Py)^2);

c23 = ((a2*s3-d4)*Pz+(a3+a2*c3)*(c1*Px+s1*Py))/(Pz^2+(c1*Px+s1*Py)^2);

r13 = -c1*(c23*c4*s5+s23*c5)-s1*s4*s5;

r23 = -s1*(c23*c4*s5+s23*c5)+c1*s4*s5;

r33 = s23*c4*s5 - c23*c5;

theta4 = atan2(-r13*s1+r23*c1,-r13*c1*c23-r23*s1*c23+r33*s23);

r11 = c1*(c23*(c4*c5*c6-s4*s6)-s23*s5*c6)+s1*(s4*c5*c6+c4*s6);

r21 = s1*(c23*(c4*c5*c6-s4*s6)-s23*s5*c6)-c1*(s4*c5*c6+c4*s6);

r31 = -s23*(c4*c5*c6-s4*s6)-c23*s5*c6;

s5 = -(r13*(c1*c23*c4+s1*s4)+r23*(s1*c23*c4-c1*s4)-r33*(s23*c4));

c5 = r13*(-c1*s23)+r23*(-s1*s23)+r33*(-c23);

theta5 = atan2(s5,c5);

s6 = -r11*(c1*c23*s4-s1*c4)-r21*(s1*c23*s4+c1*c4)+r31*(s23*s4);

c6 = r11*((c1*c23*c4+s1*s4)*c5-c1*s23*s5)+r21*((s1*c23*c4-c1*s4)*c5-s1*s23*s5)-r31*(s23*c4*c5+c23*s5);

theta6 = atan2(s6,c6);

theta1 = theta1*180/pi;

theta2 = theta2*180/pi;

theta3 = theta3*180/pi;

theta4 = theta4*180/pi;

theta5 = theta5*180/pi;

theta6 = theta6*180/pi;

if theta2>=160 && theta2<=180

theta2 = -theta2;

end

if theta1<=160 && theta1>=-160 && (theta2<=20 && theta2>=-200) && theta3<=45 && theta3>=-225 && theta4<=266 && theta4>=-266 && theta5<=100 && theta5>=-100 && theta6<=266 && theta6>=-266

nogo = 1;

theta3 = theta3+180;

break

end

if i == 4 && nogo == 0

h = errordlg('Point unreachable due to joint angle constraints.','JOINT ERROR');

waitfor(h);

nogo = 1;

noplot = 1;

break

end

end

end

end

%

%%

function pumaANI(theta1,theta2,theta3,theta4,theta5,theta6,n,trail)

% This function will animate the Puma 762 robot given joint angles.

% n is number of steps for the animation

% trail is 'y' or 'n' (n = anything else) for leaving a trail.

%

%disp('in animate');

a2 = 650; %D-H paramaters

a3 = 0;

d3 = 190;

d4 = 600;

% Err2 = 0;

%

ThetaOld = getappdata(0,'ThetaOld');

%

theta1old = ThetaOld(1);

theta2old = ThetaOld(2);

theta3old = ThetaOld(3);

theta4old = ThetaOld(4);

theta5old = ThetaOld(5);

theta6old = ThetaOld(6);

%

t1 = linspace(theta1old,theta1,n);

t2 = linspace(theta2old,theta2,n);

t3 = linspace(theta3old,theta3,n);% -180;

t4 = linspace(theta4old,theta4,n);

t5 = linspace(theta5old,theta5,n);

t6 = linspace(theta6old,theta6,n);

n = length(t1);

for i = 2:1:n

% Forward Kinematics

%

T_01 = tmat(0, 0, 0, t1(i));

T_12 = tmat(-90, 0, 0, t2(i));

T_23 = tmat(0, a2, d3, t3(i));

T_34 = tmat(-90, a3, d4, t4(i));

T_45 = tmat(90, 0, 0, t5(i));

T_56 = tmat(-90, 0, 0, t6(i));

%

% % T_67 = [ 1 0 0 0

% % 0 1 0 0

% % 0 0 1 188

% % 0 0 0 1];

%T_01 = T_01; % it is, but don't need to say so.

T_02 = T_01*T_12;

T_03 = T_02*T_23;

T_04 = T_03*T_34;

T_05 = T_04*T_45;

T_06 = T_05*T_56;

% T_07 = T_06*T_67;

%

s1 = getappdata(0,'Link1_data');

s2 = getappdata(0,'Link2_data');

s3 = getappdata(0,'Link3_data');

s4 = getappdata(0,'Link4_data');

s5 = getappdata(0,'Link5_data');

s6 = getappdata(0,'Link6_data');

s7 = getappdata(0,'Link7_data');

%A1 = getappdata(0,'Area_data');

Link1 = s1.V1;

Link2 = (T_01*s2.V2')';

Link3 = (T_02*s3.V3')';

Link4 = (T_03*s4.V4')';

Link5 = (T_04*s5.V5')';

Link6 = (T_05*s6.V6')';

Link7 = (T_06*s7.V7')';

% Tool = T_07;

% if sqrt(Tool(1,4)^2+Tool(2,4)^2)<514

% Err2 = 1;

% break

% end

%

handles = getappdata(0,'patch_h'); %

L1 = handles(1);

L2 = handles(2);

L3 = handles(3);

L4 = handles(4);

L5 = handles(5);

L6 = handles(6);

L7 = handles(7);

Tr = handles(9);

%

set(L1,'vertices',Link1(:,1:3),'facec', [0.717,0.116,0.123]);

set(L1, 'EdgeColor','none');

set(L2,'vertices',Link2(:,1:3),'facec', [0.216,1,.583]);

set(L2, 'EdgeColor','none');

set(L3,'vertices',Link3(:,1:3),'facec', [0.306,0.733,1]);

set(L3, 'EdgeColor','none');

set(L4,'vertices',Link4(:,1:3),'facec', [1,0.542,0.493]);

set(L4, 'EdgeColor','none');

set(L5,'vertices',Link5(:,1:3),'facec', [0.216,1,.583]);

set(L5, 'EdgeColor','none');

set(L6,'vertices',Link6(:,1:3),'facec', [1,1,0.255]);

set(L6, 'EdgeColor','none');

set(L7,'vertices',Link7(:,1:3),'facec', [0.306,0.733,1]);

set(L7, 'EdgeColor','none');

% store trail in appdata

if trail == 'y'

x_trail = getappdata(0,'xtrail');

y_trail = getappdata(0,'ytrail');

z_trail = getappdata(0,'ztrail');

%

xdata = [x_trail T_04(1,4)];

ydata = [y_trail T_04(2,4)];

zdata = [z_trail T_04(3,4)];

%

setappdata(0,'xtrail',xdata); % used for trail tracking.

setappdata(0,'ytrail',ydata); % used for trail tracking.

setappdata(0,'ztrail',zdata); % used for trail tracking.

%

set(Tr,'xdata',xdata,'ydata',ydata,'zdata',zdata);

end

drawnow

end

setappdata(0,'ThetaOld',[theta1,theta2,theta3,theta4,theta5,theta6]);

end

%%

%

%

%%

function InitHome

% Use forward kinematics to place the robot in a specified

% configuration.

% Figure setup data, create a new figure for the GUI

set(0,'Units','pixels')

dim = get(0,'ScreenSize');

fig_1 = figure('doublebuffer','on','Position',[0,35,dim(3)-200,dim(4)-110],...

'MenuBar','none','Name',' 3D Puma Robot Graphical Demo',...

'NumberTitle','off','CloseRequestFcn',@del_app);

hold on;

%light('Position',[-1 0 0]);

light % add a default light

daspect([1 1 1]) % Setting the aspect ratio

view(135,25)

xlabel('X'),ylabel('Y'),zlabel('Z');

title('WWU Robotics Lab PUMA 762');

axis([-1500 1500 -1500 1500 -1120 1500]);

plot3([-1500,1500],[-1500,-1500],[-1120,-1120],'k')

plot3([-1500,-1500],[-1500,1500],[-1120,-1120],'k')

plot3([-1500,-1500],[-1500,-1500],[-1120,1500],'k')

plot3([-1500,-1500],[1500,1500],[-1120,1500],'k')

plot3([-1500,1500],[-1500,-1500],[1500,1500],'k')

plot3([-1500,-1500],[-1500,1500],[1500,1500],'k')

s1 = getappdata(0,'Link1_data');

s2 = getappdata(0,'Link2_data');

s3 = getappdata(0,'Link3_data');

s4 = getappdata(0,'Link4_data');

s5 = getappdata(0,'Link5_data');

s6 = getappdata(0,'Link6_data');

s7 = getappdata(0,'Link7_data');

A1 = getappdata(0,'Area_data');

%

a2 = 650;

a3 = 0;

d3 = 190;

d4 = 600;

Px = 5000;

Py = 5000;

Pz = 5000;

%The 'home' position, for init.

t1 = 90;

t2 = -90;

t3 = -90;

t4 = 0;

t5 = 0;

t6 = 0;

% Forward Kinematics

T_01 = tmat(0, 0, 0, t1);

T_12 = tmat(-90, 0, 0, t2);

T_23 = tmat(0, a2, d3, t3);

T_34 = tmat(-90, a3, d4, t4);

T_45 = tmat(90, 0, 0, t5);

T_56 = tmat(-90, 0, 0, t6);

% Each link fram to base frame transformation

T_02 = T_01*T_12;

T_03 = T_02*T_23;

T_04 = T_03*T_34;

T_05 = T_04*T_45;

T_06 = T_05*T_56;

% Actual vertex data of robot links

Link1 = s1.V1;

Link2 = (T_01*s2.V2')';

Link3 = (T_02*s3.V3')';

Link4 = (T_03*s4.V4')';

Link5 = (T_04*s5.V5')';

Link6 = (T_05*s6.V6')';

Link7 = (T_06*s7.V7')';

% points are no fun to watch, make it look 3d.

L1 = patch('faces', s1.F1, 'vertices' ,Link1(:,1:3));

L2 = patch('faces', s2.F2, 'vertices' ,Link2(:,1:3));

L3 = patch('faces', s3.F3, 'vertices' ,Link3(:,1:3));

L4 = patch('faces', s4.F4, 'vertices' ,Link4(:,1:3));

L5 = patch('faces', s5.F5, 'vertices' ,Link5(:,1:3));

L6 = patch('faces', s6.F6, 'vertices' ,Link6(:,1:3));

L7 = patch('faces', s7.F7, 'vertices' ,Link7(:,1:3));

A1 = patch('faces', A1.Fa, 'vertices' ,A1.Va(:,1:3));

Tr = plot3(0,0,0,'b.'); % holder for trail paths

%

setappdata(0,'patch_h',[L1,L2,L3,L4,L5,L6,L7,A1,Tr])

%

setappdata(0,'xtrail',0); % used for trail tracking.

setappdata(0,'ytrail',0); % used for trail tracking.

setappdata(0,'ztrail',0); % used for trail tracking.

%

set(L1, 'facec', [0.717,0.116,0.123]);

set(L1, 'EdgeColor','none');

set(L2, 'facec', [0.216,1,.583]);

set(L2, 'EdgeColor','none');

set(L3, 'facec', [0.306,0.733,1]);

set(L3, 'EdgeColor','none');

set(L4, 'facec', [1,0.542,0.493]);

set(L4, 'EdgeColor','none');

set(L5, 'facec', [0.216,1,.583]);

set(L5, 'EdgeColor','none');

set(L6, 'facec', [1,1,0.255]);

set(L6, 'EdgeColor','none');

set(L7, 'facec', [0.306,0.733,1]);

set(L7, 'EdgeColor','none');

set(A1, 'facec', [.8,.8,.8],'FaceAlpha',.25);

set(A1, 'EdgeColor','none');

%

setappdata(0,'ThetaOld',[90,-90,-90,0,0,0]);

%

end

%%

function T = tmat(alpha, a, d, theta)

% tmat(alpha, a, d, theta) (T-Matrix used in Robotics)

% The homogeneous transformation called the "T-MATRIX"

% as used in the Kinematic Equations for robotic type

% systems (or equivalent).

%

% This is equation 3.6 in Craig's "Introduction to Robotics."

% alpha, a, d, theta are the Denavit-Hartenberg parameters.

%

% (NOTE: ALL ANGLES MUST BE IN DEGREES.)

%

alpha = alpha*pi/180; %Note: alpha is in radians.

theta = theta*pi/180; %Note: theta is in radians.

c = cos(theta);

s = sin(theta);

ca = cos(alpha);

sa = sin(alpha);

T = [c -s 0 a; s*ca c*ca -sa -sa*d; s*sa c*sa ca ca*d; 0 0 0 1];

end

%%

function del_app(varargin)

%This is the main figure window close function, to remove any

% app data that may be left due to using it for geometry.

%CloseRequestFcn

% here is the data to remove:

% Link1_data: [1x1 struct]

% Link2_data: [1x1 struct]

% Link3_data: [1x1 struct]

% Link4_data: [1x1 struct]

% Link5_data: [1x1 struct]

% Link6_data: [1x1 struct]

% Link7_data: [1x1 struct]

% Area_data: [1x1 struct]

% patch_h: [1x9 double]

% ThetaOld: [90 -182 -90 -106 80 106]

% xtrail: 0

% ytrail: 0

% ztrail: 0

% Now remove them.

rmappdata(0,'Link1_data');

rmappdata(0,'Link2_data');

rmappdata(0,'Link3_data');

rmappdata(0,'Link4_data');

rmappdata(0,'Link5_data');

rmappdata(0,'Link6_data');

rmappdata(0,'Link7_data');

rmappdata(0,'ThetaOld');

rmappdata(0,'Area_data');

rmappdata(0,'patch_h');

rmappdata(0,'xtrail');

rmappdata(0,'ytrail');

rmappdata(0,'ztrail');

delete(fig_1);

end

%%

function [hout,ax_out] = uibutton(varargin)

%uibutton: Create pushbutton with more flexible labeling than uicontrol.

% Usage:

% uibutton accepts all the same arguments as uicontrol except for the

% following property changes:

%

% Property Values

% ----------- ------------------------------------------------------

% Style 'pushbutton', 'togglebutton' or 'text', default =

% 'pushbutton'.

% String Same as for text() including cell array of strings and

% TeX or LaTeX interpretation.

% Interpreter 'tex', 'latex' or 'none', default = default for text()

%

% Syntax:

% handle = uibutton('PropertyName',PropertyValue,...)

% handle = uibutton(parent,'PropertyName',PropertyValue,...)

% [text_obj,axes_handle] = uibutton('Style','text',...

% 'PropertyName',PropertyValue,...)

%

% uibutton creates a temporary axes and text object containing the text to

% be displayed, captures the axes as an image, deletes the axes and then

% displays the image on the uicontrol. The handle to the uicontrol is

% returned. If you pass in a handle to an existing uicontol as the first

% argument then uibutton will use that uicontrol and not create a new one.

%

% If the Style is set to 'text' then the axes object is not deleted and the

% text object handle is returned (as well as the handle to the axes in a

% second output argument).

%

% See also UICONTROL.

% Version: 1.6, 20 April 2006

% Author: Douglas M. Schwarz

% Email: dmschwarz=ieee*org, dmschwarz=urgrad*rochester*edu

% Real_email = regexprep(Email,{'=','*'},{'@','.'})

% Detect if first argument is a uicontrol handle.

keep_handle = false;

if nargin > 0

h = varargin{1};

if isscalar(h) && ishandle(h) && strcmp(get(h,'Type'),'uicontrol')

keep_handle = true;

varargin(1) = [];

end

end

% Parse arguments looking for 'Interpreter' property. If found, note its

% value and then remove it from where it was found.

interp_value = get(0,'DefaultTextInterpreter');

arg = 1;

remove = [];

while arg <= length(varargin)

v = varargin{arg};

if isstruct(v)

fn = fieldnames(v);

for i = 1:length(fn)

if strncmpi(fn{i},'interpreter',length(fn{i}))

interp_value = v.(fn{i});

v = rmfield(v,fn{i});

end

end

varargin{arg} = v;

arg = arg + 1;

elseif ischar(v)

if strncmpi(v,'interpreter',length(v))

interp_value = varargin{arg+1};

remove = [remove,arg,arg+1];

end

arg = arg + 2;

elseif arg == 1 && isscalar(v) && ishandle(v) && ...

any(strcmp(get(h,'Type'),{'figure','uipanel'}))

arg = arg + 1;

else

error('Invalid property or uicontrol parent.')

end

end

varargin(remove) = [];

% Create uicontrol, get its properties then hide it.

if keep_handle

set(h,varargin{:})

else

h = uicontrol(varargin{:});

end

s = get(h);

if ~any(strcmp(s.Style,{'pushbutton','togglebutton','text'}))

delete(h)

error('''Style'' must be pushbutton, togglebutton or text.')

end

set(h,'Visible','off')

% Create axes.

parent = get(h,'Parent');

ax = axes('Parent',parent,...

'Units',s.Units,...

'Position',s.Position,...

'XTick',[],'YTick',[],...

'XColor',s.BackgroundColor,...

'YColor',s.BackgroundColor,...

'Box','on',...

'Color',s.BackgroundColor);

% Adjust size of axes for best appearance.

set(ax,'Units','pixels')

pos = round(get(ax,'Position'));

if strcmp(s.Style,'text')

set(ax,'Position',pos + [0 1 -1 -1])

else

set(ax,'Position',pos + [4 4 -8 -8])

end

switch s.HorizontalAlignment

case 'left'

x = 0.0;

case 'center'

x = 0.5;

case 'right'

x = 1;

end

% Create text object.

text_obj = text('Parent',ax,...

'Position',[x,0.5],...

'String',s.String,...

'Interpreter',interp_value,...

'HorizontalAlignment',s.HorizontalAlignment,...

'VerticalAlignment','middle',...

'FontName',s.FontName,...

'FontSize',s.FontSize,...

'FontAngle',s.FontAngle,...

'FontWeight',s.FontWeight,...

'Color',s.ForegroundColor);

% If we are creating something that looks like a text uicontrol then we're

% all done and we return the text object and axes handles rather than a

% uicontrol handle.

if strcmp(s.Style,'text')

delete(h)

if nargout

hout = text_obj;

ax_out = ax;

end

return

end

% Capture image of axes and then delete the axes.

frame = getframe(ax);

delete(ax)

% Build RGB image, set background pixels to NaN and put it in 'CData' for

% the uicontrol.

if isempty(frame.colormap)

rgb = frame.cdata;

else

rgb = reshape(frame.colormap(frame.cdata,:),[pos([4,3]),3]);

end

size_rgb = size(rgb);

rgb = double(rgb)/255;

back = repmat(permute(s.BackgroundColor,[1 3 2]),size_rgb(1:2));

isback = all(rgb == back,3);

rgb(repmat(isback,[1 1 3])) = NaN;

set(h,'CData',rgb,'String','','Visible',s.Visible)

% Assign output argument if necessary.

if nargout

hout = h;

end

%%

end

end

% Finally.

demo = uicontrol(fig_1,'String','Demo','callback',@demo_button_press,...

'Position',[20 5 60 20]);

rnd_demo = uicontrol(fig_1,'String','Random Move','callback',@rnd_demo_button_press,...

'Position',[100 5 80 20]);

clr_trail = uicontrol(fig_1,'String','Clr Trail','callback',@clr_trail_button_press,...

'Position',[200 5 60 20]);

%

home = uicontrol(fig_1,'String','Home','callback',@home_button_press,...

'Position',[280 5 70 20]);

%

% Kinematics Panel

%

K_p = uipanel(fig_1,...

'units','pixels',...

'Position',[20 45 265 200],...

'Title','Kinematics','FontSize',11);

%

% Angle Range Default Name

% Theta 1: 320 (-160 to 160) 90 Waist Joint

% Theta 2: 220 (-110 to 110) -90 Shoulder Joint

% Theta 3: 270 (-135 to 135) -90 Elbow Joint

% Theta 4: 532 (-266 to 266) 0 Wrist Roll

% Theta 5: 200 (-100 to 100) 0 Wrist Bend

% Theta 6: 532 (-266 to 266) 0 Wrist Swivel

t1_home = 90; % offset to define the "home" position as UP.

t2_home = -90;

t3_home = -90;

LD = 105; % Left, used to set the GUI.

HT = 18; % Height

BT = 156; % Bottom

%% GUI buttons for Theta 1. pos is: [left bottom width height]

t1_slider = uicontrol(K_p,'style','slider',...

'Max',160,'Min',-160,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t1_slider_button_press,...

'Position',[LD BT 120 HT]);

t1_min = uicontrol(K_p,'style','text',...

'String','-160',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t1_max = uicontrol(K_p,'style','text',...

'String','+160',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t1_text = uibutton(K_p,'style','text',... % Nice program Doug. Need this

'String','\theta_1',... % due to no TeX in uicontrols.

'Position',[LD-100 BT 20 HT]); % L, B, W, H

% t1_text = uicontrol(K_p,'style','text',... % when matlab fixes uicontrol

% 'String','t1',... % for TeX, then I can use this.

% 'Position',[LD-100 BT 20 HT]); % L, B, W, H

t1_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t1_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 2.

BT = 126; % Bottom

t2_slider = uicontrol(K_p,'style','slider',...

'Max',115,'Min',-115,'Value',0,... % Mech. stop limits !

'SliderStep',[0.05 0.2],...

'callback',@t2_slider_button_press,...

'Position',[LD BT 120 HT]);

t2_min = uicontrol(K_p,'style','text',...

'String','-110',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t2_max = uicontrol(K_p,'style','text',...

'String','+110',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t2_text = uibutton(K_p,'style','text',...

'String','\theta_2',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t2_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t2_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 3.

BT = 96; % Bottom

t3_slider = uicontrol(K_p,'style','slider',...

'Max',135,'Min',-135,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t3_slider_button_press,...

'Position',[LD BT 120 HT]);

t3_min = uicontrol(K_p,'style','text',...

'String','-135',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t3_max = uicontrol(K_p,'style','text',...

'String','+135',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t3_text = uibutton(K_p,'style','text',...

'String','\theta_3',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t3_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t3_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 4.

BT = 66; % Bottom

t4_slider = uicontrol(K_p,'style','slider',...

'Max',266,'Min',-266,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t4_slider_button_press,...

'Position',[LD BT 120 HT]);

t4_min = uicontrol(K_p,'style','text',...

'String','-266',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t4_max = uicontrol(K_p,'style','text',...

'String','+266',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t4_text = uibutton(K_p,'style','text',...

'String','\theta_4',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t4_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t4_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 5.

BT = 36; % Bottom

t5_slider = uicontrol(K_p,'style','slider',...

'Max',100,'Min',-100,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t5_slider_button_press,...

'Position',[LD BT 120 HT]);

t5_min = uicontrol(K_p,'style','text',...

'String','-100',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t5_max = uicontrol(K_p,'style','text',...

'String','+100',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t5_text = uibutton(K_p,'style','text',...

'String','\theta_5',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t5_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t5_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% GUI buttons for Theta 6.

BT = 6; % Bottom

t6_slider = uicontrol(K_p,'style','slider',...

'Max',266,'Min',-266,'Value',0,...

'SliderStep',[0.05 0.2],...

'callback',@t6_slider_button_press,...

'Position',[LD BT 120 HT]);

t6_min = uicontrol(K_p,'style','text',...

'String','-266',...

'Position',[LD-30 BT+1 25 HT-4]); % L, from bottom, W, H

t6_max = uicontrol(K_p,'style','text',...

'String','+266',...

'Position',[LD+125 BT+1 25 HT-4]); % L, B, W, H

t6_text = uibutton(K_p,'style','text',...

'String','\theta_6',...

'Position',[LD-100 BT 20 HT]); % L, B, W, H

t6_edit = uicontrol(K_p,'style','edit',...

'String',0,...

'callback',@t6_edit_button_press,...

'Position',[LD-75 BT 30 HT]); % L, B, W, H

%

%% Slider for Theta 1 motion.

%

function t1_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t1_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t2old = T_Old(2); t3old = T_Old(3); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

pumaANI(slider_value+t1_home,t2old,t3old,t4old,t5old,t6old,10,'n')

end

%

%% Slider for Theta 2 motion.

%

function t2_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t2_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t3old = T_Old(3); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

pumaANI(t1old,slider_value+t2_home,t3old,t4old,t5old,t6old,10,'n')

end

%

%% Slider for Theta 3 motion.

function t3_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t3_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t2old = T_Old(2); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

pumaANI(t1old,t2old,slider_value+t3_home,t4old,t5old,t6old,10,'n')

end

%

%% Slider for Theta 4 motion.

function t4_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t4_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t5old = T_Old(5); t6old = T_Old(6);

pumaANI(t1old,t2old,t3old,slider_value,t5old,t6old,10,'n')

end

%

%% Slider for Theta 5 motion.

function t5_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t5_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t4old = T_Old(4); t6old = T_Old(6);

pumaANI(t1old,t2old,t3old,t4old,slider_value,t6old,10,'n')

end

%

%% Slider for Theta 6 motion.

function t6_slider_button_press(h,dummy)

slider_value = round(get(h,'Value'));

set(t6_edit,'string',slider_value);

T_Old = getappdata(0,'ThetaOld');

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t4old = T_Old(4); t5old = T_Old(5);

pumaANI(t1old,t2old,t3old,t4old,t5old,slider_value,10,'n')

end

%

%% Edit box for Theta 1 motion.

%

function t1_edit_button_press(h,dummy)

user_entry = check_edit(h,-160,160,0,t1_edit);

set(t1_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t2old = T_Old(2); t3old = T_Old(3); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

%

pumaANI(user_entry+t1_home,t2old,t3old,t4old,t5old,t6old,10,'n')

end

%

%% Edit box for Theta 2 motion.

%

function t2_edit_button_press(h,dummy)

user_entry = check_edit(h,-110,110,0,t2_edit);

set(t2_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t3old = T_Old(3); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

%

pumaANI(t1old,user_entry+t2_home,t3old,t4old,t5old,t6old,10,'n')

end

%% Edit box for Theta 3 motion.

%

function t3_edit_button_press(h,dummy)

user_entry = check_edit(h,-135,135,0,t3_edit);

set(t3_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t2old = T_Old(2); t4old = T_Old(4);

t5old = T_Old(5); t6old = T_Old(6);

%

pumaANI(t1old,t2old,user_entry+t3_home,t4old,t5old,t6old,10,'n')

end

%%

%% Edit box for Theta 4 motion.

%

function t4_edit_button_press(h,dummy)

user_entry = check_edit(h,-266,266,0,t4_edit);

set(t4_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t5old = T_Old(5); t6old = T_Old(6);

%

pumaANI(t1old,t2old,t3old,user_entry,t5old,t6old,10,'n')

end

%% Edit box for Theta 5 motion.

%

function t5_edit_button_press(h,dummy)

user_entry = check_edit(h,-100,100,0,t5_edit);

set(t5_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t4old = T_Old(4); t6old = T_Old(6);

%

pumaANI(t1old,t2old,t3old,t4old,user_entry,t6old,10,'n')

end

%%

%% Edit box for Theta 6 motion.

%

function t6_edit_button_press(h,dummy)

user_entry = check_edit(h,-266,266,0,t6_edit);

set(t6_slider,'Value',user_entry); % slider = text box.

T_Old = getappdata(0,'ThetaOld'); % Current pose

%

t1old = T_Old(1); t2old = T_Old(2); t3old = T_Old(3);

t4old = T_Old(4); t5old = T_Old(5);

%

pumaANI(t1old,t2old,t3old,t4old,t5old,user_entry,10,'n')

end

%%

function user_entry = check_edit(h,min_v,max_v,default,h_edit)

% This function will check the value typed in the text input box

% against min and max values, and correct errors.

%

% h: handle of gui

% min_v min value to check

% max_v max value to check

% default is the default value if user enters non number

% h_edit is the edit value to update.

%

user_entry = str2double(get(h,'string'));

if isnan(user_entry)

errordlg(['You must enter a numeric value, defaulting to ',num2str(default),'.'],'Bad Input','modal')

set(h_edit,'string',default);

user_entry = default;

end

%

if user_entry < min_v

errordlg(['Minimum limit is ',num2str(min_v),' degrees, using ',num2str(min_v),'.'],'Bad Input','modal')

user_entry = min_v;

set(h_edit,'string',user_entry);

end

if user_entry > max_v

errordlg(['Maximum limit is ',num2str(max_v),' degrees, using ',num2str(max_v),'.'],'Bad Input','modal')

user_entry = max_v;

set(h_edit,'string',user_entry);

end

end

%

%% Demo button's callback

function demo_button_press(h,dummy)

%

% disp('pushed demo bottom');

% R = 500;

% x = 1000;

n = 2; % demo ani steps

num = 30; % home to start, and end to home ani steps

% j = 1;

% M = 1000;

for t = 0:.1:7*pi

Px = 30*t*cos(t);

Py = 1200-300*t*(t)/(50*pi);

Pz = 30*t*sin(t);

[theta1,theta2,theta3,theta4,theta5,theta6] = PumaIK(Px,Py,Pz);

if t==0 %move to start of demo

pumaANI(theta1,theta2,theta3-180,0,0,0,num,'n')

end

% Theta 4, 5 & 6 are zero due to plotting at wrist origen.

pumaANI(theta1,theta2,theta3-180,0,0,0,n,'y')

set(t1_edit,'string',round(theta1)); % Update slider and text.

set(t1_slider,'Value',round(theta1));

set(t2_edit,'string',round(theta2));

set(t2_slider,'Value',round(theta2));

set(t3_edit,'string',round(theta3-180));

set(t3_slider,'Value',round(theta3-180));

end

gohome

% pumaANI(90,-90,-90,0,0,0,num,'n')

end

%

%

%%

function home_button_press(h,dummy)

%disp('pushed home bottom');

gohome

end

%

%%

function clr_trail_button_press(h,dummy)

%disp('pushed clear trail bottom');

handles = getappdata(0,'patch_h'); %

Tr = handles(9);

%

setappdata(0,'xtrail',0); % used for trail tracking.

setappdata(0,'ytrail',0); % used for trail tracking.

setappdata(0,'ztrail',0); % used for trail tracking.

%

set(Tr,'xdata',0,'ydata',0,'zdata',0);

end

%

%

function rnd_demo_button_press(h, dummy)

%disp('pushed random demo bottom');

% a = 10; b = 50; x = a + (b-a) * rand(5)

% Angle Range Default Name

% Theta 1: 320 (-160 to 160) 90 Waist Joint

% Theta 2: 220 (-110 to 110) -90 Shoulder Joint

% Theta 3: 270 (-135 to 135) -90 Elbow Joint

% Theta 4: 532 (-266 to 266) 0 Wrist Roll

% Theta 5: 200 (-100 to 100) 0 Wrist Bend

% Theta 6: 532 (-266 to 266) 0 Wrist Swival

t1_home = 90; % offsets to define the "home" postition as UP.

t2_home = -90;

t3_home = -90;

theta1 = -160 + 320*rand(1); % offset for home

theta2 = -110 + 220*rand(1); % in the UP pos.

theta3 = -135 + 270*rand(1);

theta4 = -266 + 532*rand(1);

theta5 = -100 + 200*rand(1);

theta6 = -266 + 532*rand(1);

n = 50;

pumaANI(theta1+t1_home,theta2+t2_home,theta3+t3_home,theta4,theta5,theta6,n,'y')

set(t1_edit,'string',round(theta1)); % Update slider and text.

set(t1_slider,'Value',round(theta1));

set(t2_edit,'string',round(theta2));

set(t2_slider,'Value',round(theta2));

set(t3_edit,'string',round(theta3));

set(t3_slider,'Value',round(theta3));

set(t4_edit,'string',round(theta4));

set(t4_slider,'Value',round(theta4));

set(t5_edit,'string',round(theta5));

set(t5_slider,'Value',round(theta5));

set(t6_edit,'string',round(theta6));

set(t6_slider,'Value',round(theta6));

end

%%

%Here are the functions used for this robot example:

%

%%

% When called this function will simply initialize a plot of the Puma 762

% robot by plotting it in it's home orientation and setting the current

% angles accordingly.

function gohome()

pumaANI(90,-90,-90,0,0,0,20,'n') % show it animate home

%PumaPOS(90,-90,-90,0,0,0) %drive it home, no animate.

set(t1_edit,'string',0);

set(t1_slider,'Value',0); %At the home position, so all

set(t2_edit,'string',0); %sliders and input boxes = 0.

set(t2_slider,'Value',0);

set(t3_edit,'string',0);

set(t3_slider,'Value',0);

set(t4_edit,'string',0);

set(t4_slider,'Value',0);

set(t5_edit,'string',0);

set(t5_slider,'Value',0);

set(t6_edit,'string',0);

set(t6_slider,'Value',0);

setappdata(0,'ThetaOld',[90,-90,-90,0,0,0]);

end

%%

% This function will load the 3D CAD data.

%

function loaddata

% Loads all the link data from file linksdata.mat.

% This data comes from a Pro/E 3D CAD model and was made with cad2matdemo.m

% from the file exchange. All link data manually stored in linksdata.mat

[linkdata]=load('linksdata.mat','s1','s2', 's3','s4','s5','s6','s7','A1');

%Place the robot link 'data' in a storage area

setappdata(0,'Link1_data',linkdata.s1);

setappdata(0,'Link2_data',linkdata.s2);

setappdata(0,'Link3_data',linkdata.s3);

setappdata(0,'Link4_data',linkdata.s4);

setappdata(0,'Link5_data',linkdata.s5);

setappdata(0,'Link6_data',linkdata.s6);

setappdata(0,'Link7_data',linkdata.s7);

setappdata(0,'Area_data',linkdata.A1);

end

%

%%

% Use forward kinematics to place the robot in a specified configuration.

%

function PumaPOS(theta1,theta2,theta3,theta4,theta5,theta6)

s1 = getappdata(0,'Link1_data');

s2 = getappdata(0,'Link2_data');

s3 = getappdata(0,'Link3_data');

s4 = getappdata(0,'Link4_data');

s5 = getappdata(0,'Link5_data');

s6 = getappdata(0,'Link6_data');

s7 = getappdata(0,'Link7_data');

A1 = getappdata(0,'Area_data');

%

a2 = 650;

a3 = 0;

d3 = 190;

d4 = 600;

Px = 5000;

Py = 5000;

Pz = 5000;

t1 = theta1;

t2 = theta2;

t3 = theta3 %-180;

t4 = theta4;

t5 = theta5;

t6 = theta6;

%

% Forward Kinematics

T_01 = tmat(0, 0, 0, t1);

T_12 = tmat(-90, 0, 0, t2);

T_23 = tmat(0, a2, d3, t3);

T_34 = tmat(-90, a3, d4, t4);

T_45 = tmat(90, 0, 0, t5);

T_56 = tmat(-90, 0, 0, t6);

%T_01 = T_01;

T_02 = T_01*T_12;

T_03 = T_02*T_23;

T_04 = T_03*T_34;

T_05 = T_04*T_45;

T_06 = T_05*T_56;

%

Link1 = s1.V1;

Link2 = (T_01*s2.V2')';

Link3 = (T_02*s3.V3')';

Link4 = (T_03*s4.V4')';

Link5 = (T_04*s5.V5')';

Link6 = (T_05*s6.V6')';

Link7 = (T_06*s7.V7')';

handles = getappdata(0,'patch_h'); %

L1 = handles(1);

L2 = handles(2);

L3 = handles(3);

L4 = handles(4);

L5 = handles(5);

L6 = handles(6);

L7 = handles(7);

%

set(L1,'vertices',Link1(:,1:3),'facec', [0.717,0.116,0.123]);

set(L1, 'EdgeColor','none');

set(L2,'vertices',Link2(:,1:3),'facec', [0.216,1,.583]);

set(L2, 'EdgeColor','none');

set(L3,'vertices',Link3(:,1:3),'facec', [0.306,0.733,1]);

set(L3, 'EdgeColor','none');

set(L4,'vertices',Link4(:,1:3),'facec', [1,0.542,0.493]);

set(L4, 'EdgeColor','none');

set(L5,'vertices',Link5(:,1:3),'facec', [0.216,1,.583]);

set(L5, 'EdgeColor','none');

set(L6,'vertices',Link6(:,1:3),'facec', [1,1,0.255]);

set(L6, 'EdgeColor','none');

set(L7,'vertices',Link7(:,1:3),'facec', [0.306,0.733,1]);

set(L7, 'EdgeColor','none');

end

%%

% This function computes the Inverse Kinematics for the Puma 762 robot

% given X,Y,Z coordinates for a point in the workspace. Note: The IK are

% computed for the origin of Coordinate systems 4,5 & 6.

function [theta1,theta2,theta3,theta4,theta5,theta6] = PumaIK(Px,Py,Pz)

theta4 = 0;

theta5 = 0;

theta6 = 0;

sign1 = 1;

sign3 = 1;

nogo = 0;

noplot = 0;

% Because the sqrt term in theta1 & theta3 can be + or - we run through

% all possible combinations (i = 4) and take the first combination that

% satisfies the joint angle constraints.

while nogo == 0;

for i = 1:1:4

if i == 1

sign1 = 1;

sign3 = 1;

elseif i == 2

sign1 = 1;

sign3 = -1;

elseif i == 3

sign1 = -1;

sign3 = 1;

else

sign1 = -1;

sign3 = -1;

end

a2 = 650;

a3 = 0;

d3 = 190;

d4 = 600;

rho = sqrt(Px^2+Py^2);

phi = atan2(Py,Px);

K = (Px^2+Py^2+Pz^2-a2^2-a3^2-d3^2-d4^2)/(2*a2);

c4 = cos(theta4);

s4 = sin(theta4);

c5 = cos(theta5);

s5 = sin(theta5);

c6 = cos(theta6);

s6 = sin(theta6);

theta1 = (atan2(Py,Px)-atan2(d3,sign1*sqrt(Px^2+Py^2-d3^2)));

c1 = cos(theta1);

s1 = sin(theta1);

theta3 = (atan2(a3,d4)-atan2(K,sign3*sqrt(a3^2+d4^2-K^2)));

c3 = cos(theta3);

s3 = sin(theta3);

t23 = atan2((-a3-a2*c3)*Pz-(c1*Px+s1*Py)*(d4-a2*s3),(a2*s3-d4)*Pz+(a3+a2*c3)*(c1*Px+s1*Py));

theta2 = (t23 - theta3);

c2 = cos(theta2);

s2 = sin(theta2);

s23 = ((-a3-a2*c3)*Pz+(c1*Px+s1*Py)*(a2*s3-d4))/(Pz^2+(c1*Px+s1*Py)^2);

c23 = ((a2*s3-d4)*Pz+(a3+a2*c3)*(c1*Px+s1*Py))/(Pz^2+(c1*Px+s1*Py)^2);

r13 = -c1*(c23*c4*s5+s23*c5)-s1*s4*s5;

r23 = -s1*(c23*c4*s5+s23*c5)+c1*s4*s5;

r33 = s23*c4*s5 - c23*c5;

theta4 = atan2(-r13*s1+r23*c1,-r13*c1*c23-r23*s1*c23+r33*s23);

r11 = c1*(c23*(c4*c5*c6-s4*s6)-s23*s5*c6)+s1*(s4*c5*c6+c4*s6);

r21 = s1*(c23*(c4*c5*c6-s4*s6)-s23*s5*c6)-c1*(s4*c5*c6+c4*s6);

r31 = -s23*(c4*c5*c6-s4*s6)-c23*s5*c6;

s5 = -(r13*(c1*c23*c4+s1*s4)+r23*(s1*c23*c4-c1*s4)-r33*(s23*c4));

c5 = r13*(-c1*s23)+r23*(-s1*s23)+r33*(-c23);

theta5 = atan2(s5,c5);

s6 = -r11*(c1*c23*s4-s1*c4)-r21*(s1*c23*s4+c1*c4)+r31*(s23*s4);

c6 = r11*((c1*c23*c4+s1*s4)*c5-c1*s23*s5)+r21*((s1*c23*c4-c1*s4)*c5-s1*s23*s5)-r31*(s23*c4*c5+c23*s5);

theta6 = atan2(s6,c6);

theta1 = theta1*180/pi;

theta2 = theta2*180/pi;

theta3 = theta3*180/pi;

theta4 = theta4*180/pi;

theta5 = theta5*180/pi;

theta6 = theta6*180/pi;

if theta2>=160 && theta2<=180

theta2 = -theta2;

end

if theta1<=160 && theta1>=-160 && (theta2<=20 && theta2>=-200) && theta3<=45 && theta3>=-225 && theta4<=266 && theta4>=-266 && theta5<=100 && theta5>=-100 && theta6<=266 && theta6>=-266

nogo = 1;

theta3 = theta3+180;

break

end

if i == 4 && nogo == 0

h = errordlg('Point unreachable due to joint angle constraints.','JOINT ERROR');

waitfor(h);

nogo = 1;

noplot = 1;

break

end

end

end

end

%

%%

function pumaANI(theta1,theta2,theta3,theta4,theta5,theta6,n,trail)

% This function will animate the Puma 762 robot given joint angles.

% n is number of steps for the animation

% trail is 'y' or 'n' (n = anything else) for leaving a trail.

%

%disp('in animate');

a2 = 650; %D-H paramaters

a3 = 0;

d3 = 190;

d4 = 600;

% Err2 = 0;

%

ThetaOld = getappdata(0,'ThetaOld');

%

theta1old = ThetaOld(1);

theta2old = ThetaOld(2);

theta3old = ThetaOld(3);

theta4old = ThetaOld(4);

theta5old = ThetaOld(5);

theta6old = ThetaOld(6);

%

t1 = linspace(theta1old,theta1,n);

t2 = linspace(theta2old,theta2,n);

t3 = linspace(theta3old,theta3,n);% -180;

t4 = linspace(theta4old,theta4,n);

t5 = linspace(theta5old,theta5,n);

t6 = linspace(theta6old,theta6,n);

n = length(t1);

for i = 2:1:n

% Forward Kinematics

%

T_01 = tmat(0, 0, 0, t1(i));

T_12 = tmat(-90, 0, 0, t2(i));

T_23 = tmat(0, a2, d3, t3(i));

T_34 = tmat(-90, a3, d4, t4(i));

T_45 = tmat(90, 0, 0, t5(i));

T_56 = tmat(-90, 0, 0, t6(i));

%

% % T_67 = [ 1 0 0 0

% % 0 1 0 0

% % 0 0 1 188

% % 0 0 0 1];

%T_01 = T_01; % it is, but don't need to say so.

T_02 = T_01*T_12;

T_03 = T_02*T_23;

T_04 = T_03*T_34;

T_05 = T_04*T_45;

T_06 = T_05*T_56;

% T_07 = T_06*T_67;

%

s1 = getappdata(0,'Link1_data');

s2 = getappdata(0,'Link2_data');

s3 = getappdata(0,'Link3_data');

s4 = getappdata(0,'Link4_data');

s5 = getappdata(0,'Link5_data');

s6 = getappdata(0,'Link6_data');

s7 = getappdata(0,'Link7_data');

%A1 = getappdata(0,'Area_data');

Link1 = s1.V1;

Link2 = (T_01*s2.V2')';

Link3 = (T_02*s3.V3')';

Link4 = (T_03*s4.V4')';

Link5 = (T_04*s5.V5')';

Link6 = (T_05*s6.V6')';

Link7 = (T_06*s7.V7')';

% Tool = T_07;

% if sqrt(Tool(1,4)^2+Tool(2,4)^2)<514

% Err2 = 1;

% break

% end

%

handles = getappdata(0,'patch_h'); %

L1 = handles(1);

L2 = handles(2);

L3 = handles(3);

L4 = handles(4);

L5 = handles(5);

L6 = handles(6);

L7 = handles(7);

Tr = handles(9);

%

set(L1,'vertices',Link1(:,1:3),'facec', [0.717,0.116,0.123]);

set(L1, 'EdgeColor','none');

set(L2,'vertices',Link2(:,1:3),'facec', [0.216,1,.583]);

set(L2, 'EdgeColor','none');

set(L3,'vertices',Link3(:,1:3),'facec', [0.306,0.733,1]);

set(L3, 'EdgeColor','none');

set(L4,'vertices',Link4(:,1:3),'facec', [1,0.542,0.493]);

set(L4, 'EdgeColor','none');

set(L5,'vertices',Link5(:,1:3),'facec', [0.216,1,.583]);

set(L5, 'EdgeColor','none');

set(L6,'vertices',Link6(:,1:3),'facec', [1,1,0.255]);

set(L6, 'EdgeColor','none');

set(L7,'vertices',Link7(:,1:3),'facec', [0.306,0.733,1]);

set(L7, 'EdgeColor','none');

% store trail in appdata

if trail == 'y'

x_trail = getappdata(0,'xtrail');

y_trail = getappdata(0,'ytrail');

z_trail = getappdata(0,'ztrail');

%

xdata = [x_trail T_04(1,4)];

ydata = [y_trail T_04(2,4)];

zdata = [z_trail T_04(3,4)];

%

setappdata(0,'xtrail',xdata); % used for trail tracking.

setappdata(0,'ytrail',ydata); % used for trail tracking.

setappdata(0,'ztrail',zdata); % used for trail tracking.

%

set(Tr,'xdata',xdata,'ydata',ydata,'zdata',zdata);

end

drawnow

end

setappdata(0,'ThetaOld',[theta1,theta2,theta3,theta4,theta5,theta6]);

end

%%

%

%

%%

function InitHome

% Use forward kinematics to place the robot in a specified

% configuration.

% Figure setup data, create a new figure for the GUI

set(0,'Units','pixels')

dim = get(0,'ScreenSize');

fig_1 = figure('doublebuffer','on','Position',[0,35,dim(3)-200,dim(4)-110],...

'MenuBar','none','Name',' 3D Puma Robot Graphical Demo',...

'NumberTitle','off','CloseRequestFcn',@del_app);

hold on;

%light('Position',[-1 0 0]);

light % add a default light

daspect([1 1 1]) % Setting the aspect ratio

view(135,25)

xlabel('X'),ylabel('Y'),zlabel('Z');

title('WWU Robotics Lab PUMA 762');

axis([-1500 1500 -1500 1500 -1120 1500]);

plot3([-1500,1500],[-1500,-1500],[-1120,-1120],'k')

plot3([-1500,-1500],[-1500,1500],[-1120,-1120],'k')

plot3([-1500,-1500],[-1500,-1500],[-1120,1500],'k')

plot3([-1500,-1500],[1500,1500],[-1120,1500],'k')

plot3([-1500,1500],[-1500,-1500],[1500,1500],'k')

plot3([-1500,-1500],[-1500,1500],[1500,1500],'k')

s1 = getappdata(0,'Link1_data');

s2 = getappdata(0,'Link2_data');

s3 = getappdata(0,'Link3_data');

s4 = getappdata(0,'Link4_data');

s5 = getappdata(0,'Link5_data');

s6 = getappdata(0,'Link6_data');

s7 = getappdata(0,'Link7_data');

A1 = getappdata(0,'Area_data');

%

a2 = 650;

a3 = 0;

d3 = 190;

d4 = 600;

Px = 5000;

Py = 5000;

Pz = 5000;

%The 'home' position, for init.

t1 = 90;

t2 = -90;

t3 = -90;

t4 = 0;

t5 = 0;

t6 = 0;

% Forward Kinematics

T_01 = tmat(0, 0, 0, t1);

T_12 = tmat(-90, 0, 0, t2);

T_23 = tmat(0, a2, d3, t3);

T_34 = tmat(-90, a3, d4, t4);

T_45 = tmat(90, 0, 0, t5);

T_56 = tmat(-90, 0, 0, t6);

% Each link fram to base frame transformation

T_02 = T_01*T_12;

T_03 = T_02*T_23;

T_04 = T_03*T_34;

T_05 = T_04*T_45;

T_06 = T_05*T_56;

% Actual vertex data of robot links

Link1 = s1.V1;

Link2 = (T_01*s2.V2')';

Link3 = (T_02*s3.V3')';

Link4 = (T_03*s4.V4')';

Link5 = (T_04*s5.V5')';

Link6 = (T_05*s6.V6')';

Link7 = (T_06*s7.V7')';

% points are no fun to watch, make it look 3d.

L1 = patch('faces', s1.F1, 'vertices' ,Link1(:,1:3));

L2 = patch('faces', s2.F2, 'vertices' ,Link2(:,1:3));

L3 = patch('faces', s3.F3, 'vertices' ,Link3(:,1:3));

L4 = patch('faces', s4.F4, 'vertices' ,Link4(:,1:3));

L5 = patch('faces', s5.F5, 'vertices' ,Link5(:,1:3));

L6 = patch('faces', s6.F6, 'vertices' ,Link6(:,1:3));

L7 = patch('faces', s7.F7, 'vertices' ,Link7(:,1:3));

A1 = patch('faces', A1.Fa, 'vertices' ,A1.Va(:,1:3));

Tr = plot3(0,0,0,'b.'); % holder for trail paths

%

setappdata(0,'patch_h',[L1,L2,L3,L4,L5,L6,L7,A1,Tr])

%

setappdata(0,'xtrail',0); % used for trail tracking.

setappdata(0,'ytrail',0); % used for trail tracking.

setappdata(0,'ztrail',0); % used for trail tracking.

%

set(L1, 'facec', [0.717,0.116,0.123]);

set(L1, 'EdgeColor','none');

set(L2, 'facec', [0.216,1,.583]);

set(L2, 'EdgeColor','none');

set(L3, 'facec', [0.306,0.733,1]);

set(L3, 'EdgeColor','none');

set(L4, 'facec', [1,0.542,0.493]);

set(L4, 'EdgeColor','none');

set(L5, 'facec', [0.216,1,.583]);

set(L5, 'EdgeColor','none');

set(L6, 'facec', [1,1,0.255]);

set(L6, 'EdgeColor','none');

set(L7, 'facec', [0.306,0.733,1]);

set(L7, 'EdgeColor','none');

set(A1, 'facec', [.8,.8,.8],'FaceAlpha',.25);

set(A1, 'EdgeColor','none');

%

setappdata(0,'ThetaOld',[90,-90,-90,0,0,0]);

%

end

%%

function T = tmat(alpha, a, d, theta)

% tmat(alpha, a, d, theta) (T-Matrix used in Robotics)

% The homogeneous transformation called the "T-MATRIX"

% as used in the Kinematic Equations for robotic type

% systems (or equivalent).

%

% This is equation 3.6 in Craig's "Introduction to Robotics."

% alpha, a, d, theta are the Denavit-Hartenberg parameters.

%

% (NOTE: ALL ANGLES MUST BE IN DEGREES.)

%

alpha = alpha*pi/180; %Note: alpha is in radians.

theta = theta*pi/180; %Note: theta is in radians.

c = cos(theta);

s = sin(theta);

ca = cos(alpha);

sa = sin(alpha);

T = [c -s 0 a; s*ca c*ca -sa -sa*d; s*sa c*sa ca ca*d; 0 0 0 1];

end

%%

function del_app(varargin)

%This is the main figure window close function, to remove any

% app data that may be left due to using it for geometry.

%CloseRequestFcn

% here is the data to remove:

% Link1_data: [1x1 struct]

% Link2_data: [1x1 struct]

% Link3_data: [1x1 struct]

% Link4_data: [1x1 struct]

% Link5_data: [1x1 struct]

% Link6_data: [1x1 struct]

% Link7_data: [1x1 struct]

% Area_data: [1x1 struct]

% patch_h: [1x9 double]

% ThetaOld: [90 -182 -90 -106 80 106]

% xtrail: 0

% ytrail: 0

% ztrail: 0

% Now remove them.

rmappdata(0,'Link1_data');

rmappdata(0,'Link2_data');

rmappdata(0,'Link3_data');

rmappdata(0,'Link4_data');

rmappdata(0,'Link5_data');

rmappdata(0,'Link6_data');

rmappdata(0,'Link7_data');

rmappdata(0,'ThetaOld');

rmappdata(0,'Area_data');

rmappdata(0,'patch_h');

rmappdata(0,'xtrail');

rmappdata(0,'ytrail');

rmappdata(0,'ztrail');

delete(fig_1);

end

%%

function [hout,ax_out] = uibutton(varargin)

%uibutton: Create pushbutton with more flexible labeling than uicontrol.

% Usage:

% uibutton accepts all the same arguments as uicontrol except for the

% following property changes:

%

% Property Values

% ----------- ------------------------------------------------------

% Style 'pushbutton', 'togglebutton' or 'text', default =

% 'pushbutton'.

% String Same as for text() including cell array of strings and

% TeX or LaTeX interpretation.

% Interpreter 'tex', 'latex' or 'none', default = default for text()

%

% Syntax:

% handle = uibutton('PropertyName',PropertyValue,...)

% handle = uibutton(parent,'PropertyName',PropertyValue,...)

% [text_obj,axes_handle] = uibutton('Style','text',...

% 'PropertyName',PropertyValue,...)

%

% uibutton creates a temporary axes and text object containing the text to

% be displayed, captures the axes as an image, deletes the axes and then

% displays the image on the uicontrol. The handle to the uicontrol is

% returned. If you pass in a handle to an existing uicontol as the first

% argument then uibutton will use that uicontrol and not create a new one.

%

% If the Style is set to 'text' then the axes object is not deleted and the

% text object handle is returned (as well as the handle to the axes in a

% second output argument).

%

% See also UICONTROL.

% Version: 1.6, 20 April 2006

% Author: Douglas M. Schwarz

% Email: dmschwarz=ieee*org, dmschwarz=urgrad*rochester*edu

% Real_email = regexprep(Email,{'=','*'},{'@','.'})

% Detect if first argument is a uicontrol handle.

keep_handle = false;

if nargin > 0

h = varargin{1};

if isscalar(h) && ishandle(h) && strcmp(get(h,'Type'),'uicontrol')

keep_handle = true;

varargin(1) = [];

end

end

% Parse arguments looking for 'Interpreter' property. If found, note its

% value and then remove it from where it was found.

interp_value = get(0,'DefaultTextInterpreter');

arg = 1;

remove = [];

while arg <= length(varargin)

v = varargin{arg};

if isstruct(v)

fn = fieldnames(v);

for i = 1:length(fn)

if strncmpi(fn{i},'interpreter',length(fn{i}))

interp_value = v.(fn{i});

v = rmfield(v,fn{i});

end

end

varargin{arg} = v;

arg = arg + 1;

elseif ischar(v)

if strncmpi(v,'interpreter',length(v))

interp_value = varargin{arg+1};

remove = [remove,arg,arg+1];

end

arg = arg + 2;

elseif arg == 1 && isscalar(v) && ishandle(v) && ...

any(strcmp(get(h,'Type'),{'figure','uipanel'}))

arg = arg + 1;

else

error('Invalid property or uicontrol parent.')

end

end

varargin(remove) = [];

% Create uicontrol, get its properties then hide it.

if keep_handle

set(h,varargin{:})

else

h = uicontrol(varargin{:});

end

s = get(h);

if ~any(strcmp(s.Style,{'pushbutton','togglebutton','text'}))

delete(h)

error('''Style'' must be pushbutton, togglebutton or text.')

end

set(h,'Visible','off')

% Create axes.

parent = get(h,'Parent');

ax = axes('Parent',parent,...

'Units',s.Units,...

'Position',s.Position,...

'XTick',[],'YTick',[],...

'XColor',s.BackgroundColor,...

'YColor',s.BackgroundColor,...

'Box','on',...

'Color',s.BackgroundColor);

% Adjust size of axes for best appearance.

set(ax,'Units','pixels')

pos = round(get(ax,'Position'));

if strcmp(s.Style,'text')

set(ax,'Position',pos + [0 1 -1 -1])

else

set(ax,'Position',pos + [4 4 -8 -8])

end

switch s.HorizontalAlignment

case 'left'

x = 0.0;

case 'center'

x = 0.5;

case 'right'

x = 1;

end

% Create text object.

text_obj = text('Parent',ax,...

'Position',[x,0.5],...

'String',s.String,...

'Interpreter',interp_value,...

'HorizontalAlignment',s.HorizontalAlignment,...

'VerticalAlignment','middle',...

'FontName',s.FontName,...

'FontSize',s.FontSize,...

'FontAngle',s.FontAngle,...

'FontWeight',s.FontWeight,...

'Color',s.ForegroundColor);

% If we are creating something that looks like a text uicontrol then we're

% all done and we return the text object and axes handles rather than a

% uicontrol handle.

if strcmp(s.Style,'text')

delete(h)

if nargout

hout = text_obj;

ax_out = ax;

end

return

end

% Capture image of axes and then delete the axes.

frame = getframe(ax);

delete(ax)

% Build RGB image, set background pixels to NaN and put it in 'CData' for

% the uicontrol.

if isempty(frame.colormap)

rgb = frame.cdata;

else

rgb = reshape(frame.colormap(frame.cdata,:),[pos([4,3]),3]);

end

size_rgb = size(rgb);

rgb = double(rgb)/255;

back = repmat(permute(s.BackgroundColor,[1 3 2]),size_rgb(1:2));

isback = all(rgb == back,3);

rgb(repmat(isback,[1 1 3])) = NaN;

set(h,'CData',rgb,'String','','Visible',s.Visible)

% Assign output argument if necessary.

if nargout

hout = h;

end

%%

end

end