2016年3月31日木曜日

irMagician と GrovePi でIoTリモコン - ブラウザ操作と音声認識によるリモコン操作 -


 ハードウェアは準備出来たので、色々と機能を載せていこうと思います。まずは、irMagician をブラウザから操作して家電のOn/Offをできるようにして、PCやVPN接続でスマホで外出先からの制御ができるようにしたいと思います。また、ブラウザ操作相当の操作を音声認識により実現したいと思います。
 この手の「Raspberry Piを学習リモコンにしてスマホ等で操作する」とか「音声認識学習リモコン」とかはすでによくやられていて、前例がたくさんあります。今回は、そういった有益な銃砲をネットに公開してくださっている先達の知恵に甘えます。参考にしたサイトを幾つか挙げておきます。感謝です。

 今回は python + tornado でサーバ側でpostを受け取って、irMagicianの json形式リモコン信号データを再生するプログラムをテスト的に作成しました。といっても、上記リンク先やネットに公開されていたコードをつなぎあわせただけですが。

 部屋の照明のリモコンとエアコンのそれぞれのOn/Off信号のjsonファイルを下記のHTML(ブラウザ)側からpostされてくる 1 or 2 ・・の文字で判定してハードコーディングで処理しています。

 スマートフォンでGrovePiにアクセスすると、次のような画面で操作できます。


 また、julius 音声認識をモジュールモードで動かして、julius 側ポート 10500 とソケット通信で音声認識結果を受け取って、ブラウザページでの操作に相当するpostを送信するような以下のプログラムも走らせます。なお、juliusには認識してい欲しい言葉だけの辞書セットを作っています。

 これで、julius -音声認識結果→ test_recognition_client.py -post→ test_irMagicianServer.py と連携して、音声で家電操作ができるようになりました。でも、静かな状態ならいいんですが、BGMとかをかけたりすると誤認識して、勝手にエアコンがOn/Off したり、突然部屋の明かりが消えたり・・・。う~ん、実用には遠い状態。認識語の組み合わせやマイク感度調整等で向上するのかな?




