概述
插件是一段代码,它被编译为一个共享库,并插入到仿真中。这个插件可以通过标准的C++类直接访问Gazebo的所有功能。
插件是有用的,因为它们:
- 让开发人员控制Gazebo的任何一个方面
- 是独立的程序,很容易共享
- 可以从一个正在运行的系统中插入和删除
以前版本的Gazebo使用了控制器。它们的行为方式与插件类似,但被静态编译为Gazebo。插件更加灵活,允许用户选择他们在仿真中包含的功能。
你应该使用一个插件,当:
- 你想通过编程来改变一个仿真
移动模型,对事件作出响应,在给定的前提条件下插入新模型
- 如果没有传输层的开销,您需要一个快速接口到gazebo。
没有对消息进行序列化和反序列化。
- 你有一些可以让别人受益的代码并且想要分享它
插件类型
目前有6种插件
- 世界
- 模型
- 传感器
- 系统
- 视觉
- GUI
每个插件类型由Gazebo的不同组件管理。例如,在Gazebo中附加了一个模型插件并控制了一个特定的模型。类似地,一个世界插件连接到一个世界,一个传感器插件到一个特定的传感器。系统插件是在命令行上指定的,并且在Gazebo启动时首先加载。这个插件让用户可以控制启动过程。
应该根据需要的功能选择插件类型。使用一个世界插件来控制世界的属性,例如物理引擎,环境照明等等。使用一个模型插件来控制关节,以及一个模型的状态。使用传感器插件来获取传感器信息和控制传感器属性。
Hello World插件
插件的设计很简单。一个简单的骨骼世界插件包含一个有一些成员函数的类。
首先,如果您从debians安装了Gazebo,请确保您已经安装了Gazebo开发文件。如果您从源代码安装了Gazebo,那么您可以忽略这一步。如果你有一个除gazebo6以外的版本,用你所拥有的版本号替换6。
sudo apt-get install libgazebo6-dev
接下来,为新插件创建一个目录和一个a.cc文件:
$ mkdir ~/gazebo_plugin_tutorial
$ cd ~/gazebo_plugin_tutorial
$ gedit hello_world.cc
把下面的内容复制到hello_world.cc:
#include <gazebo/gazebo.hh>
namespace gazebo
{
classWorldPluginTutorial : public WorldPlugin
{
public:WorldPluginTutorial() : WorldPlugin()
{
printf("Hello World!\n");
}
public:void Load(physics::WorldPtr _world, sdf::ElementPtr _sdf)
{
}
};
GZ_REGISTER_WORLD_PLUGIN(WorldPluginTutorial)
}
上面的代码也位于Gazebo的源代码中:examples/plugins/hello_world/hello_world.cc,以及适当的CMakeLists.txt文件。(http://bitbucket.org/osrf/gazebo/src/gazebo6/examples/plugins/hello_world)
代码解释
#include <gazebo/gazebo.hh>
namespace gazebo
{
gazebo/gazebo.hh文件包含一组基本的gazebo函数。它不包括gazebo/physics/physics.hh,gazebo/rendering/rendering.hh,gazebo/sensors/sensors.hh。这些应该包括在案例的基础上。所有插件必须在gazebo命名空间中。
classWorldPluginTutorial : public WorldPlugin
{
public:WorldPluginTutorial() : WorldPlugin()
{
printf("Hello World!\n");
}
每个插件都必须从一个插件类型继承,在这个例子中是WorldPlugin类。
public:void Load(physics::WorldPtr _world, sdf::ElementPtr _sdf)
{
}
唯一的强制函数是Load,它接收到一个SDF元素,该元素包含在装载的SDF文件中指定的元素和属性。
GZ_REGISTER_WORLD_PLUGIN(WorldPluginTutorial)
最后,插件必须使用GZ_REGISTER_WORLD_PLUGIN宏在模拟器上注册。这个宏的唯一参数是plugin类的名称。每个插件类型都有对应的寄存器宏:GZ_REGISTER_MODEL_PLUGIN、GZ_REGISTER_SENSOR_PLUGIN、GZ_REGISTER_GUI_PLUGIN、GZ_REGISTER_SYSTEM_PLUGIN和GZ_REGISTER_VISUAL_PLUGIN。
下面的部分包含了如何编译这个插件的说明。
编译插件
请确保安装了gazebo。
要编译上面的插件,创建~/gazebo_plugin_tutorial/CMakeLists.txt:
$ gedit ~/gazebo_plugin_tutorial/CMakeLists.txt
复制下面的CMakeLists.txt:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
find_package(gazebo REQUIRED)
include_directories(${GAZEBO_INCLUDE_DIRS})
link_directories(${GAZEBO_LIBRARY_DIRS})
list(APPEND CMAKE_CXX_FLAGS"${GAZEBO_CXX_FLAGS}")
add_library(hello_world SHARED hello_world.cc)
target_link_libraries(hello_world${GAZEBO_LIBRARIES})
在gazebo6中新出现:现在所有的下游软件都需要C++11标志来针对gazebo的编译。这是在以下一行完成的:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}${GAZEBO_CXX_FLAGS}")
创建构建目录
$ mkdir ~/gazebo_plugin_tutorial/build
$ cd ~/gazebo_plugin_tutorial/build
编译代码
$ cmake ../
$ make
编译将产生一个共享库,~/gazebo_plugin_tutorial/build/libhello_world.so。因此,这可以插入到Gazebo仿真中。
最后,将您的库路径添加到GAZEBO_PLUGIN_PATH:
$ exportGAZEBO_PLUGIN_PATH=${GAZEBO_PLUGIN_PATH}:~/gazebo_plugin_tutorial/build
注意:这只改变了当前shell的路径。如果你想在你打开的每一个新模板中使用你的插件,请把上面一行附加到~/.bashrc文件。
使用插件
一旦您有了一个作为共享库编译的插件(见上面),您可以将它附加到一个SDF文件中的一个世界或模型(参见SDF文档以获得更多信息)。在启动时,Gazebo会解析SDF文件,定位插件,并加载代码。重要的是,Gazebo能够找到插件。要么是指定插件的完整路径,要么是插件存在于GAZEBO_PLUGIN_PATH环境变量的一个路径中。
SDF文档:http://gazebosim.org/sdf.html
创建一个世界文件并将下面的代码复制到其中。示例世界文件也可以在examples/plugins/hello_world/hello.world中找到。
(https://bitbucket.org/osrf/gazebo/src/gazebo6/examples/plugins/hello_world/hello.world)
$ gedit ~/gazebo_plugin_tutorial/hello.world
<?xml version="1.0"?> <sdf version="1.4"> <world name="default"> <plugin name="hello_world"filename="libhello_world.so"/> </world> </sdf>
现在用gzserver打开它:
$ gzserver ~/gazebo_plugin_tutorial/hello.world--verbose
您应该看到类似的输出:
Gazebo multi-robot simulator, version 6.1.0
Copyright (C) 2012-2015 Open Source RoboticsFoundation.
Released under the Apache 2 License.
http://gazebosim.org
[Msg] Waiting for master.
[Msg] Connected to gazebo master @ http://127.0.0.1:11345
[Msg] Publicized address: 172.23.1.52
Hello World!