中文稍后补充,先上官方原版教程。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:
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 topkg="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, includingempty.world
.- The best way to use Gazebo launch files is to simply inherit/include the master
empty_world
launch file located in thegazebo_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 torosrun 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.0
, gazebo_6.1.0
, gazebo_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
)
- gazebo 5.x series (package name
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 thegazebo7
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 thegazebo6
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 thegazebo5
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 gazebo5
, gazebo6
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-full
, ros-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.
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 rosrun
and 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 the
empty.worldworld file with the
mud.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):
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:
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:
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_description
package 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
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:
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:
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">
<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.
<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.
<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.
<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 thedamping
property is used for gazebo4 and earlier. Gazebo5 and up also uses thefriction
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.
<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_description
in 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.
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.
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>
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:
The corresponding camera view after the pendulum has fallen:
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 Camera
plugin
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:
The corresponding laser view from Rviz:
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:
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:
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.
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 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:
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.
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:
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.
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:
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.cppshould 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
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.
-End-