九州工業大学 CIR-KIT Blog

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

No.6-5:GazeboをROSに繋ぐ (GazeboにおけるURDF 編)

gazebo_logo

検証日時

02/17/2015 (Tue)

概要

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

レベル

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

チュートリアル : GazeboでURDFを使う

Universal Robotic Description Format (URDF)は、ロボットのすべての要素を記述するために、Gazeboでも使われている、XMLフォーマットを使用しています。URDFファイルをGazeboで使用し、Gazeboで適切に動作させるには、いくつかの追加シミュレーション定義のタグがにつようです。このチュートリアルでは、GazeboであなたのURDFベースのロボットを確実に動作させ、sctatchや二重定義フォーマットによる、分割SDFファイルを作るのを避けるために、必要な過程を説明します。プログラム内部では、Gazeboは自動で、URDFをSDFファイルに変換しています。

背景

URDFは使いやすく、ROSでも一般化されているフォーマットですが、多くの定義について欠陥があり、ロボティクスの発展的な内容を記述するには至っていません。URDFは、独立した、ひとつのロボットの、幾何学的要素と運動要素しか定義できません。また、URDFはロボットのいるシミュレータ上のロボットの姿勢を定義できません。さらに、ジョイントループ(平行なリンク機構)を定義できないだけでなく、摩擦などの要素を記述できないので、標準的なフォーマットではないのです。さらに加えて述べると、ロボットでない、証明や標高地図などを定義することはできません。
実際に使うという面では、URDFの文法は処理するのに重く、完全なフォーマットを行わず、XMLフォーマットを使用しています。これにより、URDFはより柔軟になっています。また、後方互換性ももちません。
こういった問題に対処し、URDFの欠陥を解決するために、Gazeboでは、Simulator Description Format (SDFと呼ばれる新しいフォーマットが作られました。SDFは、worldレベル(シミュレーション環境を記述するレベル)からロボットレベル(ロボットを記述するレベル)に至るまで、全てにおいて、完全な記述です。 SDFは規模を自由に決定でき、修正要素を追加するのも簡単です。SDFフォーマット自体は、古いバージョンから新しいバージョンへ変換するために、シンプルなアップグレードツールを簡単に使用できるような、XMLを使って記述しています。
URDFをできるだけ完全なドキュメントとし、Gazeboでサポートしようとすることは、筆者の意図するところですが、読者にとっては、なぜ2つのフォーマットが存在し、それぞれに欠陥があるのか疑問に思うのは至極当然なことです。URDFをロボティクスにおkるニーズに完全に対応させることができれば、それは素晴らしいことです。

Gazeboへの実装の概要

URDFのロボットをGazeboで完全に動作させるにはたくさんのステップがあります。以下に示すのは、このチュートリアルの残りで述べる、詳細なステップの概要です。:

必須条件

  • <link>要素にある、<internal>要素は完全にかつ詳細に定義され、構成されている必要があります。

任意条件

  • <gazebo>要素をすべての<link>に追加する
    • Gazeboのフォーマットに外観色を変換する
    • stlファイルをより良いテクスチャによってdaeファイルに変換する
    • センサプラグインを追加する
  • <gazebo>要素をすべての<joint>に追加する
    • 適切な同ダンパを定義する
    • アクチュエータの制御プラグインを追加する
  • <gazebo>要素をすべての<robot>要素に追加する
  • もし、ロボットが正確にworld/base_linkへ接続されるべきなら、<link name="world"/>を追加する

前提条件

あなたのロボットをGazeboで起動させるために必要な最初のステップは、ROS URDFチュートリアルから、動作するURDFファイルを用意ことです。Gazeboであなたのロボットを動作させる前に、Rvizで表示して検証してください。このチュートリアルでは、RRBotというシンプルなデモ用ロボットを使います。このロボットを使っても自身のものを使ってもどちらでも構いません。

RRBotを手に入れる

RRBot(Revolute-Revolute Manipulator Robot)は簡単な3つのリンク機構、2つのジョイントアームを持つロボットで、GazeboとURDFの様々な特徴を検証するのに使います。これは、基本的に2つの倒立振り子であり、シミュレータでは、いくつかの面白い制御構想を検証します。
RRBotを手に入れるには、もし、catkinワークスペースがあるなら、そのsrcフォルダに、GitHubのレポジトリよりcloneし、ワークスペースをリビルドしてください。

1
2
3
4
cd ~/catkin_ws/src/
git clone https://github.com/ros-simulation/gazebo_ros_demos.git
cd ..
catkin_make

もし、何を言っているのかよくわからなけれが、先に、ROS Overview Tutorialsを読んでください。

Rvizで見てみる

すべてうまく行っているか確かめるために、RRBotをRvizでlaunchしてください。:

1
roslaunch rrbot_description rrbot_rviz.launch

すると、以下のようになるはずです。 rrbot-rviz-1 もし、こうならなければ、killall roscoreコマンドで起動中のすべてのroscoreプロセスを終了し、再びRVizをlaunchしてください。
また、2つのジョイントを動かすために、Joint State Publisherウィンドウでslider barsを実行することもできるはずです。
Gazeboであなたのロボットが動くように変換するあいだ、Rvizや他のROSアプリケーションを終了させないということが重要です。なので、たまにRVizのロボットがすべてきちんと動いているか確かめるのは良いことです。

ROSの概要チュートリアルでは、Gazeboから直接/jointstatesをpublishして、あなたのロボットの状態を表示するための、Rvizの使い方は飛ばしました。この例では、RVizのRRBotは、ダミーのjointstateパブリッシャーノード(スライドバー月のウィンドウ)からの/jointstatesを取得(subscribe)しています。

urdfのRRBotを試してみる

このチュートリアルの残りでは、RRBotのURDFのいろいろな面を見てゆきます。早速ファイルを見てみましょう。:

1
rosed rrbot_description rrbot.xacro

いくつかのリンクやジョイントの計算を簡単にするために、Xacroを使用していることに注意してください。また、2つの追加ファイルもインクルードしています。 - rrbot.gazebo : ほとんどすべてのGazebo定義XML要素をタグに含むGazeboの定義ファイルです。 - materials.xacro : 文字列のRGBA値のための簡単なRVizのカラーファイルであり、必須のものではありませんが、あったほうが良い定義です。

Gazeboで見てみる

GazeboでもRRBotをlaunchできるはずです。:

1
roslaunch rrbot_gazebo rrbot_world.launch

launchされたGazeboのウィンドウで、直立した状態のロボットを確認できるはずです。デフォルトには物理シミュレータに恣意的な障害物が無いにも関わらず、数値エラーが始まりと当時に起こり、2つの倒立振子が数秒後に落ちます。以下に示すのは、RRBotが動いている(倒立振子が落ちている)途中の様子です。: rrbot-gazebo-1 最終的には、アームは完全に停止します。以下のチュートリアル間、URDFのロボットのシミュレーションについて学ぶのを手助けするために、URDFのいろんな面を引っ張ってテストしてみることをおすすめします。

URDFファイルのヘッダ

GazeboにはAPIの変更がたくさんあり、URDFフォーマットが必要とされてきており、その中でも、Gazeboのxml-schemaという名前空間はすでに必要とされなくなりました。もし、あなたのURDFが以下のようであるなら、:

1
2
3
4
5
<robot xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"
       xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
       xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
       xmlns:xacro="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
       name="pr2" >

これらは削除して構いません。もし以下のものを使っているなら、ロボットのエレメントタグに必要なものはロボットの名前とxacroの任意のxmlの名前空間です。:

1
<robot name="rrbot" xmlns:xacro="http://www.ros.org/wiki/xacro">

タグの<gazebo>要素

もし、<gazebo>要素がreference==""という記述無しで使用してあるなら、<gazebo>要素はすべてのロボットモデルのものと仮定されます。<gazebo>タグにある<robot>要素は以下の表のようになっています。

名前 タイプ 説明
static bool もしtrueにすると、モデルは動かなくなります。しかしながら、モデルは物理エンジンの中でシミュレーションされます。

先ほどの表には無くて、<gazebo>タグにある要素は、生成されるSDFファイルの<model>タグに直接挿入されます。
これは、ROS Motor and Sensor Pluginsチュートリアルについて議論するときに、特にプラグインにおいて有用です。

モデルをworldに正しく変換する

もしあなたのURDFモデルをworldフレーム(the ground plane)に永久に設置された状態にしたいのなら、モデルのベースとなるように変換された、worldリンクとジョイントを作らなければなりません。RRBotでは以下のようにすれば、それが可能です。

1
2
3
4
5
6
7
  <!-- Used for fixing robot to Gazebo 'base_link' -->
  <link name="world"/>

  <joint name="fixed" type="fixed">
    <parent link="world"/>
    <child link="link1"/>
  </joint>

しかし、もしあなたがモバイルベースなどの動くロボットを持っているなら、このリンクやジョイントは必要ありません。

Links

URDFのlink要素に詳しくなりましょう。
以下の例はRRBotのlinkです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  <!-- Base Link -->
  <link name="link1">
    <collision>
      <origin xyz="0 0 ${height1/2}" rpy="0 0 0"/>
      <geometry>
        <box size="${width} ${width} ${height1}"/>
      </geometry>
    </collision>

    <visual>
      <origin xyz="0 0 ${height1/2}" rpy="0 0 0"/>
      <geometry>
        <box size="${width} ${width} ${height1}"/>
      </geometry>
      <material name="orange"/>
    </visual>

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

単位における注意

ROS REP 103: Standard Units of measure and Coordinate Conventionsにあるように、Gazeboの単位はメートルとキログラムで定義されねばなりません。もし、重力のような定数を主導で変更するときには、Gazeboではできるだけヤード・ポンド法を使えるようにしています。しかし、デフォルトの重力は9.8[m/s2]です。質量を定義する際にはキログラム単位を使ってください。

<collision><visual>要素

これらのタグの働きはGazeboでもRVizでも基本的に同じです。両方を定義することは重要ですが、いくつかのROSアプリケーションでは異なるので、Gazeboでは、もし定義されていなければ、あなたの<visual>要素を<collision>要素と同じようには使いません。その代わり、Gazeboではあなたのlinkをレーザスキャナからも衝突要素としても”見えない”ものとして扱います。

collisionモデルの簡単化

collisionvisual要素のどちらにも同じように幾何要素やメッシュを使うことができます。しかし、PCの性能向上のために、衝突幾何要素のmodel/meshesは簡略化することを強くおすすめします。メッシュを簡単化するおすすめのツールはBlenderです。BlenderにはMayaや3DX Maxなど、たくさんのclosed-sourceがあり、メッシュを簡単化することもできます。

物質 : 適切な色とテクスチャを使う

通常のURDFでは、以下のようなRRBotにもあるタグを使って色を定義することができます。

1
<material name="orange"/>

これは、materials.xacroなどのファイルの中に、分割してorangeという色と一緒に以下のように定義してあります。:

1
2
3
  <material name="orange">
    <color rgba="${255/255} ${108/255} ${10/255} 1.0"/>
  </material>

しかし残念なことに、この定義方法では、linkの色はGazeboでは反映されません。というのも、linkに色をつけたり、テクスチャを貼ったりするのにこの物質スクリプトが採用されているのです。その代わり、Gazeboの物質タグは、以下のように、それぞれのリンクに定義してやる必要があります。

1
2
3
  <gazebo reference="link1">
    <material>Gazebo/Orange</material>
  </gazebo>

簡単に言うと、選択したRRBotの例では、すべてのGazeboの定義タグを`rrbot.gazeboと呼ばれるセカンドファイルからインクルードしていました。
なので、要素を探すことができたのです。
Gazeboでデフォルトで使用可能な物質はgazebo/media/materials/scripts/gazebo/scripts/gazebo.materialにあるGazeboのソースコードより見つけることができます。
より進んだもしくは独自の物質のために、オリジナルのオレンジ色もしくはテクスチャを作ることができます。それについては、以下をご覧ください。 - The SDF documentation - OGRE materials documentation

STLやColladaファイル

Rvizのように、GazeboでもSTLColladaファイルを使用することができます。通常は、Collada(.dae)ファイルを使うことをおすすめします。なぜなら、このフォーマット形式は、色とテクスチャをサポートしているからです。STLファイルだと、個体の色のlinkしか作ることができません。

<inertial>要素

Gazeboで物理エンジンを適切にうごかすためには、URDF element pageにある、<inertial>要素が必ず必要です。Gazeboでlinkが無視されないために、それらの質量は0より大きくなければなりません。更に、0の慣性モーメント(ixx, iyy, izz)は、どんな有限なトルクに対しても、無限大の加速度を出力することになります。
それぞれのlinkに正しい値を決定するには、Gazeboで物理近似を行わなければなりません。これは、たくさんのロボットパーツの計測もしくは、そういった近似のための機能付きのSolidworksのようなCADソフトを使うことにより決定されます。初心者は、値を少しずつ変えることでも決定できます。
以下は、RRBotの一つ目のlinkの慣性要素の例です。:

1
2
3
4
5
6
7
8
<inertial>
  <origin xyz="0 0 ${height1/2}" 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>

originタグはこのlinkの重心を表しています。RRBotの長方形のリンクの半分の長さのところを重心と決定することにより、質量を中心に持ってきます。GazeboのViewメニューをクリックしWireframeCenter of Massを選択すれば、GazeboであなたのURDFの重心を目視で確認することができます。
このロボットの例では、ロボットは現実世界の写しではないので、質量も慣性行列も作り上げられた(実際は存在しない)ものになっています。

リンクにおける<gazebo>要素

それぞれの要素は以下のようになっています。:

名前 タイプ 説明
material value 外観要素の物質
gravity bool 重力を使う
dampingFactor double リンク速度の指数関数的減衰。- (一つの減衰係数)により決定される一つ前のリンク速度と現在の速度を掛けあわせます。
maxVel double 最大値コンタクト補正速度の最大値トラクション
minDepth double コンタクト補正インパルスが発生する前の深さの最小値
mu1&mu2 double ODEで定義される接地面に沿った接地摩擦係数 μ
fdir1 string 3組のローカルの衝突検証座標mu1の定義される方向
kp double ODEで定義される、剛体面の接触剛性 k_p (ODEではcfmを使用)
kd double ODEで定義される、剛体面の摩擦減衰 k_d (ODEではerpを使用)
selfCollide bool もし、trueなら、リンクは他のリンクやモデルと衝突します
maxContacts int 2つの物体間での面の最大値。この値は、物理シミュレートで定義されるmax_contacts要素をオーバーライドします
laserRetro double レーザーセンサのレーザー強度

<gazebo>要素は<robot>と似ており、上の表によって定義されていない任意の物体は、SDFファイルの<link>要素と一致するところに挿入されます。これは、ROS Motor and Sensor Pluginsチュートリアルについて議論するときに、特にプラグインにおいて有用です。

RRBotの要素の例

RRBotでは、非固定で連結した2つの摩擦係数が定義されています。なのでもし、衝突が起こってもより正確な接触作用がシミュレートされます。以下はリンクの<gazebo>タグの一例です。

1
2
3
4
5
<gazebo reference="link2">
  <mu1>0.2</mu1>
  <mu2>0.2</mu2>
  <material>Gazebo/Black</material>
</gazebo>

Joints

URDFジョイントドキュメントを熟読しておいてください。しかし、URDFのジョイントのために記述される要素のうべ手がGazeboで利用可能なわけではありません。

  • <origin><parent>そして<child>が必要です。
  • <calibration><safety_controller>は無視されます。
  • <dynamics>タグでは、ダンパ(減衰)プロパティのみが使用されます。
  • <limit>タグ内のすべてのプロパティは任意です。

RRBotの例

以下は、RRBotで使用されているジョイントです。

1
2
3
4
5
6
7
<joint name="joint2" type="continuous">
  <parent link="link2"/>
  <child link="link3"/>
  <origin xyz="0 ${width} ${height2 - axel_offset*2}" rpy="0 0 0"/>
  <axis xyz="0 1 0"/>
  <dynamics damping="0.7"/>
</joint>

0.7 [Nms/rad]の線形粘性係数についての運動要素に注目してください。減衰はただ単に,ジョイントを止めるようなゆっくりとしたジョイント速度に力を発生させるものの合計です(この場合は [トルク/角速度] です)。

0.7 [Nms/rad]という値はいろいろないかに自然に振り子が触れるかを観察し、減衰させることによって決定されます。この値を増やしたり減らしたりしてこの要素がいかに物理エンジンに影響を当たるか検証することをおすすめします。

Jointにおける<gazebo>要素

名前 タイプ 説明
kp double ODEで定義される、剛体面の接触剛性 k_p (ODEではcfmを使用)
kd double ODEで定義される、剛体面の摩擦減衰 k_d (ODEではerpを使用)
stopCfm double 停止していない時に混合で使用される一定の力
stopErp double ジョイントの停止に使用されるエラーパラメータ
provideFeedback bool Gazeboのプラグインへ常にねじりデータ(トルク)をpublishしている
cfmDamping bool もし、cgm dumpingtrueなら、減衰のシミュレートにODEはCFMを使用し、無限の減衰を容認する。また、追加の強制要素(前もってジョイントの制限に使用されている) が常に有効になります。デフォルトのdampingタグよりもたくさんのスッキリとした数字で表された減衰の方法です。
fudgeFactor double ジョイントの制限にあるジョイントモータの行き過ぎ量を計測します。また、0から1の値を取るはずです

これもまた<robot><link>における<gazebo>要素と似ており、上の表によって定義されていない任意の物体は、SDFファイルの<joint>要素と一致するところに挿入されます。これは、ROS Motor and Sensor Pluginsチュートリアルについて議論するときに、特にプラグインにおいて有用です。

Gazeboモデルの機能を修正する

Gazeboをインストールすると、あなたのURDFが正しくSDFに変換できるか確かめる簡単なツールも一緒にインストールされています。以下のコマンドを実行してください。:

1
2
3
4
  # gazebo2 and below
  gzsdf print MODEL.urdf
  # gazebo3 and above
  gz sdf -p MODEL.urdf

これにより、入力されたURDFから、SDFに変換するために必要な情報の欠陥に関する警告と共に、生成されたSDFを確認できます。 Note : バージョン1.9のGazeboとそれ以上のバージョンではデバッグ情報の一部がログファイルに記録され、以下のようにして、それを確認することができます。

1
  cat ~/.gazebo/gzsdf.log

URDFをGazeboで見る

GazeboでRRBotを見ること、このチュートリアルの最初の方ですでに完了しています。あなた独自のロボットでは、そのURDFが/urdfというサブフォルダにある、MYROBOT_descriptionという名前のROSパッケージの中で有効であるとします。ROSを使ってGazeboの中にこのロケーションからURDFを開く方法は前のチュートリアル(モデルをスポーンさせるのにroslaunchファイルを使う)で述べています。もしまだそのチュートリアルをやっていないなら、すぐにやってみてください。 そのチュートリアルでは、あなたのオリジナルロボットのための、2つのROSパッケージ(MYROBOTdescriptionMYROBOTgazebo)を制作するはずです。ロボットを確認し、Gazeboで試すには、以下のコマンドが実行できるはずです。

1
roslaunch MYROBOT_gazebo MYROBOT.launch

これにより、GazeboサーバーとGUIクライアントの両方を、あなたのロボットを自動でスポーンさせるようlaunchしているはずです。

あなたのモデルを引っ張る

もしあなたのロボットモデルがGazeboで思い通りに動かなければ、あなたのURDFの調整が必要なので、Gazeboで正確にその物理特性を表現するべきだと言えます。Gazeboで利用可能であり、URDFにある<gazebo>タグでも利用可能な様々なプロパティについての情報はSDFのユーザーガイドをご覧ください。

あなたのロボットを世界と共有する

もしあなたが他の人がGazeboで使いたいと思っているであろう独自のロボットを持っているなら、GazeboのモデルデータベースにあなたのURDFを追加することをおすすめします。これは、インターネットからモデルをダウンロードする際にGazeboが接続するオンラインサーバーです。このよく変更のあるレポジトリはBitbucketに設置されてます。あなたのロボットをデータベースに追加するには、どうやってpullリクエストを投稿すればよいかなど、Gazeboのモデルデータベースドキュメントをご覧ください。

次のステップ

これでURDFを含むROSパッケージをGazeboと一緒に使用する方法を学びました。また、あなた独自のURDFをGazeboで動作するように変換する方法も学びました。あなたのURDFのロボットにプラグインを追加する方法を学ぶ準備が出来ました。なので、あなたのロボットやシミュレートされる環境の他の面をコントロールできます。ROS Motor and Sensor Pluginsをご覧ください。