九州工業大学 CIR-KIT Blog

九工大自律移動ロボット製作プロジェクトCIR-KITの技術系ブログ

No.7-1:プラグインを書く (Gazebo Plugin 101 編)

gazebo_logo

検証日時

03/04/2015 (Wed)

概要

Gazeboのチュートリアル第七弾「Write a plugin」。 プラグインを使えば、モデルやセンサ、worldプロパティをコントロールしたり、Gazeboを起動させたりできます。様々な目的のために、どのようにしてプラグインを作成したり、ロードしたりしたらよいかを述べてゆきます。 今回はその「Gazebo plugin 101」編です。 公式サイトを適当に翻訳しただけですので、あしからず。

レベル

INTERMEDIATE

環境
PC : Lenovo ThinkPad X240
Prosessor : Intel Core i7-4600U (2.10GHz, 4MB, 1600MHz)
RAM : PC3-12800 DDR3L (8GB)
OS : Ubuntu 14.04 LTS 64bit
Kernel : 3.13.0-44-generic
Gazebo : Version 5.0.1
参考

GAZEBO Tutorial-Write a Plugin

Gazeboプラグインの概要

プラグインとは、共有ライブラリとしてコンパイルされ、シミュレーションに取り込まれるコードの集合です。標準C++クラスを通じて、プラグインはすべてのGazeboの機能に直接アクセスします。
プラグインは有用です。なぜなら、:

  • Gazeboのほとんどすべてのアスペクトを開発者がコントロールできる。
  • 簡単に共有できる独立したルーチンがある。
  • 実行中のシステムに挿入したり、削除したりできる。

Gazeboの最新バージョンはコントローラとして使われています。これは、プラグインと同じような特徴を持ちますが、Gazeboのなかで、静的にコンパイルされています。プラグインはより柔軟に、かつシミュレーションに含まれる機能を選べるようにします。
以下の様なとき、プラグインを使うべきです。:

  • シミュレーションをプログラマチックに変更したいとき
    • モデルを動かす、イベントの反応をかえす、前提条件を持った新しいモデルを挿入するとき
      • トランスポートレイヤのオーバーヘッド無しに、Gazeboに高速なインターフェースがほしいとき
    • メッセージのシリアル化と非シリアル化
      • 他に利益をもたらすコードがあり、それを共有したいとき

プラグインの種類

現在、以下のようにプラグインは5種類あります。

  1. World
  2. Model
  3. Sensor
  4. System.
  5. Visual.

それぞれのプラグインタイプは異なるGazeboのコンポーネントで管理されています。例えば、ModelプラグインがGazeboのある特定のモデルのコントローラに接続されているなどが挙げられます。同じように、Worldプラグインはworldに接続され、Sensorプラグインはsensorに接続されます。システムプラグインはコマンドラインで定義され、Gazeboの初回起動時にロードします。このプラグインは初回起動時にユーザーコントロールを与えます。
プラグインの種類は望みの機能に沿ったものでなければなりません。Worldプラグインは物理エンジンや証明の設定などのworldプロパティをコントロールするのに使って下さい。Modelプラグインは、ジョイントやモデルの姿勢をコントロールするために使用して下さい。センサプラグインはセンサ情報を定義し、センサプロパティをコントロールするために使用して下さい。

Hello World プラグイン

プラグインはシンプルに設計されています。ベアボーンのworldプラグインにはいくつかの関数と共にクラスが含まれています。
最初に、デビアンパッケージよりGazeboをインストールしたら、Gazeboの開発用ファイルをインストールするのを忘れないで下さい。もし、あなたがGazeboをソースコードからインストールしたなら、このステップは無視して構いません。もしgazebo5よりも古いリリースのGazeboを使用しているなら、5の部分を持っているバージョンの番号に置き換えて以下の内容をご覧ください。

1
sudo apt-get install libgazebo5-dev

続いて、ディレクトリを作り、新しい.ccファイルのプラグインを作成して下さい。

1
2
3
 mkdir ~/gazebo_plugin_tutorial
 cd ~/gazebo_plugin_tutorial
 gedit hello_world.cc

できたら、以下をhello_world.ccにコピーして下さい。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#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)
}

上記のコードはGazeboのソースコード : examples/plugins/helloworld/helloworldにもあります。尚、リンク先にはCMakeLists.txtファイルもあります。

コードの説明

1
2
3
4
#include <gazebo/gazebo.hh>

