ABEJA Tech Blog

中の人の興味のある情報を発信していきます

ChatGPTを使って音声指示でロボットを動かしてみた(GPTsのActions、MQTT、ATOM Matrix、toio、UIFlow)

TL; DR

GPTsに音声入力で指示すると、それに従ってATOM Matrix経由でtoioが動いてくれるようなものを作ってみました。 GPTsのActionsから何秒動きたいかを判断して、BeebotteというMQTTブローカーを使ってATOM Matrix経由でtoioにその秒数を指示します。 ChatGPTなので、「ちょっと進んで」というような曖昧な指示でも1秒を設定して指示してくれます。 (スタックチャンは賑やかしのために参加してもらっただけで今回の内容とは関係ないです。そのうちAIスタックチャンのfunction callingで指示できるように改良予定) 動画↓


www.youtube.com

はじめに

こんにちは。株式会社ABEJA でプロジェクトマネージャーをメインにやっていて、データサイエンティストも兼務している道辻です。本記事はABEJAアドベントカレンダー2023の16日目の記事です!

2023年は生成AI、ChatGPTが盛り上がりました。ABEJAでもLLMに関する案件が増えており、LLMに関する講師も色々なところでやらせてもらいました。これからもしっかり技術をキャッチアップしていく必要があると思っていて、これまで持っていたG検定、E資格に加えて、JDLA Generative AI Test 2023にも合格しました。

2023/11/7のOpenAI DevDayで発表された内容は衝撃で、GPTs、GPT Builderで簡単に作れてしまう体験は特に面白いと思いました。

PM兼DSである私ですが元々機械設計をしていたのもあってIoT、M5Stack好きなので趣味で色々やっています。今回は下記の事がやってみたくなって、全部やってみた記事になります。

  • 音声指示でロボット動かしたい
  • GPTsやAssistants APIのActions使ってみたい
  • ビジュアルプログラミングって使ったことないから使ってみたい、生成AIでコード作ってくれる今どんな発展がありそうなのか触って感じよう

やり方忘れるタイプなので手順をメモりました。あまり情報がないところなので誰かの役に立てば幸いです。

目次

今回やったことの全体像

PCから音声入力でGPTsに何秒動きたいかを指示して、Actionsで判断してBeebotteというMQTTブローカーを使ってATOM Matrix経由でtoioにその秒数を指示します。MQTTを使う利点としては、同時に他のIoTにも信号を送れるので何か同期した動きとかができるから面白そうだなと思ってます。(点線のところ) ChatGPTなので、「ちょっと進んで」というような曖昧な指示でも1秒を設定して指示してくれます。

全体概要

  • GPTsじゃなくてChatGPTのAPI使ってfunction callingを使っても良かったんですが、GPTsのActions使ってみたかったからこうしてます。
  • インプットもWhisperなどで音声からテキストに処理するようにもできたんですが、GPTsのActions使ってみたかったからこうしてます。GPTsのせいでマウスをポチポチしないといけないところがあるため、音声指示と言っていいかはアレだが、音声で指示していることは間違いない。GPTsのActions使ってみたかったんです。
  • 最初はスタックチャンを動かそうかなと思っていましたが、ビジュアルプログラミングでUIFlowを使ってみたからこうしてます。

GPTsによってできるようになった事を整理

GPTs、GPT Builderでできるようになったことを従来のChatGPT、Assistants APIと比較して表に整理してみました。

従来のChatGPT、GPTs、Assistants APIの比較、機能名

GPTsで何か作るなら、せっかくなのでRAGやActionsを使ってみたいですねと思うところです。

RAGはアップロードしたファイルの知識を使って会話ができるようなもの、ActionsはAPIで使えていたfunction callingと同じようなもので指定した条件に該当するかをLLMが判断して組み込んだ機能やAPIを使用する事ができて、そこから返ってきたものを使って文章を生成できます。

https://platform.openai.com/docs/actions

今回はこのActionsを使ってMQTTのAPIを呼び出してみます。

MQTTブローカーであるbeebotteの設定

MQTT、beebotteとは

簡単に言うと、beebotteはさまざまなデバイスからデータを集めたり、それを他のデバイスへ送ったりするための便利なツールであり、その中でMQTTは、データの送受信を効率的に行うための技術です。

beebotteは、インターネット上でデータを送受信するためのサービスです。このサービスを使うと、様々なデバイスやアプリケーションからデータを集めたり、そのデータをインターネットを通じて他のデバイスやアプリケーションに送ることができます。例えば、家の温度を測定するセンサーからデータを集め、それをスマートフォンのアプリで見ることができるようにすることが可能です。

