Manuale per l’Utilizzo di URDF e PyBullet

APPUNTI, SVILUPPO SW, TUTORIAL

La simulazione robotica è un campo importante dell’ingegneria  che consente agli sviluppatori di testare e verificare i comportamenti dei robot in un ambiente virtuale. In questo articolo, esploreremo due strumenti fondamentali utilizzati in questo campo: PyBullet e URDF (Unified Robot Description Format).

Cos’è URDF?

URDF (Unified Robot Description Format) è un linguaggio XML utilizzato per descrivere un robot in termini di sue parti (come link e giunti) e le relazioni tra di loro. Questo formato consente di modellare l’aspetto fisico del robot, le proprietà meccaniche, i sensori, e molto altro.

Cos’è PyBullet?

PyBullet è una libreria di fisica open source per la simulazione di robot, rinomata per le sue funzionalità avanzate e la sua efficacia nel simulare interazioni fisiche reali. Con PyBullet, è possibile caricare modelli di robot in formato URDF e interagire con essi in una varietà di modi.

Installazione di PyBullet

Per installare PyBullet, è possibile utilizzare pip, il gestore di pacchetti Python:

pip install pybullet

Caricamento di un Modello URDF in PyBullet

Una volta installato PyBullet, è possibile caricare un modello URDF. Supponiamo di avere un file URDF chiamato `mio_robot.urdf`. Ecco come si caricherebbe in PyBullet:

import pybullet as p

p.connect(p.GUI)  # Apriamo l'interfaccia utente grafica
robot = p.loadURDF("mio_robot.urdf")  # Carichiamo il modello URDF

Interazione con il Robot

Dopo aver caricato il modello URDF, è possibile interagire con il robot. Per esempio, si può ottenere la posizione e l’orientamento del robot:

posizione, orientamento = p.getBasePositionAndOrientation(robot)
print("Posizione:", posizione)
print("Orientamento:", orientamento)

È anche possibile ottenere informazioni sui giunti del robot e modificarne le posizioni. Ad esempio, se il robot ha un giunto chiamato “giunto1”, è possibile ottenere la sua posizione attuale e impostarne una nuova:

# Ottieni l'ID del giunto
id_giunto1 = p.getJointInfo(robot, "giunto1")[0]

# Ottieni la posizione del giunto
posizione_giunto = p.getJointState(robot, id_giunto1)[0]
print("Posizione del giunto:", posizione_giunto)

# Imposta una nuova posizione per il giunto
p.setJointMotorControl2(robot, id_giunto1, p.POSITION_CONTROL, targetPosition=1.0)

Tag e Proprietà Principali di URDF

Un file URDF è composto da vari tag, ognuno dei quali descrive una parte specifica del robot. Ecco i tag principali che è possibile utilizzare in URDF:

  • robot: Questo è il tag radice di ogni file URDF. È possibile definire un nome per il robot usando l’attributo name.
  • link: Un link rappresenta una parte rigida del robot. Può avere diverse proprietà, tra cui inertial, visual e collision.
  • joint: Un joint rappresenta una connessione tra due link. Può avere diverse proprietà, tra cui parent, child, origin, axis e limit.
  • gazebo: Questo tag viene utilizzato per fornire informazioni specifiche per il simulatore Gazebo.
  • transmission: Questo tag viene utilizzato per descrivere le trasmissioni nel robot, come i riduttori di velocità.

robot

Questo è il tag radice di ogni file URDF. È possibile definire un nome per il robot usando l’attributo name.

<robot name="mio_robot">
  <!-- Definizione dei link e dei giunti -->
</robot>

link

Un link rappresenta una parte rigida del robot. Può avere diverse proprietà, tra cui inertial, visual e collision.

<link name="base">
  <!-- Proprietà del link -->
</link>

Le proprietà di un link includono:

  • inertial: Questo tag descrive le proprietà inerziali del link. Include i seguenti sotto-tag:
    • mass: Definisce la massa del link.
    • origin: Specifica l’origine del frame inerziale rispetto al frame del link.
    • inertia: Definisce i momenti d’inerzia rispetto ai tre assi del frame inerziale.
  • visual: Questo tag descrive come il link dovrebbe apparire quando viene visualizzato. Include i seguenti sotto-tag:
    • geometry: Definisce la forma del link.
    • material: Definisce il colore e la trama del link.
  • collision: Questo tag descrive come il link dovrebbe comportarsi in caso di collisione. Include un sotto-tag geometry come quello nel tag visual.

