Управляющий скрипт Lua для симулятора CoppeliaSim

Конструкторы для обучения детей робототехнике

Share Button

Методист по олимпиадной робототехнике Университета Иннополис Алексей Овсянников продолжает цикл уроков по робототехнике. Читайте о написании программ для сцен симулятора CoppeliaSim.

Управляющий скрипт Lua для симулятора CoppeliaSim

Продолжаем работу в симуляторе CoppeliaSIm (бывший V-REP). Ранее я рассказал о подготовке сцен и моделей роботов для категории “Манипуляционные ИРС”. Найти готовые сцены можно на странице ресурсов олимпиады Innopolis Open in Robotics. Эти сцены будут использоваться на курсах повышения квалификации и школе олимпиадной подготовки к IOR в Университете Иннополис.

Сегодня хочется рассказать о написании программ (управляющих скриптов) для сцен симулятора.


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

Предыдущие публикации:


Теперь переходим к теме написания скриптов. В официальной справке находим соответствующий раздел и видим достаточно широкий охват языков программирования: C/C++, Python, Java, MatLab, Lua и любой, поддерживаемый в ROS.

Управляющий скрипт Lua для симулятора CoppeliaSim

Первый столбец описывает внутренние скрипты, которые могут быть написаны только на Lua. Они используют внутренние API-команды (более 500 функций). Внутренний скрипт всегда полностью синхронизирован с симулятором, может получить полную информацию о сцене или даже изменить параметры симулирования.

На C/С++ может быть написан плагин для симулятора, который возьмет на себя управление роботом или сценой в целом. То есть можно упаковать управляющий код для робота в плагин и включить его в симуляторе. Оставим подробное рассмотрение этого процесса для отдельной статьи.

Программы, написанные на остальных языках, подключаются к симулятору по принципу клиент-серверной архитектуры: симулятор выступает сервером, управляющая программа — клиентом. Очевидно, что таких программ-клиентов можно написать и подключить несколько, для каждого симулируемого робота (например, если вы симулируете футбол роботов или иное их мультиагентное взаимодействие). Подключение может происходить через две версии фрэймворка (с использованием двух наборов API-команд): legacy remote API (или simply remote API) и B0-based remote API. Клиентская программа может быть синхронизирована с симуляцией с помощью тактов: симуляция просчитывается на короткий промежуток времени и останавливается, отправляя просчитанное состояние клиенту и ожидая от него команд, чтобы далее повторить этот процесс.

Вопросы написания программ-клиентов на различных языках я тоже оставлю за границами этой статьи, слишком объемная тема. Сегодня давайте ограничимся внутренними скриптами на Lua, для прохождения наших курсов этого будет достаточно.

Итак, скачиваем модели со страницы ресурсов олимпиады, открываем их в симуляторе. Первым делом давайте настроим параметры симуляции. В соответствующих окнах выбираем самый малый интервал времени (шаг симуляции) и самую высокую точность:

line-p

Теперь попробуем запустить симулятор. Если возникнут какие-либо ошибки, то они отобразятся в нижней области:

line2

line3

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

В младшей категории я сделал графический интерфейс с ползунками и кнопками захвата/отпускания объекта.

line4

В сцене старшей категории при корректном запуске начнет двигаться схват робота — вращаться и закрываться/открываться. Ура, наш первый запуск симуляции прошел успешно!

Кстати, обратите внимание, что у робота младшей категории вверх-вниз перемещение происходит не по оси Z, а по оси Y. Это сделано для соблюдения «правой тройки» векторов, используемой при векторном и матричном решениях прямых и обратных задач кинематики робота. Сейчас не буду этим сильно грузить, подробно об этом можем поговорить со слушателями КПК. Сейчас можете просто принять это как факт, попытаться руками пошевелить звенья робота, захватить и перетащить объекты. Поигрались? Захотелось, чтобы робот сам так умел? Тогда продолжим!

Скрипты можно найти и открыть через дерево иерархии объектов. Они привязываются к объектам и, как правило, описывают их поведение:

drevo

Добавить новый скрипт можно из контекстного меню, щелкнув по объекту правой кнопкой мыши:

drevo2

У некоторых объектов скрипты присутствуют изначально, сразу после создания. Например, скрип объекта ResizableFloor_5_25 описывает поведение пола сцены. Подозреваю, что вы его сейчас открыли двойным щелчком и получили вот такое диалоговое окно:

