Julius 音声認識ソフト 番外編 音声でロボ操作準備で障害続出

シェアする

Pocket

さて、本題です。60爺は、前回の記事(Julius 音声認識ソフト part4)で、音声による操作のための準備を行いました。そして、まア何とかなるだろうとの感触を経て、6脚ロボットの音声操作に取り掛かりました。

◆前書き

6脚ロボットは、稼動設定の終わっている状態であります。そのため、このRaspberrypi3に、音声操作のためのJuliusをインストールし、ロボット操作用の辞書を作成すれば良いわけです。そして、ロボットを操作するためのプログラムを作成すれば、音声操作の6脚ロボットが完成します。

まずは、Juliusをインストールしましょう。

今回は、part4まで使用したバージョンではなく、最新版(4.4.2)のJuliusに挑戦しました。しかし、これが悲劇の幕開けだったとは、人間たる60爺には思い当たることも無かったのです。参考記事は、これです。

Raspberry Pi 3Bで音声認識

そして、Julius 4.4.2 インストールは、ここにある通りに install したら、何の問題もなく、Julius 4.4.2 がインストールできたのです。

pi@raspbian:~ $ wget https://ja.osdn.net/projects/julius/downloads/66547/julius-4.4.2.tar.gz
pi@raspbian:~ $ tar xvzf julius-4.4.2.tar.gz
pi@raspbian:~ $ cd julius-4.4.2/
pi@raspbian:~/julius-4.4.2 $ ./configure
pi@raspbian:~/julius-4.4.2 $ make
pi@raspbian:~/julius-4.4.2 $ sudo make install
pi@raspbian:~/julius-4.4.2 $ julius -version
JuliusLib rev.4.4.2 (fast)

そして、ディクテーションキットと文法認識キットのダウンロードも問題なく実施できました。

pi@raspbian:~ $ wget https://osdn.net/projects/julius/downloads/66544/dictation-kit-v4.4.zip
pi@raspbian:~ $ wget https://osdn.net/projects/julius/downloads/51159/grammar-kit-v4.1.tar.gz

pi@raspbian:~ $ mkdir /home/pi/julius-kits
pi@raspbian:~ $ cd /home/pi/julius-kits

pi@raspbian:~ $ unzip /home/pi/dictation-kit-v4.4.zip
pi@raspbian:~ $ tar xvzf /home/pi/grammar-kit-v4.1.tar.gz

次に、USBマイクの設定を行いました。

モジュールの優先順位を変更します。モジュールの優先順位を確認すると、下記のように USBマイクの優先度が低いので、順位を変えます。

pi@raspbian:~ $ sudo vi /proc/asound/modules
 
0 snd_bcm2835
1 snd_usb_audio?
pi@raspbian:~ $ sudo vi /etc/modprobe.d/alsa-base.conf
 
options snd slots=snd_usb_audio,snd_bcm2835
options snd_usb_audio index=0
options snd_bcm2835 index=1

で、rebootしたわけなんですが、Raspberrypiが立ち上がらなくなっちゃいました。
電源が入っても、うんともすんとも言わないのです。

そこで、microSDのイメージをPCで書き出して、その内容をmicroSDに上書きして起動してみましたがダメです。立ち上がろうとはしますが、そこまで・・。OSが起動できないようです。そこで、新しいmicroSDに先ほどのイメージを書き込んで立ち上げてみましたが、全く同じ状態です。
新しいRaspberryPi3号機で動かしましたが、これも同じ状態です。

どうやら、イメージが死んでしまったようです(涙)。ラズパイのOSを容れ直して再実行しかないようです。

◆フェードアウト!◆ 

翌日、気を取り直して、RaspberryPiのOSを入れ直しました。
update、upgrade(ものすごい時間:半日以上がかかりました)を行って、やっと、再開です。

1.マイクの入力

今回は、マイクの入力から始めます。

pi@raspberrypi:~ $ lsusb
Bus 001 Device 010: ID 056e:700d Elecom Co., Ltd
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

最初から、変なエラー! usb_audioがない?なんで?

pi@raspberrypi:~ $ cat /proc/asound/modules
 1 snd_bcm2835

USBマイクを別USB口に変えました。すると、復活!?です。

pi@raspberrypi:~ $ cat /proc/asound/modules
 1 snd_bcm2835
 2 snd_usb_audio

USBサウンドカードの位置を確認してみます。

pi@raspberrypi:~ $ arecord -l
**** ハードウェアデバイス CAPTURE のリスト ****
カード 2: series [UCAM-DLN130T series], デバイス 0: USB Audio [USB Audio]
 サブデバイス: 1/1
 サブデバイス #0: subdevice #0

USBマイクのボリューム調整を行います。

pi@raspberrypi:~ $ amixer sset Mic 50 -c 1
amixer: Unable to find simple control 'Mic',0

エラーですね。マイクのカード番号は2でした。うまくいったようです。

pi@raspberrypi:~ $ amixer sset Mic 50 -c 2
Simple mixer control 'Mic',0
 Capabilities: cvolume cswitch
 Capture channels: Front Left - Front Right
 Limits: Capture 0 - 44
 Front Left: Capture 44 [100%] [16.00dB] [on]
 Front Right: Capture 44 [100%] [16.00dB] [on]

2.juliusインストール

さて、それでは、juliusをインストールしましょう(それぞれのコマンドは、本ページの始めに出てま--す)。そして、ディクテーションキットを続けてインストールします。

全く問題なくインストール出来ました。順調です。

3.julius起動

続いて、ディクテーションキットのディレクトリに移動してjuliusを起動します。

pi@raspberrypi:~/julius-kits $ cd /home/pi/julius-kits/dictation-kit-v4.4
pi@raspberrypi:~/julius-kits/dictation-kit-v4.4 $ julius -C main.jconf -C am-gmm.jconf -demo

----------------------- System Information end -----------------------

Notice for feature extraction (01),
 *************************************************************
 * Cepstral mean normalization for real-time decoding: *
 * NOTICE: The first input may not be recognized, since *
 * no initial mean is available on startup. *
 *************************************************************

Stat: adin_oss: device name = /dev/dsp (application default)
Error: adin_oss: failed to open /dev/dsp
failed to begin input stream

エラー発生!やっぱり、1回で成功しないですね。このエラー発生時は、次のコマンドを打ってrebootすればいいですね。。

pi@raspberrypi:~ $ sudo sh -c "echo snd-pcm-oss >> /etc/modules"

ここで、サウンドを見てみると、あれ、usbサウンドが無い。またです。

pi@raspberrypi:~ $ cat /proc/asound/modules
 1 snd_bcm2835

仕方ないので、USBを口を差替えて見てみると登場しました。何なんだろ、一体。

pi@raspberrypi:~ $ cat /proc/asound/modules
 0 snd_usb_audio
 1 snd_bcm2835

それでは、もう一度実行してみます。

pi@raspberrypi:~ $ cd /home/pi/julius-kits/dictation-kit-v4.4
pi@raspberrypi:~/julius-kits/dictation-kit-v4.4 $ julius -C main.jconf -C am-gmm.jconf
・
・
Warning: strip: sample 0-1023 is invalid, stripped
Warning: strip: sample 0-577 has zero value, stripped

stripのワーニングが発生、これって、part1で julius 入れたとき、発生した奴ですね。
オプション -nostrip を追加して再実行してみました。

<<< please speak >>>WARNING: adin_thread_process: too long input (> 320000 samples), segmented now
Warning: input buffer overflow: some input may be dropped, so disgard the input
STAT: skip CMN parameter update since last input was invalid

part1に戻って、よーく見てみると、-lv が必要でした。

pi@raspberrypi:~/julius-kits/dictation-kit-v4.4 $ julius -input mic -lv 10000 -C
main.jconf -C am-gmm.jconf -nostrip

### read waveform input
Stat: adin_oss: device name = /dev/dsp (application default)
Stat: adin_oss: sampling rate = 16000Hz
Stat: adin_oss: going to set latency to 50 msec
Stat: adin_oss: audio I/O Latency = 32 msec (fragment size = 512 samples)
STAT: AD-in thread created
pass1_best: こんにちは 。
pass1_best_wordseq: <s> こんにちは+感動詞 </s>
pass1_best_phonemeseq: silB | k o N n i ch i w a | silE
pass1_best_score: -3358.766602
### Recognition: 2nd pass (RL heuristic best-first)
STAT: 00 _default: 23851 generated, 2254 pushed, 299 nodes popped in 140
sentence1: ほんと だ よ 。
wseq1: <s> ほんと+名詞 だ+助動詞 よ+助詞 </s>
phseq1: silB | h o N t o | d a | y o | silE
cmscore1: 0.669 0.074 0.038 0.004 1.000
score1: -3379.684326

何とか動きました。前のバージョンより、はるかに認識率がよろしいですね。

4.辞書の作成

