Search this site
Embedded Files
No Boredom
  • Home
    • Computer Geek
    • Learning
    • Math Geek
    • Projects
No Boredom
  • Home
    • Computer Geek
    • Learning
    • Math Geek
    • Projects
  • More
    • Home
      • Computer Geek
      • Learning
      • Math Geek
      • Projects

Gazebo Basics

< Back to ROS Beginner tutorials
What is Gazebo ?
Client and server separation
Creating a world
Making your package ready
Creating world
Opening Gazebo with a world preloaded
Spawning a Robot
Creating a Robot Model
Spawning a robot model
Creating a launch file
Gazebo tags
Gazebo tag for robots
Gazebo tag for Links
Adding a sensor
Camera sensor
Visualizing on RViZ or Gazebo
Additional
Gazebo and ROS time sync
Isolated Gazebo package
Documentation
Links
Problems faced

What is Gazebo ?

Gazebo is a robotic simulator that comes installed when you install ROS, but actually is a completely separate project now. It is extremely feature rich (reference here), it has a great community, supports all families of robots, a wide range of actuators and sensors, and the best part is that it's open source so there's a lot of documentation available (complete thing here). The source code is hosted on bitbucket.

Official website: http://gazebosim.org/

Let's get started by launching gazebo, there are multiple ways of doing this if you've installed gazebo separately, but if you've installed it with ROS, then this particular method will be helpful:

  • Run the following commands on different terminals (I'd prefer that you run them on different tabs):
    • roscore
      • Start the ROS server
    • rosrun gazebo_ros gazebo
      • Start the Gazebo application as a node

There are other methods as well, as we will see later:

  • Run the gazebo command after starting roscore. This does the same thing as above

You must see the window below

Gazebo simulator

The following things can be noted from the window that just opened:

  • The big window at the center is called the world view. This is where everything visual happens and you can see the results of simulation on this window. The axis is represented by red (X axis), green (Y axis) and blue (Z axis).
  • The window on the left is called the property window. It shows all the objects in the world and also helps us adjust things in the world. Click on any property in the list and it will show you all the properties about the selected object and you can edit most of them by double clicking the property.
    • There are also options to insert things in the world and an options to alter the layers. We'll see these advanced options later.
  • On the bottom, there's a time window. It shows the time, number of iterations your physics engine has taken, FPS, etc.

Everything in Gazebo is an object. Even the world which you see is through a camera which you can control using your mouse. Click the GUI property on the property window to know everything about the camera which you're using to see everything on the world window and the grid that you can see on the floor.

You can click Physics in the property window and explore the physics properties of your world. Play around with various objects in the property window to know more about them. A notable one is the Models -> ground_plane -> link property which is basically the ground surface in the world. It's already existing and everything happens over it.

In RViZ, there was a configuration file to load RViZ with the items that we like. Similarly, in Gazebo there is something called the world file which stores the configurations and the entire world objects. You can click on File -> Save World as and save it as an SDF file somewhere and open the SDF file. It's basically an XML based description file. You can get all the worlds available already on your system at the path "/usr/share/gazebo-9/worlds" (ROS melodic uses gazebo-9). More on that here. You can load a world by the following method:

  • Run the following command:
    • gazebo worlds/pioneer2dx.world
      • Starts gazebo with loading the world pioneer2dx.world stored in /usr/share/gazebo-9/worlds folder.
      • We could also do rosrun gazebo_ros gazebo worlds/pioneer2dx.world and it would produce the exact same results.

Make sure that the currently running gazebo instance is closed before this and that the roscore is running. After the window opens, you must be able to see a robot in the middle of the world.

Client and server separation

Official page here

Gazebo actually runs two executables when we run the command gazebo. They're gzserver and gzclient. The gzserver handles simulation and all underlying execution of the physics engine. The gzclient simply shows the results on a Qt based GUI. This makes gazebo easy to use. We simply test everything on gazebo first, later link it with actual hardware and run only the gzserver on a robot, thus reducing the resources required for displaying the GUI.

Creating a world

Let's create an environment, a static world in which we'll later learn how to spawn a robot. Follow the following steps to do this:

Making your package ready

  • Create a folder named "worlds" in your package and add gazebo dependency in your package.
    • We'll use intro_robot_description package here, you could use any package or create a new one.
    • Your package must be dependent on gazebo_ros, so do the following:
      • In CMakeLists.txt of your package, add "gazebo_ros" to the list inside find_package function.
      • In package.xml file, add "gazebo_ros" as a build_depend, build_export_depend and exec_depend tags.
  • Run catkin_make in your workspace directory.
    • cd ~/ROS_workspaces/ros_ws
    • catkin_make

Creating world

Code here
  1. Run Gazebo and wait for it to start
    • roscore
    • rosrun gazebo_ros gazebo
  2. Click Edit -> Building editor to create walls and buildings.
    • Create walls by choosing the "Wall" option and drawing a shape on the canvas. Note that you can double click the line on canvas to edit properties of the wall.
    • We chose to create a 10 m by 10 m wall as a boundary. You can even click, then select objects to apply a texture.
    • You can save the world now itself, by clicking File -> Save as and choosing the worlds folder of your package. We'll save it with the name "Walls". You'll find a folder named "Walls" created in the worlds folder and that it contains a config file and an SDF file with it.
    • You can exit the building editor with File -> Exit Building Editor.
  3. Click Edit -> Model editor to insert objects into your model. You could choose a primitive shape like cube, cylinder and sphere or Add a custom shape using an STL file that you've created using a CAD software.
    • Insert a shape by clicking, then positioning it on the scene. You can double click the object or go to Model (selection on top) and double click the link to edit it's properties.
    • Then exit the model with File -> Exit Model Editor.
  4. Then click File -> Save world as and then navigate to the worlds folder of your package and save it with ".world" extension.
    • We'll save it as "FirstWorld.world" in the worlds folder of intro_robot_description package.
Code here

Opening Gazebo with a world preloaded

  • We've actually already done this, but just follow the following procedure to open the world file that we previously create. Run the following on a terminal:
    • roscd intro_robot_description/worlds/
    • rosrun gazebo_ros gazebo FirstWorld.world
      • Make sure that roscore is already running in background

We could also do:

  • rosrun gazebo_ros gazebo ~/ROS_workspaces/ros_ws/src/intro_robot_description/worlds/FirstWorld.world

You'll see the gazebo window open with the world that we created and saved earlier.

Gazebo launched with the world file created

Spawning a Robot

Let's see how to spawn (and later, control) a robot in Gazebo. It's similar to VReP but with a little additions for this, because simulations requires more information than simple visualization. For this, we'll spawn (and control) a four wheeled vehicle.

There's also an official tutorial about using a URDF in Gazebo, link here (you can check it out after reading this page).

Creating a Robot Model

Code hereName the file four_wheel_bot.xacro

We'll use XACRO to make this robot model. We'll follow the following procedure to develop code for this model:

  • Write the XML tag and define everything inside the <robot> ... </robot> tag. Make sure you define the xmlns argument for XACRO.
  • All links in gazebo need inertial, visual and collision properties well defined so that the physics can be calculated.
    • Inertia tensors must be defined (link on Wikipedia).
    • Collision geometry must be as close and approximate as possible. Use of primitives is encouraged.
  • Define the base link and then define wheels using a macro that we created for a wheel.
  • You'll observe that even though you've assigned a visual material, it won't be visible in gazebo until you declare one using the <gazebo> tag (check the <material> tag discussed later on in 'Gazebo tag for Links'). The XACRO include tag is to add gazebo materials for the links.
Code here

Spawning a robot model

To spawn a robot in gazebo, we use a node in the gazebo_ros package. The node is spawn_model. You can know more about it by running:

  • rosrun gazebo_ros spawn_model --help

We basically pass it the following arguments:

  • model MODEL_NAME: The name of the model in Gazebo.
  • urdf or sdf: Basically the file format in which the code is written (only one).
  • file FILE_NAME or param PARAM_NAME: Source of the description file, a file stored on disk or on ROS parameter server, respectively.
  • x, y, z, R, P and/or Y: The position (xyz) and orientation (rpy - Roll Pitch and Yaw) in which the model will be spawned.
  • J JOINT_NAME JOINT_POSITION: To start with the joint_name at joint_position (value of joint in the beginning, right after being spawned).

Creating a launch file

Code hereName the file RobotLauncher.launch
  • Create the following arguments:
    • robot: The file name of the robot description file. File must be stored in urdf folder of the package.It's "four_wheel_bot" by default.
    • spawn_z: This is the height above the surface that we want to spawn the robot.
    • world: Name of the world file (without extension) in the worlds folder of the package.
    • rviz: If true, then launch RViZ and visualize the robot in it as well, else false (false by default). There are other parameters related to this as well, check the file.
  • Run the following nodes:
    • gazebo from package gazebo_ros named gazebo and pass it the path to world file as argument, make it a required node.
      • Launch gazebo first, always. Gazebo creates a ROS parameter named '/use_sim_time' to synchronize time between Gazebo and ROS which is important for nodes proceeding it. You could set the parameter to false, but then you'll have to take care of synchronization of Gazebo and other processes. Best you have gazebo launched first.
    • spawn_model from package gazebo_ros named urdf_spawner and pass it the parameters required for spawning the URDF model. You can get these through running the command:
      • rosrun gazebo_ros spawn_model --help
      • It's generally a good idea to spawn the robot using a ROS parameter on the parameter server than a file, because then every node has access to the robot model (since it's residing on the server).
    • There is RViZ being launched as well, if the rviz argument is true.
