いないいないBAR

projects


表情によって”味”が変わる新感覚ドリンクバー。

表情がカクテルになる。無人ドリンクバー「いないいないBAR」を支える技術

私たちチーム「お暇箱」は、カメラに向かって作った表情から味を決め、その人だけの一杯を自動で調合するドリンクバー「いないいないBAR」を開発しました。

開発期間は約1年です。企画、UI、画像解析、通信、ポンプ制御、筐体製作まで、学生5人で分担して実装しました。

この記事では、システム構成と開発で工夫した点を紹介します。

プロジェクト概要

「いないいないBAR」は、利用者の表情を読み取り、甘味・酸味・苦味の配合を変える無人ドリンクバーです。

味は次の3つの特徴から決定します。

  • 口の横幅 → 甘味
  • 口の開き → 酸味
  • 眉のひそめ具合 → 苦味

大きく笑うと甘くなり、眉間にしわを寄せると苦味が強くなります。

単にドリンクを自動で注ぐのではなく、「表情を作る行為そのものを体験にする」ことを目指しました。

システム構成

システムは、役割ごとに3つの処理へ分けています。

  1. M5Stack CoreS3
    カメラ撮影、タッチUI、画像送信を担当
  2. 画像解析サーバー
    FastAPIとMediaPipeを使って表情を解析
  3. Raspberry Pi Pico
    解析結果に応じて蠕動ポンプを制御

画像解析のような負荷の高い処理はサーバー側で実行し、モーター制御のような確実性が必要な処理はPicoに分離しました。

それぞれのデバイスに適した役割を持たせることで、処理負荷と実装の複雑さを分散しています。

表情解析

表情解析には、MediaPipe Face Meshを使用しました。

顔から取得したランドマークをもとに、次の距離を計算します。

  • 左右の口角間の距離
  • 上唇と下唇の距離
  • 眉と目の距離

感情を「喜び」「怒り」のようなラベルに分類するのではなく、ランドマーク間の距離を連続値として扱い、味の強さへ変換しています。

この方式を選んだ理由は、次の2点です。

  • 表情の強弱を味へ反映できる
  • 味が決まった理由を説明しやすい

また、カメラとの距離によって顔の大きさが変わるため、各距離を顔の縦幅で割って正規化しています。

これにより、利用者がカメラへ近づいても、味が大きく変わらないようにしました。

画像フォーマットへの対応

M5Stackから取得する画像は、JPEGだけでなくRGB565形式になる場合がありました。

RGB565は、1ピクセルを16bitで表現する組み込み機器向けの画像形式です。一般的な画像処理ライブラリでは、そのまま扱えません。

そのため、サーバー側で受信データの先頭を確認し、JPEGとRGB565を自動判別する処理を実装しました。

RGB565の場合は、2バイトごとに色情報を分解し、RGB画像へ変換してからMediaPipeへ渡します。

組み込み機器とWebサーバーの間で異なるデータ形式を吸収する処理が必要になった点は、この開発で特に苦労した部分です。

デバイス間通信

通信方式は、接続先に応じて使い分けています。

M5Stackとサーバー

M5Stackから画像をHTTPで送信し、解析結果をJSONで受け取ります。

サーバーはFastAPIで実装しました。

画像の形式やサイズを検証し、不正なデータを処理前に拒否できる構成にしています。

M5StackとPico

M5StackとPicoの間はUARTで接続しました。

M5Stack側で味のパラメータをポンプの駆動時間へ変換し、Picoへ送信します。

Pico側では、受け取った駆動時間を50ミリ秒から20秒の範囲に制限しています。

異常な値が送信された場合でも、ポンプが動き続けないようにするための対策です。

ポンプ制御

液体の吐出には、蠕動ポンプを使用しました。

蠕動ポンプは、チューブをローラーで押しながら液体を送る仕組みです。液体がポンプ内部へ触れず、チューブ内だけを通るため、飲料を扱いやすい特徴があります。

甘味・酸味・苦味のシロップにそれぞれポンプを接続し、駆動時間によって吐出量を調整します。

表情解析で得た値をポンプの駆動時間へ変換することで、表情に応じた配合を実現しました。

M5Stack側の実装

M5Stack側はCircuitPythonで開発しました。

主な処理は次のとおりです。

  • カメラ映像の表示
  • タッチ操作の受付
  • 画像の送信
  • 解析中のアニメーション
  • Picoへの制御値送信

HTTP通信中に画面が停止しないよう、asyncioを使って非同期処理を実装しました。

また、画面ごとに非同期タスクを管理し、画面遷移時に不要なタスクを終了させています。

マイコンは使用できるメモリが限られているため、長時間動作させてもタスクが残り続けない設計を意識しました。

開発環境の改善

CircuitPythonのコードを変更するたびに手動で転送する作業が負担になったため、ファイル変更を検知して差分だけを送信するツールを作成しました。

さらに、Pythonコードを.mpy形式へ事前コンパイルし、M5Stack上でのメモリ使用量を削減しました。

プロダクト本体だけでなく、開発効率を改善するためのツールも必要に応じて自作しています。

開発で学んだこと

最も予定がずれたのは、ソフトウェアではなく筐体製作でした。

1号機は耐久性とメンテナンス性に問題があり、作り直すことになりました。その結果、完成は当初の予定から5〜6週間遅れました。

この経験から、ハードウェアを含む開発では、次の点が重要だと学びました。

  • 実装前に組み立て手順を決める
  • モック段階でメンテナンス性を確認する
  • ソフトウェアと筐体を別々に考えない
  • 各担当の境界を早めに決める

担当

私は、バックエンドとM5Stack側のフロントエンドを担当しました。

主な担当範囲は次のとおりです。

  • FastAPIによる画像解析API
  • MediaPipeを使った表情特徴量の算出
  • RGB565からRGB画像への変換
  • M5StackのタッチUI
  • HTTP、UART通信
  • 非同期処理
  • デプロイツールの作成

複数のデバイスと技術を接続し、システム全体が動作するところまで実装しました。

成果

完成後は、うめきたTechカンファレンスで登壇・出展しました。

実際に来場者に利用してもらい、表情を作ってからドリンクが完成するまでの体験を提供できました。

また、学内の発表会で、最優秀賞、オーディエンス賞を受賞しました。

おわりに

このプロジェクトでは、画像解析、Web API、組み込み開発、シリアル通信、モーター制御、筐体製作を組み合わせました。

個別の技術を実装するだけでなく、異なる技術を接続し、利用者が実際に体験できる状態まで完成させることを重視しました。

学生開発ではありますが、設計、実装、検証、展示、改善まで一通り経験できたプロジェクトです。

コメント

タイトルとURLをコピーしました