Подписаться на новости
brand brand
logo logo
Сообщество робототехников

Программируем робота в симуляторе: руководство для начинающих

Программируем-робота-в-симуляторе-руководство-для-начинающих
Четверг, 17 Января 2019, в 16:42
РОБОТОТЕХНИКА

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

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

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

Чтобы быть частью этих перемен, я прошел курс по теории контроля автономных роботов, результатом которого стало создание написанного на языке Питон симулятора. Он позволил попрактиковаться в теории контроля на примере простого мобильного робота.

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

Чтобы воспользоваться этим руководством, вам понадобятся базовые знания по математике (мы будем использовать тригонометрические функции и векторы) и о Питоне, поскольку это один из самых популярных языков программирования для простых роботов (мы будем использовать базовые библиотеки и функции).

 

Трудности работы с роботом: ожидания и реальность

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

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

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

Это одна из причин, почему программирование роботов – сложный процесс. Мы часто смотрим видео, в которых роботы, недавно разработанные в лабораториях, демонстрируют невероятные умения, навигацию, способность работать в команде, и задаемся вопросом: «Почему они не используются в реальном мире?» Когда будете смотреть подобные ролики в следующий раз, обратите внимание, насколько сильно контролируется обстановка в лабораториях. В большинстве случаев эти роботы могут выполнять свои впечатляющие задания, только если условия среды остаются неизменными. Поэтому ключ к более совершенным роботам — в создании более сложных, гибких и прочных моделей. А это уже зависит от ограничений в доступных вычислительных ресурсах.

 

Симулятор робота

Мой симулятор написан на Питоне и использует Sobot Rimulator. Вы можете найти v1.0.0 здесь. Программа обеспечивает точную симуляцию робота и дает разработчику простой фреймворк, чтобы практиковаться в создании ПО для роботов. Конечно, всегда лучше иметь дело с реальным роботом, но такой симулятор гораздо более доступен, и это хороший вариант для начала работы.

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

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

Другими словами, программирование робота в симуляторе аналогично программированию реального робота.

В этом руководстве я опишу архитектуру ПО для контролирования робота по v1.0.0 Sobot Rimulator.

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

Робот Khepera

Логика управления роботом ограничивается следующими файлами и классами:

  • models/supervisor.py — этот класс отвечает за взаимодействие между симулированным миром и роботом;

  • models/supervisor_state_machine.py — этот класс представляет различные положения, в которых может находиться робот, в зависимости от интерпретации данных сенсоров;

  • файлы из каталога models/controllers реализуют различное поведение робота в зависимости от известного состояния среды.

 

Цель

Цель нашего робота будет очень простой: попасть к определенной заранее точке пространства. Этой способностью должен обладать любой мобильный робот, от автономных машин до роботов-пылесосов. Задача осложняется тем, что на пути робот должен избегать столкновений с возникающими препятствиями.

 

Программируемый робот

У каждого робота свои возможности и проблемы управления. Ознакомимся с нашим симулируемым роботом.

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

 

 

Сенсоры

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

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

В колеса робота встроены сенсоры, отслеживающие количество вращений. Одно полное вращение вперед равноценно 2765 отметкам. При вращении в противоположную сторону идет обратный отсчет.

 

Мобильность

Одни роботы передвигаются с помощью «ног», другие катятся, как мяч, третьи ползут, словно змеи.

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

 

API

В Sobot Rimulator разделение между «компьютером» робота и симулируемым физическим миром воплощается в файле robot_supervisor_interface.py. Он определяет весь API для взаимодействия с датчиками и двигателями робота:

  • read_proximity_sensors() возвращает массив из 9 числовых значений в собственном формате датчиков;

  • read_wheel_encoders() возвращает массив из двух значений, указывающих общее количество отметок с момента старта;

  • set_wheel_drive_rates( v_l, v_r ) принимает два значения (в радианах в секунду) и устанавливает левую и правую скорость колес на эти два значения.

 

Простая модель

Модель нашего робота очень простая. Она допускает много предположений касательно мира. К самым важным относятся следующие:

  • рельеф всегда ровный;

  • препятствия не бывают круглой формы;

  • колеса никогда не проскальзывают;

  • ничто не сможет повернуть робота в другую сторону;

  • датчики не ломаются и не предоставляют ложных сведений;

  • колеса всегда поворачиваются туда, куда была команда.

 

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

 

 

Система управления

