Clase 08 - Taller de resolución
URDF y XACRO
URDF
Etiqueta <robot>..<\robot>
- Etiqueta raíz (todo el contenido se encuentra dentro)
<?xml version="1.0"?>
robot name="mi_robot">
<
...<!-- Contenido URDF -->
... robot> </
Etiqueta <link> .. </link>
- 1 solo atributo: el nombre
- 3 posibles geometrías:
<visual>
,<collision>
y<inertial>
link name="parteA_link">
<visual>..</visual>
<collision>..</collision>
<inertial>..</inertial>
<link> </
Etiqueta <visual> .. </visual>
- Origen:
origin xyz="[pos_x] [pos_y] [pos_z]" rpy="[roll] [pitch] [yaw]"/> <
- Material:
material name="nombre_material">
<color rgba="[R] [G] [B] [Alpha]"/>
<material> </
- Geometría:
<geometry> .. </geometry>
- prisma:
box size="[largo-x] [ancho-y] [alto-z]" /> <
- cilindro:
cylinder radius="[radio]" length="[ancho]" /> <
- esfera:
sphere radius="[radio]" /> <
- malla:
mesh filename="file://[nombre_del_archivo]" /> <
Etiqueta <collision> .. </collision>
- Origen:
origin xyz="[pos_x] [pos_y] [pos_z]" rpy="[roll] [pitch] [yaw]"/> <
- Geometría:
box
,cylinder
,sphere
,mesh
Etiqueta <joint> .. </joint>
- 2 atributos: el nombre y tipo
- 2 elementos requeridos: link padre e hijo
- Tipos:
- Fija (
fixed
)
joint name="parteA_joint" type="fixed"> <parent link="padre_link"/> <child link="parteA_link"/> <origin xyz="[pos_x] [pos_y] [pos_z]" < rpy="[roll] [pitch] [yaw]"/> joint> </
- Continua (
continuous
)
joint name="parteA_joint" type="revolute"> <parent link="padre_link"/> <child link="parteA_link"/> <origin xyz="[pos_x] [pos_y] [pos_z]" < rpy="[roll] [pitch] [yaw]"/> axis xyz="[x] [y] [z]"/> <joint> </
- Revolución (
revolute
)
joint name="parteA_joint" type="revolute"> <parent link="padre_link"/> <child link="parteA_link"/> <origin xyz="[pos_x] [pos_y] [pos_z]" < rpy="[roll] [pitch] [yaw]"/> axis xyz="[x] [y] [z]"/> <limit lower="[min_rad]" upper="[max_rad]" < velocity="[rad_por_seg]" effort="[effort]" /> joint> </
- Fija (
XACRO
Agregar al tag robot
del URDF xmlns:xacro="http://www.ros.org/wiki/xacro"
:
robot name="mi_robot" xmlns:xacro="http://www.ros.org/wiki/xacro" >
<
...<!-- Contenido -->
... robot> </
Inclusión de archivos
- Archivo principal: extensión ‘
.urdf.xacro
’ y contiene el tagrobot
con nombre - Archivos a incluir: extensión ‘
.xacro
’ y solo contienen el tagrobot
- Para incluir:
xacro:include filename="[nombre_archivo]" /> <
Parametrización de atributos
- Propiedades
xacro:property
: Nombre y valor
xacro:property name="diametro" value="2.1" /> <
- Operaciones matemáticas y acceso a variables:
${..}
geometry type="cylinder" radius="${diametro / 2}" length="${nombre_variable}" /> <
- Argumentos
xacro:args
: Nombre y valor por defecto
xacro:arg name="[nombre_argumento]" default="[valor_defecto]"/> <
- Buscar paquetes
$(find ..)
:
xacro:include filename="$(find [nombre_paquete])/[nombre_archivo].xacro" /> <
Bloques condicionales
- Etiqueta
xacro:if
paratrue
yxacro:unless
parafalse
xacro:if value="[expresion]">
<<!-- Si la expresión es verdadera: 'true' o 1 -->
xacro:if>
</xacro:unless value="[expresion]">
<<!-- Si la expresión es falsa: 'false' o 0 -->
xacro:unless> </
Macros
- Definir macro
xacro:macro
: Nombre y parámetros a recibir
xacro:macro name="[nombre_macro]" params="[param1] [param2]:=[valor_defecto]">
<<!-- Codigo del macro: ejemplo con parámetros -->
link name="${param1}">
<visual>
<geometry>
<sphere radius="${param2}" />
<geometry>
</visual>
</link>
</xacro:macro> </
- Aplicar o ejecutar macro
xacro:[nombre_macro]
y los parámetros definidos:
xacro:nombre_macro param1="[valor_param1]" param2="[valor_param2]" /> <
- Si ejecutamos el macro con los valores
parteA_link
y1.0
, la salida será:
...link name="parteA_link">
<visual>
<geometry>
<sphere radius="1.0" />
<geometry>
</visual>
</link>
</ ...
Compilación del URDF
Desde consola
$ xacro [ubicacion_del_archivo/nombre_archivo.xacro.urdf]
Desde launch
- Importar las librerías
from launch.substitutions import Command, PathJoinSubstitution from launch_ros.substitutions import FindPackageShare
- Ubicar el archivo y procesarlo
# Ubicación del paquete y del archivo URDF = PathJoinSubstitution( urdf_path "[nombre_paquete]"), "urdf", "[nombre_archivo].urdf.xacro"] [FindPackageShare( ) # Procesar archivo URDF = Command(['xacro ', urdf_path]) urdf
Adaptación del paquete
- Se agrega la carpeta
urdf
para los archivos de descripción
Ejemplo de estructura
📂 paquete_description
📁 paquete_description
📂 launch
📄 description.launch.py
...
📂 urdf
📄 description.urdf.xacro
📄 materials.xacro
📄 my_macro.xacro
📄 sim_sensor.xacro
...
📄 package.xml
📄 setup.py ...
- Configuración de
setup.py
setup.py
# ... Otros parámetros
data_files=[
# ... Otros archivos
# Incluir todos los archivos de la carpeta launch
(os.path.join('share', package_name, 'launch'), glob('launch/*'))
# Incluir todos los archivos de la carpeta urdf
(os.path.join('share', package_name, 'urdf'), glob('urdf/*'))
# Incluir todos los archivos de la carpeta meshes
(os.path.join('share', package_name, 'meshes'), glob('meshes/*'))
],
Robot state publisher y joint publishers
robot_state_publisher
- Ejecutar desde consola
$ ros2 run robot_state_publisher robot_state_publisher
--ros-args -p robot_description:='<robot_description>'
- Cargar desde launch
Node(= 'robot_state_publisher',
package = 'robot_state_publisher',
executable =[{
parameters'robot_description': '<robot_description>',
}] )
joint_state_publisher_gui
- Ejecutar desde consola
$ ros2 run joint_state_publisher_gui joint_state_publisher_gui
- Cargar desde launch:
Node(= 'joint_state_publisher_gui',
package = 'joint_state_publisher_gui',
executable = 'screen',
output )
Resolución ejercicios 1 y 2
Crear un paquete de ROS llamado (*)_description
para albergar el robot description siguiendo la estructura vista en clases. Crear un archivo de definición del robot en formato XACRO respetando la geometría representada en las vistas del anexo y cumpliendo con los siguientes requerimientos:
- Debe contener al menos un
base_link
asignado al chasis del robot y un link y un joint por cada rueda - Cada link deberá tener definida la geometría visual y de colisión, según la tabla correspondiente del anexo
- Debe estar parametrizado al menos el radio de las ruedas de tracción y la separación de las mismas
- En caso de poder reutilizar bloques, hacer uso de macros
- Utilice el macro
motor
importando el archivomotor.xacro
para ubicar el motor izquierdo y derecho. El macro recibe 3 parámetros:prefix
(String): para diferenciar el link con un prefijochassis_width
(Double): ancho del chasisreflect
(Bool): No reflejar (False
) o sí reflejar (True
). La orientación original es hacia la izquierda
En el mismo paquete, crear un archivo launch de nombre description.launch.py
, en el cuál se deberá procesar el archivo XACRO con la descripción del robot y se deberá publicar la misma a través del paquete robot_state_publisher
. El launch deberá recibir, a través de un parámetro de tipo bool llamado testing
, la condición para ejecutar o no el paquete joint_state_publisher_gui
y RViz
.
Este archivo será útil para probar el archivo del ejercicio anterior, por lo que se recomienda realizarlos en paralelo