首页 关于
树枝想去撕裂天空 / 却只戳了几个微小的窟窿 / 它透出天外的光亮 / 人们把它叫做月亮和星星
目录

URDF和机器人模型(一)

在本文中,我们将创建一个看起来像是R2D2的可视化机器人模型。在后续的文章中,我们将介绍如何描述模型,添加一些物理特性,通过xacro产生整洁的代码,在Gazebo中操纵它。 但在本文中,我们只关注正确创建可视化的模型。

在继续我们的教程之前,需要保证已经安装了'joint_state_publisher'包。如果我们使用apt-get来安装完整版的ROS系统或者urdf_tutorial, 那么就应该已经安装了。我们可以用rosdep工具来检查相关的依赖是否都已经安装了。

本文中提到的所有的机器人模型都可以在'urdf_tutorial'包中找到。

1. 一个形状

首先,我们研究一个简单的形状。下面是一个描述这一形状的urdf文件内容,它是一个XML文档:

        <?xml version="1.0"?>
        <robot name="myfirst">
          <link name="base_link">
            <visual>
              <geometry>
                <cylinder length="0.6" radius="0.2"/>
              </geometry>
            </visual>
          </link>
        </robot>
这个XML文档描述了一个叫做"myfirst"的机器人,它只有一个link(或者说是部分),它的visual部分只是描述了一个长0.6米,直径为0.2米的圆柱。 这可以说是一个简单的"hello world"程序,但它还是有点复杂的。

我们可以进入到urdf_tutorial包中,以用display.launch来查看一下这个模型:

        $ roscd urdf_tutorial
        $ roslaunch urdf_tutorial display.launch model:=urdf/01-myfirst.urdf
这个display.launch文件就在urdf_tutorial下的launch子目录中,其内容如下:
        <launch>
            <arg name="model" />
            <arg name="gui" default="False" />
            <param name="robot_description" textfile="$(arg model)" />
            <param name="use_gui" value="$(arg gui)"/>
            <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
            <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
            <node name="rviz" pkg="rviz" type="rviz" args="-d $(find urdf_tutorial)/urdf.rviz" required="true" />
        </launch>
它主要做了三件事: 这将打开一个RVIZ的窗口软件,其中显示了一个红色的圆柱体。
在图中我们主要关注两个对象:Grid和RobotModel。Grid是一个用来描述世界坐标系的网格,它就位于世界坐标系的原点处,其offset为(0;0;0)。 在RobotModel中有一个Link,也是位于世界坐标系的原点处,其Position为(0;0;0)。实际上我们在URDF文档中没有指定圆柱体的位置,所以rviz就默认将其渲染到了坐标系的原点上。

2. 多个形状

现在我们创建两个几何体,这两个几何体之间存在一定的位置关系,所以我们除了在URDF文件中添加一个Link来描述第二个几何体之外,还需要添加一个Joint来描述两个几何体之间的连接关系。 下面是新的URDF文档内容:

        <?xml version="1.0"?>
        <robot name="myfirst">
          <link name="base_link">
            <visual>
              <geometry>
                <cylinder length="0.6" radius="0.2"/>
              </geometry>
            </visual>
          </link>

          <link name="right_leg">
            <visual>
              <geometry>
                <box size="0.6 0.1 0.2"/>
              </geometry>
            </visual>
          </link>
  
          <joint name="base_to_right_leg" type="fixed">
            <parent link="base_link"/>
            <child link="right_leg"/>
          </joint>
        </robot>
在这个URDF文档中,我们新增加了一个长宽高分别为0.6, 0.1和0.2米的立方体。通过一个固定(fixed)的Joint把两个Link连接在一起。Joint有几种不同的形式,fixed是其中不能转动或者移动的一种。 Joint连接两个Link,他们之间是一种树型的结构,具有父子关系。这里的例子是说连杆right_leg通过关节base_to_right_leg固连到基座base_link上。这种父子关系还说明子Link的位置和姿态是基于父Link的。 运行如下的指令,我们可以在打开的RVIZ中看到这两个几何体。
        $ roscd urdf_tutorial
        $ roslaunch urdf_tutorial display.launch model:=urdf/02-multipleshapes.urdf 
在左侧的robot_model下,我们可以看到有两个Link分别叫做"base_link"和"right_leg"。但是在显示的图像中,他们是重叠在一起的,这是因为我们只是定义了两个几何体的形状和大小, Joint的添加也只是说明了两者具有连接关系,我们都还没有描述他们在空间中的位置和关系。

下面我们在"base_to_right_leg"的描述项中添加一个origin的标签。这个origin标签有两个属性xyz和rpy,它们分别描述了子Link坐标系相对于父Link坐标系的位置和姿态关系。 xyz就是我们熟悉的笛卡尔坐标系下空间点的坐标描述,而rpy则是三个欧拉角——滚转角(roll)、俯仰角(pitch)和偏航角(yaw)。 它们表示从父Link的坐标系先后绕z,y,x轴转动yaw,pitch,roll角度就可以得到一个与子Link坐标系平行的坐标系。

        <joint name="base_to_right_leg" type="fixed">
            <parent link="base_link"/>
            <child link="right_leg"/>
            <origin xyz="0 -1.22 0.25" rpy="0 0 0"/>
        </joint>
这里xyz="0 -1.22 0.25"表示子Link相对于父Link左移了1.22米,上移了0.25米;rpy="0 0 0"则说明两者之间没有相对转动。通过urdf_tutorial中的display.launch我们可以查看两个Link在空间中位置发生了变化, 如下图所示(为了方便显示我们修改了"right_leg"的尺寸为长宽高分别是0.3,0.1和0.2米)。图中的长方体在圆柱体的左上方,其中有红、绿、蓝三种颜色的线段,它们实际上是长方体的坐标系,红色对应x坐标轴, 绿色和蓝色则分别对应y轴和z轴。
xyz="0 -1.22 0.25" rpy="0 0 0" xyz="0 -1.22 0.25" rpy="0 0 -1.57075"

我们还可以为每个Link添加坐标描述,比如下面关于right_leg的描述,我们在visual标签下添加一个子标签origin,它描述了视图对象相对于几何体原点之间的相对位置和姿态关系。

        <link name="right_leg">
            <visual>
              <geometry><box size="0.3 0.1 0.2"/></geometry>
              <origin xyz="-0.15 0 0" rpy="0 0 0"/>
            </visual>
          </link>

下面是不同xyz和rpy下的视图效果

xyz="-0.15 0 0" rpy="0 0 0" xyz="-0.15 0 0" rpy="0 1.57075 0"

3. 材料描述

在前面的例子中,所有的物体都被渲染成了红色,这是因为我们没有说明物体的颜色。下面我们通过material标签来为每个几何体添加颜色说明。

        <?xml version="1.0"?>
        <robot name="origins">
          <material name="blue"><color rgba="0 0 0.8 1"/></material>
          <material name="white"><color rgba="1 1 1 1"/></material>
        
          <link name="base_link">
            <visual>
              <geometry><cylinder length="0.6" radius="0.2"/></geometry>
              <material name="blue"/>
            </visual>
          </link>
        
          <link name="right_leg">
            <visual>
              <geometry>
                <box size="0.3 0.1 0.2"/>
                <origin xyz="-0.15 0 0" rpy="0 0 0"/>
              </geometry>
              <material name="white"/>
            </visual>
          </link>
        
          <joint name="base_to_right_leg" type="fixed">
            <parent link="base_link"/>
            <child link="right_leg"/>
            <origin xyz="0 -1.22 0.25" rpy="0 0 0"/>
          </joint>
        </robot>

在这个URDF文档中,我们先定义了两个material,其中只描述了材料的颜色,有需要的话我们还可以定义一些其它关于材料的属性。在连杆中我们也添加了两个material标签, base_link采用blue的材料,而right_leg则采用white的材料。我们可以看到URDF中显示的3D图形:

4. R2D2

URDF不仅可以定义和描述简单的几何体,它还可以通过一些mesh文件来描述复杂的形状。比如我们查看urdf_tutorial下的05-visual.urdf模型,既可以看到一个完整的R2D2机器人, 它的手抓部分就是用mesh文件描述的复杂结构。

        $ roscd urdf_tutorial
        $ roslaunch urdf_tutorial display.launch model:=urdf/05-visual.urdf
我们需要在mesh标签中给出mesh文件的路径,比如说这里我们借用了PR2机器人的手抓。
        <link name="left_gripper">
            <visual>
                <origin rpy="0 0 0" xyz="0 0 0"/>
                <geometry><mesh filename="package://pr2_description/meshes/l_finger.dae"/></geometry>
            </visual>
        </link>
mesh文件可以有几种不同的格式。STL是一种比较常用的格式,RVIZ的渲染引擎也支持DAE格式。DAE是一种可以描述颜色的格式,这样我们就不用在针对它声明一些关于颜色的材料特性了。

5. 总结

至此,我们就已经了解了URDF的基本功能,使用RVIZ工具简单的查看了机器人模型。

URDF文件本质上就只是一个简单的xml文档,它用link表示机器人中的各个部分,用joint表示各个部分之间的连接关系。joint连接的两个link具有父子关系,整个机器人可以用一棵树来描述。 各个link之间存在一些相对的位置和姿态关系,可以通过在link或者joint中加入origin标签来描述。

在本文中,我们只关注了如何描述机器人的视图模型,也就是URDF中的visual标签。介绍了可以通过定义material来描述机器人的颜色,使用mesh文件来表述复杂的几何图形。 在后续的文章中我们还将讨论机器人的碰撞模型、物理属性等等。




Copyright @ 高乙超. All Rights Reserved. 京ICP备16033081号-1