Робот – это динамическая система. Положение робота, показатели его датчиков и действие его управляющих сигналов постоянно изменяются. Чтобы контролировать воздействие событий на робота, нужно:

  1. применить сигнал управления;
  2. оценить результаты;
  3. создать новые сигналы управления, которые приблизят робота к цели.

 

Эти шаги повторяются, пока цель не будет достигнута. Чем больше раз в секунду мы проходим эти шаги, тем лучше будет контроль над системой. Для робота в Sobot Rimulator они повторяются 20 раз в секунду (частота 20 Гц). Многие реальные роботы должны проделывать это тысячи и даже миллионы раз в секунду, чтобы обеспечить достаточный контроль (вспомните сказанные выше слова о разных языках программирования для разных роботов и требованиях к скорости вычислений).

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

 

Отличный трюк: упрощение модели

Чтобы контролировать робота, мы должны послать отдельные сигналы в оба колеса с указанием скорости их вращения. Обозначим эти сигналы vL и vR. Но вместо того, чтобы думать о скорости, с которой перемещаются оба колеса, гораздо естественнее думать о скорости, с которой робот двигается вперед и меняет направление. Назовем эти параметры скорость v и скорость вращения ω («омега»).

Мы можем строить всю модель на значениях v и ω, не используя параметры vL и vR. Только когда мы определим нужную манеру передвижения нашего робота, можно математически преобразовать эти характеристики в vL и vR. Такая модель называется моноконтрольной.

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

Ниже приведен код, который вносит последние изменения в supervisor.py.

Примечание: если ω = 0, оба колеса вращаются с одинаковой скоростью.

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

Оценка состояния

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

  • направление, где располагаются преграды;
  • расстояние от преград;
  • свое местоположение;
  • нужное направление.

 

Первые два пункта определяются посредством датчиков приближения. Функция API read_proximity_sensors() возвращает массив из 9 значений – по одному для каждого датчика. Мы знаем заранее, что, например, седьмой показатель получен от датчика, направленного на 75 градусов вправо от робота. Если показатель определяет дистанцию в 0,1 м, мы понимаем, что именно на этом расстоянии, 75 градусов вправо, находится преграда. Если робот не обнаружил никаких преград, он передает данные 0,2 м — максимальное расстояние, определяемое сенсором.

Из-за того как работают инфракрасные датчики (они измеряют отражения инфракрасного света), числа, которые они возвращают, являются нелинейным преобразованием фактического расстояния. Показания необходимо перевести в метры. В supervisor.py это выглядит следующим образом:

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

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

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

В симуляторе мы можем проводить вычисления одометрии на частоте 20 Гц — с той же частотой, с которой проверяем показания датчиков. Но было бы неплохо сделать отдельный поток, который бы работал быстрее и улавливал более мелкие движения колес.

Ниже приведена функция одометрии в supervisor.py, которая обновляет сведения о местоположении робота. Оценка положения формируется из координат x и y, а также направляющей theta. Они измеряются в радианах от положительной оси X. Положительное значение x расположено на востоке, положительное значение y — на севере. Курс на 0 обозначает, что робот смотрит точно на восток. Робот всегда предполагает, что его начальное положение (0, 0), 0.

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

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

 

Достижение цели

Как заставить колеса робота двигаться таким образом, чтобы он приехал к назначенной цели? Для начала упростим себе задачу и предположим, что на пути робота нет преград. Значит, робот просто должен ехать вперед по направлению к цели. Благодаря одометрии мы знаем наши текущие координаты и направление робота. Мы также знаем координаты нашей цели, ведь они были запрограммированы заранее. Используя линейную алгебру, мы можем определить вектор от нашего положения до цели. Вот как это делается в go_to_goal_controller.py:

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

Обратите внимание: мы получаем вектор к цели в системе отсчета робота, а не в координатах мира. Если цель находится на оси X в системе отсчета робота, это значит, что она расположена прямо перед ним. Угол этого вектора относительно оси X — это разница между текущим курсом и необходимым. Другими словами, это ошибка между текущим и желаемым положением. Нужно отрегулировать скорость поворота ω так, чтобы угол между нашим направлением и целью стал близким к 0. Ошибка должна быть минимизирована:

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

self.kP в приведенном выше коде означает коэффициент усиления системы управления. Он определяет скорость вращения в соответствии с расстоянием, которое осталось до цели. Если ошибка равна 0, скорость вращения тоже 0.

