一、概述:
1.机器人系统仿真:
是通过计算机对实体机器人系统进行模拟的技术,在 ROS 中,仿真实现涉及的内容主要有三:对机器人建模(URDF)、创建仿真环境(Gazebo)以及感知环境(Rviz)等系统性实现。
(1)仿真优势:低成本、高效、高安全性。
(2)仿真缺陷:仿真器所使用的物理引擎目前还不能够完全精确模拟真实世界的物理情况;仿真器构建的是关节驱动器(电机&齿轮箱)、传感器与信号通信的绝对理想情况,目前不支持模拟实际硬件缺陷或者一些临界状态等情形。
2.机器人系统仿真所需组件:
(1)创建机器人模型:
URDF (Unified Robot Description Format,统一(标准化)机器人描述格式) ,以 XML 的方式描述机器人的部分结构,比如底盘、摄像头、激光雷达、机械臂以及不同关节的自由度,该文件可以被 C++ 内置的解释器转换成可视化的机器人模型,是 ROS 中实现机器人仿真的重要组件。
(2)显示各传感器信息:
rviz(ROS Visualization Tool,ROS的三维可视化工具),它的主要目的是以三维方式显示ROS消息,可以将数据进行可视化表达。例如:可以显示机器人模型,可以无需编程就能表达激光测距仪(LRF)传感器中的传感器到障碍物的距离,Kinect或Xtion等三维距离传感器的点云数据(PCD, Point Cloud Data),从相机获取的图像值等。
(3)搭建仿真环境:
Gazebo是一款3D动态模拟器,用于显示机器人模型并创建仿真环境,能够在复杂的室内和室外环境中准确有效地模拟机器人。与游戏引擎提供高保真度的视觉模拟类似,Gazebo提供高保真度的物理模拟,其提供一整套传感器模型,以及对用户和程序非常友好的交互方式。
二、URDF语法讲解:
1.将URDF集成进rviz基本流程:
URDF 不能单独使用,需要结合 Rviz 或 Gazebo。URDF 只是一个文件,需要在 Rviz 或 Gazebo中渲染成图形化的机器人模型。
(1)创建功能包,并导入依赖:
在该功能包下创建四个文件夹:
1)urdf:用于存放机器人模型的URDF或xacro文件;
2)meshes:用于放置URDF中引用的模型渲染文件;
3)launch:用于保存相关启动文件;
4)config:用于保存rviz的配置文件。
(2)编写urdf文件:
在功能包中新建子文件夹:urdf,添加一个.urdf文件,内容如下:
<robot name="mycar">
<link name="base_link">
<visual>
<geometry>
<box size="0.5 0.2 0.1" />
</geometry>
</visual>
</link>
</robot>
(3)在launch文件中集成URDF与rviz:
在功能包中新建子文件夹:launch,添加一个.launch文件,内容如下:
<launch>
<!-- 设置参数 -->
<param name="robot_description" textfile="$((find learning_urdf)/urdf/mycar.urdf" />
<!-- 启动 rviz -->
<node pkg="rviz" type="rviz" name="rviz" />
</launch>
(4)通过launch文件启动rviz,并加载机器人模型:
PS:编译过程中有可能出现因缺少xacro的包导致编译失败
解决方式是输入以下安装指令安装xacro相关包:
sudo apt-get install ros-noetic-xacro
(5)rviz 启动后,会发现并没有机器人模型,这是因为默认情况下没有添加机器人显示组件,需要手动添加,添加方式如下:
(6)Fixed Frame处要将默认值map改为urdf文件中机器人底座的name(此处设置的是base_link):
(7)重复启动launch文件时,Rviz 之前的组件配置信息不会自动保存,需要重复执行步骤4的操作,为了方便使用,可以使用如下方式优化:
1)在功能包中新建子文件夹config:
2)将文件另存为一个.rviz文件:
2.urdf语法:
URDF文件是一个标准的XML文件,在ROS中预定义了一系列的标签用于描述机器人模型机器人模型可能较为复杂,但是ROS的URDF中机器人的组成却是较为简单,URDF中有四类标签:
<robot>:根标签,类似于 launch文件中的launch标签;
<link>:连杆标签;
<joint>:关节标签;
<gazebo>: 集成gazebo需要使用的标签。
(1)<robot>标签:
<robot>标签是完整机器人模型最顶层标签,<link>和<joint>标签都必须包含在<robot>标签内。如下图所示,一个完整的机器人模型由一系列<link>和<joint>组成:
<robot>标签内可以设置机器人的名称,其基本语法如下:
<robot name="<name of the robot>">
<link>......</link>
<link>......</link>
<joint>......</joint>
<joint>......</joint>
</robot>
(2)<link>标签:
<link>标签用于描述机器人某个部件的外观和物理属性,如形状、尺寸、颜色、惯性矩阵、碰撞参数等。机器人的link结构一般如下图所示:
基本的URDF描述语法如下:
<link name="<link name>">
<inertial>......</inertial>
<visual>......</visual>
<collision>......</collision>
</link>
子标签的描述内容如下:
示例:demo02_link.urdf
<link name="base_link">
<visual>
<!--形状-->
<geometry>
<!--长方体的长宽高-->
<!--<box size="0.5 0.3 0.1" />-->
<!--圆柱,半径和长度-->
<!--<cylinder radius="0.5" length="0.1" />-->
<!--球体,半径-->
<!--<sphere radius="0.3" />-->
<!--皮肤-->
<!--<mesh filename="package://learning_urdf/meshes/autolabor_mini.stl" />-->
</geometry>
<!--xyz坐标 rpy翻滚、俯仰、偏航(弧度)-->
<origin xyz="0 0 0" rpy="0 0 0" />
<!--颜色:r=red g=green b=blue a=alpha-->
<material name="black" >
<color rgba="0.7 0.5 0 0.5" />
</material>
</visual>
</link>
(3)<joint>标签:
<joint>标签用于描述机器人关节的运动学和动力学属性,包括关节运动的位置和速度限制。
根据机器人的关节运动形式,可以将其分为六种类型:
与人的关节一样,机器人关节(joint)的主要作用是连接两个刚体(link),这两个link分别称为parent link和child link,如下图所示:
<joint>标签的描述语法如下:
<joint name="<name of the joint>" type="<type of the joint>">
<parent link="parent_link" />
<child link="child_link" />
<calibration .../>
<dynamics damping .../>
<limit effort .../>
...
</joint>
在这些joint的属性中,必须指定joint的parent link和child link,其他属性可选:
1)<parent link>:强制的属性,父级连杆的名字,是这个link在机器人结构树中的名字。
2)<child link>:强制的属性,子级连杆的名字,是这个link在机器人结构树中的名字。
3)<origin>:xyz=各轴线上的偏移量 rpy=各轴线上的偏移弧度。
4)<axis>:xyz用于设置围绕哪个关节轴运动。
5)<calibration>:关节的参考位置,用来校准关节的绝对位置。
6)<dynamics>:用于描述关节的物理属性,例如阻尼值、物理静摩擦力等,经常在动力学仿真中用到。
7)<limit>:用于描述运动的一些极限值,包括关节运动的上下限位置、速度限制、力矩限制等。
8)<mimic>:用于描述该关节与已有关节的关系。
9)<safety_controller>:用于描述安全控制器参数。
(4)<gazebo>标签:
<gazebo>标签用于描述机器人在Gazebo模型中仿真所需要的参数,包括机器人材料的属性、Gazebo插件等。该标签不是机器人模型必须的部分,只有在Gazebo仿真时才需要加入。
基本语法如下:
<gazebo reference="link_1">
<material>Gazebo/Black</material>
</gazebo>
3.(练习)创建机器人模型,底盘为长方体,在长方体的上方安装一摄像头,摄像头可以沿着z轴360度旋转:
(1)编写demo03_joint.urdf文件:
<!--设置机器人底盘,并添加摄像头-->
<robot name="mycar" >
<!--1.底盘 link-->
<link name="base_link">
<visual>
<geometry>
<box size="0.3 0.2 0.1" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="car_color">
<color rgba="0.8 0.5 0 0.5" />
</material>
</visual>
</link>
<!--2.摄像头 link-->
<link name="camera">
<visual>
<geometry>
<box size="0.02 0.05 0.05" />
</geometry>
<origin xyz="0 0 0.025" rpy="0 0 0" />
<material name="camera_color">
<color rgba="0 0 1 0.5" />
</material>
</visual>
</link>
<!--3.关节 joint-->
<joint name="camera2base" type="continuous">
<parent link="base_link" />
<child link="camera" />
<!--设置偏移量-->
<origin xyz="0.13 0 0.05" rpy="0 0 0" />
<!--设置关节旋转参考坐标轴-->
<axis xyz="0 0 1" />
</joint>
</robot>
(2)编写launch文件:
joint_state_publisher节点:可以发布每个joint的状态。
robot_state_publisher节点:将机器人各个link、joint之间的关系,通过TF的形式整理成三维姿态信息发布出去。
<launch>
<!--1.在参数服务器载入urdf文件-->
<param name="robot_description" textfile="$(find learning_urdf)/urdf/demo03_joint.urdf" />
<!--2.启动rviz-->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find learning_urdf)/config/show_mycar.rviz"/>
<!--rviz显示urdf时,必须发布不同部件之间的坐标系关系-->
<!--ROS中已经提供了机器人模型显示发布的相关节点(两个)-->
<!--关节状态发布节点-->
<node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher"/>
<!--机器人状态发布节点-->
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher"/>
<!--添加控制关节运动的节点-->
<node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui"/>
</launch>
(3)运行:
PS:使用launch文件启动rviz时,可能出现如下报错
解决方案 :缺少依赖包,按指令安装以下依赖包即可
sudo apt-get install ros-noetic-robot-state-publisher
sudo apt-get install ros-noetic-joint-state-publisher
sudo apt-get install ros-noetic-joint-state-publisher-gui
补充完以上依赖包后,通过launch文件打开rviz,发现之前存在的status错误全部解决了。
4.base_footprint优化urdf:
之前实现的机器人模型是半沉到地下的,因为默认情况下: 底盘的中心点位于地图原点上,所以会导致这种情况产生。
优化策略:将初始link设置为一个尺寸极小的link(比如半径为0.001m的球体,或边长0.001m的立方体),然后再在初始 link上添加底盘等刚体,这个初始link一般称之为 base_footprint。
<!--base_footprint-->
<link name="base_footprint">
<visual>
<geometry>
<box size="0.001 0.001 0.001" />
</geometry>
</visual>
</link>
<!--关联baes_link与base_footprint-->
<joint name="link2footprint" type="fixed">
<parent link="base_footprint" />
<child_link="base_link" />
<!--设置偏移量-->
<origin xyz="0 0 0.05" rpy="0 0 0" />
</joint>
base_footprint的相关链接:
DAY5-URDF优化 简单小练习 工具_Zima Blue?的博客-CSDN博客
【ROS_URDF】小车+摄像头+优化footprint的urdf文件,带中文注释_Baily24的博客-CSDN博客
5.(课后作业)urdf文件编写练习:
要求:
(1)新建文件,demo05_test.urdf,并与launch文件集成;
(2)创建一个四轮圆柱状机器人模型,机器人参数如下:底盘为圆柱状,半径 10cm,高 8cm,四轮由两个驱动轮和两个万向支撑轮组成,两个驱动轮半径为 3.25cm,轮胎宽度1.5cm,两个万向轮为球状,半径 0.75cm,底盘离地间距为 1.5cm,与万向轮直径一致(注意joint偏移量的计算)。
作业过程:
(1)创建urdf文件:
<robot name="mycar">
<!-- 设置 base_footprint -->
<link name="base_footprint">
<visual>
<geometry>
<sphere radius="0.001" />
</geometry>
</visual>
</link>
<!-- 添加底盘 -->
<!--
参数
形状:圆柱
半径:10 cm
高度:8 cm
离地:1.5 cm
-->
<link name="base_link">
<visual>
<geometry>
<cylinder radius="0.1" length="0.08" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="yellow">
<color rgba="0.8 0.3 0.1 0.5" />
</material>
</visual>
</link>
<joint name="base_link2base_footprint" type="fixed">
<parent link="base_footprint"