動作のマクロ機能を追加

ピノキオ(スマホコントローラー)に、動作を記録して再現する機能を追加した。予定した行動をさせる機能としては、口頭でコマンドを与える機能も持っている。二本立てになった。これによって、複数のロボットを操りやすくなった。事前に動作を決めておいて、マクロの実行コマンドだけを与えれば、複数のロボットが一連の動作を、ほぼ同時に開始させることができる。

理解できないことに直面して

この数日テレパシーに関わる作業を続けてきたが、どうしてもうまくいかないことが続いた。ある方向で実行すると動かない、別の方向では動く、これが多種多様に発生して何が何だかわらかなくなってきた。が、おそらく次の二つが原因になっているのではないかと思う。それを書き留めておこう。
(1)あるローカルモジュール内で登録したALMemoryイベントを、同一モジュール内で、raiseEventメソッドで、イベント発生させハンドラを呼び出すことはできない。
そもそもやろうとしていることが奇妙に思える。同一モジュール内だったら、直接そのイベントハンドラに対応する関数を呼び出せば良いからである。ただ、ここで必要になったのは、子プロセスから親プロセスのハンドラを呼び出すことをしたかったわけだ。Linuxのネイティブなシステムコールなどを使えばできるのかもしない。また、naoqiのリモートモジュールだったらこれもできることは確認した。が、ローカルモジュールになった途端できない。そのハンドラを、他のモジュールや、外側のPythonから呼び出すと正常に呼び出すことができる。
できないなら仕方がない。本質的には、他のモジュールから呼び出せる限り問題ないとは言える。
(2)これも不思議なのだが、子プロセスから、textspeechなどの機能を呼び出せないーようだ。親プロセスと子プロセスを取り替えた途端しゃべるので、たぶん、そうだろうと。
JAVAだったか、グラフィックツールはメインスレッドでしかうごかせないなどという制約があったのと同じかもしれない。つまり、ハードウェアをコントロールするAPIは、メインプロセスでしかうごかせないのかもしれないということである。
上記の二つが本当かどうか、絶対にそうだとは言えない。何か他の要因でできないでいるだけかもしれない。しかし、何日も無駄にしたので、腹立ち紛れに書いておいた。
イソップ物語にある、狐と葡萄の話だ。ブドウのふさに跳びついて取れないとわかった途端、狐は「こんなぶどうは酸っぱいに決まっている」と言い捨てて立ち去ったという話だ。高校生の頃に知ったのだが、いまだにこの狐のたくましさが好きだ。

ロボットの相互把握

目的としては図のようにしたいわけである。(理想的なところはどこにあるかを記録のためにここに書いておく。)
search_robotsしかし、当面2台しか持っていないので、この図で言う認識すべきロボット数をブロードキャストで流すという部分を省略している。
デフォルトで、2台のロボットを認識すようにして、それ以上の場合は、認識すべき台数だけは、頭にタッチする以前に、個々のロボットにセットしなくてはならなくしている。
また、今は、頭頂前部のタッチにしているが、いずれは、一旦タッチすると無効にして、再有効化のためにはブロードキャストで、またセットし直す必要があるようにしたい。

1台のスマホで、複数ロボット制御

ロボットの台数スマホを用意するのは不合理だから1台のスマホで複数のロボットを同時に制御したい。基本的に、IPアドレスで区別し、それぞれセッションを立ち上げながら制御することになる。
最も大きな問題は、以下に簡単にスマホに全てのロボット情報を取り込むかだ。次のようにした。
すでにテレパシー機能で、ローカルネットに繋がっている全てのロボット情報を、ロボット自身が相互に把握し合うプロトコルを組み込んだ(とは言っても、昨日からこれを正常に機能させるのに苦労したが)。したがって、最も都合がいいのは、1代のロボットに接続すると、そのロボットが全ての他のロボットの情報も持っていることだ。
まず、全てのロボットのスイッチをオンにする。モジュールが組み込まれる。その後、頭のセンサーをタッチすると、他のロボットの探索を開始する。センサーをタッチされた全てのロボットが、相互にIPアドレスやロボット名を含めた情報を提供し合い確保する。
スマホ(ピノキオ)から、1台のロボットにアクセスする。全てのロボット情報をピノキオに取り込む。ピノキオで、対象ロボットを切り替えながら必要な制御をする。
頭のセンサータッチは、不注意でも発生するので、無効にする機能も用意すべきだろう。

