ROS MelodicでTurtlebot3をGazeboで動かしてついでにSLAMする

# まえがき
Gazebo上に置いたTurtlebot3でgmappingをやるための手順のメモ．

Turtlebot3とは？→ ROSが使える差動二輪ロボットプラットフォーム．
gmappingとは？→ 格子地図を生成するためのSLAMパッケージ．

gmappingは超簡単に言うと，tfでセンサの座標を見ながら/scanをsubscribeして/mapを作ってくれるすごいやつです．
Turtlebot3は自身のオドメトリから計算されるtfを更新しながら，搭載しているレーザセンサ(Laser Distance Sensor LDS-01)の値を/scanでpublishしています．
なので，Turtlebot3のgazeboシミュレータとgmappingのノードを動かせば地図が生成される．はず．

# 環境
私の実行環境は以下のとおりです．

- CPU: Intel core i7 3770
- GPU: Geforce RTX2070
- OS: Ubuntu 18.04 LTS
- ROS: Melodic

# 手順
## 前提
ROS Melodicのインストールが済んでいること．インストール方法は色々と情報が転がってると思うので割愛．
GazeboとRVizも使うので，ROSインストール時に一緒に入ると思うけど一応動作を確認しておいてください．

```bash
$ gazebo
$ rviz
```

## 依存パッケージをインストール
多い

```bash
sudo apt-get install ros-melodic-joy ros-melodic-teleop-twist-joy ros-melodic-teleop-twist-keyboard ros-melodic-laser-proc ros-melodic-rgbd-launch ros-melodic-depthimage-to-laserscan ros-melodic-rosserial-arduino ros-melodic-rosserial-python ros-melodic-rosserial-server ros-melodic-rosserial-client ros-melodic-rosserial-msgs ros-melodic-amcl ros-melodic-map-server ros-melodic-move-base ros-melodic-urdf ros-melodic-xacro ros-melodic-compressed-image-transport ros-melodic-rqt-image-view ros-melodic-navigation
```

本当はgmappingもaptで入ってくれると嬉しいんだけど，残念ながらまだMelodic版はaptで入ってくれない(2019.5.9現在)ので，これは後々手動で追加します．

## Turtlebot3の環境構築
いつも通りワークスペースを作ります．ワークスペース名は任意．

```bash
$ mkdir -p ~/catkin_ws/src
$ cd ~/catkin_ws/src
$ catkin_init_workspace
$ cd ~/catkin_ws
```

Turtlebot3のROSパッケージをcloneします．

```bash
$ cd ~/catkin_ws/src
$ git clone https://github.com/ROBOTIS-GIT/turtlebot3.git
$ git clone https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git
$ git clone https://github.com/ROBOTIS-GIT/turtlebot3_simulations.git
$ git clone https://github.com/ROBOTIS-GIT/turtlebot3_gazebo_plugin.git
```

ビルド．

```bash
$ cd ~/catkin_ws
$ catkin_make
$ source ~/catkin_ws/devel/setup.bash
```

## RVizで動作確認
環境変数でTurtlebot3のモデルを指定する必要があるので以下を実行してください．

```bash
$ export TURTLEBOT3_MODEL=burger
```

モデルには`burger`の他に`waffle`と`waffle_pi`があります．好きなやつを指定してください．bashrcとかに書いちゃってもいいと思う．

まずRVizで動作を確認します．

