Robótica

Clase 09

Semana 10 - 19/05/2025

Gazebo

  • Importancia de los entornos de simulación
  • Gratuito y open-source
  • Mantenido por Open Robotics (ROS)

gazebosim.org

Gazebo + ROS

Entorno virtual que reemplaza al real

Robot simulado que reemplaza al real

  • Lectura de sensores simulados
  • Comandar actuadores virtuales
  • Obtener feedback de los comandos

Sistema con joint_state_publisher_gui

Sistema con Gazebo

Ejcutar Gazebo con ROS2

Desde la linea de comando

$ ros2 launch ros_gz_sim gz_sim.launch.py gz_args:=empty.sdf

Desde archivo launch

    IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            PathJoinSubstitution([
                FindPackageShare('ros_gz_sim'), 'launch', 'gz_sim.launch.py'
            ]),
        ),
        launch_arguments={
            'gz_args': '-r empty.sdf',
            'on_exit_shutdown': 'True'
        }.items(),
    ),

SDF: Simulation Description Format

  • Gazebo utiliza archivos SDF (\(\neq\) URDF)
  • Permite describir un mundo (además de modelos)

Se puede convertir URDF a SDF, pero se necesitan ajustes

Gazebo y URDF

  • Para agregar elementos de Gazebo:

<gazebo> .. </gazebo>

  • Para hacer referencia a elementos del URDF:

<gazebo name="[nombre_link|joint|etc]">

Gazebo y URDF

Requisitos:

  • Nombramiento
  • Propiedades inerciales
  • Materiales y colores

Gazebo y URDF: <collision>

Deben definirse los elementos de colisión para cada link

<link name="[nombre_link]">
    ..
    <collision>
        <origin xyz="[origen]" rpy="[orientacion]"/>
        <geometry>
            <!-- Prisma -->
            <box size="[largo] [ancho] [alto]"/>
            <!-- Cilindro -->
             <cylinder radius="[radio]" length="[ancho]" />
            <!-- Esfera -->
            <sphere radius="[radio]" />
        </geometry>
    </collision>
    ..
</link>

Gazebo y URDF: <inertial>

Deben definirse las propiedades físicas para cada link

<link name="[nombre_link]">
    ..
    <inertial>
        <origin xyz="[traslacion]" rpy="[rotacion]"/>
        <mass value="[masa_kg]"/>
        <inertia ixx="[I_xx]" ixy="[I_xy]" ixz="[I_xz]"
                              iyy="[I_yy]" iyz="[I_yz]"
                                           izz="[I_zz]"/>
    </inertial>
    ..
</link>

inertial_macros.xacro

Se facilita un archivo XACRO para el cálculo de las inercias según la geometría

  • Prisma
    <xacro:inertial_box mass="[masa_kg]" x="[largo]" y="[ancho]" z="[alto]">
        <origin xyz="[traslacion]" rpy="[rotacion]"/>
    </xacro:inertial_box>
  • Cilindro
    <xacro:inertial_cylinder mass="[masa_kg]" radius="[radio]" length="[ancho]">
        <origin xyz="[traslacion]" rpy="[rotacion]"/>
    </xacro:inertial_cylinder>
  • Para cuando sea necesario una inercia despreciable
    <dummy_inertial />

Importar URDF en Gazebo

Dada la descripción del robot disponible en el topic /robot_description (y Gazebo ejecutandose)

  • Desde la linea de comando:
$ ros2 run ros_gz_sim create -topic robot_description -entity <nombre_robot>
  • Desde archivo launch
    Node(
        package="ros_gz_sim",
        executable="create",
        arguments=[
            "-entity", "<nombre_robot>",
            "-topic", "robot_description",
        ],
        output="screen",
    )

ros2_control

Conjunto de paquetes para desarrollar controladores genéricos para todo tipo de robots

ros2_control + Gazebo = gz_ros2_control

Actualizar el URDF

  • Definir un hardware simulado con <ros2_control>
<ros2_control name="GazeboSystem" type="system">
    <hardware>
        <plugin>gz_ros2_control/GazeboSimSystem</plugin>
    </hardware>
    ...
</ros2_control>
  • Añadir el plugin de gz_ros2_control:
<gazebo>
    <plugin filename="gz_ros2_control-system"
            name="gz_ros2_control::GazeboSimROS2ControlPlugin" />
</gazebo>

Actualizar el URDF

  • Definir interfaces para las juntas:
    • Interfaces de estado: <state_interface ../>
    • Interfaces de comando <command_interface .. />

En ambos casos pueden ser:

  • de posición
  • de velocidad
  • de esfuerzo

Actualizar el URDF

Ejemplo control de velocidad y sensado de posición y velocidad

<ros2_control name="GazeboSystem" type="system">
    ...
    <joint name="[nombre_junta]">
        <command_interface name="velocity">
            <!-- Límite de 10 rpm -->
            <param name="min">-1.047198</param>
            <param name="max">1.047198</param>
        </command_interface>
        <state_interface name="position" />
        <state_interface name="velocity" />
    </joint>
    ...
</ros2_control>

Definir controladores

Mediante un archivo de configuración YAML

controller_manager:
  ros__parameters:
    update_rate: 30
    use_sim_time: true

    # NOMBRE_CONTROLADOR
    #  type: TIPO_CONTROLADOR

    joint_broadcaster:
        type: joint_state_broadcaster/JointStateBroadcaster

    velocity_controller:
        type: velocity_controllers/JointGroupVelocityController

Definir parámetros

Mediante un archivo de configuración YAML

velocity_controller:
  ros__parameters:
    joints:
        - {nombre_junta}

    command_interfaces:
        - velocity

    state_interfaces:
        - position
        - velocity

Cargar controladores

Desde la linea de comando

    $ ros2 control load_controller --set-state active
                <nombre_controlador>

Desde archivo launch

    ExecuteProcess(
        cmd=['ros2', 'control', 'load_controller',
             '--set-state', 'active',
             '<nombre_controlador>'],
        output='screen'
    )

Comandos de ros2_control

Listar componentes de hardware disponibles

    $ ros2 control list_hardware_components

Listar interfaces de hardware disponibles

    $ ros2 control list_hardware_interfaces

Listar controladores disponibles (para cargar)

    $ ros2 control list_controller_types

Listar controladores cargados

    $ ros2 control list_controllers

Taller de resolución

Ejercicios 3 y 4