九州工業大学 CIR-KIT Blog

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

No.6-4:GazeboをROSに繋ぐ (Roslaunchを使う 編)

gazebo_logo

検証日時

02/15/2015 (Sun)

概要

Gazeboのチュートリアル第六弾「Connect to ROS」。 ROSはロボットの制御フレームワークです。このチュートリアルでは、GazeboとROSのインターフェースについて説明します。 今回はその「Using roslaunch」編です。 公式サイトを適当に翻訳しただけですので、あしからず。

レベル

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-Connect to ROS

チュートリアル : Gazebbo、worldファイル、URDFモデルを起動するためのroslaunchを使う

Gazeboを起動したり、worldモデルを開いたり、シミュレーション環境にロボットモデルをスポーンさせる方法はたくさんあります。このチュートリアルでは、rosrunroslaunchを使ったROSを用いてのそれらの方法を説明します。ROSパッケージの中のURDFを保存し、様々なROSワークスペースのリソースパスを保存する方法を含みます。

worldモデルを開くためにroslaunchを使う

roslaunchツールはROSのノードを起動し、ROSの中でロボットを起動する基本的な方法です。Gazeboの空のworlを起動することは、これまでのチュートリアルで行ってきたrosrunコマンドを使うのと同じです。以下のように、単純に実行してみましょう。

1
roslaunch gazebo_ros empty_world.launch

roslaunch引数

Gazeboの挙動を変更するためのlaunchファイルには、以下の引数を追加することができます。:

pused

Gazeboを一時停止した状態で起動する(default false)

usesimtime

ROSの/clockトピックを通じて配信される、Gazebo-publishedのシミュレーションタイムを取得するために、ROSノードに時間を問い合わせます。(default true)

gio

Gazeboのユーザーインターフェースウィンドウをlaunchします。(default true)

headless

(Ogre)コンポーネントを記録することで、シミュレータが呼び出しているすべての関数を表示します。gui:=trueと一緒では起動しません。(default false)

debug

gdbを使用したデバッグモードでgzserver(Gazeboのサーバー)を起動します。(default false)

roslaunchコマンドの例

通常、引数のデフォルト値はすべて必要であり、以下のように記述します。:

1
roslaunch gazebo_ros empty_world.launch paused:=true use_sim_time:=false gui:=true throttled:=false headless:=false debug:=true

他のデモworldをlaunchする

gazebo_rosパッケージには、他のデモworldがすでに含まれています。以下がその内容です。:

1
2
3
4
roslaunch gazebo_ros willowgarage_world.launch
roslaunch gazebo_ros mud_world.launch
roslaunch gazebo_ros shapes_world.launch
roslaunch gazebo_ros rubble_world.launch

mudworld.launchは、シンプルなジョイントメカニズムをlaunchするものであることを知っておいていください。mudworld.launchは以下の内容のlaunchファイルです。

1
2
3
4
5
6
7
8
9
10
11
<launch>
  <!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="worlds/mud.world"/> <!-- Note: the world_name is with respect to GAZEBO_RESOURCE_PATH environmental variable -->
    <arg name="paused" value="false"/>
    <arg name="use_sim_time" value="true"/>
    <arg name="gui" value="true"/>
    <arg name="headless" value="false"/>
    <arg name="debug" value="false"/>
  </include>
</launch>

このlaunchファイルでは、emptyworld.launchから機能するのに必要不可欠なほとんどすべてを継承しています。mud.Worldファイルとともにemptyworld.launchファイルを用いる代わりに、私達が変更しなければならないパラメータはworldnameパラメータだけです。他の引数はデフォルト値を設定しているだけです。

Worldファイル

mud_world.launchファイルをよく調べると、mud.worldファイルの構成に注目するでしょう。mud.worldの最初のいくつかの構成要素は以下のようになっています。:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  <sdf version="1.4">
    <world name="default">
      <include>
        <uri>model://sun</uri>
      </include>
      <include>
        <uri>model://ground_plane</uri>
      </include>
      <include>
        <uri>model://double_pendulum_with_base</uri>
        <name>pendulum_thick_mud</name>
        <pose>-2.0 0 0 0 0 0</pose>
      </include>
      ...
    </world>
  </sdf>

あなたのコンピュータ上で、フルバージョンのworldファイルを以下のセクションで確認してください。

