一.ROS的機關長度和坐标慣例
在參照架構中工作時:
ROS确定坐标軸方向使用的是如下圖所示的右手系:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLxEDN2EjNwIDM3EzMwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
食指指向x軸正方向,中指指向y軸正方向,而拇指指向z軸正方向。
ROS确定旋轉方向是由下圖所示的右手法則來定義的:
右手握拳,拇指指向某一坐标軸的正方向,其他手指卷曲的方向則是旋轉的正方向。
對于使用ROS的移動機器人,x軸指向前方,y軸指向左方,z軸指向上方。根據右手法則(從機器人的上方往下看),當機器人繞z軸做正方向旋轉時是在逆時針旋轉,而做反向旋轉時是在順時針旋轉。
ROS系統使用公制作為計量系統:
線速度通常使用米/秒(m/s)來作為機關,而角速度通常使用弧度/秒(rad/s)來作為機關。
對于室内機器人來說0.5m/s(約等于1.1mph)的線速度是比較快的速度,而1.0rad/s相當于6秒旋轉1圈或者說每分鐘旋轉10圈。當你不确定該設定什麼速度時,請用較慢的速度啟動并慢慢提升速度。
二.URDF
Unified Robot Description Format,統一機器人描述格式,簡稱為URDF。ROS中的urdf功能包包含一個URDF的C++解析器,URDF檔案使用XML格式描述機器人模型。
具體的可參看:
https://blog.csdn.net/weixin_41070687/article/details/88615737
http://wiki.ros.org/urdf/Tutorials
後面第四點直接上手實戰
三.xacro
使用urdf模型搭建機器人,我們會發現我們建立了一個十分冗長的模型檔案,其中很多内容除了參數,幾乎都是重複的内容。但是urdf檔案并不支援代碼複用的特性。ROS自然不會容忍這種冗長重複的情況,因為它的設計目标就是提高代碼複用率。于是針對URDF模型産生了另一種精簡化、可複用、子產品化的描述形式---xacro。
優勢:
- 精簡模型代碼:xacro是一個精簡版本的URDF檔案,在xacro檔案中,可以通過建立宏定義的方式定義常量或者複用代碼,不僅可以減少代碼量,而且可以讓模型代碼更加子產品化、更具可讀性。
- 提供可程式設計接口:xacro的文法支援一些可程式設計接口,如常量、變量、數學公式、條件語句等,可以讓模組化過程更加智能有效。
xacro是URDF的更新版,模型檔案的字尾名由.urdf變為.xacro,而且在模型<robot>标簽中需要加入xacro的聲明:
<?xml version="1.0"?>
<robot name="robot_name" xmlns:xacro="http://www.ros.org/wiki/xacro">
1.定義常量
在URDF模型中有很多尺寸、坐标等常量的使用,但是這些常量分布在整個檔案中,不僅可讀性差,而且後期修改起來十分困難。xacro提供了一種常量屬性的定義方式:
<xacro:property name="常量名" value="常量值" />
2.調用常量
<origin xyz="..." rpy="${常量名} . ." />
調用的時候:${ }
例如:
定義一個名為M_PI的常量,值為3.14159
<xacro:property name="M_PI" value="3.14159" />
調用該常量
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
在“${}”語句中,不僅可以調用常量,還可以使用一些常用的數學運算,包括加、減、乘、除、負号、括号等
注:所有的數學運算都會轉換成浮點數進行,以保證運算的精度
3.宏定義
xacro檔案可以使用宏定義來聲明重複使用的代碼子產品,而且可以包含輸入參數,類似程式設計中的函數概念。
定義:
<xacro:macro name="宏定義名稱" params="A B C">
...
...
...
</xacro:macro>
調用:
<name A="A_value" B="B_value" C="C_value" />
具體的後面在第五點實踐中說明
四.建立自己的機器人URDF模型
1.建立一個工作空間(本人使用的是zsh終端,https://blog.csdn.net/weixin_41070687/article/details/83215785)
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws
catkin_make
echo "source ~/catkin_ws/devel/setup.zsh" >> ~/.zshrc
source ~/.zshrc
在src目錄下建立一個描述機器人模型的功能包mbot_description,依賴項是urdf和xacro。在ROS的工作空間中,功能包名為xxx_description的一般都是描述機器人模型的功能包,我們通常也是這麼命名的
cd ~/catkin_ws/src
catkin_create_pkg mbot_description urdf xacro
cd ..
catkin_make
source ~/.zshrc
然後,在mbot_description目錄下建立四個檔案夾(mbot_description是一個元功能包),直接右擊滑鼠建立檔案夾即可
urdf:用來存放機器人模型的URDF檔案
meshes:放置URDF中引用的模型渲染檔案,如外觀紋理,logo等
launch:儲存相關的啟動檔案
config:儲存rviz的配置檔案
2.我們先在launch功能包下編寫一個launch檔案,名稱為display_mbot_base_urdf.launch,用于啟動顯示我們後面編寫的urdf模型檔案.
這個launch檔案也是一個架構,可以把這個launch檔案架構記住。我們自己在編寫時完全可以照搬這個程式,隻需要根據自己的實際情況,更改第二行裡面的textfile的内容即可。textfile="$(find mbot_description) / urdf檔案的路徑"
<launch>
<param name="robot_description" textfile="$(find mbot_description)/urdf/mbot_base.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="state_publisher" />
<!-- 運作rviz可視化界面 -->
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mbot_description)/config/mbot_urdf.rviz" required="true" />
</launch>
3.接下來開始編寫機器人的URDF模型:
在urdf功能包下建立一個mbot_base.urdf檔案
urdf檔案的最外層架構:
<?xml version="1.0" ?>
<robot name="mbot">>
...
...
...
</robot>
第一行:聲明該檔案使用XML描述
第二行:使用<robot>根标簽定義一個機器人模型,并定義該模型的名稱為“mbot”
編寫機器人模型的主體部分:
<?xml version="1.0" ?>
<robot name="mbot">
<link name="base_link">
<visual>
<origin xyz=" 0 0 0" rpy="0 0 0" />
<geometry>
<cylinder length="0.16" radius="0.20"/>
</geometry>
<material name="yellow">
<color rgba="1 0.4 0 1"/>
</material>
</visual>
</link>
</robot>
link标簽用于描述機器人的某個剛體部分的外觀屬性和實體屬性,名稱為“base_link”
visual标簽用于描述機器人的link部分的外觀參數
origin标簽定義了“base_link”的坐标,長度的機關是米,角度的的機關是弧度
- 當指定x、y、z參數時,x軸指向機器人前方,y軸指向機器人左方,z軸指向機器人上方。
- 當給旋轉變量r、p、y指派時,參數roll(r)表示的是圍繞x軸旋轉的角度,參數pitch(p)表示的是圍繞y軸旋轉的角度,參數yaw(y)表示的是圍繞z軸旋轉的角度。
geometry标簽定義了這一部分的幾何形狀:
- <box> 矩形,大小屬性包含三個邊長,原點在其中心。
- <cylinder> 圓柱,指定半徑和長度,原點在其中心。
- <sphere> 球體,指定半徑,原點在其中心。
- <mesh filename="package://pkg_description/meshs/name.dae" /> 通過該标簽可以導入該模型的mesh檔案。
material标簽定義了機器人底盤的顔色,rgb顔色的RGB值,a是指透明度,值的範圍在0-1
可以先儲存運作,看一下效果:主體是一個圓柱
在終端輸入
roslaunch mbot_description display_mbot_base_urdf.launch
我們可以更改一下urdf檔案中的一些參數值,加深了解。
例如:将origin标簽中的rpy的參數值更改成“1.5707 0 0”,即r=1.5707,p和y均為0,即主體部分繞x軸旋轉90°
更改rgb的參數值換顔色:
給機器人添加兩個輪子:
兩個link之間需要一個joint連接配接
<?xml version="1.0" ?>
<robot name="mbot">
<link name="base_link">
<visual>
<origin xyz=" 0 0 0" rpy="0 0 0" />
<geometry>
<cylinder length="0.16" radius="0.20"/>
</geometry>
<material name="yellow">
<color rgba="1 0.4 0 1"/>
</material>
</visual>
</link>
<joint name="left_wheel_joint" type="continuous">
<origin xyz="0 0.19 -0.05" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="left_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="left_wheel_link">
<visual>
<origin xyz="0 0 0" rpy="1.5707 0 0" />
<geometry>
<cylinder radius="0.06" length="0.025"/>
</geometry>
<material name="white">
<color rgbd="1 1 1 0.9"/>
</material>
</visual>
</link>
<joint name="right_wheel_joint" type="continuous">
<origin xyz="0 -0.19 -0.05" rpy="0 0 0"/>
<parent link="base_link"/>
<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.06" length="0.025"/>
</geometry>
<material name="white">
<color rgba="1 1 1 0.9"/>
</material>
</visual>
</link>
</robot>
對joint标簽部分進行解讀:
<joint name="left_wheel_joint" type="continuous">
<origin xyz="0 0.19 -0.05" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="left_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
joint标簽用于描述機器人關節的運動學和動力學屬性,包括關節運動的位置和速度限制。它有兩個屬性:name和type
type一共有六種類型:
- revolute - 旋轉關節,可繞單軸旋轉,但有旋轉的角度極限。
- continuous - 旋轉關節,可以繞單軸無限旋轉。
- prismatic - 滑動關節,可以沿着一個軸滑動,有最大值和最小值限制。
- fixed - 這不是一個實際的關節,因為它無法運動,所有的自由度都被鎖定。這種類型的關節不需要指定軸、動力學特征、标度和最大值最小值限制。
- floating - 浮動關節,允許進行平移、旋轉運動(是一個具有6個自由度的關節)。
- planar - 此關節在一個平面内運動,垂線是運動軸。
子元素中parent和child标簽是必須要有的,link是名稱。如圖所示:
axis标簽定義joint的旋轉軸。在此段代碼中joint的類型是continuous型,即可以繞單軸無限旋轉,在機器人運動過程中輪子就是可繞單軸無限旋轉。在axis參數中x、y、z代表了三個旋轉軸,其中x和z的值都是0,隻有y為1,即表示該joint的旋轉軸是正y軸,輪子在運動時會繞y軸旋轉。
再一次儲存運作一下看看效果:
機器人主體添加了兩個輪子,運作後還會有一個小框joint_state_publisher,這個是之前在launch檔案中啟動的joint_state_publisher節點,用于釋出機器人的關節狀态。移動橫條可以是輪子轉動。
給機器人前後各添加一個支撐輪:
<joint name="front_caster_joint" type="continuous">
<origin xyz="0.18 0 -0.095" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="front_caster_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="front_caster_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.015" />
</geometry>
<material name="black">
<color rgba="0 0 0 0.95"/>
</material>
</visual>
</link>
<joint name="back_caster_joint" type="continuous">
<origin xyz="-0.18 0 -0.095" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="back_caster_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="back_caster_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.015" />
</geometry>
<material name="black">
<color rgba="0 0 0 0.95"/>
</material>
</visual>
</link>
支撐輪是球體,機器人運動時支撐輪繞y軸正方向旋轉。
整個urdf檔案内容如下:
<?xml version="1.0" ?>
<robot name="mbot">
<link name="base_link">
<visual>
<origin xyz=" 0 0 0" rpy="0 0 0" />
<geometry>
<cylinder length="0.16" radius="0.20"/>
</geometry>
<material name="yellow">
<color rgba="1 0.4 0 1"/>
</material>
</visual>
</link>
<joint name="left_wheel_joint" type="continuous">
<origin xyz="0 0.19 -0.05" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="left_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="left_wheel_link">
<visual>
<origin xyz="0 0 0" rpy="1.5707 0 0" />
<geometry>
<cylinder radius="0.06" length="0.025"/>
</geometry>
<material name="white">
<color rgbd="1 1 1 0.9"/>
</material>
</visual>
</link>
<joint name="right_wheel_joint" type="continuous">
<origin xyz="0 -0.19 -0.05" rpy="0 0 0"/>
<parent link="base_link"/>
<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.06" length="0.025"/>
</geometry>
<material name="white">
<color rgba="1 1 1 0.9"/>
</material>
</visual>
</link>
<joint name="front_caster_joint" type="continuous">
<origin xyz="0.18 0 -0.095" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="front_caster_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="front_caster_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.015" />
</geometry>
<material name="black">
<color rgba="0 0 0 0.95"/>
</material>
</visual>
</link>
<joint name="back_caster_joint" type="continuous">
<origin xyz="-0.18 0 -0.095" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="back_caster_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="back_caster_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.015" />
</geometry>
<material name="black">
<color rgba="0 0 0 0.95"/>
</material>
</visual>
</link>
</robot>
再次運作指令檢視整體效果: