Tutorials/1.9/plugins/factory


 * 1) Prerequisites: ##

Model Manipulation Plugin Tutorial


 * 1) Code: ##

Location: `/examples/plugins/factory`

It can be useful to control what models exist in a running simulation, and when they should be inserted. This tutorial demonstrates how to insert predefined and custom models into Gazebo.

Use the `gazebo_plugin_tutorial` from the previous plugin tutorials

~ mkdir ~/gazebo_plugin_tutorial cd ~/gazebo_plugin_tutorial ~

Create a new source file:

gedit factory.cc

Copy the following code into the `factory.cc` file:


 * 1) include "gazebo/physics/physics.hh"
 * 2) include "gazebo/common/common.hh"
 * 3) include "gazebo/gazebo.hh"

namespace gazebo { class Factory : public WorldPlugin {   public: void Load(physics::WorldPtr _parent, sdf::ElementPtr /*_sdf*/) {       // Option 1: Insert model from file via function call. // The filename must be in the GAZEBO_MODEL_PATH environment variable. _parent->InsertModelFile("model://box");

// Option 2: Insert model from string via function call. // Insert a sphere model from string sdf::SDF sphereSDF; sphereSDF.SetFromString(      "\         \           1 2 0 0 0 0 \        \          0 0 .5 0 0 0 \          \            \               0.5  \            \          \          \            \               0.5  \            \          \        \          \        "); _parent->InsertModelSDF(sphereSDF);

// Option 3: Insert model from file via message passing. {    // Create a new transport node transport::NodePtr node(new transport::Node);

// Initialize the node with the world name node->Init(_parent->GetName);

// Create a publisher on the ~/factory topic transport::PublisherPtr factoryPub = node->Advertise("~/factory");

// Create the message msgs::Factory msg;

// Model file to load msg.set_sdf_filename("model://cylinder");

// Pose to initialize the model to    msgs::Set(msg.mutable_pose,     math::Pose(math::Vector3(1, -2, 0), math::Quaternion(0, 0, 0)));

// Send the message factoryPub->Publish(msg); }   } };

// Register this plugin with the simulator GZ_REGISTER_WORLD_PLUGIN(Factory) }


 * 1) The Code Explained ###

The first part of the code creates a world plugin.

#include "gazebo/physics/physics.h"       #include "gazebo/common/common.h"        #include "gazebo/gazebo.hh"

namespace gazebo {         class Factory : public WorldPlugin {           public: void Load(physics::WorldPtr _parent, sdf::ElementPtr /*_sdf*/)

Within the `Load` function are three different methods for model insertion.

The first method uses a World method to load a model based on a file in the resource path defined by the GAZEBO_RESOURCE_PATH environment variable.

// Option 1: Insert model from file via function call. // The filename must be in the GAZEBO_MODEL_PATH environment variable. _parent->InsertModelFile("model://box");

The second method uses a World method to load a model based on string data.

// Option 2: Insert model from string via function call. // Insert a sphere model from string sdf::SDF sphereSDF; sphereSDF.SetFromString(                "\                  \                    1 2 0 0 0 0 \                    \                      0 0 .5 0 0 0 \                      \                        \                           0.5  \                        \                      \                      \                        \                           0.5  \                        \                      \                    \                  \                "); _parent->InsertModelSDF(sphereSDF);

The third method uses the message passing mechanism to insert a model. This method is most useful for stand along applications that communicate with Gazebo over a network connection.

// Option 3: Insert model from file via message passing. {               // Create a new transport node transport::NodePtr node(new transport::Node); // Initialize the node with the world name node->Init(_parent->GetName); // Create a publisher on the ~/factory topic transport::PublisherPtr factoryPub = node->Advertise("~/factory"); // Create the message msgs::Factory msg; // Model file to load msg.set_sdf_filename("model://cylinder"); // Pose to initialize the model to               msgs::Set(msg.mutable_pose,                    math::Pose(math::Vector3(1, -2, 0), math::Quaternion(0, 0, 0))); // Send the message factoryPub->Publish(msg);


 * 1) Compile ###

Assuming the reader has gone through the Plugin Overview Tutorial, all that needs to be done in addition is save the above code as `~/gazebo_plugin_tutorial/factory.cc` and add the following lines to `~/gazebo_plugin_tutorial/CMakeLists.txt`

add_library(factory SHARED factory.cc) target_link_libraries(factory ${GAZEBO_libraries})

Compiling this code will result in a shared library, ~/gazebo_plugin_tutorial/build/libfactory.so, that can be inserted in a Gazebo simulation.

mkdir ~/gazebo_plugin_tutorial/build cd ~/gazebo_plugin_tutorial/build cmake ../ make


 * 1) Make the shapes ##

Make a models directory with a box and a cylinder inside

mkdir ~/gazebo_plugin_tutorial/models cd ~/gazebo_plugin_tutorial/models mkdir box cylinder

Create a box model

cd box gedit model.sdf

Copy and paste the following into box/model.sdf

   1 2 0 0 0 0    <link name ='link'> 0 0 .5 0 0 0      <collision name ='collision'> 1 1 1       <visual name ='visual'> 1 1 1

Create a `model.config` file

gedit model.config

Copy the following into `model.config`

<?xml version='1.0'?>

box 1.0  model.sdf

me    somebody@somewhere.com

A simple Box.

Navigate to the cylinder directory, and create a new `model.sdf` file

cd ~/gazebo_plugin_tutorial/models/cylinder gedit model.sdf

Copy the following into `model.sdf`

<?xml version='1.0'?> <sdf version ='1.4'> <model name ='cylinder'> 1 2 0 0 0 0    <link name ='link'> 0 0 .5 0 0 0      <collision name ='collision'> 0.5 1        <visual name='visual'> 0.5 1

Create a model.config file

gedit model.config

Copy the following into model.config

<?xml version='1.0'?>

cylinder 1.0  model.sdf

me    somebody@somewhere.com

A simple cylinder.


 * 1) Run the code ###

Make sure your $GAZEBO_MODEL_PATH refers to your new models directory

export GAZEBO_MODEL_PATH=$HOME/gazebo_plugin_tutorial/models:$GAZEBO_MODEL_PATH

Add your library path to the `GAZEBO_PLUGIN_PATH`:

export GAZEBO_PLUGIN_PATH=$HOME/gazebo_plugin_tutorial/build:$GAZEBO_PLUGIN_PATH

Create a world SDF file called ~/gazebo_plugin_tutorial/factory.sdf

cd ~/gazebo_plugin_tutorial gedit factory.sdf

Copy the following into the world

<?xml version="1.0"?> <sdf version="1.4"> model://ground_plane

model://sun <plugin name="factory" filename="libfactory.so"/>

Run the server.

gzserver ~/gazebo_plugin_tutorial/factory.sdf

Run the client in a new terminal.

gzclient

The client should show an environment with a sphere, box, and cylinder arranged in a row.