このworldファイルでは、3つのモデルが参照されていることをわずかに確認できます。3つのモデルはローカルのGazeboモデルデータベースの中にあります。もし見つからなければ、Gazeboのオンラインデータベースより自動的にダウンロードしてきます。 worldファイルについて詳しく知りたければ、環境をつくろう !のチュートリアルをご覧ください。

worldファイルをコンピュータ上で検索する

worldファイルは、Gazeboのリソースパス上にある、/worldsディレクトリの中にあります。このパスはGazeboをどのようにインストールし、どのタイプのシステムを使っているかということに依存します。Gazeboリソースの位置を探すには、以下のコマンドを使用してください。:

1
env | grep GAZEBO_RESOURCE_PATH

典型的なパスだと、/usr/local/share/gazebo-1.9となるでしょう。/worldsに検索したパスを追加すると、mud.worldファイルを含む、Gazeboが使うディレクトリに直接接続できます。

独自のGazebo ROSパッケージを作る

Gazeboにロボットをスポーンさせる方法について続ける前に、最新版を使うために、ROSをGazeboと使う際の基本的なファイル構造(ヒエラルキー)についてまずは学びましょう。 ここまでの段階で、あなたのcatkinワークスペースはcatkin_wsという名前であると仮定します。もちろん、ワークスペースの名前は好きなものをつけてもらって構いません。例えば、あなたのcatkinワークスペースが以下のような位置にあるとします。:

1
/home/user/catkin_ws/src

/MYROBOT_descriptionという名前のパッケージの中に、あなたのロボットモデルにつながるすべてのものと、その記述についてがROSの基本的なパラメータとして存在し、Gazeoboとともに使用されるworldファイルとlaunchファイルは/MyROBOT_gazeboという名前のROSパッケージの中に存在します。ただし、MYROBOTの部分はあなたのロボット名です。これらの2つのパッケージにより、ファイル構造は以下のようになります。:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
../catkin_ws/src
    /MYROBOT_description
        package.xml
        CMakeLists.txt
        /urdf
            MYROBOT.urdf
        /meshes
            mesh1.dae
            mesh2.dae
            ...
        /materials
        /cad
    /MYROBOT_gazebo
        /launch
            MYROBOT.launch
        /worlds
            MYROBOT.world
        /models
            world_object1.dae
            world_object2.stl
            world_object3.urdf
        /materials
        /plugins

catkin_create_pkgコマンドは、新しいパッケージを作成する際に使用します。しかし、もし必要なら、rosbuiltを使っても簡単にそれを行うことができます。ほとんどすべてのフォルダとファイルは自明でなければなりません。 次のセクションでは、カスタムのworldファイルを使うためのセッティングについて説明してゆきます。

カスタムのworldファイルを作る

あなたのパッケージやロボットに特化したあなた独自のROSパッケージの中にカスタムの.worldを作成することができます。この短いチュートリアルでは、ground、sun、gas stationのある空のシミュレーション環境を作成します。以下は推奨規約です。MYROBOTの部分はあなたのロボットの名前にするか、ロボットがなければ、testの様な名前に置き換えるということを忘れないでください。尚、以下のチュートリアルでは、catkinワークスペースが~/catkin_ws/(ホームディレクトリ直下にcatkin_wsという名前である)となっていると仮定します。

  • MYROBOT_gazeboという名前のROSパッケージを作る
1
2
3
4
5
6
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_create_pkg MYROBOT_gazebo
cd ~/catkin_ws
catkin_make
source devel/setup.sh
  • そのパッケージの中で、launchフォルダを作る
1
2
roscd MYROBOT_gazebo
mkdir launch
  • そのlaunchフォルダの中に、MYROBOT.launchファイルを作る。(デフォルトの引数はありません)
1
gedit MYROBOT.launch

尚、MYROBOT.launchは以下の内容のにする。

1
2
3
4
5
6
7
<launch>
  <!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="$(find MYROBOT_gazebo)/worlds/MYROBOT.world"/>
    <!-- more default parameters can be changed here -->
  </include>
</launch>
  • 同じパッケージの中に、worldsフォルダを作り、その中に、MYROBOT.worldファイルを作る。:
1
2
3
roscd MYROBOT_gazebo
mkdir worlds
gedit MYROBOT.world

