cocoroboペット化計画～Azureシステム事例～

こんにちは。まーやです。

先日Java女子部でSHARP製の[cocorobo](http://www.sharp.co.jp/cocorobo/)という喋るお掃除ロボットを使った[ココロボミニハッカソン](https://javajo.doorkeeper.jp/events/51000)のイベントをやりました。
色々あって結局まだ完成はしていません。。。ハッカソンイベント自体はすでに終了していますが、引き続き10月末まではcocoroboちゃんをSHARP様からレンタルしているので、細々と開発を進めています。個人的に初めて使う技術も多く楽しいシステム設計になったのでここに記しておきたいと思います。

## Agenda
- システム概要
- 使った技術
- 開発感想
- まとめ

## システム概要
今回使った技術の概要はこちら。システムを動かす基盤と分析系処理をAzureで、今回やりたかったこと(後述)に対してcocoroboに不足していた処理の実装にRasberryPiやAndroidを使用しました。すべてのデバイス同士をつなぎ合わせるのにJava(Spring Boot)を使用しました。詳細については後述していきたいと思います。

- Microsoft Azure
- RasberryPi
- Android
- Java8

実際に開発中のリポジトリは[こちら](https://github.com/java-women/cocorobo-pet)です。まだmasterリポジトリにほとんどマージされていないのですが。。。

今回作成にチャレンジした機能は名付けて「cocoroboペット」。掃除そっちのけでご主人様を追い掛け回すという本来の「お掃除ロボット」という役目を全く果たさないシステムの実装です。

cocoroboのペットモードを実現するためには大きく分けて次の3つの機能が必要でした。

1. ご主人様データ登録機能
2. cocorobo動作機能(追いかけ回し機能)
3. 目玉表示機能 ※cocoroboを可愛くするためのおまけ機能

### 1. ご主人様データ登録機能
この機能はご主人様は誰か？という情報を初期データとして登録する機能です。
処理の流れは次の通り。

- ご主人様となるユーザの顔写真をAndroidアプリで撮影
- [Azure Cognitive Services の FaceAPIs](https://azure.microsoft.com/ja-jp/services/cognitive-services/face/) の中の[DetectAPI](https://dev.projectoxford.ai/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f30395236)というAPIを使って顔写真をAzure Cognitive Servicesに登録
- DetectAPIで返却されるFaceIDをAzure Redis Cacheに保持

![init.png](https://qiita-image-store.s3.amazonaws.com/0/60850/d1ba204c-4095-5bb4-fccb-9d548a4959c8.png)

### 2. cocorobo動作機能(追い掛け回し機能)
RaspberryPiからWEBカメラを操作して写真を定期的に撮影します(※2)。撮影写真に写っている人間と初期登録したご主人様データを比較し、ご主人様のいる方向へcocoroboを走らせる機能です。ここがメインの機能になりますね。

- RaspberryPiでWebカメラを操作し、X秒おきに写真撮影をする
- 撮影した写真をDetectAPIでAzure Cognitive Servicesに登録
- 撮影した写真のfaceIDをAzure Redis Cacheに保管
- ご主人様初期登録写真のfaceIDと撮影した写真のfaceIDをFaceAPIsの[Verify API](https://dev.projectoxford.ai/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f3039523a)に送付し、同一人物判定を行う
- 撮影写真に写っている人がご主人だった場合、写っている人の位置を写真上で特定し、cocoroboの進行方向を決定する
- [cocorobo動作API](https://developer.cloudlabs.sharp.co.jp/clabsapi-web/document/api/cocorobo/move)を使ってご主人様の方向へcocoroboを動かす

![action.png](https://qiita-image-store.s3.amazonaws.com/0/60850/4e6e5a4e-cec6-0f56-5e7f-a0a9adc652d5.png)

### 3. 目玉表示機能
cocoroboを可愛くするためのおまけ機能。根幹となる処理ではないんですが、よりcocoroboを生き物っぽく仕上げるための工夫。[cocoroboから取得できるデータ](https://developer.cloudlabs.sharp.co.jp/clabsapi-web/document/api/cocorobo/getdata)の中にcocoroboの感情というのがあるので、この感情バロメータに合わせてcocoroboの表情(目だけ)が変化するという機能。cocoroboの上に乗せたAndroidに目玉を表示します。

- X秒おきに目玉表示をするAndroid端末からAPIを呼び出す
- [cocoroboデータ取得API](https://developer.cloudlabs.sharp.co.jp/clabsapi-web/document/api/cocorobo/getdata)から感情数値を取得
- 感情に合わせて表示する目玉画像を変更

![eyes.png](https://qiita-image-store.s3.amazonaws.com/0/60850/302803ca-a8f9-58f3-7b8e-1a17e002f145.png)

## 使った技術
### Azure CognitiveAPIs ～FaceAPI~
[Azure CognitiveAPIs](https://azure.microsoft.com/ja-jp/services/cognitive-services/)は機械学習の難しいところをAPIで提供してくれるサービス群。今回はこのなかの[faceAPI](https://azure.microsoft.com/ja-jp/services/cognitive-services/face/)の機能を使いました。
faceAPIだけでも

- 顔検証(同一人物判定)
- 似た顔の検索
- 顔のグループ化
- 顔識別

と機能豊富です。本当は教師データをたくさん登録して顔のグループを作って、顔検証の精度を上げていく・・・という使い方をしたかったのですが、当然時間が足りるわけもなく、今回は教師データ1枚と比較データ(Webカメラで撮影した写真)を1対1で検証していく形としました。

顔の比較をするためにはfaceAPIの中の[DetectAPI](https://dev.projectoxford.ai/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f30395236)と[VerifyAPI](https://dev.projectoxford.ai/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f3039523a)を使用します。DetectAPIで画像(写真)をAzure CognitiveAPIsに登録し、VerifyAPIで登録された写真同士を比較し、写っている人の類似度判定を返却します。

[APIリファレンス](https://dev.projectoxford.ai/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f3039523a)がかなり親切で見やすかったのと、[テスト実行できるページ](https://dev.projectoxford.ai/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f30395236/console)があったのは本当に助かりました。

VerifyAPIでの類似判定はconfidence >= 0.5 でtrue判定されるようです(※3)。何回も同じ写真を登録するとVerifyAPIの判定精度が上がるようでしたので、同じ写真を2度登録しないように気を付ける必要がありました。なんて言ったって今回は1対1の比較なので、あまり判定精度が上がってしまうとご主人様判定されずにcocoroboが全く歩かない子になってしまいます。

### Azure WebApps
最近私がお気に入りで使っているWEB用サーバのPaaSです。[こちらの記事](http://qiita.com/maaya8585/items/62faddb637f02d1c808e)とか[以前Java女子部で発表した資料](http://slides.com/maaya/20160426_javajo_lt-17#/25)があるのでよろしければ見てみてください。

今回はAndroid/RaspberryPi/cocorobo/Azure Cognitive Servicesとばらばらとしたデバイス同士をつなぐAPIをどどーんとAzure WebAppsにのっけました。

Asure WebAppsはTomcatがすでに用意されているので、今回は[Spring Boot](http://projects.spring.io/spring-boot/)をwarで固めて配置しました。war化するときにSpring Boot内の組み込みTomcatを梱包しないようにしておくとよいです。
実際に使ったGradleファイルは[こちら](https://github.com/java-women/cocorobo-pet/blob/cocorobo_develop/cocoroboController/cocorobo-pet/build.gradle#L35)です。
Web.configというファイルを書けば、jarのまま公開が可能なのですが(※4)、今回は特にjarにこだわる理由がなかったのでwarを選択しました。

### Azure Redis Cache
SaaS版Redisです。Azure Redis Cacheについては[以前投稿した記事](http://qiita.com/maaya8585/items/0561309d305fd63b20a5)がございますのでよろしければご覧ください。

最初はRedisを使う予定はなかったのですが、作業しているうちにDetectAPIから返却された写真解析情報や、画像サイズ情報などを複数APIから参照する必要が出てきたため、途中から利用する方向になりました。基本的には初期登録時に設定してもらうご主人様の名前をkeyにDetectAPIから返却されたデータをJSON型のままvalueに登録する形で利用しています。

CI環境をろくに立てずに開発していたため、認証keyを記載したままGitHubにプッシュしてしまう人が続出したんですが、ポータルからボタン1つで認証keyの再発行ができたのは本当にありがたかったです(ちゃんとCI環境整えようという教訓になりました...)。

### RaspberryPi
超小型PC。センサーを色々つけてIoTなどに使用されます。今回は市販のUSBでさすタイプのWEBカメラをRaspberryPiのUSBポートにさして、撮影制御を担当してもらいました。実際の制御システムはこれまたSpring Bootで作成しました。

## 開発感想
ココロボAPIがうまく動かないとか、メンバー同士の技術レベル差、コミュニケーションエラーなどなど開発あるあるはたった2週間2回だけのハッカソンでもやっぱり発生し、苦労しました。
全員がJavaエンジニアなゆえ、インフラ知識がちょっとばかし弱かったのですが、Azureを利用して(AWSも検討していたのですがCognitive Servecesを使うので全面Azureにしました)あまりインフラ構築に時間をかけずに結合テストに入れたのは良かったなぁと感じています。実際に開発するとなるとかなり時間を割かれる画像比較なんかもAPIでしゅしゅっとやれちゃいましたしね。

## まとめ
- PaaS/SaaSサービスを使うことで効率よく開発できる。    
アプリ開発のハッカソンだったのでサーバやミドルウェアの準備＆インストールに時間をとられることなく開発できてよかった
- Azure Cognitive ServecesのFaceAPIは簡単に比較結果が出るので、ちょっと分析やってみたい方におすすめ！


というわけで以上です。結合試験中にタイムアップになってしまったので、引き続きがんばるぞー


-------------------------------------------------------
※1：本当は[Azure storage](https://azure.microsoft.com/ja-jp/services/storage/)などのデータ保管サービスを使いたかったが時間の都合上断念。
※2：cocoroboにカメラが内蔵されているのですが、内蔵カメラをHack出来なかったためRaspberryPi＋Webカメラで代用。
※3：実際にいじってみた結果による推測です。[最初に比較させた時はconfidence=0.52でtrue判定だった](https://github.com/java-women/cocorobo-pet/issues/7)2枚の画像が、同じ写真の登録->比較を繰り返した結果、現在はconfidence=0.47となり類似判定はfalseになっています。
※4：[https://azure.microsoft.com/ja-jp/documentation/articles/web-sites-java-custom-upload/#-2](https://azure.microsoft.com/ja-jp/documentation/articles/web-sites-java-custom-upload/#-2)