ROS Efficient Advanced Capítulo 2: tome el robot con ruedas diferenciales como ejemplo para aprender el modelado de robots URDF y la optimización xacro

1 recurso

Este artículo es el segundo capítulo de ROS Efficient Advanced. Usamos el lenguaje URDF (formato xml) para hacer un modelo de robot con ruedas diferenciales, y usamos la versión mejorada de URDF xacro para volver a optimizar el archivo del modelo de robot.
Robot de rueda diferencial: El chasis diferencial de dos ruedas consta de dos ruedas motrices ubicadas en los lados izquierdo y derecho del chasis. Las dos ruedas controlan la velocidad de forma independiente, y el control de dirección del chasis se realiza dando diferentes velocidades. Generalmente estará equipado con una o dos ruedas universales para apoyo auxiliar.
En este modelado, no se introduce ningún algoritmo, solo se hace la apariencia del modelo de robot, por lo que solo se usa rivz para la visualización.
Referencias para este artículo:
(0) Modelo de cinemática de robot diferencial de dos ruedas
(1) Capítulo 5 y Capítulo 6 de "Práctica de desarrollo de robots ROS" Hu Chunxu (
2) Resumen de exploración de ROS: Interpretación de URDF
(3) Resumen de exploración de ROS: Cómo empezar desde cero Crear un modelo de robot (brazo robótico)
(4) ROS Eficiente Avanzado Capítulo 1 – rviz de ROS Componentes Avanzados

2 texto

2.1 Definición y composición de robots

(1) Definición de robot: Un robot es una máquina automatizada. La diferencia es que esta máquina tiene algunas habilidades inteligentes similares a las de los humanos o criaturas, como la percepción, la planificación, la acción y la coordinación. Es una máquina automatizada flexible avanzada.
Actualmente, los coches autónomos también se consideran un tipo de robot.
(2) Composición de los robots: los robots generalmente se dividen en cuatro partes, a saber, actuadores, sistemas de accionamiento, sistemas de detección y sistemas de control.
Tomando como ejemplo los automóviles autónomos, el actuador es el acelerador, la dirección y el freno; el sistema de conducción es el motor; el sistema de detección son varios sensores: lidar, radar, cámara, uss, imu, GNSS; el sistema de control es el Sistema de algoritmo de conducción inteligente: percepción, posicionamiento, planificación y control.
(3) Los lazos de control de las cuatro partes principales del robot son aproximadamente como se muestra en la figura:
inserte la descripción de la imagen aquí

2.2 Rutina de modelado URDF

(1) URDF: formato de descripción de robot unificado, un formato de archivo de descripción de robot unificado. Los archivos urdf utilizan el formato xml.
(2) Usando urdf para describir el robot, la rutina es la siguiente: cada robot está compuesto de múltiples enlaces (bielas) y articulaciones (articulaciones). El enlace y la junta aquí son muy anchos, y las formas no son necesariamente varillas y ejes. Por ejemplo, una mesa, el tablero y las patas son enlaces, y las juntas son juntas fijas.

<?xml version="1.0" ?>
<robot name="name of robot">
	<link> ... </link>
	<joint> ... </joint>
	...
</robot>

inserte la descripción de la imagen aquí
(3) enlace: Describa la apariencia y las propiedades físicas de una parte del cuerpo rígido del robot. La apariencia incluye: tamaño, color, forma. Las propiedades físicas incluyen: matriz de inercia (matriz inercial) y parámetros de colisión (propiedades de colisión). En el modelado de robots, cada vínculo es un sistema de coordenadas.
El siguiente es el modelado del chasis del robot de ruedas diferenciales, que generalmente se llama base.

  <link name="base_link">
  	// visual 标签就是外观
    <visual>
      // base_link本身是个坐标系,这也是差速轮式机器人各组成部分的根坐标系,一般会把他的坐标原点设置在rviz的中心处
      // origin表示底盘在其base_link坐标系下的原始位置和旋转状态
      // xyz表示底盘质心在base_link坐标系的偏移位置,rpy(roll,pitch,yaw)是底盘绕base_link的x,y,z三个轴的旋转值
      <origin xyz="0 0 0" rpy="0 0 0"/>
      // geometry是物体几何外形
      <geometry>
      	// 这里的底盘,用圆柱体表示,length值为高度,radius是半径值
        <cylinder length="0.16" radius="0.2"/>
      </geometry>
      // material是材料,这里指定底盘颜色为红色,rgba是三色+透明度表示法,三色的范围是0~1,而不是0-255
      <material name="red">
        <color rgba="1 0 0 1"/>
      </material>
    </visual>
  </link>