irMagician と GrovePi でIoTリモコン - ハードウェア準備編 -

 今回のがらくたはDexter Industries社の「GrovePi」です。



 現在、販売されているのは「GrovePi+」という新型になっていて、自分の手元には新旧一つずつあるのですが、今回使っているのは古いタイプの「GrovePi」(ATMegaがDIPタイプ)です。



 このGrovePi(+)ですが、手に入れては見たものの、割りとすぎに飽きてしまい、放置されていました・・・。だって、あんまり動きがないので・・・。
 なんでまた、飽きて放置されていたGrovePiを引っ張り出してきたかというと、なんとなく久しぶりに学習リモコンを作ってみようかなと思いついたわけです。以前にArduinoで作ったことはあったんだけどPCにUSB接続して使う形態だったのでPCの電源を切っていると、(例えば)エアコンのスイッチを入れるのにまずPCを起動するっていう・・・リモコン普通に探せばいいじゃんってなってしまう展開でした。まあ、実用的なものを作るつもりはこれっぽっちも無いわけですが、Raspberry Pi 3 発売直前でRSコンポーネントとかでRaspberry Pi 2が値引き販売していたので、つい買ってしまい、なにか使いみちがないかと考えたところ、Raspberry Piなら電源入れっぱなしにして、学習リモコンとかその他IoTハブ的な感じで、家の中なら音声認識や無線LAN経由のタブレット操作で、家の外からもVPNでスマホなどで色々コントロールできると面白いんじゃないかってことで。
 で、使ってないGrovePiに白羽の矢が立ち、はじめはGroveの赤外線リモコンモジュールを使って、lircというLinuxで学習リモコンするときに定番らしいソフトで実現するつもりでしたが、日本のエアコン等の複雑(長い)で独自プロトコルな信号は再現できない場合がある(NEC/家製協/SONYフォーマット等のある程度決められたフォーマットを前提にしているため、独自の信号形式だと上手く行かないことがる)らしく、ネットで学習リモコンについて調べていたところ、大宮技研さんの「irMagician」というのを見つけました。このirMagicianはリモコン信号を時分割したOn/Off信号として記録するため、信号フォーマットによらずに比較的柔軟に色々なリモコン信号に対応できるらしいです。そこで、途中までGrovePiで進めてきたのをirMagicianを採用する方向に変更しました。

 準備したハード構成としては、下写真のような感じです。


 Raspberry Pi のUSBコネクタに、Juliusで音声認識させるための USBマイク と irMagician を接続してあります。irMagicain は Raspberry Pi からは CDC-ACMつまりシリアルポート(ttyACM0等)として認識されます。

 irMagician の本体は、GrovePiのケース(旧タイプのBrickPiのケースを使用しています。)に固定した中華安パン・チルトカメラ台に両面テープで貼り付けて、カメラとともにサーボで方向をコントロールできるようにしました。



 ところが、ここで困ったことが一つ発覚、Groveシリーズ(元のArduino)ではサーボの制御もできるので、GrovePiでも当然できると思っていたのですが、GrovePiのドキュメントを見ると「サーボは対象外、ノイズとか面倒だから」となっていて、GrovePiでのサーボ制御が出来ないことが判明しました。しかたがないので、Raspberry Pi の UART (GPIOのTx,Rx)ポートにレベル変換をかましてGrovePi上にPISER(Pi の UART)端子というのが出ているので、このPISER端子にArduino(Sainsmartの互換機)を接続して、Arduino経由でパン・チルトのサーボを制御するようにしました。


 なんか、強引ですが、とりあえずパン・チルト駆動はできました。Arduino側のサーボコントロールプログラムは、サーボの向きを変える時だけPWM信号を出力して、あとは信号出力を停止しておくようにしました。乗っているものがRaspberry PiカメラモジュールとirMagicianだけなので、常にトルク(制御)を掛けておかなくてもサーボの向きが変わってしまう(重さで下を向くとか)ことは無いので、常にPWMをかけておく無駄と「チーッ」という発信音がサーボからたまに出るのを防ぐことが出来ます。

 irMagician に関しては、とりあえず、部屋の証明のOn/Off と Panasonic のエアコンのOn/Off は動作確認できました。Panasonicのエアコンに関しては、リモコン側に状態を持っている(リモコンの電源OnOffボタンを押すたびに本体とは関係なくリモコン側の画面・ステータスが変わる)ことに今回はじめて気が付きました。たまに、電池切れかけの時などにエアコンが反応していないのにリモコン側はスイッチがOnになったことになっていて、あれっ?て思ったことがあったんですが、今までは全く気が付かない(というか考えていなかった)でいました。たしかに、本体とリモコンが相互通信でもしないかぎり、それぞれに状態を持っていているんだから、それがずれることだってあるでしょうよと、妙に納得しました。

 ちなみに irMagician の使い方については 大宮技研さんのこの辺りの情報とか、netbuffaloさんのこちらとかこちらを参考にさせていただきました。特に、Raspberry Pi 上でリモコン信号をキャプチャ、再生、ファイル保存をするpythonのプログラムをまんま利用させてもらっています。ありがとうございます。

 また、折角なので、追加で PIRモーションセンサも追加しました。


 サーボやirMagic、各Groveセンサはサンプルプログラム等で単体の動作は一通り確認できました。Raspberry Piカメラモジュールもここらへんを参考にmjpg-streamerでブラウザから画像が見れるようになりました。あとはリモコン信号の登録、Julius音声認識の辞書設定、ブラウザ操作のための仕組み構築といったあたりですが、最後のブラウザ操作でGPIOをどんな仕組みでやるか検討中です。GrovePi が pythonのサンプルが豊富なので pythonのtornado でやるか、node.js でやるか(一応GrovePiに node.js用のライブラリも提供されているみたいですが、サンプルが少ないので、どっちの知識も薄い自分的には python のほうがとっつきやすそう。)



 
 



