「Alohomora」の呪文を現実世界で再現してみた

# 概要
[UEQareer Advent Calendar](https://qiita.com/advent-calendar/2018/ueqareer) 18日目の投稿です

いきなりですが、みなさんはハリーポッターは好きですか？
今回は、そのハリーポッターに出てくる「Alohomora」という鍵を開ける呪文を再現したお話をしたいと思います

# 目次
1. Alohomoraって？
2. 完成形
3. 使用したもの
4. システム構成
5. 中身


## Alohomoraって？
「Alohomora」とはハリーポッターに出てくる鍵を開ける呪文です
この動画をみてもらうとわかりやすいと思います



<blockquote class="twitter-tweet" data-lang="ja"><p lang="es" dir="ltr">Alohomora(for advent calendar)<a href="https://t.co/M6aRbJliGs">https://t.co/M6aRbJliGs</a></p>&mdash; もーりー🌓 (@m___04v) <a href="https://twitter.com/m___04v/status/1073501961704468483?ref_src=twsrc%5Etfw">2018年12月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

「Alohomora」と唱えながら鍵に向かって杖をかざすと、鍵が開きます

今回は「Alohomora」をRaspiとサーボモータを使って再現したいと思います

## 完成形
中身は興味ない！って人もいると思うので完成形はこちら！
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">手作りAlohomora(for advent calendar) <a href="https://t.co/6C1pKRvXFz">pic.twitter.com/6C1pKRvXFz</a></p>&mdash; もーりー🌓 (@m___04v) <a href="https://twitter.com/m___04v/status/1073504922010759168?ref_src=twsrc%5Etfw">2018年12月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
杖を振り回すと鍵が開閉できるようになっています

## 使用したもの
- **Raspberry Pi zero**
- **Raspberry Pi 3**
- **サーボモータ**
- **6軸センサ**
- **タクトスイッチ**
- **3Dプリンタ**


↓完成した魔法の杖

![DSC_1018.png](https://qiita-image-store.s3.amazonaws.com/0/192773/36aa42e6-9c81-932f-d92e-b7b24bbfd8c4.png)



## システム構成

### 魔法の杖
もともとこのシステムを作成する前に、[REDIMPULZ](https://redimpulz.com/)さん主催の[IoTハッカソン](https://ueqareer.connpass.com/event/88839/)で魔法の杖というデバイスを作成しました
魔法の杖のシステム構成は以下のようになっています
![スクリーンショット 2018-12-14 18.17.28.png](https://qiita-image-store.s3.amazonaws.com/0/192773/69a9231d-c2b1-0962-b804-03df7b6ba221.png)

1. **杖につけた6軸センサから値を取得**
2. **Jubatusで機械学習させ動作を推定**
3. **APIで動作と紐づけたイベントを発火させる**
4. **対応したIFTTTのイベントを実行させる**


このような流れで魔法の杖でテレビの電源制御やエアコンの電源制御を可能にしました

### スマートロック

また、僕は趣味で研究室の鍵をICカードで開けれるように改造しました
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">スマートロックの状態をM5Stackで常時見れるようにしたよ<br>mqtt使ってます🤔 <a href="https://t.co/35txw8qAM9">pic.twitter.com/35txw8qAM9</a></p>&mdash; もーりー🌓 (@m___04v) <a href="https://twitter.com/m___04v/status/1048887468110442497?ref_src=twsrc%5Etfw">2018年10月7日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

裏側はこんな感じ
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">裏側のゴリ押し具合 <a href="https://t.co/8gnCfgu8Vm">pic.twitter.com/8gnCfgu8Vm</a></p>&mdash; もーりー🌓 (@m___04v) <a href="https://twitter.com/m___04v/status/1044185295019696128?ref_src=twsrc%5Etfw">2018年9月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


このスマートロックは以下のようなシステム構成になっています
![スクリーンショット 2018-12-14 18.23.28.png](https://qiita-image-store.s3.amazonaws.com/0/192773/aa4cbf47-124b-3849-f8ac-0ffb77a04c1c.png)

1.　**NFCのカードリーダに登録済みのカードをかざす（OR　アプリのボタンを押す）**
2.　**Flaskで作成したAPIを叩く**
3.　**GPIOでサーボモータを制御**
4.　**鍵の開閉に成功したらMQTTのpublish**
5.　**M5StackがMQTTをsubscribeしてディスプレイの表示を変更**

### 本題：Alohomora

今回は、以上の二つの作品を組み合わせて「Alohomora」を再現しました
本題のシステム構成はこちらです!
![スクリーンショット 2018-12-14 18.51.46.png](https://qiita-image-store.s3.amazonaws.com/0/192773/a5bc679c-f3a4-f01c-bb82-f93fff913197.png)


1. **杖につけた6軸センサから値を取得**
2. **Jubatusで機械学習させ動作を推定**
3. **APIで動作と紐づけたイベントを発火**
4. **（3で得られたイベントが鍵の開閉であれば）**
5. **FlaskのAPIを叩く**
6. **GPIOでサーボモータの制御**

（MQTTの部分は省略しています）

## 中身
システムの少し詳しい中身を説明していきます
1. **動作の認識**
2. **動作からイベントの取得**
3. **サーボモータの制御**

### 動作の認識
今回は、6軸センサ（9軸センサの地磁気センサの3軸を用いいていません）を用いて杖の動きを認識してイベントと紐づけます

動作の認識の流れは以下のようになっています

1. **ボタンを押しながら杖を振る**
2. **振り終わったらボタンを離す**
3. **ボタンが押されている間のセンサの値から学習させたモデルを用いて動作を認識する**

今回定義した動作は

- 上から下
- 下から上
- 左から右
- 右から左
- 時計回り
- 反時計回り

の６つです

### 動作からイベントの取得
上記の流れで動作が認識されれば、認識された動作をデータとしてAPIを叩きます
APIでは以下の処理を行います

1. Jubatusで認識された動作（例：時計回り）がデータとして送られてくる
2. DBから特定の動作と紐づけられたイベントを取得する（今回は鍵を開ける[閉める]）
3. イベントごとのアクションを実行する（今回はFlaskで立てたAPIを叩く）

### サーボモータの制御
認識された動作から鍵を開ける[閉める]イベントが発火されたらFlaskのAPIが叩かれます
APIが叩かれればGPIOを使用してサーボモータを動かし、鍵の開閉を行います

例えば鍵を開けるAPIのコードは以下です

```key.py
@app.route("/open")
def close():

    GPIO.setmode(GPIO.BCM)

    # GPIO4を制御パルスの出力に設定
    gp_out = 4
    GPIO.setup(gp_out, GPIO.OUT)

    #「GPIO4出力」でPWMインスタンスを作成する。
    #GPIO.PWM( [ピン番号] , [周波数Hz] )
    #SG92RはPWMサイクル:20ms(=50Hz), 制御パルス:0.5ms〜2.4ms, (=2.5%〜12%)。
    servo = GPIO.PWM(gp_out, 50)
    servo.start(0)
    
    #デューティサイクルの値を変更することでサーボが回って角度が変わる。
    servo.ChangeDutyCycle(7.5)
    time.sleep(0.5)


    servo.stop()
    GPIO.cleanup()

    return "ok"
```

スマートロックの作成に関する内容は

- [スマートロックを自作してみた](https://qiita.com/mr_04v/items/156bbdf51ff8f93905bd)

に書いているのでそちらを参照してみてください

# 完成
こんな流れで作成していくと
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">手作りAlohomora(for advent calendar) <a href="https://t.co/6C1pKRvXFz">pic.twitter.com/6C1pKRvXFz</a></p>&mdash; もーりー🌓 (@m___04v) <a href="https://twitter.com/m___04v/status/1073504922010759168?ref_src=twsrc%5Etfw">2018年12月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
「Alohomora」を再現できます


#おわり
最後まで読んでいただきありがとうございました
もっと詳しい中身について知りたいよ！って方がいらっしゃいましたら気軽にコメントしてください！
# 参考記事

- [Raspberry Piでサーボモーターを回す](https://qiita.com/undo0530/items/51cc446eefec6c91c26d)
- [スマートロックを自作してみた](https://qiita.com/mr_04v/items/156bbdf51ff8f93905bd)
- [【Python】FlaskでAPIをさくっとつくる](https://qiita.com/xecus/items/b437513cbb9f0e1aa87a)