beebotteは「MQTT」という技術を使っています。MQTTは、少ないデータで効率的に情報を送受信することができる通信方法です。特に、インターネットの接続が不安定な場所や、電力をあまり使えないデバイスに適しています。例えば、遠く離れた場所にある農場の温度センサーが、少ない電力でデータを送信するのにMQTTが使われることがあります。 MQTTは「ブローカー」「パブリッシュ」「サブスクライブ」という3つの主要な概念を持っています。

ブローカー(Broker): ブローカーはMQTTの中心となるサーバーです。メッセージの受け取り、処理、そして適切なクライアントへのメッセージ配信を行います。クライアントがメッセージを送信するとき、まずこのブローカーに送ります。そして、ブローカーはそのメッセージをサブスクライブしている他のクライアントに転送します。ブローカーは、メッセージの中継点として機能し、通信を管理します。今回はbeebotteを使います。

パブリッシュ(Publish): パブリッシュは、メッセージを送信する行為です。あるクライアントが何らかの情報を共有したい場合、その情報をメッセージとしてMQTTブローカーに「パブリッシュ」します。このメッセージは特定のトピックに関連付けられています。トピックはメッセージを分類するためのラベルのようなもので、サブスクライブする際に使用されます。

サブスクライブ(Subscribe): サブスクライブは、特定のトピックのメッセージを受け取ることをブローカーに伝える行為です。クライアントは、興味のあるトピックをサブスクライブします。その後、そのトピックに関するメッセージがブローカーにパブリッシュされると、ブローカーはそのメッセージをサブスクライブしたクライアントに自動的に転送します。

要約すると、MQTTでは「ブローカー」が中心的な役割を果たし、「パブリッシュ」を通じてメッセージが送信され、「サブスクライブ」を通じてメッセージが受信されます。これにより、多数のデバイス間で効率的かつ確実に情報をやり取りすることができるのです。

↑だいたいChatGPTさんにURL渡して書いてもらいましたけど、間違ってないと思います。

beebotte.com

beebotteは無料プランでも1日に50000メッセージ送れるので個人で使うにはとても使えるものです

beebotte Plans

新しいチャンネルの作成

まずは、アカウントを作るとChannelsというところで、新しいチャンネルを作れるのでCreate Newを押します。

beebotte ダッシュボード

Channel NameとResource Nameに適当に好きな名前を設定します。あとはいったんそのままでいいので、Create channelを押すだけで準備完了!簡単ですね

beebotteチャンネル作成

ChannelsのダッシュボードでそれぞれのChannel名を選択するとChannel Tokenが確認できます。こちらはあとで使用するのでメモっておいてください

Channel Token

Account Settingsのところで、Access Managementというタブを見るとSecret Keyもありますので、こちらもメモっておいてください

Secret Key

動作を確認するためには、Consoleを使います。ここに先ほどのSecret KeyとChannel、Resourceを入力します。Subscribeを押して適当な文字を入れてPublishして動作を確認できます。これは、このあとのGPTsやATOMとの連携の時にも確認するために使用します。

Console

GPTsのActionsの設定

ActionsはGPT Builderから一番下の方にあるActionsを押すと設定できるのですが、Exampleのものを見てもなんだか難しそうですね。今回はActionsだけ動けばいいので、NameとConversation starters以外は何も入力せずで問題ないです。

GPT Builder

GPTsのActionsにどのように設定するかは、下記のようにChatGPTにスキーマのテンプレとAPIの参照ページとやりたいことを書けば作ってくれます。いくらか自分で修正は必要ではありましたが。

{
  "openapi": "3.1.0",
  "info": {
    "title": "Untitled",
    "description": "Your OpenAPI specification",
    "version": "v1.0.0"
  },
  "servers": [
    {
      "url": ""
    }
  ],
  "paths": {},
  "components": {
    "schemas": {}
  }
}

上記のスキーマに従って、下記のAPIを使って指示した数量を送るようにしてください
https://beebotte.com/docs/clientapi#publish

これによって出てきたのが、下記の内容です。ここの{channel}、{resource}をそれぞれbeebotteで設定したChannel名とResource名にします。descriptionに従って動作するのでやりたいことに修正します。全部が必要なのか、responsesのところも全部動作するか確認はしてないですが、基本的な動きはいけたので気になる人は確認して修正してみてください。

