понедельник, 11 июня 2018 г.

URDF. Язык описания роботов

Для описания роботов в ROS используется язык URDF (Universal Robotic Description Format), который является, по сути, диалектом XML. Данный язык представляет робота как совокупность звеньев (link), сочленений (joint), сенсоров и ряда вспомогательных параметров. Для подробного ознакомления с данным форматом могут быть полезны ресурсы: руководство, спецификация элеметов.

Описание звена в общем виде может быть представлено следующим образом. Блок visual содержит видимую модель робота, т.е. описывает его геометрию и свойства поверхности. Геометрия может быть задана как простейшими формами (цилиндр, параллелепипед), так и сеткой, полученной в CAD-системе. Блок collision описывает ту модель, которая будет использована при выявлении столкновений с другими объектами. Чаще всего эта часть совпадает с описанием блока visible, но может и отличаться. Например, для ускорения расчётов сложный профиль поверхности может быть аппроксимирован каким-либо примитивом. В блоке inertial содержатся физические свойства звена, такие как масса или инерция.

<link name="имя_звена">
  <visual>
    ... (геометрическая модель)
  </visual>
  <collision>
    ... (модель, используемая для определения взаимодействия)
  </collision>
  <inertial>
    ... (физические свойства модели)
  </inertial>
</link>

Если робот содержит более одного звена, его элементы должны быть соединены. Для этого служат сочленения, минимальное описание которых включает в себя указание родительского звена, а также звена-потомка. Также, необходимо определить тип соединения: revolute - для вращательных, prizmatic - для призматических, continuous - для колёс, fixed - если закрепление неподвижное.

<joint name="имя_сочленения" type="тип_сочленения">
  <parent link="звено-родитель" /> 
  <child link="звено-потомок" />
</joint>

В качестве примера попробуем сделать описание абстрактного SCARA-робота. Всё описание заключено в теги robot. Первое звено является базовым и представляет собой цилиндр, вытянутый вдоль оси z. Начало координат находится в центре фигуры. Второе звено (link1) представляет собой параллелепипед. Мы хотим, чтобы его основание было закреплено там, где заканчивается base_link. Для этого в сочленении вводятся параметры, заключённые в тег origin. Параметр xyz="0 0 0.28" означает, что координатная система для второго звена будет смещена относительно первого на 0.28 метра по оси z. Число 0.28 состоит из половины длины первого звена (0.25) и половины толщины второго (0.03). Поскольку мы не задали поворот, ориентация направляющих векторов останется прежней. Что касается самого звена, оно должно быть повёрнуто горизонтально и смещено на половину длины (т.к. его начало координат тоже находится в центре). В данном случае можно обойтись без поворота, просто сделав длину по x больше, но для наглядности я ввёл вращение относительно оси y. Поворот и смещение также устанавливается в теге origin. В данном случае звенья должны вращаться друг относительно друга, поэтому тип сочленения - revolute. Тег axis определяет ось вращения (z), а limit задаёт максимальное усилие (effort), нижний и верхний пределы поворота в радианах (lower и upper), и максимальную скорость (velocity).

<?xml version="1.0"?>
<robot name="SCARA"> 

  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.5" radius="0.03" />
      </geometry>     
    </visual>
  </link>

  <link name="link1">
    <visual>
      <geometry>
        <box size="0.06 0.06 0.4" />
      </geometry>     
      <origin rpy="0 1.57075 0" xyz="-0.2 0 0" />
    </visual>
  </link>

  <joint name="base_to_link1" type="revolute">
    <axis xyz="0 0 1" />
    <limit effort="1000.0" lower="-3.14" upper="0" velocity="0.5" />
    <parent link="base_link" />
    <child link="link1" />
    <origin xyz="0 0 0.28" />
  </joint>

  <link name="link2">
    <visual>
      <geometry>
        <box size="0.06 0.06 0.4" />
      </geometry>     
      <origin rpy="0 1.57075 0" xyz="-0.2 0 0" />
    </visual>
  </link>

  <joint name="link1_to_link2" type="revolute">
    <axis xyz="0 0 1" />
    <limit effort="1000.0" lower="-2.8" upper="2.8" velocity="0.5" />
    <parent link="link1" />
    <child link="link2" />
    <origin xyz="-0.4 0 -0.06" />
  </joint>

  <link name="link3">
    <visual>
      <geometry>
        <cylinder length="0.5" radius="0.03" />
      </geometry>     
    </visual>
  </link>

  <joint name="link2_to_link3" type="prismatic">
    <axis xyz="0 0 1" />
    <limit effort="1000.0" lower="-0.22" upper="0.22" velocity="0.5" />
    <parent link="link2" />
    <child link="link3" />
    <origin xyz="-0.43 0 0" />
  </joint>  

</robot>

Следующий элемент (link2) не сильно отличается от предыдущего. Замыкает цепочку цилиндрическое звено (link3) с призматическим сочленением. Результат показан ниже. Ещё раз обращаю внимание, что синие, зелёные и красные стрелки направлены в одном направлении, т.е. поворота системы координат в ходе преобразований не происходит, только смещения.


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

<material name="blue">
  <color  rgba="0 0 1 0" />
</material>

После этого достаточно для звеньев указать <material name="blue" />. Полный файл с описанием робота можно найти по ссылке scara1.urdf.
 
Легко заметить, что urdf-файл имеет древовидную структуру. Для её отображения служит функция urdf_to_graphiz. Например, команда

  urdf_to_graphiz scara1.urdf

сгенерирует pdf-файл, содержащий структуру системы. Проверить корректность urdf-описания позволяет утилита check_urdf. Она также отображает структуру файла в текстовом формате. 

Что касается визуализации модели, оказалось, что это не так просто сделать. Пожалуй, самый простой способ отобразить urdf-файл - залить его содержимое в онлайн симулятор mymodelrobot.appspot.com. Не знаю, как насчёт сложных систем, но простые модели он отображает отлично. Стандартным средством визуализации в ROS является программа Rviz, однако она ориентирована на отображение потоковых данных и просто загрузить в неё модель не удастся. Для решения данной проблемы можно воспользоваться файлами из пакета urdf_tutorial. В частности, для данного поста я создал ноду scara, поместил описание робота в каталог urdf/, а из urdf_tutorial скопировал папки launch/ и rviz/. В файле display.launch я заменил urdf_tutorial на наименование своего пакета (scara). После этого модель стала доступна для отображения с помощью команды

  roslaunch scara display.launch model:='$(find scara)/urdf/scara1.urdf'

 

Комментариев нет:

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