ロボットシミュレータ Gazebo の簡単な使い方 (ROS)
[最終更新] (2019/06/03 00:23:11)
最近の投稿
注目の記事

概要

ロボットシミュレータ Gazebo を ROS 開発で利用するための簡単な手順を記載します。ここでは Debian9 を利用します。個別にインストールすることもできますが、ROS を ros-melodic-desktop-full でインストールすれば gazebo もインストールされます。

URDF モデルの作成

rviz による URDF モデルの可視化

ROS ではロボットの 3D モデル情報などを Unified Robot Description Format (URDF) で記述します。インストール済みの urdf_tutorial を利用すると URDF を簡単に試せます。

$ rospack list | grep urdf_tutorial
urdf_tutorial /opt/ros/melodic/share/urdf_tutorial
$ rosls urdf_tutorial/urdf
01-myfirst.urdf  02-multipleshapes.urdf  03-origins.urdf  04-materials.urdf  05-visual.urdf  06-flexible.urdf  07-physics.urdf  08-macroed.urdf.xacro
$ rosls urdf_tutorial/launch
display.launch

rviz で URDF モデルを可視化できます。

roscd urdf_tutorial
DISPLAY=:0 roslaunch urdf_tutorial display.launch model:=urdf/01-myfirst.urdf

以下のようにしても同じです。中央ボタンのマウススクロールで拡大縮小、ドラッグで回転、Shift ドラッグで平行移動できます。

DISPLAY=:0 roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/01-myfirst.urdf'

Uploaded Image

display.launch は内部的に roscorervizjoint_state_publisherrobot_state_publisher を起動しています。

roscp urdf_tutorial display.launch .
cat display.launch

<launch>

  <arg name="model" default="$(find urdf_tutorial)/urdf/01-myfirst.urdf"/>
  <arg name="gui" default="true" />
  <arg name="rvizconfig" default="$(find urdf_tutorial)/rviz/urdf.rviz" />

  <param name="robot_description" command="$(find xacro)/xacro.py $(arg model)" />
  <param name="use_gui" value="$(arg gui)"/>

  <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
  <node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" required="true" />

</launch>

COLLADA ファイルを利用した URDF モデル

URDF ファイルからは COLLADA データを参照できます。必須ではありませんがここでは ROS パッケージを追加して URDF ファイルと COLLADA ファイルを格納するディレクトリをそれぞれ作成します。ここでは OpenRAVE のサンプルとしてインストールされる mug1.dae を URDF から参照してみます。

$ ls src/mypkg/urdf/
my.urdf
$ ls src/mypkg/meshes/
mug1.dae

my.urdf

<?xml version="1.0"?>
<robot name="myrobot">
  <material name="blue">
    <color rgba="0 0 1.0 0.5"/>
  </material>
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
      <material name="blue"/>
    </visual>
  </link>
  <link name="mug">
    <visual>
      <geometry>
        <mesh filename="package://mypkg/meshes/mug1.dae"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0.1"/>
    </visual>
  </link>
  <joint name="base_to_mug" type="fixed">
    <parent link="base_link"/>
    <child link="mug"/>
    <origin xyz="0 -0.22 0.25"/>
  </joint>
</robot>

rviz で起動すると以下のようになります。base_link リンクから Y 軸方向に -0.22m、Z 軸方向に 0.25m 平行移動した mug リンクの座標系において、メッシュの位置を Z 軸方向に 0.1m 平行移動した箇所として記述しています。簡単のため回転要素 rpy (roll pitch yaw) はすべて 0 です。その他、複雑な URDF ファイルを記述するためのマクロ Xacro 等も利用できます。

DISPLAY=:0 roslaunch urdf_tutorial display.launch model:=urdf/my.urdf

Uploaded Image

Gazebo に URDF モデルを読み込む ROS 設定

gazebo_ros パッケージの empty_world.launch

Gazebo を ROS から利用するためには gazebo_ros パッケージを利用します。

$ rospack list | grep 'gazebo_ros '
gazebo_ros /opt/ros/melodic/share/gazebo_ros

gazebo_ros パッケージには launch ファイルが複数格納されていますが、すべては empty_world.launch を参照しています。empty_world.launch は ROS 連携に必要な設定が行われた状態で内部的に Gazebo の gzserver と gzclient を起動します。

$ roscp gazebo_ros empty_world.launch .
$ egrep '(gzserver|gzclient)' empty_world.launch
  <arg unless="$(arg debug)" name="script_type" value="gzserver"/>
    <node name="gazebo_gui" pkg="gazebo_ros" type="gzclient" respawn="false" output="screen" args="$(arg command_arg3)"/>
$ dpkg -S `which gzserver`
gazebo9: /usr/bin/gzserver

world ファイル

Gazebo のシミュレーション環境は SDF 形式のファイルで設定できます。拡張子は world です。world ファイルでは環境に読み込む model を複数 include します。Gazebo には sunground_plane だけが存在する環境 empty.world ファイルがサンプルとして含まれています。

