Pythonistaでrospy

# はじめに

[ROS Advent Calendar 2017](https://qiita.com/advent-calendar/2017/ros) 15日目です。

手持ちのスマホでロボットをちょっと動かしたいという場面はたまにあると思います。ROSで動かせるロボットの場合、Androidだと[rosjavaが使える](http://wiki.ros.org/android?distro=kinetic)ようですが、そもそもAndroidのビルド環境が必要で「ちょっと」というわけにはいかないようです。またiOSだとROSのオフィシャルなクライアントライブラリもないようで、これも簡単にというわけにはいかないようです。
今回[Pythonista](http://omz-software.com/pythonista/)上でrospyを動かすことで、スマホの開発環境を構築することなく、iPhoneを使ってロボットを動かすというのが実現できたので紹介したいと思います。

# Pythonistaとは

[Pythonista](http://omz-software.com/pythonista/)は一言で言うと、iOS上で動かせるPythonの実行環境です。詳細は本家の[ドキュメント](http://omz-software.com/pythonista/docs/)をご参照ください。日本語の[紹介記事](http://hitoriblog.com/?p=42145)もあります。簡単に紹介すると以下のような特徴があります。

* コードエディタ、デバッガ、インタプリタ付き
* GUIやグラフィックスもつくれる
* カメラ、写真、クリップボート、バッテリ情報等にアクセスできる
* numpy, matplotlib等便利なライブラリが既に入っている
* Python2.7, Python3.5対応

一方で**価格が1,200円もする**アプリで、ちょっと遊ぶには高いと思える価格設定です。ただPythonistaを使うことできっと楽しいPython+スマートフォン生活がまっているはず…なので検討してみても損はないかもしれません。


# 動かし方

## 事前準備

以下は最新のPythonistaで実行しています。最新のPythonistaはPython3.5がデフォルトになっているので注意してください。

まずは、iPhoneそのままでプログラムを書くのはつらいので、Bluetoothキーボードでつなぐか、ノートPCからプログラムを転送できる環境を作ります。後者は、[FileTransfer.py](https://gist.github.com/omz/3823483)、[Dropbox File Picker.py](https://gist.github.com/omz/fb180c58c94526e2c40b)等があります。

## インストール

インタプリタで以下を実行します。

```python
import requests as r; exec(r.get('http://bit.ly/1Rq7Zi1').text)
```

以下のような感じで、rospy環境がインストールされます。
<img width="30%" alt="install.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/15624/47ee22ca-e934-b2fd-81f6-a825f33ac80b.png">

## サンプルで通信(Pub/Sub)の確認

サンプルとして、以下のようなプログラムを作成します。
``ROS_MASTER_URI``、``ROS_IP``は、それぞれ**手元のPC**及び、**Pythonistaを実行している端末のIP**を設定します(これを正しく設定しないと通信できません)。

```python
import os
import rospy
import std_msgs.msg
os.environ['ROS_MASTER_URI'] = 'http://192.169.x.x:11311'
os.environ['ROS_IP'] = '192.168.y.y'
os.environ['ROS_PYTHON_LOG_CONFIG_FILE'] = '' # without this, init_node will fail

rospy.init_node('test')
pub = rospy.Publisher('test', std_msgs.msg.Int16, queue_size=1)
rate = rospy.Rate(1)
while not rospy.is_shutdown():
    print('publish')
    pub.publish(3)
    rate.sleep()
```

手元のPCでroscoreを起動したあと、

```bash
$ roscore
... logging to /home/.../.ros/log/03281efc-e0d1-11e7-879e-58946b924f10/roslaunch-...-5345.log
Checking log directory for disk usage. This may take awhile.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://localhost:36217/
ros_comm version 1.12.7


SUMMARY
========

PARAMETERS
 * /rosdistro: kinetic
 * /rosversion: 1.12.7

NODES

auto-starting new master
process[master]: started with pid [5356]
ROS_MASTER_URI=http://localhost:11311/

setting /run_id to 03281efc-e0d1-11e7-879e-58946b924f10
process[rosout-1]: started with pid [5369]
started core service [/rosout]
```

上記のプログラムをPythonistaで実行します。

<img width="30%" alt="running.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/15624/41f1a86d-bb18-b755-4022-12f8abc917aa.png">

手元のPCの端末で以下のように入力することでPythonistaから発行されたROSのトピックが、手元のPCで受信できていることが確認できます。

```bash
$ rostopic list
/rosout
/rosout_agg
/test
$ rostopic echo /test
data: 3
---
data: 3
---
data: 3
---
data: 3
---
data: 3
---
^C
```

停止する場合、**Pythonistaごと落とす** のがいいようです。本当は別のやり方あるような気がしますが、あまり調べていないです。

## iPhoneでGazebo内のTurtleBotを動かす

次に、スマホでロボットを動かす例として、iPhoneでGazebo内のTurtleBot3を動かします。

まずは、TurtleBot3のシミュレータを以下のようにして起動します。ROS_IPを.bashrc等で設定している場合は、指定する必要はありません。

```bash
$ sudo apt-get install ros-kinetic-turtlebot3-gazebo 
$ ROS_IP=*PCのIP* TURTLEBOT3_MODEL=burger roslaunch turtlebot3_gazebo turtlebot3_world.launch
```
<img width="50%" alt="gazebo.png" src="https://qiita-image-store.s3.amazonaws.com/0/15624/2d4942f2-e1b3-66df-c8c2-7435847302d0.png">

次に、Pythonistaにプログラムをインストールします。インタプリタで、下記を実行し``turtlebot.py``をダウンロードします。

```python
import request as r; exec(r.get('http://bit.ly/2CofYwv').text)
```

``turtlebot.py``をPythonistaで実行すると、下記のような画面になるので、Robot IPに**シミュレータが動作しているPCのIP**を設定して、CONNECTボタンをおします。

<img width="30%" alt="connect.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/15624/8dd93ef4-30ea-168c-7779-042bc03b8be2.png">

無事接続されると、スライダでTurtleBot3の速度が変えられるようになります。

<img width="50%" alt="turtlebot.png" src="https://qiita-image-store.s3.amazonaws.com/0/15624/faa0ffa1-dd79-737b-7e7c-a1b9d943eea9.png"> <img width="20%" alt="gui.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/15624/959170f2-8eb5-9be5-8f8d-8d760141f46e.png">


## アンインストール

site-packages以下にrospy等がインストールされているので不要になったら削除してください。

# 中身について

PythonでROSを動かすには、(1)rospy本体とその依存モジュール、(2)メッセージ(std_msgs, sensor_msgs等)のシリアライゼーション用モジュールが必要です。ROSは基本的に、debianパッケージで配ることを想定されているため、pip等ではインストールできません。
そのため(1)については、GitHubからzipファイルでソースコードを取得することで、(2)ついては、GitHubからメッセージファイル(*.msg)を取得し、Pythonista上でgenpyを実行しダウンロード時に生成することでインストールを実現しています。

https://github.com/otamachan/get-rospy
https://github.com/otamachan/pythonista-turtlebot-controller

# 終わりに

Pythonistaを使うことでスマホアプリの開発環境を用意することなく、ROSでロボットが動かせるようになりました。
ちょっとしたデモ等でスマホでロボットが動かせるといろいろ便利かと思います。

Enjoy happy ROS hacking!