8.1URDF统一机器人建模语言.md 12 KB

8.1 URDF统一机器人建模语言

URDF(Unified Robot Description Format)统一机器人描述格式,URDF使用XML格式描述机器人文件。

XML是 被设计用来传输和存储数据的可扩展标记语言,注意语言本身是没有含义的,只是规定了其数据格式

比如说下面这段信息:

> <note>
> <to>小鱼</to>
> <from>鱼粉</from>
> <heading>100万</heading>
> <body>收到来自鱼粉的100万打赏!</body>
> </note>
> ```
>
> 其中的`<node></node>`等标签都是自定义的,只要符合xml格式即可
>
> XML格式在线校验工具:[在线代码格式化 (oschina.net)](https://tool.oschina.net/codeformat/xml)
>
> XML格式注释:<!-- 注释内容 -->
>
> robot标签的属性`name`: `<robot name="fishbot"></robot>`
>
> robot标签的子标签`link`: `<robot name="fishbot"><link name="base_link"></link>link></robot>`



使用XML定义的一个最简单的URDF模型可以像下面这样

```xml
<?xml version="1.0"?>
<robot name="fishbot">
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.18" radius="0.06"/>
      </geometry>
    </visual>
  </link>
</robot>

接着我们从下面四个方面介绍URDF:

  1. URDF的组成介绍
  2. URDF-Link介绍
  3. URDF-Joint介绍
  4. 创建一个简单的URDF并在RVIZ2中可视化

1.URDF的组成介绍

一般情况下,URDF由一个声明信息两种关键组件共同组成

1.1 声明信息

声明信息包含两部分,第一部分是xml的声明信息,放在第一行

<?xml version="1.0"?>

第二部分是机器人的声明,通过robot标签就可以声明一个机器人模型

<robot name="fishbot">
 	
</robot>

1.2 两种关键组件

观察下图机器人的结构

image-20220113094606907

可以简化为如下五个部件组成:

  • 躯体

  • 左右轮子

  • 支撑轮

  • 雷达激光

  • IMU模块

这五个部件之间的固定方式为:

graph 
A[左轮] -->C[躯体]
B[右轮] -->C[躯体]
D[IMU] -->C[躯体]
E[雷达] -->C[躯体]
F[支撑轮子] -->C[躯体]

我们把左轮,右轮、支撑轮子,IMU和雷达部件称为机器人的Link

而Link和Link之间的连接部分称之为Joint关节

接着我们给每个link和joint取个名字。

graph 
A[左轮:left_wheel_link] --left_wheel_joint-->C[躯体]
B[右轮:right_wheel_link] --right_wheel_joint-->C[躯体]
D[IMU:imu_link] --imu_joint-->C[躯体]
E[雷达:laser_link] --laser_joint-->C[躯体]
F[支撑轮子:caster_link] --caster_joint-->C[躯体:base_link]

所以我们就可以使用6个link和5个joint来描述这个机器人,接着我们分别对link和joint进行详细的介绍。

image-20220112134251483

2.Link介绍

上面我们介绍完了link,那一个link该怎么写呢?

我们来看一个base_link的,通过link标签即可声明一个link,属性name指定部件名字

  <link name="base_link">

  </link>

通过两行代码就可以定义好base_link,但现在的base_link是空的,我们还要声明我们的base_link长什么样,通过visual子标签就可以声明出来机器人的visual形状。

  <!-- base link -->
  <link name="base_link">
  	<visual>
      <origin xyz="0 0 0.0" rpy="0 0 0"/>
      <geometry>
		<cylinder length="0.12" radius="0.10"/>
      </geometry>
    </visual>
  </link>

2.1 link标签定义

link的子标签列表

  • visual 显示形状
    • <geometry>(几何形状)
    • <box> 长方体
      • 标签属性: size-长宽高
      • 举例:<box size="1 1 1" />
    • <cylinder> 圆柱体
      • 标签属性:radius -半径 length-高度
      • 举例:<cylinder radius="1" length="0.5"/>
    • sphere 球体
      • 属性:radius -半径
      • 举例:<sphere radius="0.015"/>
    • mesh 第三方导出的模型文件
      • 属性:filename
      • 举例:<mesh filename="package://robot_description/meshes/base_link.DAE"/>
    • origin (可选:默认在物体几何中心)
    • 属性 xyz默认为零矢量 rpy弧度表示的翻滚、俯仰、偏航
    • 举例:<origin xyz="0 0 0" rpy="0 0 0" />
    • material 材质
    • 属性 name 名字
      • color
      • 属性 rgba
      • 举例:<material name="black"><color rgba="1.0 1.0 1.0 0.5" /> </material>
  • collision 碰撞属性,仿真章节中讲解
  • inertial 惯性参数 质量等,仿真章节中讲解

3.Joint介绍

joint为机器人关节,机器人关节用于连接两个机器人部件,主要写明父子关系

  • 父子之间的连接类型,是否固定的,可以旋转的等

  • 父部件名字

  • 子部件名字

  • 父子之间相对位置

  • 父子之间的旋转轴,绕哪个轴转

image-20220112162931639

比如我们再建立一个雷达部件laser_link,然后将laser_link固定到base_link

<?xml version="1.0"?>
<robot name="fishbot">
    
  <!-- base link -->
  <link name="base_link">
  	<visual>
      <origin xyz="0 0 0.0" rpy="0 0 0"/>
      <geometry>
		<cylinder length="0.12" radius="0.10"/>
      </geometry>
    </visual>
  </link>
    
  <!-- laser link -->
  <link name="laser_link">
  	<visual>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <geometry>
		<cylinder length="0.02" radius="0.02"/>
      </geometry>
      <material name="black">
      	<color rgba="1.0 1.0 1.0 0.5" /> 
      </material>
    </visual>
  </link>
    
  <!-- laser joint -->
    <joint name="laser_joint" type="fixed">
        <parent link="base_link" />
        <child link="laser_link" />
        <origin xyz="0 0 0.075" />
    </joint>

