Alexa Voice Service(AVS) のサンプルを Raspberry Pi で動かす

 Alexa Skills Kit(ASK)の実装は以前試してみましたが、 Alexa Voice Service(AVS) はまだ試してみていなかったので、今回は AVS のサンプルアプリを Raspberry Pi で動かしてみました。基本的には下記のチュートリアルの内容をトレースしたものです。

github.com

 Alexa は主に ASK と AVS で構成されていて、 ASK がクラウド上で動作して処理を返すのに対して、 AVS はデバイス上で動作して、入力された音声データの処理と ASK へのリクエストとレスポンスの仲介を行います。

developer.amazon.com

使用デバイス

 今回使用したデバイスは Raspberry Pi 3 Model B と、下記のUSBマイクです。

https://www.amazon.co.jp/gp/product/B01KZPF1U8/

 スピーカーは 3.5mm ステレオジャックの手持ちのものがなかったので、とりあえず手持ちのヘッドホンを使用して試してみました。

 また、 microSDカードも新しい 16GB のものを用意してセットアップしました。

f:id:akanuma-hiroaki:20180110083836j:plain:w300

Raspberry Pi のセットアップ

 まずは Raspberry Pi のセットアップを下記で紹介されている手順に従ってNOOBSを使用して行います。

github.com

 特に難しいことはありませんが、注意点としては、 micro SD カードは購入時のままでも大抵は Mac で読み書きできますが、改めてフォーマットしてから使用しないと Raspberry Pi でインストーラが起動したところからずっと待ち状態のまま進みませんでした。

 あと追加で raspi-config から Wi-Fi アクセスのセットアップと、 GUI 上から SSH と VNC の有効化を行いました。

Amazon Developer アカウントの作成

 まだ Amazon Developer アカウントを作成していない場合は developer.amazon.com から登録します。私は以前 ASK の実装を試した時に作成していたのでそれを使用しました。詳細な登録手順は割愛します。

f:id:akanuma-hiroaki:20180109080720p:plain

製品とセキュリティプロファイルの作成

 Amazon Developer コンソールから AVS を動かす製品(デバイス)の登録とセキュリティプロファイルの作成を行います。手順については下記ページで紹介されています。

Create Security Profile · alexa/alexa-avs-sample-app Wiki · GitHub

 まず製品の登録です。コンソール上部のメニューから ALEXA をクリックし、 Alexa Voice Service の 始める をクリックします。

f:id:akanuma-hiroaki:20180109083329p:plain

 登録済みの製品の一覧ページに遷移しますので、右上の 製品を作成する をクリックします。

f:id:akanuma-hiroaki:20180109083356p:plain

 製品情報の入力フォームが表示されますので、チュートリアルで紹介されている通り、下記の画像のように入力して、 次へ をクリックします。ここで入力している製品ID はあとでサンプルアプリを動かす際に必要になります。

f:id:akanuma-hiroaki:20180109083414p:plain

 Amazon へログインするためのセキュリティプロファイルの選択画面が表示されますので、 プロフィールを新規作成する リンクをクリックします。

f:id:akanuma-hiroaki:20180109083440p:plain

 セキュリティプロファイル名とセキュリティプロファイル記述の入力フォームが開きますので、ここもチュートリアルの内容に従って下記のように入力して、 次へ をクリックします。

f:id:akanuma-hiroaki:20180109083606p:plain

 さらに画面下部にプラットフォーム情報の入力フォームが開きます。ここで表示されているクライアントIDとクライアントシークレットはあとでサンプルアプリを動かす際に必要になりますのでメモしておきます。「許可された出荷地」のフォームにURLを入力して 追加 をクリックするとURLが追加されますので、 http://localhost:3000https://localhost:3000 を追加します。また、「許可された返品 URL」の方にも同様の手順で http://localhost:3000/authresponsehttps://localhost:3000/authresponse を追加し、規約への同意のチェックボックスにチェックを入れて 完了する をクリックすると製品が追加されます。

f:id:akanuma-hiroaki:20180110224830p:plain

 続いて、作成したセキュリティプロファイルを有効化します。 Developer コンソールの Amazon でログイン のページに移動し、プルダウンから先ほど作成したセキュリティプロファイルを選択して Confirm をクリックします。

