友情提示:380元/半年,儿童学编程,就上码丁实验室。
1.9.1 使用URDF构建机器人模型
统一机器人描述格式(Unified Robot Description Format , URDF)是一种XML格式,用于描述机器人模型。在此XML文件中,作如下定义:
-
机器人的运动学和动力学描述;
-
机器人的视觉表示;
-
机器人碰撞模型;
参考链接:
http://wiki.ros.org/urdf/Tutorials
http://wiki.ros.org/urdf/Examples
机器人描述由一组链接(零件)元素和一组将链接连接在一起的关节元素组成。典型的机器人描述如下:
<robot name="pr2">
<link> ... </link>
<link> ... </link>
<link> ... </link>
<joint> .... </joint>
<joint> .... </joint>
<joint> .... </joint>
</robot>
我们将建立一个看起来像R2D2的机器人模型。此处,提到的所有机器人模型和启动文件都可以在urdf_tutorial包中找到(已与ROS一起安装)。
图1 R2D2机器人
首先,创建一个简单的形状,具体查看01-myfirst.urdf(位于urdf_tutorial包中):
<?xml version="1.0"?>
<robot name="myfirst">
<link name="base_link">
<visual>
<geometry>
<cylinder length="0.6" radius="0.2"/>
</geometry>
</visual>
</link>
</robot>
可知,创建了一个名为myfirst的机器人,该机器人仅包含一个链接,其视觉组件是一个0.6米长,半径为0.2米的圆柱体。使用rviz观察3D模型,查看display.launch(在urdf_tutorial包中)文件:
<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>
<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" />
</launch>
该launch文件执行三件事:
-
将指定的模型加载到参数服务器中;
-
运行节点以发布JointState和变换(transforms);
-
用配置文件启动rviz;
根据不同情况,运行launch文件的方式如下所示:
roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/01-myfirst.urdf'
图2 使用rviz观察3D模型
为了向urdf添加更多链接元素,我们需要定义关节(joints),关节连接父子链接,关节有不同类型,首先介绍固定关节。详情查阅文件:02-multipleshapes.urdf
<?xml version="1.0"?>
<robot name="multipleshapes">
<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.2 0.1"/>
</geometry>
</visual>
</link>
<joint name="base_to_right_leg" type="fixed">
<parent link="base_link"/>
<child link="right_leg"/>
</joint>
</robot>
roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/02-multipleshapes.urdf'
图3 多个链接元素
由上图可知,两种形状彼此重叠,因为它们共享相同的起点,为避免它们重叠,则必须定义各自的起点。此外,链接和关节都包含起点标签。
链接(Link)原点标签
origin: 定义视觉组件的中心相对于其原点的位置,如果未指定,则默认为单位元素。
Properties:
-
xyz: 代表偏移量,默认为零向量;
-
rpy: 表示旋转(滚动,俯仰,偏航),默认为单位元素。
关节(Joint)原点标签
origin: 表示父链接到子链接的变换。关节位于子链接的原点,如果未指定,则默认为单位元素。具有与链接原点标签(xyz和rpy)相同的属性。
图4 关节原点标签
对应文件: 03-origins.urdf
<?xml version="1.0"?>
<robot name="origins">
<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 .2 .1"/>
</geometry>
<origin rpy="0 1.57075 0" xyz="0 0 -0.3"/>
</visual>
</link>
<joint name="base_to_right_leg" type="fixed">
<parent link="base_link"/>
<child link="right_leg"/>
<origin xyz="0.22 0 0.25"/>
</joint>
</robot>
关节原点根据父链接参照系定义。根据上述文件,子链接原点在x方向(右)为0.22米,在z方向(上)为0.25米。视觉原点定义了视觉组件的中心相对于其原点的位置。此处,我们希望将腿连接到顶部,因此通过将z偏移设置为-0.3米来向下偏移原点,并且由于我们希望腿的长部分平行于z轴,因此我们视觉组件绕Y轴旋转PI/2。
通过如下命令查看模型:
roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/03-origins.urdf'
图5 查看模型
视觉元素的材料标签,用于指定链接元素使用的材料,属性包括:
-
name: 材料名称, 可以参考先前定义的材料;
-
color(可选):
-
rgba由一组代表red/green/blue/alpha的四个数字指定的材料的颜色,每个数字的范围为[0,1]。
-
texture(可选):材质的纹理由文件名指定。
示例文件:04-materials.urdf
<?xml version="1.0"?>
<robot name="materials">
<link name="base_link">
<visual>
<geometry>
<cylinder length="0.6" radius="0.2"/>
</geometry>
<material name="blue">
<color rgba="0 0 0.8 1"/>
</material>
</visual>
</link>
<link name="right_leg">
<visual>
<geometry>
<box size="0.6 0.2 0.1"/>
</geometry>
<origin rpy="0 1.57075 0" xyz="0 0 -0.3"/>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
</link>
<joint name="base_to_right_leg" type="fixed">
<parent link="base_link"/>
<child link="right_leg"/>
<origin xyz="0.22 0 0.25"/>
</joint>
<link name="left_leg">
<visual>
<geometry>
<box size="0.6 0.2 0.1"/>
</geometry>
<origin rpy="0 1.57075 0" xyz="0 0 -0.3"/>
<material name="white"/>
</visual>
</link>
<joint name="base_to_left_leg" type="fixed">
<parent link="base_link"/>
<child link="left_leg"/>
<origin xyz="-0.22 0 0.25"/>
</joint>
</robot>
通过如下命令查看模型:
roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/04-materials.urdf'
图6 再次查看模型
使用网格(mesh)文件可定义更多逼真的元素,而不仅仅是使用基本的几何对象/块。可以加载由我们生成的网格或使用其它模型的网格。对于我们的模型,我们将使用PR2的抓爪(gripper)。
<link name="left_gripper">
<visual>
<origin rpy="0.0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="package://pr2_description/meshes/gripper_v0/l_finger.dae"/>
</geometry>
</visual>
</link>
为借用PR2的网格(meshes),我们需要安装pr2_description软件包:
sudo apt-get install ros-kinetic-pr2-description
该软件包,包含PR2的机械臂的描述文件,有以下子目录:“urdf/”: 包含PR2各个部分的urdf描述(手臂,躯干等);“robots/”: 包含完整机器人的urdf描述,引用了”urdf /”中的宏;“gazebo/”: 包含仿真PR2组件的urdf描述,例如仿真电池控制器;“meshes/”: 包含用于可视化和碰撞属性的网格物体文件(.stl,.dae)
让我们通过添加一些组件来完成模型设计:左和右底座,四个轮子和带有抓手的手臂;最终的urdf文件:05-visual.urdf。
通过如下命令查看:
roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/05-visual.urdf'
图7 完成模型创建
1.9.2 使用URDF构建可移动机器人模型
要将模型转换为可以实际移动的机器人,需要考虑模型使用的关节类型。上述步骤创建的模型,所有关节都是固定的,现在我们将探索不同类型的活动关节:
-
旋转(revolute ):沿轴旋转并具有上限和下限指定的有限范围的铰链接头;
-
连续(continuous ):绕轴旋转的连续铰链接头,没有上限和下限;
-
棱柱形(prismatic ):沿轴滑动的滑动关节,其上限和下限指定了有限的范围;
-
固定(fixed ):这实际上不是关节,因为它无法移动;
-
浮动(floating ):该关节允许在所有6个自由度上运动;
-
平面(planar ):此关节允许在垂直于轴的平面内运动;
类比人体关节类型:
图8 人体关节类型
(1)头部
<joint name="head_swivel" type="continuous">
<parent link="base_link"/>
<child link="head"/>
<axis xyz="0 0 1"/>
<origin xyz="0 0 0.3"/>
</joint>
身体与头部之间的连接是一个连续关节,这意味着它可以采用从-∞到+∞的任意角度。我们唯需要添加的信息是旋转轴(<axis>标签),该轴指定了头部围绕其旋转的向量,例如,向量“ 0 0 1”表示它将绕z轴旋转。
(2)车轮
<joint name="right_front_wheel_joint" type="continuous">
<axis xyz="0 0 1"/>
<parent link="right_base"/>
<child link="right_front_wheel"/>
<origin rpy="0 1.57075 0" xyz="0 0.133333333333 -0.085"/>
<limit effort="100" velocity="100"/>
<dynamics damping="0.0" friction="0.0"/>
</joint>
车轮也被建模为连续关节,因此它们可以永远在两个方向上滚动。
(3)夹爪
<joint name="left_gripper_joint" type="revolute">
<axis xyz="0 0 1"/>
<limit effort="1000.0" lower="0.0" upper="0.548" velocity="0.5"/>
<origin rpy="0 0 0" xyz="0.2 0.01 0"/>
<parent link="gripper_pole"/>
<child link="left_gripper"/>
</joint>
将左、右抓爪关节建模为旋转关节,意味着它们以连续关节相同的方式旋转,但是它们具有严格的限制。因此,我们必须包含<limit>标签,以指定关节的上限和下限(以弧度为单位);我们还必须为此关节指定最大速度和最大力度。
(4)夹臂
<joint name="gripper_extension" type="prismatic">
<parent link="base_link"/>
<child link="gripper_pole"/>
<limit effort="1000.0" lower="-0.38" upper="0" velocity="0.5"/>
<origin rpy="0 0 1.57075" xyz="0 0.19 .2"/>
</joint>
将”夹臂”建模为棱柱形关节,意味着它沿着轴移动,而不是绕轴移动。这种位移运动使我们的机器人模型可以伸展和缩回其夹臂,棱柱形臂的极限以与旋转关节相同的方式指定,除了单位是米而非弧度。具有柔性关节的新型urdf文件: 06_flexible.urdf。
(5)joint_state_publisher
该软件包包含用于设置和发布给定URDF的关节状态值的工具,为机器人的所有非固定关节发布sensor_msgs / JointState消息,可以与robot_state_publisher节点结合使用,发布所有关节状态的变换。
参考链接: http://wiki.ros.org/joint_state_publisher
可视化和控制机器人模型,命令如下:
roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/06-flexible.urdf' gui:=True
这还将弹出一个GUI,允许您控制所有非固定关节的值;试一下模型,看看它如何运动。
图9 使用joint_state_publisher
1.9.3 添加物理和碰撞属性
如果要在Gazebo或任何其他模拟软件上模拟机器人,则必须添加物理和碰撞属性。我们需要在每个链接上设置几何尺寸,以计算可能发生的碰撞,赋予我们惯性的权重等等。07-physics.urdf是具有物理属性的新URDF文件。
(1)碰撞
碰撞元素是链接对象的直接子元素,与视觉标签处于同一级别。碰撞元素以与视觉元素相同的方式定义其形状,并带有一个几何标签;几何标签的格式在这里与视觉格式完全相同。我们可以使用与碰撞标签的子元素相同的方式指定原点(与视觉标签一样)。碰撞元素示例:
<link name="base_link">
<visual>
<geometry>
<cylinder length="0.6" radius="0.2"/>
</geometry>
<material name="blue">
<color rgba="0 0 .8 1"/>
</material>
</visual>
<collision>
<geometry>
<cylinder length="0.6" radius="0.2"/>
</geometry>
</collision>
</link>
通常,碰撞几何的定义与视觉几何完全相同,但存在两种特殊情况:
-
更快的处理,与两个简单的几何体相比,对两个网格进行碰撞检测的计算复杂度要高得多。因此,您可能需要在碰撞元素中用更简单的几何形状替换网格。
-
安全区,您可能希望限制移动靠近敏感设备。例如,如果我们不希望任何东西与R2D2的头部碰撞,则可以将碰撞几何定义为圆柱体,将其头部包裹住,以防止任何东西靠近他的头部。
(2)惯性
惯性是任何物理物体抵抗其运动状态的任何改变的能力,包括其速度和方向的改变。这是物体以恒定速度保持直线运动的趋势,惯性张量取决于物体的质量和质量分布, 关于惯性张量的一个很好的解释可以在这里找到:inertia.tensor.summary.pdf
3×3旋转惯量矩阵由惯性元素指定:
ixx | ixy | ixz |
ixy | iyy | iyz |
ixz | iyz | izz |
性元素示例:
<link name="base_link">
<visual>
<geometry>
<cylinder length="0.6" radius="0.2"/>
</geometry>
<material name="blue">
<color rgba="0 0 .8 1"/>
</material>
</visual>
<collision>
<geometry>
<cylinder length="0.6" radius="0.2"/>
</geometry>
</collision>
<inertial>
<mass value="10"/>
<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>
</inertial>
</link>
(3)链接元素小结
链接元素描述了刚体的惯性,视觉和碰撞等特征。
图10 链接元素小结
(4)关节元素小结
关节元素描述了关节的运动学和动力学,还指定了关节的安全极限。
图11 关节元素小结
1.9.4 使用Xacro清理URDF文件
本节介绍一些技巧,以使用Xacro减少URDF文件中的代码量。
注意07-physics.urdf文件的大小,它具有414行代码来定义我们的机器人!想象一下,如果您开始添加摄像头和其他几何图形,该文件将开始增大,并且其维护将变得更加复杂。Xacro有助于减小URDF文件的整体大小,并使其更易于阅读和维护。它还允许我们创建模块并重用它们来创建重复的结构,例如几个手臂或腿。
(1)使用Xacro
顾名思义,xacro是一种宏语言,xacro程序运行所有宏并将结果输出为urdf文件。典型用法:
rosrun xacro xacro.py model.xacro > model.urdf
您还可以在启动文件中自动生成urdf:
<param name="robot_description" command="$(find xacro)/xacro.py '$(find pr2_description)/robots/pr2.urdf.xacro'" />
在xacro文件中,必须指定名称空间才能正确解析文件。例如,以下是有效的xacro文件的前两行:
<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="robot1_xacro">
(2)常量
我们可以使用xacro声明常量。这样,我们可以避免将相同的值放在很多行中,并易于维护值的改变。您可以使用<xacro:property>标签定义常量,通常位于文件顶部然后,要使用常量的值,您可以编写$ {name_of_variable}
,常量示例:
<xacro:property name="width" value=".2" />
<xacro:property name="bodylen" value=".6" />
<link name="base_link">
<visual>
<geometry>
<cylinder radius="${width}" length="${bodylen}"/>
</geometry>
<material name="blue">
<color rgba="0 0 .8 1"/>
</material>
</visual>
<collision>
<geometry>
<cylinder radius="${width}" length="${bodylen}"/>
</geometry>
</collision>
</link>
(3)数学
您可以使用四个基本操作(+,-,*,/),一元减号和括号在$ {}构造中构建任意复杂的表达式。但是,不支持幂和模。例子:
<cylinder radius="${wheeldiam/2}" length=".1"/>
<origin xyz="${reflect*(width+.02)} 0 .25" />
(4)宏命令
宏是xacro软件包中最有用的组件,一个简单宏的示例:
<xacro:macro name="default_origin">
<origin xyz="0 0 0" rpy="0 0 0"/>
</xacro:macro>
<xacro:default_origin />
此代码将生成以下内容:
<origin xyz="0 0 0" rpy="0 0 0"/>
(5)参数化宏命令
您还可以参数化宏,以便它们每次不会生成完全相同的文本。与数学函数结合使用时,它的功能更加强大。惯性宏示例:
<xacro:macro name="default_inertial" params="mass">
<inertial>
<mass value="${mass}" />
<inertia ixx="1.0" ixy="0.0" ixz="0.0"
iyy="1.0" iyz="0.0"
izz="1.0" />
</inertial>
</xacro:macro>
<xacro:default_inertial mass="10"/>
腿宏示例:
<xacro:macro name="leg" params="prefix reflect">
<link name="${prefix}_leg">
<visual>
<geometry>
<box size="${leglen} .2 .1"/>
</geometry>
<origin xyz="0 0 -${leglen/2}" rpy="0 ${pi/2} 0"/>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
<collision>
<geometry>
<box size="${leglen} .2 .1"/>
</geometry>
<origin xyz="0 0 -${leglen/2}" rpy="0 ${pi/2} 0"/>
</collision>
<xacro:default_inertial mass="10"/>
</link>
<joint name="base_to_${prefix}_leg" type="fixed">
<parent link="base_link"/>
<child link="${prefix}_leg"/>
<origin xyz="${reflect*(width+.02)} 0 .25" />
</joint>
<!-- A bunch of stuff cut -->
</xacro:macro>
<xacro:leg prefix="right" reflect="1" />
<xacro:leg prefix="left" reflect="-1" />
检查Xacro
这是R2D2模型中使用的xacro:08-macroed.urdf.xacro 。行数从414减少至236,要查看xacro文件生成的模型,请运行:
roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/08-macroed.urdf.xacro'
图12 检查使用Xacro
机器人模型堆栈包含命令行工具check_urdf,通过命名文件的单个命令行参数调用。它尝试将文件解析为URDF描述,并打印所得运动链的描述或错误消息。
例如,要在R2D2 urdf上运行此工具:
roscd urdf_tutorial
cd urdf/
check_urdf 07-physics.urdf
图13 验证URDF
要获取您的urdf文件的graphviz图,请输入:
cp 07-physics.urdf /tmp
urdf_to_graphiz /tmp/07-physics.urdf
evince /tmp/physics.pdf
结果是一个名为physics.pdf的文件,如图所示:
图14 urdf_to_graphiz
转自公众号:
Robot404