殿堂入り記事

社内の精鋭たちを集めて3週間でAmazon Goっぽい仕組みを作った

2018.07.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

渡辺です。

米中で無人コンビニ沸騰 機動力の良さ日本でも - 日経電子版で弊社の取り組みが紹介されました。

筆者が参加した小売り関係者の勉強会では、米中の視察の報告会に加え、アマゾン・ゴーを実際に再現したシステムの体験会があった。

企画した会社は、クラスメソッド(東京・千代田)。アマゾン・ウェブ・サービス(AWS)で国内有数の実績をもつシステム会社で、なんと3週間で疑似的な体験システムを完成させた。

本日は、こちらの記事で紹介されたAmazon Goの再現システム(以下、Yokota de Go)について、技術的な部分を紹介します。

なお、このエントリーは、上記2018年7月のデモ時点の実装に基づきます。 また、3週間程度で、試行錯誤しながら、実験をしている段階であることをご理解ください。

Amazon Goに関しては、Amazon Go体験ツアーを参照ください。

発端

ある日、ボスが「Amazon Goを作りたい!」と言い始めました。 社歴のある社員は「また始まった」という感覚で、首を突っ込みたい人や巻き込まれた人などが社内で集められてきます。 そして与えられた1枚の妄想図から、プロジェクトはスタートです。

