1. 关于URDF的一些杂谈
URDF(Unified Robot Description Format), 是一种特殊的xml文件格式, 作为机器人的一种描述文件, 在ROS里面大量使用. 接触ROS比较久的同学, 应该会经常见到一种类似命名的包(package) – xxx_description. 这个包里面就是包含某个机器人的描述文件. 比如pr2_decription, baxter_descrition, 以及ur_description等. 上述举例的机器人描述包都是可以通过apt-get
的方式进行安装. 使用命令格式如斯: sudo apt-get install ros-indigo-pr2-descrition
, 其中indigo
是你所安装的ROS版本名, 后面就是所需要安装的包名, 下划线用中画线代替.
对机器人使用gazebo进行仿真时, 需要加载的机器人模型就是urdf模型, 当然, 单纯的urdf是不能精确描述机器人以及所需要仿真的世界的. gazebo对其进行了扩展, 感兴趣的朋友可以查看gazebo官网的一些教程. 其中会提供一些标签, 对系统动态, 重心等的设定.
如果想使用开源库moveit对机器人进行路径规划, 在moveit setup assistant教程中, 第一步就是关于如何将机器人模型导入进来, 导入的机器人模型就是urdf(导入xacro格式时也是先将其解析为urdf).
诸如这些应用, 当然还不限于这些应用, 可以看到, 了解URDF以及会使用URDF是一件很重要的事情. 而xacro文件, 是提供了一些更为高级编辑方式的宏文件. 这种格式的文件, 在使用时, 均先会调用rosrun xacro xacro.py xxx.urdf.xacro > xxx.urdf
, 将其解析成对应的urdf文件. 然后再使用.
下述内容, 仅仅是对urdf文件编辑和查看由最基础的了解, 以方便能够看得懂机器人描述文件, 以及该怎么利用别人已经写好的描述文件进行组合, 重构得到自己的机器人描述文件. 如果是需要更详细, 精确的描述, 则还需要自己再去对urdf文件进行学习.
2. URDF文件
2.1 link 和 joint
在URDF教程中, 第一个出现的就是下图, 很形象的将URDF要定义的主要内容给展现了出来. 一般, 机器人都是由link和joint进行描述. 都会呈现为树状(想象数据结构里面的树), 如图1, 由一个根link(link1)向上, 分别出现了两个分支–link2和link3, 分别由joint连接link. link4就可以类似的理解.
了解机器人的一般描述方式之后, 我们来看一下下图中这个形状的机器人该怎么来描述它.
<robot name="test_robot">
<link name="link1" />
<link name="link2" />
<link name="link3" />
<link name="link4" />
<joint name="joint1" type="continuous">
<parent link="link1"/>
<child link="link2"/>
</joint>
<joint name="joint2" type="continuous">
<parent link="link1"/>
<child link="link3"/>
</joint>
<joint name="joint3" type="continuous">
<parent link="link3"/>
<child link="link4"/>
</joint>
</robot>
从上述内容可以看到, 机器人最重要的两个内容 – link和joint, 是如何进行定义. 文件都定义了哪些标签, 以及该怎么使用. 其中内容很简单, 我就不浪费篇幅了.
细心的朋友肯定能够感受到, 虽然能够想象的出来大概是一个什么样子, 但是上面的内容是不能够唯一确定一个机器人或者一个…东西…, 因为每个link长什么样子?他们又是一个什么样子的位置关系? 这些在上面的内容中都是没有定义的. 如图中所示, 可能现在每一个不同的同学, 所联想到的样子都是不一样的, 一个仙人掌? 一个两指的夹持器? anythin..当然, 上面所示内容的urdf文件是不能够被正确解析的, 也是不能够可视化出来的. 但上面内容就类似于整个机器人的骨架, 机器人就由这些东西组成. 一共拥有4个link, 和3个joint, 像图中所示的样子连接起来.
2.2 位置
在定义好了机器人的骨架后, 进一步我们可以使用origin
子标签进行定义link所应该在的位置. 但是有一点应该注意到, link和link之间是使用joint进行连接, 那么link的位置, 就由连接他的joint确定. 所以, 该子标签是定义在joint内. 在三维空间中, 要精确描述一个刚性体的姿态, 仅仅使用他的xyz坐标是不够的, 还需要使用rpy. rpy角是描述船舶在海中航行时姿态的一种方法. 将船的行驶方向取为z轴, 绕z轴旋转称为滚动(Roll), 绕y轴旋转称为俯仰(Pitch), 绕x轴旋转称为偏转(Yaw). 这种描述方式大量运用于各个领域. 依稀记得, kinect2关于脸部模型匹配的DEMO程序里面, 对脸部的描述就用到了这种描述方式来描述姿态. 在机器人中, 当然运用就更多了. 现在对之前的内容进行扩充. 其中rpy代表的是角度, 用弧度表示.
<robot name="test_robot">
<link name="link1" />
<link name="link2" />
<link name="link3" />
<link name="link4" />
<joint name="joint1" type="continuous">
<parent link="link1"/>
<child link="link2"/>
<origin xyz=".5 .3 0.7" rpy="0 0 0" />
</joint>
<joint name="joint2" type="continuous">
<parent link="link1"/>
<child link="link3"/>
<origin xyz="-.2 .5 -0.3" rpy="0 0 1.57" />
</joint>
<joint name="joint3" type="continuous">
<parent link="link3"/>
<child link="link4"/>
<origin xyz=".5 0 0.2" rpy="0 0 -1.57" />
</