Google Nest + IFTTT + Beebotteでロボット(ESP32)を起動する
qiita.com 本記事はIPFactory Advent Calendar 2023 の18日目の記事として投稿しています。
はじめに
情報系の専門学校生です。学校の授業で、ESP32と複数のサーボモータを使用した高さ20cmほどの二足歩行ロボットを制作しました。スマートスピーカ(Google Nest Mini)で起動できるようにした力作です。
外部講師の方にこのロボットを気に入っていただけまして、2023年11月29日から12月2日まで東京ビッグサイトで開催された、2023国際ロボット展のブースの一角に展示してもらっていました。
今回はそのロボットの大まかな仕様について記します。
目次
写真
ジャンパ線がむき出しになっており、作りが粗いですが……。
ロボットの詳細
先述のとおり、高さ20cmほどの二足歩行ロボットです。ロボットの動作は7個のサーボモータ、PCA9685(サーボモータドライバ)、ESP32によって実現させています。
サーボモータドライバには電池ボックスを接続し、ESP32の電源供給はモバイルバッテリとUSB type-Bのケーブルで行なっています。
ロボット自体のプログラムはArduino IDEで開発し、ESP32に書き込みしています。言語は、C/C++を元にしたArduino言語です。
ロボットの各種パーツは、外部講師の方が用意してくださった3Dプリンタ製のものを利用しています。腕と大きな足はスチレンボードを切り取っています。
その他にもLED・7セグ・圧電スピーカを搭載することでロボットっぽく演出できるようにこだわりました。起動時と停止時には、ランダムな周波数で圧電スピーカが「ピロピロ」と鳴り、同時に、赤と青の単色LEDも素早く点滅します。
さらに、頭部に貼り付けた距離センサで壁までの距離を測って自動的に方向転換するようにしていますが、前にも左右にも進むことができないと分かったら、後退した後に方向転換するようにプログラミングしてあります。
スマートスピーカの利用
特にこだわった点として、ロボットにIoT的な要素を取り入れたら面白いと思い、スマートスピーカ(Google Nest Mini)に話し掛けて起動・停止できるようにしました。インターネットを介して音声による遠隔起動ができるということです。
さらに、動作中は1歩歩く度に7セグの表示がカウントアップされていくようにしているんですが、ロボット停止時、歩いた数に応じてGoogle Nest Miniが「前回の歩数」と「今回の歩数」、「前回と比較した今回の評価」を喋ってくれます!
喋らせる機能は、ロボット用のマイコン(ESP32)とは別にRaspberry Piを用意して実現しています。Raspberry Pi上でNode.js(JavaScript)のプログラムを書いています。
歩いてくれるロボットも、評価を述べてくれるスマートスピーカも、健気で可愛い気がします。
Google Nest Miniからロボットの起動・停止をする
まずは、Google Nest Miniからロボットの起動・停止をどのようにコントロールしているか説明します。
ロボット(ESP32)内のフラグで起動状態と停止状態を管理しているのですが、IFTTT連携を利用することでスマートスピーカからESP32内のフラグを操作しています。
より詳しく言うと、以下の通りです。
IFTTT連携のアプレット作成時、「Google Assistant(v2)」をトリガー(IF)に選択することができます。Google Assistantに特定のワードを話しかけたらwebhookを送る(POSTリクエストを送る)というアプレットを作成します。
BeebotteはクラウドのMQTT brokerです。Beebotteには特定のエンドポイントにHTTP POSTメソッドでリクエストを送るとMQTTのpublishとして扱ってくれる(変換してくれる?)APIがあり、今回はそれを利用しています。Beebotteではあらかじめチャンネルを作成しておきます。
BeebotteのAPIのエンドポイントを、IFTTTのwebhookの送信先URLに設定してやります。
ロボット(ESP32)はMQTT subscriberとして、Beebotte(MQTT broker)に接続します。あとは、MQTTのsub通信を受け取った時にフラグの0と1を反転させるプログラムをESP32に書いておけば良いです。
IFTTTでのGoogle Assistantとの連携について、2022年8月頃までは簡単な数字やテキストを認識してくれて、それらをパラメータとして送ることができていたようです。 kbnt.xyz
しかし現在は、IFTTTでGoogle Assistantとwebhookの連携を行う際、ほとんど固定の内容しか送信できません。だから、ESP32側では「リクエストが送られてきた時に、フラグの0と1を入れ替える」という実装になっています。こうすることで、起動用と停止用にわざわざ2つのアプレットを作らなくて済むからです。
もし仕様が以前のままであれば、「起動」とか「停止」みたいなワードをリクエストに含めて送ることができていただろうし、データを受け取る側も文字列の内容に応じて処理を分岐できたと思うので、今より格段に自由度が高かったと思います。自分はその時代を知らないので、とても残念です。
ロボット停止後Google Nest Miniを喋らせる
次に、ロボットを止めたあと、どのようにGoogle Nest Miniに「前回の歩数」「今回の歩数」「前回と比較した今回の評価」を喋らせているか説明します。
ロボット停止後、ESP32はRaspberry Piに「今回の歩数」を送ってやる必要がありますが、ここでもBeebotteを使用しています。Rapberry PiにNode.jsの環境を入れ、JavaScriptでMQTTのトピックを購読(subscribe)するプログラムを準備しておいて、あらかじめ実行しておきます。
ロボットの前回の歩数と今回の歩数から「前回と比較した今回の評価」について述べた良い具合の文章を得たいですが、これはChatGPTのAPIを使用しました。適切なプロンプトと歩数を投げてやると、それっぽい文字列がちゃんと返ってくるので面白いです。例えば、前回が20歩で今回が10歩なら「改善しましょう」のような文が返ってきますし、今回の歩数が0歩なら「歩行に問題があるようです」という言葉になったりします。
評価の文章を生成するにあたり、今回の歩数だけでなく前回の歩数も必要です。つまり、前回の歩数をどこかに記憶しておく必要があるということです。ここではデータベースを使わずに、Googleスプレッドシートを簡易的なデータベース代わりに使用しています。
ChatGPTから返却された「今回の評価」の文字列は、google-home-playerというライブラリを用いてGoogle Nest Miniに喋らせます。
ロボット停止後の流れをまとめると、
- ESP32がBeebotteを経由して、Raspberry Piに「今回の歩数」を送る
- Raspberry Pi上のプログラムでGoogleスプレッドシートの値を取得し、「前回の歩数」と「前回の評価」を得る
- ChatGPTのAPIに「プロンプト」「前回の歩数」「今回の歩数」「前回の評価」を送り、「今回の評価」を生成してもらう
- google-home-playerを用いてGoogle Nest Miniに「前回の歩数」「今回の歩数」「今回の評価」を喋らせる
- 次回起動時のため、Googleスプレッドシートに今回の歩数と評価を記録する
となります。
動画
百聞は一見にしかずと言いますし、言葉でアレコレ説明されるよりも実際に動くのを見てもらうのが最も良いのですが、今回動画が用意できませんでした……!
撮影してアップロード後、記事を更新しようと思っています。
おわりに
まだまだひよっこですので、記事内に知識不足や思い違いによる記述間違いがあればお知らせください。
特に用語の使用が間違っているところ等あれば、正確な用語・捉え方をご教示いただけますとありがたいです。
IPFactory Advent Calendar 2023 17日目は彼です!