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

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

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

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

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

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

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

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

iBotシステムの改訂

ネタのために動かしているシステムは、iBotシステムである。この基本コンセプトは「ロボットは対話で動かす」というものだ。Naoを購入した一番最初からこの思想を貫いている。5年近く続けていることになる。iBotシステムは、wsibotというモジュールを中心に組み立てられている。複数(6、7個?)のモジュール(C++で書かれたライブラリ)がロボットに組み込まれている。

ただ、長年付け加えられたり変化してきているので、ほとんど使わなくなった機能もたくさんくっついている。そのために、全体が見えにくく、扱いにくくなっている面がある。

もう一度、整理して使いやすくしたい。全面的な改訂が必要になる。シーケンスのモジュールもできて、会話から動作、知的処理、ネタなどほぼ一通り揃えたので、この際、やってみようと思う。

Qichatでヴァーチャルなif文を作る(1)

(※ 次の(2)で、単純に説明します、笑)

ロボットは対話で動かすというのが、私の確信だ。NAOを動かすときは、基本Qichatで書かれたtopicファイルに、自作ライブラリを起動するための独自コマンドを埋め込んで、制御する。

この間、一つのスクリプトで、即興漫才と即興謎かけのネタを切り替えるようにした。このスクリプトは、お題として識別できる語数は20000万語を超えている。それも、Qichatに書かれている。

ここで問題は、Qichatの変数 $manzai の値が1の時は、もらったお題に対して即興漫才を実行し、それが0の時は謎かけをするようにしたい。しかも、お題として認識できるのは、標準でこれまで作成したコンセプト2500語に引っかかるのか、その後拡張した18000 語の方に引っかかるのかということがある。混ぜていないのだ。

当初は以下のような書き方をしていた。

u:(お題は _~manzai_concepts です) $manzai==1 $1 ですね。少しお待ちください。 $sub_main=$1 $telepathy_to_emily="emily_getmanzai_subjects/$sub_main"
u:(お題は _~manzai_extended_concepts です) $manzai==1 $1 ですね。少しお待ちください。 $sub_main=$1 $telepathy_to_emily="emily_getmanzai_subjects/$sub_main"
u:(お題は _~manzai_concepts です) $manzai==0 $1 ですね。少しお待ちください。 $sub_main=$1 $telepathy_to_emily="emily_getnazokake_subjects/$sub_main"
u:(お題は _~manzai_extended_concepts です) $manzai==0 $1 ですね。少しお待ちください。 $sub_main=$1 $telepathy_to_emily="emily_getnazokake_subjects/$sub_main"

ロボットの出力文の中に、条件式を入れている。何が違うんだということになるかもしれない。$telepathy_to_emilyというのは、私のライブラリ ibotライブラリのコマンドであり、emilyというのは制御コンピュータの名前で、それに対してお題を送っている。コンピューターからは、作られたネタの要素がこれも、telepathyコマンド(Qichat的にいうとイベント)で返されてくるのだが。つまり、私のibotシステムでは、ロボットとロボット、ロボットとコンピュータの、ローカルネットを経由したやり取りは、すべてテレパシー機能として実現している。それで、お互いのデータのやり取りも2000バイトまでは日本語でもできるようになっているのだ。

Qichatに戻ろう。後の二つが謎かけの、標準コンセプトと拡張コンセプトの場合である。$manzai==1というのは、$manzaiの値が1の時だけ真となる。

Quichatのロボット出力に、一つでも真でないものがあると、その全体が出力しないという機能を使っている。$manzaiが1の時は、前二つのいずれかにマッチングし、そうでない時は、謎かけの後者二つのいずれかにマッチングするはずだった。

しかし、これはうまく機能しないかった。細かくは調べていないが、考えられるのは、Qichatは、マッチングしているイベント処理ステートメントのどれか一つでも偽の文があると、たとえ真の文があってもそれを実行しないということだ。

たとえば「お題はチューリップです」という拡張コンセプトのチューリップに一致した入力文(イベント文)が、漫才と謎かけで二つある。$manzaiが1ならば、漫才の文にだけ一致すると思うのだが、全体が偽となって、実行しなくなってしまうということだと思う。

そこで、まず、次のように改良した。

