#codamaとは?
raspberry piのVUIキット。オリジナルのトリガーワードを作成できたり、マイクアレイを使って音源の方向検知ができたりと面白い。
https://codama.ux-xu.com/
https://robotstart.info/2018/12/28/cidama-dev-01.html
#作ってみたいもの:codamaちゃん
声に反応するキャラクターロボットをやってみようと思った。
現時点では、下記サンプルを動かしてみたというところまで。最終的には外装もつける予定。
・サンプル1:オリジナルトリガーワードに反応して効果音
・サンプル2:喋っている方向にサーボモータを使ってなんとなく向く
つまずきポイントもいくつかあるので共有。なお、私はハードウェアエンジニアなので、ソースの信頼度はそこまで高くないことをご了承いただけるとありがたく。
設定
基本的には、以下に沿って設定、トリガーワードを作成する。
https://github.com/YUKAI/codama-doc-r0/wiki
躓いたポイントは、codamaのメインボードとマイクボードをつなぐケーブルが逆刺しできてしまうということ。このケーブルの向きには気をつける必要がある。赤いラインが写真の向きになっているのが正解。(逆刺ししても壊れなかったが、動作しない)
あと、ウェイク・アップ・ワード登録のときに、ボード上のジャンパーを操作する必要がある。出荷時はジャンパーがついている状態となっているが、この状態でデフォルトファームウェアが起動するようになっている。update.binを書き込んだあとは、ジャンパーを外して運用する。私は、下記写真のように、片側だけつけてジャンパーをなくさないようにしている。
その2点以外は、基本的にチュートリアル通りにやればすんなり動くようになる。
#ハードウェア製作
下記を用意
- raspi
- codama
- スピーカ
- サーボモータ
ハードウェアは、あまり推奨されないが、raspiの5V系でサーボを動かしてしまう。codamaボード上のCN10上のGND、5V, GPIO4にサーボのGND, VCC, Signalを接続。
スピーカーはcodamaメインボードのCN9に接続。
あとは、両面テープと結束バンドでいい感じにつくる。
#サンプル1:オリジナルトリガーワードに反応して効果音再生
至ってシンプル。トリガーワードが検知されると、GPIO27がHIGHになるので、それを監視して効果音を再生するシェルスクリプト。
#!/bin/sh
if [ ! -f /sys/class/gpio/gpio27/value ]; then
echo 27 > /sys/class/gpio/export
fi
TRGWORD=0
while true
do
if [ "`cat /sys/class/gpio/gpio27/value`" = 1 ] ; then
if [ $TRGWORD = 0 ] ; then
aplay -c1 -r16000 -fS16_LE jump07.wav &
TRGWORD=1
fi
else
if [ $TRGWORD = 1 ] ; then
TRGWORD=0
fi
fi
sleep 0.2
done
デモ動画
https://youtu.be/vFRrV7NrGRw
オリジナルトリガーワードはかなり正確に入る。
#サンプル2:喋っている方向にサーボモータを使ってなんとなく向く
codamaの音源方向検知を利用する。
以下コマンドで、ユーザーが触れるパラメータがわかる。
pi@raspberrypi:~ $ cd codama/codama-doc/utils/
pi@raspberrypi:~/codama/codama-doc/utils $ ./codama_i2c -p
paramater type max min r/w info
--------- ---- --- --- --- ----
HPFONOFF int 3 0 read-write High-pass Filter on microphone signals.
0 = OFF
1 = ON - 70 Hz cut-off
2 = ON - 125 Hz cut-off
3 = ON - 180 Hz cut-off
AECSILENCELEVEL float 0.93 1e-09 read-write Threshold for signal detection in AEC [-inf .. 0] dBov (Default: -80dBov = 10log10(1x10-8))
AECSILENCEMODE int 1 0 read-only AEC far-end silence detection status.
0 = false (signal detected)
1 = true (silence detected)
AGCONOFF int 1 0 read-write Automatic Gain Control.
0 = OFF
1 = ON
AGCMAXGAIN float 1000 1 read-write Maximum AGC gain factor.
[0 .. 60] dB (default 30dB = 20log10(31.6))
AGCDESIREDLEVEL float 0.99 1e-08 read-write Target power level of the output signal.
[-inf .. 0] dBov (default: -23dBov = 10log10(0.005))
AGCGAIN float 1000 1 read-write Current AGC gain factor.
[0 .. 60] dB (default: 0.0dB = 20log10(1.0))
AGCTIME float 1 0.1 read-write Ramps-up / down time-constant in seconds.
BEAMWIDTH float 1 0.2 read-write Width of the beam for desired speech sources.
[23 .. 180] (default: 60 = sin-1(0.5) 360/ pi)
BEAMANGLE float 1 -1 read-write Center of the beam for desired speech sources.
[-90 .. 90] (default: 0 = sin-1(0.0) 360/2pi)
STATNOISEONOFF int 1 0 read-write Stationary noise suppression.
0 = OFF
1 = ON
GAMMA_NS float 3 0 read-write Over-subtraction factor of stationary noise. min .. max attenuation
MIN_NS float 1 0 read-write Gain-floor for stationary noise suppression.
[-inf .. 0] dB (default: -16dB = 20log10(0.15))
NONSTATNOISEONOFF int 1 0 read-write Non-stationary noise suppression.
0 = OFF
1 = ON
GAMMA_NN float 3 0 read-write Over-subtraction factor of non- stationary noise. min .. max attenuation
MIN_NN float 1 0 read-write Gain-floor for non-stationary noise suppression.
[-inf .. 0] dB (default: -10dB = 20log10(0.3))
ECHOONOFF int 1 0 read-write Echo suppression.
0 = OFF
1 = ON
VOICEACTIVITY int 1 0 read-only VAD voice activity status.
0 = false (no voice activity)
1 = true (voice activity)
SR_GAMMA_VAD float 1000 0 read-write Set the threshold for voice activity detection.
[-inf .. 60] dB (default: 3.5dB 20log10(1.5))
KEYWORDDETECT int 1 0 read-only Keyword detected. Current value so needs polling.
DOAANGLE int 359 0 read-only DOA angle. Current value. Orientation depends on build configuration.
DOAANGLEKWD int 359 0 read-only DOA angle when keyword detects.
SOFTRESET int 1 0 write-only Soft Reset Request
MIC_ATTEN int 0 -100 read-write MIC input signal attenuator in decibels. [0 .. -100] dB (Default 0dB)
AEC_REF_ATTEN int 0 -100 read-write AEC reference signal attenuator in decibels. [0 .. -100] dB (Default: 0dB)
VERSION int 2147483647 0 read-only Version number
今回は、DOAANGLE
を使ってみる。
以下のpythonサンプルコードを作成。raspiからサーボモータを動かすライブラリはpigpiod
を使う。当初、RPi.GPIO
でやっていたのだが、pwmがノイジーでサーボがピクピク動いてしまった。
import pigpio
import time
import subprocess
import signal
import sys
pin=4
pi = pigpio.pi()
pi.set_servo_pulsewidth(pin, 1500)
def res_cmd(cmd):
return subprocess.Popen(cmd, stdout=subprocess.PIPE,shell=True).communicate()[0]
def main():
current_angle = 90
cmd = ("/home/pi/codama/codama-doc/utils/./codama_i2c DOAANGLE")
while True:
n=20
i=0
value = res_cmd(cmd).strip()
target_angle = int(value.strip("DOAANGLE:"))
if target_angle < 30 or target_angle > 150:
target_angle = 90
print 'Target angle:' + str(target_angle)
divided_angle = (current_angle - target_angle)/n
while i<n:
current_angle -= divided_angle;
pi.set_servo_pulsewidth(pin, (85/9)*current_angle + 650)
time.sleep(0.05)
i+=1
time.sleep(0.5)
if __name__ == '__main__':
main()
以下で実行。
pi@raspberrypi:~/workspace $ sudo pigpiod
pi@raspberrypi:~/workspace $ sudo python servo_test.py
デモ動画
https://youtu.be/A05lSUaqGUc
喋っていてこちらに向いてくるという機能はとてもおもしろく、可能性を感じた。ただ、反応にラグがある。また、codamaマイクの使い方として、マイクアレイは筐体に完全固定して使うことが推奨されており、今回私のサンプルでは、サーボの先の動く部分にマイクがついていることもやや精度を落としている一つの要因かと思う。
#ハマって未だに解決していないこと
i2cが見えなくなる現象が起こる。
連続して動かすと、稀に発生し、エラーメッセージは下記のとおり。再現条件は不明だが、自分の環境以外でも起きている模様。
rdwr ioctl error -1: No such device or address
Error: Control read command failed
解決方法としては、一度raspiとcodamaの電源もオフにして再起動すると復帰することが多い。(ハードウェア的に5Vを抜き差しする。rebootではNG)
これでもだめな場合、以下で直ったこともある。
$ sudo raspi-config
--> 5 Interfacing Options
--> P5 I2C
Select <No>
Select <OK>
Select <Finish>
一度、Raspberry Piを含め電源を落とし、入れ直す。起動したら、以下でI2Cデバイスが存在する事を確認。
$ ls -al /dev/i2c-1
以上、codamaを使って遊んでみたのとハマったポイントの共有でした。