私的AI研究会? > SDK on RasPi

Assistant SDK (Python) の Raspberry Pi へのインストール

#ref(): File not found: "20200209_142556_001s.jpg" at page "画像一覧"

#ref(): File not found: "20200216_092138_001s.jpg" at page "画像一覧"

事前準備

オーディオのテスト

  1. 録音および再生デバイスを見る。
    a. キャプチャハードウェアデバイスのリストでUSBマイクを見つけ、カード番号とデバイス番号を書き留める。
    $ arecord -l
     **** ハードウェアデバイス CAPTURE のリスト ****
     カード 1: Device [USB PnP Sound Device], デバイス 0: USB Audio [USB Audio]
       サブデバイス: 1/1
       サブデバイス #0: subdevice #0
    b. 再生ハードウェアデバイスのリストでスピーカーを見つけ、カード番号とデバイス番号を書き留める。
     3.5mmジャックには通常、Analogまたはbcm2835 ALSA(bcm2835 IEC958/HDMIではない)というラベルが付いていることに注意。
    $ aplay -l
    **** ハードウェアデバイス PLAYBACK のリスト ****
    カード 0: ALSA [bcm2835 ALSA], デバイス 0: bcm2835 ALSA [bcm2835 ALSA]
      サブデバイス: 7/7
      サブデバイス #0: subdevice #0
      サブデバイス #1: subdevice #1
      サブデバイス #2: subdevice #2
      サブデバイス #3: subdevice #3
      サブデバイス #4: subdevice #4
      サブデバイス #5: subdevice #5
      サブデバイス #6: subdevice #6
    カード 0: ALSA [bcm2835 ALSA], デバイス 1: bcm2835 IEC958/HDMI [bcm2835 IEC958/HDMI]
      サブデバイス: 1/1
      サブデバイス #0: subdevice #0
    カード 0: ALSA [bcm2835 ALSA], デバイス 2: bcm2835 IEC958/HDMI1 [bcm2835 IEC958/HDMI1]
      サブデバイス: 1/1
      サブデバイス #0: subdevice #0
  2. ホームディレクトリ(~/)に .asoundrc の名前で新しいファイルを作成する。<card number>と<device number>を前のステップで書き留めた番号に変更する。
    $ vi .asoundrc
    
    pcm.!default {
      type asym
      capture.pcm "mic"
      playback.pcm "speaker"
    }
    pcm.mic {
      type plug
      slave {
        pcm "hw:<card number>,<device number>"
      }
    }
    pcm.speaker {
      type plug
      slave {
        pcm "hw:<card number>,<device number>"
      }
    }
  3. 記録と再生が機能することを確認
    a. 再生音量を調整
    $ alsamixer
    または
    $ amixer sset PCM 80% -c0
    Simple mixer control 'PCM',0
      Capabilities: pvolume pvolume-joined pswitch pswitch-joined
      Playback channels: Mono
      Limits: Playback -10239 - 400
      Mono: Playback -1727 [80%] [-17.27dB] [on]
    b. 録音音量を調整
    $ amixer sset Mic 80% -c1
    Simple mixer control 'Mic',0
      Capabilities: cvolume cvolume-joined cswitch cswitch-joined
      Capture channels: Mono
      Limits: Capture 0 - 16
      Mono: Capture 13 [81%] [19.34dB] [on]
    c. テストサウンドを再生。ザーというホワイトノイズが確認できたら、Ctrl + Cを押す。これを実行しても何も聞こえない場合は、スピーカーの接続を確認。
    $ speaker-test -c2
    
    speaker-test 1.1.8
    
    再生デバイス: default
    ストリームパラメータ: 48000Hz, S16_LE, 2 チャネル
    16 オクターブのピンクノイズを使用
    レート 48000Hz (要求値 48000Hz)
    バッファサイズ範囲 480 ? 32768
    ピリオドサイズ範囲 480 ? 32768
    最大バッファサイズ 32768 を使用
    ピリオド数 = 4
    period_size = 8192 で設定
    buffer_size = 32768 で設定
     0 - Front Left
     1 - Front Right
    ピリオド時間 = 5.134241
     0 - Front Left
     1 - Front Right
    ^C
    d. 短いオーディオクリップを録音。
    $ arecord --format=S16_LE --duration=5 --rate=16000 --file-type=raw out.raw
    e. 再生して記録を確認。何も聞こえない場合は、で録音ボリュームを確認する。
    $ aplay --format=S16_LE --rate=16000 out.raw
    録音と再生が機能している場合、オーディオの設定は完了。そうでない場合は、マイクとスピーカーが正しく接続されていることを確認する。

