ROSの勉強　第10弾：移動-Twist

# #プログラミング ROS< 移動-Twist >

## はじめに
1つの参考書に沿って，ROS(Robot Operating System)を難なく扱えるようになることが目的である．その第10弾として，移動-Twistを扱う．


## 環境
##### 仮想環境
|||
|:-:|:--|
|ソフト|VMware Workstation 15|
|実装RAM|2 GB|
|OS|Ubuntu 64 ビット|
|isoファイル|ubuntu-mate-20.04.1-desktop-amd64.iso|

##### コンピュータ
|||
|:-:|:--|
|デバイス|MSI|
|プロセッサ|Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz 2.50GHz|
|実装RAM|8.00 GB (7.89 GB 使用可能)|
|OS|Windows (Windows 10 Home, バージョン：1909)|

##### ROS
|||
|:-:|:--|
|Distribution|noetic|
|プログラミング言語|Python 3.8.5|
|シミュレーション|gazebo|


## タスク
今回実行するタスクについて簡単に示す．

・1秒間に10回の頻度で動作コマンドを送り続ける
・3秒ごとに移動と停止を切り替える
・移動を0.5 m/sの前進，停止を0 m/sと定義する

ここでは，シミュレーション(gazebo)上でturtlebotを動かしてこのタスクの達成を確認する．なお，ここで用いるturtlebotは``turtlebot3``である．


## tutlebot3
turtlebot3を動かすため，その情報を知る必要がある．とりあえず，シミュレーション上でtutlebot3を構築する．

```
yuya@ubuntu:~$ export TURTLEBOT3_MODEL=burger
yuya@ubuntu:~$ roslaunch turtlebot3_gazebo turtlebot3_world.launch
```
注意としては，turtlebot3には3つのモデルがあり，どれかを選択する必要があるということである．指定しないと，エラーが出て起動しない．また，``turtlebot3_world.launch``でシミュレーションでの世界を構築しているわけだが，turtlebot3_gazeboの中にはほかにも環境のテンプレートがいくつかある．(参考：https://emanual.robotis.com/docs/en/platform/turtlebot3/simulation/ )

なお，以下のようにすることで，１つ(ここではburger)に固定されてしまうが，毎回打つ手間が省ける．

```
yuya@ubuntu:~$ echo "export TURTLEBOT3_MODEL=burger" >> ~/.bashrc
```

実行後，次のようなシミュレーション環境がgazebo上で構築される．
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/586506ba-d262-b76d-1b6c-86a91cc3e85b.png)

![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/52b489c9-4d2e-9153-5fd1-2b70de0666e4.png)
2枚目は少し拡大して，turtlebot本体を見やすくしている．

このとき，同時にturtlebotに関するトピックなども確認することができる．それにより情報を得る．
**実行前**
![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/4b95e1dd-c129-9763-8217-0c8215295600.png)
**実行後**
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/01e67b47-53e0-252c-1730-ba1bfb284d7e.png)

様々な要素が増えていることが分かる．今回は，速度制御のみを行うため，``/cmd_vel``だけに注目する．詳しく見てみると...
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/1c20bd80-edf1-0d41-c530-22c3fbaf4687.png)
このトピックをgazeboが購読しているので，このトピックを操作するようなプログラムを作成すれば，動かせそうだということが分かる．

## プログラム
先ほどの情報と，タスク内容を踏まえてプログラムを構築する．以下にソースコードを示す．

##### ソースコード
```red_light_green_light.py
#! /usr/bin/env python3

"""
タスク

・1秒間に10回の頻度で動作コマンドを送り続ける
・3秒ごとに移動と停止を切り替える
・移動：0.5 m/sの前進
・停止：0 m/s
"""

import rospy
from geometry_msgs.msg import Twist	#速度コマンドをもつ

cmd_vel_pub = rospy.Publisher('cmd_vel', Twist, queue_size = 1)	#Twist型で'cmd_vel'というトピックを生成
#queueは一時的に保存できるメッセージ数．これを超える頻度でメッセージを送ると，rospyでは超える分を破棄する

rospy.init_node('red_light_green_light') #'red_light_green_light'という名前のノードを作成

red_light_twist = Twist()	#Twistのインスタンスを作成
green_light_twist = Twist()	#こうすることで，Twistのフィールドにアクセス可能

green_light_twist.linear.x = 0.5	#green_lightのTwistでx方向に0.5 m/s


driving_forward = False
light_change_time = rospy.Time.now()
rate = rospy.Rate(10)	#10Hz → 1秒間に10回のコマンドを送る

while not rospy.is_shutdown():
	if driving_forward:
		cmd_vel_pub.publish(green_light_twist)	#green_light_twistでトピック配信
	else:
		cmd_vel_pub.publish(red_light_twist)	#red_light_twistでトピック配信


	if light_change_time < rospy.Time.now():
		driving_forward = not driving_forward	#driving_forwardのT/F切り替え
		light_change_time = rospy.Time.now() + rospy.Duration(3)

	rate.sleep()	#必要以上に膨大なメッセージを送ってしまいCPUを使い果たしてしまうことを防ぐ
```

## 実装
gazeboを起動した状態で，先ほどのプログラムを実行する．
![ezgif-7-d43d03a1f6fd.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/d129ee05-3f0e-16cb-cf80-2824f918b5f2.gif)

少し小さく見づらいが，上図左上のターミナル(端末)で，``rosrun``により先ほどのプログラムを実行．上図左下のターミナル(端末)で，``rostopic echo /cmd_vel``によりturtlebotの速度変化を可視化している．上図右はシミュレーション環境であり，黒い点のようなものが上から見たturtlebotである．速度変化に伴い動いていることが分かる．

## 結果
タスクを達成することをシミュレーション環境で確認できた．しかしながら，曲がるプログラムを入れていないにもかかわらず，turtlebotの車体が停止時に少し曲がってしまうことが見受けられた．これは何度指向しても同様の結果となった．滑っているように見えたため，おそらく左右の車輪において摩擦力の差が生まれているのかと思われるが，現時点でその中身まで確認する術は学んでいないため，考察はここまでとする．

## 感想
turtlebotおよびシミュレーション環境の詳細を探れば，停止時に曲がる原因が分かるかもしれないと思ったが，後々学ぶ中でその術が学べたらと思う．いま，そこに時間を費やすのは少し脱線してしまうと思ったため，そこまでの追及はしていない．早くそこまで分かるレベルになれるように頑張っていこう．次回はセンサの扱いについて学ぶ．これも実践的で楽しみである．

## 参考文献
プログラミングROS Pythonによるロボットアプリケーション開発
　　　　　　　　Morgan Quigley, Brian Gerkey, William D.Smart 著
　　　　　　　　　　　　　　　　　　　　　　　河田　卓志　監訳
　　　　　　　　　　  　松田　晃一，福地　正樹，由谷　哲夫　訳
　　　　　　　　　　　　　　　　　　オイラリー・ジャパン　発行