尚、MYROBOT.worldは以下の内容にする。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" ?>
<sdf version="1.4">
  <world name="default">
    <include>
      <uri>model://ground_plane</uri>
    </include>
    <include>
      <uri>model://sun</uri>
    </include>
    <include>
      <uri>model://gas_station</uri>
      <name>gas_station</name>
      <pose>-2.0 7.0 0 0 0 0</pose>
    </include>
  </world>
</sdf>
  • ここまで完了した後、以下のコマンドを使えば、Gazeboの中にカスタムのworld(ガソリンスタンド付き)をlaunchすることができるはずです。:
1
2
source ~/catkin_ws/devel/setup.bash
roslaunch MYROBOT_gazebo MYROBOT.launch

うまく行けば、以下のようになります。(マウスを使ってズームアウトしてください) gasstation

うまく行かない場合
  • launchファイルまたは、worldファイルに間違いが無いか確認してください。 よくある間違いは、MYROBOTの部分の間違いです。

  • ディレクトリ名が正しいか確認してください 私は、worldsとしなければならないところをworldにしてしまい、つまづいてましたorz

  • gzserverがきちんと終了していることを確認してください これが最も厄介なものですが、前回のチュートリアルでroslaunch gazebo_ros gazeborosrun gazebo_ros gazeboにより、Gazeboの起動確認をしていた場合、 Cntrl-Cで終了しても、gzserverのプロセスが終了していないことがあります。 この場合は、システムモニタを開き、起動中のプロセス一覧からgzserverを探し、終了させてください。 ちなみに、gzserverってなんぞ?という方は、Gazeboのコンポーネントでその概要を簡単に説明しているので、そちらをご覧ください。

  • gzclientは立ち上がるが、真っ暗なままですorz 今回のチュートリアルでは、Gazeboのオンラインデータベースにあるgass stationモデルを使用しますが、これを一度もgzclientで表示したことがない場合、自動でダウンロードを行うことになります。 ただ、このダウンロードは結構な時間がかかります。結構な時間とは、1分〜3分です。なので、気長に待ってみましょう。 そんなの待ってらんないぜ!という方は、gazeboを普通に立ち上げ、Insertタブの一番下にある、オンラインのモデル一覧からgass stationを選択して、一度良いので使ってみるか、 ここから直接gass stationを探し、~/.gazebo/model/にダウンロードすると良いです。

Gazeboの中でworldファイルを編集する

あなたのロボットのworldファイルに、モデルを追加することができますし、ウィンドウの左上にあるFile->Save Asをクリックすることで、編集したworldファイルをROSパッケージに出力することができます。

URDFのロボットをスポーンさせるのにroslaunchを使う

roslaunchを使って、URDFベースのロボットをGazeboにスポーンさせる方法は2つあります。

ROS Servise Call Spawn Method

1つ目の方法では、あなたのロボットのROSパッケージをレポジトリのチェックアウトとコンピュータの間でより運用しやすくするようにします。ROSパッケージパスに関連するあなたのロボットの位置を維持することが許されているだけでなく、小規模の(python)スクリプトを使ってROSサービスコールを作ることが必要です。

Model Database Method

2つ目の方法では、あなたのロボットを.worldファイルの中にインクルードすることが許されています。これは、単純で便利に見えるかもしれませんが、あなたのロボットを環境変数を設定し、Gazeboのモデルデータベースに追加する必要があります。

これら2つの方法をやってみます。私達が推奨する方法は、ROS Service Call Spawn Methodです。

“ROS Service Call” Robot Spawn Method

この方法では、GazeboにカスタムのURDFを追加するために、gazebo_rosのROSノード(rostopicの名前空間では単純にgazeboという名前がついています)にサービスコールリクエストを行うため、spawn_modelと呼ばれる小規模のpythonスクリプトを使います。spawn_modelスクリプトはgazebo_rosパッケージにあります。以下の方法で、このスクリプトを使用することができます。

1
rosrun gazebo_ros spawn_model -file `rospack find MYROBOT_description`/urdf/MYROBOT.urdf -urdf -x 0 -y 0 -z 1 -model MYROBOT

名前空間、trimeshプロパティ、ジョイントポジション、そしてRPY初期値を含む、spawn_modelのすべての発展的な引数を見るためには、以下のコマンドを実行してください。:

1
rosrun gazebo_ros spawn_model -h
Baxterを使ったURDFの例

