ROS机器人建模与仿真(一)——URDF模型的建立和改进
申明:本系列參考古月大神教材《ROS機器人開發實踐》第六章內容,結合自己學習過程和遇到的問題逐一分解,爭取能夠吃透!歡迎大家一起討論!
URDF 是 ROS 中機器人模型的描述格式,包含對機器人剛體外觀、物體屬性、關節類型等方面的描述。URDF(Unified Robot Description Format,統一機器人描述格式)是 ROS 中一個非常重要的機器人模型描述格式,ROS 同時也提供 URDF 文件的 C++ 解析器,可以解析 URDF 文件中使用 XML 格式描述的機器人模型。
使用版本: ROS Melodic
1 URDF 文件中常用的標簽
1.1 < link > 標簽
< link >標簽用于描述機器人某個剛體部分的外觀和物理屬性,包括尺寸(size)、顏色(color)、形狀(shape)、慣性矩陣(inertial matrix)、碰撞參數(collision properties)等。
機器人的 link 結構,基本 URDF 描述語法如下:
<link name = "<link name>">
<inertial> ------------</inertial><visual>-------------</visual><collision>--------- </collision>
</link>
< visual >用于描述機器人link部分的外觀參數,< inertial >標簽用于描述link的慣性參數,而< collision >標簽用于描述link的碰撞屬性。一般來說,檢測碰撞的link區域大于外觀可視的區域,也就是說有一定的安全空間
1.2 < joint >標簽
< joint >標簽用于描述機器人關節的運動學和動力學屬性,包括關節運動的位置和速度限制。機器人關節的主要作用是連接兩個剛體link,這兩個link分別稱為 parent link 和 child link。
< joint >標簽的描述語法如下:
<joint name="<name of the joint>"><parent link = "parent_link" /><child link = "child_link" /><calibration ---- /><dynamics damping ---- /><limit effort ---- />
</joint>
其中必須指定joint的parent link 和 child link,還可以設置關節的其他屬性。
< calibration > : 關節的參考位置,用來校準關節的絕對位置
< dynamics > : 用于描述關節的物理屬性,例如阻尼值、物理經摩擦力等,經常在運動學仿真中用到。
< limit > : 用于描述運動的一些極限值,包括關節運動的上下限位置、速度限制、力矩限制等。
< mimic > : 用于描述該關節與已有關節的關系。
< safety_controller > : 用于描述安全控制器的參數。
1.3 < robot > 標簽
< robot > 是完整機器人模型的最頂層標簽,< link > 和 < joint > 標簽都必須包含在< robot >標簽內。一個完整的機器人模型由一系列的< link > 和 < joint > 組成。
< robot >標簽語法如下:
<robot name = "<name of the robot>"><link> -------</link><link> -------</link><joint>-------</joint><joint>-------</joint>
</robot>
1.4 < gazebo >標簽
< gazebo >標簽用于描述機器人模型在Gazebo中仿真所需要的參數,包括機器人材料的屬性、Gzaebo 插件等。該標簽不是機器人模型必須的部分,只有在 Gazebo 仿真時才需加入。
< gazebo >標簽的基本語法如下:
<gazebo reference = "link_1"><material> Gazebo/Black</material>
</gazebo>
2 創建一個機器人URDF 模型
2.1 準備工作(創建功能包和文件夾)
創建test_mrobot_description功能包,依賴urdf,xacro
在其下創建4個文件夾urdf、meshes、launch和config
- urdf : 用于存放機器人模型的 URDF 或 xacro 文件
- meshes : 用于存放URDF中引用的模型渲染文件
- launch : 用于存放相關啟動文件
- config : 用于存放日 rviz 的配置文件
2.2 創建 URDF 模型
任務:創建一個機器人的底盤模型
這個機器人底盤模型有7個link和6個joint。7個 link 包括 1 個機器人底板、2個電機、2個驅動輪和2個萬向輪;6個 joint 負責將驅動輪、萬向輪、電機安裝到底板上,并設置相應的連接方式。
模型文件test_mrobot_chassis.urdf
(經過測試,URDF文件不能加入中文字符,寫程序時注意將中文注釋去掉!!!)
<?xml version= "1.0" ?>
<!--申明該文件使用XML描述-->
<robot name="test_mrobot_chassis">
<!--定義機器人的名稱--><link name="base_link"><!--定義第一個link——底盤--><visual><!--外觀--><origin xyz="0 0 0" rpy="0 0 0" /><!--申明三維坐標位置和旋轉姿態--><geometry><!--幾何尺寸--><cylinder length="0.005" radius="0.13" /><!--圓柱體 高0.005 半徑0.13--></geometry><material name="yellow"><!--定義顏色--><color rgba="1 0.4 0 1" /></material></visual></link><joint name="base_left_motor_joint" type="fixed"><!--關節:連接底盤和左驅動電機,類型為fixed,固定--><origin xyz="-0.055 0.075 0" rpy="0 0 0" /><parent link= "base_link" /><!--定義父link--><child link="left_motor" /><!--定義子link--></joint><link name="left_motor"><!--左電機link--><visual><origin xyz="0 0 0 " rpy="1.5707 0 0" /><!--繞X軸傾角約為90度--><geometry><cylinder radius="0.02" length="0.08"/></geometry><material name="gray"><color rgba="0.75 0.75 0.75 1" /></material></visual></link><joint name="left_motor_wheel_joint" type="continuous"><!--關節:左輪和左電機,類型為圍繞軸進行旋轉--><origin xyz="0 0.0485 0" rpy="0 0 0" /><parent link="left_motor" /><child link="left_wheel_link" /><axis xyz="0 1 0" /></joint><link name="left_wheel_link"><!--左輪link--><visual><origin xyz="0 0 0" rpy="1.5707 0 0" /><geometry><cylinder radius="0.033" length="0.017" /></geometry><material name="white"><color rgba="1 1 1 0.9 "/></material></visual></link><!--右輪與左輪幾乎相同,注釋不再寫--><joint name="base_right_motor_joint" type="fixed"><origin xyz="-0.055 -0.075 0" rpy="0 0 0" /><parent link="base_link" /><child link="right_motor" /></joint><link name="right_motor"><visual><origin xyz="0 0 0" rpy="1.5707 0 0" /><geometry><cylinder radius="0.02" length="0.08" /></geometry><material name="gray"><color rgba="0.75 0.75 0.75 1" /></material></visual></link><joint name="right_motor_wheel_joint" type="continuous"><origin xyz="0 -0.0485 0" rpy=" 0 0 0" /><parent link="right_motor"/><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 radius="0.033" length="0.017" /></geometry><material name="white"><color rgba=" 1 1 1 0.9"/></material></visual></link><!--前萬向輪--><joint name="front_castor_joint" type="fixed"><origin xyz="0.1135 0 -0.0165" rpy=" 0 0 0" /><parent link="base_link"/><child link="front_castor_link" /></joint><link name="front_castor_link"><visual><origin xyz=" 0 0 0" rpy="0 0 0" /><geometry><sphere radius="0.0165" /></geometry><material name="black" ><color rgba="0 0 0 0.95" /></material></visual></link>
</robot>
URDF提供了一些命令行工具,幫助我們檢查、梳理模型文件,首先在終端安裝:
sudo apt-get install liburdfdom-tools
使用 check_urdf 命令對 mrobot_chassis.urdf 文件進行檢查,切記:使用命令時需要進入存放此 .urdf 文件的文件夾中:
check_urdf test_mrobot_chassis.urdf
check_urdf 的作用是解析URDF文件,并且顯示解析過程中發現的錯誤。如果一切正常,會輸出如下結果:
還可以使用 urdf_to_graphiz 命令查看URDF模型的整體結構:
urdf_to_graphiz test_mrobot_chassis.urdf
執行 urdf_to_graphiz 命令后,會在當前目錄下生成一個pdf文件(另外,還會生成一個 .gv格式的文件,不知道如何打開,有知道的可以討論下):
2.3 在rviz中顯示模型
創建一個launch文件,test_display_mrobot_chassis_urdf.launch ,詳細內容如下:
<launch><param name="robot_description" textfile="$(find test_mrobot_description)/urdf/test_mrobot_chassis.urdf" /><!--設置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 test_mrobot_description)/config/mrobot_urdf.rviz" required="true" />
</launch>
(特別注意,第一次打開rviz,配置好插件后,save config as保存 .rviz文件,在通過args加載保存好的config文件)
joint_state_publisher 和 robot_state_publisher兩個節點都是系統自帶的,joint_state_ publisher可以發布每個joint(除了fixed類型)的狀態,而且能通過UI 對joint進行控制。
robot_state_publisher節點的功能是將機器人各個link、joint之間的關系,通過TF 的形式整理成三維姿態信息發布出去。在rviz中,選擇TF插件可以顯示各部分的坐標信息。
3 改進URDF模型
3.1 添加物理和碰撞信息
在之前的模型中,我們僅創建了模型外觀的可視化屬性,除此之外,還需要添加物理慣性屬性和碰撞屬性。
- 慣性參數的設置主要包括質量和慣性矩陣。規則物體可以通過尺寸、質量等計算得到慣性矩陣。
- 為了簡化,碰撞屬性標簽< collision >和外觀屬性標簽 < visual >中的內容幾乎一致。
規則物體的慣性矩陣計算公式:(轉自 :ROS漫漫長路(一)——Gazebo中機器人圓柱,球,長方體慣性矩陣推導與代碼實現)
因此,針對底盤 base_link,加入< inertial >和 < collision>標簽:
<link name="dummy"></link><joint name="dummy_joint" type="fixed"><parent link="dummy"/><child link="base_link"/></joint><link name="base_link"><inertial><mass value="2" /><inertia ixx="0.00845" ixy="0.0" ixz="0.0"iyy="0.00845" iyz="0.0" izz="0.0169" /></inertial> <visual><origin xyz="0 0 0" rpy="0 0 0" /><geometry><cylinder length="0.005" radius="0.13" /></geometry><material name="yellow"><color rgba="1 0.4 0 1" /></material></visual><collision><origin xyz=" 0 0 0" rpy="0 0 0" /><geometry><cylinder length="0.005" radius="0.13" /></geometry></collision></link>
針對此處出現的警告進行修改:
1、base_link警告
The root link base_link has an inertia specified in the URDF, but KDL does not support a root link with an inertia. As a workaround, you can add an extra dummy link to your URDF
修改:增加一個額外的虛實體和關節:
<link name="dummy"></link><joint name="dummy_joint" type="fixed"><parent link="dummy"/><child link="base_link"/></joint>
2、joint_state_publisher警告
[WARN] [1588564677.171522]: The ‘use_gui’ parameter was specified, which is deprecated. We’ll attempt to find and run the GUI, but if this fails you should install the ‘joint_state_publisher_gui’ package instead and run that. This backwards compatibility option will be removed in Noetic.
[ERROR] [1581780877.646970]: Could not find the GUI, install the ‘joint_state_publisher_gui’ package
修改:先下載 joint_state_publisher_gui 軟件包
sudo apt-get install ros-kinetic-joint-state-publisher-gui
修改launch文件:
<node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" />
3.2 使用 xacro 優化 URDF
URDF 文件不支持代碼復用,針對URDF 模型產生了另一種精簡化、可復用、模塊化的描述形式——xacro,具體優點不再贅述,在后面代碼中會有所體現。
xacro 是 URDF 的升級版,模型文件后綴名由 .urdf 改為 .xacro,而且在模型< robot >標簽中需要加入 xacro 申明:
<? xml version="1.0" ?>
<robot name="robot_name" xmlns:xacro="https://www.ros.org/wiki/xacro">
接下來介紹 xacro 模型的一些典型語法:
- 使用常量定義
xacro 模型中可以事先申明常量,便于后期修改:
<xacro:property name="M_PI" value="3.1415926" />
使用該常量時,使用如下語法調用:
<origin xyz="0 0 0" rpy="${M_PI}/2 0 0" />
接下來,將文件中的各個參數使用常量定義申明:
<xacro:property name="wheel_radius" value="0.033" />
<xacro:property name="wheel_length" value="0.017" />
<xacro:property name="base_link_radius" value="0.13" />
<xacro:property name="base_link_length" value="0.005" />
<xacro:property name="motor_radius" value="0.02" />
<xacro:property name="motor_length" value="0.08" />
<xacro:property name="motor_x" value="-0.055" />
<xacro:property name="motor_y" value="0.075" />
<xacro:property name="plate_height" value="0.07" />
<xacro:property name="standoff_x" value="0.12" />
<xacro:property name="standoff_y" value="0.10" />
- 調用數學公式
在“${}”語句中,不僅可以調用常量,還可以使用一些常用的數學運算,包括加、減、乘、除、負號、括號等,例如:
<origin xyz="0 ${(motor_length+wheel_length)/2} 0" rpy="0 0 0" />
所有的運算都會轉換成浮點數進行,以保證運算精度。
- 使用宏定義
xacro 文件可以使用宏定義來聲明重復使用的代碼模塊,而且可以包含輸入參數,類似編程中的函數概念。在Mrobot底盤上還有兩層支撐板,支撐板之間共需8根支撐柱,支撐柱的模型一樣,只是位置有所不同,用URDF 文件一共要描述8次。在xacro中,這種相同的模型可以使用一種宏定義模塊的方式重復使用。
<xacro:macro name="mrobot_standoff_2in" param="parent number" x_loc y_loc z_loc><joint name="standoff_2in_${number}_joint" type="fixed"><origin xyz="${x_loc} ${y_loc} ${z_loc}" rpy="0 0 0" /><parent link="${parent}" /><child link="standoff_2in_${number}_link" /></joint><link name="standoff_2in_${number}_link"><inertial><mass value="0.001" /><origin xyz="0 0 0" /><inertia ixx="0.0001" ixy="0.0" ixz="0.0"iyy="0.0001" iyz="0.0" izz="0.0001" /></inertial><visual><origin xyz="0 0 0" rpy="0 0 0" /><geometry><box size="0.01 0.01 0.07" /></geometry><material name="black"><color rgba="0.16 0.17 0.15 0.9" /></material> </visual><collision><origin xyz="0.0 0 0" rpy="0 0 0" /><geometry><box size="0.01 0.01 0.07" /></geometry></collision></link>
</xacro:macro>
以上宏定義包含五個輸入參數:joint的parent link,支撐柱的序號number,支撐柱在x,y,z三個方向上的偏移。需要使用宏模塊時,使用如下語句調用,設置輸入參數即可:
<xacro:mrobot_standoff_2in parent="base_link" number="4" x_loc="${standoff_x/2}" y_loc="${standoff_y}" z_loc="${plate_hight/2}" />
3.3 完整實現過程
完整的test_mrobot_body.urdf.xacro 代碼如下:
<?xml version="1.0"?>
<!--statement-->
<robot xmlns:xacro="https://www.ros.org/wiki/xacro"><!--Constant definition--><xacro:property name="M_PI" value="3.1415926" /><xacro:property name="wheel_radius" value="0.033" /><xacro:property name="wheel_length" value="0.017" /><xacro:property name="base_link_radius" value="0.13" /><xacro:property name="base_link_length" value="0.005" /><xacro:property name="motor_radius" value="0.02" /><xacro:property name="motor_length" value="0.08" /><xacro:property name="motor_x" value="-0.055" /><xacro:property name="motor_y" value="0.075" /><xacro:property name="plate_height" value="0.07" /><xacro:property name="standoff_x" value="0.12" /><xacro:property name="standoff_y" value="0.10" /><!--the first macro definition--><xacro:macro name="mrobot_standoff_2in" params="parent number x_loc y_loc z_loc"><joint name="standoff_2in_${number}_joint" type="fixed"><origin xyz="${x_loc} ${y_loc} ${z_loc}" rpy="0 0 0" /><parent link="${parent}" /><child link="standoff_2in_${number}_link" /></joint><link name="standoff_2in_${number}_link"><inertial><mass value="0.001" /><origin xyz="0 0 0" /><inertia ixx="0.0001" ixy="0.0" ixz="0.0"iyy="0.0001" iyz="0.0" izz="0.0001" /></inertial><visual><origin xyz="0 0 0" rpy="0 0 0" /><geometry><box size="0.01 0.01 0.07" /></geometry><material name="black"><color rgba="0.16 0.17 0.15 0.9" /></material> </visual><collision><origin xyz="0.0 0 0" rpy="0 0 0" /><geometry><box size="0.01 0.01 0.07" /></geometry></collision></link></xacro:macro><!--main macro definition--><xacro:macro name="test_mrobot_body"><!--color definition--><material name="green"><color rgba="0.0 0.8 0.0 1.0" /></material><material name="yellow"><color rgba="1 0.4 0.0 1.0" /></material><material name="black"><color rgba="0.0 0.0 0.0 0.95" /></material><material name="gray"><color rgba="0.75 0.75 0.75 1.0" /></material><!--bottom_link--><link name="base_footprint"><visual><origin xyz="0 0 0" rpy="0 0 0" /><geometry><box size="0.001 0.001 0.001" /></geometry></visual></link><joint name="base_footprint_joint" type="fixed"><origin xyz="0 0 ${wheel_radius}" rpy=" 0 0 0" /><parent link="base_footprint" /><child link="base_link"/></joint><!--body link and joint--><link name="base_link"><inertial><mass value="2" /><inertia ixx="0.00845" ixy="0.0" ixz="0.0"iyy="0.00845" iyz="0.0" izz="0.0169" /></inertial> <visual><origin xyz="0 0 0" rpy="0 0 0" /><geometry><cylinder length="${base_link_length}" radius="${base_link_radius}" /></geometry><material name="yellow" /></visual><collision><origin xyz=" 0 0 0" rpy="0 0 0" /><geometry><cylinder length="${base_link_length}" radius="${base_link_radius}" /></geometry></collision></link><joint name="base_left_motor_joint" type="fixed"><origin xyz="${motor_x} ${motor_y} 0" rpy="0 0 0" /><parent link= "base_link" /><child link="left_motor" /></joint><link name="left_motor"><inertial><origin xyz="0 0 0 " /><mass value="0.1" /><inertia ixx="0.001" ixy="0.0" ixz="0.0"iyy="0.001" iyz="0.0" izz="0.001" /></inertial><visual><origin xyz="0 0 0 " rpy="${M_PI/2} 0 0" /><geometry><cylinder radius="${motor_radius}" length="${motor_length}"/></geometry><material name="gray" /></visual><collision><origin xyz="0 0 0 " rpy="${M_PI/2} 0 0" /><geometry><cylinder radius="${motor_radius}" length="${motor_length}" /></geometry></collision></link><joint name="left_motor_wheel_joint" type="continuous"><origin xyz="0 ${(motor_length+wheel_length)/2} 0" rpy="0 0 0" /><parent link="left_motor" /><child link="left_wheel_link" /><axis xyz="0 1 0" /></joint><link name="left_wheel_link"><inertial><origin xyz="0 0 0" /><mass value="0.01" /><inertia ixx="0.001" ixy="0.0" ixz="0.0"iyy="0.001" iyz="0.0"izz="0.001" /></inertial><visual><origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /><geometry><cylinder radius="${wheel_radius}" length="${wheel_length}" /></geometry><material name="white" /></visual><collision><origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /><geometry><cylinder radius="${wheel_radius}" length="${wheel_length}" /></geometry></collision></link><joint name="base_right_motor_joint" type="fixed"><origin xyz="${motor_x} -${motor_y} 0" rpy="0 0 0" /><parent link="base_link" /><child link="right_motor" /></joint><link name="right_motor"><inertial><origin xyz="0 0 0" /><mass value="0.1" /><inertia ixx="0.001" ixy="0.0" ixz="0.0"iyy="0.001" iyz="0.0"izz="0.001" /></inertial><visual><origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /><geometry><cylinder radius="${motor_radius}" length="${motor_length}" /></geometry><material name="gray" /></visual><collision><origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /><geometry><cylinder radius="${motor_radius}" length="${motor_length}" /></geometry></collision></link><joint name="right_motor_wheel_joint" type="continuous"><origin xyz="0 -${(motor_length+wheel_length)/2} 0" rpy=" 0 0 0" /><parent link="right_motor"/><child link="right_wheel_link" /><axis xyz="0 1 0" /></joint><link name="right_wheel_link"><inertial><origin xyz="0 0 0" /><mass value="0.01" /><inertia ixx="0.001" ixy="0.0" ixz="0.0"iyy="0.001" iyz="0.0"izz="0.001" /></inertial><visual><origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /><geometry><cylinder radius="${wheel_radius}" length="${wheel_length}" /></geometry><material name="white" /></visual><collision><origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /><geometry><cylinder radius="${wheel_radius}" length="${wheel_length}" /></geometry></collision></link><joint name="front_castor_joint" type="fixed"><origin xyz="${base_link_radius-wheel_radius/2} 0 -${wheel_radius/2}" rpy=" 0 0 0" /><parent link="base_link"/><child link="front_castor_link" /></joint><link name="front_castor_link"><inertial><origin xyz="0 0 0" /><mass value="0.001" /><inertia ixx="0.0001" ixy="0.0" ixz="0.0"iyy="0.0001" iyz="0.0"izz="0.0001" /></inertial><visual><origin xyz=" 0 0 0" rpy="${M_PI/2} 0 0" /><geometry><sphere radius="${wheel_radius/2}" /></geometry><material name="black" /></visual><collision><origin xyz=" 0 0 0" rpy="${M_PI/2} 0 0" /><geometry><sphere radius="${wheel_radius/2}" /></geometry></collision></link><mrobot_standoff_2in parent="base_link" number="1" x_loc="-${standoff_x/2+0.03}" y_loc="-${standoff_y-0.03}" z_loc="${plate_height/2}" /><mrobot_standoff_2in parent="base_link" number="2" x_loc="-${standoff_x/2+0.03}" y_loc="${standoff_y-0.03}" z_loc="${plate_height/2}" /><mrobot_standoff_2in parent="base_link" number="3" x_loc="${standoff_x/2}" y_loc="-${standoff_y}" z_loc="${plate_height/2}" /><mrobot_standoff_2in parent="base_link" number="4" x_loc="${standoff_x/2}" y_loc="${standoff_y}" z_loc="${plate_height/2}" /><joint name="plate_1_joint" type="fixed"><origin xyz="0 0 ${plate_height}" rpy="0 0 0" /><parent link="base_link"/><child link="plate_1_link" /></joint><link name="plate_1_link"><inertial><origin xyz="0 0 0" /><mass value="0.1" /><inertia ixx="0.01" ixy="0.0" ixz="0.0"iyy="0.01" iyz="0.0" izz="0.01" /></inertial><visual><origin xyz="0 0 0" rpy="0 0 0" /><geometry><cylinder radius="${base_link_radius}" length="${base_link_length}" /></geometry><material name="yellow" /></visual><collision><origin xyz="0 0 0" rpy="0 0 0" /><geometry><cylinder radius="${base_link_radius}" length="${base_link_length}" /></geometry></collision></link><mrobot_standoff_2in parent="standoff_2in_1_link" number="5" x_loc="0" y_loc="0"z_loc="${plate_height}" /><mrobot_standoff_2in parent="standoff_2in_2_link" number="6" x_loc="0" y_loc="0"z_loc="${plate_height}" /><mrobot_standoff_2in parent="standoff_2in_3_link" number="7" x_loc="0" y_loc="0"z_loc="${plate_height}" /><mrobot_standoff_2in parent="standoff_2in_4_link" number="8" x_loc="0" y_loc="0"z_loc="${plate_height}" /><joint name="plate_2_joint" type="fixed"><origin xyz="0 0 ${plate_height}" rpy="0 0 0" /><parent link="plate_1_link" /><child link="plate_2_link" /></joint><link name="plate_2_link"><inertial><origin xyz="0 0 0" /><mass value="0.01" /><inertia ixx="0.001" ixy="0.0" ixz="0.0"iyy="0.001" iyz="0.0"izz="0.001" /></inertial><visual><origin xyz="0 0 0" rpy="0 0 0" /><geometry><cylinder radius="${base_link_radius}" length="${base_link_length}" /></geometry><material name="yellow" /></visual><collision><origin xyz="0 0 0" rpy="0 0 0" /><geometry><cylinder radius="${base_link_radius}" length="${base_link_length}" /></geometry> </collision></link></xacro:macro>
</robot>
test_mrobot.urdf.xacro 調用代碼如下:
<?xml version="1.0"?>
<robot name="mrobot" xmlns:xacro="https://www.ros.org/wiki/xacro"><xacro:include filename="$(find test_mrobot_description)/urdf/test_mrobot_body.urdf.xacro" /><test_mrobot_body /></robot>
其中,< robot >標簽之間只有兩行代碼
<xacro:include filename="$(find test_mrobot_description)/urdf/test_mrobot_body.urdf.xacro" />
第一行代碼描述該xacro文件中所包含的其他xacro文件,類似于C 語言中的 include 文件。聲明關系后,該文件可以使用被包含文件中的模塊了。
<test_mrobot_body />
第二行代碼調用了被包含文件 test_mrobot_body.urdf.xacro 中的機器人模型的宏定義。這相當于把機器人本體看作一個模塊,后續在機器人模型上裝配 camera 、Kinect、rplidar 會更加容易,具體的將在后面進行描述。
3.4顯示優化后的模型
有兩種方法可以將優化后的模型顯示在rviz中:
- 1 將 xacro 文件轉換為 URDF 文件(不常用)
rosrun xacro xacro.py test_mrobot.urdf.xacro > test_mrobot.urdf
使用命令后,當前目錄下會生成一個轉化后的 URDF 文件,使用上面介紹的 launch 文件可將該URDF 模型顯示在 rviz中
- 2 直接調用 xacro 文件解析器
該過程省略了 xacro 文件的轉化過程,直接在 test_display_mrobot.launch 文件中進行配置:
<arg name="model" default="$(find xacro)/xacro --inorder '$(find test_mrobot_description)/urdf/test_mrobot.urdf.xacro'">
<param name="robot_description" command="arg model" />
launch文件中其余節點的調用與原 lunch 文件相同,大家參照上文自行修改。
roslaunch test_mrobot_description test_display_mrobot.launch
使用上述命令在 rviz 中進行模型顯示。rviz 中的配置方式和模型顯示結果如下圖所示:
本節完,記錄本人的學習過程,其間有問題的部分歡迎大家一起討論!
總結
以上是生活随笔為你收集整理的ROS机器人建模与仿真(一)——URDF模型的建立和改进的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软路由-Hi-Spider Router
- 下一篇: 乌鲁木齐特产有哪些有名的(乌鲁木齐必买带