本文在Ubuntu18.04 + ROS melodic环境下完成,其他ROS版本类似。

有很多方法可以启动gazebo,将世界模型以及将机器人模型生成到仿真环境中。在本教程中,我们介绍了ROS的处理方式:将urdf文件存储在ROS包中,使用roslaunch命令启动gazebo和urdf模型。

一、使用roslaunch打开世界模型

1、roslaunch简介

roslaunch工具是启动ROS节点和机器人的标准方法,我们通过该工具在gazeb中打开一个空白世界:

$ roslaunch gazebo_ros empty_world.launch

你也可以在roslaunch文件中加入以下参数去改变gazebo的行为:

  • paused
以暂停状态启动gazebo(默认为false)
  • 。use_sim_time
告诉ROS节点需要的时间来获取在ROS主题/clock上发布的凉亭发布的仿真时间(默认为true)。
  • gui
启动gazebo的用户界面窗口(默认为true)。
  • debug
使用gdb在调试模式下启动gzserver(gazebo服务器)(默认为false)。
  • verbose
使用--verbose运行gzserver和gzclient,将错误和警告打印到终端(默认为false)。
  • server_required
gzserver(gazebo Server)退出时终止启动脚本(默认为false)。
  • gui_required
gzclient(用户界面窗口)退出时终止启动脚本(默认为false)

通常以下这些参数的默认值就是您所需要的:

$ roslaunch gazebo_ros empty_world.launch paused:=true use_sim_time:=false gui:=true throttled:=false recording:=false debug:=true verbose:=true gui_required:=true

2、打开其他世界模型

gazebo_ros软件包中已经包含了其他世界的demo,你可以逐一运行察看,包括:

$ roslaunch gazebo_ros willowgarage_world.launch
$ roslaunch gazebo_ros mud_world.launch
$ roslaunch gazebo_ros shapes_world.launch
$ roslaunch gazebo_ros rubble_world.launch

注意,在mud_world.launch中启动了一个简单的联合机制。mud_world.launch的启动文件包含以下内容:

<launch>
  <!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="worlds/mud.world"/> <!-- Note: the world_name is with respect to GAZEBO_RESOURCE_PATH environmental variable -->
    <arg name="paused" value="false"/>
    <arg name="use_sim_time" value="true"/>
    <arg name="gui" value="true"/>
    <arg name="recording" value="false"/>
    <arg name="debug" value="false"/>
  </include>
</launch>

在此启动文件中,我们从empty_world.launch继承了大多数必要的功能。我们唯一需要更改的参数是world_name参数,用empty.world文件替换了mud.world文件。其他参数仅设置为其默认值。

3、世界文件

现在我们来看一下mud.world文件的内容。mud_world的前几个组成部分如下所示:

<sdf version="1.4">
  <world name="default">
    <include>
      <uri>model://sun</uri>
    </include>
    <include>
      <uri>model://ground_plane</uri>
    </include>
    <include>
      <uri>model://double_pendulum_with_base</uri>
      <name>pendulum_thick_mud</name>
      <pose>-2.0 0 0 0 0 0</pose>
    </include>
    ...
  </world>
</sdf>

在这个文件片段中,您可以看到引用了三个模型。 在您当地的gazebo模型数据库中搜索这三个模型。 如果未在此处找到,则会自动从Gazebo的在线数据库中下载。

关于如何使用gazebo搭建一个世界,并生成world文件,您可以查阅官网的详细教程:

你可以查看所有的世界文件,世界文件位于您的gazebo资源路径的/worlds目录中。该路径的位置取决于安装gazebo的方式以及所用系统的类型。要查找gazebo资源的位置,请使用以下命令:

$ env | grep GAZEBO_RESOURCE_PATH

二、创建自己的gazebo ROS程序包

1、文件层次结构

在讨论如何将机器人生成到gazebo中之前,我们将讨论将ROS与gazebo一起使用的文件层次结构标准。

我们将假定您的catkin工作区名为catkin_ws,您可以将其替换为您工作空间的名称。根据ROS标准,与机器人的模型和说明有关的所有内容都位于一个名为/MYROBOT_description的功能包中,与gazebo一起使用的所有世界文件和启动文件都位于一个名为
/MYROBOT_gazebo的功能包中。用小写字母的机器人名称替换“MYROBOT”,使用这两个功能包。 层次结构应如下所示:

../catkin_ws/src
    /MYROBOT_description
        package.xml
        CMakeLists.txt
        /urdf
            MYROBOT.urdf
        /meshes
            mesh1.dae
            mesh2.dae
            ...
        /materials
        /cad
     ...
    /MYROBOT_gazebo
        /launch
            MYROBOT.launch
        /worlds
            MYROBOT.world
        /models
            world_object1.dae
            world_object2.stl
            world_object3.urdf
        /materials
        /plugins

