How to create Gazebo plugins in ROS, Part 1

Written by Bayode Aderinola

08/03/2023

In this post, you will learn how to create Gazebo plugins by making the Gazebo plugin tutorial, Hello World, compile and work in a ROS package. This is a response to the question posted on Gazebo Answers.

Step 1: Fire up a system with ROS installation

“Hey, do you mean I have to install ros2 first?” Absolutely not! Just log in to The Construct to get access to virtual machines pre-installed with ROS.

Once logged in, click on My Rosjects, then Create a New Rosject, supply the information as shown in the image below, and click Create. Then RUN the rosject.

Create a new Rosject

You might also want to try this on a local PC if you have ROS installed. However, please note that we cannot support local PCs and you will have to fix any errors you run into on your own. The rest of the instruction assumes that you are working on The Construct; please adapt them to your local PC and ROS installation.

PS: We are using ROS Kinetic here, but you should be able to use any ROS 1 distro.

Step 2: Create a new package that we’ll use to demonstrate creating Gazebo plugins

Open Code Editor
Open a web shell

Open a web shell and run the following commands to create the package. When creating Gazebo plugins, you need, at a minimum, the roscpp and gazebo_ros dependencies.

cd catkin_ws/src
source /opt/ros/kinetic/setup.bash
catkin_create_pkg example_plugins_gazebo roscpp gazebo_ros

Create a new C++ file in the package you just created:

cd example_plugins_gazebo/src
touch simple_world_plugin.cpp

Now head over to the Code Editor to make changes to the C++ file. Check the image below for how to open the Code Editor.

Open the Code Editor

Locate the C++ file in the code editor: catkin_ws > src > example_plugins_gazebo > src > simple_world_plugin.cpp and paste in the following code.

#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_WARN("Hello World!");
  }

};
GZ_REGISTER_WORLD_PLUGIN(WorldPluginTutorial)
}

Next, replace the package’s CMakeLists.txt with the following:

cmake_minimum_required(VERSION 2.8.3)
project(example_plugins_gazebo)

## Add support for C++11, supported in ROS Kinetic and newer
add_definitions(-std=c++11)

# 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})

# For tc_simple_world_plugin plugin
add_library(simple_world_plugin src/simple_world_plugin.cpp)
target_link_libraries(simple_world_plugin ${catkin_LIBRARIES} ${GAZEBO_LIBRARIES})

catkin_package(
  DEPENDS 
    roscpp 
    gazebo_ros 
)

Also, replace the package.xml file content with the following:

<?xml version="1.0"?>
<package>
  <name>example_plugins_gazebo</name>
  <version>0.0.0</version>
  <description>The example_plugins_gazebo package</description>
  <maintainer email="name@email.com">user</maintainer>

  <license>TODO</license>

  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>gazebo_ros</build_depend>
  <build_depend>roscpp</build_depend>
  <run_depend>gazebo_ros</run_depend>
  <run_depend>roscpp</run_depend>


  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <gazebo_ros plugin_path="${prefix}/lib" gazebo_media_path="${prefix}" />
  </export>
</package>

So much for all the hard work – now is the time to see if it works. Time to compile the code. In the same web shell, run the following commands:

cd ~/catkin_ws
catkin_make
source devel/setup.bash

Success! We have now created a new plugin. Next, we will use it!

PS: if your code did not compile correctly, please go over the instructions and ensure you have created the files in the exact locations specified.

Step 3: Use the new Gazebo plugin we just created

Create a new folder in the package. We’ll create Gazebo worlds in it, so it’s so named!

cd ~/catkin_ws/src/example_plugins_gazebo
mkdir -p worlds
cd worlds
touch simple_world.world

Open the simple_world.world file in the code editor and paste in the following:

<?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="simple_world_plugin" filename="libsimple_world_plugin.so"/>
  </world>
</sdf>

But, wait…how did we know the right filename to use in the line highlighted in the world file? It is by convention named lib{name_of_cpp_executable}.so, and we should find it in ~/catkin_ws/src/devel/lib/

cd ~/catkin_ws/devel/lib/
ls

That covered, we move. Now we’ll create a launch file to launch our world with the Gazebo plugin.

cd ~/catkin_ws/src/example_plugins_gazebo
mkdir -p launch
cd launch
touch simple_world.launch

Open the simple_world.launch file in the code editor and paste in the following content.

<?xml version="1.0" encoding="UTF-8"?>
<launch>
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="$(find example_plugins_gazebo)/worlds/simple_world.world"/>
  </include>
</launch>

Perfect! Time to launch the package.

roslaunch example_plugins_gazebo simple_world.launch

Now you should see something like this: Hello World! printed on the terminal and an empty Gazebo world. We are done here!

Gazebo world with custom “Hello World” plugin

Step 4: Check your learning

Do you understand how to create Gazebo plugins? If you don’t know it yet, please go over the post again, more carefully this time.

Here are the links to the resources used in this tutorial:

  • http://gazebosim.org/tutorials/?tut=plugins_hello_world
  • http://gazebosim.org/tutorials?tut=ros_gzplugins
  • http://gazebosim.org/tutorials?tut=guided_i5
  • http://gazebosim.org/tutorials/?tut=ros_advanced
  • http://gazebosim.org/tutorials?tut=plugins_model

(Extra) Step 5: Watch the video to understand how to create Gazebo plugins

Here you go:

Feedback

Did you like this post? Do you have any questions about how to create Gazebo plugins? Please leave a comment in the comments section below, so we can interact and learn from each other.

If you want to learn about other ROS topics, please let us know in the comments area and we will do a video or post about it.

Masterclass 2023 batch2 blog banner

Check Out These Related Posts

129. ros2ai

129. ros2ai

I would like to dedicate this episode to all the ROS Developers who believe that ChatGPT or...

read more

0 Comments

Submit a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Pin It on Pinterest

Share This