Softbankから発売されるPepperはAldebaran社との共同で作られており、そのフレームワークに同社のフレームワークであるNAOqi Frameworkが採用さているようです。
NAOqiとは
Aldebaranロボティクス社のロボット上・もしくはロボット制御用ソフトウェアの総称です。
NAOqi OSの上でNAOqi Frameworkが動いているようです。
OSに注目が集まりがちですが、NAOqi OSは多分単なるリアルタイムLinuxであり、NAOqi Frameworkこそが
NAOqiの中核であると言えます。
NAOqi Frameworkとは
NAOqi FrameworkとはNAOをプログラムするためのフレームワークで、
動作、音声、画像に対して、一貫したインタフェースを提供します。
(2014/08/22)現在のバージョンは2.1です。
以下は↓の参考URLの意訳になります。
参考: https://community.aldebaran.com/doc/2-1/dev/naoqi/index.html
NAOqi Frameworkの特徴
以下の2つが特徴として挙げられています。
- クロスプラットフォーム(Windows/Linux/Mac)。Win/Macではクロスコンパイルのみ。
- 多言語対応(C++/Pythonのみ)
多言語対応
多言語といっても、日本語英語の話ではなく、C++/Pythonの話しです。
例えば、ロボットに何か喋らせたいとして、以下のようにほぼ(意味的に)同じコードで記述できます。
textToSpeachProxy.say("こんにちわ")
textToSpeachProxy->say("こんにちわ");
分散処理
リアルタイムなアプリケーションはスタンドアロンなものにもなるし、分散環境にもなります。
どちらも同じように記述することができます。アプリケーションが他のロボットにIPアドレスとポートで接続すると、すべてのAPIがローカルAPIと全く同じ方法で実行することが出来ます。
ただし、外部から呼び出し可能なAPIを作成するにはモジュールという単位のライブラリをC++で作成する必要があります。Pythonは呼び出しのみ。
動作の仕組み
Introspection
BIND_METHODというAPIを使うことで、Introspectionが使えるようになります。
これによりロボットが今ロードしているモジュールのどんなAPIが使えるかが簡単にわかります。
- 登録した関数がC++/Pythonのどちらからでも呼べるようになる
- その関数が実行中であるかどうか分かる
- 外部コンピュータや他のロボットからも関数呼び出しができるようになる
- wait/stop/isRunningが使える
APIを調べるには http://ROBOT_IP:9559 にアクセスするだけで出来ます(ROBOT_IPはロボットのIPアドレス(127.0.0.1など)。
モジュールのリスト、メソッドリスト、パラメータ、コメントやサンプルをブラウザ上に表示できます。
ブラウザ上には実行中の関数も表示されます。
プロセスモデル
ロボットは実行にautoload.iniというファイルに書かれたライブラリを読み込みます。ライブラリの中にはモジュールが1つ以上含まれます。
Broker
autoload.iniを読み込むプログラムはBrokerと呼ばれ、どんなモジュールがローカル・リモートに存在するかを管理します。
Proxy
モジュールを呼び出すために対象としたモジュールに対応するProxyを作成します。
プロキシの作成の方法には、ローカルとリモートの2通りのやり方があります。
モジュール
モジュールはライブラリ(.soファイル)中のC++のクラスとして作られます。これはautoload.iniにより読みこまれ、自動的にインスタンスが作成されます。
- リモートモジュール:ロボットの外部で実行する場合は、モジュールは1つの実行ファイルになります。ロボット外なので、デバッグがし易いですが、効率が悪いです。通信にはSOAPが使われています。そのため高速なデータ転送には向いていません。
- ローカルモジュール:ロボット体内の場合はライブラリになります。通信の遅延やオーバーヘッドがないので効率がよいです。ローカルモジュール同士は同一プロセスになります。
リモートモジュールの通信
- Broker同士の接続: Broker同士をつなげるとお互いのモジュールにすべてアクセス可能になります。
- BrokerへのProxyを作成: 外部Brokerへのプロキシを作成すると、そのProxyを通じて外部Brokerの持つモジュールすべてにアクセス可能になります。この場合は、外部Brokerに存在するモジュールからこちらのモジュールにはアクセス出来ません。
Broker同士の接続
Broker同士を接続する場合は、モジュール実行時に--pipオプションと--pportオプションにより、外部BrokerのIPとポートを指定します。モジュールの中では、以下のようにして外部モジュールにアクセス出来ます。
AL::ALProxy proxy = AL::ALProxy(MODULE_NAME);
実行時にIPとポートが指定されているので、プログラム中でそれらを気にする必要はありません。
BrokerへのProxyを作成
BrokerへのProxyを作る場合はプログラム中で相手のIPとポートを指定する必要があります。
// 接続先NAOqi ip
const std::string pip = "127.0.0.1"; // local NAOqi
// 接続先NAOqi port
int pport = 9559;
// 自分のBrokerの生成
const std::string brokerName = "mybroker";
boost::shared_ptr<AL::ALBroker> broker =
AL::ALBroker::createBroker(brokerName, "0.0.0.0", 54000, pip, pport);
AL::ALProxy proxy = AL::ALProxy(broker, <modulename>);
ブロッキングとノンブロッキング
ブロッキングは普通の関数のように、処理が終わるまで待ちます。
module.doSomething();
// 処理が終わってから進む
これを module.postというオブジェクトを通じて実行することで、ノンブロッキングに処理を行うことが出来ます。
int taskID = module.post.doSomething();
// 処理が終わる前に先にすすむ
taskIDを使って、実行状態を調べることが出来ます。
これは非常に便利ですね。
メモリ
ロボットはALMemoryという、すべてのモジュールが共通してアクセス可能な、スレッドセーフな記憶領域を持ちます。
イベント
イベントという仕組みによって何かが発生したときのコールバックを登録しておくことが出来ます。
例えば人の顔を認識したときにイベントが発生するようにしておけば、それに対して、手を振る、人の顔の方向に首を曲げる、といったコールバックが登録可能です。
概要は以上になります。