Gazebo - симулятор для роботов. Создаем модель простейшего робота

Газибо представляет собой один из многих симуляторов роботов. Развивается Open Source Robotic Foundation и довольно тесно взаимодействует с Операционной системой для роботов (ROS)


Чтобы установить его на мак для начала необходимо поставить XQuartz:

brew install Caskroom/cask/xquartz

Далее устанавливаем сам газибо:

brew tap osrf/simulation
brew install gazebo7

Вместе с ним в систему будут установлены Qt, OGRE, Bullet3 и Simbody (в качестве физических движков)
Или все это можно сделать с помощью скрипта:
curl -ssL http://get.gazebosim.org | sh

Запускаем клиент:

gazebo

При старте он подгрузит множество моделей, которые можно добавить в сцену. Так, например, можно создать свой мир, добавив туда робота и предметы, с которым он будет взаимодействовать:
Или использовать тестовые миры, которые можно найти в /usr/local/share/gazebo-7/worlds/

Вот, например как Boston Dynamics тренировали ходить своего робота Atlas в газибо:
Попробуем и мы. Далее идет более-ли менее адаптированный перевод tutorial'а по созданию моделей.

Симулятор состоит из сервера gzserver,  который занимается просчетом физики, столкновений симуляцией, сенсоров. В качестве физического движка там используется в том числе библиотека Bullet3, которая может ускорять вычисления с помощью OpenCL на GPU. К серверу могут подсоединятся клиенты - gzclient - один из них. Именно он занимается отображением UI. Для сенсоров и моделей можно писать свои плагины - это позволяет управлять самой моделью и симулировать входные данные от датчиков.

Команда gazebo как раз и запускает оба это приложения по очереди

Миры и модели описываются с помощью SDF - специального формата XML. В принципе в gzclient есть встроенный редактор моделей (Edit -> Model Editor)& Но всегда интереснее покопаться в начинке. И создать своего робота

Для начала создадим папку my_model, с двумя пустыми файлами model.config и model.sdf:
my_model/
├── model.config
└── model.sdf

И создадим симлинк для нашей модели. Так, чтобы Газибо UI видел нашу модель.
ln -s $(pwd)/my_model ~/model_editor_models/my_model

model.config - XML файл с метаданными нашей модели:
<?xml version="1.0"?>
<model>
    <!-- так наша модель будет называться в gzclient-->
    <name>Simple Robot</name>
    
    <version>1.0</version>
    
    <!-- имя файла, в котором содержится сама модель-->
    <sdf version='1.4'>model.sdf</sdf>
    
    <author>
        <name>Max Lunin</name>
        <email>nut.code.monket@gmail.com</email>
    </author>
    
    <description>тестовый робот</description>
</model>

И содержимое самой модели: model.sdf:
<?xml version='1.0'?>
<sdf version="1.4">
  <model name="my_model">
    
    <!-- если модель статическая, она будет игнорироваться
     физическим движком. Это позволит нам пока изменять 
     модель в редакторе -->
    <static>true</static>
    
    <!-- создадим прямоугольное шасси -->
    <link name='chassis'>
      
      <!-- первые три цифры x/y/z позиция модели -->
      <!-- последние три вращение в радианах  x/y/z -->
      <pose>0 0 .1 0 0 0</pose>
      
      <!-- тело, которое будет воспринимать физический движок,
       для определения столкновений. Коробка -->
      <collision name='collision'>
        <geometry>
          <box>
            <!-- размеры в метрах -->
            <size>.4 .2 .1</size>
          </box>
        </geometry>
      </collision>
      
      <!-- тело, которое будет отрисовываться UI клиентом -->
      <visual name='visual'>
        <geometry>
          <box>
            <!-- размеры в метрах -->
            <size>.4 .2 .1</size>
          </box>
        </geometry>
      </visual>
    </link>
  </model>
</sdf>

Теперь можем импортировать наш новосозданный объект в Gazebo клиент и полюбоваться прямоугольником парящим над поверхностью:
Добавим теперь пару колес по бокам, и две связи для них:
<?xml version='1.0'?>
<sdf version="1.4">
  <model name="my_model">
    <static>false</static>
    <link name='chassis'>  
      <pose>0 0 .1 0 0 0</pose>
      <collision name='collision'>
        <geometry>
          <box>
            <!-- размеры в метрах -->
            <size>.4 .2 .1</size>
          </box>
        </geometry>
      </collision>
      <!-- тело, которое будет отрисовываться UI клиентом -->
      <visual name='visual'>
        <geometry>
          <box>
            <!-- размеры в метрах -->
            <size>.4 .2 .1</size>
          </box>
        </geometry>
      </visual>
      
      <!-- заднее колесо будет шаром-->
      <collision name='caster_collision'>
        <pose>-0.15 0 -0.05 0 0 0</pose>
        <geometry>
          <sphere>
            <radius>.05</radius>
          </sphere>
        </geometry>
        <surface>
          <friction>
            <ode>
              <mu>0</mu>
              <mu2>0</mu2>
              <slip1>1.0</slip1>
              <slip2>1.0</slip2>
            </ode>
          </friction>
        </surface>
      </collision>
      <visual name='caster_visual'>
        <pose>-0.15 0 -0.05 0 0 0</pose>
        <geometry>
          <sphere>
            <radius>.05</radius>
          </sphere>
        </geometry>
      </visual>
    </link>
    
    <!-- левое колесо-->
    <link name="left_wheel">
      <pose>0.1 0.13 0.1 0 1.5707 1.5707</pose>
      <collision name="collision">
        <geometry>
          <cylinder>
            <radius>.1</radius>
            <length>.05</length>
          </cylinder>
        </geometry>
      </collision>
      <visual name="visual">
        <geometry>
          <cylinder>
            <radius>.1</radius>
            <length>.05</length>
          </cylinder>
        </geometry>
      </visual>
    </link>
    
    <!-- правое колесо-->
    <link name="right_wheel">
      <pose>0.1 -0.13 0.1 0 1.5707 1.5707</pose>
      <collision name="collision">
        <geometry>
          <cylinder>
            <radius>.1</radius>
            <length>.05</length>
          </cylinder>
        </geometry>
      </collision>
      <visual name="visual">
        <geometry>
          <cylinder>
            <radius>.1</radius>
            <length>.05</length>
          </cylinder>
        </geometry>
      </visual>
    </link>
    
    <!-- соединение левого колеса с шаси по оси Y -->
    <joint type="revolute" name="left_wheel_hinge">
      <pose>0 0 -0.03 0 0 0</pose>
      <child>left_wheel</child>
      <parent>chassis</parent>
      <axis>
        <xyz>0 1 0</xyz>
      </axis>
    </joint>
    
    <!-- соединение правого колеса с шаси по оси Y -->
    <joint type="revolute" name="right_wheel_hinge">
      <pose>0 0 0.03 0 0 0</pose>
      <child>right_wheel</child>
      <parent>chassis</parent>
      <axis>
        <xyz>0 1 0</xyz>
      </axis>
    </joint>
  </model>
</sdf>

Теперь это уже начинает напоминать тележку:

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

Комментарии

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

Популярные сообщения из этого блога

Алгоритм NEAT. Эволюционирующие нейронные сети возрастающих топологий.

Цепи Маркова простыми словами. Пишем пирожки.