🤖

カチャカをボタンで操作できる"カチャカボタンハブ"をOSSとして公開しました

2024/05/08に公開

こんにちは、株式会社Preferred Roboticsの日台です。カチャカのソフトウェアを開発しています。
今回、カチャカボタンハブというプロダクトを出したので、それについて紹介をします。

概要

カチャカボタンハブは、カチャカの操作を「押しボタン」から行えるように、ボタンとカチャカの間を取り持つハブの役割をするデバイスです。

Overview

カチャカ

カチャカは皆さんご存知、家具を運んでくれるロボットです。日本を代表するAI企業の Preferred Networks からカーブアウトした Preferred Robitics がハードからソフトまで内製して、2023年に発売しました。グッドデザイン賞や家電大賞(プレスリリース)など多数の賞を受賞しています。展示会などで動いているロボットを見せると「中国製ですか?」と聞かれることもあるのですが、Designed in Tokyo, Japan です。

カチャカ

カチャカは「カチャカAPI」を提供していて、ローカルネットワーク上からgRPCでカチャカに指令を出したり、カチャカの状態やセンサー値を取得することが可能になっています。カチャカボタンハブからは、このgRPC APIを使って指令を出します。

カチャカAPIについては、以下の記事が参考になります。

https://qiita.com/ksyundo/items/f10f9a6c704442bb3a10

ボタン

カチャカボタンは、省電力で無線通信ができる押しボタンです。Braveridge のボタンビーコン BTN01をそのまま使います。
ボタンを押すと、ビーコンが飛びます。電池交換はできないですが、超省電力なので4〜5年は使える計算になります。

Braveridgeボタン

ハブ

カチャカボタンハブは、ビーコンをカチャカのコマンドに変換して、カチャカAPIを通してカチャカに指令を出す小さなデバイスです。ハードウェアはM5Stack Basic v2.7を利用し、そこでカチャカボタンハブのソフトウェアを動かします。ハブはWi-Fiでカチャカと通信します。

M5Stack

ボタンから来たビーコンをボタンハブが受信すると、それを内部で持っているDB(command table)と照合してカチャカコマンドに変換し、gRPCでカチャカAPIを叩きます。
コマンドの具体例としては、以下のようなものになります。

  • 家具Aを目的地Xに運ぶ
  • 家具Bをホームに片付け、その後、「◯◯」と喋る

コマンドの関連図

DB(command table)は、スマートフォンなどのWebブラウザを利用した設定UIを使って編集します。設定画面のコンテンツは全てカチャカボタンハブがサーブしているので、インターネット上のサーバは必要ありません。

設定の関連図

カチャカ本体のセットアップが済んでいて、ゴミ箱やお菓子が入ったシェルフをカチャカが運べる状態になっているとします。ここで、自分の机やソファーなど、好きな場所にボタンを配置しておけば、それを押すだけで誰でも一撃でカチャカを(ゴミ箱等を)呼び出すことができるようになります。

https://www.youtube.com/watch?v=JchqRCBZPdE

もともとカチャカは、音声コマンド(ねぇカチャカ、◯◯して)とスマートフォンアプリから指令を出せますが、ボタンの利用により、更に使い勝手が向上します。

カチャカボタンが使えるようになるまで

カチャカボタンハブは今のところ一般向けに販売は行っていません。しかし、ソフトウェアがオープンソースとなっているので、必要なハードウェアを購入すればどなたでも利用することが可能です(インストールには多少のエンジニアリング力が必要ではあります)。ここでは、実際にインストールして動くところまでやってみようと思います。

ハードウェアの調達

以下の4つを用意します。

カチャカは、すでにセットアップが終わっているとします。なお、セットアップは以下の動画を参照してください。

https://www.youtube.com/watch?v=5ZyMC8_nszc

ボタンビーコンは、買ってきたものをそのまま使います。何の設定も必要ありません。

カチャカボタンハブのインストール

M5Stack にソフトウェアをインストールしてみましょう。

インストール方法は以下の GitHub ページに記載されていますが、

https://github.com/pf-robotics/kachaka-button-hub

ここでは、Dockerを使った簡単なビルド方法を使います。
まず、お使いのPCに、Docker CE をインストールしましょう。

https://docs.docker.com/engine/install/

次に GitHub からソースコードを git clone します。

git clone https://github.com/pf-robotics/kachaka-button-hub.git

後は、以下の手順でビルドできて、成果物は _build ディレクトリ以下に展開されます。