f:id:akanuma-hiroaki:20180109083937p:plain

 プライバシーポリシーの入力フォームが表示されますので、ダミーのURLを入力しておき、 Save をクリックします。

f:id:akanuma-hiroaki:20180109084000p:plain

サンプルアプリの clone

 GitHub からサンプルアプリを clone します。

$ cd ~/デスクトップ
$ git clone https://github.com/alexa/alexa-avs-sample-app.git
Cloning into 'alexa-avs-sample-app'...
remote: Counting objects: 1488, done.
remote: Total 1488 (delta 0), reused 0 (delta 0), pack-reused 1488
Receiving objects: 100% (1488/1488), 19.94 MiB | 1.57 MiB/s, done.
Resolving deltas: 100% (638/638), done.
Checking connectivity... done.

インストールスクリプトの編集

 インストールスクリプトを編集し、先ほど作成した製品とセキュリティプロファイルの製品ID(ProductID)、クライアントID(ClientID)、クライアントシークレット(ClientSecret)を記載します。

$ cd ~/デスクトップ/alexa-avs-sample-app/
$ vi automated_install.sh
$ head -20 automated_install.sh 
#!/bin/bash

#-------------------------------------------------------
# Paste from developer.amazon.com below
#-------------------------------------------------------

# This is the name given to your device or mobile app in the Amazon developer portal. To look this up, navigate to https://developer.amazon.com/edw/home.html. It may be labeled Device Type ID.
ProductID=my_device

# Retrieve your client ID from the web settings tab within the developer console: https://developer.amazon.com/edw/home.html
ClientID=amzn1.application-oa2-client.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Retrieve your client secret from the web settings tab within the developer console: https://developer.amazon.com/edw/home.html
ClientSecret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

#-------------------------------------------------------
# No need to change anything below this...
#-------------------------------------------------------

#-------------------------------------------------------

インストールスクリプトの実行

 それでは下記のようにインストールスクリプトを実行します。

$ . automated_install.sh

 いくつか質問のプロンプトが表示されますが、yes で回答するとインストールが始まります。

サンプルアプリの実行

 ここまでで一通り準備はできたのでサンプルアプリを実行してみます。サンプルアプリは下記3つの要素で構成されています。

  • Companion Service:サンプルアプリの認証を行うためのWebサービス

  • AVS Sample App:AVSサンプルアプリ本体

  • Wake Word Engine:"Alexa" というフレーズでサンプルアプリとのインタラクションを開始するためのエンジン

 上記をそれぞれ別ターミナルで動作させます。インストールスクリプトの実行までは ssh 等での CLI からの実行でも問題ないかと思いますが、サンプルアプリでは GUI やブラウザを使用しますので、直接 Raspberry Pi にログインするか、 VNC Viewer などで Raspberry Pi の GUI デスクトップにアクセスして実行します。まずは Companion Service を起動します。 Companion Service は node.js のサーバアプリになっています。

$ cd ~/デスクトップ/alexa-avs-sample-app/samples
$ cd companionService && npm start

> alexa-voice-service-sample-companion-service@1.0.0 start /home/pi/デスクトップ/alexa-avs-sample-app/samples/companionService
> node ./bin/www

This node service needs to be running to store token information memory and vend them for the AVS app.

Listening on port 3000

 これでポート 3000 で接続を待ち受けます。続いてサンプルアプリ本体を起動します。Companion Service とは別のターミナルで下記コマンドを実行します。サンプルアプリ本体は Java アプリになっています。

$ cd ~/デスクトップ/alexa-avs-sample-app/samples
$ cd javaclient && mvn exec:exec
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Alexa Voice Service Sample Java Client 20160207.7
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- exec-maven-plugin:1.2.1:exec (default-cli) @ sample-java-client ---

 サンプルアプリを起動すると下記のような Window が表示されます。

f:id:akanuma-hiroaki:20180110075434p:plain

 これはデバイスを登録するためにデフォルトブラウザを起動して表示されているURLにアクセスするかどうかということなので、 はい をクリックするとブラウザが起動します。起動しない場合は手動でブラウザを起動して表示されているURLにアクセスします。プライバシー保護の警告が表示されますが、問題ないので 詳細設定 をクリックします。