Suplemento: Aquí solo hacemos modelos de apariencia, por lo que no involucramos la configuración de atributos físicos por el momento. Cuando simule en la glorieta en el próximo capítulo, agregaremos atributos físicos al enlace en la muestra.
(4) unión: describe la relación entre dos enlaces, incluidos los atributos cinemáticos y dinámicos. Aquí solo nos centramos en los atributos cinemáticos. Por lo general, la relación entre dos enlaces generalmente se divide en seis tipos:

continuous:旋转关节,可以围绕单轴360度无限旋转,比如轮子的轴
revolute:旋转关节,但是有旋转角度的范围限制,比如钟摆
prismatic:滑动关节,也叫活塞关节,沿某一轴线移动的关节,有位置限制,强调一维,比如打气筒
planar:平面关节,允许在平面正交方向上平移或旋转,强调平面,比如抽屉内外滑动
floating:浮动关节,允许进行平移和旋转运动,比如人体的肩关节
fixed:固定关节,比如桌子腿和桌面

A continuación se muestra un ejemplo de la unión entre la rueda motriz y el chasis del robot rueda diferencial:

  // joint标签就是关节,type表示链接关系
  <joint name="left_wheel_joint" type="continuous">
    // origin表示轮子在base_link坐标系下的偏移和旋转
    <origin xyz="0 0.19 -0.05" rpy="0 0 0" />
    // 根link是底盘,子link是轮子
    <parent link="base_link" />
    <child link="left_wheel_link" />
    // axis描述的轮子相对于其自身坐标系的 y 轴旋转,=
    <axis xyz="0 1 0" />
  </joint>
  
  // 这是轮子link
  <link name="left_wheel_link">
    <visual>
      // 轮子相当于其x轴,旋转90度,也就是立起来
      <origin xyz="0 0 0" rpy="1.5707 0 0"/>
      <geometry>
        <cylinder length="0.06" radius="0.06"/>
      </geometry>
      <material name="white">
        <color rgba="1 1 1 0.9"/>
      </material>
    </visual>
  </link>

2.3 Usar URDF para hacer un modelo de robot diferencial con ruedas

(1) Cree el paquete mbot_description y los archivos relacionados

cd ~/catkin_ws/src
catkin_create_pkg mbot_description urdf xacro

cd mbot_description 
mkdir -p config doc launch meshes urdf/sensor
touch launch/display_mbot_urdf.launch launch/display_mbot_xacro.launch
touch urdf/mbot_base.urdf urdf/mbot_base.xacro
touch urdf/sensor/camera.xacro urdf/sensor/kinect.xacro urdf/sensor/laser.xacro

