Ignition GazeboとROS2の連携を学ぶ！

# 概要

Ignitionは，高性能なアプリケーション開発を簡単にできるよう設計されたオープンソースライブラリ群[^1]で，このライブラリで作り直されたGazebo がIgnition Gazeboになります．この記事では，Ignition Gazeboをインストールして，シミュレーション上のロボットをROSで動かしたり，シミュレーション上のセンサからデータを取得してrvizで可視化させたりすることで，IgnitionとROSの連携を学んでいきます．なお，本記事は，Ubuntu20.04, ROS2 foxyを前提としています．
[^1]: https://ignitionrobotics.org/about

# 0. 準備
ROS2 foxyをインストールしたのちに，以下のパッケージをインストールします．

```shell
$ sudo apt install ignition-citadel ros-foxy-ros-ign
```

__(オプション)__
最新バージョンのdomeをインストールしたいときは，gazeboのレポジトリを追加することで，パッケージ管理ツール経由でインストールできます[^2]．

[^2]: https://ignitionrobotics.org/docs/dome/install_ubuntu

```shell
$ sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list'
$ wget http://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install ignition-dome
```


# 1. はじめに

Ignitionライブラリの多くは，異なるソフトウェアコンポーネント間でデータを交換するためにIgnition Transportを利用しています．Ignition Transportは，高速かつ効率的な非同期メッセージパッシング、サービス、データロギングを提供する通信ライブラリで，Google のProtocol buffersを用いて実装されています．Ignition GazeboとROSが連携するには，このIgnition TransportとROS間でデータ交換が必要になりますが，これを実現するのがros_ign_bridgeになります．本記事では，Ignition Gazebo上のモデルをROS側で操作したり，カメラセンサの画像をrvizで表示したりする事例を通して，ros_ign_bridgeの利用方法とIgnition GazeboとROSの連携を学んでいきます．

# 2. モデルの準備
まず，Ignition Gazeboで動かすモデルを用意します．Ignition-ROS連携を学ぶのによさそうなモデルを作成したので下記からダウンロードしてください．

https://gist.github.com/tygoto/1536eaf784f93c7a5204f06022562dbb

SDFの作成は，基本的にGazeboのときと同じですが，当然ながら，プラグインの指定はIgnitionのものを指定する必要があります．それから，Ignition GazeboのGUIは，IgnitionGUIを利用していてXMLでGUIの構成を変更でき，読み込むSDF内でデフォルトの構成をオーバーライドすることができます．上記のSDFにはインスペクタにカメラセンサからの画像を表示するパネルを追加しています．デフォルトの構成は，$HOME/.ignition/gazebo/gui.config に記述されています．そのうち解説記事を投稿できればと思います．

下記，コマンドを実行してIgnition Gazeboを立ち上げます．

```shell
$ ros2 launch ros_ign_gazebo ign_gazebo.launch.py ign_args:="ros_ign_tutorial.sdf"
```

問題がなければ，以下のようなウィンドウを確認することができると思います．

![Gazebo 12_16_2020 5_51_12 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403742/b701aefe-1d93-1d4f-5436-bb99caaabb31.png)

# 3. Ignition Gazebo上のロボットを動かす

Ignition内でメッセージを送信してロボットを動かしてみます．

```shell
$ ign topic -t "/model/vehicle/cmd_vel" -m ignition.msgs.Twist -p "linear: {x: 1.0}"
```

次に，ros_ign_bridgeを立ち上げます．ros_ign_bridgeは以下の形式で記述します．
__ros2 run ros_ign_bridge parameter_bridge /TOPIC@ROS_MSG@IGN_MSG__

```shell
$ ros2 run ros_ign_bridge parameter_bridge /model/vehicle/cmd_vel@geometry_msgs/msg/Twist@ignition.msgs.Twist
```

別のターミナルを起動して，以下のコマンドで，ROS側からメッセージを送り，ロボットを動かしてみます．

```shell
$ ros2 topic pub --once /model/vehicle/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 1.0}}"
```

シミュレータ上のロボットが前進していると思います．Ignition GazeboのPlayボタンの押し忘れに注意！

# 4. カメラセンサからのデータをrvizで確認

移動ロボットの先端に付けているカメラセンサからのデータをrvizで表示します．

以下のコマンドで，ros_ign_bridge を立ち上げます．

```shell
$ ros2 run ros_ign_bridge parameter_bridge /camera_info@sensor_msgs/msg/CameraInfo@ignition.msgs.CameraInfo
```

別のターミナルで，以下のトピックのブリッジも行います．

```shell
$ ros2 run ros_ign_bridge parameter_bridge /camera@sensor_msgs/msg/Image@ignition.msgs.Image
```

別ターミナルでrvizを立ち上げます．

```shell
$ ros2 run rviz2 rviz2
```

以下の画像のようにカメラプラグインを追加します．
![c9027f00c0f44cfe4508e03b09781ba5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403742/7259bfe7-72b7-eaa6-ff64-c57ad2c95965.png)

次に，以下のようにFixed Frameを「vehicle/camera/camera」に変更すると，Cameraプラグインのパネルにカメラセンサからの画像が表示されます．

![d109ae1b55220792b5a601b4b376c4ce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403742/2a949507-b03f-43fd-6119-d17216bd0f3c.png)

# 5. おわりに

Ignitionはros2と同じようなコマンドで操作できて，ROS2を使っていると違和感なく利用できる気がします．