f:id:akanuma-hiroaki:20180110080033p:plain

 localhost にアクセスする をクリックして続行します。

f:id:akanuma-hiroaki:20180110080137p:plain

 Amazon のログインページに遷移しますのでメールアドレスとパスワードでログインします。

f:id:akanuma-hiroaki:20180110080420p:plain

 認証に成功すると https://localhost:3000/authresponse で始まるURLに遷移し、ブラウザには下記のように表示されます。

device tokens ready これで認証は完了です。 Java アプリの方に戻ると下記のような Window が表示されていますので、 OK をクリックして Window を閉じます。

f:id:akanuma-hiroaki:20180110081115p:plain

 するとサンプルアプリのGUIが表示されます。

f:id:akanuma-hiroaki:20180110081443p:plain

 ここまでで GUI のマイクマークをクリックすることで Alexa とのインタラクションをスタートすることはできるようになっていますが、 Wake Word を使用するために Wake Word Engine を起動します。このサンプルアプリのプロジェクトではサードパーティの Wake Word Engine として Sensory の TrulyHandsFree と KITT.AI の Snowboy がサポートされています。今回は下記のように Sensory の TrulyHandsFree を使用してみます。

$ cd ~/デスクトップ/alexa-avs-sample-app/samples
$ cd wakeWordAgent/src && ./wakeWordAgent -e sensory
INFO:main: Starting Wake Word Agent
INFO:WakeWordAgent: State set to IDLE(2)
INFO:Initializing Sensory library | library name: TrulyHandsfree | library version: 5.0.0-beta.10.2 | model file: ../ext/resources/spot-alexa-rpi.snsr
WARNING:Library expires on: License expires on 28 Mar 2018 00:00:00 GMT
INFO:SensoryWakeWordEngine: mainLoop thread started
INFO:WakeWordIPCSocket::mainLoop thread started
INFO:WakeWordIPCSocket: init socket on port:5123
INFO:WakeWordAgent: thread started
INFO:===> Connected to AVS client <===

動作確認

 それではサンプルアプリの動作を確認してみます。 GUI のマイクマークをクリックするか、 "Alexa" と話しかけるとインタラクションが開始します。「今何時?』「今日の天気は?」などと質問すると Amazon Echo と同じように Alexa が応答してくれます。 Wake Word Engine を動かしているターミナルには下記のような出力があります。

INFO:===> WakeWordAgent: wake word detected <===
INFO:WakeWordAgent: State set to WAKE_WORD_DETECTED(3)
INFO:WakeWordAgent: State set to SENT_WAKE_WORD_DETECTED(4)
INFO:WakeWordAgent: IPC Command received:3
INFO:WakeWordAgent: State set to WAKE_WORD_PAUSE_REQUESTED(5)
INFO:SensoryWakeWordEngine: handling pause
INFO: *** THREAD JOINING: Sensory ***
INFO:SensoryWakeWordEngine: mainLoop thread ended
INFO:WakeWordAgent: State set to WAKE_WORD_PAUSED(6)
INFO:WakeWordAgent: IPC Command received:4
INFO:WakeWordAgent: State set to WAKE_WORD_RESUME_REQUESTED(7)
INFO:SensoryWakeWordEngine: handling resume
INFO:SensoryWakeWordEngine: mainLoop thread started
INFO:WakeWordAgent: State set to IDLE(2)

 ちなみに Wake Word Engine については、 Amazon Echo Dot ではカタカナ発音の「アレクサ」でも十分検知してくれましたが、今回のケースでは英語っぽく "Alexa" と発音しないと検知してくれませんでした。

まとめ

 今回はチュートリアルの内容をトレースすることで Raspberry Pi と Alexa を統合することができましたが、ここまでの内容だけでは Amazon Echo をそのまま使うのと変わらないので、 Raspberry Pi の自由度を活かして色々なデバイスと連携させたりしてみたいと思っています。ただ、サンプルアプリで Java アプリが公開されているものの、実装方法の詳細についての説明は見つからず、 C++ の SDK である AVS Device SDK も見てみましたが詳細な部分はよくわからなかったので、今後わかりそうであれば Raspberry Pi 上で動かす独自アプリを実装してみたいと思います。

github.com