Plugins 101 - modulabs/gazebo-tutorial GitHub Wiki

Overview of Gazebo Plugins

ํ”Œ๋Ÿฌ๊ทธ์ธ์€ shared library (๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)๋กœ ์‚ฝ์ž…ํ•œ๋‹ค. ํ”Œ๋Ÿฌ๊ทธ์ธ์€ standard C++ classes (ํ‘œ์ค€ c++ ํด๋ž˜์Šค)๋กœ ๋ชจ๋“  ๊ธฐ๋Šฅ์— ์ง์ ‘ ์ ‘๊ทผํ•˜์—ฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์•„๋ž˜์™€ ๊ฐ™์€ ์ด์œ ๋กœ ์œ ์šฉํ•˜๋‹ค:

  • ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ฐ€์ œ๋ณด์˜ ๊ฑฐ์˜ ๋ชจ๋“  ๋ถ€๋ถ„์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค
  • ์‰ฝ๊ฒŒ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ๋…๋ฆฝ์ ์ธ ๋ฃจํ‹ด์ด๋‹ค
  • ์‹คํ–‰์ค‘์ธ ์‹œ์Šคํ…œ์—์„œ ์‚ฝ์ž… ๋ฐ ์ œ๊ฑฐ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค

์ด์ „ ๋ฒ„์ „์˜ ๊ฐ€์ œ๋ณด์—์„œ๋Š” controllers (์ปจํŠธ๋กค๋Ÿฌ)๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค. ์ปจํŠธ๋กค๋Ÿฌ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜์ง€๋งŒ, ์ •์ ์œผ๋กœ ์ปดํŒŒ์ผ๋˜์—ˆ๋‹ค (statically compiled). ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ๋ณด๋‹ค ๋” ์œตํ†ต์„ฑ์ด ์žˆ์–ด (flexible), ์‚ฌ์šฉ์ž๊ฐ€ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์— ํฌํ•จํ•  ๊ธฐ๋Šฅ์„ ๊ณ ๋ฅด๊ณ  ์„ ํƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฝ์šฐ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค:

  • ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹ (programmatically)์œผ๋กœ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์„ ๋ณ€๊ฒฝํ•˜๊ธฐ๋ฅผ ์›ํ•˜๋Š” ๊ฒฝ์šฐ

์˜ˆ: ๋ชจ๋ธ ์ด๋™, ์ด๋ฒคํŠธ ๋Œ€์‘, ์ „์ œ ์กฐ๊ฑด์„ ๊ฐ€์ง„ ์ƒˆ๋กœ์šด ๋ชจ๋ธ ์‚ฝ์ž…

  • ์ „์†ก ์ธต (transport layer)์˜ ์˜ค๋ฒ„ํ—ค๋“œ(overhead) ์—†์ด ๊ฐ€์ œ๋ณด์™€ ๋น ๋ฅธ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์›ํ•˜๋Š” ๊ฒฝ์šฐ

์˜ˆ: ๋ฉ”์‹œ์ง€์˜ ์ง๋ ฌํ™” ๋ฐ ๋น„ ์ง๋ ฌํ™”๊ฐ€ ์—†๋‹ค.

  • ๋‹ค๋ฅธ์‚ฌ๋žŒ์—๊ฒŒ ๋„์›€์ด ๋˜๊ฑฐ๋‚˜ ๊ณต์œ ํ•˜๊ธฐ๋ฅผ ์›ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ

Plugin Types

ํ˜„์žฌ๋Š” 6 ๊ฐ€์ง€ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์žˆ๋‹ค.

  1. World
  2. Model
  3. Sensor
  4. System
  5. Visual
  6. GUI (Graphical User Interface)

๊ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ๊ฐ€์ œ๋ณด์˜ ๋‹ค๋ฅธ ์š”์†Œ๋กœ ๊ด€๋ฆฌ๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Model Plugin์€ ๊ฐ€์ œ๋ณด์˜ ํŠน์ • ๋ชจ๋ธ์— ์ฒจ๋ถ€ํ•˜์—ฌ ์ œ์–ด๋œ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ World plugin ์€ world์—, Sensor plugin์€ ํŠน์ • ์„ผ์„œ์— ์ ์šฉ๋œ๋‹ค. System plugin์€ ๋ช…๋ น์ค„ (command line)์—์„œ ์ง€์ •๋˜๊ณ , ๊ฐ€์ œ๋ณด๊ฐ€ ์‹œ์ž‘ํ•˜๋Š” ๋™์•ˆ ๋กœ๋”ฉ๋œ๋‹ค. ์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์‹œ์ž‘ ํ”„๋กœ์„ธ์Šค(Startup process)๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ๊ณตํ•œ๋‹ค.

ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค. World plugin์€ ๋ฌผ๋ฆฌ ์—”์ง„, ์ฃผ๋ณ€ ์กฐ๋ช… ๋“ฑ์˜ world ์†์„ฑ์„ ์ œ์–ดํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค. Model plugin ์€ ๋ชจ๋ธ์˜ ์กฐ์ธํŠธ ๋ฐ ์ƒํƒœ๋ฅผ ์ œ์–ดํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค. Sensor plugin์€ ์„ผ์„œ ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ์„ผ์„œ ์†์„ฑ์„ ์ œ์–ดํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