(2) mbot_base.urdf: este es el archivo de modelado de mbot completo, incluido el chasis, dos ruedas motrices, dos ruedas universales, una cámara, un kinect (cámara de profundidad) y un lidar. Para la gramática específica, consulte la introducción en la sección anterior, por lo que no la repetiré aquí.

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

  <link name="base_link">
    <visual>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <geometry>
        <cylinder length="0.16" radius="0.2"/>
      </geometry>
      <material name="red">
        <color rgba="1 0 0 1"/>
      </material>
    </visual>
  </link>

  <joint name="left_wheel_joint" type="continuous">
    <origin xyz="0 0.19 -0.05" rpy="0 0 0" />
    <parent link="base_link" />
    <child link="left_wheel_link" />
    <axis xyz="0 1 0" />
  </joint>

  <link name="left_wheel_link">
    <visual>
      <origin xyz="0 0 0" rpy="1.5707 0 0"/>
      <geometry>
        <cylinder length="0.06" radius="0.06"/>
      </geometry>
      <material name="white">
        <color rgba="1 1 1 0.9"/>
      </material>
    </visual>
  </link>

  <joint name="right_wheel_joint" type="continuous">
    <origin xyz="0 -0.19 -0.05" rpy="0 0 0" />
    <parent link="base_link" />
    <child link="right_wheel_link" />
    <axis xyz="0 1 0" />
  </joint>

  <link name="right_wheel_link">
    <visual>
      <origin xyz="0 0 0" rpy="1.5707 0 0"/>
      <geometry>
        <cylinder length="0.025" radius="0.06" />
      </geometry>
      <material name="white">
        <color rgba="1 1 1 0.9"/>
      </material>
    </visual>
  </link>

  <joint name="front_caster_joint" type="continuous">
    <origin xyz="0.18 0 -0.095" rpy="0 0 0" />
    <parent link="base_link"/>
    <child link="front_caster_link" />
    <axis xyz="0 1 0" />
  </joint>

  <link name="front_caster_link">
    <visual>
      <origin xyz="0 0 0" rpy="0 0 0" />
      <geometry>
        <sphere radius="0.015" />
      </geometry>
      <material name="white">
        <color rgba="1 1 1 0.9"/>
      </material>
    </visual>
  </link>

  <joint name="back_caster_joint" type="continuous">
    <origin xyz="-0.18 0 -0.095" rpy="0 0 0" />
    <parent link="base_link"/>
    <child link="back_caster_link" />
    <axis xyz="0 1 0" />
  </joint>

  <link name="back_caster_link">
    <visual>
      <origin xyz="0 0 0" rpy="0 0 0" />
      <geometry>
        <sphere radius="0.015" />
      </geometry>
      <material name="white">
        <color rgba="1 1 1 0.9"/>
      </material>
    </visual>
  </link>

  <joint name="camera_joint" type="fixed">
    <origin xyz="-0.17 0 0.1" rpy="0 0 0" />
    <parent link="base_link"/>
    <child link="camera_link" />    
  </joint>

  <link name="camera_link">
    <visual>
      <origin xyz="0 0 0" rpy="0 0 0" />
      <geometry>
        <box size="0.03 0.04 0.04" />
      </geometry>
      <material name="grey">
        <color rgba="0.5 0.5 0.5 1"/>
      </material>
    </visual>
  </link>

  <joint name="stage_joint" type="fixed">
    <origin xyz="0 0 0.14" rpy="0 0 0" />
    <parent link="base_link"/>
    <child link="stage_link" />    
  </joint>

  <link name="stage_link">
    <visual>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <geometry>
        <cylinder length="0.12" radius="0.1"/>
      </geometry>
      <material name="red">
        <color rgba="1 0 0 1"/>
      </material>
    </visual>
  </link>

  <joint name="laser_joint" type="fixed">
    <origin xyz="0 0 0.085" rpy="0 0 0" />
    <parent link="stage_link"/>
    <child link="laser_link" />    
  </joint>

  <link name="laser_link">
    <visual>
      <origin xyz="0 0 0" rpy="0 0 0" />
      <geometry>
        <cylinder length="0.05" radius="0.05"/>
      </geometry>
      <material name="grey">
        <color rgba="0.5 0.5 0.5 1"/>
      </material>
    </visual>
  </link>

  <joint name="kinect_joint" type="fixed">
    <origin xyz="0.15 0 0.11" rpy="0 0 0" />
    <parent link="base_link"/>
    <child link="kinect_link" />    
  </joint>

  <link name="kinect_link">
    <visual>
      <origin xyz="0 0 0" rpy="0 0 1.5708" />
      <geometry>
        // 使用三维软件导出的模型文件
        <mesh filename="package://mbot_description/meshes/kinect.dae" />
      </geometry>
    </visual>
  </link>