本当にコレだけが要件定義書のようなものです・・・。 日経の記事にもあった小売関係者向けの勉強会でお披露目したいとのことで、1ヶ月弱で作るということになります(`・ω・´) なお、この時点では、どこまで出来るんだろう…という感覚なのは否めませんw

センサーとデータ

Amazon Go と同じような体験を提供するというのが本プロジェクトの方針です。 そのためには、センサーからのデータ収集が不可欠となります。 様々なセンサーが検討できますが、今回は重量センサーとToFセンサー(深度センサー)の2つを利用することになりました。 ToFセンサーは、モノの奥行きを検知できるセンサーで、空間を3次元に認識することができます。 当初はWebカメラを利用して静止画像や動画をAWSにアップロードし、画像解析などを行っていました。 しかし、実験を踏まえ、デモ数日前に今回のバージョンからは除外されています。

重量センサーは、ESP32という開発ボードで商品棚の裏側に設置され、棚の重量を定期的にAWSに送信します。 また、AWS上では、商品のマスターデータを持ちます(例: 「うまい棒」の標準重量が7g)。 理論的には、あるタイミングで、商品棚の重量が7g減っていたならば「1個購入した」、14g減っていたならば「2個購入した」といった判定が可能です。 しかし、現実としては、センサーからのデータ精度やタイミング(タイムスタンプ)のズレなど、不確定要素も多く、単純なロジックとはなりません。

センサーからAWSへのデータ送信手段は、主に2つあります。 ひとつはAWS IoT/MQTTを利用する方法で、もうひとつはHTTP(s)を利用する方法です。 IoT/MQTTを利用する方が送信コストは少なくて済みます。 また、AWS IoTの機能を活用し、送信されたデータをフィルタリングしたり、Lambda以外の方法で処理することができます。 可能であればIoT/MQTTを利用する方が良いでしょう。 センサー側でMQTTを利用するのが難しそうな場合、HTTP(s)も利用できます。 Lambdaの前にAPI Gatewayを設置し、LambdaでデータをDynamoDBに保存するなどすれば良いでしょう。 なお、HTTPSの利用が難しい場合は、API Gatewayの前にCloudFrontを配置します。

今回、重量センサーからはHTTPでデータを転送し、CloudFront/API Gateway/Lambda/DynamoDB という流れとしました。 DynamoDBには大量のデータが蓄積されるため、TTLを設定し、数日後には自動的に消えます。

ToFセンサーでは、入店したユーザをトラッキングし、商品棚に手を伸ばすアクションを検知します。 今回のデモでは、ToFセンサー5台を含むローカルネットワークを構築し、センサーデータを解析するアプリケーションを動かしています。 5個所から取得したセンサーデータからユーザをトラッキングします。 そして、棚に手を伸ばした時や入店時など、MQTTでAWSにAWS IoTイベントを送信し、Lambda関数がキックされます。

入店と退店

ユーザは、入店時にQRコードをアプリに読み込ませます。 この時、Cognitoを用いた認証を行い、AWS側のAPIをキックしますが、ここは一般的なモバイルアプリケーションと代わりません。 無人店舗で異なるのは、ToFセンサーによるトラッキングデータと突合する部分です。

ToFセンサーはチェックイン等は関係なく、ユーザをトラッキングします。 したがって、そのままでは誰が購入したか解りません。 そこで、入店タイミングにToFセンサーからのイベントを送信し、アプリからのチェックイン情報と突合しています。

退店も同様です。 トラッキングしていたユーザが出口エリアから出た時に、AWSに退店イベントを送信します。 AWS側では、チェックイン情報と突合し、退店処理が実行されます。

退店するとアプリに明細が届きます。

購入

無人店舗システムでは、「誰が」「どの商品を」「何個」購入したかを認識する必要があります。 この購入認識のためのインプットは、センサーからのデータです。 しかし、センサーデータは「可能性がある」という精度であり、確実な情報ではないことが肝になります。 言い換えれば、「かもしれない」入力データを総合的に判断し、購入を認識します。

複数のセンサーからのデータを突合する時、キーとなるのは時間(タイムスタンプ)です。 ただし、各センサーからのデータのタイムスタンプが完全に一致することはなく、数秒のズレを許容しなければなりません。 14:20.50に購入イベントがあったとしても、重量変化は14:20.51であることは珍しくないのです。 このため、数秒から数十秒程度の幅を持たせて「同時刻のイベント」と認識します。

今回のバージョンでは、ユーザが商品棚に手を伸ばしたことをToFセンサーで認識し、購入候補イベントとしてAWSに送信します。 この時点で、商品を取ったのか、手を伸ばしただけなのかは解りません。 AWSでは、各購入候補イベントに対し、重量センサーからの情報を引き当てます。 この時、重量が減っていたならば「購入した」と認識しています。

現段階では、センサーと判定を最小化し、ToFセンサーと重量センサーのみを利用しました。 しかし、センサーを増やせば、判定に必要な情報が増え、より正確に識別できるようになるはずです。 今後は多くのセンサーを増設しながら検証する必要があります。

エッジとクラウド

今回のバージョンは最終的にシンプルな形に落とし込めました。 一方、初期段階ではWebカメラで動画を撮り、画像解析等も試しています。 最終的にはToFセンサーを活用したローカル処理を中心に組み立てる方針となりました。 ここに、無人店舗システムの面白いところがあります。

ToFセンサーを活用した場合、ToFセンサーとローカルシステムが、店舗内でのユーザのトラッキングと、棚に手を伸ばすイベントをすべてカバーします。 このように、ローカル側で処理する部分はエッジ処理と呼ばれます。

エッジですべての処理を行うことも可能です。 例えば、重量センサーのデータもトラッキングシステムに統合してしまえば、シンプルなAPIを叩くだけになるでしょう。 しかし、エッジに処理を寄せれば寄せるほど、複雑なエッジ処理が増えます。 そして、ハードウェアスペックとそのコストがネックとなります。

一方、静止画や動画をAWSにアップロードし、各種サービスを使って解析させることも可能です。 この場合、エッジ側は単純になり、クラウド側のリソースをフル活用できます。 ランニングコストは増えますが、ハードウェアコストが減り従量課金となる点は魅力です。 なによりイニシャルコストが小さくなるため、参入障壁が小さくなるでしょう。

エッジに全て寄せることがベストでも、クラウドに全て寄せることがベストなわけでもありません。 エッジとクラウドのバランスが肝になると感じました。 そして、どの程度がバランス良いのかは、やってみないと解らない部分です。

まとめ

今回のプロジェクトは、ウチのボスがAmazon Goを実際に体験し「やってみたい」と感じ、社内でメンバーを募集して行われたR&D案件です。 正直なところ、出来るかどうかは解らないけどやってみるか…程度の感覚であったことは否めません。 一方で、日経電子版の方でも触れられていますが、「失敗しても良いからやってみよう」というのはメンバーへのプレッシャーも最小化されますし、伸び伸びと試してみることができました。

もし、このようなプロジェクトに興味のあるエンジニアがいましたら、クラスメソッドへようこそ。