dr3

Не надо ничего менять, просто закройте окно крестиком или клавишей Esc. Лучше в сцене младшей категории найдите объект base_link_respondable и откройте его скрипт.

robo-ovs

Давайте разберемся, что в нем описано. Как и в других средах программирования зеленым выделены комментарии. Однострочный комментарий объявляется через двойной знак тире, многострочный — с помощью комбинаций —[[ многострочный комментарий ]]—. В первых 9 строках описывается как подключить внешний файл со скриптом к симулятору. Мало ли, у вас уже есть готовая программа на Lua и вы захотите ее проверить в симуляторе?

Далее идет функция sysCall_threadmain(), которая вызывается главным потоком симулятора при обращении к объекту. Функции в языке Lua создаются ключевым словом function, заканчиваются ключевым словом end. В строке 13 идет вызов функции UI_init, а сама функция описывается в строках 81-101.

В функции UI_init происходит создание графического интерфейса через XML-код (можно нарисовать интерфейс в сторонней программе и скопировать оттуда готовый код). В нем же идут ссылки на функции grabClick и reliaseClick, которые вызываются при нажатии кнопок графического интерфейса и передают команды пневматическому схвату зацепить и отпустить объект.

Переходим к строкам 15-17. В них происходит связывание объектов сцены с объектами-ссылками в скрипте. Делается это командой

sim.getObjectHandle(‘имя_объекта_на_сцене’)

Я привязываю приводы (кинематические пары, joint’ы) с именами X, Y и Z к объектам-ссылкам roboX, roboY и roboZ.

При использовании интерфейса управления с ползунками их значения считываются в переменные roboX_pos, roboY_pos и roboZ_pos, а далее в бесконечном цикле (62-73 строки скрипта) устанавливаются кинематическим парам. Происходит это с помощью команды

sim.setJointPosition(объект-ссылка_на_привод, требуемая_позиция)

Обе команды я подсмотрел в сценах-примерах, которые идут с симулятором. Их можно найти в папке программы в …Program Files\CoppeliaRobotics\CoppeliaSimEdu\scenes. Не стесняйтесь туда подглядывать. И не стесняйтесь искать команды в общем списке API. Например, там можно найти команды, которые управляют не только позицией кинематической пары, но и ее усилием

join-robo

Вообще, симулятор содержит огромное количество «волшебных» команд, которые могут очень сильно упростить создание скрипта. Даже СЛИШКОМ сильно. Например, можно найти команду, в которой задается желаемое положение звена (или всех звеньев) робота и время, за которое нужно его достигнуть, а симулятор сам двигает робота. Я ее намеренно не называю, так как, к сожалению, таких «волшебных» команд нет в Arduino, Lego или других контроллерах, поэтому все движения робота приходится прописывать самостоятельно.

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

 

Подобное перемещение можно реализовать следующим образом:

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

2. Задаемся временем и количеством шагов, за которые хотим дойти из текущей точки до требуемой. Их можно просто задать как константы (каждое движение делаем за 100 шагов и 5 секунд) или вычислять по расстоянию между точками и максимальной скорости приводов робота. Расстояние между точками в трехмерном пространстве определяется по формуле

formula-io

Например, если звено робота может перемещаться со скоростью 10 мм/сек, а расстояние между точками 60 мм, то робот пройдет его за 6 секунд. Ну и каждую секунду делаем по 50 шагов, то есть все перемещение занимает 300 шагов.

3. Вычисляем разницу по каждой обобщенной координате между текущим и требуемым положением и делим его на количество шагов. Таким образом мы получим длину одного шага по каждой обобщенной координате. Эти значения могут быть как положительными, так и отрицательными, знак будет показывать направление перемещения звена. Для вычисленной общей длительности перемещения в 300 шагов каждый шаг будет равен 1/300 доле всего перемещения. Например, если одно звено должно сдвинуться на 150 мм, а другое повернуться на 60 градусов, то за один шаг они сдвинутся и повернутся на 0.5 мм и 0,2 градуса соответственно (при 300 шагов).

4. Запускаем цикл на количество итераций, равное количеству шагов перемещения. На каждом шаге смещаем звенья на длину шага по каждой обобщенной координате. То есть, за вычисленные 300 шагов мы изменим положение каждого звена 300 раз по 1/300 — как раз на нужную нам величину.