</robot>

(3)display_mbot_urdf.lanzamiento

<launch>
  // 设置ros的全局参数robot_description,指定机器人模型文件
  <param name="robot_description" textfile="$(find mbot_description)/urdf/mbot_base.urdf" />

	<!-- 设置GUI参数,显示关节控制插件 -->
	// 用这个可以控制机器人关节,但本文的demo没看到这个,有点遗憾
	<param name="use_gui" value="true"/>

	<!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
	<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />

	<!-- 运行robot_state_publisher节点,发布tf  -->
	<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />

	// robot_state_publisher结合joint_state_publisher可以实时把机器人各关节和各坐标系关系发布出来,让rviz显示。如果不设置,rviz无法完整加载机器人模型。
	// rviz显示后会生成配置文件,保存后再打开,就不用频繁设置了。
	<!-- 运行rviz可视化界面 -->
	<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mbot_description)/config/mbot_urdf.rviz" required="true" />

</launch>

(4) Utilice la herramienta de línea de comandos urdf_to_graphiz para volcar el contenido del archivo urdf en forma de árbol en formato pdf. Use esto para leer rápidamente el enlace y la unión de urdf, la siguiente figura es el diagrama de árbol de nodos del ejemplo anterior.

cd ~/catkin_ws/
urdf_to_graphiz src/mbot_description/urdf/mbot_base.urdf

inserte la descripción de la imagen aquí

(5) Compilar y ejecutar

cd ~/catkin_ws/
catkin_make --source src/mbot_description
source devel/setup.bash
roslaunch mbot_description display_mbot_urdf.launch

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

2.4 Uso de xacro para optimizar el modelo de robot con ruedas diferenciales

(1) La sintaxis original de urdf es relativamente simple, lo que da como resultado archivos de modelo de robot extensos. Por ejemplo, la escritura de dos ruedas motrices y dos ruedas universales es muy repetitiva. ROS propone la sintaxis xacro para permitir que los archivos de modelos de robots sean programables, como establecer parámetros, definir funciones macro y llamarlas, e inclusión de archivos. El siguiente es un ejemplo de clasificación:
configuración y llamada de parámetros:

   // xacro:property设置参数
  <xacro:property name="M_PI" value="3.1415926" />
  // 引用参数用${}
  <origin xyz="0 0 0" rpy="${M_PI/2} 0 0"/>

Configure la función macro y llame:

  // xacro:macro设置宏函数,名字是wheel,参数是prefix 和 reflect
  <xacro:macro name="wheel" params="prefix reflect">
    <joint name="${prefix}_wheel_joint" type="continuous">
      <origin xyz="${wheel_joint_x} ${reflect*wheel_joint_y} ${-wheel_joint_z}" rpy="0 0 0" />
      <parent link="base_link" />
      <child link="${prefix}_wheel_link" />
      <axis xyz="0 1 0" />
    </joint>

    <link name="${prefix}_wheel_link">
      <visual>
        <origin xyz="0 0 0" rpy="${M_PI/2} 0 0"/>
        <geometry>
          <cylinder length="${wheel_length}" radius="${wheel_radius}"/>
        </geometry>
        <material name="white" />
      </visual>
    </link>
  </xacro:macro>
  // 调用wheel宏函数
  <xacro:wheel prefix="left"  reflect="1"/>  
  <xacro:wheel prefix="right"  reflect="-1"/>  

el archivo contiene

  // xacro:include是文件包含,camera.xacro里面定义了一个宏函数
  <xacro:include filename="$(find mbot_description)/urdf/sensor/camera.xacro" />
  // 调用camera.xacro里面的宏函数
  <xacro:usb_camera joint_x="${camera_joint_x}" joint_y="${camera_joint_y}" joint_z="${camera_joint_z}"/>  

(2) Los varios archivos aquí son la reescritura del mbot_base.urdf anterior, usando xacro, vea la explicación anterior para la sintaxis específica.
mbot_base.xacro