「julius-kits」ディレクトリに移動し、辞書ファイル「houkou.yomi」を作成して、音声コマンド用の方向を示すワードを登録します。記事にありますように、「まえへ」と「マエエ」の間はタブにしています。

pi@raspberrypi:~ $ cd /home/pi/julius-kits
pi@raspberrypi:~/julius-kits $ sudo vi houkou.yomi
pi@raspberrypi:~/julius-kits $ cat houkou.yomi
まえへ マエエ
ばっく バック
うしろへ ウシロエ
みぎへ ミギエ
ひだりへ ヒダリエ
すとっぷ ストップ
すたんばい スタンバイ
ばるす バルス

ラピュタ滅びの呪文を、性懲りも無く、入れています。

音声コマンド用の単語(houkou.yomi)を登録したので、juliusが認識可能な単語辞書ファイル(houkou.dic)に変換します。

pi@raspberrypi:~/julius-kits $ iconv -f utf8 -t eucjp houkou.yomi | /home/pi/julius-kits/grammar-kit-v4.1/bin/yomi2voca.pl > houkou.dic

ius-kits/grammar-kit-v4.1/bin/yomi2voca.pl > houkou.dic
Error: (they were also printed to stdout)
line 1: まえへ マエエ
line 2: ばaく バaク
line 3: うしろへ ウシロエ
line 4: みぎへ ミギエ
line 5: ひ$りへ ヒ%?
レine 6: す?aぷ ス?aプ
line 7: すたんばい スタンバイ
line 8: ば? ぅ丱?pi@raspberrypi:~/julius-kits $ ls
dictation-kit-v4.4 grammar-kit-v4.1 houkou.dic houkou.yomi

うまく行ったようです。
次に、変換した辞書を使うための設定ファイルを作成します。

pi@raspberrypi:~/julius-kits $ sudo vi houkou.jconf
pi@raspberrypi:~/julius-kits $ cat houkou.jconf
 -w base_dict.dic
 -input mic
 -charconv euc-jp utf8
 -h model/phone_m/jnas-tri-3k16-gid.binhmm
 -hlist model/phone_m/logicalTri
 -output 1

さて、各単語を認識するか。

ところが、この設定では、エラーが出てうまくいきません。①base_dict.dicが見つからないと言われます。また、②ERROR: m_chkparam: cannot access model/phone_m/jnas-tri-3k16-gid.binhmmのエラーが発生します。

①は、上記houkou.confでの単純なミスです。base_dict.dicを今回作成したhoukou.dicにせねばなりません。
②も、指定のミスです。model/phone_mには、jnas-tri-3k16-gid.binhmmは存在しませんでした。調べたところ、60爺の環境では、/home/pi/julius-kits/dictation-kit-v4.4/model/phone_m/にありましたので、上記のフォルダにコピーしました。

修正後の houkou.jconf はこうなります。もうひとつ、houkou.jconfは、~/julius-kits/grammar-kit-v4.1に格納します。そうでないと、-hに指定しているフォルダと、うまくつながらないためです。

pi@raspberrypi:~/julius-kits $ cat houkou.jconf
 -w /home/pi/julius-kits/houkou.dic
 -input mic
 -charconv euc-jp utf8
 -h model/phone_m/jnas-tri-3k16-gid.binhmm
 -hlist model/phone_m/logicalTri
 -output 1

これで、実行してみます。

pi@raspberrypi:~/julius-kits/grammar-kit-v4.1 $ julius -C houkou.jconf  -lv 10000 -input mic -nostrip

STAT: reading [/home/pi/julius-kits/houkou.dic]...
Stat: init_wordlist: reading in word list
Error: voca_load_wordlist: line 1: logical phone "マエエ" not found
Error: voca_load_wordlist: the line content was: まええ マエエ
Error: voca_load_wordlist: line 2: logical phone "バaク" not found
Error: voca_load_wordlist: the line content was: ばaく  バaク
Error: voca_load_wordlist: line 3: logical phone "ウシロエ" not found
Error: voca_load_wordlist: the line content was: うしろえ       ウシロエ
Error: voca_load_wordlist: line 4: logical phone "ミギエ" not found
Error: voca_load_wordlist: the line content was: みぎえ ミギエ
Error: voca_load_wordlist: line 5: logical phone "ヒ%?ア not found
Error: voca_load_wordlist: the line content was: ひ$?   ぅ劵%?
Error: voca_load_wordlist: line 6: logical phone "ス?aプ" not found
Error: voca_load_wordlist: the line content was: す?aぷ ス?aプ
Error: voca_load_wordlist: line 7: logical phone "スタンバイ" not found
Error: voca_load_wordlist: the line content was: すたんばい     スタンバイ
Error: voca_load_wordlist: line 8: logical phone "バ?ア not found
Error: voca_load_wordlist: the line content was: ば?    ぅ丱?
Error: voca_load_htkdict: begin missing phones
Error: voca_load_htkdict:
Error: voca_load_htkdict: end missing phones
Error: init_wordlist: error in reading /home/pi/julius-kits/houkou.dic: 8 words failed out of 0 words
ERROR: failed to read word list "/home/pi/julius-kits/houkou.dic"
ERROR: m_fusion: some error occured in reading grammars
ERROR: Error in loading model