joint

Un joint rappresenta una connessione tra due link. Può avere diverse proprietà, tra cui parent, child, origin, axis e limit.

<joint name="giunto_base_braccio" type="revolute">
  <!-- Proprietà del giunto -->
</joint>

Le proprietà di un joint includono:

  • parent: Definisce il link padre.
  • child: Definisce il link figlio.
  • origin: Specifica l’origine del frame del giunto rispetto al frame del link padre.
  • axis: Definisce l’asse del giunto (per i giunti rotatori).
  • limit: Stabilisce i limiti di movimento del giunto.

gazebo

Questo tag viene utilizzato per fornire informazioni specifiche per il simulatore Gazebo.

<gazebo>
  <!-- Proprietà specifiche di Gazebo -->
</gazebo>

transmission

Questo tag viene utilizzato per descrivere le trasmissioni nel robot, come i riduttori di velocità.

<transmission name="trasmissione">
  <!-- Proprietà della trasmissione -->
</transmission>

Semplice Modello URDF

Creare un modello URDF richiede una certa pratica, ma può essere un processo molto gratificante. Iniziamo con un esempio di base: un robot con due link (la base e il braccio) collegati da un giunto. Questo robot è piuttosto semplice, ma il modello URDF ci mostra come definire i link, impostare alcune delle loro proprietà e creare un giunto.

Ecco come potrebbe apparire l’URDF per il nostro robot:

<robot name="mio_robot">

  <!-- Primo link -->
  <link name="base">
    <inertial>
      <mass value="1.0" />
      <origin rpy="0 0 0" xyz="0 0 0.1" />
      <inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0" />
    </inertial>
  </link>

  <!-- Secondo link -->
  <link name="braccio">
    <inertial>
      <mass value="1.0" />
      <origin rpy="0 0 0" xyz="0 0 0.5" />
      <inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0" />
    </inertial>
  </link>

  <!-- Giunto -->
  <joint name="giunto_base_braccio" type="revolute">
    <parent link="base" />
    <child link="braccio" />
    <origin rpy="0 0 0" xyz="0 0 1.0" />
    <axis xyz="0 1 0" />
    <limit effort="100.0" lower="-3.1416" upper="3.1416" velocity="1.0" />
  </joint>

</robot>

In questo esempio, abbiamo definito due link chiamati “base” e “braccio”. Ogni link ha un tag “inertial”, che definisce le proprietà inerziali del link. Abbiamo anche definito un giunto di tipo “revolute” che connette la “base” e il “braccio”.

Questo è un esempio di base, ma URDF è capace di molto di più. Puoi definire un numero qualsiasi di link e giunti, impostare le proprietà visive e di collisione dei link, definire sensori e attuatori, e altro ancora.

Il codice URDF seguente invece è un esempio più complesso ed è la descrizione di un drone quadricottero. Il robot ha una struttura composta da un link centrale (o base) e quattro eliche, ognuna delle quali è modellata come un link separato collegato alla base con un giunto fisso.

1. Proprietà: Le proprietà del robot, come la massima velocità, il raggio dell’elica, i coefficienti di trascinamento, e altri parametri fisici, sono definiti all’inizio del file.

2. Link base: Il link centrale del robot, “base_link”, ha una massa di 0.027 kg e un tensore di inerzia specificato. Questo link ha anche una forma di visualizzazione, un box grigio, e una forma di collisione, un cilindro.

3. Link delle eliche: Ci sono quattro eliche, ognuna delle quali è modellata come un link separato (“prop0_link”, “prop1_link”, “prop2_link”, “prop3_link”). Ciascuna elica è posizionata in un angolo diverso attorno alla base. Le eliche non hanno massa o inerzia, il che implica che nel modello non contribuiscono all’inerzia del robot. Ogni elica è visualizzata come un cilindro di un colore diverso.

4. Giunti: Ogni elica è collegata alla base con un giunto fisso. Questo significa che le eliche non possono muoversi o ruotare rispetto alla base nel modello URDF.

