この記事はCAMPHOR- Advent Calendar 2016の14日目の記事です。
こんにちは @siriusjack です。去年に引き続き HOUSE ネタを今回も投稿してみたいと思います。CAMPHOR-HOUSE の照明は OB からの寄贈により一部 Philips Hue が採用されています。この照明を取りまとめている親機には REST API が用意されており外部からHTTP経由で照明の状態を変化させることが可能なため、昨年は Slack CAMPHOR- の Slack に bind されている Slack + Hubot 経由で on/off 操作を行ってみました。今年はその操作を音声認識経由で行ってみたのでその内容を一部紹介します。
動機
HOUSEの照明はもともと Slack 上の Hubot 経由で操作可能ではありますが、その操作が日常使いでは少々面倒だと感じる部分が多かったというのが一番の動機です。例えば、夜に HOUSE の戸締まりをして帰る際、今までは以下の作業が必要でした。
- 携帯をポケットから取り出す
- Slack を起動する
- HubotがListenしている適当なChannelを探す(e.g. playground)
bot lights off
コマンドを入力
この作業が音声認識になれば
- HOUSEに向かって話しかける
に短縮できて楽なのでは?というのが今回検証してみたかったことです。
全体の構成
ざっくりした全体の構成と対応する機器を以下に載せます。
ソフトウェア
- 音声認識エンジン: Julius
ハードウェア
- Main board: Raspberry Pi 2
- USB Microphone: サンワサプライ MM-MCUSB21BK
処理の流れは以下です。
- 音声認識エンジン (Julius) により HOUSE 内の音声から認識結果を出力
- 認識結果のストリームの中から照明操作に関わる内容があれば抽出
- 抽出内容に応じて Philips Hue の REST API を叩く
では、実際に行った作業に移りましょう。
セットアップ
まず、Julius を使って HOUSE 内の音声から音声認識結果を生成します。Julius は-module
オプションを付けて起動すると音声認識内容を\n.\n
区切りのxmlで出力し続ける tcp server として動作させることができます。デフォルトではport#10500で接続を待ち受けて接続があると認識結果をその都度出力し続けてくれます。この出力を適当に処理して正規化しパターンマッチにより人間が求めているコマンドに対応付けることが今回のゴールになります。
具体的にはまず認識してしてほしい用語を Julius に登録し、登録した用語が検出されたタイミングで対応するコマンドを発行し、Hueを点けたり消したりします。
音声認識には Julius のには以下のような単語リスト(word.list)を登録しました。
s
il [] silB
sil [] silE
sp [] sp
ボット [ぼっと] b o q t o
ホット [ほっと] h o q t o
ボットライトオン [ぼっとらいとおん] b o q t o r a i t o o n
ボットライトオフ [ぼっとらいとおふ] b o q t o r a i t o o h u
ライト [らいと] r a i t
コーヒー [コーヒー] k o: h i
実際に辞書を用いて julius をモジュールモードで実行すると例えば以下のような出力が得られます。以下は試しに得られた出力をそのまま表示してみたものです。
この結果を適当にparseして利用してみましょう。
そこで次の段階として、以下のような Python Script を用いて、Julius の出力が順に得られる stream
から音声認識内容を表す <WHYPO/> 要素のみを取り出し、Attribute を整形して json で出力する以下のフィルターを作成してみました。
1 2 3 4 5 6 7 |
def filter_recognout(stream): reg = re.compile(r'WHYPO WORD="(.*)" CLASSID="(.*)" PHONE="(.*)" CM="(\d\.\d{3})"') for msg in stream: match = re.search(reg, msg) if match: word, cid, phone, cm = match.groups(1) yield json.dumps({'word': word, 'cid': cid, 'phone':phone, 'cm': cm}, ensure_ascii=False) |
これを適用すると以下のような出力が得られます。
ここまで来ればあとは認識された言葉に応じてコマンドを実行すればOKです。今回は”ボットライトオン”で照明ON、”ボットライトオフ”で照明OFFのAPIを叩く設定にし、実際に稼働させてみることにしました。今後しばらく使ってみて新たな気付きがあれば追記してみたいと思います。
またもし実装の詳細が知りたい場合は今回作ったものを以下に公開しておきますので、よければ参考にしてみてください。
https://github.com/siriusjack/house_vcontroller
次はKojiAomatsuの記事です。明日もお楽しみに。
参考サイト
http://usicolog.nomaki.jp/engineering/raspberryPi/raspberryPi_Julius.html
http://d.hatena.ne.jp/penkoba/20130928/1380351297