TouchDesignerからPepperをMQTTで操作する

こんにちは。Marvoと申します。
こちらは「[Advent Calendar 2018](http://qiita.com/)」12月16日の記事となります。

つい先日[TouchDesigner Study Weekend](https://tdsw.co/)の初心者コースを受講してからTouchDesignerにドハマりしてしまい、これをロボットと繋げて何かやりたい！！！と思い、今回は最初の一歩としてPepperと繋げてみました。

#TouchDesignerについて
こちらでの詳細な説明は割愛いたします！ソフトウェアはユーザー登録すれば無料ライセンスで利用できます（有料のプロ版ライセンスもあります）。
最近は[Study Weekend](https://tdsw.co/)のようなハンズオンイベントの機会も増えているようですので、ご興味ある方は是非参加してみてください！

#今回やってみたこと
シンプルにTouchDesignerから適当な値をPublishし、Pepper側でSubscribeして受け取ってみました。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">シンプルにTouchDesignerとPepperをMQTTで連携させてみた <a href="https://t.co/3ZmvK8fq6C">pic.twitter.com/3ZmvK8fq6C</a></p>&mdash; MARVO@anima (@marvo737) <a href="https://twitter.com/marvo737/status/1074286754406981632?ref_src=twsrc%5Etfw">2018年12月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#TouchDesigner側の準備
TouchDesignerからのMQTTでのpublishには[MQTT Client DAT](https://docs.derivative.ca/index.php?title=MQTT_Client_DAT)と[CHOP Execute DAT](https://www.derivative.ca/wiki088/index.php?title=CHOP_Execute_DAT)というオペレーター(関数のようなもの)を用います。
以下が今回作成したフローの全体図になります。
<img width="761" alt="2.png" src="https://qiita-image-store.s3.amazonaws.com/0/90062/32225e63-113a-e5c8-e3bb-5b491951ded9.png">
なお、Button CMOPとNull CHOPの使い方については割愛いたします。
詳しくは[こちらの方](https://www.shuhei-matsuyama.com/single-post/2016/01/04/TouchDesigner-%E4%B8%8A%E3%81%A7%E3%80%81UI%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B)の記事をご参照ください。

###MQTT Client DAT
TouchDesignerでMQTTを扱う際に一番重要なオペレーターがMQTT Client DATです。
パラメータ欄の"Network Address"にMQTTブローカーのIPアドレスとポート番号を設定してください。
※MQTTブローカーは別途適当なところに立ててください。
<img width="761" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/90062/9a9c3dae-2eeb-cc10-0da3-95c7192f4208.png">
なお、TouchDesigner側でsubscribeする場合は、このオペレーターについてくるmqttclient1_callbacksというオペレーターに細かい挙動をpythonで設定します(画像には載せておりません)。
こちらについてご興味ある方は[こちらの方](https://qiita.com/kitazaki/items/c298f6be83cb7bc0cc49)の記事が参考になります。
###CHOP Execute DAT
<img width="862" alt="4.png" src="https://qiita-image-store.s3.amazonaws.com/0/90062/c1d759d5-dc4f-d134-4a4d-9555d82b3047.png">
CHOP Execute DATの使い方は[こちらの方](http://txton.net/hoehoe/20170609041851)の記事が参考になりました。
パラメータ欄の”CHOP”に値の変化が見たいCHOP（緑色の）オペレーターの名前を入力します。
今回の例だと、null2オペレーターの値が変わったら（UI上のボタンが押されたら）chopexec1のpythonが実行されます。

```python:chopexec1
# me - this DAT
#
# channel - the Channel object which has changed
# sampleIndex - the index of the changed sample
# val - the numeric value of the changed sample
# prev - the previous sample value
#
# Make sure the corresponding toggle is enabled in the CHOP Execute DAT.

a = op('/project1/mqttclient1')

# subscribe to the temp/random topic
#a.subscribe('/pishield/chan6',qos=0)

def onOffToOn(channel, sampleIndex, val, prev):
	a.publish('sub/td/kick',b'23')
	return

def whileOn(channel, sampleIndex, val, prev):
	return

def onOnToOff(channel, sampleIndex, val, prev):
	return

def whileOff(channel, sampleIndex, val, prev):
	return

def onValueChange(channel, sampleIndex, val, prev):
	return
```
nullオペレーターの値が0→1になった時に、トピック"sub/td/kick"に対して適当な値をpublishしています。

#Pepper側の準備
Pepper側でMQTTを用いるにあたり、[こちらの方](https://qiita.com/yacchin1205/items/4b2aab2f6d9ee3b03746)のMQTT  Adapterボックスをお借りいたしました。
"Host"にMQTTブローカーのIPアドレス、"Key-Topic Bindings"には MQTT/sub/#:sub/#:json を設定しています。
<img width="496" alt="5.png" src="https://qiita-image-store.s3.amazonaws.com/0/90062/ed5730bc-983a-5a3b-db9b-d31adf253c64.png">
ALMemoryから"MQTT/トピック名"を追加し、そのさきにSayボックスを繋げています。

これで各クライアントがMQTTブローカーに繋がっていれば、TouchDesigner上のボタンを押すとPepperが喋るはずです。

#まとめ
以上、TouchDesignerとPepperをMQTTで簡単に繋いでみました。
今回はPepperでやってみましたが、もちろん他のデバイスとも繋げて色々できそうです。

今後も色々繋げてみて、面白いもの作れたらと思います！(そしてIoTLTでLT(￣^￣)ゞ笑）

P.S.[書籍](https://www.amazon.co.jp/dp/B075L6DRBW/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)買うくらいどハマりしているのですが、付録を改造して曲のキックに合わせてうなずくPepperも作ってみました。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">音楽のキック拾ってPepperをうなずかせてみました<a href="https://twitter.com/hashtag/TouchDesigner?src=hash&amp;ref_src=twsrc%5Etfw">#TouchDesigner</a> <a href="https://t.co/gX8QRPCiVR">pic.twitter.com/gX8QRPCiVR</a></p>&mdash; MARVO@anima (@marvo737) <a href="https://twitter.com/marvo737/status/1074239652700143617?ref_src=twsrc%5Etfw">2018年12月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>