5. Centro di massa: Infine, c’è un link aggiuntivo chiamato “center_of_mass_link” che è collegato alla base con un giunto fisso. Questo link non ha massa o inerzia, e non viene visualizzato nel modello. Potrebbe essere utilizzato per calcolare il centro di massa del robot in una simulazione.

 

<?xml version="1.0" ?>

<robot name="cf2_x_variant">

  <properties arm="0.0397" kf="3.16e-10" km="7.94e-12" thrust2weight="2.25" max_speed_kmh="30" gnd_eff_coeff="11.36859" prop_radius="2.31348e-2" drag_coeff_xy="9.1785e-7" drag_coeff_z="10.311e-7" dw_coeff_1="2267.18" dw_coeff_2=".16" dw_coeff_3="-.11" />

  <link name="base_link">

    <inertial>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <mass value="0.027"/>
      <inertia ixx="1.4e-5" ixy="0.0" ixz="0.0" iyy="1.4e-5" iyz="0.0" izz="2.17e-5"/>
    </inertial>


    <visual>
      <origin rpy="0 0 55" xyz="0 0 -0.005"/>
      <geometry>
        <box size="0.04 0.04 0.015"/>
      </geometry>
      <material name="grey">
        <color rgba=".5 .5 .5 1"/>
      </material>
    </visual>

    <collision>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <cylinder radius=".06" length=".025"/>
      </geometry>
    </collision>

  </link>

  <link name="prop0_link">
    <inertial>
      <origin rpy="0 0 0" xyz="0.028 0.028 0"/>
      <mass value="0"/>
      <inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/>
    </inertial>
    <visual>
      <origin rpy="0 0 0" xyz="0.028 0.028 0.005"/>
      <geometry>
        <cylinder radius=".02" length=".015"/>
      </geometry>
      <material name="light_red">
        <color rgba="1.0 0.0 0.0 0.5"/>
      </material>
    </visual>
  </link>
  <joint name="prop0_joint" type="fixed">
    <parent link="base_link"/>
    <child link="prop0_link"/>
  </joint>

  <link name="prop1_link">
    <inertial>
      <origin rpy="0 0 0" xyz="-0.028 0.028 0"/>
      <mass value="0"/>
      <inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/>
    </inertial>
    <visual>
      <origin rpy="0 0 0" xyz="-0.028 0.028 0.005"/>
      <geometry>
        <cylinder radius=".02" length=".015"/>
      </geometry>
      <material name="light_yellow">
        <color rgba="1.0 1.0 0.0 0.5"/>
      </material>
    </visual>
  </link>
  <joint name="prop1_joint" type="fixed">
    <parent link="base_link"/>
    <child link="prop1_link"/>
  </joint>

  <link name="prop2_link">
    <inertial>
      <origin rpy="0 0 0" xyz="-0.028 -0.028 0"/>
      <mass value="0"/>
      <inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/>
    </inertial>
    <visual>
      <origin rpy="0 0 0" xyz="-0.028 -0.028 0.005"/>
      <geometry>
        <cylinder radius=".02" length=".015"/>
      </geometry>
      <material name="light_green">
        <color rgba="0.0 1.0 0.0 0.5"/>
      </material>
    </visual>
  </link>
  <joint name="prop2_joint" type="fixed">
    <parent link="base_link"/>
    <child link="prop2_link"/>
  </joint>

  <link name="prop3_link">
    <inertial>
      <origin rpy="0 0 0" xyz="0.028 -0.028 0"/>
      <mass value="0"/>
      <inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/>
    </inertial>
    <visual>
      <origin rpy="0 0 0" xyz="0.028 -0.028 0.005"/>
      <geometry>
        <cylinder radius=".02" length=".015"/>
      </geometry>
      <material name="light_blue">
        <color rgba="0.0 0.0 1.0 0.5"/>
      </material>
    </visual>
  </link>
  <joint name="prop3_joint" type="fixed">
    <parent link="base_link"/>
    <child link="prop3_link"/>
  </joint>

  <link name="center_of_mass_link">
    <inertial>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <mass value="0"/>
      <inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/>
    </inertial>
  </link>
  <joint name="center_of_mass_joint" type="fixed">
    <parent link="base_link"/>
    <child link="center_of_mass_link"/>
  </joint>

</robot>

 

Se vuoi farmi qualche richiesta o contattarmi per un aiuto riempi il seguente form

    Comments