WSL2の環境下において、Traffic-Editorを使って複数ロボットの移動をシミュレーションできる環境を構築してみた

# 1. はじめに
[先日の投稿](https://qiita.com/bebebefu/items/ff7839dce4f1db3e336e)では、WSL2の環境でもFree Fleet ServerとOpen-RMFを接続し、かつブラウザから指示を出し複数のturtlebot3を動かすことができました。
今回はtraffice-editorを使って環境を構築してロボットを動かすことについて、[移動ロボット評価指標調査検討委員会【資料１】評価環境作成手順編](https://www.jmfrri.gr.jp/content/files/Open/2022/WG3_Cyousa_sim/20220623-032903.pdf)（以下、参考サイト[[1]](#参考記事やサイト)）で手順が分かりやすく公開されていましたので、これを参考にやってみたいと思います。

＊初回投稿では書き忘れていましたが、本記事では自動ドアも設置しており、ロボットとドアの連携（設備連携）もしています。

# 2. 実行環境
- CPU: CORE i7 7th Gen
- メモリ: 32GB
- GPU: GeForce RTX 2070
- OSと構築した環境: Window11でWSL2にUbuntu20.04をインストールした環境
- ROS2: Foxy
- Open-RMFの構築環境：[WSL2の環境下において、Open-RMFを使って複数のturtlebot3を動かしてみた　環境構築編](https://qiita.com/bebebefu/items/ccbca44c24e285b3e30f)にて構築した環境（[[2]](#参考記事やサイト)）

# 3. 方針
私が[[3]](#参考記事やサイト)や[[4]](#参考記事やサイト)の記事で投稿しているEnergyPlusのExercise 2の建物モデルをtraffice-editorを再現し、その中で複数のロボットを動かしてみたいと思います。
ただそのまま作ると建物の中にドアがない5つの部屋があるだけ建物になり、ロボットの走行範囲が狭くなりますので、以下の図で赤で囲んだところにドアを設置したいと思います。（外に出るドアはとりあえず作りますが、外は走行させないので単に飾りとします）

👇：[[5]](#参考記事やサイト)のFigure 6.1: Schematic for Exercise 2.より引用。ドアを設置したところ赤丸で示しました。
![ドア設置位置.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/f2652a06-e791-f4c1-68bf-816f89636ec9.png)

# 4. 手順
基本的には[[1]](#参考記事やサイト)の[移動ロボット評価指標調査検討委員会【資料１】評価環境作成手順編](https://www.jmfrri.gr.jp/content/files/Open/2022/WG3_Cyousa_sim/20220623-032903.pdf)の手順に従っての手順に従って進めましたので、ここでは細かい手順は省略して「私はどうやったか」ということを中心に書きたいと思います。

## 4.1 Traffic editorの起動
ターミナルを開き以下のコマンドを実行して起動します。
```:terminal
cd ~/Work/open-rmf/free_fleet/ros2
source install/setup.bash
traffic-editor
```
## 4.2 Traffic Editorでの環境ファイル作成準備
[[1]](#参考記事やサイト)の14ページでの手順に基本的には従って以下のように進めました。

- 以下の図で赤枠で囲んだメニューをクリックします。
![新規ファイル作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/1ad54408-2aa0-aa36-c0a2-e58d2be899d3.png)

- 以下の図で赤枠で囲んだところをクリックして、"energyplusexercise"という名前のファイルを作成しました（緑枠で囲んだファイル）。ちなみに私は[[5]](#参考記事やサイト)で構築した環境内における、home/test/Work/open-rmf/free_fleet/ros2/src/demonstrations/rmf_demos/rmf_demos_maps/maps配下にファイルを作成しました。
![新規ファイル_名前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/f7043422-cb4d-ef64-8047-16b44d32eafe.png)

- 下図で赤枠で囲んだところに"energyplusexercise"という名前を入力し、下図の緑枠で囲んだ「Save」をクリックすることで"energyplusexercise.building.yaml"を作成しました。
![buildingyaml作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/5a94d25d-6460-5ec4-12f0-5637a6c811ad.png)

ここで[[1]](#参考記事やサイト)の記載の通り、「次のステップに行く前に、一度Traffic Editorを終了。」することをお勧めします。

## 4.3 ひな形地図のコピー
[[1]](#参考記事やサイト)の15ページでの手順に基本的には従って以下のように進めました。

- 用意したenergyplusexercise.png（以下の図の赤枠）をenergyplusexercise.building.yamlが保存されているフォルダ内に保存しました。
![pngファイルの保存.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/9d498973-0a2c-addb-d66d-3eff70b5eb73.png)

## 4.4 .project.yamlファイルの作成
[[1]](#参考記事やサイト)の16ページでの手順に基本的には従って以下のように進めました。
- 用意したenergyplusexercise.project.yaml（以下の図の赤枠）をenergyplusexercise.building.yamlやenergyplusexercise.pngが保存されているフォルダ内に保存しました。
![projectファイルの保存.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/fb302987-0a4a-e12d-f112-19fbd9f034e2.png)

    なお、energyplusexercise.project.yamlの内容は以下です。
    ```yaml:energyplusexercise.project.yaml
    building:
      filename: energyplusexercise.building.yaml
    name: energyplusexercise
    traffic_maps:
      {}
    version: 1
    ```

## 4.5 Traffic Editorでの環境ファイル作成方法
[[1]](#参考記事やサイト)の17～20ページでの手順に基本的には従って以下のように進めました。

- 以下の図の赤枠の「add」のところをクリックすると、下図中央にあるウィンドウが開きますので、そこの緑枠で囲んだ「Find」をクリックします。
![add.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/a03be6da-c3ea-d691-9028-2ca734b21c0a.png)

- 「Find」をクリックして、4.3章のところで保存した"energyplusexercise.png"を選択して、読み込みに成功すると以下の図のようになります。なお、[[1]](#参考記事やサイト)と同じように以下の図の赤枠の「Name」のところは「1F」に当初はしたのですが、ここは「L1」にあとで修正しました。(なぜかL1にしないと起動せず、おそらく自分のlaunchファイルやrvizの設定が良くなかったものと考えられます。)
![図の挿入.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/0f3648e0-1bd0-a6cb-c1a1-fa32770120d3.png)

## 4.6 読み込んだ地図上でスケールの設定
[[1]](#参考記事やサイト)の21ページでの手順に基本的には従って進めました。
以下の図で赤枠で囲んだ「Adding a measurement」のアイコンをクリックし、地図上の適切な線と同じ長さの線を引いて、以下の図で緑枠囲んだところにその線の長さを入力しました。長さは[[2]](#参考記事やサイト)の61ページより30.5mとしました。
![長さ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/99b2496d-d827-7ee5-137e-348368bbae68.png)

## 4.7 壁の設定
[[1]](#参考記事やサイト)の22ページでの手順に基本的には従って進めました。
以下の図で赤枠で囲んだ「Adding a wall」のアイコンをクリックして地図データの壁をなぞるようにして、ドアにする部分は避けて壁を設定しました。
![壁の設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/525a9271-97df-f1e7-5937-97536a1d1729.png)

## 4.8 ドアの設定
[[1]](#参考記事やサイト)の23ページでの手順に基本的には従って進めました。今回は[[6]](#参考記事やサイト)を参考に建物外部につながるドアは「hingeドア」を2つ、建物内部に設置するドアは「slidingドア」を4つと「double_slidingドア」を2つ設置しました。それぞれのドアの設定は以下のようにしました。
- higeドアの設定
Traffic-editorのメニューにあるドアのアイコンをクリックした後に、ドアの両端を選択します。そして以下の図で赤枠で囲んだnameには任意の名前を入力し、typeにはhingeと入力します。設置したドアは青枠で囲んだものになります。
![hingeドア.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/6306b8e4-4eae-e9e2-4319-9188e48feefc.png)

- slidingドアの設定
Traffic-editorのメニューにあるドアのアイコンをクリックした後に、ドアの両端を選択します。そして以下の図で赤枠で囲んだnameには任意の名前を入力し、typeにはslidingと入力します。設置したドアは青枠で囲んだものになります。
![sldingdoor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/25e57174-34f0-26cb-fc3e-f42abf8899f0.png))

- double_slidingドアの設定
Traffic-editorのメニューにあるドアのアイコンをクリックした後に、ドアの両端を選択します。そして以下の図で赤枠で囲んだnameには任意の名前を入力し、typeにはdouble_slidingと入力します。
![double_slidingの設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/060e737f-1561-4237-bdf4-56dc8f545c7c.png)

## 4.9 オブジェクトの設定
[[1]](#参考記事やサイト)の24ページでの手順に基本的には従って進めました。今回はテーブルのみを設置します。以下の図で赤枠で囲んだ「add model」のアイコンをクリックするとmodelを選ぶためのウィンドウが開きました。次にそのウィンドウ内で緑枠で囲んだところに設置したいオブジェクト（今回はtable）を検索して、OKをクリック⇒設置したいところをクリックすることでオブジェクトを設置できました。オブジェクトの移動や回転については[[1]](#参考記事やサイト)の24～25ページに記載がありますので、ここでは省略します。
![スクリーンショット 2024-02-18 081234.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/4a308c28-6964-da6d-2f74-f8a7986f6c18.png)

設置が完了した様子は以下です。
![スクリーンショット 2024-02-18 081351.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/02ee9cd9-bd96-45e5-8004-968ef380ac3a.png)

## 4.10 グランドの設定
[[1]](#参考記事やサイト)の26ページでの手順に従って、グランドを設定しました。以下は設定したときの様子です。特にエリアを区切ることなく、全体を一つのグランドとして設定しました。（下図はテーブル以外にも椅子を設置したときの様子ですが、走行の邪魔になったため椅子は後で消しました。）
![スクリーンショット 2024-02-18 081922.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/fecdf309-f301-f9a1-3241-fe8a7a1da3f5.png)

## 4.11 経路の設定
以下の図で緑枠で囲んだ「Add lane」のアイコンをクリックして、以下のように設定していきました。また今回は2台のtinyRobotを用いるため赤枠で囲んだところを、初期位置として設定しました。

![経路の設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/aa71a5cb-05a6-8b82-5d46-1c8d7dfa2889.png)

なお、左下のtinyRobotの初期位置には以下の設定をしました。
![tinyrobot1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/16be11d1-6bde-b84c-f14a-6964b17f9d56.png)

また右上のtinyRobotの初期位置には以下の設定をしました。
![tibyrobot2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/f9355488-0e9d-ef4f-e06e-e07d90a00a08.png)

## 4.12 Traffic Editorの環境ファイルからのGazeboModel作成
[[1]](#参考記事やサイト)の28ページでの手順に基本的には従って進めましたが、自分の環境に合わせると以下のようにコマンドを実行してビルドしました。
```:terminal
cd ~/Work/open-rmf/free_fleet/ros2
source install/setup.bash
colcon build
```

## 4.13 作成したGazeboModelの確認
[[1]](#参考記事やサイト)の29ページでの手順に従って確認しましたが、私の環境ではhome/test/Work/open-rmf/free_fleet/ros2/install/rmf_demos_maps/share/rmf_demos_maps/mapsの中にenergyplusexerciseという名前のフォルダが生成され、その中にモデルが作成されていることを確認できました。

## 4.14 ロボットシミュレーションを行うための設定
### launchファイルの作成
home/test/Work/open-rmf/free_fleet/ros2/src/demonstrations/rmf_demos/rmf_demos/launchの中に以下の内容のenergyplusexercise.launch.xmlを作成しました。

```xml:rmf_demos内のenergyplusexercise.launch.xml
<?xml version='1.0' ?>

<launch>
  <arg name="use_sim_time" default="true"/>
  <arg name="failover_mode" default="false"/>

  <!-- Common launch -->
  <include file="$(find-pkg-share rmf_demos)/common.launch.xml">
    <arg name="use_sim_time" value="$(var use_sim_time)"/>
    <arg name="viz_config_file" value ="$(find-pkg-share rmf_demos)/include/energyplusexercise/energyplusexercise.rviz"/>
    <arg name="config_file" value="$(find-pkg-share rmf_demos_maps)/energyplusexercise/energyplusexercise.building.yaml"/>
    <arg name="dashboard_config_file" value="$(find-pkg-share rmf_demos_dashboard_resources)/energyplusexercise/dashboard_config.json"/>
  </include>

  <!-- TinyRobot fleet adapter and robot state aggregator needed for the TinyRobot slotcar_plugin -->
  <group>
    <let name="fleet_name" value="tinyRobot"/>
    <include file="$(find-pkg-share rmf_demos)/include/adapters/tinyRobot_adapter.launch.xml">
      <arg name="fleet_name" value="$(var fleet_name)"/>
      <arg name="use_sim_time" value="$(var use_sim_time)"/>
      <arg name="nav_graph_file" value="$(find-pkg-share rmf_demos_maps)/maps/energyplusexercise/nav_graphs/0.yaml" />
    </include>
    <include file="$(find-pkg-share rmf_fleet_adapter)/robot_state_aggregator.launch.xml">
      <arg name="robot_prefix" value="tinyRobot"/>
      <arg name="fleet_name" value="$(var fleet_name)"/>
      <arg name="use_sim_time" value="$(var use_sim_time)"/>
      <arg name="failover_mode" value="$(var failover_mode)"/>
    </include>
  </group>

</launch>
```

次にhome/test/Work/open-rmf/free_fleet/ros2/src/demonstrations/rmf_demos/rmf_demos_gz/launchの中に以下の内容のenergyplusexercise.launch.xmlを作成しました。

```xml:rmf_demos_gz内のenergyplusexercise.launch.xml
<?xml version='1.0' ?>

<launch>
  <arg name="gazebo_version" default="11"/>
  <arg name="use_sim_time" default="true"/>
  <arg name="failover_mode" default="false"/>

  <!-- Common launch -->
  <include file="$(find-pkg-share rmf_demos)/energyplusexercise.launch.xml">
    <arg name="use_sim_time" value="$(var use_sim_time)"/>
    <arg name="failover_mode" value="$(var failover_mode)"/>
  </include>

  <!-- Simulation launch -->
  <include file="$(find-pkg-share rmf_demos_gz)/simulation.launch.xml">
    <arg name="map_name" value="energyplusexercise" />
    <arg name="gazebo_version" value="$(var gazebo_version)" />
  </include>

</launch>

```

### rvizファイルの作成
home/test/Work/open-rmf/free_fleet/ros2/src/demonstrations/rmf_demos/rmf_demos/launch/includeの配下にenergyplusexerciseという名前のファイルを作成して、rvizファイルを作成する必要がありますが、私の場合はhome/test/Work/open-rmf/free_fleet/ros2/src/demonstrations/rmf_demos/rmf_demos/launch/include/rmf_demos内にあるofficeというフォルダのrvizファイルをそのままコピーしました。


### dashboardファイルの作成
ブラウザからの指示をしなければこれはいらないですが、launchファイルに書いてしまっているため作成しないとエラーが出ます。私の場合はhome/test/Work/open-rmf/free_fleet/ros2/src/demonstrations/rmf_demos/rmf_demos_dashboard_resourcesの中にenergyplusexerciseという名前のファイルを作成して、home/test/Work/open-rmf/free_fleet/ros2/src/demonstrations/rmf_demos/rmf_demos_dashboard_resourcesの中にあるofficeというフォルダの中の内容をコピーしました。
そしてdashboard_config.jsonファイルを以下のように修正しました。
```json:dashboard_config.json
{
  "world_name" : "energyplusexercise World",  
  "valid_task": ["Loop"],
  "task": {
    "Delivery": {
    },
    "Loop": {
      "places": [
        "point0",
        "point1",
        "point2",
        "point3",
        "point4",
        "point5",
        "point6",
        "point7"
      ]
    },
    "Clean": {
    },
    "Station": {
    },
    "Patrol": {
    },
    "Charging": {
    }
  }
}
```

### 再ビルド
上記の設定が終わったら以下のコマンドで再ビルドをします。
```:terminal
cd ~/Work/open-rmf/free_fleet/ros2
source install/setup.bash
colcon build
```

## 4.15 シミュレーション環境の起動と巡回の指示
以下のコマンドでgazeboとrvizを起動します。
```:terminal(1)
cd ~/Work/open-rmf/free_fleet/ros2
source install/setup.bash
ros2 launch rmf_demos_gz energyplusexercise.launch.xml
```
そして別ターミナルを開き、以下のようにして2つのloopタスクを投げました。
```:terminal(2)
cd ~/Work/open-rmf/free_fleet/ros2
source install/setup.bash
ros2 run rmf_demos_tasks dispatch_loop -s point0 -f point6 -n 3 --use_sim_time
ros2 run rmf_demos_tasks dispatch_loop -s point2 -f point4 -n 3 --use_sim_time
```

# 5. 結果
上記のコマンドで起動・loopタスクを出してロボットを動かしたときの動画が以下です。動画は4倍速で流しています。また右側の画像がrivz側の様子、左側の画像がgazebo側の様子です。
<iframe width="560" height="315" src="https://www.youtube.com/embed/Hi1wDOycOOo?si=FcI0fsrhNP4MBFfe" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
traffic-editorで設定した経路をたどりながら2台のtinyRobotが動いている様子が見られます。

# 6. まとめと課題
上記の手順にて、WSL2の環境下において、Traffic-Editorを使って複数ロボットの移動をシミュレーションできる環境を構築し、複数台のロボットを設定した経路に沿って動かすことに成功したと考えられます。これからは、もうちょっと複雑な環境の作成やブラウザからの指示や他のソフトウェアとの連携などを試してみたいと考えています。

# 参考記事やサイト
[1][移動ロボット評価指標調査検討委員会【資料１】評価環境作成手順編](https://www.jmfrri.gr.jp/content/files/Open/2022/WG3_Cyousa_sim/20220623-032903.pdf)
[2][WSL2の環境下において、Open-RMFを使って複数のturtlebot3を動かしてみた　環境構築編](https://qiita.com/bebebefu/items/ccbca44c24e285b3e30f)
[3][EnergyPlusのGetting Startを試してみる　その5（Exercise 2A）](https://qiita.com/bebebefu/items/110aaec3dfd9ee5f968c)
[4][EnergyPlusのGetting Startを試してみる　その6（Exercise 2B）](https://qiita.com/bebebefu/items/0ba195155854e9338753)
[5][EnergyPlusのGetting Start](https://energyplus.net/documentation)
[6][Traffic Editor](https://osrf.github.io/ros2multirobotbook/traffic-editor.html)

# 関連記事
- [WSL2の環境下において、Traffic-Editorを使って複数ロボットとエレベータの連携をシミュレーションできる環境を構築してみた](https://qiita.com/bebebefu/items/32dcb43db1213e1a00e0)にて設備連携とロボット群制御をしてみました。