Raspberry Pi での導入準備

仮想環境のコントロール

Assistant SDK (Python) インストール

認証情報の登録

Google Assistant のデモ機能実行

google-assistant-demo の実行

※ 2020/02/15 記

google-assistant-pushtotalk の実行

(env) pi@raspberrypi:~ $ googlesamples-assistant-pushtotalk --project-id raspberryai-mizutu --device-model-id raspberryai-mizutu-rasaiprd-bxeos5
INFO:root:Connecting to embeddedassistant.googleapis.com
Expression 'paInvalidSampleRate' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2048
Expression 'PaAlsaStreamComponent_InitialConfigure( &self->capture, inParams, self->primeBuffers, hwParamsCapture, &realSr )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2719
Expression 'PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer, &inputLatency, &outputLatency, &hostBufferSizeMode )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2843
Traceback (most recent call last):
  File "/home/pi/env/bin/googlesamples-assistant-pushtotalk", line 8, in <module>
    sys.exit(main())
  File "/home/pi/env/lib/python3.7/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/home/pi/env/lib/python3.7/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/home/pi/env/lib/python3.7/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/pi/env/lib/python3.7/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/home/pi/env/lib/python3.7/site-packages/googlesamples/assistant/grpc/pushtotalk.py", line 351, in main
    flush_size=audio_flush_size
  File "/home/pi/env/lib/python3.7/site-packages/googlesamples/assistant/grpc/audio_helpers.py", line 190, in __init__
   blocksize=int(block_size/2),  # blocksize is in number of frames.
  File "/home/pi/env/lib/python3.7/site-packages/sounddevice.py", line 1345, in __init__
    **_remove_self(locals()))
  File "/home/pi/env/lib/python3.7/site-packages/sounddevice.py", line 861, in __init__
    'Error opening {0}'.format(self.__class__.__name__))
  File "/home/pi/env/lib/python3.7/site-packages/sounddevice.py", line 2653, in _check
    raise PortAudioError(errormsg, err)
sounddevice.PortAudioError: Error opening RawStream: Invalid sample rate [PaErrorCode -9997]

エラーが発生、原因と解決方法を調査。
解決のヒントをくれたサイトhttps://github.com/googlesamples/assistant-sdk-python/issues/382
次のファイルを変更する。(録音設定にレートを加える。)

$ vi .asoundrc

pcm.!default {
  type asym
  capture.pcm "mic"
  playback.pcm "speaker"
}
pcm.mic {
  type plug
  slave {
    pcm "hw:1,0"
    rate 48000
  }
}
pcm.speaker {
  type plug
  slave {
    pcm "hw:<0,0>"
  }
}

再度コマンドを実行する。