もし、まだ例などで、URDFモデルをテストしたことがないなら、Rethink Roboticsのbaxter_commonレポジトリからbaxter_descriptionパッケージをダウンロードできます。以下のようにして、このパッケージをcatkinワークスペースに設置してください。尚、これまでと同様、catkinワークスペースの配置は~/catkin_wsとなっているとします。

1
2
cd ~/catkin_ws/src
git clone https://github.com/RethinkRobotics/baxter_common.git

上記コマンドを実行すると、baxter.urdfという名前のURDFファイルがbaxter_description/urdf/にできるはずです。できたら以下のコマンドが実行できます。

1
rosrun gazebo_ros spawn_model -file `rospack find baxter_description`/urdf/baxter.urdf -urdf -z 1 -model baxter

下図のように、ガソリンスタンドにbaxterのURDFモデルを出現させるには、先ほどまでに作成した、MYROBOT.launchをlaunchし、上記のコマンドを実行する必要があります。

1
2
roslaunch MYROBOT_gazebo MYROBOT.launch
rosrun gazebo_ros spawn_model -file `rospack find baxter_description`/urdf/baxter.urdf -urdf -z 1 -model baxter

baxter on gass station

ROSのlaunchファイルに直接これを統合するには、MYROBOT_gazebo/launch/MYROBOT.launchを再び開き、以下のな教を</launch>タグの前に追加してください。

1
2
<!-- Spawn a robot into Gazebo -->
<node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-file $(find baxter_description)/urdf/baxter.urdf -urdf -z 1 -model baxter" />

このファイルをlaunchすると、先ほどrosrunを使って実行したものと同じ結果が得られるはずです。

PR2を使ったXACROの例

もし、あなたのURDFがXMLフォーマットではないが、XACROフォーマットであったとしても、launchファイルを変更することで、同じようなものが作れます。以下のパッケージをインストールすることにより、PR2の例を実行することができます。

ROS Groovy: - Note : このdebianパッケージとして公開されているpullリクエストだけでは、GroovyのPRは壊れています

1
sudo apt-get install ros-groovy-pr2-common

ROS Hydro:

1
sudo apt-get install ros-hydro-pr2-common

ROS Indigo:

1
sudo apt-get install ros-indigo-pr2-common

インストールが終わったら、以下の内容をMYROBOT.launchに追加しましょう。:

1
2
3
4
  <!-- Convert an xacro and put on parameter server -->
  <param name="robot_description" command="$(find xacro)/xacro.py $(find pr2_description)/robots/pr2.urdf.xacro" />
  <!-- Spawn a robot into Gazebo -->
  <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-param robot_description -urdf -model pr2" />

このlaunchファイルをlaunchすると、以下のように、PR2がガソリンスタンドにいるのが確認できると思います。 Note : この記事を書いている時点では、PR2のURDFの挙動をGazeboのAPIに変更する必要があると言ったようなエラーや渓谷がコンソールの出力に大量に出力されます。(公式サイトより) pr2 on the gass station

“Model Database”Robot Spawn Method

Gazeboにロボットをスポーンさせる2つ目の方法は、あなたのロボットを.worldファイルの中にインクルードすることが許されています。これは、単純で便利に見えるかもしれませんが、あなたのロボットを環境変数を設定し、Gazeboのモデルデータベースに追加する必要があります。この環境変数が必要となるのは、GazeboのROS依存関係による分割が原因です。URDFパッケージパスは直接.worldファイルの中に記述することはできません。というのもGazeboはROSパッケージの構造理念とは異なるからです。 この方法を実行するには、一つのロボットだけで構成される新しいモデルデータベースを作らなければなりません。これはGazeboにあなたのURDFを読み込ませるためには単純な方法であるとは言えません。しかしこれは、あなたのコンピュータにあなたのURDFロボットのコピーを2つ作り、維持する必要が内容にするための方法なのです。もし、以下の説明が難しく、混乱してしまうようなら、モデルの構成と必要条件のチュートリアルへ戻り、なぜそのようなステップが必要なのかをしっかりと学んでください。 あなたのROSワークスペースのファイル小僧は以下ようになっていると仮定します。唯一違う点は、model.configファイルがMYROBOT_descriptionパッケージに追加されている点です。:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
../catkin_ws/src
    /MYROBOT_description
        package.xml
        CMakeLists.txt
        model.config
        /urdf
            MYROBOT.urdf
        /meshes
            mesh1.dae
            mesh2.dae
            ...
        /materials
        /plugins
        /cad