駄目ですね。エラー発生です。なんか、単語辞書がおかしいような・・・。いろいろとググってみたりしたんですけど、もう一度、記事と60爺の単語表を比べたら、何とバカな事をやっていたのを発見しましたーー。
辞書の中身ですが、記事は、カタカナ→ひらがなの順なのに、60爺は、ひらがな→カタカナの順にしていました。これを直してやってみました。すると、辞書作成時に、何の表示もでないんですね。あれは、エラーだったのか!

pi@raspberrypi:~/julius-kits $ iconv -f utf8 -t eucjp houkou.yomi | /home/pi/julius-kits/grammar-kit-v4.1/bin/yomi2voca.pl > houkou.dic
pi@raspberrypi:~/julius-kits $

で、これで実行してみると、ちゃんと動きましたーーー。

pi@raspberrypi:~/julius-kits/grammar-kit-v4.1 $ julius -C houkou.jconf -lv 10000 -input mic -nostrip
STAT: include config: houkou.jconf
STAT: jconf successfully finalized
・
・
・
----------------------- System Information end -----------------------

Notice for feature extraction (01),
        *************************************************************
        * Cepstral mean normalization for real-time decoding:       *
        * NOTICE: The first input may not be recognized, since      *
        *         no initial mean is available on startup.          *
        *************************************************************

------
### read waveform input
Stat: adin_oss: device name = /dev/dsp (application default)
Stat: adin_oss: sampling rate = 16000Hz
Stat: adin_oss: going to set latency to 50 msec
Stat: adin_oss: audio I/O Latency = 32 msec (fragment size = 512 samples)
STAT: AD-in thread created
・
pass1_best: マエエ
pass1_best_wordseq: マエエ
pass1_best_phonemeseq: silB m a e e silE
pass1_best_score: -2288.345947
sentence1: マエエ
wseq1: マエエ
phseq1: silB m a e e silE
cmscore1: 0.945
score1: -2288.345947

pass1_best: ウシロエ
pass1_best_wordseq: ウシロエ
pass1_best_phonemeseq: silB u sh i r o e silE
pass1_best_score: -2672.608887
sentence1: ウシロエ
wseq1: ウシロエ
phseq1: silB u sh i r o e silE
cmscore1: 0.987
score1: -2672.608887

pass1_best: ヒダリエ
pass1_best_wordseq: ヒダリエ
pass1_best_phonemeseq: silB h i d a r i e silE
pass1_best_score: -2388.519287
sentence1: ヒダリエ
wseq1: ヒダリエ
phseq1: silB h i d a r i e silE
cmscore1: 0.954
score1: -2388.519287

pass1_best: ミギエ
pass1_best_wordseq: ミギエ
pass1_best_phonemeseq: silB m i g i e silE
pass1_best_score: -2522.857910
sentence1: ミギエ
wseq1: ミギエ
phseq1: silB m i g i e silE
cmscore1: 0.723
score1: -2522.857910

pass1_best: ストップ
pass1_best_wordseq: ストップ
pass1_best_phonemeseq: silB s u t o q p u silE
pass1_best_score: -2687.319336
sentence1: ストップ
wseq1: ストップ
phseq1: silB s u t o q p u silE
cmscore1: 0.992
score1: -2687.319336

pass1_best: スタンバイ
pass1_best_wordseq: スタンバイ
pass1_best_phonemeseq: silB s u t a N b a i silE
pass1_best_score: -2862.957764
sentence1: スタンバイ
wseq1: スタンバイ
phseq1: silB s u t a N b a i silE
cmscore1: 0.619
score1: -2862.957764

pass1_best: バルス
pass1_best_wordseq: バルス
pass1_best_phonemeseq: silB b a r u s u silE
pass1_best_score: -2101.563477
sentence1: バルス
wseq1: バルス
phseq1: silB b a r u s u silE
cmscore1: 0.907
score1: -2101.563477

