Up:Tutorial? Previous:動力学シミュレーションのサンプル Next:エージェント間のメッセージのやりとり?
人間またはロボットの形をしたエージェントの関節の操作方法を説明します。
人間が手を上げるサンプルコードを紹介します。
NewWorldディレクトリに新しくAgentController.cppを作成します。
$ cd ~/sigverse-<version>/bin/NewWorld $ emacs AgentController.cpp
AgentController.cpp
のサンプルはシミュレーション開始と同時に my->setJointAngleでエージェントの左腕が上に45°に上がるというものです。
次にMakefileを変更します。
$ emacs Makefile
変更前
#オブジェクトファイルの指定 OBJS = MoveController.so
変更後
#オブジェクトファイルの指定 OBJS = AgentController.so
Makefile
#SIGVerseソースの場所指定 SIG_SRC = /home/<username>/sigverse-<version>/include/sigverse #オブジェクトファイルの指定 OBJS = AgentController.so all: $(OBJS) #コンパイルを行います。 ./%.so: ./%.cpp g++ -DCONTROLLER -DNDEBUG -DUSE_ODE -DdDOUBLE -I$(SIG_SRC) -I$(SIG_SRC)/comm/controller -fPIC -shared -o $@ $<
コンパイルします。
$ make
次に世界ファイルを作成します。
$ cd ~/sigverse-<version>/bin $ ln -s ../share/sigverse/data/xml/ xml
xmlファイルがあるディレクトリまで遠いのでリンクを貼りました。
$ emacs xml/AgentWorld.xml
AgentWorld.xml
エージェントとしてMan-nii.xmlを読み込むように設定し、動力学演算をfalseにしました。動力学演算をtrueにするとエージェントの関節角度などを直接指定することができないので注意が必要です。
それではSIGVerseを起動してみましょう。
$ ./sigserver.sh -w AgentWorld.xml -p 9001
SIGViewerを起動して見てみると人間のエージェントが手を広げてスタンバイしていると思います。 シミュレーションを開始するとエージェントの左腕が45°上がります。
#ref(): File not found: "man_1.jpg" at page "人間型エージェントの操作(v2.0系)"
今回setJointAngleという関数を用いて"LARM_JOINT2" を45°にする設定を行いました。"LARM_JOINT2"は左肩のz軸での回転として定義された関節の名前です。同様に"LARM_JOINT0","LARM_JOINT1"はそれぞれ左肩のx軸、y軸の回転として定義されています。(エージェント座標系。)これらの関節名はsigverse-<version>/share/sigverse/data/shape/にあるx3dファイル(nii_man.x3d)で定義されています。サンプルモデルのジョイント名はJoint定義一覧?を参照
AgentWorld.xmlファイルはMan-nii.xmlファイルを読み込みMan-nii.xmlファイルは人間型エージェントの形状を記述したnii_man.x3dを読み込んでいます。
SIGViewerでエージェントをクリックすると右のAttributesタブでエージェントの名前や位置(x,y,z)、エージェントの向き(qw,qx,qy,qz)、視点の位置(epx,epy,epz)などの属性を見ることができます。これらの属性の値はxmlファイルで設定されています。
#ref(): File not found: "attr_1.jpg" at page "人間型エージェントの操作(v2.0系)"
人間型エージェントMan-niiはAgentクラスを継承したオブジェクトです。Agentクラスの属性のデフォルトの値はAgent.xmlで設定されています。見てみましょう。
$ less xml/Agent.xml
上で見たvpx,vvxなどの値が設定されているのがわかります。 さらにAgentクラスはEntityクラスを継承しています。Entityクラスは自律動作を行わない物体のクラスです。
エンティティ、エージェントの基本的な属性を紹介します。
エンティティの属性
属性名 | 意味 | 備考 |
x,y,z | エンティティの位置 | グローバル座標。x軸は原点から緑矢印 ,y軸は赤矢印 z軸は黄色矢印で表示 |
fx,fy,fz | エンティティにかかる力 | |
vx,vy,vz | エンティティの速度 | |
qw,qx,qy,qz | エンティティの向き | クオータニオン表記 |
scalex, scaley, scalez | エンティティの大きさ | |
collision | 衝突判定フラグ(デフォルトはtrue) |
エージェントの属性
属性名 | 意味 | 備考 |
vpx,vpy,vpz | エージェントの視点の位置(ヒューマノイド以外) | エージェント座標、原点はエージェントの位置 |
vvx,vvy,vvz | 視線の方向(ヒューマノイド以外) | ベクトル表記 |
elnk1,elnk2,...elnk9 | 視点(カメラ)を設置するリンク名(ヒューマノイドのみ) | elnk1はデフォルトでHEAD_LINKに設置されている。 |
epx1,epy1,epz1,...epx9, epy9, epz9 | 視点(カメラ)の位置(ヒューマノイドのみ) | 原点はelnkで指定されたリンクの位置 |
evx1,evy1,evz1,...evx9, evy9, evz9 | 視点(カメラ)の方向(ヒューマノイドのみ) | |
FOV | エージェントの視野角(高さ) | |
voiceReachRadius | エージェント声が届く範囲 |
これらの属性はすべて世界ファイルで設定が行えます。
前回は定期的に呼び出されるonActionで手を上げるサンプルコードを紹介しました。次はSIGViewerからのメッセージを送信することによりエージェントがお辞儀をするようなサンプルコードを紹介します。
まずAgentController.cppを変更します。
$ cd NewWorld $ emacs AgentController.cpp
AgetnController.cpp
onActionで手を下げ、メッセージを受信したときに呼び出される関数onRecvMessageを追加しました。メッセージが"Hello"だったときにお辞儀をします。
コンパイルします。
$ make
次にエージェントの属性を編集します。
それでは実行してみましょう。
$ cd .. $ ./sigserver.sh -w AgentWorld.xml -p 9001
SIGViewerで接続して、 sendボタンをクリックしてシミュレーションを開始すると、まずonActionが呼び出されて右手と左手を下に下げます。
#ref(): File not found: "man_2.jpg" at page "人間型エージェントの操作(v2.0系)"
まずSIGViewerの右上にあるCommandタブをクリックします。 一番上の入力欄でvoiceとgeneralが選択できるようになっています。ここではgeneralを選択します。次に送信対象選択ボタンをクリックして画面上のエージェントをクリックします。エージェント名が自動的に入力されると思います。そしてSendMessage引数のところにHelloと入力します。
#ref(): File not found: "man_3.jpg" at page "人間型エージェントの操作(v2.0系)"
入力が完了したら、実行ボタンを押します。
#ref(): File not found: "man_4.jpg" at page "人間型エージェントの操作(v2.0系)"
お辞儀をしました。
関節の回転はクオータニオンによって設定することもできます。(※バージョン110223以降で動作)
関節回転箇所を以下のように修正します。
AgentController.cpp
↓
setJointQuaternionという関数を使って関節のクオータニオンを設定します。引数で関節名の次にクオータニオンのw,x,y,z成分を指定します。
クオータニオンを指定した場合はあらかじめ設定されている関節の回転軸に関係なく回転します。 正常に関節が回転するか確認してみてください。
Up:Tutorial? Previous:動力学シミュレーションのサンプル Next:エージェント間のメッセージのやりとり?
English version?