ピノキオ1台で複数のロボット制御

2台目のロボットが来たので、2台のロボットでテレパシー機能を使った対話など、いろいろやろうと思って大学に来たら、スマホを1台しか持ってこなかった。本当は、Nexus7も持ってきて、それぞれコントロールしようと思ったのだが・・・。
しかし、そもそも、ロボットの台数だけ携帯端末を用意するというのは確かに不合理だと気付いた。
1台で複数のロボットを切り替えながら制御できるのが良い。まず、複数のロボットのIPアドレスや名前などを情報をしてlocalStrageに溜め込んで、接続を切り替える機能をピノキオに加えることにした(公開は、次のバージョン)。
最初の接続の時は、ロボットのIDとパスワードを聞かれて面倒かもしれないが、その後は、IPが変わらない限り、接続の切り替えだけで済むはずである。
テレパシーモジュールの中に、1台のロボットで、ローカルネット上のすべてのロボットのIPアドレスとロボット名を取得するメソッドが作成済みなので、それを使えば情報把握だけは簡単にできる。
ロボットのことに専念できる、せっかくの土曜日の1日だが、これに使っちゃうしかないか。早めに出来上がれば良いが。

暗号化の問題

当初予定していたほんとんどのことに取り組めたと思っていたが、暗号化のことを忘れていた。実用性を考えたときに、対話スクリプトの暗号化は必要だ。あるいみ、そのために、自前モジュールを用意していたような面があるから。
opensslを使ってiBotサーバー上でencryptして、ロボット上でdecryptすることが通常考えられる。ロボットは、opwnsslのライブラリを通常持っていないから(そのためにインストールするのは面倒くさい)、少し大きくなってもモジュールにスタティックでlibをくっつけるしかないかと思う。それで正常にロボット上のdecryptができるかどうかは調べてみないとわからない。
もしそれができたとしても、完全に安全なシステムになるとは思えないが、それくらいの対応は必要だろう。

対話台本

今週中に2台目のロボットが来るはずだから、この2台のロボットの対話をテレパシーで制御するための、脚本を書いている。2本書いた。3本書いて、準備しようと思っている。

ピノキオにテレパシー制御機能を組み込む

テレパシーモジュールは、基本的にiBotの対話機能で、したがってロボットとの対話で、(1)他者ロボット探索、(2)接続初期化、(3)イベント送受信などの機能を実行できる。しかし、他者ロボット探索や初期化を対話で行うのが時間と手間がかかりすぎる場合がある。その時のために、このような初期作業を行う機能を次のバージョンのピノキオに組み込む。

テレパシーモジュール:他のロボットの初期探索

テレパシーを実現するためには、他のロボットの情報(少なくともIPアドレス)を得ていなければならない。これを対話的に与えるのはとても面倒なので、ロボット同士で、相互に情報を交換するシステムにする。
モジュールの中に、探索開始イベントハンドラを用意して、ALMemoryによってこのイベントが発生したことが伝えられたら探索を開始する(イベントの発生は対話で、ALDialogをとおして行えるので)。
探索は、前にも書いたように、ネットワークにブロードキャストパケットを送り出す。ローカルネットワークに繋がっている全てのロボットから送り出させる。それらを受信しあって、相手の存在を確認する。現状では、そのロボットのIPアドレスと、システムが保管しているロボットの名前を情報にする。自分のプロファイルをロボットクラスオブジェクトとして保存し、相手のロボット情報も同じクラスのオブジェクトとして保存する。
いずれ自分の初期位置情報も交換させたい。
確認した相手ロボットの名前を喋らせてもよい。
こうすれば、いちいち相手ロボットの情報を入力しなくて済む。
モジュールのコンパイルは済んだが、C++のnaoqiシミュレーターが、ALSystem を持っていない(不思議だ)、ので、そのロボットの名前を取得するシミュレーションができない。そこだけを適当に名前をつけて、シミュレーションするしかない。あとは、実機でシミュレーションだが、これは2台以上ロボットがないとテストできない。
ただ、対話のトピックファイルの中に、相手ロボットのIPを書き込まないとけないのか、その辺りが解決していない課題となっている。名前を書いておけば、モジュールがIPに変換するというのがいいのかもしれない。