openapi: 3.1.0
info:
  title: Beebotte API
  description: OpenAPI specification for publishing data to Beebotte channels.
  version: v1.0.0
servers:
  - url: 'https://api.beebotte.com/v1'
paths:
  /data/publish/{channel}/{resource}:
    post:
      summary: Publish a message to a Beebotte channel
      operationId: publishNumericalValue
      tags:
        - publish
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NumericalData'
      responses:
        '200':
          description: Numerical value published successfully
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
components:
  schemas:
    NumericalData:
      type: object
      required:
        - data
      properties:
        data:
          type: integer
          description: Numerical value to be published
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-Auth-Token

これをActionsのSchemaに貼り付けます。

Actions設定

API Keyを押して図のような設定にして、API KeyにbeebotteのChannel Tokenを入力します。

API Keyの設定

これで、「10秒動いて」と指示してなんか出てくるものに許可ってやって、無事にAPIが送信できれば成功です。先ほどのbeebotteのconsoleでPublishされているかを確認します。GPTs側の準備は完了

GPTsへの指示

UIFlowを使ってビジュアルプログラミング

使用したもの

今回動かすのはこちら、toioとATOM MatrixをATOM Mate for toioを使って組み合わせます。充電器も必要です。工具も何もいらないので簡単です。

toio™コア キューブwww.switch-science.com

ATOM Matrixwww.switch-science.com

ATOM Mate for toio™www.switch-science.com

toio™コア キューブ専用充電器www.switch-science.com

M5Burnerの設定

UIFlowを使うためにM5Burnerが必要です。

OSに合わせてM5Burnerをダウンロードしてインストールします。USBドライバもM5Stack系を使ったことなければ必要です。USBでATOM Matrixと接続しておきます。USB-Cケーブルは充電しかできなくて書き込めないものもあるので注意!

docs.m5stack.com

M5Burnerを起動したら、マイコンの一覧から自分が使うマイコンを選択してDownloadをします。なんかキレイで良いです。ログインできますが使う分には特にログインの必要ありません。

M5Burnerダウンロード

私のUIFlow_MatrixはすでにBurnボタンになっていますが、Downloadが完了するとこのような画面になります。 Burnボタンを押すとWi-Fiのアクセスポイントの情報を入力できますが、2.4GHzにしか対応していないので注意! ポートを選択してそのまま書き込めば準備完了

なんですが、Configureボタンがすごく重要なのでここで説明をしておきます。まずはAPIKEYを後で使うのでメモっておきます。

このなかのStart Modeというところが選べるのですが、MQTT通信をするためにはUIFlowからのRunでなくダウンロードが必要になります。一旦ダウンロードするとここがApp modeになります。App modeになるとUIFlowを受け付けてくれなくなるので、再度プログラムを変えて書き込むときは、ここでInternet modeに切り替えてから再度UIFlowで接続する必要があります。ここがわからなくてだいぶハマりました。

M5Burner Config

UIFlowでビジュアルプログラミングする

次にUIFlowに接続します。 flow.m5stack.com

まずは左下のAPI Keyの部分か右上の設定からAPI Keyを設定します。M5BurnerでメモったAPIKEYをここに入力します。 左下の矢印が回転してるマークをクリックすると接続済みになると思います。ここが接続の確認です。ここでエラーが出た場合はうまくつながっていない、もしくは先ほどのApp Modeになっている可能性があるのでM5BurnerでInternet modeに変えます。

UIFlow

あとは、頑張ってUIFlowでブロックを組み立てます。MQTTのところですが、ユーザー名とパスワードは同じでbeebotteのChannel Tokenを入力します。MQTTブローカーの名前とかはなんでも良さそうです。is_connectというのは関数を設定するとでてきて、一番右のブロックで表現されてるものです。toioにつながらないとピカピカします。中央のブロックがSubscribeしたときの挙動です。データがJSONで来るので、そこから数字を取り出してその秒数待機するようにしています。M5GPTがチャンネル名、moveがリソース名です。

UIFlow program

右下のダウンロードボタンを押せば完成です。beebotteのconsoleからpublishしてみて、動くかを確認してください。

こういうときはいっきにやると原因がどこにあるかわからないので、まずはtoioがサンプルコードで動くかを確認して、そのあとMQTTの部分を確認、その後に全部合体させるのがいいと思います。このときにGPTsからの指示でいきなりやるのではなくbeebotteのconsoleからやるようにして、段階を踏んで一つ一つ実装を試す方がいいと思います。