2016年3月20日日曜日

Dexter Industries GoPiGo 組み立て

 今回のガラクタは Dexter Industries社の GoPiGo です。


 Raspberry Pi + ATMega328 (Arudino相当) で構成される車輪ロボットで、モータ・タイヤ・アクリルのフレームと ATMega328 の載った基板等でキットになっています。

 パッケージ。


 開けたところ。


 ボディはDexter Industries お得意のいつものアクリル板をレーザ加工したものとネジ、支柱での組み合わせです。まずは、底板にギアモータを取り付けます。ギアモータはaitendo等でも売っている中華製のあれです。格安ですが両軸出ています。

 ギアモータは底面板にネジ止めするのではなくアクリルのT字型の小さな板で挟みこむような形でギアモータに空いている貫通穴と一緒に長いネジを通してナットで止めるのですが、自分はここを足回りなのでキツ目に締め込んでおこうと思ってドライバで締めた際に「ミシッ」という嫌な音がして小さな板にヒビが入ってしまいました。Dexterの組立てビデオを後から見たのですが、ここはドライバを使わず手でナットを締める程度にしておくみたいです。走らせた時ゆるまないのかな?


 ギアモータの内側の軸にスペーサ2枚とエンコーダ円盤を挿しこみます。ここもネジ止めなどはなく、挿すだけです。子供でも作りやすいようにドライバでのネジ止めも最低限にしてあるってことでしょうか。


 ひっくり返して、底板の上面に制御ボードを取り付けます。この制御ボードにはATMega328Pが載っていて、ファームウェアはArduinoのスケッチとして作成されているようです。GoPiGo は他のDexter Industries社製品同様に各種情報がオープンソースで提供されています。GoPiGoはこちらのGitHubに情報が公開されています。BrickPi や GrovePi も同様に Dexter Industries社はオープンにしてくれているのには感謝です。(Mindsensors社も各種センサの設計情報公開してくれないかな?)
 ちなみにGoPiGoの主なハード構成を回路図から見てみると、前述のとおり RPi と制御ボード上のATMega328P (ファームウェアを見るとArduinoのスケッチ、~.inoになっています)がやり取りをする構成です。回路図を見るとRPiとArduino(制御ボードのATmega328P)がUART、I2C、SPIでそれぞれ接続されているように見えますが、RPi側のライブラリとArduino側のスケッチを見ると RPi がI2CマスタでArduino側がI2Cスレーブとなっているようです。SPIとUARTの接続はArduino側のファーム書き換え用ではないでしょうか。また、モータのドライブはArduinoのPWM出力を HブリッジのICに入れているようです。また、フォトインタラプタの間にエンコーダ円盤を挟んでカウント信号をArduinoのInterrupt入力端子で受けているようです。


 次にボールキャスタを取り付けます。あとで気がついたんですが、上の写真はボールキャスタを前後間違えて取り付けています。ちょうどいい穴があったので画像向かって左側に間違って付けてしまいましたが、最終的に右側に取り付け直しています。


 制御ボードにRaspberry Piを裏返した状態で取り付けます。ボールキャスタの位置を取り付け直しています。


電池ボックスをマジックテープで取り付けます。


 裏返したところ。


 Raspberry Pi のOSはRaspbianをDexter Industries社がカスタマイズした Raspbian for Robots をダウンロードして使いました。
 続けて、ライントレース用センサオプションを取り付け。


 やっぱり、アクリル板と支柱の組み合わせ。


 こんな感じで取り付けられます。


 続いて、サーボマウント(パン=水平方向の首振り)オプションを取り付け。


 アクリル板とネジ・・・。


 組み立てて、Raspberry Piのカメラモジュールを取り付けました。


それと、Groveの超音波センサを両面テープで取付。


 これで、とりあえず、ハードの組み立ては終了です。


 さて、何をして遊ぼうか?