Code here

To launch everything, run the command:

  • roslaunch intro_robot_description RobotLauncher.launch

The window that opens must look something like what's shown below.

Robot model spawned in Gazebo simulator

Gazebo tags

Official page here

The <gazebo ... > ... </gazebo> tag is used to give Gazebo specific properties to the model. It is used to describe everything for Gazebo, from simulation properties like damping and friction to even various sensors to the model. The gazebo tag is used in three major forms, for reference to a link, joint and entire robot. It has different elements under each category. We'll discuss a few in brief. The official page on this here.

Usually, we do the following to use a gazebo tag:

  • Create a file that bears the same name as the xacro file, but ends with extension ".gazebo", we'll write all main code for gazebo tags in this file. We'll call this the gazebo file from here on. Include this file in the main XACRO file using <xacro:include filename="..." /> tag.
  • This gazebo file is essentially an XML file, so start is with <?xml version="1.0"?> line, just like an XML file. Then, enclose everything inside a <robot> ... </robot> tag. If this step is not done, the file won't be parsed successfully.
  • Any gazebo tag with an element (a property with value elementValue) is written like "<gazebo ... > ... <element> elementValue </element> ... </gazebo>". So follow this for all gazebo tags. Keep in mind that most of the element values are not strings, they're to be written as variables (like a number).

