re:Invent 2017でAlexaをRaspberryPi経由で利用する方法のワークショップに参加した。
ワークショップでは、構成済みのMicroSDを使って、単純にコマンドを流したり、支持されたようにファイルを書き換えたりしただけだったので、まっさらなMicroSDの状態から同様に動くようになるまでをやってみたいと思う。
用意するもの
Raspberry Pi 3 Model B
USBマイク < 多分これ
イヤホン
USBキーボード
USBマウス
HDMIケーブル
ディスプレイ
MicroSD Class10 16G
事前準備(Macでの作業)
インストーラーのダウンロード
こちらからNOOBSをダウンロードする
今回ダウンロードしたバージョンは v2.4.5
MicroSDにコピーする
ダウンロードしたNOOBS_v2_4_5.zip
を解凍しFAT32でフォーマット済みのMicroSDにファイルをコピーする。
cp -a Downloads/NOOBS_v2_4_5/* /Volumes/UNTITLED
Raspbianのインストール
先ほどのMicroSDをRaspberry Piに刺して電源を入れるとインストーラーが立ち上がるので、Raspbian [RECOMMENDED]
にチェックを入れて、左上のInstallをクリックしてインストールすればOK
事前準備(Raspberry Piでの準備)
一応OSのバージョンチェック
こんな記載があるので、Raspbian Stretchかどうか一応チェック
This guide provides step-by-step instructions to set up the Alexa Voice Service (AVS) Device SDK on a Raspberry Pi running Raspbian Stretch with Desktop
$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)"
NAME="Raspbian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
ネットワークに接続
有線LANもあるので有線でつなげる場合には、何もしなくて大丈夫
Wi-Fiを利用する場合には右上にマークがあるのでそこから接続設定する
SSH/VNCの有効化
有効化しなくてもOKだけど、リモートから行える作業はできるだけリモートで行うと楽なので有効化しておく
ビルド環境の構築+ビルド
基本的にはこちらにある通りに行う
https://github.com/alexa/avs-device-sdk
依存関係のあるライブラリ、AVS Device SDK, Sensory wake word engine のインストール
Sensory wake word engineはオープンソースは非商用限定のライセンスなので注意すること
cd /home/pi/
mkdir sdk-folder
cd sdk-folder
mkdir sdk-build sdk-source third-party application-necessities
cd application-necessities
mkdir sound-files
sudo apt-get update
sudo apt-get -y install \
git gcc cmake build-essential libsqlite3-dev libcurl4-openssl-dev \
libfaad-dev libsoup2.4-dev libgcrypt20-dev libgstreamer-plugins-bad1.0-dev \
gstreamer1.0-plugins-good libasound2-dev doxygen
cd /home/pi/sdk-folder/third-party
wget -c http://www.portaudio.com/archives/pa_stable_v190600_20161030.tgz
tar zxf pa_stable_v190600_20161030.tgz
cd portaudio
./configure --without-jack
make
pip install commentjson
cd /home/pi/sdk-folder/sdk-source
git clone git://github.com/alexa/avs-device-sdk.git
cd /home/pi/sdk-folder/third-party
git clone git://github.com/Sensory/alexa-rpi.git
cd ./alexa-rpi/bin/
./license.sh
ビルド
make のオプションは -j4までいけるけど、オーバーヒートに注意しましょう(と書いてある)
cd /home/pi/sdk-folder/sdk-build
cmake /home/pi/sdk-folder/sdk-source/avs-device-sdk \
-DSENSORY_KEY_WORD_DETECTOR=ON \
-DSENSORY_KEY_WORD_DETECTOR_LIB_PATH=/home/pi/sdk-folder/third-party/alexa-rpi/lib/libsnsr.a \
-DSENSORY_KEY_WORD_DETECTOR_INCLUDE_DIR=/home/pi/sdk-folder/third-party/alexa-rpi/include \
-DGSTREAMER_MEDIA_PLAYER=ON \
-DPORTAUDIO=ON \
-DPORTAUDIO_LIB_PATH=/home/pi/sdk-folder/third-party/portaudio/lib/.libs/libportaudio.a \
-DPORTAUDIO_INCLUDE_DIR=/home/pi/sdk-folder/third-party/portaudio/include
make SampleApp -j2
Alexa Voice Serviceへの登録
先ほどビルドしたSampleAppからAlexa Voice Serviceへ接続するためには設定を作る必要があるので作成する。
Amazon Developerに登録
こちらからログインする
日本でもEchoが発売されたのでamazon.co.jpアカウントでもログインできるらしい
Alexa Voice Service に製品を登録する
!!! 一度作成した設定は削除できないようなので注意 !!!
Alexa Voice Service を選ぶ
CREATE PRODUCTを選ぶ
プロダクト情報を入力する
Product Name: 任意
Product ID: 任意(あとで使うのでメモっておくこと)
Is your product an app or device?: Device
Will your device use -----: 任意(Deviceを選ぶと出てくる)
Product category: 任意
Brief product description: 任意
How will end users -----: Hands-free
Upload an image: 任意
Do you intend to -----: No
Is this a children's -----: No
セキュリティプロファイルの設定を作る
CREATE NEW PROFILEを選択すると、下にプロファイル名と説明を入れる欄が出るので、入力する。
URLの登録
次で使うので、Client ID, Client Secretをメモに取る
http://localhost:3000
を入力してADDボタンを押す
同様にAllowed return URLsにはhttp://localhost:3000/authresponse
を入力してADDボタンを押す
アプリケーション側に設定を反映
その前にvimのインストール
nano, edとかは入ってるけど辛いのでvimをインストール
sudo apt-get install -y vim
設定ファイルの書き換え
YOUR_CLIENT_SECRET, YOUR_CLIENT_ID, YOUR_PRODUCT_IDを先ほどメモったものに書き換えて以下を実行する
cat <<EOF >/home/pi/sdk-folder/sdk-build/Integration/AlexaClientSDKConfig.json
{
"authDelegate":{
"clientSecret":"YOUR_CLIENT_SECRET",
"deviceSerialNumber":"123456",
"refreshToken":"",
"clientId":"YOUR_CLIENT_ID",
"productId":"YOUR_PRODUCT_ID"
},
"alertsCapabilityAgent":{
"databaseFilePath":"/home/pi/sdk-folder/application-necessities/alertsCapabilityAgent.db"
},
"settings":{
"databaseFilePath":"/home/pi/sdk-folder/application-necessities/settings.db",
"defaultAVSClientSettings":{
"locale":"en-US"
}
},
"certifiedSender":{
"databaseFilePath":"/home/pi/sdk-folder/application-necessities/certifiedSender.db"
},
"sampleApp":{
"displayCardsSupported":false
}
}
EOF
音の設定
cat <<EOF >~/.asoundrc
pcm.!default {
type asym
playback.pcm {
type plug
slave.pcm "hw:0,0"
}
capture.pcm {
type plug
slave.pcm "hw:1,0"
}
}
EOF
リフレッシュトークンの取得
先ほど書き換えず空のままだったrefreshTokenを取得する
まずは、下記コマンドを実行して認証用Webサーバーを立ち上げる
cd /home/pi/sdk-folder/sdk-build && python AuthServer/AuthServer.py
直接もしくはVNCを利用して、Raspberry Pi内のブラウザを立ち上げて http://localhost:3000/ にアクセスするとSign in to [セキュリティプロファイル名] using your Amazon account
のページにリダイレクトされるので、ログインする
ログインが完了すると立ち上げてWebサーバーにリダイレクトされて戻ってきて、The file is written successfully.
という表示がされている
Server is shutting down, so you can close this window.
サンプルアプリケーションの実行
$ cd /home/pi/sdk-folder/sdk-build/SampleApp/src
$ TZ=UTC ./SampleApp \
/home/pi/sdk-folder/sdk-build/Integration/AlexaClientSDKConfig.json \
/home/pi/sdk-folder/third-party/alexa-rpi/models
#############################
# Connecting... #
#############################
########################################
# Alexa is currently idle! #
########################################
///ここに大量のエラーが出ているけど、一旦動作には関係なさそうなので放置///
# # # ##### ##### ###### # #
# # # # # # # # # # # #
# # # # # # # # # #
# # # # ##### ##### # # ###
####### # # # # # # # #
# # # # # # # # # # # #
# # # ##### ##### ###### # #
##### #
# # ## # # ##### # ###### # # ##### #####
# # # ## ## # # # # # # # # # #
##### # # # ## # # # # ##### # # # # # #
# ###### # # ##### # # ####### ##### #####
# # # # # # # # # # # # #
##### # # # # # ###### ###### # # # #
+----------------------------------------------------------------------------+
| Options: |
| Wake word: |
| Simply say Alexa and begin your query. |
| Tap to talk: |
| Press 't' and Enter followed by your query (no need for the 'Alexa').|
| Hold to talk: |
| Press 'h' followed by Enter to simulate holding a button. |
| Then say your query (no need for the 'Alexa'). |
| Press 'h' followed by Enter to simulate releasing a button. |
| Stop an interaction: |
| Press 's' and Enter to stop an ongoing interaction. |
| Privacy mode (microphone off): |
| Press 'm' and Enter to turn on and off the microphone. |
| Playback Controls: |
| Press '1' for a 'PLAY' button press. |
| Press '2' for a 'PAUSE' button press. |
| Press '3' for a 'NEXT' button press. |
| Press '4' for a 'PREVIOUS' button press. |
| Settings: |
| Press 'c' followed by Enter at any time to see the settings screen. |
| Speaker Control: |
| Press 'p' followed by Enter at any time to adjust speaker settings. |
| Info: |
| Press 'i' followed by Enter at any time to see the help screen. |
| Quit: |
| Press 'q' followed by Enter at any time to quit the application. |
+----------------------------------------------------------------------------+
こんな感じで動いてとりあえずひと段落、Alexa
と呼びかけるか、t + Enter
でLinteningモードに入る
そうすると、以下のように、ステータスが遷移して、Speakingで話してくれるはず、、、はず、、、
############################
# Listening... #
############################
###########################
# Thinking... #
###########################
###########################
# Speaking... #
###########################
########################################
# Alexa is currently idle! #
########################################
あれれ?
音が出ない
音が出ない何故???と思ったら、ディスプレイ側のピンジャックにイヤホンを繋げたら声が聞こえる
ということはHDMI側に信号が流れてしまっているみ???
インターフェイスの優先度的な問題かと思い、HDMIを抜いたり、刺したり、設定変えたりしたけれども解決の糸口が見えないのでとっても困ってます
例えば、以下を実行してもやっぱりHDMI経由で音が出力される・・・
$ amixer cset numid=3 1
numid=3,iface=MIXER,name='PCM Playback Route'
; type=INTEGER,access=rw------,values=1,min=0,max=2,step=0
: values=0
上の状況でYouTubeを確認したところ、ピンジャックからの出力になっていたので、ここの設定はAlexaには関係なさそう
また、ワークショップで使ったMicroSDを刺して起動した場合には、しっかりとピンジャックから音が出力されるので何らかの設定ミスの線が濃厚
RaspberryPiの知見も、Linuxで音を出す的な知見も全くないので、お手上げ状態です
どなたかわかる方いらっしゃったら教えてもらえたら嬉しいです
音が切れる
もう一つの問題として、Alexaの話が途中で切れることWhat's your name
ときくとMy name is Ale
という感じで途中で切れてしまう
これも設定で何とかできるんじゃないかと思っているけれども、今の所、どう調べたらいいものやらという感じで止まっている
音がピンジャックから出ない問題と同様に教えてもらえたら嬉しいです
助けてもらえるときのために、関連しそうな情報を末尾に載せておきます
今後のやりたいこと
単純にAlexaと声をかけて、声で操作するだけならEchoを使えばいいだけなので、すぐに思いつくようなことだけではあるけれども、以下のようなことを考えている
- Wake word engineが独立しているので、Alexa以外の言葉に反応させられたら、専用で作る意味が出てくるので、試したい
- Wake wordだけでなくコマンドから入力受付状態にできるので、受付システムとかできそうなので試したい
音の設定関連の情報
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 0: ALSA [bcm2835 ALSA], device 1: bcm2835 ALSA [bcm2835 IEC958/HDMI]
Subdevices: 1/1
Subdevice #0: subdevice #0
$ aplay -L
null
Discard all samples (playback) or generate zero samples (capture)
default
sysdefault:CARD=ALSA
bcm2835 ALSA, bcm2835 ALSA
Default Audio Device
dmix:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Direct sample mixing device
dmix:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Direct sample mixing device
dsnoop:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Direct sample snooping device
dsnoop:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Direct sample snooping device
hw:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Direct hardware device without any conversions
hw:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Direct hardware device without any conversions
plughw:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Hardware device with all software conversions
plughw:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Hardware device with all software conversions
$ amixer cset numid=3
numid=3,iface=MIXER,name='PCM Playback Route'
; type=INTEGER,access=rw------,values=1,min=0,max=2,step=0
: values=0