Tutorials/1.3/plugins/factory


 * Prerequisites:** Model Manipulation Plugin Tutorial


 * Code:** `/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

cd ~/gazebo_plugin_tutorial

Copy the following code into a file called `factory.cc.`


 * 1) include "physics/physics.hh"
 * 2) include "common/common.hh"
 * 3) include "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) }

The first part of the code creates a world plugin.

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

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 Simple World 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.


 * 1) Make the shapes ###

Make a models directory with a box and a cylinder inside

mkdir models cd 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 \   \ 0 0 .5 0 0 0 \     <collision name ='collision'>\ \          1 1 1  \        \      \      <visual name ='visual'>\ \          1 1 1  \        \      \    \  \

Copy the following into box/manifest.xml

<?xml version="1.0"?>

box 1.0  model.sdf

me    somebody@somewhere.com

A simple Box.

Copy the following into cylinder/model.sdf

<sdf version ='1.3'>\ <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  \        \      \    \  \

Copy the following into cylinder/manifest.xml

<?xml version="1.0"?>

cylinder 1.0  model.sdf

me    somebody@somewhere.com

A simple cylinder.

Make sure your $GAZEBO_MODEL_PATH refers to your new models directory

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


 * 1) Run the code ###

Create a world file called ~/factory_plugin/factory.world

<?xml version="1.0"?> <gazebo version="1.2"> model://ground_plane

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

Run the server.

gzserver ~/gazebo_plugin_tutorial/factory.world

Run the client in a new terminal.

gzclient

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