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:
一般情况下,URDF由一个声明信息
和两种关键组件
共同组成
声明信息包含两部分,第一部分是xml的声明信息,放在第一行
<?xml version="1.0"?>
第二部分是机器人的声明,通过robot标签就可以声明一个机器人模型
<robot name="fishbot">
</robot>
观察下图机器人的结构
可以简化为如下五个部件组成:
躯体
左右轮子
支撑轮
雷达激光
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进行详细的介绍。
上面我们介绍完了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>
link的子标签列表
<geometry>
(几何形状)<box>
长方体
size
-长宽高<box size="1 1 1" />
<cylinder>
圆柱体
radius
-半径 length
-高度<cylinder radius="1" length="0.5"/>
sphere
球体
radius
-半径<sphere radius="0.015"/>
mesh
第三方导出的模型文件
<mesh filename="package://robot_description/meshes/base_link.DAE"/>
xyz
默认为零矢量 rpy
弧度表示的翻滚、俯仰、偏航<origin xyz="0 0 0" rpy="0 0 0" />
name
名字
rgba
<material name="black"><color rgba="1.0 1.0 1.0 0.5" /> </material>
joint为机器人关节,机器人关节用于连接两个机器人部件,主要写明父子关系
父子之间的连接类型,是否固定的,可以旋转的等
父部件名字
子部件名字
父子之间相对位置
父子之间的旋转轴,绕哪个轴转
比如我们再建立一个雷达部件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>
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" />
讲完joint和link,我们来把我们上面定义的简单的URDF(包含身体和雷达)用RVIZ2显示出来,直观的感受下,我们的机器人模型。
URDF可视化的步骤如下:
建立机器人描述功能包
建立urdf
文件夹编写urdf文件
建立launch
文件夹,编写launch文件
修改setup.py
配置,编译测试
轻车熟路,先创建一个fishbot_ws
工作空间,然后建立功能包,包的类型选ament_python
ros2 pkg create fishbot_description --build-type ament_python
建立文件夹,创建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>
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]
导入头
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': [
],
},
)
编译
colcon build
运行测试
source install/setup.bash
ros2 launch fishbot_description display_rviz2.launch.py
添加robotmodel模块,分别选择link名称如下,即可看到机器人的模型显示
此时看看节点关系图
练习1:尝试将机器人的雷达固定位置向车体的y轴负方向移动5cm,并在rviz中显示出来
练习2:尝试在URDF中添加imu_link并使用imu_joint将其固定在车体的上表面中心,imu采用的几何形状为box。长宽高各是1cm
参考文档
技术交流&&问题求助:
QQ交流群:139707339
版权保护:已加入“维权骑士”(rightknights.com)的版权保护计划