ROSを始めよう　その２

# 前回の内容
[その１](https://qiita.com/hagi-suke/items/b0bb678678b0ec45147c)

# 今回の内容
ROSの基礎知識を身に着け、ROSを体験する
参考：http://wiki.ros.org/ja/ROS/Tutorials/UnderstandingNodes
　　　http://wiki.ros.org/ja/ROS/Tutorials/UnderstandingTopics
　　　http://wiki.ros.org/ja/ROS/Tutorials/UnderstandingServicesParams

# 参考にするもの
主に参考にしたのは次の２つです。
- [ROSwiki Tutorial](http://wiki.ros.org/ja/ROS/Tutorials)
- [ROSではじめるロボットプログラミング―フリーのロボット用「フレームワーク」 (I・O BOOKS)](https://www.amazon.co.jp/ROSではじめるロボットプログラミング―フリーのロボット用「フレームワーク」-I・-BOOKS-小倉-崇/dp/4777519015)

以下の書籍は目を通してみた感じとして、初心者にはやや厳しい印象を受けたので、今回はあまり参考にしませんでしたが、中級者レベルの方は読んでみると良いと思います。
- [ROSプログラミング](https://www.amazon.co.jp/ROSプログラミング-銭-飛/dp/4627853416/ref=pd_sim_14_5?_encoding=UTF8&pd_rd_i=4627853416&pd_rd_r=3a331bee-1e22-11e9-bf49-a1b91366b5d6&pd_rd_w=7kNf2&pd_rd_wg=QMajL&pf_rd_p=68cfebef-f8b4-4691-9d72-a10f0956615a&pf_rd_r=GNAVA1M7PBG6FVFECQZ9&psc=1&refRID=GNAVA1M7PBG6FVFECQZ9) ---簡単な応用例が充実しているようなので、今後参考にするかもしれません
- [Raspberry Piで学ぶ ROSロボット入門](https://www.amazon.co.jp/Raspberry-Piで学ぶ-ROSロボット入門-上田-隆一/dp/4822239292/ref=pd_sim_14_2?_encoding=UTF8&pd_rd_i=4822239292&pd_rd_r=3a331bee-1e22-11e9-bf49-a1b91366b5d6&pd_rd_w=7kNf2&pd_rd_wg=QMajL&pf_rd_p=68cfebef-f8b4-4691-9d72-a10f0956615a&pf_rd_r=GNAVA1M7PBG6FVFECQZ9&psc=1&refRID=GNAVA1M7PBG6FVFECQZ9)
- [実用ロボット開発のためのROSプログラミング](https://www.amazon.co.jp/実用ロボット開発のためのROSプログラミング-西田-健/dp/462767581X/ref=pd_sbs_14_6?_encoding=UTF8&pd_rd_i=462767581X&pd_rd_r=6db8f561-1e22-11e9-b46b-c1dbd27410ef&pd_rd_w=rDhDC&pd_rd_wg=TZZ1M&pf_rd_p=cda7018a-662b-401f-9c16-bd4ec317039e&pf_rd_r=1PD3SQGPSS9XKAV3BTCV&psc=1&refRID=1PD3SQGPSS9XKAV3BTCV)
- [ROSロボットプログラミングバイブル](https://www.amazon.co.jp/ROSロボットプログラミングバイブル-表-允〓/dp/4274221962/ref=pd_sbs_14_1?_encoding=UTF8&pd_rd_i=4274221962&pd_rd_r=6db8f561-1e22-11e9-b46b-c1dbd27410ef&pd_rd_w=rDhDC&pd_rd_wg=TZZ1M&pf_rd_p=cda7018a-662b-401f-9c16-bd4ec317039e&pf_rd_r=1PD3SQGPSS9XKAV3BTCV&psc=1&refRID=1PD3SQGPSS9XKAV3BTCV)
- [プログラミングROS ―Pythonによるロボットアプリケーション開発 (オライリー・ジャパン)](https://www.amazon.co.jp/プログラミングROS-―Pythonによるロボットアプリケーション開発-オライリー・ジャパン-Morgan-Quigley/dp/4873118093/ref=pd_sbs_14_4?_encoding=UTF8&pd_rd_i=4873118093&pd_rd_r=6db8f561-1e22-11e9-b46b-c1dbd27410ef&pd_rd_w=rDhDC&pd_rd_wg=TZZ1M&pf_rd_p=cda7018a-662b-401f-9c16-bd4ec317039e&pf_rd_r=1PD3SQGPSS9XKAV3BTCV&psc=1&refRID=1PD3SQGPSS9XKAV3BTCV)

# ROSの基本用語
ここではROSの基本用語と考え方をざっくりと理解します。
## Node
ROSでは１つのプロセスをNodeと呼びます。
それぞれのNodeは「キーボード入力を受ける」とか「カメラ画像を取得する」とか「モータを動かす」とか「ログを出力する」とかです。
これは、複数のNode同士がつながってグラフを作るためです。
複数のプログラムを結合する通信ライブラリこそがROSの中心部であるとも言えます。
## Message
ROSで通信するためにはあらかじめ決められた型が必要なのですが、型を持った通信で受け渡しされるデータのことをMessageと呼びます。
## Master
roscoreコマンドで起動するプロセスで、ROSのNode同士が通信するための名前の解決をしてくれます。必ず最初に起動しておく必要があります。

# ROSの通信方法
先ほど、ROSではNode同士が通信すると述べました。
ここではその通信方法をざっくりと理解します。
## Topic
ROSのNodeがPublusher/Subscriberモデルでデータを送受信する通信方法です。
あるNodeがあるTopicにデータをPublishして(送信)、そのTopicから別のNodeがデータをSubscribeします(受信)。このとき送受信されるデータがMessageと呼ばれるのでしたね。
このとき、それぞれのNodeは通信相手が誰なのかを意識することなく通信することができます。これは、Topicの型が決まっているため、相手のIPアドレスやポート番号の情報が通信に必要ないからです。
相手を仮定しない通信であるため、相手からの返事を待たない非同期通信となります。![Picture1.png](https://qiita-image-store.s3.amazonaws.com/0/314195/2fd8c829-4cfd-ff47-3769-40cf1970a403.png)
## Service
相手に何かをしてもらい、その成否を知りたいときに利用する同期通信です。
ここではあるNodeをServer、別のNodeをClientと呼ぶことにします。ServerはClientに呼び出されたら何らかの処理をしてくれます(サービスを提供)。そしてその成否をClientに返します。Clientに呼び出されるまでは待機しています。それに対してClientはServerを呼び出し、何らかの処理をさせます(サービスを要求)。そしてServerから成否が返ってくるのを待つのですが、その間Client側の処理は止まります。
![Picture2.png](https://qiita-image-store.s3.amazonaws.com/0/314195/d58507de-16d3-8942-c2e6-ee71834195e7.png)
## Parameter
同じプログラムで様々なロボットを動かせるように、ロボットごとに詳細なパラメータを通信により設定します。
## Action
Serviceでは成否が返ってくるまでClient側の処理が止まってしまい、その間の処理を中断したり、途中の様子を見たりすることができません。別のTopicやServiceを立ち上げて併用すれば良いのですが、そんなことをしなくてもActionというものを使えば、まとめて行うことができます。ここではNodeをActionServer、ActionClientと呼ぶことにします。actionlibというライブラリを利用して実装するのですが、詳しくは実装時に見ていきましょう。

# ROSの各通信方法を体験する
ここではturtlesimというちょっとしたロボットシミュレータ(ロボットというか亀ですが)を使って先ほど紹介した各通信方法を体験し、何となく感覚をつかみます。また、幾つかの基本的なコマンドにも慣れていきましょう。
先に注意しておくと、ROSでは複数のターミナル(端末)を立ち上げることになります。Ctrl+Shift+Tなどをうまく使って、できるだけごちゃごちゃにならないようにしましょう。

## まず最初に必ずすること
`$ roscore`コマンドでMasterを起動しましょう。
このターミナルはそのままにしておく必要があります。

## 亀を動かすためのプログラムを走らせる
ターミナルをもう1つ立ち上げて、`$ rosrun turtlesim turtlesim_node`を実行しましょう。(必要に応じて`$ sudo apt-get install ros-kinetic-turtlesim`でインストール)
ちなみにこのrosrunはプログラムを実行するコマンドです。
上手くいかないときは、`$ sudo apt-get install ros-kinetic-ros-tutorials`をしてみましょう。

## キーボード操作するためのプログラムを走らせる
ターミナルをもう1つ立ち上げて、`$ rosrun turtlesim turtle_teleop_key`を実行しましょう。
このターミナル上で矢印キーを押すと亀が動きます。
実はこれがもうTopicによる通信なのです。それがよくわかるように次は可視化してみたいと思います。
![turtle_key.png](https://qiita-image-store.s3.amazonaws.com/0/314195/0fa50691-002b-98a4-49bc-b2ebd14d86b5.png)

## 可視化ツールを使ってみる
新しいターミナルを立ち上げて、`$ rqt_graph`というコマンドを打つと、Nodeの関係が表示されます。
![999730425B6A2FFB02.png](https://qiita-image-store.s3.amazonaws.com/0/314195/5ecc87c5-dec4-07a5-f938-92942da04f92.png)
見てみると、teleop_turtleというNodeとturtlesimというNodeが、/turtle1/cmd_velというTopicで結ばれています。teleop_turtleというNodeではキーボードの入力を速度指令に変換して、TopicにPublishしています。そのTopicからturtlesimというNodeが速度指令をSubscribeして亀を動かしています。2つのNodeはお互いを意識せずに通信をしているのです。

## コマンドrostopic
新しいターミナルを立ち上げて、`$ rostopic echo`というコマンドを打ってみましょう。これはTopicを詳しく見ることができるコマンドなのですが、このままではよくわかりません。
そこで、`$ rostopic echo /turtle1/cmd_vel`と打ってみましょう。先ほどrqt_graphで見ましたが、/turtle1/cmd_velというのはTopicの名前ですね。この状態で亀を動かしてみると、linear、angularのように前進速度と回転速度のデータが表示されると思います。このようにrostopicではTopicを詳しく見ることができるのです。
ちなみに、このrostopicも実は1つのNodeであり、今回の場合はTopicからSubscribeすることで、情報を取得しているのです。

それでは、他の使い方も見てみましょう。
`$ rostopic type /turtle1/cmd_vel`これでTopicの型を調べることができます。今回のTopicの型はgeometry_msgs/Twistのようです。
`$ rostopic pub /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'`型がわかればTopicにPublishして値を書き込めます。亀が動きましたか？
`$ rostopic pub -r 1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'`オプションで-r 1を加えると1Hz(1秒に1回)データ送信を繰り返します。
`$ rostopic list`現在登録されている全Topicの一覧表示

## コマンドrosservice
`$ rosservice list`現在利用可能な全Serviceの一覧表示
この中に/spawnという亀を生成するServiceがあるので、これを使ってみましょう。
`$ rosservice type /spawn | rossrv show`でServiceの引数と返り値を調べます。

```
$ rosservice type /spawn | rossrv show
float32 x
float32 y
float32 theta
string name
---
string name
```
どうやら座標x, yと姿勢thetaを入力として、そこにnameという名前の亀を生成し、成否をnameで出力するようですね。
`$ rosservice call /spawn 2 3 1 'kame'`で実際にServiceを呼び出せます。

## コマンドrosparam
`$ rosparam list`現在セットされている全Parameterの一覧表示
`$ rosparam get /background_b`Parameterにセットされた値の取得(ここでは背景色の青成分)
`$ rosparam set /background_b 100`Parameterに値をセット
あれ、色が変わりません。実はParameterは基本的に起動時に1回読み取るものなので、`$rosservice call /clear`というコマンドで/clearというServiceを呼び出して、更新しましょう。色は変わりましたか？

## まとめ
今回はROSの基礎知識を身に着け、幾つかのコマンドによってROSを体験していきました。
次回はついにプログラムを書いていこうと思います。

[その３](https://qiita.com/hagi-suke/items/9158a2770db65ea3d4d0)