</robot>

3.1 joint标签详解

joint属性

  • name 关节的名称
  • type 关节的类型
    • revolute: 旋转关节,绕单轴旋转,角度有上下限,比如舵机0-180
    • continuous: 旋转关节,可以绕单轴无限旋转,比如自行车的前后轮
    • fixed: 固定关节,不允许运动的特殊关节
    • prismatic: 滑动关节,沿某一轴线移动的关节,有位置极限
    • planer: 平面关节,允许在xyz,rxryrz六个方向运动
    • floating: 浮动关节,允许进行平移、旋转运动

joint的子标签

  • parent 父link名称
    • <parent link="base_link" />
  • child子link名称
    • <child link="laser_link" />
  • origin 父子之间的关系xyz rpy
    • <origin xyz="0 0 0.014" />
  • axis 围绕旋转的关节轴
    • <axis xyz="0 0 1" />

4.URDF可视化

讲完joint和link,我们来把我们上面定义的简单的URDF(包含身体和雷达)用RVIZ2显示出来,直观的感受下,我们的机器人模型。

URDF可视化的步骤如下:

  1. 建立机器人描述功能包

  2. 建立urdf文件夹编写urdf文件

  3. 建立launch文件夹,编写launch文件

  4. 修改setup.py配置,编译测试

4.1 建立功能包

轻车熟路,先创建一个fishbot_ws工作空间,然后建立功能包,包的类型选ament_python

ros2 pkg create fishbot_description --build-type ament_python

4.2 建立URDF文件

建立文件夹,创建urdf文件

cd fishbot_description && mkdir urdf 
touch fishbot_base.urdf

编辑fishbot_base.urdf

<?xml version="1.0"?>
<robot name="fishbot">
    
  <!-- base link -->
  <link name="base_link">
  	<visual>
      <origin xyz="0 0 0.0" rpy="0 0 0"/>
      <geometry>
		<cylinder length="0.12" radius="0.10"/>
      </geometry>
    </visual>
  </link>
    
  <!-- laser link -->
  <link name="laser_link">
  	<visual>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <geometry>
		<cylinder length="0.02" radius="0.02"/>
      </geometry>
      <material name="black">
      	<color rgba="1.0 1.0 1.0 0.5" /> 
      </material>
    </visual>
  </link>
    
  <!-- laser joint -->
    <joint name="laser_joint" type="fixed">
        <parent link="base_link" />
        <child link="laser_link" />
        <origin xyz="0 0 0.075" />
    </joint>

</robot>

4.3 建立launch文件

mkdir launch
touch display_rviz2.launch.py

import os
from launch import LaunchDescription
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare


def generate_launch_description():
    package_name = 'fishbot_description'
    urdf_name = "fishbot_base.urdf"

    ld = LaunchDescription()
    pkg_share = FindPackageShare(package=package_name).find(package_name) 
    urdf_model_path = os.path.join(pkg_share, f'urdf/{urdf_name}')

    robot_state_publisher_node = Node(
        package='robot_state_publisher',
        executable='robot_state_publisher',
        arguments=[urdf_model_path]
        )

    joint_state_publisher_node = Node(
        package='joint_state_publisher_gui',
        executable='joint_state_publisher_gui',
        name='joint_state_publisher_gui',
        arguments=[urdf_model_path]
        )

    rviz2_node = Node(
        package='rviz2',
        executable='rviz2',
        name='rviz2',
        output='screen',
        )

    ld.add_action(robot_state_publisher_node)
    ld.add_action(joint_state_publisher_node)
    ld.add_action(rviz2_node)

    return ld

想要可视化模型需要三个节点参与

  • joint_state_publisher_gui 负责发布机器人关节数据信息,通过joint_states话题发布
  • robot_state_publisher_node负责发布机器人模型信息robot_description,并将joint_states数据转换tf信息发布
  • rviz2_node负责显示机器人的信息
graph
A[joint_state_publisher]--joint_states-->B
B[robot_state_publisher]--robot_de-->C
C[rviz2]

4.4 修改setup.py

导入头

from glob import glob
import os

加入目录安装

('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),

完整

from setuptools import setup
from glob import glob
import os

package_name = 'fishbot_description'

setup(
    name=package_name,
    version='0.0.0',
    packages=[package_name],
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
        (os.path.join('share', package_name, 'launch'), glob('launch/*.launch.py')),
        (os.path.join('share', package_name, 'urdf'), glob('urdf/**')),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='root',
    maintainer_email='root@todo.todo',
    description='TODO: Package description',
    license='TODO: License declaration',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
        ],
    },
)

4.5 编译测试

编译

colcon build

运行测试

source install/setup.bash
ros2 launch fishbot_description display_rviz2.launch.py

添加robotmodel模块,分别选择link名称如下,即可看到机器人的模型显示

image-20220113104129248

此时看看节点关系图

image-20220113105040037

5.本节练习

练习1:尝试将机器人的雷达固定位置向车体的y轴负方向移动5cm,并在rviz中显示出来

练习2:尝试在URDF中添加imu_link并使用imu_joint将其固定在车体的上表面中心,imu采用的几何形状为box。长宽高各是1cm

参考文档


技术交流&&问题求助:

  • 微信公众号及交流群:鱼香ROS
  • 小鱼微信:AiIotRobot
  • QQ交流群:139707339

  • 版权保护:已加入“维权骑士”(rightknights.com)的版权保护计划