C++ローカルモジュールからのログ出力

ローカルもモジュール(ロボットから直接起動するモジュール)のデバグ用にログを出力したいのだが、ただコンソール出力にしているだけ(リモートモジュールの場合は、これだけで良かった)では、どこにも出力されなくなってしまう。したがって、ログ出力のライブラリを使わなければならない。以下のようにする。
(1)main.cppに次のようにインクルードファイルを設定する。
#include <cstdlib> //for atexit
#include <qi/log.hpp>
(2)同じく、main関数の中で、次のような初期化を行う。
qi::log::init();
atexit(qi::log::destroy);
(3)使用するcppファイルに、
#include <qi/log.hpp>
を入れて、情報の場合は、
qiLogInfo("wsftmod") << "******** トピックリストの取得 *********";
などとコマンドを入れる。警告の場合は、
qiLogWarning("wsftmod") << "トピックリストを取得できませんでした;
などと入れる。
ここで、"wsftmod"は、出力の冒頭に記載される識別子で、自分が区別できれば何でもよい。モジュール名をいれておけば最低間に合う。
以上の操作で、以前示したロボットのログの中に情報が現れデバグが簡単にできてしまう。(gdbを使うまでもないと思う。多分使えない。)

Localモジュールの問題

研究会のサーバーから、ロボット用のtopicファイルをダウンロードしてロボットに組み込むモジュールを作成した。クラウドの入り口に立とうという狙いだ。モジュールがリモートだと、ダウンロードしたファイルをロボットに保存できないので、ロボット本体に組み込むローカルモジュールに変更した。
組み込んでみると、ロボットの電源を入れたときに、そのモジュールを読み取るはずなのだが、失敗している。ログを調べると、原因は、モジュールをコンパイルしているのは64ビットのLinuxマシンなのだが、ロボットは、32ビットのLinuxで動いていて、モジュール実行時の整合性がとれていないためのようだ。Cコンパイラを調整すれば、64ビットのLinuxでも、32ビットの実行ファイルを作成できるようなのだが、いろいろやってもうまくいかない。
そこで、Linux64を入れているVirtualBoxにLinux32も追加した。そして、そこに、naoqiのビルド関係の一式を再度インストールして、コンパイルし直した。それでモジュールとしてロボットに組み込むと、めでたく起動時にそれを読み込んだ。
外見上は特に問題なく機能しているようなのだが、ファイルをロボットに保存している段階で失敗しているようだ。パーミッションの問題なのかチェックしたが、ログがどこにも見つからない。はて困った。
(2014年8月18日追記)
単に保存するパスを間違えていたためであることが分かった。

関節のStiffnessの問題

C++のモジュールから動きをつけるときの、動作のぎこちなさが完全に解消できないので、そのことをAldebaran社のフォーラムに投稿して聞いてみたところ、いくつかのチェック項目を指揮された。大概チェック済みのものだが、一つ、関節のStiffnessが1.0になっていない状態で動こうとすると、おかしくなるよというのがあった。
そこで、動作の前にStiffnessがどうなっているかをALMotionのメソッドで調べてみた。結果的に、全ての関節が1.0になっていて問題なかった。が、motionのAPIは、あまり触れる予定がなかったことなので、視野が開けた気はした。
なお、stiffnessについて一言説明する。例えば人間で言えば、筋肉の力を全て緩めてしまえば、立っていられず、グニャグニャとなってしまうように、ロボットも、関節のモーターに力を入れておかないと、しゃきっとはしていられなくなる。Stiffnessとは、このようにロボットの筋肉に力を入れることを意味している。

brokerとmotionの問題