Hello WorldPlugin!

ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ๋‹จ์ˆœํ•˜๊ฒŒ ์„ค๊ณ„๋˜์–ด์žˆ๋‹ค. Bare bones world plugin์€ ๋ช‡ ๊ฐ€์ง€ ๋ฉค๋ฒ„ ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” ํด๋ž˜์Šค๋กœ ๊ตฌ์„ฑ๋˜์–ด์žˆ๋‹ค.

๋จผ์ € debian์—์„œ ๊ฐ€์ œ๋ณด๋ฅผ ์„ค์น˜ํ–ˆ๋‹ค๋ฉด, ๊ฐ€์ œ๋ณด ๊ฐœ๋ฐœ ํŒŒ์ผ์„ ์„ค์น˜ํ–ˆ๋Š”์ง€ ํ™•์ธํ•ด๋ผ. ๋งŒ์•ฝ source๋กœ ๊ฐ€์ œ๋ณด๋ฅผ ์„ค์น˜ํ–ˆ๋‹ค๋ฉด, ์ด ๋‹จ๊ณ„๋ฅผ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ๊ฐ€์ œ๋ณด 6๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ๋ฒ„์ „์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด, ๋ฒ„์ „์„ 6์œผ๋กœ ๋ฐ”๊พธ์–ด๋ผ.

$ sudo apt-get install libgazebo6-dev

๊ทธ๋ฆฌ๊ณ  ์ƒˆ๋กœ์šด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์œ„ํ•œ ๋””๋ ‰ํ† ๋ฆฌ์™€ .cc ํŒŒ์ผ์„ ๋งŒ๋“ ๋‹ค:

$ mkdir ~/gazebo_plugin_tutorial
$ cd ~/gazebo_plugin_tutorial
$ gedit hello_world.cc

hello_world.cc ์— ์•„๋ž˜ ๋‚ด์šฉ์„ ๋ณต์‚ฌํ•œ๋‹ค:

#include <gazebo/gazebo.hh>

namespace gazebo
{
  class WorldPluginTutorial : public WorldPlugin
  {
    public: WorldPluginTutorial() : WorldPlugin()
            {
              printf("Hello World!\n");
            }

    public: void Load(physics::WorldPtr _world, sdf::ElementPtr _sdf)
            {
            }
  };
  GZ_REGISTER_WORLD_PLUGIN(WorldPluginTutorial)
}

์œ„ ์ฝ”๋“œ๋Š” the Gazebo sources์— ์žˆ์œผ๋ฉฐ, ๊ทธ์— ๋งž๋Š” CMakeLists.txt ํŒŒ์ผ๋„ ํ•จ๊ป˜์žˆ๋‹ค: examples/plugins/hello_world/hello_world.cc

Code Explained

#include <gazebo/gazebo.hh>

namespace gazebo
{

gazebo/gazebo.hh ํŒŒ์ผ์€ ๊ธฐ๋ณธ ๊ฐ€์ œ๋ณด ํ•จ์ˆ˜์˜ ํ•ต์‹ฌ ์š”์†Œ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค. gazebo/physics/physics.hh, ๋˜๋Š” gazebo/rendering/rendering.hh, gazebo/sensors/sensors.hh๋Š” ํ•„์š”์‹œ์— ํฌํ•จ๋˜์–ด์•ผํ•˜๋ฏ€๋กœ ํฌํ•จ๋˜์–ด์žˆ์ง€ ์•Š๋‹ค. ๋ชจ๋“  ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ๊ฐ€์ œ๋ณด ๋„ค์ž„์ŠคํŽ˜์ด์Šค (namespace)๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

  class WorldPluginTutorial : public WorldPlugin
  {
    public: WorldPluginTutorial() : WorldPlugin()
            {
              printf("Hello World!\n");
            }

ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ํ”Œ๋Ÿฌ๊ทธ์ธ ํƒ€์ž…์„ ์ƒ์†ํ•ด์•ผ ํ•˜๋ฉฐ, ์ด ๊ฒฝ์šฐ๋Š” WorldPlugin class๋ฅผ ์ƒ์†ํ•œ ๊ฒƒ์ด๋‹ค.

    public: void Load(physics::WorldPtr _world, sdf::ElementPtr _sdf)
            {
            }

Load ํ•จ์ˆ˜์˜์—์„œ ๋‹ค๋ฅธ ์ธ์ž๋Š” SDF์ธ๋ฐ, ๋กœ๋“œ๋œ SDF ํŒŒ์ผ์—๋Š” ์š”์†Œ(elements)์™€ ์†์„ฑ(attributes)์ด ํฌํ•จ๋˜์–ด์žˆ๋‹ค.