Как определить скорость движения вперед v, зная угловую скорость ω? Если робот не поворачивается, он может ехать вперед на полной скорости, но чем быстрее он поворачивается, тем медленнее нужно продвигаться. Поэтому v является функцией от ω. В go_to_goal_controller.py уравнение имеет следующий вид:

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

Предлагаем уточнить эту формулу, чтобы учесть, что мы обычно замедляемся, когда приближаемся к цели, чтобы достичь ее с нулевой скоростью. Измененная формула должна включать замену v_max() на что-то пропорциональное расстоянию. Итак, мы почти завершили один цикл управления. Единственное, что осталось сделать, – перевести параметры этих двух моноконтрольных моделей в разные скорости колес и послать сигналы в колеса. Вот пример траектории робота без препятствий:

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

Как видим, вектор цели — эффективный ориентир, на котором мы можем основывать свои контрольные вычисления. Но иногда идти к цели напрямик — плохая идея, поэтому мы должны рассчитать другой вектор.


Преодоление препятствий

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

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

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

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

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

Вот код, который делает это вычисление в avoid_obstacles_controller.py:

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

Используя полученный ao_heading_vector, робот будет успешно избегать преград, но не будет продвигаться к цели:

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

Гибридные автоматы

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

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

В нашем фреймворке контролирующее устройство для робота воплощено в файле supervisor_state_machine.py.

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

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

У этой проблемы несколько решений. Читателям, которые ищут более глубоких знаний, стоит проверить архитектуру ПО под названием DAMN.

Но для нашего симулируемого робота подойдет более простое решение: зададим еще одно поведение для преодоления препятствия и перемещения на другую сторону пространства.

 

Поведение «следуй вдоль стены»

Когда мы сталкиваемся с препятствием, то берем показания двух датчиков, которые расположены ближе всего к препятствию, и используем их для оценки поверхности препятствия. Затем устанавливаем опорный вектор так, чтобы он шел параллельно этой поверхности. Продолжаем следовать за стеной, пока А) препятствие больше не будет между нами и целью; Б) мы ближе к цели, чем были вначале. Тогда мы можем быть уверены, что преодолели препятствие правильно.

Имея ограниченную информацию, мы не можем точно определить, где быстрее обойти препятствие — справа или слева. Чтобы принять решение, выбираем направление, которое сразу же приблизит нас к цели. Для этого нужно знать опорные векторы для поведения «идти к цели» (Go-to-Goal behavior) и «избегать препятствий» (Avoid-Obstacle behavior), а также оба возможных вектора «следования за стеной» (Follow-Wall). Вот иллюстрация того, как будет принято окончательное решение (в этом случае робот решит идти налево):

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

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

 

Создание финальной контрольной модели

Итоговая модель использует поведение «следуй вдоль стены» практически для всех столкновений с препятствиями. Однако если робот окажется в труднодоступном месте, в опасной близости от столкновения, он переключится в режим обхода препятствий до тех пор, пока не окажется на более безопасном расстоянии и снова не перейдет в режим следования вдоль стены. После успешного преодоления препятствий включается режим следования к цели. Вот окончательная схема, которая находится в supervisor_state_machine.py:

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

Так выглядит успешное передвижение робота в пространстве с преградами с использованием финальной контрольной модели:

 

Программируем-робота-в-симуляторе-руководство-для-начинающих

 

Метод проб и ошибок

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

Экспериментируйте с составляющими контрольной схемы в Sobot Rimulator, наблюдайте и пытайтесь объяснить результат. Любые изменения, внесенные в схему, повлияют на поведение робота:

  • Ошибки в каждой схеме контроля.
  • Изменения показаний датчиков.
  • Исчисление v как функции ω в каждой схеме контроля.
  • Изменение условий в supervisor_state_machine.py.
  • Почти все другие изменения.

 

Робот в системе Sobot Rimulator не всегда может справиться с определенными картами местности. Иногда он заезжает в угол и не может оттуда выбраться. Иногда он просто двигается взад и вперед возле преграды. В таких ситуациях необходимо добавить новые функции или изменить схему действия.

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

 

Смотрите также:

рейтинг

904

просмотров

0

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

порекомендовать друзьям

ЧИТАТЬ НА ЭТУ ТЕМУ

Loading

комментарии

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

Гость

Дорогие друзья! Помните, что администрация сайта будет удалять:

  • Комментарии с грубой и ненормативной лексикой
  • Прямые или косвенные оскорбления героя поста или читателей
  • Короткие оценочные комментарии ("ужасно", "класс", "отстой")
  • Комментарии, разжигающие национальную и социальную рознь
brand brand