u:(お題は _~manzai_concepts です) $1 ですね。少しお待ちください。 $sub_main=$1 [ $getmanzai_script=1 $getnazokake_script=1 ]
u:(お題は _~manzai_extended_concepts です) $1 ですね。少しお待ちください。 $sub_main=$1 [ $getmanzai_script=1 $getnazokake_script=1]
u:(e:getmanzai_script) $manzai==1 $telepathy_to_emily="emily_getmanzai_subjects/$sub_main"
u:(e:getnazokake_script) $manzai==0 $telepathy_to_emily="emily_getnazokake_subjects/$sub_main"

ポイントは、初めのロボット出力文の最後に、オプション処理の [ ] でくくっって、のちの、テレパシー送信文の漫才と謎かけのいずれかを実行するようにしたのだ。

これでいいかと思った。実際、ちゃんと謎かけのお題を与えると、パソコンにデータを送信し、回答をもらうようになった。そして、ネタ見せもこれでやった。

ただ、問題があることもすぐにわかった。たとえば、漫才の一つ目のお題をもらって実行する。それはちゃんとやる。しかし、それを終えて、もう一つお題をもらう。すると、「〇〇ですね、少しお待ちください」と言ったあと黙ってしまうのだ。そういう時は、もう一度お題を伝えると、今度はちゃんとテレパシーを送ってパソコンからの回答ももらう。

それで、さっき原因がわかった。 [  ] のオプションオペレータを使ったからなのだ。つまり[ ]がロボットの出力に与えられると、実行するたびに、一つずつ変わるようになっている。だから、最初のお題は、漫才用に対応するが、次にまたお題をもらうと、次の謎かけの処理をしてしまうのだ。

結局!!この [ ] を外したら思う通りの処理するようになった。 [ ]を外すと、選択せずに毎回両方実行する。その先のイベント処理の出力の中に、真があろうが偽があろうが関係なしに実行するのだ。だから、$manzaiが1の時は、つねに偽になっている、謎かけは実行されずに、漫才の処理だけが実行されるのだ。

あまりに単純なことで、笑ってしまいそうなくらいだった。

Mysqlにログインできなくなって

ロボットの対話関係の知識データは、基本的にいつでも持ち運んでいるmacbookのmysqlデータベースに入れている。ここから、ロボットも必要な情報を取ってくるし、決定的に重要なデータベースなのだ。
数時間前に急にログインできなくなった。あせった!!久しぶりにbookを再起動したのがきっかけか、なんなのか、よくわからないが、rootでもユーザーでも正しいパスワードを入れてもaccess denyになってしまう。
まさに、今日、ロボットのネタでこのデータベースを使うという時に。
2時間ほど悪戦苦闘した。結局何が何だかわからないのだが、やったことといえば、mysqlが入れていあるフォルダーがあって、そのデータ部分を実際、使っていたであろうデータに移し替えた。少し詳しく言えば、古いバージョンのmysqlmのフォルダーに、使っていたdataフォルダがあって、シンボリックされている新しいバージョンのmysqlのフォルダのdataフォルダは使っていたデータが入っていない。そこで、古いバージョンのdataフォルダーを新しい方に移して、オーナーをもとどおりに変えたりしたのだ。OSの方のrootになってだ。そのあたりは複雑なのだが。
そんなことを、色々やっているうちに、再起動すると、不意に戻った。ログインできるようになった。バンザーイ!!
すぐさま、今のデータベースのデータをmysqldumpで全てバックアプした。

ibotのライブラリにタイマーコマンドを加える

ロボットと何かパフォーマンスをやっているときに、尺が気になる。時間切れで失格ということが実際にあるからだ。そこで、対話システム用のコマンドに、タイマーコマンドを作成した。
トピックファイルの中に、
$wscom_starttimer_1=タイマー秒数
をいれると、それが実行された段階で、指定秒数のタイマーがスタートする。時間が来ると割り込みイベントが発生するので、それを、トピックファイルのイベント関数で、たとえば、
u:(e:TIMEOUT) 時間が来ました
のように、しておけばよい。
途中でタイマーを止める時は、
$wscom_stoptimer_1=1
をトピックファイルに埋め込んでおけば良い。

ldtexeの廃止

一連の動作及び発話を記述したコマンドリストファイルをロードし、対話の中の与えられたタイミングで実行する ldtexeを廃止する。同じコマンド ldexeがあるので不要だ。両方可能にしようかと思ったが、逆に混乱するので。
ldtexeは、ロボットの対話でコマンドリストを作り上げていくモードとトピックファイル中に埋め込むモードで、ロード&実行関数を区別していたのだが、区別が不要になって、意味がなくなっていた。

ロボット植え込みiBotは、ほぼできた

