Ignition Gazebo チュートリアル  - インストールとROS 2との連携

# Igniton Gazeboとros_ign_bridgeのインストール

すでにROS2 Humbleがインストール済みとする

### Ignition本体のインストール

```bash
sudo apt install ignition-fortress
```

インストールするバージョンに注意
ROS2のバージョンと対応するIgnition Gazebo の対応は以下を参照

https://github.com/gazebosim/ros_gz

### ros_ign_bridgeのインストール

IgnitionのメッセージとROS2 メッセージを相互に変換するためのもの

```bash
sudo apt install ros-humble-ros-ign 
```


# サンプルのワールドで差動2輪ロボットを動かす

このページでいろいろなワールドが公開されているので、適当な差動2輪ロボットが動くWorldファイルをダウンロードする。
今回はtugbot_depot.sdfを使用

https://app.gazebosim.org/fuel/worlds

こちらのページからtugbot_depot.sdfファイルをダウンロードして起動

https://app.gazebosim.org/Fahadalbahoth/fuel/worlds/tugbot_depot

```bash
ign gazebo tugbot_depot.sdf
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399606/80f7b9a5-360a-27ed-448e-d8f7a7af068a.png)

## Ignitionからトピックを送って動かす

### Ignition のGUIから動かす

・右上から`Teleop`と検索してTeleopのGUIを表示させる。
・Topic を`/model/tugbot/cmd_vel`に変更する。
・左下の再生ボタンを押してから`Teleop`のボタンを押すとロボットが動く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399606/2665af73-aaf7-74c2-5824-9f911036807e.png)

### コマンドから動かす
ign topic コマンドで`/model/tugbot/cmd_vel`に直接値を入力して動かす。

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

## ROS2からトピックを送って動かす

ros_ign_bridgeを起動してTwist型の`/model/tugbot/cmd_vel`をbridgeする

```bash
ros2 run ros_ign_bridge parameter_bridge /model/tugbot/cmd_vel@geometry_msgs/msg/Twist@ignition.msgs.Twist
```

ros2 topic pub コマンドでトピックを送る

```bash
ros2 topic pub --once /model/tugbot/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 1.0}}"
```






# センサのトピックをROS2で見る

## Velodyneの点群をrviz2で見る

```bash
ros2 run ros_ign_bridge parameter_bridge /world/world_demo/model/tugbot/link/scan_omni/sensor/scan_omni/scan/points@sensor_msgs/msg/PointCloud2@ignition.msgs.PointCloudPacked
```

rviz2を起動
Fixed Frameをtugbot/scan_omni/scan_omni にして、PointCloud2を表示


```bash
rviz2
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399606/f6b83830-6eed-52a8-bdfe-6520ed63a2ee.png)




## カメラの画像をrqt_image_viewで見る

```bash
ros2 run ros_ign_bridge parameter_bridge /world/world_demo/model/tugbot/link/camera_front/sensor/color/image@sensor_msgs/msg/Image@ignition.msgs.Image
```


rqt_image_viewを起動して画像を見る

```bash
ros2 run rqt_image_view rqt_image_view
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399606/cd9f423e-06f8-074a-b836-d5af9bd0b43f.png)



# TFの変換

ignition gazeboのDiff Drive pluginから出力されるTF 情報（odom <-> base_link）をROS2側で使えるようにする。
Gazebo側のトピック名`/model/tugbot/tf`を`/tf`にremapする。

```bash
 ros2 run ros_ign_bridge parameter_bridge /model/tugbot/tf@tf2_msgs/msg/TFMessage@ignition.msgs.Pose_V --ros-args --remap /model/tugbot/tf:=/tf
```

ROS2側でrqt_tf_treeを実行した結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399606/c50e244c-7fc0-842c-9c0f-7b941e1b2b81.png)

これでbase_linkから必要なセンサのframeのTFをstatic_transform_publisherなどで出力すれば、
ROS2側でSLAMしたり、Nav2で動かしたりできる。


# おわりに

 Igniton Gazeboとros_ignをインストールして、公開されているsdfを使用してROS2と連携して動かした。
間違っている点があればコメントでご指摘ください。


# 参考

https://qiita.com/tygoto/items/052954ff5905f7733b77


https://www.ncnynl.com/archives/202201/4917.html


# その他

## ignitionのコマンドメモ

ros2 topicコマンドと同じ感覚で操作できる

トピック一覧を見る

```bash
 ign topic -l
```

指定したトピックに値を送信

```bash
ign topic -t /model/[model_name]/cmd_vel -m ignition.msgs.Twist -p '[command_values]':
```

トピックの値を見る

```bash
ign topic -e -t /model/[model_name]/cmd_vel
```

## ros_ign_bridgeを起動するlaunchファイルの例

1つのトピックに対してros_ign_bridgeを起動するのは面倒くさいので、launchファイルでまとめて起動する例。
引数に複数のトピックを指定することで、1つのノードで複数のトピックをbridgeできる。

```python:sample.launch.py
from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='ros_ign_bridge',
            executable='parameter_bridge',
            name='bridge_node',
            arguments=[
                '/model/tugbot/cmd_vel@geometry_msgs/msg/Twist@ignition.msgs.Twist',
                '/world/world_demo/model/tugbot/link/scan_omni/sensor/scan_omni/scan/points@sensor_msgs/msg/PointCloud2@ignition.msgs.PointCloudPacked',
                '/world/world_demo/model/tugbot/link/camera_front/sensor/color/image@sensor_msgs/msg/Image@ignition.msgs.Image',
                '/model/tugbot/tf@tf2_msgs/msg/TFMessage@ignition.msgs.Pose_V'
            ],
            remappings=[
                ('/model/tugbot/tf', '/tf')
            ],
            output='screen'
        )
    ])

```