対話の曖昧さ

ほとんどの対話はかなりの曖昧さを持ったまま行われている。肝心なことは、それで用が足りているということだ。確かに次の電車の時間を尋ねるものと答えるものとの間で、伝えようとしたことと聞こうとしたことのポイントがずれることはないかもしれない。しかし、花の美しさを伝えようとするものと、聞こうとするものの間の会話は、曖昧さに支配される。われわれの日常会話の多くが後者のたぐいだ。
私が岩手大学に勤めていた頃だから、もう三十年近く前のことだ。還暦過ぎの母が福井から出て来て、盛岡にあった私の家を訪問した。私たち家族と母は、八幡平の奥にある温泉に出かけた。大浴場に行ったときのことだ。女風呂から先に出てきた妻が私に言った。
「おばあちゃん、地元のおばさんと楽しそうに話していたわ」
しばらくして、母が風呂から出てきた。私は母に聞いた。
「地元の人と何を話していたの?」
母は答えた。
「それが、相手の話が訛っていて、ぜんぜんわからなかったのよ」
母は、妻が外国語と思うほど、福井弁が強烈である。相手は、岩手弁だったのだろう。会話の呈をなしてなかったと思われる。
それでもその会話は母にとって楽しいものだったのに違いない。意味ある会話だったのである。
ロボット相手の会話も、そのような曖昧さがあっていい。

ローカルモジュールの出力を呼び出し側にかえす

ローカルモジュールからNAOqiへのログ出力については既に書いた。コンソール出力は、ただ、stdoutにストリームを出せばよい。ここで問題にするのは(それほど大げさなことではないが)ローカルモジュールのあるメソッドを実行させた場合に、その戻り値を呼出側でとらえる方法だ、難しくはない。
たとえば、ローカルもジュールのバージョンを獲得する場合を考えよう。次のようなrRobotクラスメソッドをモジュールの中に書き込む。
std::string Robot::getVersion()
{
std::string version = "0.0.4";
return version;
}
これをPythonから呼び出す場合、
>>> ws = ALProxy("Robot","127.0.0.1",9559)
>>> rep = ws.getVersion()
>>> print rep
これで、versionが出力される。
ただし、APIマニュアルでは、クラスのコンストラクタで
functionName("getVersion", getName(), "ibotのバージョンを取得する");
setReturn("char*", "return version");
BIND_METHOD(Robot::getVersion);
とsetReturnを入れてバインドするようにかかれているが、必須ではない。
ただ、一つは困ったのは、文字列をchar*で出力すると、モジュールがコアダンプして止まってしまうことだ。理由はわからない。std::stringで出力するようにしたら正常に獲得できた。どこかに考え違いがあるようだ。

認識した顔情報をQiChatスクリプト変数に戻す

どうやるか、相当時間考えたが現状の結論はこうだ。
まず、顔認識が実行されたときに発生させるイベント関数(ALFaceDetectionのEvent APIを参照する)を設定しておいて(このやり方はspeechRecognitionのサンプルを使えばいい)、このCallBack関数に与えられるデータから、認識された顔情報をALMemoryのInsertメソッドを通じて、変数に値を組み込む。
ということなのだが。

QiChatスクリプトLoad時の例外処理

QiChatスクリプトをロボットに組み込むときに、スクリプトにバグがあると正常に組み込めない。C++でこのプロセスをALDialogのloadメソッドでやると、組み込み失敗でプログラムが止まってしまう。例外処理をやらないといけないのだ。
APIマニュアルには例外を取れとだけ書いてあってどのような例外がスローされるか書いてなかった。例外処理をしないと実用上とてもまずいので、また、Aldebaranのdeveloper forumに質問したところ早速解答があった。
catch(const std::exception& e){
std::cout << e.what() << std::endl;
}
と、
catch (const AL::ALError& e)
{
std::cout << e.what() << std::endl;
}
のどちらも、正常に機能した。基本的に同じものであるようだ。どちらかでよい。

スクリプトの暗号化

QiChatはスクリプトであり、ロボットは可読なテキストファイルの状態でそれを入力する。作成したユーザーがそれを一貫して読めることは大事だが、そのスクリプトを他者に使わせるときに読まれることが望ましくない場合がある。
iBotシステムでも、ロボットが使用する瞬間には可読なテキストファイルでなければならないが、ユーザーから他者にわたったときには暗号化されているようにするつもりだ。それができるのは、スクリプトをロボットに読み込ませるのはiBotであって、iBotが暗号化されたスクリプトを複合できれば良いわけだから。
ユーザーは、結局最終的なスクリプトの利用者に複合化キーを渡さなければならないので、完全ではない。
iBotが固有の複合キーを持たせてスクリプトを隠蔽すれば、利用者はほぼ完全にテキストで見れなくなるが、iBotは、C++ で書かれ、コンパイルされ、バイナリファイルになっているので、それをリバースエンジニアリングで解読すればそれも見られてしまう。しかし、それは仕方がないだろう。

QiChatにおける変数の扱い

iBotシステムは、最後の詰めのところで、複雑で手間のかかる作業になっている。
特に変数の取り扱いだ。iBotは、Choregrapheを全く使わなくても、対話、動作、認知の機能を利用できるようにするシステムだ。中心には人との対話があり、それに起動されてさまざまな動作、認識機能が発動される。コンセプトがそうなっている。
その全体を直接コンんとロールするのがQiChatスクリプトである。QiCHatスクリプトにはめ込まれる機能を全て解釈して実行するのは、直接にはロボットなのだが、人とそのロボットの機能を媒介するシステムがiBotである。ほとんどそれはiBotで実現できるようになるのだが、NAOQiには、多様な機能があるので、全ては組み込まない。
その際、変数の扱いが面倒である。というのもNaoqiというロボットOSは、変数のイベント処理が重要な役割を持っている。変数に値が入力されたり変更されたりすると、それだけでイベントが発生し、プログラムの方でそれを獲得できるようになっているのだ。
たとえば、人の顔を学ぶとき、それが誰の顔かを変数で入れ籠まないと行けない。具体的な名前にすると、全く融通が利かないからだ。それをQiChatから、iBotシステム経由で、naoqiに渡す作業が必要になる。あるいは、認識した顔が誰であるかをQiChatのスクリプトの中に戻せなければならない。これら全てが変数によって媒介される。非常によくねられたシステムであることは間違いない。ちゃんと使えるようになっている。
iBotがどのように拡張されても、この変数を合理的に扱えるようなシステムにしたい。

編集機能の充実

iBotシステムのQiChatスクリプト編集機能で、簡単に入力できるように、また、質疑応答の構造かも容易になるような機能を組み込んでいる。当初は、これは後まわしにしてシステムを公開することを考えたが、この編集機能があるかないかで、スクリプトの開発スピードが格段に違うようになりそうなので、その部分も完成した後に公開しようと思う。