途中、ロボットのウェッブサーバーをapache2にしようかという迷いがあったが、結局、originalのnginxを使った。これからは、本番は、スマホだけで全て処理できる。
こちらに何か支障があれば、今まで通りノートブックのサーバー上のiBotでもコントロールできるので、セキュリティが高まった。
ロボット植え込みiBotの弱点は、パソコンからのファイル転送をftpなどに頼らなければならないところだ。これも、nginx用のfcgiを使えるようになればなんとかなるので、しばらくそれに取り組みたい。
それが終わったら、 クラウドの人工知能機能を利用する段取りに入りたい。

apache2のcgiから、naoqiのロボット制御モジュールを呼び出す

ALTextToSpeechを呼び出して「こんにちわ、サリーです」とロボットに言わせる単純な、cgiをC++で作った。NAO(名前がサリー)に組み込んだ、apache2のcgiとして、外部のpcからアクセスすると、ちゃんとロボットは喋った。
qimessaging.jsの代わりに、qimessaging.cgiをC++で作れることはほぼ間違いがない。ALbrokerを使えば、汎用性の高いcgiにすることができるはずだ。
急いで作ろう。

qimessaging.jsの代わりになるcgi実行ファイル

埋め込みサイトで、apache2も正常に機能し、先に作成したファイルアップロード受け口用のC++で書いたcgiファイルも正常に実行されることが確認できたが、肝心のqimessaging.jsがうまく機能しない。呼び出し中に、ソケットIDがらみのエラーが出る。そのとのサーバーからの呼び出しでは問題なく機能していたのだが。
色々やれば、解決できるのかもしれないが、ふと、そこまでqimessaging.jsに位存在なければならないの??という疑問がふつふつと湧いてきた。ロボットのローカルでサーバーが動いている、C++で書いたcgiの実行ファイルも正常に動く。ロボット内部のライブラリ(システムのも、こちらで作成したもの)も問題ない。だったら、C++で書いたcgiの実行ファイルから、直接、ライブラリのメソッドを呼び出せばいいのではないか??
ふと、それをpythonで書こうかと思ったが、いやいや、それは面倒だ。直接C++で書けば良い。brokerを使えば、コンパクトで汎用性のあるものが作れるのではないかという気がしてきた。

ロボットnaoにapache2ウェッブサーバーをインストール

前に書いた理由で、新たにnaoにapache2をインストールすることにした。手順をメモがわりに書いておく。
(1)apache2の最新版をダウンロードする。ここでは、apache2-2.4.25を使った。
(2)opennaoバーチャルロボットにpsftpなどで転送し、解凍する
(3)解凍したフォルダで、./configure --prefix=ロボット上のインストールしたいフォルダの指定する。私は、rootじゃなく、naoで実行したいので、/home/nao 以下のフォルダを指定した。
(4)普通にmakeとmake installを実行する。エラーは出ない。
(5)インストールしたフォルダごとアーカイブし、naoの実機に転送する。
(6)httpd.confを編集する。私の場合は、portを80から8080に変更。変更しないと、通常のrobotページとバッティングするので。cgiを動かす設定、ドメイン名がコメントアウトされているのをそのまま外す。関係のないドメイン名になっているが、コメントアウトするとスタート時に警告が出るを避けるだけの目的。
(7)ただ、これだけでは、apachectl startとやるとライブラリがらみのエラーが出て、実行できない。そこで以下の操作をやる。
opennaoの/usr/libディレクトリから、次の二つのファイルを取ってくる。
libaprutil-1.so.0
libapr-1.so.0
これをapache2のあるフォルダ以下libフォルダを作成してその下に入れておく。今そのフォルダを、
/home/nao/hoge/lib
だったとしよう。/etc/ld.so.conf.d/にnanoを使って、apache.confファイルを作り、そこに、上記フォルダのパスを書いて保存する。
ロボットのrootになって、ldconfigを実行する。その後、
ldconfig -p | grep libapr
をrootで実行すると、
libaprutil-1.so.0 (libc6) => /home/nao/ibot/www/lib/libaprutil-1.so.0
libapr-1.so.0 (libc6) => /home/nao/ibot/www/lib/libapr-1.so.0
となり、これでOKである。
あとは、ポートを8080にしている限り、rootにならなくても、naoユーザーのままで、apachectl
./bin/apachectl start
を起動すれば、サーバーが立ち上がり、ロボットのipとポートを指定すると、
と、無事立ち上がった。