• ROS学习之URDF


    URDF

    为了制作我们的模拟器,首先我们得了解下什么是URDF

    什么是URDF? Unified Robot Description Format——统一机器人描述格式。总觉得这和Sensor支持才是ROS的精华所在,通信frameworks的并不见得出彩。

    可能大部分读者都像我这样穷<bi~背景声>没钱买ROS支持的机器人,不过ROS还是很Nice的考虑到了这一群体,提供了模拟器支持。(明明是为了更快速的软件开发,喂!)

    本想从ROS网站的培训教程开始http://wiki.ros.org/urdf/Tutorials开始的,不过本着实践为本的目的,我们还是以《Learning ROS for Robostic Programming》为基础吧。

     

    参考文献

    1. ROS urdf教程:http://wiki.ros.org/urdf/Tutorials

    2. 《Learning ROS for Robostic Programming》

    准备工作

    安装urdf_tutorial包

    1. sudo apt-get install ros-hydro-urdf-tutorial  

    执行

    1. rosrun rviz rviz  

    当然,没有运行roscore你的rviz也无法启动。不过如果错误显示你的rviz找不到执行文件的话,请参照http://wiki.ros.org/rviz

    URDF基本语法

    统一机器人描述格式URDF,其实就是为了能够抽象描述一个机器人的硬件。而且URDF是基于XML的,所以阅读起来应该非常容易。

    笔者以为要理解URDF用自顶向下的方式更快。即从为了解决一个怎样的问题开始。在这里我们先用一个简单场景熟悉一下会用到的工具。

    不得不说小车是最简单实用的机器人, 一个车身加四个轮子就组成了最基本的小车结构,而且具备一定载重能力的小车也不会太贵。

    见如下图片。

    (图一)

    第一版

    在URDF语言中,机器人都会由各个部件(Link)通过关节(Joint)连接而成。而这里的关键就是描述部件和关节之间的关系。

    在这个简单的小车模型中,一共有5个部件: 车身 + 4个轮子。 4个关节: 每个轮子一个。

    于是,我们得到了最初了URDF版本 01_car_skeleton.urdf

    1. <robot name="test_robot">  
    2.   <link name="base_link" />  
    3.   <link name="wheel_1" />  
    4.   <link name="wheel_2" />  
    5.   <link name="wheel_3" />  
    6.   <link name="wheel_4" />  
    7.   
    8.   
    9.   <joint name="joint_base_wheel1" type="fixed">  
    10.     <parent link="base_link"/>  
    11.     <child link="wheel_1"/>  
    12.   </joint>  
    13.   
    14.   
    15.   <joint name="joint_base_wheel2" type="fixed">  
    16.     <parent link="base_link"/>  
    17.     <child link="wheel_2"/>  
    18.   </joint>  
    19.   
    20.   
    21.   <joint name="joint_base_wheel3" type="fixed">  
    22.     <parent link="base_link"/>  
    23.     <child link="wheel_3"/>  
    24.   </joint>  
    25.   
    26.   
    27.   <joint name="joint_base_wheel4" type="fixed">  
    28.     <parent link="base_link"/>  
    29.     <child link="wheel_4"/>  
    30.   </joint>  
    31. </robot>  

    很简单对吧?

    用<link> tag描述各个部件,<joint> tag描述各个关节。用<parent>和<child>描述关节连接的部件。

    只要描述了Link和Joint之间的关系,我们很容易就能构建机器人的框架。

    我们可以用如下命令来检查urdf文件是否有语法问题。

    1. check_urdf 01_skeleton.urdf  

    只要得到如下结果就表明语法没问题。

    1. robot name is: test_robot  
    2. ---------- Successfully Parsed XML ---------------  
    3. root Link: base_link has 4 child(ren)  
    4.     child(1):  wheel_1  
    5.     child(2):  wheel_2  
    6.     child(3):  wheel_3  
    7.     child(4):  wheel_4  

    但请注意这虽然描述了各个部件之间的关系,但仍是一个不完整的URDF,无法在模拟器中显示。

    第二版

    <visual>tag用来描述模块的视觉效果。

    <geometry>tag 用来描述模块的形状和大小。

    <origin>tag用来描述模块的位置。

    加上模块大小之后的小车文件如下所示。02_visual.urdf

    1. <robot name="test_robot">  
    2.   <link name="base_link">  
    3.     <visual>  
    4.        <geometry>  
    5.          <box size="0.2 .3 .1"/>  
    6.        </geometry>  
    7.        <origin rpy="0 0 0" xyz="0 0 0.05"/>  
    8.     </visual>  
    9.   </link>  
    10.   
    11.   <link name="wheel_1">  
    12.     <visual>  
    13.       <geometry>  
    14.         <cylinder length="0.05" radius="0.05"/>  
    15.       </geometry>  
    16.       <origin rpy="0 1.5 0" xyz="0.1 0.1 0"/>  
    17.     </visual>  
    18.   </link>  
    19.   
    20.   <link name="wheel_2">  
    21.     <visual>  
    22.       <geometry>  
    23.         <cylinder length="0.05" radius="0.05"/>  
    24.       </geometry>  
    25.       <origin rpy="0 1.5 0" xyz="-0.1 0.1 0"/>  
    26.     </visual>  
    27.   </link>  
    28.   
    29.   <link name="wheel_3">  
    30.     <visual>  
    31.       <geometry>  
    32.         <cylinder length="0.05" radius="0.05"/>  
    33.       </geometry>  
    34.       <origin rpy="0 1.5 0" xyz="0.1 -0.1 0"/>  
    35.     </visual>  
    36.   </link>  
    37.   
    38.   <link name="wheel_4">  
    39.     <visual>  
    40.       <geometry>  
    41.         <cylinder length="0.05" radius="0.05"/>  
    42.       </geometry>  
    43.       <origin rpy="0 1.5 0" xyz="-0.1 -0.1 0"/>  
    44.     </visual>  
    45.   </link>  
    46.   
    47.   <joint name="joint_base_wheel1" type="fixed">  
    48.     <parent link="base_link"/>  
    49.     <child link="wheel_1"/>  
    50.   </joint>  
    51.   
    52.   <joint name="joint_base_wheel2" type="fixed">  
    53.     <parent link="base_link"/>  
    54.     <child link="wheel_2"/>  
    55.   </joint>  
    56.   
    57.   <joint name="joint_base_wheel3" type="fixed">  
    58.     <parent link="base_link"/>  
    59.     <child link="wheel_3"/>  
    60.   </joint>  
    61.   
    62.   <joint name="joint_base_wheel4" type="fixed">  
    63.     <parent link="base_link"/>  
    64.     <child link="wheel_4"/>  
    65.   </joint>  
    66. </robot>  


    现在通过如下命令,你就通过rviz查看你的小车模型啦。

    1. roslaunch urdf_tutorial display.launch model:=02_visual.urdf  

    第三步: 上色

    Mmm,我们的小车就快完成了,但全是红色总觉得怪怪的而且很难辨认。

    不过上色同样很简单。使用<material> tag并且设置<color> tag

    我们得到第三个版本:03_color.urdf

    1. <robot name="test_robot">  
    2.   <link name="base_link">  
    3.     <visual>  
    4.        <geometry>  
    5.          <box size="0.2 .3 .1"/>  
    6.        </geometry>  
    7.        <origin rpy="0 0 0" xyz="0 0 0.05"/>  
    8.        <material name="white">  
    9.          <color rgba="1 1 1 1"/>  
    10.        </material>  
    11.     </visual>  
    12.   </link>  
    13.   
    14.   <link name="wheel_1">  
    15.     <visual>  
    16.       <geometry>  
    17.         <cylinder length="0.05" radius="0.05"/>  
    18.       </geometry>  
    19.       <origin rpy="0 1.5 0" xyz="0.1 0.1 0"/>  
    20.       <material name="black">  
    21.         <color rgba="0 0 0 1"/>  
    22.       </material>  
    23.     </visual>  
    24.   </link>  
    25.   
    26.   <link name="wheel_2">  
    27.     <visual>  
    28.       <geometry>  
    29.         <cylinder length="0.05" radius="0.05"/>  
    30.       </geometry>  
    31.       <origin rpy="0 1.5 0" xyz="-0.1 0.1 0"/>  
    32.       <material name="black"/>  
    33.     </visual>  
    34.   </link>  
    35.   
    36.   <link name="wheel_3">  
    37.     <visual>  
    38.       <geometry>  
    39.         <cylinder length="0.05" radius="0.05"/>  
    40.       </geometry>  
    41.       <origin rpy="0 1.5 0" xyz="0.1 -0.1 0"/>  
    42.       <material name="black"/>  
    43.     </visual>  
    44.   </link>  
    45.   
    46.   <link name="wheel_4">  
    47.     <visual>  
    48.       <geometry>  
    49.         <cylinder length="0.05" radius="0.05"/>  
    50.       </geometry>  
    51.       <origin rpy="0 1.5 0" xyz="-0.1 -0.1 0"/>  
    52.       <material name="black"/>  
    53.     </visual>  
    54.   </link>  
    55.   
    56.   <joint name="joint_base_wheel1" type="fixed">  
    57.     <parent link="base_link"/>  
    58.     <child link="wheel_1"/>  
    59.   </joint>  
    60.   
    61.   <joint name="joint_base_wheel2" type="fixed">  
    62.     <parent link="base_link"/>  
    63.     <child link="wheel_2"/>  
    64.   </joint>  
    65.   
    66.   <joint name="joint_base_wheel3" type="fixed">  
    67.     <parent link="base_link"/>  
    68.     <child link="wheel_3"/>  
    69.   </joint>  
    70.   
    71.   <joint name="joint_base_wheel4" type="fixed">  
    72.     <parent link="base_link"/>  
    73.     <child link="wheel_4"/>  
    74.   </joint>  
    75. </robot>  



    我们可以看到rviz的结果,如图一所示。

    这下我们差不多完成了。我们马上就可以移动我们的小车啦。

    但是等等,在我们的URDF文件中,内嵌了关于各个部件的大小参数以及位置。这些当然是我们根据草图用计算器算出来的。

    但是这样的扩展性也太差了吧?难道对每个模型我们都得这么计算吗?对于相同模型的不同尺寸我们还得重新计算一次?

     

    第四步: Xacro

    什么是Xacro? 我们可以把它理解成为针对URDF的扩展性和配置性而设计的宏语言(macro language)。

    有了Xacro,我们就可以像编程一样来写URDF文件了。

    首先我们来看Xacro文件的变量定义:

    1. <xacro:property name="body_width" value=".2" />  

    只要定义了body_width,我们就可以通过${body_width}来引用其值了。有了这个,至少我们可以把需要配置的变量进行统一管理。

    其次,我们来看一下Xacro如何进行宏定义。

    这里的宏和C语言的宏很像,在转换成URDF文件时编译器会将其展开。其基本语法为:

    1. <xacro:macro name="wheel" params="param1 param2">  
    2. </xacro:macro>  


    我们来看下URDF文件中关于车身和车轮的大小描述。

    <box size="0.2 .3 .1"/>

    <origin rpy="0 0 0" xyz="0 0 0.05"/>

    <cylinder length="0.05" radius="0.05"/>

    <origin rpy="0 1.5 0" xyz="-0.1 0.1 0"/>

    这里涉及到的参数有:

    车身的大小(body_size),车身中心的位置(body_pos)。

    车轮半径(wheel_radius)和轮胎宽度(wheel_width),车轮圆心的位置(wheel1_pos, wheel2_pos, wheel3_pos, wheel4_pos)。

    相应的在Xacro中定义参数的语法为:

    1.   <xacro:property name="body_size" value=".2 .3 .1" />  
    2.   <xacro:property name="body_pos" value="0 0 0.05" />  
    3.   <xacro:property name="wheel_radius" value="0.05" />  
    4.   <xacro:property name="wheel_length" value="0.05" />  
    5.   <xacro:property name="wheel1_pos" value="0.1 0.1 0" />  
    6.   <xacro:property name="wheel2_pos" value="-0.1 0.1 0" />  
    7.   <xacro:property name="wheel3_pos" value="0.1 -0.1 0" />  
    8.   <xacro:property name="wheel4_pos" value="-0.1 -0.1 0" />  

    并且每个轮子和连接的代码也基本相同。

    基于上述亮点,我们可以得到以下xacro文件。04_xacro.xacro

    1. <?xml version="1.0"?>  
    2. <robot xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"  
    3.          xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"  
    4.          xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"  
    5.          xmlns:xacro="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface" name="test_robot">  
    6.   
    7.   <xacro:property name="body_size" value=".2 .3 .1" />  
    8.   <xacro:property name="body_pos" value="0 0 0.05" />  
    9.   <xacro:property name="wheel_radius" value="0.05" />  
    10.   <xacro:property name="wheel_length" value="0.05" />  
    11.   <xacro:property name="wheel1_pos" value="0.1 0.1 0" />  
    12.   <xacro:property name="wheel2_pos" value="-0.1 0.1 0" />  
    13.   <xacro:property name="wheel3_pos" value="0.1 -0.1 0" />  
    14.   <xacro:property name="wheel4_pos" value="-0.1 -0.1 0" />  
    15.   
    16.   <xacro:macro name="wheel" params="wheelname position">  
    17.     <link name="${wheelname}">  
    18.       <visual>  
    19.         <geometry>  
    20.           <cylinder length="${wheel_length}" radius="${wheel_radius}"/>  
    21.         </geometry>  
    22.         <origin rpy="0 1.5 0" xyz="${position}"/>  
    23.         <material name="black">  
    24.           <color rgba="0 0 0 1"/>  
    25.         </material>  
    26.       </visual>  
    27.     </link>  
    28.   
    29.     <joint name="joint_base_${wheelname}" type="fixed">  
    30.       <parent link="base_link"/>  
    31.       <child link="${wheelname}"/>  
    32.     </joint>  
    33.   </xacro:macro>  
    34.   <xacro:wheel wheelname="wheel1" position="${wheel1_pos}"/>  
    35.   <xacro:wheel wheelname="wheel2" position="${wheel2_pos}"/>  
    36.   <xacro:wheel wheelname="wheel3" position="${wheel3_pos}"/>  
    37.   <xacro:wheel wheelname="wheel4" position="${wheel4_pos}"/>  
    38.   
    39.   <link name="base_link">  
    40.     <visual>  
    41.        <geometry>  
    42.          <box size="${body_size}"/>  
    43.        </geometry>  
    44.        <origin rpy="0 0 0" xyz="${body_pos}"/>  
    45.        <material name="white">  
    46.          <color rgba="1 1 1 1"/>  
    47.        </material>  
    48.     </visual>  
    49.   </link>  
    50. </robot>  


    验证该文件的正确性可以有两种方法。

    1. 转换成URDF文件,使用check_urdf

    1. rosrun xacro xacro.py 04_xacro.xacro > 04_xacro.urdf  


    2. 使用xacrodisplay.launch

    1. roslaunch urdf_tutorial xacrodisplay.launch model:=04_xacro.xacro  


    我们都会得到和图1一样的小车模型。这下我们就可以用Xacro来构建机器人模型了。

  • 相关阅读:
    学习使用linux下tags文件
    uboot常用命令详解
    U-boot中TFTP 解释
    eth0: ERROR while getting interface flags: No such device 没有eth0 有其他的eth
    取消挂载 umount 时出现的 “Device is busy”
    Linux的log日志功能
    oracle的安装
    SOA架构设计分析
    立方体模型
    质量属性的六个常见属性场景(淘宝网)
  • 原文地址:https://www.cnblogs.com/flyingjun/p/8926824.html
Copyright © 2020-2023  润新知