2、创建自定义世界文件

您可以在自己的ROS功能包中创建自己的机器人和world文件。 在这个教程中,我们将创建一个带有地面,太阳和加油站的空世界。以下是我们推荐的约定:

  • 创建MYROBOT_gazebo功能包
  • 在此功能包中,创建launch文件夹
  • 在launch文件夹中,创建一个MYROBOT.launch文件,其中包含以下内容(不包括默认参数):
  • <launch>
      <!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
      <include file="$(find gazebo_ros)/launch/empty_world.launch">
        <arg name="world_name" value="$(find MYROBOT_gazebo)/worlds/MYROBOT.world"/>
        <!-- more default parameters can be changed here -->
      </include>
    </launch>
  • 在MYROBOT_gazebo功能包中,创建一个worlds文件夹,并创建一个具有以下内容的MYROBOT.world文件:
  • <?xml version="1.0" ?>
    <sdf version="1.4">
      <world name="default">
        <include>
          <uri>model://ground_plane</uri>
        </include>
        <include>
          <uri>model://sun</uri>
        </include>
        <include>
          <uri>model://gas_station</uri>
          <name>gas_station</name>
          <pose>-2.0 7.0 0 0 0 0</pose>
        </include>
      </world>
    </sdf>
  • 现在,您应该可以使用以下命令启动自定义世界:

    $ roslaunch MYROBOT_gazebo MYROBOT.launch

    您应该看到以下世界模型(用鼠标上的滚轮放大):

  • 此时,您可以通过gazebo GUI插入其他模型,并将新的世界模型保存为world文件,点击“File”->“Save”将已编辑的世界导出。

    在本教程的其余部分中,您的MYROBOT_gazebo空世界需要持续运行(不要关闭终端)。

    三、使用roslaunch导入urdf机器人

    当我们拥有了世界模型后,接着我们要将机器人导入世界中,要使用roslaunch工具,有两种方法可以将urdf机器人模型加载到gazebo中:

    • ROS服务调用生成方法
    第一种方法可以使您的机器人的ROS软件包在计算机和存储库检出之间更加便携。它可以让您保持机器人相对于ROS包路径的位置,而且还要求您使用小的(python)脚本进行ROS服务调用。
    • 模型数据库方法
    第二种方法允许您将机器人包含在world文件中,该文件看起来更干净,更方便,但需要您通过设置环境变量将机器人添加到gazebo模型数据库中。

    我们将介绍两种方法。 总的来说,推荐的方法是使用“ ROS服务调用生成方法”

    1、ROS服务调用生成方法

    此方法使用一个名为spawn_model的小型python脚本向gazebo_ros ROS节点(在rostopic名称空间中简称为“gazebo”)发出服务调用请求,以将自定义urdf添加到gazebo中。spawn_model脚本位于gazebo_ros软件包中。您可以通过以下方式使用此脚本:

  • $ rosrun gazebo_ros spawn_model -file `rospack find MYROBOT_description`/urdf/MYROBOT.urdf -urdf -x 0 -y 0 -z 1 -model MYROBOT
  • (1)urdf模型示例

    如果您没有自定义的urdf模型文件,您可以从Rethink Robotics的baxter_common存储库中下载baxter_description包。 通过运行以下命令将此包放入catkin工作区:

    $ git clone https://github.com/RethinkRobotics/baxter_common.git

    现在,您应该在baxter_description/urdf/中有一个名为baxter.urdf的urdf文件,然后运行下方命令:

  • $ rosrun gazebo_ros spawn_model -file `rospack find baxter_description`/urdf/baxter.urdf -urdf -z 1 -model baxter
  • 然后,您应该看到类似以下的内容:
  • 如果要将其直接集成到世界环境的launch文件中,请打开MYROBOT_gazebo/launch
    /MYROBOT.launch文件,并在</launch>标记之前添加以下内容:
  • <!-- Spawn a robot into Gazebo -->
    <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-file $(find baxter_description)/urdf/baxter.urdf -urdf -z 1 -model baxter" />
  • 通过此方法,就可以同时导入世界模型和urdf模型了。启动此文件,您应该看到与使用rosrun相同的结果。

    $ roslaunch MYROBOT_gazebo MYROBOT.launch

    (2)xarco模型示例

    如果您的urdf不是XML格式,而是XACRO格式,则可以对启动文件进行类似的修改。 您可以通过安装以下程序包来运行此PR2示例:

    $ sudo apt-get install ros-melodic-pr2-common

    然后将其添加到本教程先前创建的启动文件MYROBOT_gazebo/launch/MYROBOT.launch中:

    <!-- Convert an xacro and put on parameter server -->
    <param name="robot_description" command="$(find xacro)/xacro.py $(find pr2_description)/robots/pr2.urdf.xacro" />
    
    <!-- Spawn a robot into Gazebo -->
    <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-param robot_description -urdf -model pr2" />

    启动此文件,您应该在加油站中看到PR2,如图所示:

    $ roslaunch MYROBOT_gazebo MYROBOT.launch

    2、模型数据库方法

    将机器人生成到gazebo中的第二种方法允许您将机器人包括在world文件中,这看起来更干净、方便,但还需要您通过设置环境变量将机器人添加到gazebo模型数据库中。urdf功能包路径不能直接在world文件中使用,因为gazebo没有ROS功能包的概念。

    要实现此方法,您必须创建一个仅包含单个机器人的新模型数据库。这不是将urdf加载到给gazebo中的最干净的方法,但是不必在计算机上保留机器人urdf的两个副本。

    我们将假定您的ROS工作空间文件层次结构已按照上述部分进行了设置。唯一的区别是,现在将model.config文件添加到您的MYROBOT_description包中,如下所示:b

    ../catkin_ws/src
        /MYROBOT_description
            package.xml
            CMakeLists.txt
            model.config
            /urdf
                MYROBOT.urdf
            /meshes
                mesh1.dae
                mesh2.dae
                ...
            /materials
            /plugins
            /cad

    通过以下文件夹/文件,此层次结构特别适合用作gazebo模型数据库:

    • /home/user/catkin_ws/src,这被视为gazebo模型数据库的位置
    • /MYROBOT_description,该目录被视为单个gazebo模型文件夹
    • model.config,这是gazebo在其数据库中查找此模型所需的配置文件
    • MYROBOT.urdf,这是您的机器人描述文件
    • /meshes,将.stl或.dae文件放在此处,就像使用常规urdf一样

    (1)model.config

    每个模型必须在模型的根目录中具有一个model.config文件,其中包含有关该模型的元信息:

    <?xml version="1.0"?>
    <model>
      <name>MYROBOT</name>
      <version>1.0</version>
      <sdf>urdf/MYROBOT.urdf</sdf>
      <author>
        <name>My name</name>
        <email>name@email.address</email>
      </author>
      <description>
        A description of the model.
      </description>
    </model>

    2)环境变量

    最后,您需要在.bashrc文件中添加一个环境变量,该变量告诉gazebo在哪里寻找模型数据库。使用您选择的编辑器编辑“〜/.bashrc”。检查是否已经定义了GAZEBO_MODEL_
    PATH。如果已经有一个,请使用分号将其追加。 假设您的catkin工作区在〜/catkin_ws/中,您的路径应类似于:

    $ export GAZEBO_MODEL_PATH=/home/user/catkin_ws/src/

    现在,通过启动gazebo来测试是否正确配置了新的gazebo模型数据库:

    $ gazebo

    然后点击左侧的“insert”标签。 您可能会看到几个不同的下拉列表,它们代表系统上可用的不同模型数据库,包括在线数据库。 找到与您的机器人对应的数据库,打开子菜单,单击您的机器人的名称,然后使用鼠标在gazebo中选择一个位置来放置机器人。

    (3)通过roslaunch启动

    模型数据库方法的优点在于,现在您可以将机器人直接包含在world文件中,而无需使用ROS包路径。在MYROBOT_gazebo/launch文件夹中,编辑具有以下内容MYROBOT.world文件:

    <?xml version="1.0" ?>
    <sdf version="1.4">
      <world name="default">
        <include>
          <uri>model://ground_plane</uri>
        </include>
        <include>
          <uri>model://sun</uri>
        </include>
        <include>
          <uri>model://gas_station</uri>
          <name>gas_station</name>
          <pose>-2.0 7.0 0 0 0 0</pose>
        </include>
        <include>
          <uri>model://MYROBOT_description</uri>
        </include>
      </world>
    </sdf>

    现在,您应该可以使用以下命令,将加油站和机器人同时启动到gazebo的自定义世界:

    $ roslaunch MYROBOT_gazebo MYROBOT.launch

    这种方法的缺点是打包的MYROBOT_description和MYROBOT_gazebo在计算机之间不那么容易移植,您必须首先在任何新系统上设置GAZEBO_MODEL_PATH才能使用这些ROS功能包。