namespace gazebo
{

gazebo/gazebo.hhファイルは基本的なGazeboの関数群のコアをインクルードしています。これは、gazebo/physics/physics.hhgazebo/rendering/rendering.hhgazebo/sensors/sensors.hhを臨機応変でインクルードされるべきものとしてインクルードしていません。すべてのプラグインはgazeboという名前空間が必要です。

1
2
3
4
5
6
  class WorldPluginTutorial : public WorldPlugin
  {
    public: WorldPluginTutorial() : WorldPlugin()
            {
              printf("Hello World!\n");
            }

それぞれのプラグインはプラグインタイプを継承しなければなりません。今回の例では、WorldPluginクラスを継承します。

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

その他の必須の関数はLoadです。これはロードされるSDFファイルによって定義される属性や要素を含むSDF要素を受け取ります。

1
  GZ_REGISTER_WORLD_PLUGIN(WorldPluginTutorial)

最終的に、プラグインはGZ_REGISTER_WORLD_PLUGINマクロを使ってシミュレーションと共に登録されなければなりません。このマクロへの唯一のパラメータはプラグインクラスの名前です。それぞれのプラグインタイプに合わせて登録されたマクロの照合が行われます。: GZ_REGISTER_MODEL_PLUGIN, GZ_REGISTER_SENSOR_PLUGIN, GZ_REGISTER_SYSTEM_PLUGINGZ_REGISTER_VISUAL_PLUGINなどです。
以下のセクションではこのプラグインをどのようにしてコンパイルするかについての簡単な説明も行ってゆきます。

プラグインをコンパイルする

Gazeboが正しくインストールされていることを確認して下さい。
上記のプラグインをコンパイルするために、~/gazebo_plugin_tutorial/CMakeListsを作成して下さい。:

1
 gedit ~/gazebo_plugin_tutorial/CMakeLists.txt

以下をCMakeLists.txtにコピーして下さい。:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

find_package(Boost REQUIRED COMPONENTS system)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})

include (FindPkgConfig)
if (PKG_CONFIG_FOUND)
  pkg_check_modules(GAZEBO gazebo)
endif()
include_directories(${GAZEBO_INCLUDE_DIRS})
link_directories(${GAZEBO_LIBRARY_DIRS})

add_library(hello_world SHARED hello_world.cc)
target_link_libraries(hello_world ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})

ビルドディレクトリを作成して下さい。

1
2
 mkdir ~/gazebo_plugin_tutorial/build
 cd ~/gazebo_plugin_tutorial/build

コードをコンパイルして下さい。

1
2
 cmake ../
 make

コンパイルの結果は共有ライブラリにでき、~/gazebo_plugin_tutorial/build/libhello_world.soをGazeboシミュレーションに挿入することができます。
最後に、ライブラリパスをGAZEBO_PLUGIN_PATHに追加して下さい。:

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

プラグインを使う

プラグインを共有ライブラリとしてコンパイルしたら(上記をご覧ください)、SDFファイルのworldやmodelにそれを追加することができます(詳しくは、SDFドキュメントをご覧ください)。最初に、GazeboはSDFファイルを解析し、プラグインを設置します。そしてコードを読み込みます。Gazeboがプラグインを探すことができるというのはとても重要なことです。プラグインへの絶対パスが定義されている、もしくはプラグインがGAZEBOPLUGINPATHパスの中にあればプラグインを利用した環境が利用可能です。
worldファイルの例は、examples/plugins/helloworld/helloworldでも見つけることができます。

1
2
3
4
5
6
<?xml version="1.0"?>
<sdf version="1.4">
  <world name="default">
    <plugin name="hello_world" filename="libhello_world.so"/>
  </world>
</sdf>

~/gazebo_plugin_tutorial/hello.worldにあるファイルのコピーを作成して下さい。
もし、GAZEBO_PLUGIN_PATHの中にビルドディレクトリがないなら、Gazeboサーバーをビルドディレクトリから起動しなければなりません。

1
2
$ cd build
$ gzserver ../hello.world --verbose

うまく実行できれば、以下のような出力を得られるはずです。:

1
2
3
4
5
6
7
8
Gazebo multi-robot simulator, version 1.9.5
Copyright (C) 2013 Open Source Robotics Foundation.
Released under the Apache 2 License.
http://gazebosim.org

Msg Waiting for master
Msg Connected to gazebo master @ http://localhost:11345
Hello World!