聖夜の夜にGazeboでクリスマス

# メリークリスマス !!!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280822/103509b7-2cee-ebfa-475a-45453c4321e1.png)

エンジニアのみなさん、メリークリスマス:bangbang::santa_tone3:

こんにちは、kuwano(@calm0815)です。
[ROS2 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ros2) 最終日、そして令和最初のクリスマス、みなさんいかがお過ごしでしょうか？

え？~~ひとり？~~

ケーキは？　ない！？　...お金がない！？

それはいけない。せめて仮想空間でだけでも（？）視覚的に（？）楽しみましょう:relaxed:

# Gazebo内にクリスマスパーティ環境を作る
まだ、間に合う！！！

## モデル作成に関するTips
パーティ環境を作る前にさくっとGazeboでのモデル作成に関する情報を少しまとめておきます。

### モデルを作成するのに必要なデータ
Gazebo内にモデルを出現させるには「衝突用のSTLファイル(.stl)」と「外観用のCOLLADAファイル(.dae)」の２種類と、xml形式で記述されたsdfファイルを用意する必要があります。Gazeboはsdfを読み込んで、そこに記述されたモデルの情報をSTL/COLLADAから取得してシミュレーションをする。という感じです。

モデルを準備する際にCOLLADAはBlenderを用いてSTLから生成可能なので、STLさえ手に入ればなんとかなります。

【注意点】
複雑なSTLデータを用いたモデルがワールドに存在すると、物理シミュレータであるGazeboの動作が重くなるので注意が必要です。
これの対策として「メッシュの量を減らす（後述）」や、「衝突を考える必要のないモデルには衝突用のデータを持たせない」などができます。

### モデリングツール
モデリングは基本的にBlenderを使います。
Blenderに慣れていない方や、そもそもモデリングをしたことがない方はYoutubeの動画に合わせてモデリングをしてみましょう。
ショートカットが大量に設定されているBlenderですが、しばらく我慢して使ってみるとすぐにある程度扱えるようになります。

練習でおすすめなのはソファのモデリングです。

