Gazebo機器人仿真學習探索筆記(七)连接ROS

中文稍后补充,先上官方原版教程。ROS Kinetic 搭配 Gazebo 7

附件----官方教程

Tutorial: ROS integration overview

As of Gazebo 1.9 and ROS Hydro, Gazebo no longer has any direct ROS dependencies and is now installed as an Ubuntu stand-alone package. Historically using Gazebo with ROS required a specific version of Gazebo to be built with the legacy 'simulator_gazebo' stack.

To achieve ROS integration with stand-alone Gazebo, a new set of ROS packages named gazebo_ros_pkgs has been created to provide wrappers around the stand-alone Gazebo. They provide the necessary interfaces to simulate a robot in Gazebo using ROS messages, services and dynamic reconfigure Some differences between simulator_gazebo andgazebo_ros_pkgs are the following:

  • Supports the latest stand alone system dependency of Gazebo, that has no ROS bindings on its own
  • Builds with catkin
  • Treats URDF and SDF as equally as possible
  • Reduces code duplication with Gazebo
  • Improves out of the box support for controllers using ros_control
  • Integrates real time controller efficiency improvements from the DARPA Robotics Challenge
  • Cleans up old code from previous versions of ROS and Gazebo

An overview of the gazebo_ros_pkgs interface is in the following diagram:

Gazebo機器人仿真學習探索筆記(七)连接ROS

Upgrading from simulator_gazebo (ROS groovy and earlier)

The following guidelines will help you upgrade your Gazebo-dependent packages from simulator_gazebo for use in your ROS packages:

Catkin

Your previous packages for interfacing with Gazebo with the old simulator_gazebo stack are likely still using the rosbuild build system. With gazebo_ros_pkgs in ROS Hydro, you will first need to "catkinize" your packages to begin migration. See the Catkin Tutorials.

Launch Files

Some changes are required in previously created roslaunch files for starting Gazebo. The best way to update these packages is to review the Using roslaunch files to spawn models in Gazebo tutorial. In a nutshell:

  • Within roslaunch files, pkg="gazebo" needs to be now renamed to pkg="gazebo_ros"
  • gazebo_worlds package has been removed. Most of the world files were rarely used and were not maintained with changes in SDF XML formats. Thus, all worlds have been centralized within the Gazebo project itself, including empty.world.
  • The best way to use Gazebo launch files is to simply inherit/include the master empty_world launch file located in the gazebo_ros package.

CMakeLists.txt

  • Because Gazebo is no longer a ROS package but instead a system dependency, your CMake file might need to be reconfigured. The following is an example CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.3)
project(YOURROBOT_gazebo_plugins) find_package(catkin REQUIRED COMPONENTS
gazebo_ros
) # Depend on system install of Gazebo
find_package(gazebo REQUIRED) include_directories(include ${catkin_INCLUDE_DIRS} ${GAZEBO_INCLUDE_DIRS} ${SDFormat_INCLUDE_DIRS}) # Build whatever you need here
add_library(...) # TODO catkin_package(
DEPENDS
gazebo_ros
CATKIN_DEPENDS
INCLUDE_DIRS
LIBRARIES
)

package.xml

This is the replacement for the rosbuild "manifest.xml":

  • Add dependency on the new gazebo_ros package:
<build_depend>gazebo_ros</build_depend>
<run_depend>gazebo_ros</run_depend>

Running Gazebo

The names of the ROS nodes to launch Gazebo have changed slightly to coincide with the Gazebo executable names:

  • rosrun gazebo_ros gazebo now launch both the Gazebo server and GUI.
  • rosrun gazebo_ros gui has been renamed to rosrun gazebo_ros gzclient
  • rosrun gazebo_ros gzserver has been added

Available nodes to run:

rosrun gazebo_ros gazebo
rosrun gazebo_ros gzserver
rosrun gazebo_ros gzclient
rosrun gazebo_ros spawn_model
rosrun gazebo_ros perf
rosrun gazebo_ros debug

These nodes are better documented in the tutorial Using roslaunch files to spawn models in Gazebo.

More

Add your upgrade issues here, please

Tutorials

Tutorials from ros.org have been almost entirely removed and re-written from scratch on this website to reflect the many changes that have occurred over the course of Gazebo's history. We've done our best to thoroughly document how to get your URDF-based robot running smoothly in Gazebo. If you have any question please see answers.ros.org.

Continue to Installing gazebo_ros Packages.

Which combination of ROS/Gazebo versions to use

Introduction

This document provides an overview about the options to use different versions of ROS in combination with different versions of Gazebo. It is recommended to read it before installing the Gazebo ROS wrappers.

Important! simple analysis for a quick and correct decision

If you are planning on using a specific version of ROS and don't have a reason to use a specific version of Gazebo, you should proceed with the Installing gazebo_ros_pkgs tutorial which explains how to install the fully supported version of gazebo by ROS.

Warning: note that using a different gazebo version than the official version delivered from the ROS repositories could end up in conflicts or other integration problems with ROS packages.

Gazebo versions and ROS integration

Gazebo is an independent project like boost, ogre or any other project used by ROS. Usually, the latest major version of gazebo available at the beginning of every ROS release cycle (for example gazebo5 for ROS Jade) is selected as the official one to be fully integrated and supported and will be kept during the whole life of the ROS distribution.

Gazebo development is not synced with ROS, so each new major version of Gazebo must be released before being used in a ROS distribution. The following sections cover how to use ROS with different versions of Gazebo.

Note that Gazebo ABI stability policy follows the semantic versioning philosophy, in which all versions that have the same major number (gazebo_6.0.0gazebo_6.1.0gazebo_6.0.1, ...) are binary compatible and thus interchangeable when using the same ROS distro.

Installing Gazebo

Gazebo Ubuntu packages

The easiest way of installing Gazebo is to use packages. There are two main repositories which host Gazebo packages: one is packages.ros.org and the other ispackages.osrfoundation.org. At the time of writing:

  • packages.ros.org
    • Indigo: host gazebo version 2.x package.
    • Jade: host gazebo version 5.x package.
  • packages.osrfoundation.org
    • gazebo 5.x series (package name gazebo5)
    • gazebo 6.x series (package name gazebo6)
    • gazebo 7.x series (package name gazebo7)

This means that including the osrfoundation repository is not strictly needed to get the Gazebo Ubuntu package. It can be installed from the ros repository.

Gazebo built from source

If you have compiled a gazebo version from source, note that depending on the repository branch used (gazebo6,gazebo7,...) your gazebo will be binary compatible with thegazebo_ros_pkgs (and all other ROS packages compiled on top of gazebo) only if the major version matches your local branch repository and the gazebo version used in your ROS distro. For example, if you are compiling from gazebo branch gazebo_2.0, you can use the gazebo_ros_pkgs present in Indigo (which uses gazebo2 series).

Note that if you are using default branch, you are probably not binary compatible with any of the packages released, so you will need a catkin workspace for getting a validgazebo_ros_pkgs.

Using the default Gazebo version for a ROS distribution

For the users that need to run a specific version of ROS and want to use all the gazebo ROS related packages out-of-the-box, this is the recommended section:

Jade

ROS Jade hosts the 5.x version of Gazebo. For a fully-integrated ROS system, we recommend using the 5.x version of Gazebo. The way to proceed is just to use the ROS repository (it will automatically install gazebo5) and do not use the osrfoundation repository.

Indigo

ROS Indigo hosts the 2.x version of Gazebo. For a fully-integrated ROS system, we recommend using the 2.x version of Gazebo. The way to proceed is just to use the ROS repository (it will automatically install gazebo2) and do not use the osrfoundation repository.

Using a specific Gazebo version with ROS

Warning!: Using this option, you won't be able to use any ROS Ubuntu package related to Gazebo from ROS deb repository. The equivalent of gazebo_ros_pkgs can be installed from debian packages, but all other software (such as turtlebot_gazebo) must be built from source. Thanks to catkin workspaces this is quite easy to do.

There is a way of using any specific version of gazebo and ROS if really needed:

Gazebo 7.x series

The OSRF repository provides -gazebo7- versions of ROS/Indigo and ROS/Jade gazebo wrappers (gazebo7_ros_pkgs) which are built on top of the gazebo7 package. The steps to use them are:

  • Add the osrfoundation repository to your sources list.
  • Install ros-$ROS_DISTRO-gazebo7-ros-pkgs from the osrfoundation repository, which will install the gazebo7 package.
  • Use catkin workspaces to compile the rest of the software used from source.

Gazebo 6.x series

The OSRF repository provides -gazebo6- versions of ROS/Indigo and ROS/Jade gazebo wrappers (gazebo6_ros_pkgs) which are built on top of the gazebo6 package. The steps to use them are:

  • Add the osrfoundation repository to your sources list.
  • Install ros-$ROS_DISTRO-gazebo6-ros-pkgs from the osrfoundation repository, which will install the gazebo6 package.
  • Use catkin workspaces to compile the rest of the software used from source.

Gazebo 5.x series

The OSRF repository provides -gazebo5- versions of ROS/Indigo gazebo wrappers (gazebo5_ros_pkgs) which are built on top of the gazebo5 package. The steps to use them are:

  • Add the osrfoundation repository to your sources list.
  • Install ros-indigo-gazebo5-ros-pkgs from the osrfoundation repository, which will install the gazebo5 package.
  • Use catkin workspaces to compile the rest of the software used from source.

FAQ

I am not using ROS at all, which version should I use?

If you don't need ROS support, the recommended version is the latest released version that can be installed using the osrfoundation repo.

I want to use the bullet/simbody/dart physics engine, which version of Gazebo should I use?

Starting from gazebo4, bullet and simbody support is built into the Ubuntu package, so please follow the above instructions to use gazebo4 in combination with ROS. Dart still requires gazebo installation from source (starting from gazebo3), so you can use gazebo3 or above and follow the instructions above in this page to make it work with ROS.

I need to use gazebo5/gazebo6/gazebo7 and ROS Indigo, what can I do?

Warning!: Using this option, you won't be able to use any ROS Indigo package related to Gazebo from ROS deb repository. The way to go is to build them from source. Thanks to catkin workspaces this is quite easy to do.

If you need some features only present in version 5.x, 6.x or 7.x of Gazebo, there is a way of installing gazebo5gazebo6 or gazebo7 and ROS Indigo. Please follow the instructions about how to use ROS with gazebo4, gazebo5 or gazebo6 which are in this same document.

I need to use gazebo6/gazebo7 and ROS Jade, what can I do?

Warning!: Using this option, you won't be able to use any ROS Jade package related to Gazebo from ROS deb repository. The way to go is to build them from source. Thanks to catkin workspaces this is quite easy to do.

If you need some features only present in versions 6.x/7.x of Gazebo, there is a way of installing gazebo6 or gazebo7 and ROS Jade. Please follow the instructions about how to use ROS with gazebo6 package which are in this same document.

Some ROS packages conflict with GazeboX ROS Wrappers!

Note that each ROS distribution is designed to be used with an specific version of Gazebo (gazebo5 in Jade). When someone chooses to use a different version of Gazebo than the one recommended in the ROS distribution, problems may appear and some of them could be unsolvable.

If you a find a dependency conflict (for example with RVIZ) after trying to install one of the versions described in this document, you will need to probably install ROS or Gazebo from source.

Installing gazebo_ros_pkgs

Introduction

The set of ROS packages for interfacing with Gazebo are contained within a new meta package (catkin's version of stacks) named gazebo_ros_pkgs. See Overview of new ROS integrationfor background information before continuing here.

These instructions are for using the Gazebo versions that are fully integrated with ROS Jade, ROS Indigo and ROS Hydro, It is recommended to first read Which combination of ROS/Gazebo version to use before going on with this tutorial. Depending on your needs, you could need an alternative installation.

Prerequisites

You should understand the basic concepts of ROS and have gone through the ROS Tutorials.

Install ROS

We recommend for these ROS integration tutorials you install (ros-jade-desktop-fullros-indigo-desktop-full or ros-hydro-desktop-full) so that you have all the necessary packages.

See the ROS installation page for more details. Be sure to source your ROS setup.bash script by following the instructions on the ROS installation page.

Install Gazebo

You can install Gazebo either from source or from pre-build Ubuntu debians.

See Install Gazebo. If installing from source, be sure to build the gazebo_X.Y (X.Y being your desired version) branch.

Test that stand-alone Gazebo works

Before attempting to install the gazebo_ros_pkgs, make sure the stand-alone Gazebo works by running in terminal:

gazebo

You should see the GUI open with an empty world. Also, test adding a model by clicking on the "Insert" tab on the left and selecting a model to add (then clicking on the simulation to select where to place the model).

Test that you have the right version of Gazebo

To see where you install Gazebo, and if it is in the correct location, run:

which gzserver
which gzclient

If you installed from source to the default location it should say:

/usr/local/bin/gzserver
/usr/local/bin/gzclient

If you installed from debian it should say:

/usr/bin/gzserver
/usr/bin/gzclient

Install gazebo_ros_pkgs

Choose the method you would prefer. The easier and faster is installing it from packages but installing from source means you can more easily debug and submit bug patches ;-)

