期限切れの無線ルーターを上手に使う

昨夜、事務所(松竹芸能)のネタ見せが角座であった。なんと、無線ルーターにロボットが接続できず、ネタを披露できないというロボットをネガに使い始めて初めての大失態を犯した。多分で、伝説になると思う。

その原因は、先月まで2年間使っていたWIFIのルーター(左)が、契約切れで、新しいものを契約せず、簡易なWIFIルーター(右)を使ったことだ。

おそらく、簡易WIFIの電波が弱く、ちょっとの移動でロボットとの接続が切れてしまったためだと思う。外から、劇場にロボットをルーターと接続したまま持ち込むのだが、その途中に切れてしまったのだ。もっと十分なテストをすべきだった。

帰りながら、前のルーターは、ローカルにロボット同士をつなぐのには、別に契約が切れても大丈夫なのではないかと思いついた。こちらは、ローカルの配信に使う電波は十分に強いだろう。

契約切れでも、案の定、ローカルのロボットもパソコンもスマホも、相互接続を難なく繋げることができた。しかも、インターネットに接続したWIFIにつなぐことができることもわかった。自宅のWIFIモスマホのテザリングも繋ぐことができた。

しかも、こちらの方は電波が強く安定していることは間違いない。これでいける!!

2019年3月7日:結局どちらも使いもにならないことがわかった。一応繋がるが、安定しない。繋がらない状況や接続の切断が発生する

Google Cloud Platform のSpeech Recgnitionで日本語音声ファイルをテキスト化

Google Cloud Platform の提供するSpeech Recgnition機能の初歩的なものがなんとか動かせたので、記録のためにここに記載しておく。
実際やってみて、googleの人工知能、すごかったという感じです。
基本的に、
https://cloud.google.com/speech/docs/rest-tutorial
にある、「REST API 音声認識チュートリアル」のPythonプログラムを動かして、手元にある日本語の音声データをテキスト化しただけなのですが、これまで色々失敗してきたのでできたときは感激でした。
まず、結果をお示ししましょう。ユニコード化されて送られてきたんですが、返された日本語テキストは次のようなものです。
「私は鷲田豊明と申します今日はお切りについて皆さんにちょっとお話したいと思うんですがロボットに大喜利をやらせると本当にかん可能でしょうか難しいんじゃないかなと思っていますでも挑戦してみますよ」
まちがっているのは、最初の方の大喜利とすべきところを「お切り」としてしまっているところ、ただの「可能」を「かん可能」としてしまっているところくらいですね。あとは、噛みながら話したのですが、ほぼ完璧に日本語テキスト化しています。
やるべきところを記載しておきます。基本的に上記のページに書いてあることなのですが、私なりの表現にすることによって、別な見方が提供されわかりやすくなるんじゃないかと思います。
基本、MAC用の話である。
(1)Google Cloud Platformに登録する。きちんと支払い情報も入れておく。60日の間に¥34,542.00分の利用権利もタダで与えられる。有料化されても、それほど高いものでもない。
(2)プロジェクトを作成する。
(3)認証情報を作成のところで「サービスアカウントキー」を選択すると、認証情報を組み込んだファイルがダウのロードされるので、それを確認する。あとで、プロジェクトIDとキーファイルが必要になる。
(4)pythonでやるので、当然pythonが入っていなければならない。他にも、Node.jsでもできるようだが試していない。pipもインストールされている必要がある。
(5)チュートリアルに書かれていないのだが、python用のgoogle-api-clientが必要なので以下のようにしてインストールしておく。
$ sudo pip install --upgrade google-api-python-client
(6)音声ファイルを用意する。rawが使われている。私は、iPhoneで録音し(MacBookでもできるのだが、iPhone7plusの方がいいような気がしたので)、それをiTunesを使ってwavファイルに変換し、最後にsoxを使ってrawファイルに変換した。rawへの変換は、
$ sox testrec.wav testrec.raw
(7)認証関係の設定をする。まず、先ほど作成したサービスアカウントキーファイルのありかを環境変数に記録する。
$ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service_account_file.json
pathの部分を自分のパス、最後の、service_account_file.jsonの部分は自分がつけたファイル名にする。
$ export GCLOUD_PROJECT=your-project-id
プロジェクトIDは、自分のコンソールで確認できる。一連の数字ではなく、名前である。
(8)チュートリアルにあるpythonプログラムを、テキストファイルでテキストファイルにする。基本的に変えなくて良いが、1箇所だけ言語設定のところを次のようにかえる。
'languageCode': 'en-US',  # a BCP-47 language tag

