AmazonDashButtonを押したらドローンにハッピーターンを運んできてもらう


みなさん、こんにちわ。
オープンストリームのKokichiです。
さて、今回はボタンを押したらドローンに物を運んでもらうというお話です。

#使うもの＆やること
**ドローン**：[Parrot Mambo](https://www.parrot.com/jp/minidoron/parrot-mambo-mission#parrot-mambo-mission)
このドローンにはアームがあり、これを装着することで物（最大4 g）を運べるようになります。

**運ぶ物**：ハッピーターン１枚
私はハッピーターン中毒者なので、ハッピーターン運んでもらいます。重さは約4gなので、運べそうです。
(ちなみカロリーは約21kcal)

**ボタン**：[Amazon Dash Button](https://www.amazon.co.jp/b/?ie=UTF8&node=4752863051&ref=bb1_dascb5d4f8b6886&pf_rd_r=EH5T0N8B3Y4FYP9CH61H&pf_rd_p=9f4c80bf-b10e-44ca-bee3-0e6eb629c44d)
アマゾンプライムデーの時に大量購入したAmazon Dash Buttonを使います。もちろん正しくない方向で使用します。

**管制塔**：Raspberry Pi 3（OS:Raspbian GNU/Linux 8.0 jessie）
ドローンを操作したり、Amazon Dash Buttonシグナルを検知したり色々やってもらいます。
今回はOSはRaspbian(Jessie)を使用しますが、最新のRaspbian(Stretch)でも問題ないと思います。

ということで、Amazon Dash Buttonを押したらドローンにハッピーターンを運んできてもらうことにします。

![overview_image.png](https://qiita-image-store.s3.amazonaws.com/0/60630/d24fb9d2-d4e4-7526-ce6d-72b187cc87b6.png)

#作業内容
大まかな作業は以下の２つなります。

- Raspberry Piからドローンを操作する。
- Amazon Dash Buttonが押されたらRaspberry Piでシグナルを検知する。

Raspberry PiへのOSセットアップは完了しており、Wi-fi接続されている前提で進めます。
また、作業はコマンド操作がメインになるため、Raspberry PiにSSH接続してコマンド実行できるようにしています。

#Raspberry Piからドローンを操作する

ここでの作業は以下になります。

1. ソフトウェアのインストール
2. [pyparrot](https://github.com/amymcgovern/pyparrot)のダウンロード（ドローン操作ライブラリ）
3. Pythonプログラムを書く
4. ドローンを操作する

##ソフトウェアのインストール
Raspberry Piにドローンを操作するために必要なソフトウェアをインストールしていきます。
Python3はデフォルトでインストールされているためインストール作業はしてません。

まずはパッケージを最新にします。

```linux-config:raspbian
$　sudo　apt-get update
$　sudo　apt-get upgrade
```

ドローンとWi-Fi接続するためのソフトウェアをインストールします。

```linux-config:raspbian
$　sudo pip3 install zeroconf
```

ドローンとBluetooth接続するためのソフトウェアをインストールします。

```linux-config:raspbian
$　sudo apt-get install bluetooth
$　sudo apt-get install bluez
$　sudo apt-get install python-bluez
$　sudo pip3 install untangle
$　sudo apt-get install python-pip libglib2.0-dev
$　sudo pip3 install bluepy
$　sudo apt-get update
```
##pyparrotをダウンロード

作業ディレクトリを作成します。

```text:raspbian
$　mkdir -p  ~/work/drone
$　cd ~/work/drone
```
作業ディレクトリ配下に`pyparrot`をダウンロードし解凍します。
（2017/12/13 時点で最新のリリース1.2.1をダウンロードしています。）

```text:raspbian
$　wget https://github.com/amymcgovern/pyparrot/archive/1.2.1.tar.gz
$　tar -zxvf 1.2.1.tar.gz
$　rm -r 1.2.1.tar.gz
$ cd pyparrot-1.2.1
```

##ドローンのBLEアドレスを調べる

ドローンの電源を入れ、先程ダウンロードした`pyparrot-1.2.1`フォルダ中の`findMambo.py`を実行します。

```linux-config:raspbian
$ sudo python3 findMambo.py
・
・
・
FOUND A MAMBO!
Device xx:xx:xx:xx:xx:xx (random), RSSI=-00 dB　 // 見つかるとドローンのBLEアドレスが表示される
  Complete Local Name = Mambo_*****
```

見つかったBLEアドレスは次のプログラム作業で使用するのでメモをしておく。

##Pythonプログラムを書く

先程メモしたBLEアドレスを書き換えて`droneApp.py`という名前で`pyparrot-1.2.1`フォルダ配下に保存します。

```py3:droneApp.py
from Mambo import Mambo

# 先程メモしたドローンのBLEアドレスに書き換えください
mamboAddr = "xx:xx:xx:xx:xx:xx"

# ドローンのオブジェクト作成
# ドローンのアームはBLE接続しないと操作できないためWi-FiはOFFにしてBLE接続する
mambo = Mambo(mamboAddr, use_wifi=False)

# ドローンと接続開始
print("trying to connect")
success = mambo.connect(num_retries=3)
print("connected: %s" % success)

# アームを開く
print("open the claw")
mambo.open_claw()
mambo.smart_sleep(5)

# アームを閉じる
# ここでハッピーターンをキャッチ
print("close the claw")
mambo.close_claw()
mambo.smart_sleep(5)

# 離陸
print("taking off!")
mambo.safe_takeoff(5)

# 前進
print("Flying direct: going forward")
mambo.fly_direct(roll=0, pitch=50, yaw=0, vertical_movement=0, duration=1)
mambo.smart_sleep(5)

# アームを開く
# ここでハッピーターンをリリース
print("open the claw")
mambo.open_claw()
mambo.smart_sleep(5)

# 着陸
print("landing")
mambo.safe_land(5)
mambo.smart_sleep(5)

# ドローンと接続解除
print("disconnect")
mambo.disconnect()
```

##テスト飛行
ドローンを起動して、書いた`droneApp.py`を実行してボタンを押します。

```py3:droneApp.py
sudo python3 droneApp.py
```

<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr"><a href="https://t.co/Vs06zrgtaL">pic.twitter.com/Vs06zrgtaL</a></p>&mdash; kokichi@opst (@kokichi_opst) <a href="https://twitter.com/kokichi_opst/status/941218290424098816?ref_src=twsrc%5Etfw">2017年12月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

書いたプログラムはアームの開閉と前進しかしてませんが、この他にもいろんな動きができます。
もっといろんな動き試したい方は、[pyparrotのGithub](https://github.com/amymcgovern/pyparrot)にメソッドの説明がありますので、そちらを参照してください。また、ダウンロードした`pyparrot-1.2.1`にサンプルコードがあるのでそちらも参考にしてみてください。

続いてAmazon Dash Buttonの設定作業に移ります。

#Amazon Dash Buttonが押されたらRaspberry Piでシグナルを検知する
ここでの作業は以下になります。

1. Amazon Dash Buttonのセットアップ
2. Node.jsをインストール
3. [dash-button](https://www.npmjs.com/package/dash-button)モジュールのインストールとセットアップ
4. Amazon Dash ButtonのMACアドレスを調べる
5. Node.jsプログラムを書く

##Amazon Dash Buttonのセットアップ

Amazonショッピングアプリのメニューから「アカウントサービス」→「Dash端末」→「新しい端末をセットアップ」に移動してセットアップ開始してください。Wi-Fi設定まで完了すると「商品を選択」画面になります。ここで右上の「×」を押し、ダイアログが表示されたら「セットアアップを終了」を選んで完了させてください。

<img width="200" alt="DropShadow ~ IMG_1198.png" src="https://qiita-image-store.s3.amazonaws.com/0/60630/2f38ff94-7309-37d3-42e5-b4299663ead2.png">

##Node.jsをインストール
Node.jsをインストールします。私の環境では`apt-get`を使用してNode.jsをインストールすると古いバージョンがインストールされるため、今回は公式からパッケージをダウンロードしてインストールするようにしました。

dash-buttonモジュールは`NODE_MODULE_VERSION`が`59`以上のものが必要なため、`node-v9.2.1-linux-armv7l.tar.xz`をダウンロードします。

```text:raspbian
$ cd ~/Downloads
$ wget https://nodejs.org/dist/v9.2.1/node-v9.2.1-linux-armv7l.tar.xz
$ cd /usr/local
$ sudo xzcat ~/Downloads/node-v9.2.1-linux-armv7l.tar.xz | sudo tar xvf -
$ sudo mv node-v9.2.1-linux-armv7l nodejs
```

PAHTを設定します。`~/.profile`に以下を追記してください。

```text:.profile
if [ -d "/usr/local/nodejs/bin" ] ; then
    PATH="/usr/local/nodejs/bin:$PATH"
fi
```
追記したPAHTを反映させます。

```text:raspbian
$ source ~/.profile
```

nodeコマンドが実行できるか確認します。

```text:raspbian
$ node -v
v9.2.1
```

コマンドの確認ができたらNode.jsのインストールは完了です。

##dash-buttonモジュールのインストールとセットアップ
作業フォルダを作成します。

```text:raspbian
$　mkdir -p  ~/work/dashButton
$　cd ~/work/dashButton
```
`package.json` を生成します。
コマンド実行あとに色々質問されますが、全て`ENTER`でOKです。

```text:raspbian
$　npm init
```

`dash-button`をインストールします。

```text:raspbian
$　sudo apt-get install libpcap-dev
$　npm install --save dash-button
```

`package.json`を編集します。

```text:package.json
{
  "name": "dashButton",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "dash-button": "^3.2.0"
  },
  "devDependencies": {},
  "scripts": {
     "scan": "dash-button scan"　 //←これを追加
  },
  "author": "",
  "license": "ISC"
}
```

##Amazon Dash ButtonのMACアドレスを調べる
MACアドレスを調べます。

```text:raspbian
$ sudo npm run scan

// Amazon Dash Buttonを押す

Scanning for DHCP requests and ARP probes on en0...
Detected a DHCP request or ARP probe from xx:xx:xx:xx:xx:xx　←これがボタンのMACアドレス

```

調べたMACアドレスは次のプログラム作業で使用するのでメモをしておいてください。

##Node.jsプログラムを書く
ボタンが押されたらシグナルをフックして、ドローンを起動するプログラムを書きます。
先程メモしたMACアドレスを書き換えて`dash.js`という名前で保存してください。

```js:dash.js
// モジュール読み込み
const DashButton = require("dash-button");
const exec = require('child_process').exec;

// Amazon Dash ButtonのMACアドレス
const DASH_BUTTON_MAC_ADDRESS = "xx:xx:xx:xx:xx:xx";

console.log("Listening!");

// Amazon Dash Buttonからのシグナル監視
let button = new DashButton(DASH_BUTTON_MAC_ADDRESS);
let subscription = button.addListener(() => {
  console.log("Execute drone program!!!!!");
  exeDroneProgram();
});

//ドローンのプログラムを実行する関数
function exeDroneProgram() {
  exec('python3 ../drone/pyparrot-1.2.1/dronApp.py', (err, stdout, stderr) => {
    if (err) { console.log(err); }
       console.log(stdout);
   });
}
                                  
```

#ハッピーターンを運んできてもらう 
書いた`dash.js`を実行してボタンを押します。

```text:raspbian
$ sudo node dash.js 
Listening!
// Amazon Dash Buttonを押す
```

<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr"><a href="https://t.co/I2yhEb9fmW">pic.twitter.com/I2yhEb9fmW</a></p>&mdash; kokichi@opst (@kokichi_opst) <a href="https://twitter.com/kokichi_opst/status/941220562067603457?ref_src=twsrc%5Etfw">2017年12月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ハッピーターン運べました！



#参考
- [pyparrot](https://github.com/amymcgovern/pyparrot)
- [dash-button](https://www.npmjs.com/package/dash-button)
- [Amazon Dash Buttonを(正しくない方向で)使ってみた](https://qiita.com/takustaqu/items/8539b33780c9675c8657)