A. Install Pre-Built Debians

The gazebo_ros_pkgs packages are available in:

Note: currently in ROS Jade there is no ros-jade-gazebo-ros-control package released. Check the issue in the gazebo_ros_control tracker to see the progress.

sudo apt-get install ros-jade-gazebo-ros-pkgs
sudo apt-get install ros-indigo-gazebo-ros-pkgs ros-indigo-gazebo-ros-control
sudo apt-get install ros-hydro-gazebo-ros-pkgs ros-hydro-gazebo-ros-control

If this installation method ends successfully for you, jump to the Testing Gazebo with ROS Integration section below.

B. Install from Source (on Ubuntu)

If you are running an earlier version of ROS (Groovy or earlier) you will need to install gazebo_ros_pkgs from source. Installing from source is also useful if you want to develop new plugins or submit patches.

Setup A Catkin Workspace

These instructions require the use of the catkin build system.

If you do not have a catkin workspace setup, try the following commands:

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace
cd ~/catkin_ws
catkin_make

Then add to your .bashrc file a source to the setup scripts:

echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc

For more details see the Create A Catkin Workspace tutorial.

Clone the Github Repositories

Make sure git is installed on your Ubuntu machine:

sudo apt-get install git
ROS Jade

Jade is using the gazebo 5.x series, start by installing it:

sudo apt-get install -y libgazebo5-dev

Download the source code from the gazebo_ros_pkgs github repository:

cd ~/catkin_ws/src
git clone https://github.com/ros-simulation/gazebo_ros_pkgs.git -b jade-devel

Check for any missing dependencies using rosdep:

rosdep update
rosdep check --from-paths . --ignore-src --rosdistro jade

You can automatically install the missing dependencies using rosdep via debian install:

rosdep install --from-paths . --ignore-src --rosdistro jade -y

Note: currently in ROS Jade there is no ros-jade-gazebo-ros-control package released. Check the issue in the gazebo_ros_control tracker to see the progress. Meantime, we need to disable the gazebo-ros-control compilation:

touch gazebo_ros_pkgs/gazebo_ros_control/CATKIN_IGNORE

Now jump to the build the gazebo_ros_pkgs section.

ROS Indigo

Indigo is using the gazebo 2.x series, start by installing it:

sudo apt-get install -y gazebo2

Download the source code from the gazebo_ros_pkgs github repository:

cd ~/catkin_ws/src
git clone https://github.com/ros-simulation/gazebo_ros_pkgs.git -b indigo-devel

Check for any missing dependencies using rosdep:

rosdep update
rosdep check --from-paths . --ignore-src --rosdistro indigo

You can automatically install the missing dependencies using rosdep via debian install:

rosdep install --from-paths . --ignore-src --rosdistro indigo -y

Now jump to the build the gazebo_ros_pkgs section.

ROS Hydro

Hydro is using the gazebo 1.x series, start by installing it:

sudo apt-get install -y gazebo

Download the source code from the gazebo_ros_pkgs github repository:

cd ~/catkin_ws/src
git clone https://github.com/ros-simulation/gazebo_ros_pkgs.git -b hydro-devel

Check for any missing dependencies using rosdep:

rosdep update
rosdep check --from-paths . --ignore-src --rosdistro hydro

You can automatically install the missing dependencies using rosdep via debian install:

rosdep install --from-paths . --ignore-src --rosdistro hydro -y

Now jump to the build the gazebo_ros_pkgs section.

Build the gazebo_ros_pkgs

To build the Gazebo ROS integration packages, run the following commands:

cd ~/catkin_ws/
catkin_make

See answers.gazebosim.org for issues or questions with building these packages.

Testing Gazebo with ROS Integration

Be sure to always source the appropriate ROS setup file, which for Hydro is done like so:

source /opt/ros/hydro/setup.bash

You might want to add that line to your ~/.bashrc.

Assuming your ROS and Gazebo environment have been properly setup and built, you should now be able to run Gazebo through a simple rosrun command, after launching roscore if needed:

Source the catkin setup.bash if it's not already in your .bashrc

source ~/catkin_ws/devel/setup.bash
roscore &
rosrun gazebo_ros gazebo

The Gazebo GUI should appear with nothing inside the viewing window.

Gazebo機器人仿真學習探索筆記(七)连接ROS

To verify that the proper ROS connections are setup, view the available ROS topics:

rostopic list

You should see within the lists topics such as:

/gazebo/link_states
/gazebo/model_states
/gazebo/parameter_descriptions
/gazebo/parameter_updates
/gazebo/set_link_state
/gazebo/set_model_state

You can also verify the Gazebo services exist:

rosservice list

You should see within the list services such as:

/gazebo/apply_body_wrench
/gazebo/apply_joint_effort
/gazebo/clear_body_wrenches
/gazebo/clear_joint_forces
/gazebo/delete_model
/gazebo/get_joint_properties
/gazebo/get_link_properties
/gazebo/get_link_state
/gazebo/get_loggers
/gazebo/get_model_properties
/gazebo/get_model_state
/gazebo/get_physics_properties
/gazebo/get_world_properties
/gazebo/pause_physics
/gazebo/reset_simulation
/gazebo/reset_world
/gazebo/set_joint_properties
/gazebo/set_link_properties
/gazebo/set_link_state
/gazebo/set_logger_level
/gazebo/set_model_configuration
/gazebo/set_model_state
/gazebo/set_parameters
/gazebo/set_physics_properties
/gazebo/spawn_gazebo_model
/gazebo/spawn_sdf_model
/gazebo/spawn_urdf_model
/gazebo/unpause_physics
/rosout/get_loggers
/rosout/set_logger_level

Other ROS Ways To Start Gazebo

There are several rosrun commands for starting Gazebo:

  • Launch both the server and client together

    rosrun gazebo_ros gazebo
  • Launch the Gazebo server only

    rosrun gazebo_ros gzserver
  • Launch the Gazebo client only

    rosrun gazebo_ros gzclient
  • Launches the Gazebo server only, in debug mode using GDB

    rosrun gazebo_ros debug
  • Additionally, you can start Gazebo using roslaunch

    roslaunch gazebo_ros empty_world.launch

Using roslaunch

Tutorial: Using roslaunch to start Gazebo, world files and URDF models

There are many ways to start Gazebo, open world models and spawn robot models into the simulated environment. In this tutorial we cover the ROS-way of doing things: using rosrunand roslaunch. This includes storing your URDF files in ROS packages and keeping your various resource paths relative to your ROS workspace.

Using roslaunch to Open World Models

The roslaunch tool is the standard method for starting ROS nodes and bringing up robots in ROS. To start an empty Gazebo world similar to the rosrun command in the previous tutorial, simply run

roslaunch gazebo_ros empty_world.launch

roslaunch Arguments

You can append the following arguments to the launch files to change the behavior of Gazebo:

paused

Start Gazebo in a paused state (default false)

usesimtime

Tells ROS nodes asking for time to get the Gazebo-published simulation time, published over the ROS topic /clock (default true)

gui

Launch the user interface window of Gazebo (default true)

headless

Disable any function calls to simulator rendering (Ogre) components. Does not work with gui:=true (default false)

debug

Start gzserver (Gazebo Server) in debug mode using gdb (default false)

Example roslaunch command

Normally the default values for these arguments are all you need, but just as an example:

roslaunch gazebo_ros empty_world.launch paused:=true use_sim_time:=false gui:=true throttled:=false headless:=false debug:=true

Launching Other Demo Worlds

Other demo worlds are already included in the gazebo_ros package, including:

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

Notice in mud_world.launch a simple jointed mechanism is launched. The launch file for mud_world.launch contains the following:

<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="headless" value="false"/>
<arg name="debug" value="false"/>
</include>
</launch>

In this launch file we inherit most of the necessary functionality from emptyworld.launch. The only parameter we need to change is the `worldnameparameter, substituting theempty.worldworld file with themud.world` file. The other arguments are simply set to their default values.

World Files

Continuing with our examination of the mud_world.launch file, we will now look at the contents of the mud.world file. The first several components of the mud world is shown below:

  <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>

See the section below to view this full world file on your computer.

In this world file snippet you can see that three models are referenced. The three models are searched for within your local Gazebo Model Database. If not found there, they are automatically pulled from Gazebo's online database.

You can learn more about world files in the Build A World tutorial.

Finding World Files On Your Computer

World files are found within the /worlds directory of your Gazebo resource path. The location of this path depends on how you installed Gazebo and the type of system your are on. To find the location of your Gazebo resources, use the following command:

env | grep GAZEBO_RESOURCE_PATH

An typical path might be something like /usr/local/share/gazebo-1.9. Add /worlds to the end of the path and you should have the directory containing the world files Gazebo uses, including the mud.world file.

Creating your own Gazebo ROS Package

Before continuing on how to spawn robots into Gazebo, we will first go over file hierarchy standards for using ROS with Gazebo so that we can make later assumptions.

For now, we will assume your catkin workspace is named catkin_ws, though you can name this to whatever you want. Thus, your catkin workspace might be located on your computer at something like:

/home/user/catkin_ws/src

Everything concerning your robot's model and description is located, as per ROS standards, in a package named /MYROBOT_description and all the world files and launch files used with Gazebo is located in a ROS package named /MYROBOT_gazebo. Replace 'MYROBOT' with the name of your bot in lower case letters. With these two packages, your hierarchy should be as follows:

../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

Remember that the command catkin_create_pkg is used for creating new packages, though this can also easily be adapted for rosbuild if you must. Most of these folders and files should be self explanatory.

The next section will walk you through making some of this setup for use with a custom world file.

Creating a Custom World File

You can create custom .world files within your own ROS packages that are specific to your robots and packages. In this mini tutorial we'll make an empty world with a ground, a sun, and a gas station. The following is our recommended convention. Be sure to replace MYROBOT with the name of your bot, or if you don't have a robot to test with just replace it with something like 'test':

  • Create a ROS package with the convention MYROBOT_gazebo
  • Within this package, create a launch folder
  • Within the launch folder create a YOUROBOT.launch file with the following contents (default arguments excluded):
<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>
  • Within the same package, create a worlds folder, and create a MYROBOT.world file with the following contents:
<?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>
  • You should now be able to launch your custom world (with a gas station) into Gazebo using the following command:
. ~/catkin_ws/devel/setup.bash
roslaunch MYROBOT_gazebo MYROBOT.launch

You should see the following world model (zoom out with the scroll wheel on your mouse):

Gazebo機器人仿真學習探索筆記(七)连接ROS

Editing the World File Within Gazebo

You can insert additional models into your robot's world file and use the File->Save As command to export your edited world back into your ROS package.

Using roslaunch to Spawn URDF Robots

There are two ways to launch your URDF-based robot into Gazebo using roslaunch:

ROS Service Call Spawn Method

The first method keeps your robot's ROS packages more portable between computers and repository check outs. It allows you to keep your robot's location relative to a ROS package path, but also requires you to make a ROS service call using a small (python) script.

Model Database Method

The second method allows you to include your robot within the .world file, which seems cleaner and more convenient but requires you to add your robot to the Gazebo model database by setting an environment variable.

We will go over both methods. Overall our recommended method is using the '''ROS Service Call Spawn Method'''

"ROS Service Call" Robot Spawn Method

This method uses a small python script called spawn_model to make a service call request to the gazebo_ros ROS node (named simply "gazebo" in the rostopic namespace) to add a custom URDF into Gazebo. The spawn_model script is located within the gazebo_ros package. You can use this script in the following way:

rosrun gazebo_ros spawn_model -file `rospack find MYROBOT_description`/urdf/MYROBOT.urdf -urdf -x 0 -y 0 -z 1 -model MYROBOT

To see all of the available arguments for spawn_model including namespaces, trimesh properties, joint positions and RPY orientation run:

rosrun gazebo_ros spawn_model -h

URDF Example with Baxter

If you do not yet have a URDF to test, as an example you can download the baxter_description package from Rethink Robotics's baxter_common repo. Put this package into your catkin workspace by running:

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

You should now have a URDF file named baxter.urdf located in a within baxter_description/urdf/, and you can run:

rosrun gazebo_ros spawn_model -file `rospack find baxter_description`/urdf/baxter.urdf -urdf -z 1 -model baxter

You should then see something similar to:

Gazebo機器人仿真學習探索筆記(七)连接ROS

To integrate this directly into a ROS launch file, reopen the file MYROBOT_gazebo/launch/YOUROBOT.launch and add the following before the </launch> tag:

<!-- 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" />

Launching this file, you should see the same results as when using rosrun.

XACRO Example with PR2

