# 8.5 統一機器人描述格式URDF
## 8.5.1 URDF基礎
$$\qquad$$URDF(Unified Robot Description Format)統一機器人描述格式,URDF使用XML格式描述機器人文件。URDF語法規范,參考鏈接:[http://wiki.ros.org/urdf/XML](http://wiki.ros.org/urdf/XML),URDF組件,是由不同的功能包和組件組成:

$$\qquad$$其中urdf\_parser和urder\_interface已經在hydro之后的版本中去除了。urdf\_paser\_plugin是URDF基礎的插件,衍生出了urdfdom(面向URDF文件)和collar\_parser(面向相互文件)。在URDF當中,當你想要描述一個機器人的時候,例如小車的base\_link和右輪right,兩個link之間需要joint來連接。參考下圖:
$$\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad$$
## 8.5.2 制作URDF模型
$$\quad$$**(1)添加基本模型**
$$\quad$$我們以構建一個小車為例子,為大家講解這部分的內容:(相關的示例代碼可以從我們的tf\_demo中找到),我們的想法是,首先構建base\_link作為小車的父坐標系,然后在base\_link基礎上,再構建左輪,右輪 和雷達 link. 最后不同的link之間通過joint來連接。參考代碼如下:
$$\quad \quad \quad \quad\quad \quad \quad \quad \quad \quad \quad$$
$$\quad$$小技巧: sudo apt-get install liburdfdom-tools,安裝完畢后,執行檢查check\_urdf my\_car.urdf如果一切正常,就會有如下顯示: ** **
$$\quad \quad \quad \quad\quad \quad \quad \quad \quad \quad \quad$$
$$\quad \quad$$隨后打開新的終端,輸入roslaunch urdf\_demo display\_urdf\_link\_joint.launch,回車之后,發現所有的link和joint都在一起了,詳見urdf本章的demo。
$$\quad \quad \quad \quad\quad \quad \quad \quad \quad \quad \quad\quad \quad \quad \quad \quad$$
$$\quad$$(2)**添加機器人link之間的相對位置關系**
$$\quad$$在基礎模型之上,我們需要為機器人之間link來設相對位置和朝向的關系,URDF中通過<origin>來描述這種關系。
$$\quad \quad \quad \quad\quad \quad \quad \quad \quad \quad \quad$$
$$\quad \quad$$隨后打開新的終端,輸入roslaunch urdf\_demo display\_urdf\_link\_position.launch,回車之后,發現所有的link和joint已經有在固定的位置上了,詳見urdf本章的demo。
$$\quad \quad \quad \quad\quad \quad \quad \quad \quad \quad \quad$$
$$\quad$$**(3)添加模型的尺寸,形狀和顏色等**
$$\quad$$在已經設置好模型的link基礎上,添加模型的形狀(例如圓柱或長方體),相對于link的位置,顏色等。其中形狀用<geometry>來描述,顏色用<color>來描述。
$$\quad \quad \quad \quad\quad \quad \quad \quad \quad $$
$$\quad$$(4)**顯示URDF模型**
$$\quad$$想要在rviz中顯示出我們制作好的小車的URDF模型,可以寫一個launch文件,參考如下:
$$\quad \quad \quad \quad$$
$$\quad$$除了launch文件中的前3句,導入我們制作小車的URDF模型外,還需要添加joint\_state\_publisher和robot\_state\_publisjer這兩個節點。效果如下:
$$\quad \quad \quad \quad\quad \quad \quad \quad \quad$$
$$\quad$$另外,我們可以輸入rosrun rqt\_tf\_tree rqt\_tf\_tree,可以看到以下tf 樹:

$$\quad$$**小技巧:**你可以將launch文件中的param name="use\_gui"的值由false改成true會彈出一個窗口,同一移動進度條,可以臨時改變joint的朝向。
$$\quad \quad \quad \quad\quad \quad \quad \quad \quad \quad \quad \quad \quad \quad\quad \quad \quad \quad \quad \quad \quad$$
## 8.5.3 制作xacro模型
$$\quad$$什么是Xacro? 我們可以把它理解成為針對URDF的擴展性和配置性而設計的宏語言\(macro language\)。有了Xacro,我們就可以像編程一樣來寫URDF文件。XACRO格式提供了一些更高級的方式來組織編輯機器人描述. 主要提供了三種方式來使得整個描述文件變得簡單。
$$\quad$$**(1)Constants**
```
Usage:<xacro:property name="WIDTH" value="2.0"/>
```
$$\quad$$類似于C語言中的宏定義, 在頭部定義后就可以${body\_width}進行引用其數值,有了這個,至少我們可以把需要配置的變量進行統一管理和使用。
$$\quad$$**(2)Macros**
```
Usage:<xacro:macro name="default_origin">
<origin xyz="0 0 0" rpy="0 0 0"/>
</xacro:macro>
<xacro:default_origin />
```
$$\quad$$Macros是xacro文件中最重要的部分. 就像宏函數一樣, 完成一些最小模塊的定義, 方便重用, 以及可以使用參數來標識不同的部分.
$$\quad$$**(3)Include**
$$\quad$$很多模型都是已宏的形式進行定義, 并以最小集團分成很多個文件. 而最終的機器人描述就變得非常簡單了. 下面摘錄一個ur5的描述文件. 從中可以看出來xacro的強大優勢. 在最后的示例中我們還能夠看到, urdf文件也是能夠直接導入進來的.
```
Usage:<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="ur5" >
<!-- common stuff -->
<xacro:include filename="$(find ur_description)/urdf/ur5/common.gazebo.xacro" />
<!-- ur5 -->
<xacro:include filename="$(find ur_description)/urdf/ur5/ur5.urdf.xacro" />
<!-- arm -->
<xacro:ur5_robot prefix="" joint_limited="false"/>
<link name="world" />
<joint name="world_joint" type="fixed">
<parent link="world" />
<child link = "base_link" />
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
</joint>
</robot>
```
$$\quad$$include類似于C語言中的include, 先將該文件擴展到包含的位置. 但包含進來的文件很有可能只是一個參數宏的定義. 并沒有被調用.$$\quad$$
$$\quad$$舉例說明打開新的終端,輸入roslaunch urdf\_demo display\_xacro.launch,回車之后,發現所有的link和joint已經有在固定的位置上了,并且小車顏色和形狀已經固定完成,詳見urdf本章的demo。
$$\quad \quad \quad \quad \quad \quad \quad \quad \quad \quad$$
## 8.5.4 制作gazebo模型
$$\quad$$在已經制作好的xcaro模型的基礎上,添加gazebo模型的組建,看起已經變得十分的具有可操作性。對于二輪差動模型通過添加libgazebo\_ros\_diff\_drive.so插件對小車左右輪的控制。
```
<gazebo>
<plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
<robotNamespace>/</robotNamespace>
<alwaysOn>true</alwaysOn>
<legacyMode>false</legacyMode>
<updateRate>50</updateRate>
<leftJoint>mybot_left_wheel_hinge</leftJoint>
<rightJoint>mybot_right_wheel_hinge</rightJoint>
<wheelSeparation>${chassisWidth+wheelWidth}</wheelSeparation>
<wheelDiameter>${2*wheelRadius}</wheelDiameter>
<torque>20</torque>
<commandTopic>mybot_cmd_vel</commandTopic>
<odometryTopic>mybot_odom</odometryTopic>
<odometryFrame>odom</odometryFrame>
<robotBaseFrame>mybot_link</robotBaseFrame>
</plugin>
</gazebo>
```
$$\quad$$通過添加libgazebo\_ros\_p3d.so來計算里程。
```
<gazebo>
<plugin name="ground_truth" filename="libgazebo_ros_p3d.so">
<frameName>map</frameName>
<bodyName>mybot_chassis</bodyName>
<topicName>odom</topicName>
<updateRate>30.0</updateRate>
</plugin>
</gazebo>
```
$$\quad$$最后,對gazebo模型中小車左右輪相關PID等參數進行設置
```
<gazebo reference="mybot_chassis">
<material>Gazebo/Orange</material>
</gazebo>
<gazebo reference="caster_wheel">
<mu1>0.0</mu1>
<mu2>0.0</mu2>
<material>Gazebo/Red</material>
</gazebo>
<gazebo reference="right_wheel">
<mu1 value="1.0"/>
<mu2 value="1.0"/>
<kp value="10000000.0" />
<kd value="1.0" />
<fdir1 value="1 0 0"/>
<material>Gazebo/Black</material>
</gazebo>
<gazebo reference="left_wheel">
<mu1 value="1.0"/>
<mu2 value="1.0"/>
<kp value="10000000.0" />
<kd value="1.0" />
<fdir1 value="1 0 0"/>
<material>Gazebo/Black</material>
</gazebo>
</robot>
```
$$\quad$$舉例說明打開新的終端,輸入roslaunch urdf\_demo display\_gazebo\_rviz.launch,回車之后,發現所有的link和joint已經有在固定的位置上了,并且小車顏色和形狀已經固定完成,gazebo界面同樣顯示正常,詳見urdf本章的demo。
- 前言
- 第一章 ROS簡介
- 機器人時代的到來
- ROS發展歷程
- 什么是ROS
- 安裝ROS
- 安裝ROS-Academy-for-Beginners教學包
- 二進制與源碼包
- 安裝RoboWare Studio
- 單元測試一
- 第二章 ROS文件系統
- Catkin編譯系統
- Catkin工作空間
- Package軟件包
- CMakeLists.txt
- package.xml
- Metapacakge軟件元包
- 其他常見文件類型
- 單元測試二
- 第三章 ROS通信架構(一)
- Node & Master
- Launch文件
- Topic
- Msg
- 常見msg類型
- 單元測試三
- 第四章 ROS通信架構(二)
- Service
- Srv
- Parameter server
- Action
- 常見srv類型
- 常見action類型
- 單元測試四
- 第五章 常用工具
- Gazebo
- RViz
- Rqt
- Rosbag
- Rosbridge
- moveit!
- 單元測試五
- 第六章 roscpp
- Client Library與roscpp
- 節點初始、關閉與NodeHandle
- Topic in roscpp
- Service in roscpp
- Param in roscpp
- 時鐘
- 日志與異常
- 第七章 rospy
- Rospy與主要接口
- Topic in rospy
- Service in rospy
- Param與Time
- 第八章 TF與URDF
- 認識TF
- TF消息
- tf in c++
- tf in python
- 統一機器人描述格式
- 附錄:TF數學基礎
- 三維空間剛體運動---旋轉矩陣
- 三維空間剛體運動---歐拉角
- 三維空間剛體運動---四元數
- 第九章 SLAM
- 地圖
- Gmapping
- Karto
- Hector
- 第十章 Navigation
- Navigation Stack
- move_base
- costmap
- Map_server & Amcl
- 附錄:Navigation工具包說明
- amcl
- local_base_planner
- carrot_planner
- clear_costmap_recovery
- costmap_2d
- dwa_local_planner
- fake_localization
- global_planner
- map_server
- move_base_msg
- move_base
- move_slow_and_clear
- navfn
- nav_core
- robot_pose_ekf
- rotate_recovery