The <gazebo ...> ... </gazebo> tag has the following attributes:

  • reference: The reference object for which the gazebo tag is used, if not specified, it's taken as the entire robot.

Gazebo tag for robots

Reference

It has the following elements:

  • static: If set to true, the model is immovable. Otherwise the model is simulated in the dynamics engine. It's a boolean type

Gazebo tag for Links

Reference

When referenced to links, it has the following elements:

  • material: Material, how you want the link to appear on the gazebo simulator. Complete code on BitBucket here.

For example:

<gazebo reference="base_link">
    <material>Gazebo/DarkGrey</material>
</gazebo>

There are also sensors added through this manner (more in the "Adding a sensor" section) through this tag:

  • sensor: Used to add sensors to the model (more in "Adding a sensor" section later on). Attributes are type (sensor type) and name (a unique name given to the sensor). It has the following major elements:
    • update_rate: The update rate of the sensor (number of times per second).
    • sensor element tag, this is unique for every sensor. It defines all kinds of properties about the sensor. This is parsed through the different ".cc" and ".hh" files present in the sensors API. The entire list is on BitBucket.
    • plugin: The plugin code that has settings about how the sensor data must be dealt with. Topic names for publishing, distortion of data, frames and other information comes here. They are present in the directory "/opt/ros/melodic/lib/" as "libgazebo_roc*.so" files, they're also available online on docs. The plugin tag must be passed the filename as an attribute. Another attribute is the unique plugin name.
      • All kinds of things in Gazebo, like sensors, models, GUI elements and even controllers are plugins. You can see the complete list of predefined plugins on the gazebo website in this tutorial page.

Adding a sensor

The <gazebo> tag contains a <sensor> tag to add all kinds of sensors that gazebo supports. Everything in the gazebo tag is basically a plugin. So here we talk about sensor plugins in Gazebo. Here are a few things that you must remember before starting up with sensors:

  • All the sensors must have a physical link they're attached to. So first create a physical link for them.
    • Virtually, all sensors sense things facing the positive X axis, so orient your link accordingly.

Camera sensor

Official page here
  • Add a physical link for the camera sensor. Place it with the X axis facing in the recording direction.