cd kachaka-button-hub
git submodule update --init
./tools/build-by-docker.sh

私の環境では、以下の通りファイルが生成されました。

% ls -la _build 
total 57928
drwxr-xr-x 1 hidai hidai      224 May  2 09:50 ./
drwxr-xr-x 1 hidai hidai      230 May  2 09:50 ../
-rw-r--r-- 1 hidai hidai  3537744 May  2 09:50 button_hub.ino.bin
-rw-r--r-- 1 hidai hidai    18992 May  2 09:50 button_hub.ino.bootloader.bin
-rwxr-xr-x 1 hidai hidai 36449600 May  2 09:50 button_hub.ino.elf*
-rw-r--r-- 1 hidai hidai 19303913 May  2 09:50 button_hub.ino.map
-rw-r--r-- 1 hidai hidai     3072 May  2 09:50 button_hub.ino.partitions.bin

これを M5Stack に書き込むには以下のコマンドが利用可能です。USBケーブルで M5Stack と PC を接続してから実行してください。デバイスファイル /dev/ttyACM0 は環境によって変更する必要があるかもしれません。

docker run --rm --device /dev/ttyACM0 -v ./_build:/_build pfr-kachaka-button arduino-cli upload -p /dev/ttyACM0 --fqbn m5stack:esp32:m5stack_core2 --input-file /_build/button_hub.ino.bin

これが成功すれば、M5Stack にカチャカボタンハブのソフトウェアがインストールされ、起動してくると思います。

設定

カチャカボタンハブは、起動直後に初期設定として Wi-Fi 接続の設定を行う必要があります。この Wi-Fi は、カチャカが接続しているものと同じネットワークである必要があります。
Wi-Fi の設定を行うためには SSID とパスワードなどの情報が必要ですが、M5Stack にはキーボードのような入力デバイスがないので、一旦 M5Stack を Wi-Fi アクセスポイントにして、スマートフォンをそこに接続してスマートフォン経由で設定します。
以下のような画面になるので、お手持ちのスマートフォンでQRコードを読み込んで、指示に従ってください。
ここから先は、手順書があるので、こちらを御覧ください。

https://kachaka.zendesk.com/hc/ja/articles/6966050952847

ソフトウェア開発に関するトピック(開発者向け)

カチャカボタンハブのソフトウェアについて、開発秘話ではないですが、社内でもよく聞かれるトピックについて書いておきます。

RAMが512KBしかない

M5Stack v2.7 は512KBのRAMしか搭載していません。その上で、Wi-Fi、BLE、gRPCクライアント、HTTP+WebSocketサーバなどの機能を動かす必要があります。マルチスレッドと動的なメモリ確保が前提であるOSSライブラリも利用しているので、全てを事前にプリアロケートすることも不可能です。
なので、状況によってはどうしてもヒープメモリの確保に失敗して思い通りに機能しないときもあります。ですが、できる限りメモリを節約しています。具体的には以下のアクションをとっています。

  • 選択の余地がある場合は、メモリ消費量の少ないOSSライブラリを利用する(例:NimBLE, nanopb)
  • 起動シーケンスはシーケンシャルに行う(同時に2つの非同期処理の初期化を走らせない)
  • OSSライブラリで大きめの固定長バッファを確保しているところは、パッチをあてて小さくする(例:nghttp2)

なお、上位機種であるM5Stack Core2には8MBのSPRAMが搭載されているので、この問題は存在しません。実際に同じソフトウェアがCore2で動作するので、予算に余裕がある方はCore2を利用すると良いかもしれません。

カチャカボタンハブが512KBの機種を選んだのは、価格が安価なことと、物理ボタンがあること、の2点で、特に物理ボタンの押しやすさは大きな違いです。

gRPC on ESP32

gRPCはHTTP/2とprotocol buffersをベースとした通信プロトコルです。カチャカ本体を外から自由に制御できる「カチャカAPI」はgRPCで提供されています。
調べたところ、M5StackのマイコンであるESP32上で公式gRPCライブラリを稼働させる実績はあまりないようです。ネット上を検索してみても、「こうすればできる」という記述はほとんど見当たりません。一方で、ある程度手を抜いてHTTP/2上に直接gRPCのプロトコルを直接流し込むことで、無理やりgRPCクライアントを実現できた、との情報をGitHub上で見つけたので、それに倣ってカチャカボタンハブでもgRPCを実現しています。ですので、結果としてgRPCライブラリは利用していません。必要な部分を自前で用意しています。