'languageCode': 'ja-JP',  # a BCP-47 language tag
にする。つまり、英語を日本語にするのだ。
(9)実行。
$ python tutorial.py testrec.raw
とする。すると、数十秒かかるが、次のような結果のJSONファイルが帰ってくる。
{"results": [{"alternatives": [{"confidence": 0.8346436, "transcript": "\u79c1\u306f\u9df2\u7530\u8c4a\u660e\・・・中略・・・\u6226\u3057\u3066\u307f\u307e\u3059\u3088"}]}]}
83%の正確さの結果だ。このユニコードを適当なサイトを利用して日本語に変換する。私は、
http://www.kwonline.org/u_esc_seq.php
を使わせていただいた。そして、上記の結果が得られたのだ。

iBotNaoのスマホからの制御にアプリ不要

誤解されるといけないから書いておく。iBotNaoによって、ロボットのパフォーマンスのほとんどの制御がスマホからできることになったが、スマホのアプリは一切いらない。単に、インターネットブラウザがあれば良い。

iBotNaoがほぼ完成!!スマホとロボットで全てができる!!

iBotNaoは、ロボットの内臓ウェッブサーバー上に、ibotシステムを動かして、ibotシステムがもともと持っていたロボット制御システムを全て外部のウェッブクライアントから可能にするシステムだ。
したがって、すべて、スマホで管理できる。パソコンは不要だ。iBotのc++で作成した組み込みライブラリのほとんどの機能がスマホから使えるようになった。
最後まで手がかかった、ローカルからロボットへのテキスト、サウンドファイルの転送が、htmlのcgiでできるようになったので、完成と言える出来栄えになった。
外で、ロボットのパフォーマンスを見せるときも、ノートパソコンは要らないのだ。スマホにテザリングの機能があればwifiルータもいらない。ただ、wifiは、何かとトラブルがらみなのであったほうがいい。
iBotNaoでできることの概略を書いておく。
(1)スクリプトの作成、編集、転送など。スクリプトとは、ibotコマンドを書き込める対話用のtopicスクリプト、ロボットの行動や発声を一連のコマンドとして管理できるスクリプト、また、その中で制御可能なサウンドファイル(mp3,wav)も転送管理できる。
(2)対話の制御。ibotの最大の特徴は、全て対話でロボットを制御(行動も対話も)できることだ。どのトピックファイルを使って対話を開始するか、対話の開始と停止、ロボットへ対話への強制入力なども可能である。
(3)ステータス管理。ロボットの停止、休息、覚醒、強制発話、ビップ音制御、ASR認識値制御、音声レベル制御、ロボットの全体的状態表示など。
(4)動作と発話の直接制御。前進後退などの前後左右ななめなどの動き、回転、などを画面のタッチでコントロールできる。同時に発話も、リストに沿って適宜送り出すこともできる。自動制御のコントロール。
(5)複数のロボット同士のコミュニケーション機能である、テレパシー機能の制御。
これまでは、ロボットをライブの舞台にあげるときに、ロボット自身がちゃんと動くかだけではなく、ノートパソコンが不調になったら、ibotのシステム起動ができず、どうしようもなかったのだが、これで、スマホさえ持っていれば、パソコンが壊れても大丈夫だ。不安が減少した。

NAOのnginxでC++のcgiを動かす手続き