cat /usr/share/gazebo-9/worlds/empty.world 

<?xml version="1.0" ?>
<sdf version="1.5">
  <world name="default">
    <!-- A global light source -->
    <include>
      <uri>model://sun</uri>
    </include>
    <!-- A ground plane -->
    <include>
      <uri>model://ground_plane</uri>
    </include>
  </world>
</sdf>

model ファイル

world ファイルで読み込む model は model.config で設定されます。SDF だけでなく URDF も model.config で指定できます。以下は SDF の例です。sunground_plane はサンプルとして Gazebo に含まれています。

ls /usr/share/gazebo-9/models/sun/
model.config  model.sdf

cat /usr/share/gazebo-9/models/sun/model.config
<?xml version="1.0"?>

<model>
  <name>Sun</name>
  <version>1.0</version>
  <sdf version="1.5">model.sdf</sdf>

  <author>
    <name>Nate Koenig</name>
    <email>nate@osrfoundation.org</email>
  </author>

  <description>
    A directional light for the sun.
  </description>
</model>

empty_world.launch の利用例

以下のように world ファイルを指定して Gazebo を起動できます。

DISPLAY=:0 roslaunch gazebo_ros empty_world.launch world_name:=worlds/empty.world

ground_planesun が読み込まれていることが World タブで確認できます。

Uploaded Image

インストールしたバージョンによっては SSL 証明書のエラーが出ます。

[Err] [REST.cc:205] Error in REST request
libcurl: (51) SSL: no alternative certificate subject name matches target host name 'api.ignitionfuel.org'

$ dpkg -S /usr/share/ignition/fuel_tools/config.yaml
libignition-fuel-tools:amd64: /usr/share/ignition/fuel_tools/config.yaml

~/.ignition/fuel/config.yaml の URL を新しい URL に変更することで解消します。

-    url: https://api.ignitionfuel.org
+    url: https://api.ignitionrobotics.org

独自に world ファイルと model ファイルを作成

ROS パッケージを新規に作成して world ファイルと model ファイルを格納することにします。

catkin_create_pkg myrobot_gazebo

world ファイルと model ファイルを格納するディレクトリを作成します。

cd myrobot_gazebo/
mkdir worlds
mkdir models

SDF サイトの Bitbucket からサンプルとして利用できる gazebo_models がダウンロードできます。今回作成する world ファイルではこれらの model を利用してみます。git ではなく mercurial レポジトリです。以下のコマンドでダウンロードできます。サイズが大きいため時間がかかります。

cd /tmp/
hg clone https://bitbucket.org/osrf/gazebo_models
cd -

myrobot_gazebo/models に必要なものをコピーします。model 内で自己参照している箇所があるため、ディレクトリ名を変更すると読み込めなくなります。例えば gas_stationgas_station2 とはできません。

cp -r /tmp/gazebo_models/sun models/
cp -r /tmp/gazebo_models/ground_plane models/
cp -r /tmp/gazebo_models/gas_station models/

これらを参照する world ファイルを作成します。

worlds/myrobot.world

<?xml version="1.0" ?>
<sdf version="1.4">
  <world name="default">
    <include>
      <uri>model://sun</uri>
    </include>
    <include>
      <uri>model://ground_plane</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_ros パッケージの empty_world.launch で起動してみます。Gazebo が model ファイルを参照できるように GAZEBO_MODEL_PATH を設定します。world ファイルを参照できるように GAZEBO_RESOURCE_PATH を設定します。Gazebo は /usr/share/gazebo-9/models~/.gazebo/modelsGAZEBO_MODEL_PATH を model ディレクトリとして参照できます。

roscd myrobot_gazebo
export GAZEBO_MODEL_PATH=`pwd`/models:${GAZEBO_MODEL_PATH}
export GAZEBO_RESOURCE_PATH=`pwd`
DISPLAY=:0 roslaunch gazebo_ros empty_world.launch world_name:=worlds/myrobot.world
  • esc → ドラッグで視点の平行移動、中央ボタンドラッグで視点移動による拡大縮小
  • t → RGB の軸をドラッグして物体を平行移動
  • r → RGB のリングをドラッグして物体を回転
  • s → RGB の軸を Shift キーを押しながらドラッグして物体を拡大縮小

Uploaded Image

URDF ファイルの読み込み

URDF ファイルに対応する model.config を作成して Gazebo の world ファイルで読み込む方法もありますが、ここではそうではなく、gazebo_ros パッケージの spawn_model で world とは別に追加で読み込む方法を利用します。Gazebo で読み込める URDF のサンプルとして baxter をダウンロードします。

cd /tmp/
git clone --depth 1 https://github.com/RethinkRobotics/baxter_common.git
cd -

新規にパッケージとしてダウンロードした URDF をコピーします。

roscd myrobot_gazebo
cd ../
cp -r /tmp/baxter_common/baxter_description .