<?xml version="1.0" ?>
<robot name="mbot" xmlns:xacro="http://www.ros.org/wiki/xacro">
  <xacro:property name="M_PI" value="3.1415926" />

  <xacro:property name="wheel_joint_x" value="0" />
  <xacro:property name="wheel_joint_y" value="0.19" />
  <xacro:property name="wheel_joint_z" value="0.05" />

  <xacro:property name="wheel_length" value="0.06" />
  <xacro:property name="wheel_radius" value="0.06" />

  <xacro:property name="caster_joint_x" value="0.18" />
  <xacro:property name="caster_joint_y" value="0" />
  <xacro:property name="caster_joint_z" value="0.095" />  

  <xacro:property name="caster_radius" value="0.015" />

  <xacro:property name="base_length" value="0.16" />
  <xacro:property name="base_radius" value="0.2" />

  <xacro:property name="stage_length" value="0.12" />
  <xacro:property name="stage_radius" value="0.1" />

  <xacro:property name="camera_joint_x" value="0.17" />
  <xacro:property name="camera_joint_y" value="0" />
  <xacro:property name="camera_joint_z" value="0.1" />  

  <xacro:property name="kinect_joint_x" value="0.15" />
  <xacro:property name="kinect_joint_y" value="0" />
  <xacro:property name="kinect_joint_z" value="0.11" />  

  <xacro:property name="laser_joint_x" value="0" />
  <xacro:property name="laser_joint_y" value="0" />
  <xacro:property name="laser_joint_z" value="0.085" />  

  <material name="white">
    <color rgba="1 1 1 0.9"/>
  </material>
  <material name="red">
    <color rgba="1 0 0 1"/>
  </material>

  <material name="grey">
    <color rgba="0.5 0.5 0.5 1"/>
  </material>

  <xacro:macro name="base_stage">
    <link name="base_link">
      <visual>
        <origin xyz="0 0 0" rpy="0 0 0"/>
        <geometry>
          <cylinder length="${base_length}" radius="${base_radius}"/>
        </geometry>
        <material name="red" />
      </visual>
    </link>

    <joint name="stage_joint" type="fixed">
      <origin xyz="0 0 ${(base_length + stage_length)/2}" rpy="0 0 0" />
      <parent link="base_link"/>
      <child link="stage_link" />    
    </joint>

    <link name="stage_link">
      <visual>
        <origin xyz="0 0 0" rpy="0 0 0"/>
        <geometry>
          <cylinder length="${stage_length}" radius="${stage_radius}"/>
        </geometry>
        <material name="red" />
      </visual>
    </link>
  </xacro:macro>

  <xacro:macro name="wheel" params="prefix reflect">
    <joint name="${prefix}_wheel_joint" type="continuous">
      <origin xyz="${wheel_joint_x} ${reflect*wheel_joint_y} ${-wheel_joint_z}" rpy="0 0 0" />
      <parent link="base_link" />
      <child link="${prefix}_wheel_link" />
      <axis xyz="0 1 0" />
    </joint>

    <link name="${prefix}_wheel_link">
      <visual>
        <origin xyz="0 0 0" rpy="${M_PI/2} 0 0"/>
        <geometry>
          <cylinder length="${wheel_length}" radius="${wheel_radius}"/>
        </geometry>
        <material name="white" />
      </visual>
    </link>
  </xacro:macro>

  <xacro:macro name="caster" params="prefix reflect">
    <joint name="${prefix}_caster_joint" type="continuous">
      <origin xyz="${reflect*caster_joint_x} ${caster_joint_y} ${-caster_joint_z}" rpy="0 0 0" />
      <parent link="base_link"/>
      <child link="${prefix}_caster_link" />
      <axis xyz="0 1 0" />
    </joint>

    <link name="${prefix}_caster_link">
      <visual>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <geometry>
          <sphere radius="${caster_radius}" />
        </geometry>
        <material name="white" />
      </visual>
    </link>
  </xacro:macro>

  <xacro:base_stage />  
  <xacro:wheel prefix="left"  reflect="1"/>  
  <xacro:wheel prefix="right"  reflect="-1"/>  

  <xacro:caster prefix="front"  reflect="1"/>  
  <xacro:caster prefix="back"  reflect="-1"/>  

  <xacro:include filename="$(find mbot_description)/urdf/sensor/camera.xacro" />
  <xacro:usb_camera joint_x="${camera_joint_x}" joint_y="${camera_joint_y}" joint_z="${camera_joint_z}"/>  

  <xacro:include filename="$(find mbot_description)/urdf/sensor/kinect.xacro" />
  <xacro:kinect joint_x="${kinect_joint_x}" joint_y="${kinect_joint_y}" joint_z="${kinect_joint_z}"/>  

  <xacro:include filename="$(find mbot_description)/urdf/sensor/laser.xacro" />
  <xacro:laser joint_x="${laser_joint_x}" joint_y="${laser_joint_y}" joint_z="${laser_joint_z}"/>  