pythonのコードはこんな感じです。

from m5stack import *
from m5ui import *
from uiflow import *
from ThirdParty.toio import toio
import time
import json

from m5mqtt import M5mqtt

rgb.set_screen([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])

Json = None
num = None

# この関数の説明…
def is_connect():
  global Json, num
  rgb.set_screen([0,0,0,0,0xdf2626,0,0,0,0xdf2626,0,0,0,0xdf2626,0,0,0,0xdf2626,0,0,0,0xdf2626,0,0,0,0])
  wait_ms(200)
  rgb.set_screen([0xdf2626,0,0,0,0,0,0xdf2626,0,0,0,0,0,0xdf2626,0,0,0,0,0,0xdf2626,0,0,0,0,0,0xdf2626])
  wait_ms(200)

def fun_M5GPT_move_(topic_data):
  global Json, num
  rgb.set_screen([0xffffff,0,0xffffff,0,0xffffff,0,0xffffff,0,0xffffff,0,0xffffff,0,0xffffff,0,0xffffff,0,0xffffff,0,0xffffff,0,0xffffff,0,0xffffff,0,0xffffff])
  Json = json.loads(topic_data)
  num = Json['data']
  rgb.set_screen([0,0,0x31f271,0,0,0,0x31f271,0x31f271,0x31f271,0,0x31f271,0,0x31f271,0,0x31f271,0,0,0x31f271,0,0,0,0,0x31f271,0,0])
  toio_ble.write_motor_speed(20, 20)
  wait(num)
  toio_ble.write_motor_stop()
  rgb.set_screen([0,0,0x2947a3,0,0,0,0x2947a3,0,0x2947a3,0,0x2947a3,0,0,0,0x2947a3,0,0x2947a3,0,0x2947a3,0,0,0,0x2947a3,0,0])
  pass

rgb.set_screen([0,0,0xffffff,0,0,0,0xffffff,0,0xffffff,0,0xffffff,0,0,0,0xffffff,0,0xffffff,0,0xffffff,0,0,0,0xffffff,0,0])
toio_ble = toio()
toio_ble.scan_connect()
while not (toio_ble.is_connected()):
  is_connect()
m5mqtt = M5mqtt('Atom01', 'mqtt.beebotte.com', 1883, 'token_xxx', 'token_xxx', 300)
m5mqtt.subscribe(str('M5GPT/move'), fun_M5GPT_move_)
m5mqtt.start()
rgb.set_screen([0,0,0xdf2626,0,0,0,0xdf2626,0,0xdf2626,0,0xdf2626,0,0,0,0xdf2626,0,0xdf2626,0,0xdf2626,0,0,0,0xdf2626,0,0])

最後に

感想と今後やりたいこと

ビジュアルプログラミングに関しては情報が少ないのでかなり苦戦しましたがとりあえず触れて満足です。目でブロックを探すのが大変でしたがLEDの設定は見やすくて良かったです。MQTTの設定は情報少なすぎて英語のドキュメントをChatGPTさんに助けてもらいながら読んでで大変でした。生成AIがある今、もしかしたらビジュアルプログラミングよりもコード作ってしまった方が初心者にとっても楽なのかもしれません。逆にコードからビジュアルで確認できるように変換できると視認性が上がって、他の人にも見やすいというところは利点になるかもしれません。

GPTsでできることも大体わかったので満足です。ノーコードでできると良かったのですが、GPTsのActionsの設定はノーコードとは言い難いものでした。

音声指示で無事に動いていったん満足ですが、やりたいことはたくさんあります。

  • Assistants APIでもやってみたい
  • 指示できる動きを増やしたい、せっかくToFとかもついてるので
  • ChatGPTのAPIでfunction calling使ってparallelに実行させたい
  • 他のIoTも連動させてなんか面白いことないか考えたい
  • AIスタックチャンをfunction calling使って動かしたい
  • もっとAgent的に複雑な処理をさせたい
  • 今回のGPTsは作成者のAPI Keyを使うので、誰かに使えるようなものではないので、それぞれのAPI Keyを設定できないか考えたい。
  • 大田黒さんのロボットを音声指示で動かしたい tech-blog.abeja.asia

We Are Hiring!

We Are Hiring! ABEJAは、テクノロジーの社会実装に取り組んでいます。 技術はもちろん、技術をどのようにして社会やビジネスに組み込んでいくかを考えるのが好きな方は、下記採用ページからエントリーください! (新卒の方のエントリーもお待ちしております)

careers.abejainc.com