  GZ_REGISTER_WORLD_PLUGIN(WorldPluginTutorial)

๋งˆ์ง€๋ง‰์œผ๋กœ, ํ”Œ๋Ÿฌ๊ทธ์ธ์€ GZ_REGISTER_WORLD_PLUGIN ๋งคํฌ๋กœ(macro)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์— ๋“ฑ๋กํ•ด์•ผ ํ•œ๋‹ค. ์ด ๋งคํฌ๋กœ์˜ ์œ ์ผํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ(parameter)๋Š” ํด๋ž˜์Šค ์ด๋ฆ„์ด๋‹ค. ๊ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ ํƒ€์ž…์— ๋”ฐ๋ผ ์‚ฌ์šฉํ•˜๋Š” ๋งคํฌ๋กœ๊ฐ€ ์žˆ๋‹ค: GZ_REGISTER_MODEL_PLUGIN, GZ_REGISTER_SENSOR_PLUGIN, GZ_REGISTER_GUI_PLUGIN, GZ_REGISTER_SYSTEM_PLUGIN and GZ_REGISTER_VISUAL_PLUGIN.

๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ปดํŒŒ์ผ ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•˜์—ฌ ์„ค๋ช…ํ•œ๋‹ค.

Compiling the Plugin

๊ฐ€์ œ๋ณด๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์น˜๋˜์–ด์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

์œ„ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ปดํŒŒ์ผํ•˜๋ ค๋ฉด ~/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})

๋ชจ๋“  downstream software๋ฅผ ๊ฐ€์ œ๋ณด์— ์ปดํŒŒ์ผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” c++11 ํ”Œ๋ž˜๊ทธ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์•„๋ž˜ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•œ๋‹ค:

list(APPEND CMAKE_CXX_FLAGS "${GAZEBO_CXX_FLAGS}")

๋นŒ๋“œ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค

$ mkdir ~/gazebo_plugin_tutorial/build
$ cd ~/gazebo_plugin_tutorial/build

Compile the code.

$ cmake ../
$ make

์ปดํŒŒ์ผํ•˜๋ฉด ๊ฐ€์ œ๋ณด ์‹œ๋ฎฌ๋ ˆ์ด์…˜์— ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณต์œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค: ~/gazebo_plugin_tutorial/build/libhello_world.so

๋งˆ์ง€๋ง‰์œผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฒฝ๋กœ๋ฅผ GAZEBO_PLUGIN_PATH์— ์ถ”๊ฐ€ํ•œ๋‹ค:

$ export GAZEBO_PLUGIN_PATH=${GAZEBO_PLUGIN_PATH}:~/gazebo_plugin_tutorial/build

Note: ์ด๊ฒƒ์€ ํ˜„์žฌ ์‰˜ ๊ฒฝ๋กœ๋งŒ ๋ณ€๊ฒฝํ•œ๋‹ค. ๋งŒ์•ฝ ์ƒˆ๋กœ์šด ํ„ฐ๋ฏธ๋„์„ ์—ด๋•Œ๋งˆ๋‹ค ๋„ˆ์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ~/.bashrc ํŒŒ์ผ์— ์œ„ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ด๋ผ.

Using a Plugin

ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์œ„์™€๊ฐ™์ด ๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ปดํŒŒ์ผํ•˜๋ฉด, world, model, ๋˜๋Š” SDF ํŒŒ์ผ (์ƒ์„ธ ์ •๋ณด๋Š” SDF ๋ฌธ์„œ ์ฐธ๊ณ )์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹œ์ž‘ ์‹œ ๊ฐ€์ œ๋ณด๋Š” SDF ํŒŒ์ผ์„ ๋ถ„์„(parsing)ํ•˜๊ณ , ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ฐพ์•„ ์ฝ”๋“œ๋ฅผ ๋กœ๋“œํ•œ๋‹ค. ๊ฐ€์ œ๋ณด๊ฐ€ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ฐพ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค. ํ”Œ๋Ÿฌ๊ทธ์ธ์— ๋Œ€ํ•œ ์ „์ฒด ๊ฒฝ๋กœ๊ฐ€ ์ง€์ •๋˜์—ˆ๊ฑฐ๋‚˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด GAZEBO_PLUGIN_PATH ํ™˜๊ฒฝ๋ณ€์ˆ˜์˜ ๊ฒฝ๋กœ์— ์กด์žฌํ•ด์•ผ ํ•œ๋‹ค.

world ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณต์‚ฌํ•œ๋‹ค. ์˜ˆ์ œ ํŒŒ์ผ์€ 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 ~/gazebo_plugin_tutorial/hello.world --verbose

์•„๋ž˜์™€ ๋น„์Šทํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค:

Gazebo multi-robot simulator, version 6.1.0
Copyright (C) 2012-2015 Open Source Robotics Foundation.
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!
โš ๏ธ **GitHub.com Fallback** โš ๏ธ