pi@raspberrypi:~ $ source ~/env/bin/activate
(env) pi@raspberrypi:~ $ googlesamples-assistant-pushtotalk --project-id raspberryai-mizutu --device-model-id raspberryai-mizutu-rasaiprd-XXXXXX
INFO:root:Connecting to embeddedassistant.googleapis.com
WARNING:root:Device config not found: [Errno 2] No such file or directory: '/home/pi/.config/googlesamples-assistant/device_config.json'
INFO:root:Registering device
INFO:root:Device registered: 48b079ce-4fbf-11ea-ac12-dca63271afe7
Press Enter to send a new request...
INFO:root:Recording audio request.
INFO:root:Transcript of user request: "who".
INFO:root:Transcript of user request: "who are".
INFO:root:Transcript of user request: "who I".
INFO:root:Transcript of user request: "who  I".
INFO:root:Transcript of user request: "who  is".
INFO:root:Transcript of user request: "who  I".
INFO:root:Transcript of user request: "who  is".
INFO:root:Transcript of user request: "who  I am".
INFO:root:Transcript of user request: "who I am".
INFO:root:End of audio request detected.
INFO:root:Stopping recording.
INFO:root:Transcript of user request: "who I am".
INFO:root:Playing assistant response.
WARNING:root:SoundDeviceStream write underflow (size: 1600)
WARNING:root:SoundDeviceStream write underflow (size: 1600)
WARNING:root:SoundDeviceStream write underflow (size: 1600)
INFO:root:Finished playing assistant response.
Press Enter to send a new request...
INFO:root:Recording audio request.
INFO:root:Transcript of user request: "what".
INFO:root:Transcript of user request: "what time".
INFO:root:Transcript of user request: "what  time".
INFO:root:Transcript of user request: "what  time is".
INFO:root:Transcript of user request: "what time  is".
INFO:root:Transcript of user request: "what time  is it".
INFO:root:Transcript of user request: "what time is  it".
INFO:root:Transcript of user request: "what time is it".
INFO:root:End of audio request detected.
INFO:root:Stopping recording.
INFO:root:Transcript of user request: "what time is it".
INFO:root:Playing assistant response.
INFO:root:Finished playing assistant response.
Press Enter to send a new request...
INFO:root:Recording audio request.
INFO:root:Transcript of user request: "what".
INFO:root:Transcript of user request: "what  is".
INFO:root:Transcript of user request: "what  is a".
INFO:root:Transcript of user request: "what  is".
INFO:root:Transcript of user request: "what is".
INFO:root:Transcript of user request: "what is  a".
INFO:root:Transcript of user request: "what is  the".
INFO:root:Transcript of user request: "what is  this".
INFO:root:Transcript of user request: "what is this".
INFO:root:End of audio request detected.
INFO:root:Stopping recording.
INFO:root:Transcript of user request: "what is this".
INFO:root:Playing assistant response.
INFO:root:Finished playing assistant response.
Press Enter to send a new request...
INFO:root:Recording audio request.
INFO:root:Transcript of user request: "what".
INFO:root:Transcript of user request: "what is".
INFO:root:Transcript of user request: "what  is".
INFO:root:Transcript of user request: "what is".
INFO:root:Transcript of user request: "what is  the".
INFO:root:Transcript of user request: "what is the".
INFO:root:Transcript of user request: "what is The  Wiz".
INFO:root:Transcript of user request: "what is the  least".
INFO:root:Transcript of user request: "what is the  reason".
INFO:root:Transcript of user request: "what is the  weasel".
INFO:root:Transcript of user request: "what is the  wizard".
INFO:root:Transcript of user request: "what is the  result".
INFO:root:Transcript of user request: "what is the result".
INFO:root:Transcript of user request: "what is the result  in".
INFO:root:Transcript of user request: "what is the result  in some".
INFO:root:Transcript of user request: "what is the result  in South".
INFO:root:Transcript of user request: "what is the result in  South".
INFO:root:Transcript of user request: "what is the result in  San".
INFO:root:Transcript of user request: "what is the result in  San Fran".
INFO:root:Transcript of user request: "what is the result in  San".
INFO:root:Transcript of user request: "what is the result in  San Francisco".
INFO:root:Transcript of user request: "what is the result in San  Francisco".
INFO:root:Transcript of user request: "what is the  weather in San Francisco".
INFO:root:End of audio request detected.
INFO:root:Stopping recording.
INFO:root:Transcript of user request: "what is the weather in San Francisco".
INFO:root:Playing assistant response.
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
INFO:root:Finished playing assistant response.
Press Enter to send a new request...
INFO:root:Recording audio request.
INFO:root:End of audio request detected.
INFO:root:Stopping recording.
INFO:root:Finished playing assistant response.
Press Enter to send a new request...
INFO:root:Recording audio request.
^C
Aborted!
Segmentation fault

一応スペースキーで英語の音声入力を受け付けて、応答するようになった。

冒頭に出る WARNING: については、ドキュメント「初回にデバイスインスタンスIDを見つける」の項目によれば

Google Assistant を日本語化する

スマートスピーカーのカスタマイズ

#ref(): File not found: "fig4-2.jpg" at page "画像一覧"

#ref(): File not found: "fig4-1.jpg" at page "画像一覧"

 ハードウェアボタン(タクトSW)とLEDを紐づけて、ボタンを押して「Push to Talk」を起動させるようにする。
LEDタクトSWの接続回路は右記のとおり。

Button To Talk プログラムの作成

独自コマンド Traits 追加 (検証中)

参考資料