Если мы не хотим включать графический интерфейс, то просто закомментируем строки 13, 68 и 70, так как в них тоже идет обращение к интерфейсу. Давайте так и сделаем.

Длинный участок кода, с 23 по 59 строку, закомментирован. Давайте уберем комментарии в этих строках и посмотрим, что там описано? А там как раз описан наш алгоритм. В строках 28-29 задаем количество шагов и время перемещения. В строках 30-32 — координаты требуемой точки (дальний правый верхний угол рабочего пространства).

Строки 34-36 должны были выглядеть вот так:

robo-step

Но раз у нас текущая позиция по всем координатам нулевая, то формулы были сокращены.

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

Ну и, наконец, в цикле на каждом шаге происходит вычисление новой позиции и перемещение звеньев манипулятора в нее. Обратите внимание, что в коде скрипта координаты точек описываются в миллиметрах, а команда sim.setJointPosition принимает в параметрах метры. Поэтому происходит дополнительное деление на 1000. Подобное преобразование надо делать и для вращательных пар — мы привыкли и оперируем в скрипте градусами, а команда принимает на вход радианы:

sim.setJointPosition(link4, link4_pos*math.pi/180)

Несколько слов надо сказать о связях между скриптами, а именно — робота и схвата. Каждый из них имеет свой скрипт. Программу робота мы как раз изменяем, а у схвата при создании появляется свой собственный скрипт. В нем уже описаны действия по открытию-закрытию или захвату-отпусканию объекта, достаточно их только запустить. В CoppeliaSIm это делается через систему «сигналов»: в одном скрипте мы можем послать такой сигнал командой

sim.setIntegerSignal(‘имя_сигнала’, числовое_значение_сигнала)

а в другом скрипте считать его командой

sig=sim.getIntegerSignal(‘имя_сигнала’)

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

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

Хоть данный материал и направлен на предварительную подготовку слушателей номинации «Манипуляционные ИРС», но описанные принципы могут использоваться для симуляции роботов любых других соревнований. Почему бы не использовать «волшебные команды» для определения координат роботов и не попробовать написать алгоритм для футбола, коптера или автоматического склада?

Я прерываюсь на выходные. Еще раз напоминаю, что хочу услышать ваше мнение о статьях и предложения по улучшению в комментариях.

Справка

Университет Иннополис  (university.innopolis.ru) специализируется на образовании, исследованиях и разработках в области информационных технологий и робототехники. В 2019/2020 учебном году в вузе обучается 771 студент по 181 курсу бакалавриата, магистратуры и аспирантуры: компьютерные науки, теоретические основы компьютерных наук, управление разработкой ПО, разработка безопасных сетей и систем, управление большими данными, робототехника и компьютерное зрение. Средний балл ЕГЭ студентов, зачисленных на первый курс в 2019 году, — 92,7. По данным совместного мониторинга НИУ ВШЭ, Яндекса, Рособрнадзора и Министерства высшего образования и науки РФ, этот показатель стал самым высоким среди всех негосударственных вузов России. ИТ-вуз также разделил 5—6 место с петербургским университетом ИТМО в рейтинге по приему на бюджетные места и стал единственным учебным заведением Татарстана из топ-10 этого списка. 87 место (единственный вуз из РФ) в мировом рейтинге вузов-исследователей игр — Institutions Active in Technical Games Research.

В 2019 году Университет Иннополис провёл 24 образовательные смены и сбора по олимпиадным направлениям. 5 олимпиад ИТ-вуза эксперты включены в перечень Российского союза олимпиад школьников на 2019-2020 учебный год. Университет проводит методическую поддержку 9 международных и всероссийских олимпиад и конкурсов для школьников по информатике, математике, робототехнике, финтеху, информационной безопасности, проектным инженерно-научным задачам. Ежегодно мероприятия довузовского направления охватывают 30 000 школьников.

Share Button

Нет комментариев.

Оставить комментарий

© 2014-2020 Занимательная робототехника, Гагарина Д.А., Гагарин А.С., Гагарин А.А. All rights reserved / Все права защищены. Копирование и воспроизведение в любой форме запрещено. Политика конфиденциальности. Соглашение об обработке персональных данных.
Наверх