</robot>

camara.xacro

<?xml version="1.0" ?>
<robot name="mbot" xmlns:xacro="http://www.ros.org/wiki/xacro">
  <xacro:macro name="usb_camera" params="joint_x joint_y joint_z">
    <joint name="camera_joint" type="fixed">
      <origin xyz="${-joint_x} ${joint_y} ${joint_z}" rpy="0 0 0" />
      <parent link="base_link"/>
      <child link="camera_link" />    
    </joint>

    <link name="camera_link">
      <visual>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <geometry>
          <box size="0.03 0.04 0.04" />
        </geometry>
        <material name="grey" />
      </visual>
    </link>
  </xacro:macro>
</robot>

kinect.xacro

<?xml version="1.0" ?>
<robot name="mbot" xmlns:xacro="http://www.ros.org/wiki/xacro">

  <xacro:macro name="kinect" params="joint_x joint_y joint_z">
    <joint name="kinect_joint" type="fixed">
      <origin xyz="${joint_x} ${joint_y} ${joint_z}" rpy="0 0 0" />
      <parent link="base_link"/>
      <child link="kinect_link" />    
    </joint>

    <link name="kinect_link">
      <visual>
        <origin xyz="0 0 0" rpy="0 0 1.5708" />
        <geometry>
          <mesh filename="package://mbot_description/meshes/kinect.dae" />
        </geometry>
      </visual>
    </link>
  </xacro:macro>

</robot>

láser.xacro

<?xml version="1.0" ?>
<robot name="mbot" xmlns:xacro="http://www.ros.org/wiki/xacro">

  <xacro:macro name="laser" params="joint_x joint_y joint_z">
    <joint name="laser_joint" type="fixed">
      <origin xyz="${joint_x} ${joint_y} ${joint_z}" rpy="0 0 0" />
      <parent link="stage_link"/>
      <child link="laser_link" />    
    </joint>

    <link name="laser_link">
      <visual>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <geometry>
          <cylinder length="0.05" radius="0.05"/>
        </geometry>
        <material name="grey"/>
      </visual>
    </link>
  </xacro:macro>
</robot>

(3) pantalla_mbot_xacro.lanzamiento

<launch>
	// 引入xacro的解释器,不然无法读取 .xacro文件
	<arg name="model" default="$(find xacro)/xacro '$(find mbot_description)/urdf/mbot_base.xacro'" />

	<param name="robot_description" command="$(arg model)" />

	<!-- 设置GUI参数,显示关节控制插件 -->
	<param name="use_gui" value="true"/>

	<!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
	<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />

	<!-- 运行robot_state_publisher节点,发布tf  -->
	<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />

	<!-- 运行rviz可视化界面 -->
	<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mbot_description)/config/mbot_xacro.rviz" required="true" />

</launch>

(4) El efecto de ejecución es el siguiente, donde se muestran los ejes del sistema de coordenadas
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

3 Resumen

El código de este artículo está alojado en mi github: mbot_description

Supongo que te gusta

Origin blog.csdn.net/cy1641395022/article/details/131830631
Recomendado
Clasificación