Использование Gazebo для обучения с подкреплением

  • Home
  • blog
  • Использование Gazebo для обучения с подкреплением
blog image

Мир крайне сложен.

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

Именно этого и пытаются достичь исследования в области обучения с глубоким подкреплением (DRL — от англ. «deep reinforcement learning»). Конечной целью является создание интеллектуальной компьютерной программы — агента, который учится самостоятельно работать в новом мире только с помощью системы вознаграждения, основанной на его действиях. Если агент достигает цели, которую мы хотим, чтобы он достиг, мы можем дать ему положительное вознаграждение, а отрицательное — за нежелательные действия. Агент выполняет эти действия, основываясь на текущем состоянии мира, которым может быть, например, просто изображение, полученное с камеры. Таким образом, в целом, агент получает состояния и награды от окружающей среды, и совершает действия, основанные на них. Сам процесс обучения основан на нейронных сетях. 

Overused diagram of an agent and environment interaction

Диаграмма взаимодействия агента и окружающей среды. (Источник: Reinforcement Learning -book )

Имеются данные, свидетельствующие о том, что обучение с помощью подкрепления может быть правильным способом применения искусственного интеллекта. Усиливающие обучающие агенты достигли некоторых больших успехов, таких как умение играть в игры Atari, победа над чемпионом мира по игре Го и  освоение сложной игры StarCraft. Но какое отношение имеют игры или, более того, видеоигры к робототехнике? Общий аспект заключается в том, что настройка осталась прежней: у нас есть состояния, действия и награды. Теперь мы просто работаем в трехмерном пространстве, а не в двухмерном пространстве видеоигр.

Если вы хотите поближе познакомиться со всей этой темой, я предлагаю вам посмотреть эту замечательную книгу от Ричарда Саттона и Эндрю Барто.

Установка и настройка Gazebo для экспериментов в области обучения с подкреплением.

Подготовка реальности

Установка «Gazebo» с ROS для глубокого обучения может быть сложной, так как есть много вещей, которые вы должны реализовать и позаботиться о них. Вместо того, чтобы давать здесь полностью детализированное руководство о том, как это сделать, мы представим обзор того, как мы это сделали, и предоставим больше материалов, которым вы можете следовать, если вы хотите реализовать нечто подобное.

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

Обзор среды Gazebo и изображения с точки зрения робота.

Обратите внимание, что количество объектов в Gazebo должно быть минимальным. Многие алгоритмы RL требуют миллионы шагов в симулируемой среде, поэтому мы хотим запустить симуляцию как можно быстрее. Крупные объекты могут значительно пропускать кадры в секунду (fps). Физика для нашего робота также должна быть определена достаточно точно, так как робот будет исследовать все различные действия в данном мире. Из-за проблем с физикой, обсуждавшихся в предыдущих постах блога, нам пришлось перейти от плагина Planar Move, используемого для голономического режима, к Skid Steering Drive.

Еще одна вещь, за которой вам следует следить, это то, как ваш мир будет сохранен, если вы используете графический интерфейс Gazebo для его создания. Мы сделали это вместо того, чтобы определять мир непосредственно в формате .sdf, что вызвало проблемы при сбросе симуляции в Gazebo. Странно, что мир мог быть сброшен, и объекты оставались на своих местах, но робот все равно мог упасть с середины моста, как видно из видео ниже. Так что в каком-то смысле объекты на самом деле были в неправильном положении, но выглядели нормально. Это произошло из-за <state>-тегов в файле, которые были автоматически добавлены Gazebo. Они используются для сохранения определенных позиций объектов в мире Gazebo по отношению к времени моделирования, поэтому сброс не работал так, как предполагалось. Просто удалив эти переходы состояний и перепозиционировав объекты, проблема была решена.

YouTube

By loading the video, you agree to YouTube's privacy policy.
Learn more

Load video

Когда Gazebo спас мир с помощью <state>-tags, перезагрузка мира не сработала, заставив робота упасть с середины моста.

Окружение для тренировки OpenAI Gym

Когда ваш мир Gazebo будет готов, следующим шагом вы должны внедрить окружение   OpenAI gym для вашей задачи. Использование алгоритмов обучения с помощью подкрепления действительно простое, так как в этом случае можно использовать все готовые реализации, такие как  стабильные базовые линии и Keras-RL. Вместо обычного класса окружения, вы должны иметь три отдельных класса окружения:

  • GazeboEnv —Класс, который обрабатывает общение с Gazebo и заключает сделки, например, с перезагрузкой, приостановкой симуляции и ее закрытием. Он всегда один и тот же и не зависит от задачи или робота.

  • RobotEnv — Inherits GazeboEnv. Управляет специальными функциями робота, такими как перемещение робота и считывание данных с датчиков.

  • TaskEnv — Inherits RobotEnv. Обрабатывает специфические функции, например, когда дается вознаграждение, какие действия доступны и когда эпизод заканчивается.