```bash
$ roslaunch turtlebot3_fake turtlebot3_fake.launch
```
RVizが起動して，画面内にさっき指定したモデルのTurtlebot3がいればOK．(画像はwaffleです）
![Screenshot from 2019-05-09 15-38-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198828/3ce14780-a4f5-1076-d0b9-b90348d06336.png)
もしTurtlebot3のモデルが真っ白になってる場合は，他に起動しているroscoreを落としてもう一回RVizを立ち上げるとちゃんと表示されると思います．
/cmd_velでTwistを投げると動きます．rqtから手動で送ることもできるけど，キーボードで動かしたい場合はターミナルをもう一つ開いて，

```bash
$ roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
```

でキーボードコントローラを実行できます．WASDXキーでRViz上のTurtlebot3が動きます．

![Screenshot from 2019-05-09 16-01-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198828/b8c065e2-410f-22db-d1d3-8c9078508130.png)
rqt_graphを表示した図．キーボードコントローラから/cmd_velトピックがTurtlebot3に流れていることがわかりますね．

## Gazeboで動作確認
RVizでTurtlebot3が動くことを確認したらGazeboで動かします．
RVizを閉じて以下のコマンドを実行してください．

```bash
$ roslaunch turtlebot3_gazebo turtlebot3_world.launch
```

このとき，

```
terminate called after throwing an instance of 'std::runtime_error'
  what():  locale::facet::_S_create_c_locale name not valid
```

とか出てGazeboが起動しない場合は

```
$ export LC_ALL=C; unset LANGUAGE
```

とかやると動くと思います．

Gazeboが起動するとカメ🐢のようなワールドにTurtlebot3が配置されています．
![Screenshot from 2019-05-09 16-16-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198828/81c9b0cd-b817-a3bc-7ec1-f6636c622b84.png)
先ほどRViz内のTurtlebot3を動かしたときと同様に，キーボードコントローラを用いて動かすことができます．

## gmappingの環境構築
gmappingを用いたSLAMをするための準備をします．まず起動しているGazeboとキーボードコントローラを終了してください．

gmapping関連のパッケージをcloneします．

```bash
$ cd ~/catkin_ws/src
$ git clone https://github.com/ros-perception/slam_gmapping.git
$ git clone https://github.com/ros-perception/openslam_gmapping.git
$ git clone https://github.com/ros-planning/navigation_msgs.git
$ git clone https://github.com/ros-planning/navigation.git
$ git clone https://github.com/ros/geometry2.git
```

再度ビルド．

```bash
$ cd ~/catkin_ws
$ catkin_make
$ source ~/catkin_ws/devel/setup.bash
```

gmappingのビルドにそれなりに時間がかかるのでお茶🍵でも飲んで待ちましょう．

## gmappingの動作確認

ビルドが終了したら先程と同様にGazeboとteleopコントローラを立ち上げます．

```bash
$ roslaunch turtlebot3_gazebo turtlebot3_world.launch
```

```bash
$ roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
```

次にgmappingのノードを立ち上げます．Turtlebot3のパッケージにlaunchファイルが用意されているので，そちらを用います．

```bash
$ roslaunch turtlebot3_slam turtlebot3_slam.launch slam_methods:=gmapping
```

RVizが立ち上がり，Turtlebot3本体とセンサの取得データ，および生成されたmapデータが表示されていればOKです．
![Screenshot from 2019-05-09 16-41-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198828/1448159f-0d86-4639-745c-325cbddcba9b.png)
コントローラで動かして空間内を移動させていくと，地図が逐次更新されていくのがわかると思います．

rqt_graphで表示したノード間の関係です．
![Screenshot from 2019-05-09 16-42-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198828/39d95880-59de-6270-2d71-d180a5c5877b.png)
gazebo(Turtlebot3)がtfを更新しながら/scanをPublishし，gmappingノードがそれをSubscribeして/mapを出力しているのがわかります．

# 参考文献

- [ROBOTIS e-Manual | TurtleBot3](http://emanual.robotis.com/docs/en/platform/turtlebot3/overview/)
- [BRILLIANTSERVICE TECHNICAL BLOG | ROSで始めるロボティクス（12）](http://bril-tech.blogspot.com/2017/06/ros12.html)
- [ROS Wiki | gmapping](http://wiki.ros.org/gmapping)
- [ROSのSLAMを使った地図作成とナビゲーション](http://joe.ash.jp/program/ros/tutorial/tutorial_slam.htm)
- [技術メモ集 | ROS melodic(Ubuntu18.04)でmap_server,gmapping,navigationパッケージを導入する](https://www.robotech-note.com/entry/2018/12/16/ROS_melodic%28Ubuntu18_04%29%E3%81%A7map_server%2Cgmapping%2Cnavigation%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%82%92%E5%B0%8E%E5%85%A5%E3%81%99%E3%82%8B)