このファイル構造は、以下のフォルダ/¥とファイルに従った方法で、Gazeboのモデルデータベースを使うために最適化されています。

  • /home/USER/catkin_workspace/src : これはGazeboのモデルデータベースのロケーションとして扱われます
  • /MYROBOT_description : このディレクトリはGazeboのモデルフォルダと仕手のみ扱われます
  • model.config : これは、Gazeboがこのモデルをデータベースで探すために必要とするコンフィギュレーションファイルです
  • MYROBOT.urdf : これはあなたのロボットの構成ファイルです。またRvizMOveIt!..etcでも使用されます。
  • /meshes : worldファイルとともに、レギュラーのURDFとして、.stl.daeファイルを個々に置きます。
model.config

すべてのモデルには、モデルについてのメタデータを含む、モデルのルートディレクトリにmodel.configファイルがあります。まずは、このmodel.configファイルをコピーし、ファイルネームとともにmodel.urdfと置き換えてください。:

1
2
3
4
5
6
7
8
9
10
11
12
13
  <?xml version="1.0"?>
  <model>
    <name>MYROBOT</name>
    <version>1.0</version>
    <sdf>urdf/MYROBOT.urdf</sdf>
    <author>
      <name>My name</name>
      <email>name@email.address</email>
    </author>
    <description>
      A description of the model
    </description>
  </model>

SDFファイルとは異なり、URDFでこのファイルを利用する際には、バージョンのタグは必要ありません。より詳しい情報は、Gazeboのモデルデータベースドキュメントをご覧ください。

環境変数

最後に、Gazeboにモデルデータベースはどこを探せばよいか知らせる、.bashrcファイルに環境変数を追加する必要があります。好きなエディタで~/.bashrcを編集してください。GAZEBO_MODEL_PATHが定義されているか確かめてください。もし、すでに定義されていれば、セミコロンを使って新しいexportパスを追加してください。catkinワークスペースが~/catkin_ws/であるとすると、exportするGAZEBO_MODEL_PATHは以下のようになっているはずです。:

1
  export GAZEBO_MODEL_PATH=/home/user/catkin_ws/src/
Gazeboで確認する - 手動

もし、Gazeboのモデルデータベースがlaunchする際にすでに適切に定義されているとして、テストしてみましょう。:

1
  gazebo

起動できたら、画面左にあるInsertタブをクリックしてください。すると、あなたのシステムで利用可能なオンラインデータベースを含む、異なるモデルのデータベースを代表するドロップダウンリストを確認できるでしょう。あなたのロボットと一致するデータベースを探し、ロボットの名前の上で右クリックし、サブメニューを開いたら、ロボットを設置するためにGazeboの中のロケーションを選んでください。

Gazeboで確認する - モデルデータベースとroslaunch

モデルデータベースの発展的なメソッドでは、ROSパッケージパスを使うことなく、ロボットを直接worldファイルに加えることができます。worldファイルをつくるというというセクションで作ったものと同じセットアップを使いまが、以下のようにworldファイルを変更します。

  • 以前のように、MYROBOT_description/launchフォルダの時とと同じように、MYROBOT.worldファイルを以下の内容にしてください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" ?>
<sdf version="1.4">
  <world name="default">
    <include>
      <uri>model://ground_plane</uri>
    </include>
    <include>
      <uri>model://sun</uri>
    </include>
    <include>
      <uri>model://gas_station</uri>
      <name>gas_station</name>
      <pose>-2.0 7.0 0 0 0 0</pose>
    </include>
    <include>
      <uri>model://MYROBOT</uri>
    </include>
  </world>
</sdf>
  • 以下のコマンドで、カスタムのworldをガソリンスタンドとロボットとともにGazeboでlaunchできるようになっているはずです。:
1
  roslaunch MYROBOT_gazebo MYROBOT.launch

この方法の欠点は、あなたのMYROBOT_descriptionパッケージとMYROBOT_gazeboパッケージが簡単運用できないということです。

  • これらのROSパッケージを利用する前に、最初に新規のシステムには、GAZEBO_MODEL_PATHを設定しなければならないのです。

次のステップ

ここまでで、Gazeboやworldファイル、そしてURDFモデルを起動するroslaunchの作り方を学びました。チュートリアルを通して、GazeboでURDFを使うことで、あなた独自のGazebo-ready URDFモデルを作成する準備が出来ました。