This plugin example programmatically modifies gravity.
Source: gazebo/examples/plugins/world_edit
Use the gazebo_plugin_tutorial
from the previous plugin tutorials
$ mkdir ~/gazebo_plugin_tutorial; cd ~/gazebo_plugin_tutorial
Create a file called ~/gazebo_plugin_tutorial/world_edit.world
$ gedit world_edit.world
Add the following contents to it:
<?xml version ='1.0'?>
<sdf version ='1.4'>
<world name='default'>
<include>
<uri>model://ground_plane</uri>
</include>
<include>
<uri>model://sun</uri>
</include>
<plugin filename="libworld_edit.so" name="world_edit"/>
</world>
</sdf>
Create a file called ~/gazebo_plugin_tutorial/world_edit.cc
:
$ gedit world_edit.cc
Add the following content to it:
#include <sdf/sdf.hh>
#include <ignition/math/Pose3.hh>
#include "gazebo/gazebo.hh"
#include "gazebo/common/Plugin.hh"
#include "gazebo/msgs/msgs.hh"
#include "gazebo/physics/physics.hh"
#include "gazebo/transport/transport.hh"
/// \example examples/plugins/world_edit.cc
/// This example creates a WorldPlugin, initializes the Transport system by
/// creating a new Node, and publishes messages to alter gravity.
namespace gazebo
{
class WorldEdit : public WorldPlugin
{
public: void Load(physics::WorldPtr _parent, sdf::ElementPtr _sdf)
{
// Create a new transport node
transport::NodePtr node(new transport::Node());
// Initialize the node with the world name
node->Init(_parent->Name());
// Create a publisher on the ~/physics topic
transport::PublisherPtr physicsPub =
node->Advertise<msgs::Physics>("~/physics");
msgs::Physics physicsMsg;
physicsMsg.set_type(msgs::Physics::ODE);
// Set the step time
physicsMsg.set_max_step_size(0.01);
// Change gravity
msgs::Set(physicsMsg.mutable_gravity(),
ignition::math::Vector3d(0.01, 0, 0.1));
physicsPub->Publish(physicsMsg);
}
};
// Register this plugin with the simulator
GZ_REGISTER_WORLD_PLUGIN(WorldEdit)
}
// Create a new transport node
transport::NodePtr node(new transport::Node());
// Initialize the node with the world name
node->Init(_parent->Name());
We create a new node pointer, and initialize it to using the world name. The world name allows the node to communicate with one specific world.
// Create a publisher on the ~/physics topic
transport::PublisherPtr physicsPub =
node->Advertise<msgs::Physics>("~/physics");
A publisher is created for sending physics messages on the "~/physics" topic.
msgs::Physics physicsMsg;
physicsMsg.set_type(msgs::Physics::ODE);
// Set the step time
physicsMsg.set_max_step_size(0.01);
// Change gravity
msgs::Set(physicsMsg.mutable_gravity(),
ignition::math::Vector3d(0.01, 0, 0.1));
physicsPub->Publish(physicsMsg);
A physics message is created, and the step time and gravity are altered. This message is then published to the "~/physics" topic.
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/world_edit.cc
and add the following lines to ~/gazebo_plugin_tutorial/CMakeLists.txt
add_library(world_edit SHARED world_edit.cc)
target_link_libraries(world_edit ${GAZEBO_LIBRARIES})
Compiling this code will result in a shared library, ~/gazebo_plugin_tutorial/build/libworld_edit.so
, that can be inserted in a Gazebo simulation.
$ mkdir ~/gazebo_plugin_tutorial/build
$ cd ~/gazebo_plugin_tutorial/build
$ cmake ../
$ make
First you need to add the folder to the GAZEBO_PLUGIN_PATH
environment variable:
export GAZEBO_PLUGIN_PATH=${GAZEBO_PLUGIN_PATH}:~/gazebo_plugin_tutorial/build/
Then in a terminal
$ cd ~/gazebo_plugin_tutorial
$ gazebo world_edit.world
You should see an empty world.
Now add a box to the world using the Box icon located above the render window. The box should float up and away from the camera.