Готовые реализации для GazeboEnv и шаблоны для двух других классов можно найти в репозитории openai_ros repository.

Одна из проблем, с которой мы столкнулись при работе со средами по умолчанию, заключалась в том, как сбрасывалась симуляция. Каждый раз при сбросе тема одометрии переставала публиковаться по каким-то странным причинам. Мы исправили это, просто изменив параметр reset_world_or_sim с “SIMULATION” на “WORLD”. Также физика сбрасывается по умолчанию при запуске, в результате чего наш робот теряет способность двигаться. Изменение параметра start_init_physics_parameters с true на false может быть хорошей идеей, если вы испытываете подобные проблемы.

 

Награды и окончания эпизода

Управление роботом и получение данных с датчиков может быть реализовано довольно просто с помощью Python с использованием тем ROS. Дождитесь действия от нейронной сети, определите, что оно означает с точки зрения линейной и угловой скорости, а затем опубликуйте его на тему управления двигателем. Но как определить, когда роботу даются награды и когда эпизод должен закончиться?

Первое, что пришло нам в голову, это использовать координаты, полученные из Gazebo. Если мы находимся в определенных координатах, мы знаем, что мы достигли этой желаемой позиции и дать награду роботу. Но мы быстро поняли, что это работает не очень хорошо, если мы хотим, например, обнаружить, когда робот сталкивается с чем-то. Нам нужно будет применить tf-трансформации для проверки, например, если только наше левое колесо касается финишной черты. И нам понадобятся различные конечные точки объекта, с которым мы не хотим сталкиваться. С таким подходом все может очень быстро запутаться, поэтому мы подумали, что должен быть лучший способ сделать это.

Эта возможность есть в виде плагина «Контакты»  Contacts plugin  (также называется «Бампер»). С помощью этого плагина можно определить для каждой части робота, какие объекты к ней прикасаются. Мы можем определить индивидуально для базы робота и каждого колеса, если они касаются моста, футболки бетона или линии ворот. Мост был определен как единая переменная столкновения, поэтому, чтобы определить разницу между полом моста и сторонами, мы добавили асфальтовый слой на верхней части моста.

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

Возникла одна ошибка с плагином для контактов. Мы могли бы использовать плагин, посмотреть соответствующую тему ros для него, даже метки времени были правильно опубликованы, но не было никакой информации о коллизиях. Решение мы нашли в  этом видео, сделанным «The Construct». Коротко, проблема была в том, что пространство имён фактических и конечных переменных столкновения не совпадало с теми, что видны в .xacro-файлах. Когда пакет gazebo_ros используется с моделью spawn_model, файл .xacro  сначала автоматически конвертируется в формат .urdf и потом в формат .sdf. Это вызвало проблему с неправильными именами переменных. Вы можете вручную сгенерировать этот .sdf файл, выполнив эти команды:

> rosrun xacro xacro —inorder [FILE_NAME.urdf.xacro] > check_contacts.urdf

> gz sdf -p check_contacts.urdf > check_contacts.sdf

Поэтому мы последовали инструкциям на видео, создав .sdf файл нашего робота, проверили в нем правильное имя переменной, и добавили его внутри <collision> — tags в файл .xacro. Не зная этого, можно подумать, что имя переменной должно быть robot_base_footprint_collision, но, например, для нас окончательное решение выглядело именно так:

<contact>  <collision>robot_base_footprint_fixed_joint_lump__robot_base_link_collision_</collision> </contact>

 

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

 

Финальные оптимизации

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

<max_step_size>0.001</max_step_size>

<real_time_update_rate>1000</real_time_update_rate>

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

Последнее, что вы можете сделать, это отключить GUI, что также должно принести некоторое увеличение скорости. При такой настройке мы можем запустить симуляцию со скоростью ~15x. Когда работал алгоритм обучения, скорость упала до ~6x из-за тяжелых вычислений.

YouTube

By loading the video, you agree to YouTube's privacy policy.
Learn more

Load video

Робот, совершающий случайные действия в окружающей среде

Подводя итог, можно сказать, что теперь у нас есть «тренажерная среда» для выполнения нашей задачи, который реализует рамки между симулятором Gazebo и нашим агентом RL. Наш робот, агент, получает изображение с камеры из окружающей среды, выбирает действие на его основе и получает вознаграждение и следующее изображение из окружающей среды. На следующем этапе мы продолжим добавлять движущиеся объекты в окружающую среду и начнем тестировать различные алгоритмы обучения глубокого усиления.

Оставайтесь с нами!