world と urdf を別々に起動する launch ファイルを、world を含む myrobot_gazebo パッケージ内に作成します。

roscd myrobot_gazebo
mkdir launch
vi launch/myrobot.launch

myrobot.launch

<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>
  <!-- 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>

以下のようなコマンドで起動できます。

roscd myrobot_gazebo
export GAZEBO_MODEL_PATH=`pwd`/models:${GAZEBO_MODEL_PATH}
DISPLAY=:0 roslaunch myrobot_gazebo myrobot.launch

myrobot.launch 相当の処理は以下のコマンドでも行えます。

roscd myrobot_gazebo
export GAZEBO_MODEL_PATH=`pwd`/models:${GAZEBO_MODEL_PATH}
export GAZEBO_RESOURCE_PATH=`pwd`
DISPLAY=:0 roslaunch gazebo_ros empty_world.launch world_name:=worlds/myrobot.world

別ターミナル

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

Uploaded Image

package.xml で model パスを指定

package.xml を編集すると GAZEBO_MODEL_PATH を export せずに launch できるようになります。

roscd myrobot_gazebo
vi package.xml

<exec_depend>gazebo_ros</exec_depend>
<export>
  <gazebo_ros gazebo_model_path="${prefix}/models"/>
</export>

cd ../..
catkin_make

DISPLAY=:0 roslaunch myrobot_gazebo myrobot.launch

Gazebo で読み込める URDF の作成

新規に ROS パッケージを作成します。

catkin_create_pkg myrobot_description

本ページで作成した URDF ファイルを用意します。

meshes/mug1.dae
urdf/myrobot.urdf

URDF ファイルは Gazebo シミュレーションのための十分な情報を持っていません。Gazebo が内部的に URDF を SDF に変換するために必要な情報 <inertial></inertial> を追記する必要があります。剛体力学などでも登場する inertia 慣性モーメントは、質量が物体の平行移動のしづらさを表現するのと同様に、物体の回転のしづらさのようなものを表現するパラメータです。単位は kg および m です。また SDF 変換のためには必要のない情報ですが、地面で着地するために <collision></collision> も追記します。

<?xml version="1.0"?>
<robot name="myrobot">
  <material name="blue">
    <color rgba="0 0 1.0 0.5"/>
  </material>
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
      <material name="blue"/>
    </visual>
    <collision>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
    </collision>
    <inertial>
      <origin xyz="0 0 1" rpy="0 0 0"/>
      <mass value="1"/>
      <inertia
        ixx="1.0" ixy="0.0" ixz="0.0"
        iyy="1.0" iyz="0.0"
        izz="1.0"/>
    </inertial>
  </link>
  <link name="mug">
    <visual>
      <geometry>
        <mesh filename="package://myrobot_description/meshes/mug1.dae"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0.1"/>
    </visual>
    <collision>
      <geometry>
        <mesh filename="package://myrobot_description/meshes/mug1.dae"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0.1"/>
    </collision>
    <inertial>
      <origin xyz="0 0 1" rpy="0 0 0"/>
      <mass value="1"/>
      <inertia
        ixx="1.0" ixy="0.0" ixz="0.0"
        iyy="1.0" iyz="0.0"
        izz="1.0"/>
    </inertial>
  </link>
  <joint name="base_to_mug" type="fixed">
    <parent link="base_link"/>
    <child link="mug"/>
    <origin xyz="0 -0.22 0.25"/>
  </joint>
</robot>

環境にロボットを登場させてみます。inertial の origin を変更して link の重心をバランスの悪そうな箇所にずらすとロボットが転倒します。

roscd myrobot_gazebo
export GAZEBO_MODEL_PATH=`pwd`/models:${GAZEBO_MODEL_PATH}
DISPLAY=:0 roslaunch myrobot_gazebo myrobot_not_baxter.launch

Uploaded Image

読み込んだ URDF モデルを ROS から扱えるように設定

この続きが気になる方は

ロボットシミュレータ Gazebo の簡単な使い方 (ROS)

残り文字数は全体の約 36 %
tybot
100 円
関連ページ
    概要 ロボットを制御する際に複数の座標系を扱う必要があります。これら複数の座標系間の変換等を行うためのライブラリに tf2 (transform2) があります。C++ と Python がサポートされていますが、ここでは Python を用いて簡単な使い方を把握します。 tf2 チュートリアルと同様に動作検証のための
    概要 産業用ロボットには、垂直多関節ロボット (Articulated) や水平多関節ロボット (SCARA) があります。ロボットにはジョイントとリンクがあり、ジョイントの関節値を指定することで制御できます。 関節値を指定して、位置姿勢を求める場合を順運動学 (Forward Kinematics) とよびます。
    概要 Python で数学的なことを試すときに利用される Matplotlib/SciPy/pandas/NumPy についてサンプルコードを記載します。 Matplotlib SciPy pandas NumPy チュートリアル Installing packages Quickstart tutorial