NAOの内蔵ウェッブサーバーのnginxでC++で作成した実行ファイルをCGIとして動かす手続きが理解できたので、メモがわりに書いておく。
(1)ヴァーチャルなNAOであるopen-naoにlibfcgiの一連のツールをインストールする。(open-naoについては、aldebaranのサイトにインストールに仕方があるので省略)私は、libfcgi-master.zipをとってきて、
./configure
make
sudo make install
で、インストールしたが、他にもfastcgi++-2.1.tar.bz2なんかでもできそうだがやっていない。
(2)spawn-fcgi-1.6.4.tar.gzを取ってきて、
./configure
make
する。私は、ubuntuの32ビット版の方でやってしまったが、open-naoの方でもできると思う。インストールしなくてもよい。
srcフォルダにspawn-fcgiができているので、そのまま、open-naoに持ってきた。open-naoで作ったら当然、そのままでいい。
このspawnは、c++で作成した実行ファイルを、nginxからのリクエストに応じて、実行させるための媒体のようなものだ。
(3)open-nao上で実行ファイルを作成する。(32ビット版だからといって、ubuntuで作ると、libcのバージョン違いで失敗してしまった)
この辺りのことは、
http://chriswu.me/blog/writing-hello-world-in-fcgi-with-c-plus-plus/
に決定的に依存している。このページがなかったら、nginxでfastcgiを動かすイメージが、全く湧かなかったと思う。とても優れたページだ。
そこにサンプルがあるから、open-nao上で、nanoエディタで作成してコンパイルすると良い。なにしろ、open-naoには、開発環境が一通り揃っているし、ロボットと同じ実行環境が約束されている。なお、open-naoとPCとのファイルの転送は、psftpを使う必要がある。
(4)つぎに、naoのnginxの設定ファイルをいじる。設定ファイルは、/etc/nginxの中の、nginx.confに書かれている。(万が一のため、オリジナルのnginx.confをnginx.conf.orgなどにコピーしておく)
設定ファイルのなかに、次の行を加える。
location ~ \.cgi$ {
fastcgi_pass 127.0.0.1:8000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
この意味は、cgiという拡張子がついたファイルへのアクセスは、ローカルの8000版ポートで待機している実行ファイルを起動させることにする、というものだ。
(5)ロボット内でnginxを再起動する。
/etc/init.d/nginx restart
でよい。エラーがなければ問題ない。
(6)次に、(1)で作成したライブラリの/usr/local/lib以下にある、libfcgiで始まるファイルを全部zipなどでアーカイブして、nao本体に送り込む。そして、/usr/local/lib以下に同じように解凍する。その際、シンボリックリンクが壊れているので、もとの、open-naoの/usr/local/lib以下でのシンボリックをそのまま再現する。
(7)c++で作成したcgiの実行ファイル、例えば、foobar.cgiを
spawn-fcgi -p 8000 -n foobar.cgi
と立ち上げる。
(8)ロボットの外から、アクセスすれば、foobar.cgiが実行される。たとえば、上記のサイトにあるように、curlを使えば、

> curl -d "Chris" http://localhost/foobar
<html>
  <head>
    <title>Hello, world!</title>
  </head>
  <body>
    <h1>Hello Chris from /foobar !</h1>
  </body>
</html>

という感じで出力される。

トピックファイル中の命令変数と引数(1)動作編

iBotのシステムは、トピックファイルを中心にしている。対話の中で様々な動作を入れたり、顔を認識させたり、テレパシーを相手に送ったりするなどの機能は、すべてトピックファイルの記述されている。そして、その基本は、変数であり、変数の名前、変数の引数がいろいろな意味を持っている。
今回、関節を独立に自由に動かすための、コマンドをトピックファイルの中に入れるに当たって、引数の与え方を拡張する。それにあたって、いままで、様々な機能を組み込んできて、複雑になっているので、まず、これまでの方法を整理しておこうと考えた。
(動作)
動作については、トピックファイルの中に、$ファイル名_動作タイプ_番号=1
(※ 二つのアンダースコアーで区切っている。したがって、トピックファイル名にアンダースコアを使ってはならない)
という形で入れることを基本にしていた。
QiChatのトピックファイルの変数は、無条件でグローバル変数になるので、複数のトピックファイルを有効化したときに、名前のバッティングが問題になるのでファイルの中での一意性だけを考えれば良いようにしている。
動作タイプは、
walk
navi
sitdown
standup
lyingback
crouch
をさしあたって組み込んでいる。このうち、walk とnaviについては、引数が必要である。
たとえば、walkの変数が、$testfile_walk_001である場合、次のようなコメント文をトピックファイルの中に組み込む。
## <ibot motion walk>testfile_walk_001,0.5,1.2,30</ibot motion>
これは、前方50cm、左方向1.2mに左に30度回転する形で進むということになる。(実際、方向と回転を同時に指定すると動きが複雑になって思うようにいかない場合が多かった。)
対話の本文の中に、
$testfile_walk_001=1
と入れたところで、歩行が実行される。
引数のいらない歩行のポーズコマンドは、そこに値1が代入された時点でポーズの実行動作に入る。たとえば、
$testfile_sitdown_001=1
と会話本文に入っていれば、座る動作をする。
(動作終了イベント)
一般に、動作が終わると、また次の対話、あるいは動作に入るので、iBotの動作変数については、終了後のイベントを自動的に登録している。たとえば、先の$testfile_walk_001=1というイベントが終了するとdid_testfile_walk_001というイベントが自動的に発火する。それを捉えるためには、たとえば、
u:(e:did_testfile_walk_001) 次は何をしましょうか。
と会話文を置いておくと、動作終了時に「次は何をしましょうか」とロボットが喋ることになる。
(次回は、顔認識のためのトピックファイル)