Budowanie robota URDF

W wielu przedsięwzięciach robotycznych rozpoczyna się od modelowania robota. To znaczy do stworzenie jakiegoś jego uproszczonego opisu, który pozwala nam sprawdzić, to co akurat sprawdzić chcemy, może to być np.:

  • Możemy przed kupieniem robota chcieć sprawdzić, jak będzie się zachowywał współpracując z innymi maszynami ( np. czy jego wielkości będą OK)
  • Możemy chcieć wyliczyć jakie przyśpieszenia będą miały określone części robota, albo jakie momenty będą w jego złączach, przy wykonywaniu określonego ruchu
  • Możemy też chcieć wizualizować korzystając z modelu robota to co się z nim dzieje przy zdalnej pracy, np. gdy dany robot jest łazikiem marsjańskim.

W ROS formatem jaki możemy użyć do opisu robota (takiego o strukutrze kinematycznej drzewa) jest URDF – Unified Robot Description Format. Format pozwala opisać różne cechy robota, chociaż niekoniecznie wszystkie muszą nas interesować. Najważniejsza z nich to sama struktura geometryczna, to znaczy co do czego jest połączone i jak te połączenia się zachowują – do tego będzie służyć opis złącz (joint) robota. Oprócz tego, istotne będzie opisanie poszczególnych elementów robota (link) i ich parametrów – vizualnych, inercyjnych i kolizyjnych.

URDF to format danych wychodzący z XMLa i w związku z tym pisanie ręczne takich plików wymaga pewnej precyzji i cierpliwości, bo ogólnie w przypadku XMLa trzeba pamiętać o pewnych zasadach, w wielkim skrócie: jeśli coś jest otwarte np: <robot> to musi być zamknięte </robot>. W przypadku elementów, które się zawierają w jednej linijce, zamykamy na koniec dając / np: ` . Drugą ważną zasadą jest że jeśli jakiś element *zawiera* się w drugim, to musi być zamknięty przed tym jak zamkniemy ten zawierający to znaczy: </link> a nie </link>`.

Jeśli chodzi o to jak rozpocząć zabawę z URDF, to moim zdaniem najfajniej jest zbudować sobie R2D2 w MyModelRobot).

Tutorial do MyModelRobot umieściłem na youtubie:

Cały tutorial dostępny jest tutaj, a kod na githubie: https://github.com/ros/urdf_tutorial ale w tym dokumencie przyjrzymy się najważniejszym częściom, bawiąc się kodem z tamtej strony.

Wrzucając taki kod do MyModelRobot:

<?xml version="1.0"?>
<robot name="myfirst">
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
    </visual>
  </link>
</robot>

Co da nam taki efekt:

cylinder

To co stworzyliśmy to robot, składający się z jednego elementu – linku o nazwie “base_link”. Teraz, jeśli np. zmienimy 0.6 na 1.2, długość cylindra wzrośnie.

Skacząc parę kroków, tak wygląda kod dwuelementwego robota:

<?xml version="1.0"?>
<robot name="origins">
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
    </visual>
  </link>

  <link name="right_leg">
    <visual>
      <geometry>
        <box size="0.6 .2 .1"/>
      </geometry>
      <origin rpy="0 1.57075 0" xyz="0 0 -0.3"/>
    </visual>
  </link>

  <joint name="base_to_right_leg" type="fixed">
    <parent link="base_link"/>
    <child link="right_leg"/>
    <origin xyz="0.22 0 .25"/>
  </joint>

</robot>