つまらんミスで、余計な時間を食ってしまいました。しかし、これで、前に進めます。

5.モジュールモードでの確認

今度は、モジュールモードで動かしてみます。

pi@raspberrypi:~/julius-kits/grammar-kit-v4.1 $ julius -C houkou.jconf  -lv 10000 -input mic -nostrip -module
・
・
STAT: [5] prepare for real-time decoding
STAT: All init successfully done

Stat: server-client: socket ready as server
///////////////////////////////
///  Module mode ready
///  waiting client at 10500
///////////////////////////////

もうひとつ、teratermの画面を立ち上げて、次のプログラムを流します。
さて、きちんと音声認識してくれるでしょうか?

pi@raspberrypi:~ $ python print.py

そして、前え、後ろえ

---- replace ----
***** m a e e *****
0.994
---- replace ----
***** u s i r o e *****
0.998
---- replace ----
***** b a k k u *****
1.0
---- replace ----
***** m i g i e *****
0.976
---- replace ----
***** h i d a r i e *****
0.466
---- replace ----
***** s u t o p p u *****
0.531
---- replace ----
***** s u t a n b a i *****
0.946
---- replace ----
バルス
0.947
##### THE END #####

なかなかの認識率です。
バックのスコアなぞ、100%です。音声の認識は、たぶん大丈夫ですね。

プログラムを掲載しておきます。

#!/usr/bin/python
# -*- coding: utf-8 -*-
import socket
import xml.etree.ElementTree as ET
import subprocess
import sys
import re

def main():
    host = 'localhost'
    port = 10500

    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect((host, port))

    try:
        data = ''
        while 1:
            if '\n.' in data:

#                print data

                r_data = data.replace('\n', '@@@')
                r = re.compile("(.*)(/RECOGOUT)(.*)")

                m = r.match(r_data)
                if m != None:
                    a = m.group(1)
                    data = a.replace('@@@', '\n') + '/RECOGOUT>\n.'
                    print '---- replace ----'
#                    print data
                else:
                    print '---- None ----'
#                    print data

                root = ET.fromstring('\n' + data[data.find(''):].replace('\n.', ''))
                for whypo in root.findall('./SHYPO/WHYPO'):
                    command = whypo.get('WORD')
                    score = float(whypo.get('CM'))
#                    print command
                    if command == u'マエエ':
                       print '***** m a e e *****'
                       print score
                    elif command == u'ウシロエ':
                        print '***** u s i r o e *****'
                        print score
                    elif command == u'バック':
                        print '***** b a k k u *****'
                        print score
                    elif command == u'ミギエ':
                        print '***** m i g i e *****'
                        print score
                    elif command == u'ヒダリエ':
                        print '***** h i d a r i e *****'
                        print score
                    elif command == u'ストップ':
                        print '***** s u t o p p u *****'
                        print score
                    elif command == u'スタンバイ':
                        print '***** s u t a n b a i *****'
                        print score
                # PG終了 ラピュタ滅びの呪文「バルス」
                    elif command == u'バルス':
                        print command
                        print score
                        print '##### THE END #####'
                        sys.exit()
                    else:
                        print '----- e t c ! -----'
                        print command
                        print score
                data = ''
            else:
                data = data + client.recv(1024)
    except KeyboardInterrupt:
        client.close()

if __name__ == "__main__":
    main()


5.6脚ロボット駆動

6脚ロボット駆動用の全てのプログラムが消えてしまったので、再びダウンロードを行います。プログラム自体は、サポートページからダウンロードすればいいので、さほど苦にはなりません。
はたして、すんなり動くかどうかやってみます。その前に配線を確認します。これも、大した配線ではないので、書籍を見ながら設定します。さァ、実行します。

あれれ、エラーですね。

・
・
・
File "bb2-08-02-6legs-pca9685.py", line 36, in setPCA9685Duty3
 bus.write_i2c_block_data(address_pca9685, channelpos, data)
IOError: [Errno 121] Remote I/O error

こいつは、いつもの奴--電源が足りないようです。ですので、モーターを電源を、単3電池3本⇒4本の電池パックで代替させました。また、スマホの充電用バッテリは、使わないので、どかしました。これで実行したところ、無事に稼動しました。

6.6脚ロボット音声操作プログラムの作成

さて、こいつが最後の難関です。しかし、ここ迄来るのに、思いのほかページを食ってしまいましたので、ここで完了とさせていただき、本題は、次のpartで実施させてください。本件は、番外編と致します。すみません。

スポンサーリンク

シェアする

フォローする