- How to Make a Couch In Blender - Part 1  
[![How to Make a Couch In Blender - Part 1](http://img.youtube.com/vi/i14DlYj6AdE/0.jpg)](http://www.youtube.com/watch?v=i14DlYj6AdE)

ちなみにAutodesk InventorなどのCADソフトは食べ物のような不定形物、布などのシワがある物のモデリングには不向きです。（できなくはないけどめんどくさい。）
逆に寸法が明らかなモデルはCADでさくっと済ませた方が早いです。

【注意点】
CADソフトからSTLを出力する際は単位系に注意してください。
Gazeboのワールドでは「m（メートル）」で扱われるので、出力するときは必ず「m（メートル）」で出力してください。
単位系がずれると大変なことになります。

### 投稿サイトの利用
身の回りのものや有名なものについてはモデルの投稿サイトを探してみると見つかる場合が多いです。「モデリングがめんどくさい」とか「どうモデリングしたらいいのかわからない」ようなモデルに関しては探してみるといいかもです。

#### モデル
以下に自分がよく利用するサイトを載せておきます。

- [Thingiverse](https://www.thingiverse.com/) : ３Dプリントできるような小物系が強い。
- [GrubCAD](https://grabcad.com/library) : 小さなものから大きなものまで高詳細なモデルが置いてあるので、見てるだけで楽しい。
- [Free Plant 3D models](https://www.cgtrader.com/free-3d-models/plant?page=2) : 植物系モデルが多く置いてある。有料なものが多い。

#### テクスチャ
Blenderの作業で必要になります。
こちらについても自分がよく使うものを載せておきます。

- [textures.com](https://www.textures.com/)
- [poliigon.com](https://www.poliigon.com/)

## Let's クッキング
### モデルの作成（チキン）
みんな大好きチキンのモデルを作りながら説明していきます。

#### COLLADAとSTLファイルの準備
さっそくですが投稿サイトのお世話になりましょう:rolling_eyes:笑

##### モデル探し
Thingiverseにいい感じの七面鳥が置いてありました。

- [Turkey Roast](https://www.thingiverse.com/thing:3211679) by ksamuelsen Nov 12, 2018

##### メッシュ調整
モデルを拾ってきたらBlenderに取り込みます。まずはモデルのメッシュ量を確認してみましょう。
Blenderのビューを「Object Mode」から「Edit Mode」に切り替えます（Tabキー）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280822/817f16a8-9a25-94f6-f50f-0ab8550753c9.png)

メッシュが細かく切られてますね。。
このように投稿サイトから拾ってきたような高詳細モデルは曲面などを綺麗に表現するためにメッシュが細かく切られているものが大半です。（嫌いじゃないけどね）
この場合はBlenderのモディファイア機能を使って、原型をなるべく維持したままメッシュ量を減らしていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280822/7ad86471-e73e-aaa1-483b-8885e8ca6bcb.png)

使用するモディファイアは「Decimate」です。
この機能を使うことでモデルの形状を保ったままメッシュ量をかなり減らすことができます。
（さらに大事なことを言うと、この機能を使ってメッシュの修正もできます。話すと本題から逸れるので別の機会に。。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280822/a09b32f2-8ac2-748e-5fcc-285f5af3d445.png)

Decimate適用後（20%）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280822/8e06a845-6a4f-7c29-34bd-f6138e772846.png)

かなり抑えられましたね！　これ以上下げると表面のカクつきが目立ってくるのでここまでにします。

##### マテリアル適用
メッシュをある程度抑えたあとはモデルにマテリアル情報を与えます。
Blenderの画面右側に表示されているマテリアルタブから、マテリアルを追加しましょう。
マテリアルタブに移動して「+ add」を押すだけでいいです。

##### テクスチャ貼付
次はテクスチャを貼っていきます。
テクスチャは以下の工程で貼っていきます。

1. シームでメッシュに切れ目をいれる
2. UV展開
3. メッシュにテクスチャ画像を貼る→微調整

テクスチャを貼る手順について説明している以下の動画がわかりやすいです。

- How to Add Textures in Blender 2.8 (UV Unwrapping for Beginners)  
[![How to Add Textures in Blender 2.8 (UV Unwrapping for Beginners)](http://img.youtube.com/vi/SnKNTANTtd8/0.jpg)](http://www.youtube.com/watch?v=SnKNTANTtd8)

シームで切れ目を入れるのがめんどくさい！！
という場合は「smart UV project」という機能を使うとBlenderが自動でUV展開をしてくれます。

smart UV projectを使えばUVが楽になりますが、変なところでメッシュが切れたりするので仕上がりがイマイチになります。困
コツは最初からsmart UV projectを使うのではなく、ある程度自分でシームを切っておくことです。（自分で切ったところはsmart UV projectの結果にも反映されます。）

さて、テクスチャの貼り方がわかったところで、
いい感じのテクスチャを拾ってくるか、コストコに行って七面鳥（正確には「ロティサリーチキン」）の表面をパシャッてきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280822/3a5509e8-7d44-1ca7-c074-f67e20df2b5e.png)
これがウメェんだ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280822/b7f4ae20-07af-0476-0dc5-4738ae2d65bd.png)

いい感じですな。
（おなかすいてきた。。。笑）

##### エクスポート
テクスチャまで貼り終えたらCOLLADAファイルとSTLをエクスポートします。（ファイル名：turkey）

#### ディレクトリの整理
ディレクトリを以下のように構成します。

turkey/
├── meshes
│   ├── DAE <-- COLLADAファイルとテクスチャ画像
│   │   ├── (エクスポートされたテクスチャ).jpg
│   │   └── turkey.dae
│   ├── STL <-- STLファイル
│   │   └── turkey.stl
│   └── turkey.blend
├── model.config
└── model.sdf

model.sdf、model.configの2つはGazeboがモデルを読み込む際に必要なファイルです。
中身は次のようになっています。

```xml:model.sdf
<sdf version='1.5'>
  <!-- Draw Model -->
  <model name="turkey">
    <static>true</static>
    <link name="turkey">
      <collision name="collision">
        <geometry>
          <mesh>
            <uri>model://turkey/meshes/STL/turkey.stl</uri>
          </mesh>
        </geometry>
      </collision>

      <visual name="visual">
        <geometry>
          <mesh>
            <uri>model://turkey/meshes/DAE/turkey.dae</uri>
          </mesh>
        </geometry>
      </visual>
    </link>
  </model>
</sdf>
```
```xml:model.config
<?xml version="1.0"?>

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

  <author>
    <name>user name</name>
    <email>user mail</email>
  </author>

  <description>
    turkey
  </description>
</model>
```

ここまで出来たら、この「turkey」というディレクトリを適当な場所においてパスを通します。
「/path/to/models_directory」は「turkey」がいる階層までのパスを表します。
Gazebo起動時に毎回コマンド叩くのがめんどくさければbashrcに記述してもいいと思います。

```bash
export GAZEBO_MODEL_PATH="/path/to/models_directory:$GAZEBO_MODEL_PATH"
```

パスが通ったらGazeboを開いて「insertタブ」からturkeyを呼び出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280822/db3cf827-5484-5d04-a770-111e93acb13f.png)

七面鳥をスポーン出来たら完了です。

#### モデル作成まとめ
ここまでチキンを例に「Gazeboのモデル作成」について順をおって説明してきました。他のモデルについても作り方に変わりないのでお好みで追加してください。

また、あまり説明はしませんでしたが、
モデルの情報を記述するSDFファイルについては[ココ](http://sdformat.org/spec?ver=1.6&elem=sdf)にまとめられています。
いろいろと機能があるようなので試してみるのもアリです。
（これに関するまとめ記事を書いてみたくなったので今度書きます。）

自分がこれまでに作ってきたモデルはGithub上にあります。自由に使ってもらってかまいません。
この記事をみて「こんなの作ってみました！！」ってのがあれば追加してほしかったりします。一緒にいろんなモデルをGazeboに置きましょう！！笑

- [gazebo_models](https://github.com/calm0815/gazebo_models) <-- ココ

## Gazeboワールド作成
さぁ！料理ができたら会場の準備をしましょう！！
ワールドは以下のものを使います。

- [labo.world](https://github.com/calm0815/gazebo_models/blob/master/worlds/labo_world/labo.world) : 今年の盆休みに暇すぎて作ったワールド。学校の研究室がモデル。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280822/e87f74b7-211f-c9a6-80d1-81da4775aa5e.png)

このワールドに先ほど作ったモデルを次のように追加します。
「christmas_tree」はturkeyと一緒に作りました。

```xml:labo.world（抜粋）
    <model name="christmas_tree">
      <static>true</static>
      <include>
        <uri>model://christmas_tree</uri>
      </include>
      <pose>2.0 -1.8 0  0 0 0</pose>
    </model>

    <model name="turkey">
      <static>false</static>
      <include>
        <uri>model://turkey</uri>
      </include>
      <pose>2.8 -0.60 0.76  0 0 0</pose>
    </model>
```

さぁ、どんな出来栄えになるのか！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280822/eda0aaf4-a01b-a7b7-60b1-bfc1edf89e9e.png)
$\textlarge{デッカww}$


ま、まぁ、
こういうことはよくあるので、その場合はBlenderでモデルのサイズをお好みで再度調整してください。:relaxed:

今回はこの辺で終わりたいと思います。

# まとめ
今回の記事では最初こそふざけてました（スイマセン）が、
「Gazeboのworldの作り方」について自分流ですが説明しました。

「ROS2アドベントカレンダーなのにROS2じゃないじゃないか！」という意見もあるかと思いますが、ROS1であってもROS2であっても上記の作り方は変わりません。
むしろこれからどんどんROS2の利用者が増えるなかで、冒頭で煽り倒したように
「お金がない！」とか「オリジナルのシミュレーション環境がほしい！」とかの要求が出てきた場合に、この記事の「ワールドの作り方」が少しでも参考になることを願います。

今回の記事だけでは書ききれなかったことも多くあるので、それについては追々書き記していければと思います。（特にSDF！！）

長くなりましたが、これからさらに盛り上がりを見せるROS2界隈、
バラエティに富んだモデルやワールドがROS1時代よりも増えることを期待してます！


```math
\def\textlarge#1{%
  {\rm\Large #1}
}
```