protobufのシリアライズ・デシリアライズにはnanopbというCで書かれた組み込み向け軽量ライブラリを利用しています。

nghttp2の修正

nghttp2はHTTP/2の実装で、Arduinoのm5stackコアにコンパイル済みライブラリが含まれています。これをこのまま利用すればHTTP/2で通信ができますが、そのまま使うと16Kバイトのバッファーを複数箇所で確保しようとするため、512KバイトしかRAMが無いM5Stackでメモリ確保に失敗することがあります。
この問題を回避するため、カチャカボタンハブではnghttp2のソースを取り込んでいて、バッファサイズの定数を16KBから4KBに修正して利用しています。

React

カチャカボタンハブの設定には、スマホやPCのウェブブラウザを利用します。このための、ブラウザ上で動くWebアプリケーションをReactで開発しました。

プロジェクト開始時は、大昔の掲示板サイトみたいに簡単なフォームを使ってページ遷移するUIを作る必要があるのかもしれない、と思っていました。しかし、やってみるとM5Stackで普通にWebSocketが使えたので、ReactのSPAをそのままサーブすればいつもと同じReactアプリを使える、と思い直して方針転換しました。

Reactはビルドするとindex.htmlやindex.jsなどのファイルを生成しますが、これをC++のバイト列定数としてプログラム中に埋め込み、HTTPサーバがGETのレスポンスとしてそのバイト列を返します。こうすることで、プログラムバイナリの中にデータを含むことができます。
ハブとブラウザは、WebSocketで通信を行います。一部例外的にGETやPUTも行いますが、WebSocketのコネクションを様々な用途に再利用することでM5Stack側の消費メモリの削減が行えます。

おしゃれな見た目や高機能なUIコンポーネントを提供するUIフレームワークの利用も検討しましたが、いくつか試してみたところ、どれもビルド結果のJavaScriptサイズが巨大になるため断念しました。

設定画面の例

OTA(ソフトウェアアップデート)

カチャカボタンハブにはOTAの機能が組み込まれています。ただし、クラウド側に対応するインフラを用意する必要があり、OSS版ではデフォルトでOTA機能は無効化されています。クラウドAPIの仕様は特に公開していませんが、ソースを読めばだいたい理解できると思います。

M5Stackのフラッシュ上のアプリケーション領域はA/Bの両面が存在するので、稼働中に裏面を書き込むことで、サービス停止時間をほぼ無くしたソフトウェアアップデートが実現できます。ただし、OTAイメージ取得用のHTTPクライアントを動かしながら同時にハブのメイン機能を稼働させると、色々と問題が発生しがちであることがわかったため、カチャカボタンハブでは、OTAするときは(一度再起動した後に)メインの機能を停止して、OTAの処理だけを走らせるようにしています。

設定の永続化

WiFiや音量・画面輝度などの各種設定は、ESP32のNVSに永続化しています。NVSはkey-valueストアで、非常に簡単に利用できるライブラリを利用しています。
一方、ボタンの設定はSPIFFSというファイルシステムにJSONで書き込んでいます。

バイナリサイズ

最終的なバイナリサイズは3.4MBです、そのうち1.4MBが日本語フォントになっています。また0.4MBがReactの生成物なので、正味のバイナリサイズは1.6MBのようです。

最後に

カチャカボタンハブはアイデア自体は以前からあったのですが、最近特に欲しいという声が高まってきたので、1ヶ月程度の短期間でバーっと作って実戦投入した新しいプロダクトです。ESP32の制限されたマイコン環境上でgRPCなどの高度なプロトコルを使い、更にReactのウェブ技術を乗っけた面白いプロダクトになったと思います。
実際に、弊社のオフィスでは毎日お菓子やゴミ箱などをカチャカ君がせっせと運んでくれていて、仕事に集中しているときにボタンプッシュで呼んだり返したりできるのはとても便利です。

Preferred Robitics では、30名程度の少人数でカチャカやHapiibotのようなプロダクトを開発・販売しています。ロボット本体の開発以外にも、カチャカボタンのような周辺技術もあり、様々な人材を募集しています。
https://www.pfrobotics.jp/#career

他の社員の書いた記事もご覧ください。

https://qiita.com/KazutoMurase/items/f91c97cf271638d8e4ae

https://qiita.com/terakoji-pfr/items/0f1535b45fda58edad83

Discussion