昨日うまく行かなかった二つの問題が一部解決した。
(1)外側で起動されたAPIからのイベントメッセージをDIALOGの中で受け取ることで、これは、
AL::ALProxy memory(broker,"ALMemory");
memory.callVoid("declareEvent","didSitdown");
memory.callVoid("declareEvent","didStandup");
if(poseType == "Sit"){
memory.callVoid("raiseEvent","didSitdown",1);
}else if(poseType == "Stand"){
memory.callVoid("raiseEvent","didStandup",1);
}
この様にイベントをコールすればよい。すなわち、declareEventしてから、raseEventをやるのである。
(2)二つの目問題は、「座れ」に対してすわるのだが、甚だしくぎこちない、座ろうとして止めたりまたやったり、ビクッとしたり、見ていられない。なかなか原因が分からなかったが、色々やった末に、brokerが原因かもしれないと思うようになった。動きの調整がとれていないのだ。そこで、あらたにポーズをとるための専用brokerを作成して、使ってみることにした。brokerの作成のためには、IPとport番号が必要なのだが、それは、親のbrokerからとってくることにした。brokerは次のように作る。
broker = AL::ALBroker::createBroker(
"poseBroker", "0.0.0.0", 54000,
pbroker->getIP(), // 親brokerからのIPをセットする
pbroker->getPort(), // 親brokerのPortをセットする
0 // デフォールト
);
という感じだ。
これで、改善した気もするが、確信はないがいつまでも関わっていられない。Aldebaranのフォーラムに、問題を投稿して、当面保留か。
どなたかわかる方がいたら教えていただきたい。

C++モジュールのロボット上での機能

昨日までに作った、C++からALDialogモジュールを使用する一連の作業をロボット上で確認した。いくつか問題が生じた。
(0)モジュールはリモートでも、トピックファイルはロボット上に置かなければならないことがわかった。
(1)今までの呼び出し手順に、ALDialogプロキシから、subscribe("モジュール名")の呼び出しを追加しなければならないことがわかった。いままでは、基本的に、
ALDialogのインスタンス作成
言語の設定
トピックのロード
トッピックの有効化
の手順だったが、言語設定とロードの間に、subscribe("モジュール名")をはさむこと。これによってモジュールの機能がスタートするらしい。
(2)もう一つは、いままでは、三つのトッピックファイルについて、一つずつ、ロードしたら有効化していたのだが、コンパイルから有効化の間に、ログに訳の分からないエラーが出てくる。そこで、まず、三つのトピックファイルを一挙にロードし、コンパイル用に1秒のsleep関数を挟み、次にすべてを有効化する手順にしたら、エラーが消えて、ロボットがトピックファイルに従って返事をするようになった。このあたりになるとほとんど裏技である。
以上は、解決した問題なのだが、未解決の問題。
(3)ロボットの座る立つの動きがぎこちなさすぎる。言葉に従って、動作はするのだが、動きの途中で、素早すぎる動きがわずかに挟まれ、おかしい。原因不明。動きを0.5など、遅くしているのが原因かもしれない。
(4)最後の、坐れなどの動作のあとに、トピックファイルに仕込んだ、変数変化のイベントをコールバックすることがうまくいっていない。

クラウド上でロボットを管理

次の戦略は、ロボットの対話などのコンテンツ、ロボットの管理そのものをサーバー上で行うこと。そのためには、ロボットのモジュールとしてネットワーク通信を行うものを装着しなければならない。

「C++からALRobotPostureの呼び出し」を追加

手間取ったが、なんとか「C++からALRobotPostureの呼び出し」を実行できるようになった。ここに解説
この組み込んだ新しいクラスのなかから、ALMemoryの変数に値を与え、トピックファイルの中で定義されているイベント処理命令に反応させ、ロボットに言葉を発しさせるのが次の手順である。

「C++で変数変化のイベントをとらえAPIを起動」を加えた

表題のページを、ここに置いた。
残っている課題は、外のAPIの結論を再び、QiChatのトッピックファイルの中でとらえて、ダイアログの言葉に戻ることだ。QiChatで拾う方法は、Choregrapheの場合と同じですでにやり方はわかっている。問題は、その変数を変化させる方法だ。勝手に、C++の変数を変化させてもだめなことはわかっている。大事なことは、ALMmoryの変数にしてそれを変化させることだ。これからそれを、調べてみよう。

解説「C++からALDialogを使う」を加える

「C++からALDialogを使う」をNAOの技術に関するページに加えた。こちらへ。
これで、C++からQiChatを使えるようになったはずである。したがって、当面の目標に到達するために最後に必要なのは、QiChatのなかで、変数の値を経こうしたときに、そのイベントをとらえ、他のAPIを起動させることである。そうすれば、Choregrapheでできることで、私が使わなければならないと思っているもののかなりのものを、C++から使えることになる。