If your URDF is not in XML format but rather in XACRO format, you can make a similar modification to your launch file. You can run this PR2 example by installing this package:

ROS Groovy: - Note: PR2 in Groovy is currently broken until this pull request is merged and released to public debians

sudo apt-get install ros-groovy-pr2-common

ROS Hydro:

sudo apt-get install ros-hydro-pr2-common

Then adding this to your launch file created previously in this tutorial:

<!-- 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" />

Launching this file, you should see the PR2 in the gas station as pictured:

Gazebo機器人仿真學習探索筆記(七)连接ROS

Note: at this writing there are still a lot of errors and warnings from the console output that need to be fixed from the PR2's URDF due to Gazebo API changes.


"Model Database" Robot Spawn Method

The second method of spawning robots into Gazebo allows you to include your robot within the .world file, which seems cleaner and more convenient but also requires you to add your robot to the Gazebo model database by setting an environment variable. This environment variable is required because of the separation of ROS dependencies from Gazebo; URDF package paths cannot be used directly inside .world files because Gazebo does not have a notion of ROS packages.

To accomplish this method, you must make a new model database that contains just your single robot. This isn't the cleanest way to load your URDF into Gazebo but accomplishes the goal of not having to keep two copies of your robot URDF on your computer. If the following instructions are confusing, refer back to the Gazebo Model Database documentation to understand why these steps are required.

We will assume your ROS workspace file hierarchy is setup as described in the above sections. The only difference is that now a model.config file is added to your MYROBOT_descriptionpackage like so:

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

This hierarchy is specially adapted for use as a Gazebo model database by means of the following folders/files:

  • /home/user/catkin_workspace/src - this is treated as the location of a Gazebo Model Database
  • /MYROBOT_description - this directory is treated as a single Gazebo model folder
  • model.config - this is a required configuration file for Gazebo to find this model in its database
  • MYROBOT.urdf - this is your robot description file, also used by Rviz, MoveIt!, etc
  • /meshes - put your .stl or .dae files in here, just as you would with regular URDFs

model.config

Each model must have a model.config file in the model's root directory that contains meta information about the model. Basically copy this into a model.config file, replacing model.urdf with your file name:

  <?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>

Unlike for SDFs, no version is required for the tag when it is used for URDFs. See the Gazebo Model Database documentation for more info.

Environment Variable

Finally, you need to add an environment variable to your .bashrc file that tells Gazebo where to look for model databases. Using the editor of your choice edit "~/.bashrc". Check if you already have a GAZEBO_MODEL_PATH defined. If you already have one, append to it using a semi-colon, otherwise add the new export. Assuming your Catkin workspace is in ~/catkin_ws/Your path should look something like:

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

Viewing In Gazebo - Manually

Now test to see if your new Gazebo Model Database is properly configured by launching Gazebo:

  gazebo

And clicking the "Insert" tab on the left. You will probably see several different drop down lists that represent different model databases available on your system, including the online database. Find the database corresponding to your robot, open the sub menu, click on the name of your robot and then choose a location within Gazebo to place the robot, using your mouse.

Viewing In Gazebo - roslaunch with the Model Database

The advantage of the model database method is that now you can include your robot directly within your world files, without using a ROS package path. We'll use the same setup from the section "Creating a world file" but modify the world file:

  • Within the same MYROBOT_description/launch folder, edit the MYROBOT.world file with the following contents:
<?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</uri>
</include>
</world>
</sdf>
  • You should now be able to launch your custom world with both the gas station and robot into Gazebo using the following command:
    roslaunch MYROBOT_gazebo MYROBOT.launch
    

The disadvantage of this method is that your packaged MYROBOT_description and MYROBOT_gazebo are not as easily portable between computers - you first have to set theGAZEBO_MODEL_PATH on any new system before being able to use these ROS packages.

Exporting model paths from a package.xml

The useful info would be the format for exporting model paths from a package.xml:

<export>
<gazebo_ros gazebo_model_path="${prefix}/models"/>
<gazebo_ros gazebo_media_path="${prefix}/models"/>
</export>

The '${prefix}` is something that new users might not immediately know about either, and necessary here.

Also would be useful to have some info on how to debug these paths from the ROS side, e.g. that you can use rospack plugins --attrib="gazebo_media_path" gazebo_ros To check the media path that will be picked up by gazebo.

Next Steps

Now that you know how to create roslaunch files that open Gazebo, world files and URDF models, you are now ready to create your own Gazebo-ready URDF model in the tutorial Using A URDF In Gazebo

URDF in Gazebo

Tutorial: Using a URDF in Gazebo

The Universal Robotic Description Format (URDF) is an XML file format used in ROS to describe all elements of a robot. To use a URDF file in Gazebo, some additional simulation-specific tags must be added to work properly with Gazebo. This tutorial explains the necessary steps to successfully use your URDF-based robot in Gazebo, saving you from having to create a separate SDF file from scratch and duplicating description formats. Under the hood, Gazebo will then convert the URDF to SDF automatically.

Background

While URDFs are a useful and standardized format in ROS, they are lacking many features and have not been updated to deal with the evolving needs of robotics. URDF can only specify the kinematic and dynamic properties of a single robot in isolation. URDF can not specify the pose of the robot itself within a world. It is also not a universal description format since it cannot specify joint loops (parallel linkages), and it lacks friction and other properties. Additionally, it cannot specify things that are not robots, such as lights, heightmaps, etc.

On the implementation side, the URDF syntax breaks proper formatting with heavy use of XML attributes, which in turn makes URDF more inflexible. There is also no mechanism for backward compatibility.

To deal with this issue, a new format called the Simulation Description Format (SDF) was created for use in Gazebo to solve the shortcomings of URDF. SDF is a complete description for everything from the world level down to the robot level. It is scalable, and makes it easy to add and modify elements. The SDF format is itself described using XML, which facilitates a simple upgrade tool to migrate old versions to new versions. It is also self-descriptive.

It is the intention of this author to make URDFs as fully documented and supported in Gazebo as possible, but it is relevant to the reader to understand why the two formats exist and the shortcomings of both. It would be nice if more work was put into URDFs to update them to the current needs of robotics.

Overview of Converting to Gazebo

There are several steps to get a URDF robot properly working in Gazebo. The following is an overview of steps, which are then elaborated on in the rest of this tutorial:

Required

  • An <inertia> element within each <link> element must be properly specified and configured.

Optional

  • Add a <gazebo> element for every <link>
    • Convert visual colors to Gazebo format
    • Convert stl files to dae files for better textures
    • Add sensor plugins
  • Add a <gazebo> element for every <joint>
    • Set proper damping dynamics
    • Add actuator control plugins
  • Add a <gazebo> element for the <robot> element
  • Add a <link name="world"/> link if the robot should be rigidly attached to the world/base_link
Element" data-unique="TheElement" style="box-sizing: border-box; color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 14px; line-height: 20px;">

The <gazebo> Element

The <gazebo> element is an extension to the URDF used for specifying additional properties needed for simulation purposes in Gazebo. It allows you to specify the properties found in the SDF format that are not included in the URDF format. None of the elements within a <gazebo> element are required because default values will be automatically included. There are three different types of <gazebo> elements - one for the <robot> tag, one for <link> tags, and one for <joint> tags. We will discuss the attributes and elements within each type of<gazebo> element throughout this tutorial.

Prerequisites

The first step to getting your robot working in Gazebo is to have a working URDF file from the corresponding ROS URDF Tutorials. Test your URDF by viewing it in Rviz before proceeding to configure your robot with Gazebo. In this tutorial, we'll use a simple demo robot named RRBot. Feel free to follow along with this robot or your own bot.

Getting RRBot

RRBot, or ''Revolute-Revolute Manipulator Robot'', is a simple 3-linkage, 2-joint arm that we will use to demonstrate various features of Gazebo and URDFs. It essentially a double inverted pendulum and demonstrates some fun control concepts within a simulator.

To get RRBot, clone the gazebo_ros_demos Github repo into the /src folder of your catkin workspace and rebuild your workspace:

cd ~/catkin_ws/src/
git clone https://github.com/ros-simulation/gazebo_ros_demos.git
cd ..
catkin_make

If any of this is unfamiliar, be sure you have read the previous ROS Overview Tutorials.

View in Rviz

To check if everything is working, launch RRBot in Rviz:

roslaunch rrbot_description rrbot_rviz.launch

And you should see our little bot like so:

Gazebo機器人仿真學習探索筆記(七)连接ROS

If you do not get this, try killing all old roscore processes with killall roscore and relaunching RViz.

You should also be able to play with the slider bars in the Joint State Publisher window to move the two joints.

It is important that while converting your robot to work in Gazebo, you don't break Rviz or other ROS-application functionality, so its nice to occasionally test your robot in Rviz to make sure everything still works.

The gazebo_ros_control tutorial will explain how to use Rviz to monitor the state of your simulated robot by publishing /joint_states directly from Gazebo. In the previous example, the RRBot in Rviz is getting its /joint_states from a fake joint_states_publisher node (the window with the slider bars).

Examine the RRBot URDF

The rest of this tutorial will refer to various aspects of the RRBot URDF. Go ahead and view the rrbot.xacro file now:

rosed rrbot_description rrbot.xacro

Note that we are using Xacro to make some of the link and joint calculations easier. We are also including two additional files:

  • rrbot.gazebo a Gazebo specific file that includes most of our Gazebo-specific XML elements including the tags
  • materials.xacro a simple Rviz colors file for storing rgba values, not really necessary but a nice convention

View in Gazebo

You should also be able to launch RRBot into Gazebo:

roslaunch rrbot_gazebo rrbot_world.launch

In the launched Gazebo window you should see the robot standing straight up. Despite there being no intentional disturbances in the physics simulator by default, numerical errors should start to build up and cause the double inverted pendulum to fall after a few seconds. The following is a mid-swing screenshot of the RRBot:

Gazebo機器人仿真學習探索筆記(七)连接ROS

Eventually the arm should come to a complete stop. We encourage you to tweak and test various aspects of the URDF during the following tutorials to help you learn more about simulating URDF robots.

Header of a URDF File

There have been many API changes in Gazebo and the required URDF format, one of which that Gazebo xml-schema namespaces are no longer needed. If your URDF has something like:

<robot xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"
xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
xmlns:xacro="http://playerstage.sourceforge.net/gazebo/xmlschema/#xacro"
name="pr2" >

You can remove them. All you need in your root element tag is the name of the robot and optionally the xml namespace for xacro if you are using that:

<robot name="rrbot" xmlns:xacro="http://www.ros.org/wiki/xacro">
elementforthetag" data-unique="elementforthetag" style="box-sizing: border-box; color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 14px; line-height: 20px;">

<gazebo> element for the tag

If a <gazebo> element is used without a reference="" property, it is assumed the <gazebo> element is for the whole robot model. The elements for a <robot> inside the <gazebo> tag are listed in the following table:

Name Type Description
static bool If set to true, the model is immovable. Otherwise the model is simulated in the dynamics engine.

Elements within a <gazebo> tag that are not in the above table are directly inserted into the SDF <model> tag for the generated SDF. This is particularly useful for plugins, as discussed in the ROS Motor and Sensor Plugins tutorial.

Rigidly Fixing A Model to the World

If you would like your URDF model to be permanently attached to the world frame (the ground plane), you must create a "world" link and a joint that fixes it to the base of your model. RRBot accomplishes this with the following:

  <!-- Used for fixing robot to Gazebo 'base_link' -->
<link name="world"/> <joint name="fixed" type="fixed">
<parent link="world"/>
<child link="link1"/>
</joint>

If however you have a mobile base or some other moving robot, you do not need this link or joint.

Links

Be sure you are familiar with the URDF link element.

The following is an example link from RRBot:

  <!-- Base Link -->
<link name="link1">
<collision>
<origin xyz="0 0 ${height1/2}" rpy="0 0 0"/>
<geometry>
<box size="${width} ${width} ${height1}"/>
</geometry>
</collision> <visual>
<origin xyz="0 0 ${height1/2}" rpy="0 0 0"/>
<geometry>
<box size="${width} ${width} ${height1}"/>
</geometry>
<material name="orange"/>
</visual> <inertial>
<origin xyz="0 0 1" rpy="0 0 0"/>
<mass value="1"/>
<inertia
ixx="1.0" ixy="0.0" ixz="0.0"
iyy="1.0" iyz="0.0"
izz="1.0"/>
</inertial>
</link>

Note On Units

As per ROS REP 103: Standard Units of measure and Coordinate Conventions, units in Gazebo should be specified in meters and kilograms. Gazebo could possibly be used with imperial units if the constants such as gravity were changed manually, but by default gravity is 9.81 m/s^2. When specifying mass, use units of kilograms.

andelements" data-unique="andelements" style="box-sizing: border-box; color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 14px; line-height: 20px;">

<collision> and <visual> elements

