Turtlebot2でROSの勉強始めたよ！

## やること
ROSを勉強し始めて、Turtlebot2というROSで動くマシンを買ったので迎え入れる準備をします。

* ubuntu14.04がインストールされているPCを用意し、ROS環境を構築します。
* Turtlebotシミュレーターをインストールします。
* 簡単な命令を与えて動かします。

[ROS Robotics By Example](https://www.amazon.co.jp/Ros-Robotics-Example-Carol-Fairchild/dp/1782175199/ref=sr_1_1?ie=UTF8&qid=1480847403&sr=8-1&keywords=ros+robotics+by+example) という本に書かれているチュートリアルの通りに環境を構築して行っています。
Example形式で進められており書いてある内容も新しいため、本に沿って進めていくだけで結構覚えられます。

## 私のROSスキル
３ヶ月に初めてROSというものを知りました。
完全無欠の初心者です。
普段はJavaやScalaなどで広告システムを開発しているエンジニアです。

## Turtlebot2とは
ROSを既に使い込んでる方に説明するのは恐れ多いですが、知らない人のために。
http://www.turtlebot.com/
これです。
テーブルがついてるRoombaだと思っていただければいいと思います。
これはROSラーニング用に大学などの研究機関や企業でもよく使われるマシンで、シミュレーション環境も整っているためこれを動かしながらROSの勉強をすると捗ります。
オープンソースハードウェアなのでそれを組み立てて販売している企業から購入できます。
日本でも輸入販売している業者がいますが、いくつか見たけど売り切れだったので公式で紹介している http://www.turtlebot.com/distributors/ このへんの企業から買いました。
#### お値段なんと 1,400$ ~ 2,200$！  + 送料100$ ~ 500$ !

安っ...！！これは買うしかないっ...！！

<br>
<br>
すみません、嘘です。さすがにFF15をAmazonでポチるレベルの気安さでは買えません。
個人で買ったわけではありませんが色々な事情があり手に入りました。


## 実機のubuntu14.04にROS環境構築
[これからROSをはじめる人へ](http://qiita.com/potix2/items/a50339c60e1395fb4711)
ROS Advent Calendar 1日目で@potix2さんが書いていますが、本気で勉強したいなら実機のubuntuを手にいれるのが一番いいと思います。理由はこの記事のとおりです。

### ROS Indigoをインストール
ros-indigo をインストールするために必要なツールも含めapt-getで入れてくれるスクリプトを公開してくれている方がいるのでこれを使うとかなり楽です。

```sh
git clone https://github.com/ryuichiueda/ros_setup_scripts_Ubuntu14.04_server
cd ros_setup_scripts_Ubuntu14.04_server
# 二つのスクリプトを順に実行します。
./step0.bash
./step1.bash
```

ubuntu14.04を入れたばかりの環境なら特に困ることはなく終わるはずです。
最後にROSパッケージもフルインストールしておきます。

```
sudo apt-get install ros-indigo-desktop-full
```

これでROSの一通りのパッケージはインストールされました。

```
roscore
rosrun turtlesim turtlesim_node
```

このへんのコマンドを叩いてみて、正常にインストールされてるか確認しましょう。

## ros-turtlebotの環境構築
http://wiki.ros.org/turtlebot/Tutorials/indigo/Turtlebot%20Installation
こちらのサイトに沿ってTurtlebotを入れていきます。

```
sudo apt-get install ros-indigo-turtlebot ros-indigo-turtlebot-apps ros-indigo-turtlebot-interactions ros-indigo-turtlebot-simulator ros-indigo-kobuki-ftdi ros-indigo-rocon-remocon ros-indigo-rocon-qt-library ros-indigo-ar-track-alvar-msgs
```

主にこのコマンドで大体入ります。
(自分でインストールし終わった後にコマンド辿りながら書いてるので、抜けてるものがあるかもしれません。)

### turtlebotシミュレーターをgazeboで立ち上げます。

```
roslaunch turtlebot_gazebo turtlebot_world.launch
```

![screenshot](https://qiita-image-store.s3.amazonaws.com/0/59819/7c2db48a-e40b-8fe8-4b10-f509119c078a.png)

このような画面が立ち上がればオッケーです。

シミュレーター上のTurtlebotがどうやって動くのか私が理解した範囲でざっくり説明すると

* ROSはApacheKafkaのようなPubSubモデルのアーキテクチャ
* シミュレーターを立ち上げると、Turtlebotのトピックが立ち上がる
* 速度に関するトピックを見つけてそこに、速度を変更するようなメッセージをパブリッシュするとTurtlebotの状態（速さ）が変更される

トピックを確認します。

```
rostopic list | grep mobile_base
```

> /mobile/base/commands/motor_power
/mobile/base/commands/reset_odometry
/mobile/base/commands/velocity
/mobile/base/events/bumper
/mobile/base/events/cliff
/mobile/base/sensors/bumper_pointcloud
/mobile/base/sensors/core
/mobile/base/sensors/imu_data
/mobile/base_nodelet_manager/bond

というトピックが見つかります。 `/mobile/base/commands/velocity` というトピックが速さの状態変更を受け付けるトピックのようなのでこれに対してパブリッシュしたいと思います。

```
rostopic type /mobile_base/commands/velocity
```

> geometry_msgs/Twist

メッセージの型が取得できました。
この型でパブリッシュします。

```
rostopic pub -r 10 /mobile_base/commands/velocity geometry_msgs/Twist '{linear: {x: 0.3}}'
```

`-r 10` は10Hz感覚でスリープするという引数。（たぶん）
`linear` のx成分を0.3に書き換えました。

### 実行結果
![line.gif](https://qiita-image-store.s3.amazonaws.com/0/59819/bc21f3ea-fbba-d5fc-b2b9-e42db85319c5.gif)

動きましたね。
`x: -0.3` とすると逆に進みます。
Turtlebotを右クリックして `View > Joints` を選択すると物体の軸が可視化できて運動が見やすいです。

### rospyでpythonからROSトピックに対してパブリッシュする
コマンドから叩けたので次にやりたいのがプログラムから動かすことです。
rospyというPythonのライブラリがあるのでそれを使えば簡単にROSを操作できます。

```py
#!/usr/bin/env python
import rospy
from geometry_msgs.msg import Twist

class TurtleBotSim():
    def __init__(self):
        rospy.init_node('ControlTurtleBot', anonymous=False)


        rospy.loginfo(" Press CTRL+c to stop TurtleBot")

        rospy.on_shutdown(self.shutdown)

        self.cmd_vel = rospy.Publisher('cmd_vel_mux/input/navi', Twist, queue_size=10)

        r = rospy.Rate(10);
        twist = Twist()

        # x軸の速さ
        twist.linear.x = 0.3
        # 回転速度
        twist.angular.z = 0

        while not rospy.is_shutdown():
            self.cmd_vel.publish(twist)
            r.sleep()


    def shutdown(self):
        rospy.loginfo("Stop TurtleBot")
        self.cmd_vel.publish(Twist())
        rospy.sleep(1)

if __name__ == '__main__':
    try:
        TurtleBotSim()
    except:
        rospy.loginfo("TurtleBot finish")
```

`CTRL + c` でプログラムが強制終了されるまで、ループで実行し続けます。
直進は先ほどコマンドからやったので回転させてみます。

```py
import math
~
twist.angular.z = math.pi
```

このように変更した後、プログラムを実行します。

```
python TurtleBotSim.py
```

結果↓
![spin.gif](https://qiita-image-store.s3.amazonaws.com/0/59819/a0f124b5-7a4c-8c3e-d457-b73c1c2ca050.gif)

回りました。
angular.zというのは回転軸に対する速度のようです。単位は `rad/sec` です。
ちなみに、横に動かしたくて `twist.linear.y = 0.3` のように書いたのですが動きませんでした。
なぜかというとTurtlebotはタイヤの構造的にx軸にしか動かないからです。
横に行きたい場合、回転させてから直進必要があります。


次に、両方入れるとどうなるか
```
twist.linear.x = 0.6
twist.angular.z = 0.6
```

結果↓
![ci.gif](https://qiita-image-store.s3.amazonaws.com/0/59819/052ee950-0836-7204-ceb3-22fa1a9ac43f.gif)

はい、やる前に想像はつくけど回りました。

最後です
```
twist.linear.x = 500000
```

シミュレータだととりあえず一度はやりたくなりますよね。
結果↓
![boost.gif](https://qiita-image-store.s3.amazonaws.com/0/59819/f8338664-bda3-331a-c2e5-9be180dae918.gif)

シミュレータ上でまっすぐ以外の力が働いているのか、スピンしてしまいます。
立ち上げて何も動かしていない状態でもこうなってしまいましたが、たまーにまっすぐ走ります。


## まとめ

* ROSの勉強を始めた -> Turtlebotを購入。届くまでシミュレータで遊ぶ
* ROSとTurtlebotSimulatorをUbuntu14.04にインストール
* シミュレータを起動し、コマンドやPythonからメッセージを送りTurtlebotを動かした

Ubuntu14.04でROSやTurtlebotを動かす方法は探せばネットいっぱい情報があるため、勉強するのにはあまり困りません。（感謝です。）
Pythonから動かすところまでいったので、プログラミングできるベースは整いました。
今後、センサーや画像の情報からTurtlebotを制御できるようにしていけたらと思います。
次回はクリスマス前に、実際に動かしてみた様子を書こうかと思います。
それまでに、届くといいんですが！