Tutorials/1.0/plugins/factory


 * Prerequisites:** Simple World 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.`

#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*/) {             // Option 1: Insert model from file via function call. // The filename must be in the GAZEBO_RESOURCE_PATH environment variable. _parent->InsertModelFile("models/box.model"); // 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("models/cylinder.model"); // 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_RESOURCE_PATH environment variable. _parent->InsertModelFile("models/box.model");

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("models/cylinder.model"); // 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) Run the code ###

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

  model://ground_plane

model://sun 

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.