2021年流行る!?「Webots」というオープンソースのロボットシミュレータについて。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96992/c0822166-b029-0900-b088-39c5f2443829.png)

# はじめに

[Webots](https://github.com/cyberbotics/webots)というロボットシミュレータをご存知でしょうか？
私が探した限り、日本語の記事はあまり見つけることができませんでした。[品質確認の時間も短縮、ルンバも使ったクラウドシミュレーターの可能性とは \(1/3\) \- MONOist（モノイスト）](https://monoist.atmarkit.co.jp/mn/articles/2006/23/news014.html)で
> 研究や教育分野向けロボットの開発に適したシミュレーターとしては「webots」があります。

と、少し触れられていた程度です。

Webotsは、スイスのCyberbotics社が公開しているロボットシミュレータです。公式では次のように説明されています。
> Webots is an open-source robot simulator released under the terms of the Apache 2.0 license. It provides a complete development environment to model, program and simulate robots, vehicles and biomechanical systems.
> Webotsは、Apache 2.0ライセンスのもとでリリースされたオープンソースのロボットシミュレータです。ロボット、乗り物、生体力学システムのモデル化、プログラミング、シミュレーションを行うための完全な開発環境を提供します。

フロントページを漁ってみると、

* ROSインターフェイスがあって、
* プリインストールでいろんなアセット（ロボットCADデータ、センサー類、壁などの障害物）が数多く用意されている

すごいシミュレータという様子が伺えました。

特に、[Webots documentation: Robots](https://cyberbotics.com/doc/guide/robots)というページを見てみると、「Spot Mini」「Aibo」「Turtlebot3」などなど有名な市販ロボットは一通り用意してあり、ダメ押しでBB-8まである。これはすごい!!(小並感)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96992/9e9b67b0-4757-92a2-d1be-864af8be0ef9.png)

以下、ざっくりとした、報告です。

# インストールについて
Linux版、Windows版、Mac版とそれぞれのOSで動くようです。ROSとの親和性を考えるとLinux版が使いやすい気がします。導入はaptコマンドで一発でした。
詳細はこちらを参照（[Installation Procedure](https://cyberbotics.com/doc/guide/installation-procedure)）

```bash
$ wget -qO- https://cyberbotics.com/Cyberbotics.asc | sudo apt-key add -
$ sudo apt-add-repository 'deb https://cyberbotics.com/debian/ binary-amd64/'
$ sudo apt-get update
$ sudo apt-get install webots
```


# ROS1とROS2
何はさておき、ROSクラスタの皆様におかれましては、一番気になるところだと思います。

## ROS1
チュートリアルにはROSでの操作までを含んでいます（[Tutorial 8: Using ROS \(60 Minutes\)](https://cyberbotics.com/doc/guide/tutorial-8-using-ros)）。
サンプルの導入は非常に簡単で、一般的なROSパッケージと同様にパッケージマネージャでインストールできました。

```bash
$ sudo apt-get install ros-noetic-webots-ros
```

実際にチュートリアルの指示通りに起動してみましょう。[E\-puck mobile robot](https://en.wikipedia.org/wiki/E-puck_mobile_robot)という赤外線センサー搭載差動二輪ロボットをラインに沿って動かすプログラムです。

```bash
$ roslaunch webots_ros e_puck_line.launch
```

このサンプルは、TFやロボットモデルは公開されていないようです。とりあえずセンサーの値は取れました。これは距離センサーの値のようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96992/70ab65ac-77e7-e6e2-2bda-7310bc53dc07.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96992/ce1d82ff-1c5b-d999-3751-66281fcd7790.png)

launchファイルは次の通りです。webots.launchでは独自Pythonプログラムでwebots本体を起動しています。その際に指定される`wbtファイル`（ワールドファイル、後述）で、このシミュレーションの内容を定義しています。特に、ロボットである`e-puck`に紐づくコントローラー（後述）として、Webots用のROSコントローラー（/usr/local/webots/projects/default/controllers/ros/Ros.cpp）が選択されている点に注目です。
WebotsにおけるROSプログラミングでは基本的にこいつが、使うセンサー類に応じて、いい感じにトピックなりサービスを全て調整します。使うセンサー類は、GUIで簡単に追加できます（[Sensors](https://cyberbotics.com/doc/guide/sensors)）。

そして、ライントレースプログラム自体はROSノード（e_puck_line）として起動しています。ソースコードは普通のROSプログラムなので詳細は省きます。[webots\_ros/e\_puck\_line\.cpp at master · cyberbotics/webots\_ros](https://github.com/cyberbotics/webots_ros/blob/master/src/e_puck_line.cpp)

```xml:e_puck_line.launch
<?xml version="1.0"?>
<launch>
  <!-- start Webots -->
  <arg name="no_gui" default="false," doc="Start Webots with minimal GUI"/>
  <include file="$(find webots_ros)/launch/webots.launch">
    <arg name="mode" value="realtime"/>
    <arg name="no_gui" value="$(arg no_gui)"/>
    <arg name="world" value="$(find webots_ros)/worlds/e-puck_line.wbt"/>
  </include>

  <arg name="duration" default="20" doc="Duration in seconds"/>
  <arg name="auto_close" default="false" doc="Startup mode"/>
  <node name="epuck_line" pkg="webots_ros" type="e_puck_line" args="$(arg duration)" required="$(arg auto_close)"/>
</launch>
```

```xml:webots.launch
<?xml version="1.0"?>
<launch>
  <arg name="world" default="" doc="Path to the world to load"/>
  <arg name="mode" default="realtime" doc="Startup mode"/>
  <arg name="no_gui" default="false" doc="Start Webots with minimal GUI"/>
  <node name="webots" pkg="webots_ros" type="webots_launcher.py" args="--world=$(arg world) --mode=$(arg mode) --no-gui=$(arg no_gui)" required="true"/>
</launch>
```

みんな大好きPioneer3ロボットの場合はセンサー全部載せのデモが実施できます。TFもちゃんと発行しているので見ていて楽しいデモです。

```bash
$ roslaunch webots_ros pioneer3at.launch
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96992/b36ace9f-03ab-e49b-a69e-cc5b314c444b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96992/da4172c5-731d-b1c1-0f77-dbf134dc99a3.png)


## ROS2
[公式ページのユーザガイド](https://cyberbotics.com/doc/guide/index)には、特に記述がありませんでした。ただし、調べてみると同社より、以下のパッケージが公開されていました。
[cyberbotics/webots\_ros2: Webots ROS2 packages](https://github.com/cyberbotics/webots_ros2)　どうやらROS1と同様に専用パッケージが提供されているようです。（時間切れで未検証ですスイマセン）


# 画面について
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96992/b686a84d-0250-fd1b-bd75-37d61659245a.png)
こんな感じです。Unityに近いようなIDEに近いような。

# ワールドについて
ワールドというのは、ロボットが活動する領域です。その他に環境光やカメラ位置などもこれに該当するようです（ノードとと呼ぶらしい。）。便利な点は、Webotsでは基本的なワールドはウィザード形式で簡単に展開できる点です。ワールドはワールドファイルとして管理され（.wbtファイル）、ノードはシーンツリーと呼ばれるツリー構造で構成されています。また、ノードはフィールと呼ばれるカスタマイズ可能なプロパティを持っているので自由自在なワールドを作ることができるようになっています。

# コントローラーについて
コントローラは、ロボットの動作を定義するプログラムのことです。以下の言語で書けるようです。

- C
- C++
- Java
- Python
- MATLAB

コントローラは、ロボットノードのフィールドとして紐付いています。この辺はUnityっぽいですね。ロボットは一度に1つのコントローラしか使用できないことに注意ください。特徴としては、同一プロジェクト内では作ったコントローラを簡単に使い回せるような作りになっている点が挙げられます。素晴らしい。

コントローラのソースコードとしては以下の感じのモノを記述します。車輪を最高速度（毎秒1回転=6.28ラジアン）の10%で動かし続けるという簡単なプログラムです。wb_motor_set_positionを無限にしたりいろいろやってますがこの辺は慣れでしょうか。APIリファレンスもちゃんと整理されているので困ることはなさそう。[Webots documentation: Webots Reference Manual](https://cyberbotics.com/doc/reference/index)

```c
#include <webots/robot.h>

// Added a new include file
#include <webots/motor.h>

#define TIME_STEP 64

#define MAX_SPEED 6.28

int main(int argc, char **argv) {
  wb_robot_init();

  // get a handler to the motors and set target position to infinity (speed control)
  WbDeviceTag left_motor = wb_robot_get_device("left wheel motor");
  WbDeviceTag right_motor = wb_robot_get_device("right wheel motor");
  wb_motor_set_position(left_motor, INFINITY);
  wb_motor_set_position(right_motor, INFINITY);

  // set up the motor speeds at 10% of the MAX_SPEED.
  wb_motor_set_velocity(left_motor, 0.1 * MAX_SPEED);
  wb_motor_set_velocity(right_motor, 0.1 * MAX_SPEED);

  while (wb_robot_step(TIME_STEP) != -1) {
  }

  wb_robot_cleanup();

  return 0;
}
```

# スーパーバイザーについて
スーパーバイザーは、ロボットの移動距離を測定したり、ロボットを初期位置に戻すなどの人間のアクションを置き換えることができます。コントローラーと同様Webotsで非常に重要な要素の一つです。この答え合わせの為の機能はCI/CDには欠かせないと考えられます。
[Webots documentation: Supervisor](https://cyberbotics.com/doc/reference/supervisor)

# Gazebo比較
Redditでこんな書き込みがありました。GazeboとWebotsの物理エンジン比較ですね。修正版のODEを使っているらしい。
[How does the accuracy of the dynamics of Webots compare to Gazebo?](https://www.reddit.com/r/robotics/comments/hhz5nn/how_does_the_accuracy_of_the_dynamics_of_webots/)

また、Gazeboのみならず、他ロボットシミュレーターとの比較が英語版のWikipediaにすごくきれいにまとめてありました。
[Robotics simulator \- Wikipedia](https://en.wikipedia.org/wiki/Robotics_simulator)


# 雑感
上記のGazeboとの比較に近いですが、既存テクノロジーとの使い分けをどうするか？が重要になってくると思います。あくまでも個人的な意見を羅列。プロトタイピングはWebots、作り込みはGazeboというのが最適解な気がします。みなさんの意見はどうでしょうか。

- Webotsを使いたい
   - 市販されているロボットでシミュレーションを素早く動かしたい場合
   - Worldを画面を見ながらいじりたい場合
   - ロボットがモノ（例えばボールとか）に対して影響を与えるような操作を想定する場合
      - なんとなくUnityに近い操作感が好きな人はこっちの方がとっつきやすい
- Gazeboを使いたい
   - 作りたいものがはっきりしている、完全オリジナルロボットをシミュレーションする場合
      - どうせURDF、ros_controlに近いものを実装するならROSの標準的手法を使った方がメンテナンスしやすい気がする。
 

# 参考文献
[Webots: robot simulator](https://cyberbotics.com/#cyberbotics)
[品質確認の時間も短縮、ルンバも使ったクラウドシミュレーターの可能性とは \(1/3\) \- MONOist（モノイスト）](https://monoist.atmarkit.co.jp/mn/articles/2006/23/news014.html)