W kodzie pojawia się sporo nowych elementów. Pierwsze to relacja między dwoma elementami, zrealizowana jako joint. W relacji podajemy kto jest rodzicem a kto dzieckiem, możemy też podać, jak elementy ( ich główne układy współrzędnych) są względem siebie przesunięte czy obrócone, zgodnie z obrazkiem (źródło: http://wiki.ros.org/urdf/XML/joint):

układy_wspolrzednych

Przesunięcie i obrót realizujemy definując parametry xyz i rpy elementu origin. xyz to przesunięcie w osiach x,y,z układu rodzica, rpy to kąty roll (obrót wokół osi x), pitch i yaw, w stałym układzie współrzędych.

Co ważne dany element link ma ze sobą powiązanych ileś układów współrzędnych, każdy związany z określoną cechą robota (wyglądem, przestrzenią kolizji etc). Które mogą być przesunięte czy obrócone względem układu określonego na rysunku jako joint frame.

Jeśli teraz w ostatnim przykładzie zmodyfikujemy typ złącza z fixed na prismatic, to element right_leg będziemy mogli przesuwać, korzystając z suwaka. Dopiszmy jeszcze parametr czyli:

<joint name="base_to_right_leg" type="fixed">
    <parent link="base_link"/>
    <child link="right_leg"/>
    <origin xyz="0.22 0 .25"/>
  </joint>

Aby przesuwać element w osi z złącza. Powinno to wyglądać tak:

filmik

Inne rzeczy, jak ustawianie kolorów elementów, obracanie itd są dobrze opisane w tutorialu po angielsku, gdzie można zbudować sobie legendarnego R2D2: http://wiki.ros.org/urdf/Tutorials/Building%20a%20Visual%20Robot%20Model%20with%20URDF%20from%20Scratch. Polecam też samą dokumentację elementów joint i link, zawiera szczegółowe informacje jak np. nadawać limity złączom czy ustawiać parametry intercyjne.

Na koniec chcę zwrócić uwagę na jedną rzecz. Jako, że często w robotyce modelujemy roboty za pomocą notacji Denavita-Hartenberga, dobrze się trzymać opisywania robota w tych samych układach współrzędnych także pisząc URDF. Trzeba jednak zwrócić uwagę, że tak jak parametry wynikające z notacji DH opisują przejścia w aktualnych osiach (obrót wokół z, przesunięcie wzdłuż z, przesunięcie zdłuż x, obrót wokół x), tak tutaj przejście opisywywane jest w stałych osiach. Dodatkowo parametr axis (który w przypadku notacji DH będzie miał zawsze postać xyz=”0 0 1”, bo po tej osi następuje obrót czy przesunięcie zgodnie z charakterem złącza) pozwala na dołącznienie złaczu obrotu czy przesunięcia jak gdyby na koniec operacji (tj po przesunięciu i obrocie) a nie jak by to wynikało z notacji DH na początek.

Aby ułatwić pracę przy konwertowaniu notacji robota z DH do URDF stworzyłem narzędzie: DH2URDF dostępne pod adresem: https://adohaha.github.io/DH2URDF. Wystarczy wrzucić tabelkę DH a otrzyma się szkielet robota w formacie URDF. Aby trzymać się kolejności transformacji, przejście między kolejnymi układami współprzędnych wymagało dwóch “złącz” formatu URDF.

Notacja D-H wymusza zaczepienie układów w określonych miejscach. To znaczy parametr a translacji po x jest zdefiniowany jako odległość między osiami, stąd nowy układ będzie miał środek tam gdzie taka długość jest najmniejsza. Stąd bardzo przydatne będzie to, że możemy przesuwać sam wygląd (visual) względem układu joint. Zauważcie, że element visual ma własny origin, to znaczy, że można mu nadać przesunięcie i obrót, względem układu współrzędnych jego złącza. Tak jest w ostatnim przykładzie jaki pokazałem. Zamień typ złącza na revolute i zobacz wokół jakiej osi się obraca – bo obraca się wokół osi układu współrzędnych joint

Ogólnie, łatwiej jest rozpocząć od opisania robota korzystając z notacji D-H, a później, wiedząc jak położone są względem siebie układy współrzędnych, rozpocząć opisywanie kolejnych elementów robota w tych układach współrzędnyc. Można rozpocząć nawet od szkieletowego robota ,z prawidłowo rozmieszczonymi układami i później budować na tym szkielecie, już właściwie wyglądającego robota.