These tags work essentially the same in Gazebo as in Rviz. It is important that you specify both though, because unlike some ROS applications, Gazebo will not use your <visual>elements as <collision> elements if you do not explicitly specify a <collision> element. Instead, Gazebo will treat your link as "invisible" to laser scanners and collision checking.

Simplify collision model

You can use the same geometry or meshes for both your collision and visual elements, though for performance improvements we strongly suggest you have a simplified model/meshes for your collision geometry. A good open-source tool for simplifying meshes is Blender. There are many closed-source tools, such as Maya and 3DS Max, which can also simplify meshes.

Materials: Using proper colors and textures

A standard URDF can specify colors using a tag such as in the RRBot:

<material name="orange"/>

With the color orange defined separately such as in the file materials.xacro:

  <material name="orange">
<color rgba="${255/255} ${108/255} ${10/255} 1.0"/>
</material>

Unfortunately, this method of specifying link colors does not work in Gazebo as it adopts OGRE's material scripts for coloring and texturing links. Instead, a Gazebo material tag must be specified for each link, such as:

  <gazebo reference="link1">
<material>Gazebo/Orange</material>
</gazebo>

As mentioned earlier, in the RRBot example we have chosen to include all Gazebo-specific tag in a secondary file called rrbot.gazebo. You can find the <link> and <material> elements there.

The default available materials in Gazebo can be found in the Gazebo source code at gazebo/media/materials/scripts/gazebo.material.

For more advanced or custom materials, you can create your own OGRE colors or textures. See:

STL and Collada files

Like in Rviz, Gazebo can use both STL and Collada files. It is generally recommended you use Collada (.dae) files because they support colors and textures, whereas with STL files you can only have a solidly colored link.

Element" data-unique="Element" style="box-sizing: border-box; color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 14px; line-height: 20px;">

<inertial> Element

For the Gazebo physics engine to work properly, the <inertial> element must be provided as documented on the URDF link element page. For links to not be ignored in Gazebo, their mass must be greater than zero. Additionally, links with zero principal moment of inertia (ixx, iyy, izz) could lead to infinite acceleration under any finite torque application.

Determining the correct values for each link is required to get accurate physics approximations in Gazebo. This can be performed by conducting various measurements of the robots parts, or by using CAD software like Solidworks that includes features for approximating these values. For beginners, you can also just make the values up.

An example inertia element from the RRBot first link:

    <inertial>
<origin xyz="0 0 ${height1/2}" rpy="0 0 0"/>
<mass value="1"/>
<inertia
ixx="1.0" ixy="0.0" ixz="0.0"
iyy="1.0" iyz="0.0"
izz="1.0"/>
</inertial>

The origin tag represents the center of mass of this link. By setting the center of mass to half the height of the RRBot's rectangular link, we center the mass in the middle. You can visually check if your center of mass is correct in your URDF within Gazebo by clicking on the ''View'' menu of Gazebo and selecting both ''Wireframe'' and ''Center of Mass''.

In this example robot, both the mass and inertia matrix are made up values since this robot has no real-world counterpart.

ElementsForLinks" data-unique="ElementsForLinks" style="box-sizing: border-box; color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 14px; line-height: 20px;">

<gazebo> Elements For Links

List of elements that are individually parsed:

Name Type Description
material value Material of visual element
gravity bool Use gravity
dampingFactor double Exponential velocity decay of the link velocity - takes the value and multiplies the previous link velocity by (1-dampingFactor).
maxVel double maximum contact correction velocity truncation term.
minDepth double minimum allowable depth before contact correction impulse is applied
mu1 double Friction coefficients μ for the principal contact directions along the contact surface as defined by the Open Dynamics Engine (ODE) (see parameter descriptions in ODE's user guide)
mu2
fdir1 string 3-tuple specifying direction of mu1 in the collision local reference frame.
kp double Contact stiffness k_p and damping k_d for rigid body contacts as defined by ODE (ODE uses erp and cfm but there is a mapping between erp/cfm and stiffness/damping)
kd
selfCollide bool If true, the link can collide with other links in the model.
maxContacts int Maximum number of contacts allowed between two entities. This value overrides the max_contacts element defined in physics.
laserRetro double intensity value returned by laser sensor.

Similar to <gazebo> elements for <robot>, any arbitrary blobs that are not parsed according to the table above are inserted into the the corresponding <link> element in the SDF. This is particularly useful for plugins, as discussed in the ROS Motor and Sensor Plugins tutorial.

RRBot Example of element

In the RRBot, the friction coefficients of the two non-fixed linked were specified so that if a collision occurred more accurate contact interactions were simulated. The following is an example link's <gazebo> tag:

  <gazebo reference="link2">
<mu1>0.2</mu1>
<mu2>0.2</mu2>
<material>Gazebo/Black</material>
</gazebo>

Joints

Make sure you are familiar with the URDF joint documentation. However, not all of the elements documented for URDF joints are applicable to Gazebo:

  • The <origin><parent> and <child> are required
  • <calibration> and <safety_controller> are ignored
  • In the <dynamics> tag, only the damping property is used for gazebo4 and earlier. Gazebo5 and up also uses the friction property.
  • All of properties in the <limit> tag are optional

RRBot Example

The following is a joint used in the RRBot:

  <joint name="joint2" type="continuous">
<parent link="link2"/>
<child link="link3"/>
<origin xyz="0 ${width} ${height2 - axel_offset*2}" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
<dynamics damping="0.7"/>
</joint>

Notice the dynamics element with a viscous damping coefficient of 0.7 N*m*s/rad, damping is simply the amount of opposing force to any joint velocity (in this case torque per angular velocity) that is used to "slow" a moving joint towards rest.

The value of 0.7 N*m*s/rad was decided on by testing different amounts of damping and watching how "realistic" the swinging pendulum appeared. We encourage you to play with this value now (increase/decrease it) to get a feel for how it affects the physics engine.

ElementsForJoints" data-unique="ElementsForJoints" style="box-sizing: border-box; color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 14px; line-height: 20px;">

<gazebo> Elements For Joints

Name Type Description
stopCfm double Joint stop constraint force mixing (cfm) and error reduction parameter (erp) used by ODE
stopErp
provideFeedback bool Allows joints to publish their wrench data (force-torque) via a Gazebo plugin
implicitSpringDamper bool If this flag is set to true, ODE will use ERP and CFM to simulate damping. This is a more stable numerical method for damping than the default damping tag. The cfmDamping element is deprecated and should be changed to implicitSpringDamper.
cfmDamping
fudgeFactor double Scale the excess for in a joint motor at joint limits. Should be between zero and one.

Again, similar to <gazebo> elements for <robot> and <link>, any arbitrary blobs that are not parsed according to the table above are inserted into the the corresponding <joint>element in the SDF. This is particularly useful for plugins, as discussed in the ROS Motor and Sensor Plugins tutorial.

Verifying the Gazebo Model Works

With Gazebo installed, an easy tool exists to check if your URDF can be properly converted into a SDF. Simply run the following command:

  # gazebo2 and below
gzsdf print MODEL.urdf
# gazebo3 and above
gz sdf -p MODEL.urdf

This will show you the SDF that has been generated from your input URDF as well as any warnings about missing information required to generate the SDF.

Note: in Gazebo version 1.9 and greater, some of the debug info has been moved to a log file you can view with:

  cat ~/.gazebo/gzsdf.log

Viewing the URDF In Gazebo

Viewing the RRBot in Gazebo was already covered at the beginning of this tutorial. For your own custom robot, we assume its URDF lives in a ROS package named MYROBOT_descriptionin the subfolder /urdf. The method to open a URDF from that location into Gazebo using ROS was covered in the previous tutorial, Using roslaunch Files to Spawn Models. If you have not completed that tutorial, do so now.

From that tutorial you should have two ROS packages for your custom robot: MYROBOT_description and MYROBOT_gazebo. To view your robot and test it in Gazebo, you should be able to now run something like:

roslaunch MYROBOT_gazebo MYROBOT.launch

This should launch both the Gazebo server and GUI client with your robot automatically launched spawned inside.

Tweaking your model

If your robot model behaves unexpectedly within Gazebo, it is likely because your URDF needs further tuning to accurately represent its physics in Gazebo. See the SDF user guide for more info on various properties available in Gazebo, which are also available in the URDF via the <gazebo> tag.

Sharing your robot with the world

If you have a common robot that other's might want to use in Gazebo, you are encouraged to add your URDF to the Gazebo Model Database. It is an online server that Gazebo connects to to pull down models from the internet. Its Mercurial repository is located on Bitbucket. See Gazebo Model Database documentation for how to submit a pull request to have your robot added to the database.

Next steps

You have now learned how to use ROS packages containing URDFs with Gazebo, and how to convert your custom URDF to work in Gazebo. You are now ready to learn about adding plugins to your URDF so that different aspects of your robot and the simulated environment can be controlled. See ROS Motor and Sensor Plugins.

Gazebo plugins in ROS

Tutorial: Using Gazebo plugins with ROS

Gazebo plugins give your URDF models greater functionality and can tie in ROS messages and service calls for sensor output and motor input. In this tutorial we explain both how to setup preexisting plugins and how to create your own custom plugins that can work with ROS.

Prerequisites

Make sure you have the RRBot setup as described in the previous tutorial on URDFs.

Adding Plugins

Plugins can be added to any of the main elements of a URDF - a <robot><link>, or <joint> depending on what the scope and purpose of the plugin is. To accomplish adding a plugin to a particular element in your URDF, you must wrap your <plugin> tag within a <gazebo> element.

element" data-unique="Addingaplugintotheelement" style="box-sizing: border-box; color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 14px; line-height: 20px;">

Adding a plugin to the <robot> element

The following is an example of a plugin for a <robot> element in a URDF:

<gazebo>
<plugin name="differential_drive_controller" filename="libdiffdrive_plugin.so">
... plugin parameters ...
</plugin>
</gazebo>

In the above example the plugin was added to the <robot> element because, similar to other <gazebo> elements and properties, if no reference="x" is specified it is assumes the reference is the entire <robot>. In SDF terminology, it assumes the reference is the <model>.

SDF Note:

Delving a little deeper in the conversion process, your URDF is converted to a SDF before being parsed by Gazebo. Any elements inside the <gazebo> tags which are not in the element table described in the previous tutorial on URDFs are directly inserted into the <model> tag of the generated SDF. As an example, this feature can be used to introduce model specific plugins. The following is the converted SDF from the above URDF example:

<model name="your_robot_model">
<plugin name="differential_drive_controller" filename="libdiffdrive_plugin.so">
... plugin parameters ...
</plugin>
</model>

Refer to the SDF documentation for more information on how this feature can be used.

element" data-unique="Addingaplugintotheelement" style="box-sizing: border-box; color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 14px; line-height: 20px;">

Adding a plugin to the <link> element

Similar to <plugin> elements for<robot>, you can add a <plugin> element to a link by passing a reference="your_link_name" value.

<gazebo reference="your_link_name">
<plugin name="your_link_laser_controller" filename="libgazebo_ros_laser.so">
... plugin parameters ...
</plugin>
</gazebo>
element" data-unique="Addingaplugintotheelement" style="box-sizing: border-box; color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 14px; line-height: 20px;">

Adding a plugin to the <joint> element

This is accomplished in the same way as a <link> except the reference name is a joint name.

Plugins available in gazebo_plugins

The following sections document all of the plugins available in the gazebo_plugins. We suggest you review them in order because more detail is covered in the first couple of plugins and you can learn some of the concepts from the various plugins' documentation.

The names of each section is derived from the plugin class name. For example, "Block Laser" is from the GazeboRosBlockLaser class and can be found in the filegazebo_plugins/src/gazebo_ros_block_laser.cpp.

If there are some sections blank, it means that this author got tired of documenting every plugin and you should fill in the area with your experience should you have knowledge and examples of how to use the particular plugin.

Camera

Description: provides ROS interface for simulating cameras such as wge100camera by publishing the CameraInfo and Image ROS messages as described in sensormsgs.

RRBot Example

In this section, we will review a simple RGB camera attached to the end of the RRBot pendulum arm. You can look inside rrbot.xacro to follow the explanation. The first elements of this block are an extra link and joint added to the URDF file that represents the camera. We are just using a simple red box to represent the camera, though typically you could use a mesh file for a better representation.

  <joint name="camera_joint" type="fixed">
<axis xyz="0 1 0" />
<origin xyz="${camera_link} 0 ${height3 - axel_offset*2}" rpy="0 0 0"/>
<parent link="link3"/>
<child link="camera_link"/>
</joint> <!-- Camera -->
<link name="camera_link">
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<box size="${camera_link} ${camera_link} ${camera_link}"/>
</geometry>
</collision> <visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<box size="${camera_link} ${camera_link} ${camera_link}"/>
</geometry>
<material name="red"/>
</visual> <inertial>
<mass value="1e-5" />
<origin xyz="0 0 0" rpy="0 0 0"/>
<inertia ixx="1e-6" ixy="0" ixz="0" iyy="1e-6" iyz="0" izz="1e-6" />
</inertial>
</link>

A Xacro property is also defined:

  <xacro:property name="camera_link" value="0.05" /> <!-- Size of square 'camera' box -->

You should be able to launch the RRBot and see a red box attached to the end of the arm.

Next we will review the Gazebo plugin that gives us the camera functionality and publishes the image to a ROS message. In the RRBot we have been following the convention of putting Gazebo elements in the rrbot.gazebo file:

  <!-- camera -->
<gazebo reference="camera_link">
<sensor type="camera" name="camera1">
<update_rate>30.0</update_rate>
<camera name="head">
<horizontal_fov>1.3962634</horizontal_fov>
<image>
<width>800</width>
<height>800</height>
<format>R8G8B8</format>
</image>
<clip>
<near>0.02</near>
<far>300</far>
</clip>
<noise>
<type>gaussian</type>
<!-- Noise is sampled independently per pixel on each frame.
That pixel's noise value is added to each of its color
channels, which at that point lie in the range [0,1]. -->
<mean>0.0</mean>
<stddev>0.007</stddev>
</noise>
</camera>
<plugin name="camera_controller" filename="libgazebo_ros_camera.so">
<alwaysOn>true</alwaysOn>
<updateRate>0.0</updateRate>
<cameraName>rrbot/camera1</cameraName>
<imageTopicName>image_raw</imageTopicName>
<cameraInfoTopicName>camera_info</cameraInfoTopicName>
<frameName>camera_link</frameName>
<hackBaseline>0.07</hackBaseline>
<distortionK1>0.0</distortionK1>
<distortionK2>0.0</distortionK2>
<distortionK3>0.0</distortionK3>
<distortionT1>0.0</distortionT1>
<distortionT2>0.0</distortionT2>
</plugin>
</sensor>
</gazebo>

Let's discuss some of the properties of this plugin...

  <gazebo reference="camera_link">

The link name "camera_link" must match the name of the link we added to the Xacro URDF.

    <sensor type="camera" name="camera1">

The sensor name "camera1" must be unique from all other sensor names. The name is not used many places except for within Gazebo plugins you can access

      <update_rate>30.0</update_rate>

Number of times per second a new camera image is taken within Gazebo. This is the maximum update rate the sensor will attempt during simulation but it could fall behind this target rate if the physics simulation runs faster than the sensor generation can keep up.

        <horizontal_fov>1.3962634</horizontal_fov>
<image>
<width>800</width>
<height>800</height>
<format>R8G8B8</format>
</image>
<clip>
<near>0.02</near>
<far>300</far>
</clip>

Fill in these values to match the manufacturer's specs on your physical camera hardware. One thing to note is that the pixels are assumed to be square.

Additionally, the near and far clips are simulation-specific parameters that give an upper and lower bound to the distance in which the cameras can see objects in the simulation. This is specified in the camera's optometry frame.

      <plugin name="camera_controller" filename="libgazebo_ros_camera.so">

This is where the actual gazebo_ros/gazebo_ros_camera.cpp file is linked to, as a shared object.

        <cameraName>rrbot/camera1</cameraName>
<imageTopicName>image_raw</imageTopicName>
<cameraInfoTopicName>camera_info</cameraInfoTopicName>

Here we define the rostopic the camera will be publishing to, for both the image topic and the camera info topic. For RRBot, you should subscribe to:

/rrbot/camera1/image_raw
/rrbot/camera1/camera_info
        <frameName>camera_link</frameName>

The coordinate frame the image is published under in the tf tree.

Running the RRBot Example

After you have saved both rrbot.xacro and rrbot.gazebo, you should be able to launch both Rviz and Gazebo in separate terminals:

roslaunch rrbot_gazebo rrbot_world.launch
roslaunch rrbot_description rrbot_rviz.launch

In Rviz, add a ''Camera'' display and under ''Image Topic'' set it to /rrbot/camera1/image_raw.

You should see a camera view of your Gazebo environment. In the following two pictures, a soda can was added to the environment for better visuals.

The coke can added:

Gazebo機器人仿真學習探索筆記(七)连接ROS

The corresponding camera view after the pendulum has fallen:

Gazebo機器人仿真學習探索筆記(七)连接ROS

Multicamera

Description: synchronizes multiple camera's shutters such that they publish their images together. Typically used for stereo cameras, uses a very similar interface as the plain Cameraplugin

Note: currently only supports stereo cameras. See Github issue.

Atlas Code Example

In this code example there is both a left and right camera:

  <gazebo reference="left_camera_frame">
<sensor type="multicamera" name="stereo_camera">
<update_rate>30.0</update_rate>
<camera name="left">
<horizontal_fov>1.3962634</horizontal_fov>
<image>
<width>800</width>
<height>800</height>
<format>R8G8B8</format>
</image>
<clip>
<near>0.02</near>
<far>300</far>
</clip>
<noise>
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.007</stddev>
</noise>
</camera>
<camera name="right">
<pose>0 -0.07 0 0 0 0</pose>
<horizontal_fov>1.3962634</horizontal_fov>
<image>
<width>800</width>
<height>800</height>
<format>R8G8B8</format>
</image>
<clip>
<near>0.02</near>
<far>300</far>
</clip>
<noise>
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.007</stddev>
</noise>
</camera>
<plugin name="stereo_camera_controller" filename="libgazebo_ros_multicamera.so">
<alwaysOn>true</alwaysOn>
<updateRate>0.0</updateRate>
<cameraName>multisense_sl/camera</cameraName>
<imageTopicName>image_raw</imageTopicName>
<cameraInfoTopicName>camera_info</cameraInfoTopicName>
<frameName>left_camera_optical_frame</frameName>
<!--<rightFrameName>right_camera_optical_frame</rightFrameName>-->
<hackBaseline>0.07</hackBaseline>
<distortionK1>0.0</distortionK1>
<distortionK2>0.0</distortionK2>
<distortionK3>0.0</distortionK3>
<distortionT1>0.0</distortionT1>
<distortionT2>0.0</distortionT2>
</plugin>
</sensor>
</gazebo>

Depth Camera

Description: simulates a sensor like a Kinect, which is duplicated in the Kinect plugin. Will probably be merged in the future.

Openni Kinect

'''Description:''' Simulates an Xbox-Kinect, publishes the same topics as the corresponding ROS drivers for the Xbox kinect as documented in the Fuerte documentation here.

<gazebo>
<plugin name="${link_name}_controller" filename="libgazebo_ros_openni_kinect.so">
<baseline>0.2</baseline>
<alwaysOn>true</alwaysOn>
<updateRate>1.0</updateRate>
<cameraName>${camera_name}_ir</cameraName>
<imageTopicName>/${camera_name}/depth/image_raw</imageTopicName>
<cameraInfoTopicName>/${camera_name}/depth/camera_info</cameraInfoTopicName>
<depthImageTopicName>/${camera_name}/depth/image_raw</depthImageTopicName>
<depthImageInfoTopicName>/${camera_name}/depth/camera_info</depthImageInfoTopicName>
<pointCloudTopicName>/${camera_name}/depth/points</pointCloudTopicName>
<frameName>${frame_name}</frameName>
<pointCloudCutoff>0.5</pointCloudCutoff>
<distortionK1>0.00000001</distortionK1>
<distortionK2>0.00000001</distortionK2>
<distortionK3>0.00000001</distortionK3>
<distortionT1>0.00000001</distortionT1>
<distortionT2>0.00000001</distortionT2>
<CxPrime>0</CxPrime>
<Cx>0</Cx>
<Cy>0</Cy>
<focalLength>0</focalLength>
<hackBaseline>0</hackBaseline>
</plugin>
</gazebo>

GPU Laser

Description: simulates laser range sensor by broadcasting LaserScan message as described in sensor_msgs. See Hokuyo Laser Scanners Reference.

RRBot Example

See the RRBot Example for adding a Camera to RRBot before reviewing this example. Similar to adding a camera, we will add a new link and joint to the Xacro URDF of the RRBot. This time, instead of using just a rectangle for the visual model, we'll use a mesh:

  <joint name="hokuyo_joint" type="fixed">
<axis xyz="0 1 0" />
<origin xyz="0 0 ${height3 - axel_offset/2}" rpy="0 0 0"/>
<parent link="link3"/>
<child link="hokuyo_link"/>
</joint> <!-- Hokuyo Laser -->
<link name="hokuyo_link">
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<box size="0.1 0.1 0.1"/>
</geometry>
</collision> <visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<mesh filename="package://rrbot_description/meshes/hokuyo.dae"/>
</geometry>
</visual> <inertial>
<mass value="1e-5" />
<origin xyz="0 0 0" rpy="0 0 0"/>
<inertia ixx="1e-6" ixy="0" ixz="0" iyy="1e-6" iyz="0" izz="1e-6" />
</inertial>
</link>

Now we'll add the plugin information to rrbot.gazebo, again as we did for the camera example:

  <!-- hokuyo -->
<gazebo reference="hokuyo_link">
<sensor type="gpu_ray" name="head_hokuyo_sensor">
<pose>0 0 0 0 0 0</pose>
<visualize>false</visualize>
<update_rate>40</update_rate>
<ray>
<scan>
<horizontal>
<samples>720</samples>
<resolution>1</resolution>
<min_angle>-1.570796</min_angle>
<max_angle>1.570796</max_angle>
</horizontal>
</scan>
<range>
<min>0.10</min>
<max>30.0</max>
<resolution>0.01</resolution>
</range>
<noise>
<type>gaussian</type>
<!-- Noise parameters based on published spec for Hokuyo laser
achieving "+-30mm" accuracy at range < 10m. A mean of 0.0m and
stddev of 0.01m will put 99.7% of samples within 0.03m of the true
reading. -->
<mean>0.0</mean>
<stddev>0.01</stddev>
</noise>
</ray>
<plugin name="gazebo_ros_head_hokuyo_controller" filename="libgazebo_ros_gpu_laser.so">
<topicName>/rrbot/laser/scan</topicName>
<frameName>hokuyo_link</frameName>
</plugin>
</sensor>
</gazebo>

Most of the properties are self-explanatory, but we'll review some below:

      <visualize>false</visualize>

When true, a semi-translucent laser ray is visualized within the scanning zone of the gpu laser. This can be an informative visualization, or an nuisance.

More documentation on the <sensor> and <ray> elements can be found in the SDF Documentation.

<topicName>/rrbot/laser/scan</topicName>
<frameName>hokuyo_link</frameName>

Set these to the ROS topic name you would like to publish the laser scans to, and the transform frame you would like TF to use.

Running the RRBot Example

After you have saved both rrbot.xacro and rrbot.gazebo, you should be able to launch both Rviz and Gazebo in separate terminals:

roslaunch rrbot_gazebo rrbot.launch
roslaunch rrbot_description rrbot_rviz.launch

In Rviz, add a ''LaserScan'' display and under ''Topic'' set it to /rrbot/camera1/image_raw.

You should see a faint laser scan line in your Gazebo environment. While the pendulum is swinging, you should also see the laser scan swing. If the scan is too faint, you can up the size of the laser scan in the properties of the LaserScan display in Rviz. A size of 1m is very easy to see. In the following two pictures, a house and construction barrel was added to the environment for better visuals.

View from Gazebo:

Gazebo機器人仿真學習探索筆記(七)连接ROS

The corresponding laser view from Rviz:

Gazebo機器人仿真學習探索筆記(七)连接ROS

Laser

Description: the non-GPU version of GPU Laser, but essentially uses the same code. See GPU Laser for documentation.

To run with RRBot, open rrbot.gazebo and change the following two lines.

replace

    <sensor type="gpu_ray" name="head_hokuyo_sensor">

with

    <sensor type="ray" name="head_hokuyo_sensor">

and replace

      <plugin name="gazebo_ros_head_hokuyo_controller" filename="libgazebo_ros_gpu_laser.so">

with

      <plugin name="gazebo_ros_head_hokuyo_controller" filename="libgazebo_ros_laser.so">

save, then launch the same launch files as for GPU Laser.

Block Laser

Description: provides grid style laser range scanner simulation (e.g. Velodyne).

F3D (Force Feedback Ground Truth)

Description: broadcasts external forces on a body in simulation over WrenchStamped message as described in geometry_msgs.

Force

Description: ROS interface for applying Wrench (geometry_msgs) on a body in simulation.

IMU

Description: simulates imu_node

IMU sensor (GazeboRosImuSensor)

Description: simulates an Inertial Motion Unit sensor, the main differences from IMU (GazeboRosIMU) are: - inheritance from SensorPlugin instead of ModelPlugin, - measurements are given by gazebo ImuSensor instead of being computed by the ros plugin, - gravity is included in inertial measurements.

Joint Pose Trajectory

Description: listens to a jointtrajectoryaction and plays back the set of joint positions. Sets the set of joints to exact positions without regards to simulated physics and forces.

P3D (3D Position Interface for Ground Truth)

Description: broadcasts the inertial pose of any body in simulation via Odometry message as described in nav_msgs via ROS topic.

Projector

Description: projects a static texture from a source outwards, such as used with the PR2's original head camera sensor. See API documentation for more information.

Prosilica Camera

Description: Simulates interfaces exposed by a ROS Prosilica Camera. Here's an example URDF Xacro macro.

Bumper

Description: provides contact feedback via ContactsState message.

<gazebo>
<plugin name="${name}_gazebo_ros_bumper_controller" filename="libgazebo_ros_bumper.so">
<alwaysOn>true</alwaysOn>
<updateRate>${update_rate}</updateRate>
<bumperTopicName>${name}_bumper</bumperTopicName>
<frameName>world</frameName>
</plugin>
</gazebo>

Differential Drive

Description model plugin that provides a basic controller for differential drive robots in Gazebo. You need a well defined differential drive robot to use this plugin.

<gazebo>
<plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
<alwaysOn>true</alwaysOn>
<updateRate>${update_rate}</updateRate>
<leftJoint>base_link_right_wheel_joint</leftJoint>
<rightJoint>base_link_left_wheel_joint</rightJoint>
<wheelSeparation>0.5380</wheelSeparation>
<wheelDiameter>0.2410</wheelDiameter>
<torque>20</torque>
<commandTopic>cmd_vel</commandTopic>
<odometryTopic>odom</odometryTopic>
<odometryFrame>odom</odometryFrame>
<robotBaseFrame>base_footprint</robotBaseFrame>
</plugin>
</gazebo>

Skid Steering Drive

Description model plugin that provides a basic controller for skid steering drive robots in Gazebo (Pioneer 3AT for instance).

<gazebo>
<plugin name="skid_steer_drive_controller" filename="libgazebo_ros_skid_steer_drive.so">
<updateRate>100.0</updateRate>
<robotNamespace>/</robotNamespace>
<leftFrontJoint>front_left_wheel_joint</leftFrontJoint>
<rightFrontJoint>front_right_wheel_joint</rightFrontJoint>
<leftRearJoint>back_left_wheel_joint</leftRearJoint>
<rightRearJoint>back_right_wheel_joint</rightRearJoint>
<wheelSeparation>0.4</wheelSeparation>
<wheelDiameter>0.215</wheelDiameter>
<robotBaseFrame>base_link</robotBaseFrame>
<torque>20</torque>
<topicName>cmd_vel</topicName>
<broadcastTF>false</broadcastTF>
</plugin>
</gazebo>

Video Plugin

Description visual plugin that displays a ROS image stream on an OGRE Texture inside gazebo. This plugin does not modify the texture of one of the existing link surfaces, but creates a new texture on top of it. The texture will be created on the XY plane, visible from the +Z side. The plugin requires a pixel size while constructing the texture, and will resize incoming ROS image messages to match if they are a different size.

<gazebo reference="display_screen_link">
<visual>
<plugin name="display_video_controller" filename="libgazebo_ros_video.so">
<topicName>image</topicName>
<height>120</height>
<width>160</width>
</plugin>
</visual>
</gazebo>

Planar Move Plugin

Description model plugin that allows arbitrary objects (for instance cubes, spheres and cylinders) to be moved along a horizontal plane using a geometry_msgs/Twist message. The plugin works by imparting a linear velocity (XY) and an angular velocity (Z) to the object every cycle.

Here is a full URDF example that demonstrates how to control a floating box inside gazebo using this plugin, using different visual and collision elements. Note: The object needs to have sufficient inertia to prevent undesirable motions - which can occur as a reaction to the supplied velocity. You can try increasing inertia until the object moves as desired. It is also good to have the center of mass close to the ground.

<robot name="test_model">

  <!-- root link, on the ground just below the model origin -->
<link name="base_footprint">
<visual>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<box size="0.001 0.001 0.001" />
</geometry>
</visual>
</link> <joint name="base_link_joint" type="fixed">
<origin xyz="0.0 0 1.25" rpy="0 0 0" />
<parent link="base_footprint"/>
<child link="base_link" />
</joint> <!-- the model -->
<link name="base_link">
<inertial>
<mass value="50" />
<origin xyz="0 0 -1.25" />
<inertia ixx="50.0" ixy="0.0" ixz="0.0"
iyy="50.0" iyz="0.0"
izz="50.0" />
</inertial>
<visual>
<geometry>
<box size="0.5 0.5 1.0" /> <!-- does not need to match collision -->
</geometry>
</visual>
<collision>
<origin xyz="0 0 -1.0" />
<geometry>
<cylinder length="0.5" radius="0.25" />
</geometry>
</collision>
</link> <gazebo>
<plugin name="object_controller" filename="libgazebo_ros_planar_move.so">
<commandTopic>cmd_vel</commandTopic>
<odometryTopic>odom</odometryTopic>
<odometryFrame>odom</odometryFrame>
<odometryRate>20.0</odometryRate>
<robotBaseFrame>base_footprint</robotBaseFrame>
</plugin>
</gazebo> </robot>

Template

Description: an example c++ plugin template for anyone who wants to write their own plugin.

Issue report, contribution

Gazebo-ROS plugins are stored in a ROS package. See gazebo_plugins wiki page about how you can contribute.

3rd party plugins

In addition to the plugins explained above, there are also a number of 3rd party Gazebo-ROS plugins. Some of them are found on ros.org (example of search keyword). If a 3rd party plugin is useful and generic enough, please consider pulling it into the official gazebo_plugins package (wiki page) by opening a suggestion at the issue tracker of each repository.

Next Steps

Next we will analyze the ros_control packages integrated with Gazebo for tight controller/actuator/simulator integration Actuators, controllers, and ros_control.

ROS control

Tutorial: ROS Control

In this tutorial we will setup simulated controllers to actuate the joints of your robot. This will allow us to provide the correct ROS interfaces for planners like MoveIt!. We will be using theros_control packages, a new standard in ROS for controller interfaces.

About ros_control

We encourage you to read an overview of the documentation on ros_control before proceeding.

Data flow of ros_control and Gazebo

Simulating a robot's controllers in Gazebo can be accomplished using ros_control and a simple Gazebo plugin adapter. An overview of the relationship between simulation, hardware, controllers and transmissions is shown below:

Gazebo機器人仿真學習探索筆記(七)连接ROS

Prerequisites

This tutorial builds off of many of the concepts in the previous tutorials. We will again be using the RRBot that was setup in the Using URDF in Gazebo tutorial, as an example for the plugins covered here.

Make sure you have already installed ros_control, ros_controllers, and their dependencies as described in the installation instructions.

Usage

Add transmission elements to a URDF

To use ros_control with your robot, you need to add some additional elements to your URDF. The <transmission> element is used to link actuators to joints, see the <transmission> specfor exact XML format.

For the purposes of gazebo_ros_control in its current implementation, the only important information in these transmission tags are:

  • <joint name=""> - the name must correspond to a joint else where in your URDF
  • <type> - the type of transmission. Currently only "transmission_interface/SimpleTransmission" is implemented. (feel free to add more)
  • <hardwareInterface> - within the <actuator> and <joint> tags, this tells the gazebo_ros_control plugin what hardware interface to load (position, velocity or effort interfaces). Currently only effort interfaces are implemented. (feel free to add more)

The rest of the names and elements are currently ignored.

Add the gazebo_ros_control plugin

In addition to the transmission tags, a Gazebo plugin needs to be added to your URDF that actually parses the transmission tags and loads the appropriate hardware interfaces and controller manager. By default the gazebo_ros_control plugin is very simple, though it is also extensible via an additional plugin architecture to allow power users to create their own custom robot hardware interfaces between ros_control and Gazebo.

The default plugin XML should be added to your URDF:

<gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
<robotNamespace>/MYROBOT</robotNamespace>
</plugin>
</gazebo>

The gazebo_ros_control <plugin> tag also has the following optional child elements:

  • <robotNamespace>: The ROS namespace to be used for this instance of the plugin, defaults to robot name in URDF/SDF
  • <controlPeriod>: The period of the controller update (in seconds), defaults to Gazebo's period
  • <robotParam>: The location of the robot_description (URDF) on the parameter server, defaults to '/robot_description'
  • <robotSimType>: The pluginlib name of a custom robot sim interface to be used (see below for more details), defaults to 'DefaultRobotHWSim'

Default gazebo_ros_control Behavior

By default, without a <robotSimType> tag, gazebo_ros_control will attempt to get all of the information it needs to interface with a ros_control-based controller out of the URDF. This is sufficient for most cases, and good for at least getting started.

The default behavior provides the following ros_control interfaces:

  • hardware_interface::JointStateInterface
  • hardware_interface::EffortJointInterface
  • hardware_interface::VelocityJointInterface - not fully implemented

Advanced: custom gazebo_ros_control Simulation Plugins

The gazebo_ros_control Gazebo plugin also provides a pluginlib-based interface to implement custom interfaces between Gazebo and ros_control for simulating more complex mechanisms (nonlinear springs, linkages, etc).

These plugins must inherit gazebo_ros_control::RobotHWSim which implements a simulated ros_control hardware_interface::RobotHW. RobotHWSim provides API-level access to read and command joint properties in the Gazebo simulator.

The respective RobotHWSim sub-class is specified in a URDF model and is loaded when the robot model is loaded. For example, the following XML will load the default plugin (same behavior as when using no <robotSimType> tag):

<gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
<robotNamespace>/MYROBOT</robotNamespace>
<robotSimType>gazebo_ros_control/DefaultRobotHWSim</robotSimType>
</plugin>
</gazebo>

RRBot Example

We add a <transmission> block similar to the following for every joint that we wish to have Gazebo actuate. Note that the <hardwareInterface> must be included in both the <joint>and <actuator> tags (see ros_control issue here). Open your rrbot.xacro file and at the bottom of the file you should see:

  <transmission name="tran1">
<type>transmission_interface/SimpleTransmission</type>
<joint name="joint1">
<hardwareInterface>EffortJointInterface</hardwareInterface>
</joint>
<actuator name="motor1">
<hardwareInterface>EffortJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission> <transmission name="tran2">
<type>transmission_interface/SimpleTransmission</type>
<joint name="joint2">
<hardwareInterface>EffortJointInterface</hardwareInterface>
</joint>
<actuator name="motor2">
<hardwareInterface>EffortJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>

You'll also see the gazebo_ros_control plugin in rrbot.gazebo that reads in all the <transmission> tags:

<gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
<robotNamespace>/rrbot</robotNamespace>
</plugin>
</gazebo>

Create a ros_controls package

We'll next need to create a configuration file and launch file for our ros_control controllers that interface with Gazebo.

Create new package

mkdir ~/catkin_ws
cd ~/catkin_ws
catkin_create_pkg MYROBOT_control ros_control ros_controllers
cd MYROBOT_control
mkdir config
mkdir launch

Create a .yaml config file

The PID gains and controller settings must be saved in a yaml file that gets loaded to the param server via the roslaunch file. In the config folder of your MYROBOT\_control package, adapt the following RRBot example to your robot as MYROBOT_control/config/rrbot_control.yaml:

rrbot:
# Publish all joint states -----------------------------------
joint_state_controller:
type: joint_state_controller/JointStateController
publish_rate: 50 # Position Controllers ---------------------------------------
joint1_position_controller:
type: effort_controllers/JointPositionController
joint: joint1
pid: {p: 100.0, i: 0.01, d: 10.0}
joint2_position_controller:
type: effort_controllers/JointPositionController
joint: joint2
pid: {p: 100.0, i: 0.01, d: 10.0}

See the next section for more details about these controllers.

Create a roslaunch file

Create a roslaunch file for starting the ros_control controllers. Within the launch folder create a MYROBOT_control/launch/MYROBOT_control.launch file and adapt the following RRBot example to your robot:

<launch>

  <!-- Load joint controller configurations from YAML file to parameter server -->
<rosparam file="$(find rrbot_control)/config/rrbot_control.yaml" command="load"/> <!-- load the controllers -->
<node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false"
output="screen" ns="/rrbot" args="joint1_position_controller joint2_position_controller joint_state_controller"/> <!-- convert joint states to TF transforms for rviz, etc -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"
respawn="false" output="screen">
<remap from="/joint_states" to="/rrbot/joint_states" />
</node> </launch>

Explanation

The first line, "rosparam", loads the controller settings to the parameter server by loading a yaml configuration file (discussed in the next section).

The controller_spawner node starts the two joint position controllers for the RRBot by running a python script that makes a service call to the ros_control controller manager. The service calls tell the controller manager which controllers you want. It also loads a third controller that publishes the joint states of all the joints with hardware_interfaces and advertises the topic on /joint_states. The spawner is just a helper script for use with roslaunch.

The final line starts a robot_state_publisher node that simply listens to /joint_states messages from the joint_state_controller then publishes the transforms to /tf. This allows you to see your simulated robot in Rviz as well as do other tasks.

Start the controllers using roslaunch

Test the RRBot controlled by ros_control by running the following:

Start the RRBot simulation:

roslaunch rrbot_gazebo rrbot_world.launch

Load the controllers for the two joints by running the second launch file:

roslaunch rrbot_control rrbot_control.launch

Using service calls manually

If you first load the rrbot_control.yaml files to the parameter server, you could load the controllers manually through service requests. We'll include them here for reference though we usually prefer roslaunch:

Load the controllers:

rosservice call /rrbot/controller_manager/load_controller "name: 'joint1_position_controller'"
rosservice call /rrbot/controller_manager/load_controller "name: 'joint2_position_controller'"

Start the controllers:

rosservice call /rrbot/controller_manager/switch_controller "{start_controllers: ['joint1_position_controller','joint2_position_controller'], stop_controllers: [], strictness: 2}"

Stop the controllers:

rosservice call /rrbot/controller_manager/switch_controller "{start_controllers: [], stop_controllers: ['joint1_position_controller','joint2_position_controller'], strictness: 2}"

Manually send example commands

Send example joint commands to them for testing:

rostopic pub -1 /rrbot/joint1_position_controller/command std_msgs/Float64 "data: 1.5"
rostopic pub -1 /rrbot/joint2_position_controller/command std_msgs/Float64 "data: 1.0"

Use RQT To Send Commands

In this section we'll go over tools to help you visualize the performance of your controller and tune any gains/parameters the controller might have, particularly PID gains. We'll be usingRQT, ROS's plugin-based user interface, so be sure you first have that installed.

Start RQT:

rosrun rqt_gui rqt_gui

Add a Command Publisher

On the 'Plugins' menu of RQT add the 'Topics->Message Publisher' plugin then choose the topic from the drop down box that commands any particular controller that you want to publish to. For the RRBot, add the controller:

/rrbot/joint1_position_controller/command

Then press the green plus sign button at the top right.

Enable the topic publisher by checking the check box on the left of the topic name. Set the rate column to 100 (the frequency we send it commands - 100hz in this case).

Next, expand the topic so that you see the "data" row. In the expression column, on the data row, try different radian values between joint1's joint limits - in RRBot's case there are no limits because the joints are continuous, so any value works. You should be able to get the RRBot to swing around if you are doing this tutorial with that robot.

Next, in that same expression box we'll have it automatically change values using a sine wave. Add the following:

sin(i/100)

For more advanced control, you can configure it to publish a sine wave to your robot's exact joint limits:

sin(i/rate*speed)*diff + offset

An explanation of variables:

  • i - the RQT variable for time
  • rate - the frequency that this expression is evaluated. This should be the same number as in the rate column of the topic publisher. Recommended value is 100.
  • speed - how quick you want the join to actuate. Start off with just 1 for a slow speed
  • upper_limit and lower_limits - the joint limits of the hardware being controlled by this controller
  • diff = (upper_limit - lower_limit)/2
  • offset = upper_limit-diff

Visualize the controller's performance

Add a Plot plugin to RQT and add the same topic as the one you chose above for the topic publisher:

/rrbot/joint1_position_controller/command/data

Click the green add button. You should now see a sine wave being plotted on the screen.

Add another topic to the Plot plugin that tracks the error between the commanded position and actual position of the actuator being controlled. For the RRBot:

/rrbot/joint1_position_controller/state/error

You screen should look something like this:

Gazebo機器人仿真學習探索筆記(七)连接ROS

Note: the RQT plot plugin is known to have bugs after running for a while (>1min). The drawings start acting strangely. The current solution is to press the blue refresh button at the top right of the plugin.

Tune the PID gains

Finally, we'll use dynamic reconfigure to tune the proportional, derivative, and integral gains of the PID controller, assuming this is applicable to your robot.

Add the 'Dynamic Reconfigure' plugin to RQT and click 'Expand All' to see the sub-options. Assuming your controller uses PID, you should use a "pid" option. Clicking on it should reveal 5 sliders that let you tune the controller, as pictured in the following screenshot. Adjust these values until you get the desired performance of your controller.

Gazebo機器人仿真學習探索筆記(七)连接ROS

Use roslaunch to save your RQT perspective

A pre-configured RQT perspective for the rrbot can be easily launched with the following command:

roslaunch rrbot_control rrbot_rqt.launch

You can use that as a template for doing this with your own robot.

Connect Rviz to Gazebo Simulation

Now that you are using ros_control to send commands to your robot in simulation, you can also use the ros_control jointstatecontroller to read the state of the robot from Gazebo. The idea behind a good simulator is that you should be able to use the same software on your real hardware as you do in simulation. A good starting point for that is visualizing your simulated robot in Rviz, similar to how it is done with real hardware.

Assuming you are already starting a joint_state_controller as documented above in your rosparam and roslaunch files, your next step is to start Rviz:

rosrun rviz rviz

Under "Global Options" change your "Fixed Frame" to "world" to resolve any errors it might be giving you.

Next, add a "RobotModel" display type to Rviz and you should then see your simulated robot in Gazebo being visualized in Rviz!

Demo Code

The example code used for the RRBot in this tutorial is available in the repository gazebo_ros_demos.

Next Steps

Learn about ROS message and service calls that are available for use with Gazebo in the tutorial ROS Communication with Gazebo.

ROS communication

Tutorial: ROS Communication

Gazebo provides a set of ROS API's that allows users to modify and get information about various aspects of the simulated world. In the following sections, we will demonstrate some of the utilities for manipulating the simulation world and objects. The complete list of ROS messages and services for gazebo can be found here also.

Prerequisites

If you would like to follow along with the examples make sure you have the RRBot setup as described in the Using URDF in Gazebo. In this tutorial we'll have the RRBot "kick" a coke can using various techniques.

We'll assume you have Gazebo already launched using:

roscore &
rosrun gazebo_ros gazebo

You may occasionally need to restart Gazebo after different commands listed below.

Terminologies

In the following context, the pose and twist of a rigid body object is referred to as its '''state''. An object also has intrinsic '''properties''', such as mass and friction coefficients. In Gazebo, a '''body''' refers to a rigid body, synonymous to '''link''' in the URDF context. A Gazebo '''model''' is a conglomeration of bodies connected by '''joints'''.

About the gazebo_ros_api_plugin

The gazebo_ros_api_plugin plugin, located with the gazebo_ros package, initializes a ROS node called "gazebo". It integrates the ROS callback scheduler (message passing) with Gazebo's internal scheduler to provide the ROS interfaces described below. This ROS API enables a user to manipulate the properties of the simulation environment over ROS, as well as spawn and introspect on the state of models in the environment.

This plugin is only loaded with gzserver.

About the gazebo_ros_paths_plugin

A secondary plugin named gazebo_ros_paths_plugin is available in the gazebo_ros package that simply allows Gazebo to find ROS resources, i.e. resolving ROS package path names.

This plugin is loaded with both gzserver and gzclient.

Gazebo Published Parameters

Parameters:

/use_sim_time : Bool - Notifies ROS to use published /clock topic for ROS time.

Gazebo uses the ROS parameter server to notify other applications, particularly Rviz, if simulation time should be used via the /use_sim_time parameter. This should be set automatically by Gazebo as true when you start gazebo_ros

/use_sim_time is true if gazebo_ros is publishing to the ROS /clock topic in order to provide a ROS system with simulation-synchronized time. For more info on simulation time, see ROS C++ Time.

Checking the value

To see what the parameter is set as run:

rosparam get /use_sim_time

Gazebo Subscribed Topics

Topics:

~/set_link_state : gazebo_msgs/LinkState - Sets the state (pose/twist) of a link.

~/set_model_state : gazebo_msgs/ModelState - Sets the state (pose/twist) of a model.

Set Model Pose and Twist in Simulation via Topics

Topics can be used to set the pose and twist of a model rapidly without waiting for the pose setting action to complete. To do so, publish the desired model state message to/gazebo/set_model_state topic. For example, to test pose setting via topics, add a coke can to the simulation by spawning a new model from the online database:

rosrun gazebo_ros spawn_model -database coke_can -gazebo -model coke_can -y 1

and set the pose of the coke can by publishing on the /gazebo/set_model_state topic:

rostopic pub -r 20 /gazebo/set_model_state gazebo_msgs/ModelState '{model_name: coke_can, pose: { position: { x: 1, y: 0, z: 2 }, orientation: {x: 0, y: 0.491983115673, z: 0, w: 0.870604813099 } }, twist: { linear: { x: 0, y: 0, z: 0 }, angular: { x: 0, y: 0, z: 0}  }, reference_frame: world }'

You should see the coke can hovering in front of the RRBot, just asking to be hit (we'll get there).

Gazebo機器人仿真學習探索筆記(七)连接ROS

Gazebo Published Topics

Topics:

/clock : rosgraph_msgs/Clock - Publish simulation time, to be used with /use_sim_time parameter.

~/link_states : gazebo_msgs/LinkStates - Publishes states of all the links in simulation.

~/model_states : gazebo_msgs/ModelStates - Publishes states of all the models in simulation.

Retrieving Model and Link States Using Topics

Gazebo publishes /gazebo/link_states and /gazebo/model_states topics, containing pose and twist information of objects in simulation with respect to the gazebo world frame. You can see these in action by running:

rostopic echo -n 1 /gazebo/model_states

or

rostopic echo -n 1 /gazebo/link_states

To reiterate, a '''link''' is defined as a rigid body with given inertial, visual and collision properties. Whereas, a '''model''' is defined as a collection of links and joints. The state of a '''model''' is the state of its canonical '''link'''. Given that URDF enforces a tree structure, the canonical link of a model is defined by its root link.

Services: Create and destroy models in simulation

These services allow the user to spawn and destroy models dynamically in simulation:

~/spawn_urdf_model : gazebo_msgs/SpawnModel - Use this service to spawn a Universal Robotic Description Format (URDF)

~/spawn_sdf_model : gazebo_msgs/SpawnModel - Use this service to spawn a model written in Gazebo Simulation Description Format (SDF)

~/delete_model : gazebo_msgs/DeleteModel - This service allows the user to delete a model from simulation.

Spawn Model

A helper script called spawn_model is provided for calling the model spawning services offered by gazebo_ros. The most practical method for spawning a model using the service call method is with a roslaunch file. Details are provided in the tutorial Using roslaunch Files to Spawn Models. There are many ways to use spawn_model to add URDFs and SDFs to Gazebo. The following are a few of the examples:

Spawn a URDF from file - first convert .xacro file to .xml then spawn:

rosrun xacro xacro `rospack find rrbot_description`/urdf/rrbot.xacro >> `rospack find rrbot_description`/urdf/rrbot.xml
rosrun gazebo_ros spawn_model -file `rospack find rrbot_description`/urdf/rrbot.xml -urdf -y 1 -model rrbot1 -robot_namespace rrbot1

URDF from parameter server using roslaunch and xacro: See Using roslaunch Files to Spawn Models

SDF from local model database:

rosrun gazebo_ros spawn_model -file `echo $GAZEBO_MODEL_PATH`/coke_can/model.sdf -sdf -model coke_can1 -y 0.2 -x -0.3

SDF from the online model database:

rosrun gazebo_ros spawn_model -database coke_can -sdf -model coke_can3 -y 2.2 -x -0.3

To see all of the available arguments for spawn_model including namespaces, trimesh properties, joint positions and RPY orientation run:

rosrun gazebo_ros spawn_model -h

Delete Model

Deleting models that are already in Gazebo is easier as long as you know the model name you gave the object. If you spawned a rrbot named "rrbot1" as described in the previous section, you can remove it with:

rosservice call gazebo/delete_model '{model_name: rrbot1}'

Services: State and property setters

These services allow the user to set state and property information about simulation and objects in simulation:

~/set_link_properties : gazebo_msgs/SetLinkProperties

~/set_physics_properties : gazebo_msgs/SetPhysicsProperties

~/set_model_state : gazebo_msgs/SetModelState

~/set_model_configuration : gazebo_msgs/SetModelConfiguration - This service allows the user to set model joint positions without invoking dynamics.

~/set_joint_properties : gazebo_msgs/SetJointProperties`

~/set_link_state : gazebo_msgs/SetLinkState

~/set_link_state : gazebo_msgs/LinkState

~/set_model_state : gazebo_msgs/ModelState

Set Model State Example

Let's have some fun and have the RRBot hit a coke can using the /gazebo/set_model_state service.

If you have not already added a coke can to your simulation run

rosrun gazebo_ros spawn_model -database coke_can -gazebo -model coke_can -y 1

This should be prepackaged with Gazebo or available via the online model database (internet connection required). Place the coke can anywhere in the scene, it doesn't matter where. Now we'll call a service request to move the coke can into position of the RRBot:

rosservice call /gazebo/set_model_state '{model_state: { model_name: coke_can, pose: { position: { x: 0.3, y: 0.2 ,z: 0 }, orientation: {x: 0, y: 0.491983115673, z: 0, w: 0.870604813099 } }, twist: { linear: {x: 0.0 , y: 0 ,z: 0 } , angular: { x: 0.0 , y: 0 , z: 0.0 } } , reference_frame: world } }'

You should see the setup like this:

Gazebo機器人仿真學習探索筆記(七)连接ROS

Now get the RRBot to start spinning using the following command:

rosservice call /gazebo/set_model_state '{model_state: { model_name: rrbot, pose: { position: { x: 1, y: 1 ,z: 10 }, orientation: {x: 0, y: 0.491983115673, z: 0, w: 0.870604813099 } }, twist: { linear: {x: 0.0 , y: 0 ,z: 0 } , angular: { x: 0.0 , y: 0 , z: 0.0 } } , reference_frame: world } }'

With luck you'll have the coke can launched some variable distance :) If it fumbles you can always try again, this is a tutorial you know.

Gazebo機器人仿真學習探索筆記(七)连接ROS

Services: State and property getters

These services allow the user to retrieve state and property information about simulation and objects in simulation:

~/get_model_properties : gazebo_msgs/GetModelProperties- This service returns the properties of a model in simulation.

~/get_model_state : gazebo_msgs/GetModelState - This service returns the states of a model in simulation.

~/get_world_properties : gazebo_msgs/GetWorldProperties - This service returns the properties of the simulation world.

~/get_joint_properties : gazebo_msgs/GetJointProperties - This service returns the properties of a joint in simulation.

~/get_link_properties : gazebo_msgs/GetLinkProperties - This service returns the properties of a link in simulation.

~/get_link_state : gazebo_msgs/GetLinkState - This service returns the states of a link in simulation.

~/get_physics_properties : gazebo_msgs/GetPhysicsProperties - This service returns the properties of the physics engine used in simulation.

~/link_states : gazebo_msgs/LinkStates - Publish complete link states in world frame

~/model_states : gazebo_msgs/ModelStates - Publish complete model states in world frame

Note:

link_names are in gazebo scoped name notation, [model_name::body_name]

Get Model State Example

Now that you've "kicked" the coke can some distance, you'll want to know how far it went. Building off of the previous example (with the same simulation running), we'll query the pose and twist of the coke can by using the service call:

rosservice call gazebo/get_model_state '{model_name: coke_can}'

Which depending on your robot's kicking skill could give you something like:

pose:
position:
x: -10.3172263825
y: -1.95098702647
z: -0.00413857755159
orientation:
x: -0.0218349987011
y: -0.00515029763403
z: 0.545795377598
w: 0.83761811887
twist:
linear:
x: -0.000385525262354
y: -0.000344915539911
z: -0.00206406538336
angular:
x: -0.104256200218
y: 0.0370371098566
z: 0.0132837766211
success: True

My robot kicked the can 10 meters, how did you do?

Retrieving Simulation World and Object Properties

You can get a list of models (ground_plane, coke cane, rrbot) in the world by running:

rosservice call gazebo/get_world_properties
sim_time: 1013.366
model_names: ['ground_plane', 'rrbot', 'coke_can']
rendering_enabled: True
success: True
status_message: GetWorldProperties: got properties

and retrieve details of a specific model by

rosservice call gazebo/get_model_properties '{model_name: rrbot}'
parent_model_name: ''
canonical_body_name: ''
body_names: ['link1', 'link2', 'link3']
geom_names: ['link1_geom', 'link2_geom', 'link3_geom', 'link3_geom_camera_link', 'link3_geom_hokuyo_link']
joint_names: ['fixed', 'joint1', 'joint2']
child_model_names: []
is_static: False
success: True
status_message: GetModelProperties: got properties

Services: Force control

These services allow the user to apply wrenches and forces to bodies and joints in simulation:

~/apply_body_wrench : gazebo_msgs/ApplyBodyWrench - Apply wrench to a body in simulation. All active wrenches applied to the same body are cumulative.

~/apply_joint_effort : gazebo_msgs/ApplyJointEffort - Apply effort to a joint in simulation. All active efforts applied to the same joint are cumulative.

~/clear_joint_forces : gazebo_msgs/ClearJointForces - Clear applied efforts to a joint.

~/clear_body_wrenches : gazebo_msgs/ClearBodyWrenches - Clear applied wrench to a body.

Apply Wrenches to Links

To demonstrate wrench applications on a Gazebo body, let's spawn an object with gravity turned off. Make sure the coke can has been added to the simulation:

rosrun gazebo_ros spawn_model -database coke_can -gazebo -model coke_can -y 1

Then to turn off gravity send a service call to /gazebo/set_physics_properties with no gravity in any of the axis:

rosservice call /gazebo/set_physics_properties "
time_step: 0.001
max_update_rate: 1000.0
gravity:
x: 0.0
y: 0.0
z: 0.0
ode_config:
auto_disable_bodies: False
sor_pgs_precon_iters: 0
sor_pgs_iters: 50
sor_pgs_w: 1.3
sor_pgs_rms_error_tol: 0.0
contact_surface_layer: 0.001
contact_max_correcting_vel: 100.0
cfm: 0.0
erp: 0.2
max_contacts: 20"

Apply a 0.01 Nm torque at the coke can origin for 1 second duration by calling the /gazebo/apply_body_wrench service, and you should see the coke can spin up along the positive x-axis:

rosservice call /gazebo/apply_body_wrench '{body_name: "coke_can::link" , wrench: { torque: { x: 0.01, y: 0 , z: 0 } }, start_time: 10000000000, duration: 1000000000 }'

You should see your coke can spinning:

Gazebo機器人仿真學習探索筆記(七)连接ROS

Apply a reverse -0.01 Nm torque for 1 second duration at the coke can origin and the can should stop rotating:

rosservice call /gazebo/apply_body_wrench '{body_name: "coke_can::link" , wrench: { torque: { x: -0.01, y: 0 , z: 0 } }, start_time: 10000000000, duration: 1000000000 }'

In general, torques with a negative duration persists indefinitely. To clear any active wrenches applied to the body, you can:

rosservice call /gazebo/clear_body_wrenches '{body_name: "coke_can::link"}'

Apply Efforts to Joints in Simulation

Call /gazebo/apply_joint_effort to apply torque to the joint

rosservice call /gazebo/apply_joint_effort "joint_name: 'joint2'
effort: 10.0
start_time:
secs: 0
nsecs: 0
duration:
secs: 10
nsecs: 0"

And the link should start rotating.

Gazebo機器人仿真學習探索筆記(七)连接ROS

To clear efforts on joints for a specific joint, call

rosservice call /gazebo/clear_joint_forces '{joint_name: joint2}'

Services: Simulation control

These services allow the user to pause and unpause physics in simulation:

~/pause_physics : std_srvs/Empty - Pause physics updates.

~/unpause_physics : std_srvs/Empty - Resume physics updates.

~/reset_simulation : std_srvs/Empty - Resets the entire simulation including the time

~/reset_world : std_srvs/Empty - Resets the model's poses

Pausing and Unpausing Physics

Say you want to get a good screenshot of your soda can flying in the air. You can pause the physics engine by calling:

rosservice call gazebo/pause_physics

When simulation is paused, simulation time is stopped and objects become static. However, Gazebo's internal update loop (such as custom dynamic plugin updates) are still running, but given that the simulation time is not changing, anything throttled by simulation time will not update. To resume simulation, unpause the physic engine by calling:

rosservice call gazebo/unpause_physics

Next Steps

Learn how to create custom ROS plugins for Gazebo.

ROS plugin

Tutorial: Ros Plugins

In this tutorial we'll walk through creating a very basic Gazebo plugin that is ROS-aware.

Create a ROS Package

Create a new ROS package in your catkin workspace:

cd ~/catkin_ws/src
catkin_create_pkg gazebo_tutorials gazebo_ros roscpp

Create the Plugin

Create a very simple plugin as described here and save the file as gazebo_tutorials/src/simple_world_plugin.cpp:

#include <gazebo/common/Plugin.hh>
#include <ros/ros.h> namespace gazebo
{
class WorldPluginTutorial : public WorldPlugin
{
public:
WorldPluginTutorial() : WorldPlugin()
{
} void Load(physics::WorldPtr _world, sdf::ElementPtr _sdf)
{
// Make sure the ROS node for Gazebo has already been initialized
if (!ros::isInitialized())
{
ROS_FATAL_STREAM("A ROS node for Gazebo has not been initialized, unable to load plugin. "
<< "Load the Gazebo system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)");
return;
} ROS_INFO("Hello World!");
} };
GZ_REGISTER_WORLD_PLUGIN(WorldPluginTutorial)
}

Update CMakeLists.txt

Open gazebo_tutorials/CMakeLists.txt and replace it with the following:

cmake_minimum_required(VERSION 2.8.3)
project(gazebo_tutorials) # Load catkin and all dependencies required for this package
find_package(catkin REQUIRED COMPONENTS
roscpp
gazebo_ros
) # Depend on system install of Gazebo
find_package(gazebo REQUIRED) link_directories(${GAZEBO_LIBRARY_DIRS})
include_directories(${Boost_INCLUDE_DIR} ${catkin_INCLUDE_DIRS} ${GAZEBO_INCLUDE_DIRS}) add_library(${PROJECT_NAME} src/simple_world_plugin.cpp)
target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${GAZEBO_LIBRARIES}) catkin_package(
DEPENDS
roscpp
gazebo_ros
)

Update package.xml

Update gazebo_tutorials/package.xml by adding the following line within the <export></export> tags (or add the <export></export> tags also).

  <gazebo_ros plugin_path="${prefix}/lib" gazebo_media_path="${prefix}" />

Compiling the Plugin

Build the plugin by going to the base of your work space and running catkin:

cd ~/catkin_ws
catkin_make

Creating a World file

Save the following file as gazebo_tutorials/worlds/hello.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> <!-- reference to your plugin -->
<plugin name="gazebo_tutorials" filename="libgazebo_tutorials.so"/>
</world>
</sdf>

Create a Launch File

Create the following launch file gazebo_tutorials/launch/hello.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 gazebo_tutorials)/worlds/hello.world"/>
<!-- more default parameters can be changed here -->
</include>
</launch>

Before continuing source your new setup.*sh file:

source devel/setup.bash

Run the Plugin

roslaunch gazebo_tutorials hello.launch

An empty Gazebo should open and in the terminal you should see it print out something like:

 INFO ros.gazebo_tutorials: Hello World!

Starting from a Template

A template is available to help you quickly get a Gazebo-ROS plugin working:

gazeborostemplate.cpp

Adding Functionality

To make your plugin do something useful with Gazebo and ROS, we suggest you read the ROS-agnostic tutorials on Plugins.

ROS Node Note

All gazebo-ros plugins should check if the ROS node has already been initialized in their Load() function, as discussed in this issue. The initialization of the ROS node is performed automatically when you run

rosrun gazeboros gazebo

or use the generic empty.world launch file. The

gazeboros/src/gazeborosapi_plugin.cpp

should be the only place in Gazebo that calls

ros::init()

.

Next Steps

For miscellaneous Gazebo-ROS tricks see Advanced ROS integration

Advanced ROS Integration

Tutorial: ROS Advanced Integration

Dynamic Reconfigure

Some of the physics properties can be adjusted within Gazebo as we described in the modifying a world tutorial. In addition, we can modify this properties using ROS's dynamic reconfigure mechanism.

As an example, we'll invert the gravity in the simulation. Make sure you have the following installed for groovy:

sudo apt-get install ros-groovy-rqt-common-plugins ros-groovy-dynamic-reconfigure

Or these packages for hydro:

sudo apt-get install ros-hydro-rqt-common-plugins ros-hydro-dynamic-reconfigure

Start Gazebo:

rosrun gazebo_ros gazebo

Let's insert a model in gazebo before making any change in the physics. Go ahead and click ''Insert'' in the left side of the gazebo main window. Click on the ''Pioneer 2DX'' robot model.

Start RosGui tool for interacting with gazebo in runtime:

rosrun rqt_gui rqt_gui

Gazebo機器人仿真學習探索筆記(七)连接ROS

Resize the rqt (a.k.a. RosGui) tool until you see something similar to the upper picture. Click on ''gazebo'' in the left side of rqt. You will see the physics parameter list that you will be able to modify. Change the ''gravity_z'' parameter to ''+9.8'' and you should see how the gravity affects your robot.

Gazebo機器人仿真學習探索筆記(七)连接ROS

-End-

上一篇:QT 的使用及编写代码遇到的问题和解决方法


下一篇:JanaScript预解析