|
@@ -18,6 +18,12 @@ URDF(Unified Robot Description Format)统一机器人描述格式,URDF使
|
|
|
> 其中的`<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>`
|
|
|
|
|
|
|
|
|
|
|
@@ -51,7 +57,7 @@ URDF(Unified Robot Description Format)统一机器人描述格式,URDF使
|
|
|
|
|
|
一般情况下,URDF由`一个声明信息`和`两种关键组件`共同组成
|
|
|
|
|
|
-1.1 声明信息
|
|
|
+### 1.1 声明信息
|
|
|
|
|
|
声明信息包含两部分,第一部分是xml的声明信息,放在第一行
|
|
|
|
|
@@ -67,28 +73,427 @@ URDF(Unified Robot Description Format)统一机器人描述格式,URDF使
|
|
|
</robot>
|
|
|
```
|
|
|
|
|
|
+## 1.2 两种关键组件
|
|
|
+
|
|
|
+观察下图机器人的结构
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+可以简化为如下五个部件组成:
|
|
|
+
|
|
|
+- 躯体
|
|
|
+
|
|
|
+- 左右轮子
|
|
|
+
|
|
|
+- 支撑轮
|
|
|
+
|
|
|
+- 雷达激光
|
|
|
+
|
|
|
+- IMU模块
|
|
|
+
|
|
|
+这五个部件之间的固定方式为:
|
|
|
+
|
|
|
+```mermaid
|
|
|
+graph
|
|
|
+A[左轮] -->C[躯体]
|
|
|
+B[右轮] -->C[躯体]
|
|
|
+D[IMU] -->C[躯体]
|
|
|
+E[雷达] -->C[躯体]
|
|
|
+F[支撑轮子] -->C[躯体]
|
|
|
+```
|
|
|
+
|
|
|
+我们把左轮,右轮、支撑轮子,IMU和雷达部件称为机器人的Link
|
|
|
|
|
|
+**而Link和Link之间的连接部分称之为Joint关节**
|
|
|
|
|
|
-1.2 两种关键组件
|
|
|
+接着我们给每个link和joint取个名字。
|
|
|
|
|
|
-观察一个机器人
|
|
|
+```mermaid
|
|
|
+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进行详细的介绍。
|
|
|
|
|
|
+
|
|
|
|
|
|
## 2.Link介绍
|
|
|
|
|
|
+上面我们介绍完了link,那一个link该怎么写呢?
|
|
|
+
|
|
|
+我们来看一个base_link的,通过link标签即可声明一个link,属性name指定部件名字
|
|
|
+
|
|
|
+```xml
|
|
|
+ <link name="base_link">
|
|
|
+
|
|
|
+ </link>
|
|
|
+```
|
|
|
+
|
|
|
+通过两行代码就可以定义好base_link,但现在的base_link是空的,我们还要声明我们的base_link长什么样,通过`visual`子标签就可以声明出来机器人的visual形状。
|
|
|
+
|
|
|
+```xml
|
|
|
+ <!-- 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为机器人关节,机器人关节用于连接两个机器人部件,主要写明父子关系
|
|
|
+
|
|
|
+- 父子之间的连接类型,是否固定的,可以旋转的等
|
|
|
+
|
|
|
+- 父部件名字
|
|
|
+- 子部件名字
|
|
|
+- 父子之间相对位置
|
|
|
+- 父子之间的旋转轴,绕哪个轴转
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+比如我们再建立一个雷达部件`laser_link`,然后将`laser_link`固定到`base_link`
|
|
|
+
|
|
|
+```xml
|
|
|
+<?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`
|
|
|
+
|
|
|
+```shell
|
|
|
+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
|
|
|
+<?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
|
|
|
+```
|
|
|
+
|
|
|
+```python
|
|
|
+
|
|
|
+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`负责显示机器人的信息
|
|
|
+
|
|
|
+```mermaid
|
|
|
+graph
|
|
|
+A[joint_state_publisher]--joint_states-->B
|
|
|
+B[robot_state_publisher]--robot_de-->C
|
|
|
+C[rviz2]
|
|
|
+
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+### 4.4 修改setup.py
|
|
|
+
|
|
|
+导入头
|
|
|
+
|
|
|
+```python
|
|
|
+from glob import glob
|
|
|
+import os
|
|
|
+```
|
|
|
+
|
|
|
+加入目录安装
|
|
|
+
|
|
|
+```python
|
|
|
+('share/ament_index/resource_index/packages',
|
|
|
+['resource/' + package_name]),
|
|
|
+('share/' + package_name, ['package.xml']),
|
|
|
+```
|
|
|
+
|
|
|
+完整
|
|
|
+
|
|
|
+```python
|
|
|
+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名称如下,即可看到机器人的模型显示
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+此时看看节点关系图
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+## 5.本节练习
|
|
|
+
|
|
|
+练习1:尝试将机器人的雷达固定位置向车体的y轴负方向移动5cm,并在rviz中显示出来
|
|
|
+
|
|
|
+练习2:尝试在URDF中添加imu_link并使用imu_joint将其固定在车体的上表面中心,imu采用的几何形状为box。长宽高各是1cm
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
参考文档
|
|
|
|
|
|
+- [urdf/XML/link - ROS Wiki](http://wiki.ros.org/urdf/XML/link)
|
|
|
+
|
|
|
- http://docs.ros.org/en/foxy/Tutorials/URDF/URDF-Main.html
|
|
|
-- https://sychaichangkun.gitbooks.io/ros-tutorial-icourse163/content/chapter8/8.5.html
|
|
|
|
|
|
--------------
|
|
|
|