• 【ROS进阶篇】第十讲 基于Gazebo的URDF集成仿真流程及实例


    【ROS进阶篇】第十讲 基于Gazebo的URDF集成仿真流程及实例

    在这里插入图片描述

    前言

    在上一节博客中我们系统的学习了如何在RVIZ中使用Arbotix实现对于使用URDF文件生成的机器人模型的运动控制,并通过一个简单的运动实例讲解了具体的仿真流程,本节内容主要聚焦于如何在Gazebo中集成URDF文件对应的机器人模型,为今后的联合仿真打下基础,也初步认识了Gazebo仿真软件该如何使用。
    在这里插入图片描述


    \qquad

    一、URDF与Gazebo的基本集成流程


    1. 基本流程介绍


    第一步,创建功能包:

    \qquad 依赖项:urdf、xacro、gazebo_ros、gazebo_ros_control、gazebo_plugins等


    第二步,编写URDF文件组建机器人模型:

    
    
    <robot name="mycar">
        <link name="base_link">
            <visual>
                <geometry>
                    <box size="0.5 0.2 0.1" />
                geometry>
                <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
                <material name="yellow">
                    <color rgba="0.5 0.3 0.0 1" />
                material>
            visual>
            <collision>
                <geometry>
                    <box size="0.5 0.2 0.1" />
                geometry>
                <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            collision>
            <inertial>
                <origin xyz="0 0 0" />
                <mass value="6" />
                <inertia ixx="1" ixy="0" ixz="0" iyy="1" iyz="0" izz="1" />
            inertial>
        link>
        <gazebo reference="base_link">
            <material>Gazebo/Blackmaterial>
        gazebo>
    
    robot>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    注意:在此处URDF文件有关键要求,对于标签的使用存在与Rviz外的额外要求,在集成相关设置中具体讲述;


    第三步,启动Gazebo并显示模型:launch文件编写

    <launch>
    
        
        <param name="robot_description" textfile="$(find demo02_urdf_gazebo)/urdf/urdf01_helloworld.urdf" />
    
        
        <include file="$(find gazebo_ros)/launch/empty_world.launch" />
    
        
        <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description"  />
        
        
    
    launch>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2. 集成相关设置


    第一项,必须添加 collision 标签

    • 原因:对于Gazebo仿真来说,先要实现环境的完整仿真,必然涉及到碰撞检测,就需要添加collision提供依据;

    \qquad 当机器人的link属于标准几何体时,碰撞设置与link的visual属性一致即可;


    第二项,必须添加 inertial 标签

    • 原因:此标签标注了当前机器人某个刚体部分的惯性矩阵,用于一些力学相关的仿真计算,除了 base_footprint 外,机器人的每个刚体部分都需要设置惯性矩阵,且此矩阵必须准确得到,否则会出现抖动等现象;

    • 设置方法:结合link的质量与外形参数动态生成,标准矩阵举例如下:

    1. 球体惯性矩阵
    
       <xacro:macro name="sphere_inertial_matrix" params="m r">
           <inertial>
               <mass value="${m}" />
               <inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0"
                   iyy="${2*m*r*r/5}" iyz="0" 
                   izz="${2*m*r*r/5}" />
           inertial>
       xacro:macro>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 圆柱惯性矩阵
    <xacro:macro name="cylinder_inertial_matrix" params="m r h">
           <inertial>
               <mass value="${m}" />
               <inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0"
                   iyy="${m*(3*r*r+h*h)/12}" iyz = "0"
                   izz="${m*r*r/2}" /> 
           inertial>
       xacro:macro>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 立方体惯性矩阵
    <xacro:macro name="Box_inertial_matrix" params="m l w h">
          <inertial>
                 <mass value="${m}" />
                 <inertia ixx="${m*(h*h + l*l)/12}" ixy = "0" ixz = "0"
                      iyy="${m*(w*w + l*l)/12}" iyz= "0"
                      izz="${m*(w*w + h*h)/12}" />
          inertial>
      xacro:macro>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    第三项,使用gazebo标签重新标注颜色

    • 原因:之前的颜色设置为了方便调试包含透明度,而在gazebo仿真环境下没有此选项;
    • 设置方法:使用指定标签显示,示例如下:
    		<gazebo reference="link节点名称">
    		     <material>Gazebo/Bluematerial>
    		gazebo>
    
    • 1
    • 2
    • 3

    二、集成仿真实例


    第一步,编写惯性矩阵算法相关的xacro文件

    <robot name="base" xmlns:xacro="http://wiki.ros.org/xacro">
        
        <xacro:macro name="sphere_inertial_matrix" params="m r">
            <inertial>
                <mass value="${m}" />
                <inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0"
                    iyy="${2*m*r*r/5}" iyz="0" 
                    izz="${2*m*r*r/5}" />
            inertial>
        xacro:macro>
    
        <xacro:macro name="cylinder_inertial_matrix" params="m r h">
            <inertial>
                <mass value="${m}" />
                <inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0"
                    iyy="${m*(3*r*r+h*h)/12}" iyz = "0"
                    izz="${m*r*r/2}" /> 
            inertial>
        xacro:macro>
    
        <xacro:macro name="Box_inertial_matrix" params="m l w h">
           <inertial>
                   <mass value="${m}" />
                   <inertia ixx="${m*(h*h + l*l)/12}" ixy = "0" ixz = "0"
                       iyy="${m*(w*w + l*l)/12}" iyz= "0"
                       izz="${m*(w*w + h*h)/12}" />
           inertial>
       xacro:macro>
    robot>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    第二步,对机器人模型中的各link添加相关设置(collision、inertial、颜色)

    \qquad 1. 底盘Xacro文件

    
    
    <robot name="my_base" xmlns:xacro="http://www.ros.org/wiki/xacro">
        
        
        <xacro:property name="PI" value="3.1415926"/>
        
        <material name="black">
            <color rgba="0.0 0.0 0.0 1.0" />
        material>
        
        <xacro:property name="base_footprint_radius" value="0.001" /> 
        <xacro:property name="base_link_radius" value="0.1" /> 
        <xacro:property name="base_link_length" value="0.08" /> 
        <xacro:property name="earth_space" value="0.015" /> 
        <xacro:property name="base_link_m" value="0.5" /> 
    
        
        <link name="base_footprint">
          <visual>
            <geometry>
              <sphere radius="${base_footprint_radius}" />
            geometry>
          visual>
        link>
    
        <link name="base_link">
          <visual>
            <geometry>
              <cylinder radius="${base_link_radius}" length="${base_link_length}" />
            geometry>
            <origin xyz="0 0 0" rpy="0 0 0" />
            <material name="yellow">
              <color rgba="0.5 0.3 0.0 0.5" />
            material>
          visual>
          <collision>
            <geometry>
              <cylinder radius="${base_link_radius}" length="${base_link_length}" />
            geometry>
            <origin xyz="0 0 0" rpy="0 0 0" />
          collision>
          <xacro:cylinder_inertial_matrix m="${base_link_m}" r="${base_link_radius}" h="${base_link_length}" />
    
        link>
    
    
        <joint name="base_link2base_footprint" type="fixed">
          <parent link="base_footprint" />
          <child link="base_link" />
          <origin xyz="0 0 ${earth_space + base_link_length / 2 }" />
        joint>
        <gazebo reference="base_link">
            <material>Gazebo/Yellowmaterial>
        gazebo>
    
        
        
        <xacro:property name="wheel_radius" value="0.0325" />
        <xacro:property name="wheel_length" value="0.015" />
        <xacro:property name="wheel_m" value="0.05" /> 
    
        
        <xacro:macro name="add_wheels" params="name flag">
          <link name="${name}_wheel">
            <visual>
              <geometry>
                <cylinder radius="${wheel_radius}" length="${wheel_length}" />
              geometry>
              <origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
              <material name="black" />
            visual>
            <collision>
              <geometry>
                <cylinder radius="${wheel_radius}" length="${wheel_length}" />
              geometry>
              <origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
            collision>
            <xacro:cylinder_inertial_matrix m="${wheel_m}" r="${wheel_radius}" h="${wheel_length}" />
    
          link>
    
          <joint name="${name}_wheel2base_link" type="continuous">
            <parent link="base_link" />
            <child link="${name}_wheel" />
            <origin xyz="0 ${flag * base_link_radius} ${-(earth_space + base_link_length / 2 - wheel_radius) }" />
            <axis xyz="0 1 0" />
          joint>
    
          <gazebo reference="${name}_wheel">
            <material>Gazebo/Redmaterial>
          gazebo>
    
        xacro:macro>
        <xacro:add_wheels name="left" flag="1" />
        <xacro:add_wheels name="right" flag="-1" />
        
        
        <xacro:property name="support_wheel_radius" value="0.0075" /> 
        <xacro:property name="support_wheel_m" value="0.03" /> 
    
        
        <xacro:macro name="add_support_wheel" params="name flag" >
          <link name="${name}_wheel">
            <visual>
                <geometry>
                    <sphere radius="${support_wheel_radius}" />
                geometry>
                <origin xyz="0 0 0" rpy="0 0 0" />
                <material name="black" />
            visual>
            <collision>
                <geometry>
                    <sphere radius="${support_wheel_radius}" />
                geometry>
                <origin xyz="0 0 0" rpy="0 0 0" />
            collision>
            <xacro:sphere_inertial_matrix m="${support_wheel_m}" r="${support_wheel_radius}" />
          link>
    
          <joint name="${name}_wheel2base_link" type="continuous">
              <parent link="base_link" />
              <child link="${name}_wheel" />
              <origin xyz="${flag * (base_link_radius - support_wheel_radius)} 0 ${-(base_link_length / 2 + earth_space / 2)}" />
              <axis xyz="1 1 1" />
          joint>
          <gazebo reference="${name}_wheel">
            <material>Gazebo/Redmaterial>
          gazebo>
        xacro:macro>
    
        <xacro:add_support_wheel name="front" flag="1" />
        <xacro:add_support_wheel name="back" flag="-1" />
    
    
    robot>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144

    \qquad 2. 摄像头Xacro文件

    
    <robot name="my_camera" xmlns:xacro="http://wiki.ros.org/xacro">
        
        <xacro:property name="camera_length" value="0.01" /> 
        <xacro:property name="camera_width" value="0.025" /> 
        <xacro:property name="camera_height" value="0.025" /> 
        <xacro:property name="camera_x" value="0.08" /> 
        <xacro:property name="camera_y" value="0.0" /> 
        <xacro:property name="camera_z" value="${base_link_length / 2 + camera_height / 2}" /> 
    
        <xacro:property name="camera_m" value="0.01" /> 
    
        
        <link name="camera">
            <visual>
                <geometry>
                    <box size="${camera_length} ${camera_width} ${camera_height}" />
                geometry>
                <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
                <material name="black" />
            visual>
            <collision>
                <geometry>
                    <box size="${camera_length} ${camera_width} ${camera_height}" />
                geometry>
                <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            collision>
            <xacro:Box_inertial_matrix m="${camera_m}" l="${camera_length}" w="${camera_width}" h="${camera_height}" />
        link>
    
        <joint name="camera2base_link" type="fixed">
            <parent link="base_link" />
            <child link="camera" />
            <origin xyz="${camera_x} ${camera_y} ${camera_z}" />
        joint>
        <gazebo reference="camera">
            <material>Gazebo/Bluematerial>
        gazebo>
    robot>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    \qquad 3. 雷达Xacro文件

    
    <robot name="my_laser" xmlns:xacro="http://wiki.ros.org/xacro">
    
        
        <xacro:property name="support_length" value="0.15" /> 
        <xacro:property name="support_radius" value="0.01" /> 
        <xacro:property name="support_x" value="0.0" /> 
        <xacro:property name="support_y" value="0.0" /> 
        <xacro:property name="support_z" value="${base_link_length / 2 + support_length / 2}" /> 
    
        <xacro:property name="support_m" value="0.02" /> 
    
        <link name="support">
            <visual>
                <geometry>
                    <cylinder radius="${support_radius}" length="${support_length}" />
                geometry>
                <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
                <material name="red">
                    <color rgba="0.8 0.2 0.0 0.8" />
                material>
            visual>
    
            <collision>
                <geometry>
                    <cylinder radius="${support_radius}" length="${support_length}" />
                geometry>
                <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            collision>
    
            <xacro:cylinder_inertial_matrix m="${support_m}" r="${support_radius}" h="${support_length}" />
    
        link>
    
        <joint name="support2base_link" type="fixed">
            <parent link="base_link" />
            <child link="support" />
            <origin xyz="${support_x} ${support_y} ${support_z}" />
        joint>
    
        <gazebo reference="support">
            <material>Gazebo/Whitematerial>
        gazebo>
    
        
        <xacro:property name="laser_length" value="0.05" /> 
        <xacro:property name="laser_radius" value="0.03" /> 
        <xacro:property name="laser_x" value="0.0" /> 
        <xacro:property name="laser_y" value="0.0" /> 
        <xacro:property name="laser_z" value="${support_length / 2 + laser_length / 2}" /> 
    
        <xacro:property name="laser_m" value="0.1" /> 
    
        
        <link name="laser">
            <visual>
                <geometry>
                    <cylinder radius="${laser_radius}" length="${laser_length}" />
                geometry>
                <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
                <material name="black" />
            visual>
            <collision>
                <geometry>
                    <cylinder radius="${laser_radius}" length="${laser_length}" />
                geometry>
                <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            collision>
            <xacro:cylinder_inertial_matrix m="${laser_m}" r="${laser_radius}" h="${laser_length}" />
        link>
    
        <joint name="laser2support" type="fixed">
            <parent link="support" />
            <child link="laser" />
            <origin xyz="${laser_x} ${laser_y} ${laser_z}" />
        joint>
        <gazebo reference="laser">
            <material>Gazebo/Blackmaterial>
        gazebo>
    robot>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    \qquad 4. 组合Xacro文件

    
    <robot name="my_car_camera" xmlns:xacro="http://wiki.ros.org/xacro">
        <xacro:include filename="my_head.urdf.xacro" />
        <xacro:include filename="my_base.urdf.xacro" />
        <xacro:include filename="my_camera.urdf.xacro" />
        <xacro:include filename="my_laser.urdf.xacro" />
    robot>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    第三步,编写launch文件,在gazebo中执行

    <launch>
        
        <param name="robot_description" command="$(find xacro)/xacro $(find demo02_urdf_gazebo)/urdf/xacro/my_base_camera_laser.urdf.xacro" />
        
        <include file="$(find gazebo_ros)/launch/empty_world.launch" />
    
        
        <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description"  />
    launch>
    n" command="$(find xacro)/xacro $(find demo02_urdf_gazebo)/urdf/xacro/my_base_camera_laser.urdf.xacro" />
        
        <include file="$(find gazebo_ros)/launch/empty_world.launch" />
    
        
        <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description"  />
    launch>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    显示效果如下:

    在这里插入图片描述


    三、Gazebo仿真环境搭建

    1. 仿真环境创建方式

    • 方式1:启动Gazebo,添加内置组件创建环境;
    • 方式2:自定义完成,手动绘制仿真环境;
    • 方式3:直接下载第三方/官方仿真环境插件;

    2. 内置组件创建仿真环境

    • 2.1 启动gazebo,添加基本插件

    在这里插入图片描述

    • 2.2 保存仿真环境(.world文件)

    在这里插入图片描述

    • 2.3 编写启动文件
    <launch>
    
        
        <param name="robot_description" command="$(find xacro)/xacro $(find demo02_urdf_gazebo)/urdf/xacro/my_base_camera_laser.urdf.xacro" />
        
        <include file="$(find gazebo_ros)/launch/empty_world.launch">
            <arg name="world_name" value="$(find demo02_urdf_gazebo)/worlds/hello.world" />
        include>
    
        
        <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description"  />
    launch>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3. 手动绘制仿真环境

    • 3.1 Edit->Building Editor,打开构建面板绘制环境

    在这里插入图片描述

    • 3.2 file->save,file->Exit Building Editor,添加插件后保存环境文件;
    • 3.3 编写启动文件(同上)

    4. 直接下载仿真环境

    • 4.1 下载模型库

    这里以官方模型库为例,git下载较为耗时,可自行寻找目标文件

    git clone https://github.com/osrf/gazebo_models
    
    • 1
    • 4.2 应用模板文件
    1. 复制文件:
      将gazebo_models文件夹内容复制到 /usr/share/gazebo-*/models
    2. 重启gazebo,应用文件:
      选择左侧菜单栏的 insert 可以选择并插入相关道具

    总结

    • 声明:本节博客部分参考了CSDN用户赵虚左的ROS教程,本文主要内容是在Gazebo中集成由URDF文件生成的机器人模型,从集成流程出发,深入理解如何使用Gazebo仿真组件对机器人进行仿真,并在文章后部附上了对Gazebo仿真环境的创建以及集成仿真实例,下篇博客将会进入联合仿真阶段,重点探讨如何对传感器数据进行收集并通过Rviz实现可视化分析,敬请期待。

    在这里插入图片描述

  • 相关阅读:
    全国职业技能大赛云计算--高职组赛题卷③(私有云)
    Linux多线程概念及实现
    MIGO新增页签增强
    【Java基础面试三十四】、接口中可以有构造函数吗?
    Pandas 数据变形和模型分析
    django学习记录07——订单案例(复选框+ajax请求)
    Leetcode151. 反转字符串中的单词
    Vue3+node.js实战项目网易云音乐APP(二)
    英伟达jetson硬件(NX,nano,AGX,TX1,TX2)通用开机自动开启风扇教程
    揭秘OLED透明拼接屏的参数规格:分辨率、亮度与透明度全解析
  • 原文地址:https://blog.csdn.net/lc1852109/article/details/126007484