In the gazebo description file, add the following:

  • Create a gazebo reference for the camera link.
  • Add a sensor tag for it. The type argument must be "camera" and name argument must be a unique sensor name.
  • Create a <camera ... > tag, with attribute name (assign it "head"). All our camera properties go in here.
  • First specify the horizontal_fov element (horizontal field of view, double datatype). This is the horizontal field of view of the camera. It comes along in the datasheet, more about it on Wikipedia (specify 1.3962634 if you have no idea).
  • Start the <image ... > tag to specify details and encoding about the images the camera will send. It has the following elements:
    • width attribute (width of image in number of pixels, integer)
    • height attribute (height of image in number of pixels, integer)
    • format or the encoding of image, like R8G8B8 (for RGB 8 bit scheme).
  • End the </image> tag
  • Start the <clip> tag, this is to specify near and far elements (both integers) as the field of view limits. End the </clip> tag after that.
  • Start the <noise> tag, to generate noise in images. I'd suggest that you use gaussian always (specify that in type argument). Set the mean argument to 0.0 and standard deviation (stddev argument) to 0.007 value. After that, close the </noise> and the </camera> tag.
  • Now, we define the camera plugin for gazebo. Start the <plugin ... > tag, pass it arguments name (usually something like "camera_controller") and filename (must be "libgazebo_ros_camera.so" to link it to the correct shared object file). Mention the following elements:
    • alwaysOn: true, if you want the camera to always be turned on
    • updateRate: set it to 0, we're not going to change this plugin and we've specified the camera properties before.
    • imageTopicName and cameraInfoTopicName so that the data can be published on topics
    • frameName of the camera.
    • There are various other tags related to distortion that we don't need right now.
  • Close all open tags in the gazebo file
Code to a sample gazebo file hereCode to a sample robot description file here

Visualizing on RViZ or Gazebo

  • After launching Gazebo with the model and everything, click on Window -> Topic Visualization and select the topic that ends with ImageStamped (double click the message under it). You'll observe a camera viewer show up.
  • Open RViZ with the robot model or the camera frame as the fixed frame and do the following:
    • Add a Camera to the Displays panel.
    • Choose the correct image topic under which images are being displayed.
    • If all transformations are right and camera is working, then feed will appear right there.

You can use this launch file with this RViZ configuration, run the command:

  • roslaunch intro_robot_description RobotLauncher.launch rviz:="true"

In case the above command throws errors (this happens because of the launch order being random). This creates some clock issues for RViZ and Gazebo. This is in fact one of the reasons why the gazebo files and robot description files are kept in separate packages and are launched using different launch files. We'll see this later, for now you could run the following commands on different terminals:

  • roslaunch intro_robot_description RobotLauncher.launch
    • Launch Gazebo with the robot spawned first. Wait for Gazebo to get launched and ready.
  • rosrun rviz rviz -d $(rospack find intro_robot_description)/rviz/RobotViewer.rviz
    • Launch RViZ with the configuration file of the package. Right now, the robot model won't be showed because the transformations are not being published
  • rosrun joint_state_publisher joint_state_publisher
    • Launch the joint state controller to publish joint states (no use_gui parameter here, so the GUI controller window will not be seen here).
  • rosrun robot_state_publisher robot_state_publisher
    • Launch the robot state controller to publish transformations from joint states.

Visualization of results on Gazebo

Visualization of results on RViZ

Additional

Gazebo and ROS time sync

Gazebo uses the /use_sim_time parameter (on the ROS Parameter server) to synchronize ROS time with Gazebo simulation time. If it's true (which is the default configuration), then Gazebo publishes /clock as a simulation time clock. It it's set to false, then Gazebo and ROS follow individual times.

More on this here.

Isolated Gazebo package

Gazebo packages are kept isolated from robot description packages because of some launch issues, launch files do not launch nodes in a specific order.

Doing this makes it a little difficult to launch everything because now we have two launch files for the project, but on the other hand, the execution problem is then solved. The next tutorial will explore this very option.

Documentation

  • Plugin source codes and documentation here.
  • Plugin basics tutorial here.

Links

  • Gazebo plugins on GitHub. All ROS Simulation packages here.

Problems faced

  • Error in REST request for accessing api.ignition.org
    • This is probably a server side issue
    • Fix: Change URL in ~/.ignition/fuel/config.yaml from https://api.ignitionfuel.org to https://api.ignitionrobotics.org


< Back to ROS Beginner tutorials
Google Sites
Report abuse
Page details
Page updated
Google Sites
Report abuse