概要
Raspberry PiにつないだフルカラーLEDをjuliusでの認識結果に応じて操作させることにチャレンジし、無事操作させることができた。
背景と目的
前回、認識させたい言葉を自分で定義し、それが認識されることが確認できた。そこで、今回はその仕組みを利用し、Raspberry PiにつないだフルカラーLEDを操作できるようにPythonスクリプトを作成し、動作を確認する。
詳細
他のプログラムでjuliusとやりとりするには、こちらによればjuliusをモジュールモードと呼ばれる音声認識サーバとして動かせばよさそう。なので、まず以下のシェルスクリプト(start_julius.sh)を作成。Juliusサーバをバックグラウンドプロセスにし、標準出力にプロセスIDを出力させる。また、起動直後サーバ接続するとエラーになるので時間稼ぎのsleep。
julius -C ../julius-kits/dictation-kit-v4.3.1-linux/word.jconf -module > /dev/null & echo $! sleep 3
次に、Pythonスクリプトでは、subprocessモジュールを使って上記シェルスクリプトを実行させる。最後に、killを実行してjuliusのプロセスを殺す。
import subprocess # julius起動スクリプトを実行 p = subprocess.Popen(["bash start_julius.sh"], stdout=subprocess.PIPE, shell=True) pid = p.stdout.read() # juliusのプロセスIDを取得 : : p.kill() # 起動スクリプトのプロセスを終了 subprocess.call(["kill " + pid], shell=True) # juliusのプロセスを終了
juliusの出力をPythonでもらうには、Pythonのsocketモジュールを使えばよいらしいので、こちらを参考に以下のようなコードを書く。Dataという変数に、参考1にあるようなXML形式の文字列が入ってくるので、それをPython側で適当に処理すれば認識結果が取得できるだろう。
import socket HOST = "192.168.11.7" # アドレス PORT = 10500 # ポート # TCPクライアントを作成し接続 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect((HOST, PORT)) # サーバの応答を受信 data = client.recv(1024)
最後に、ラズベリーパイにつないだフルカラーLEDを操作。LEDは、図3.1のようなもので、GPIO17,27,22をHIGHにすればRGBそれぞれが点灯できるようにしてある。

図3.1 ラズパイにつないだフルカラーLED
1,2の要素を組み合わせて作成したPythonスクリプトは以下。Dataという変数に入ってきたデータのうち、RECOGOUTという要素をXMLとしてパースし認識されたワードを取り出している。赤、青、緑、白、消灯の5種類に反応できる。
# coding:utf-8 import socket import subprocess import xml.etree.ElementTree as ET import RPi.GPIO as GPIO HOST = "192.168.11.7" PORT = 10500 PORT_RED = 17 PORT_GREEN = 27 PORT_BLUE = 22 colors = { u"赤" : [True, False, False], \ u"緑" : [False, True, False], \ u"青" : [False, False, True], \ u"白" : [True, True, True], \ u"消灯" : [False, False, False] } GPIO.setmode(GPIO.BCM) GPIO.setup(PORT_RED, GPIO.OUT) GPIO.setup(PORT_GREEN, GPIO.OUT) GPIO.setup(PORT_BLUE, GPIO.OUT) def changeColor(colorName): GPIO.output(PORT_RED, colors[colorName][0]) GPIO.output(PORT_GREEN, colors[colorName][1]) GPIO.output(PORT_BLUE, colors[colorName][2]) print colorName def main(): # julius起動スクリプトを実行 p = subprocess.Popen(["bash start_julius.sh"], stdout=subprocess.PIPE, shell=True) pid = p.stdout.read() # juliusのプロセスIDを取得 # TCPクライアントを作成し接続 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect((HOST, PORT)) # サーバからのデータ受信と try: data = "" while 1: if "</RECOGOUT>\n." in data: # RECOGOUT要素以下をXMLとしてパース root = ET.fromstring('<?xml version="1.0"?>\n' + data[data.find("<RECOGOUT>"):].replace("\n.", "")) # 言葉を判別 for whypo in root.findall("./SHYPO/WHYPO"): if whypo.get("WORD") in colors.keys(): # 判別した言葉に応じて色を変える changeColor(whypo.get("WORD")) else: print "Unknown" data = "" else: data = data + client.recv(1024) except KeyboardInterrupt: # CTRL+Cで終了 print "KeyboardInterrupt occured." p.kill() # subprocess.call(["kill " + pid], shell=True) # juliusのプロセスを終了 client.close() GPIO.cleanup() if __name__ == "__main__": main()
プログラムを実行し、声を発すると、無事5種類の言葉を正しく認識しLEDの色が変わった。非常に簡単なものだが、音声で操作できる装置が作れた!
まとめと今後の課題
今回のjuliusのお試しを通じて、Raspberry Piを使った音声操作できる装置を作れる可能性が広がった。これを使えばなかなか面白い装置が作れそう。今後も、いろいろなアイディアを試してみたい。