[[Tutorial]] #contents *視覚に関する操作方法 [#f37ce459] 視覚に関する操作方法を説明します。 **周りを見渡す [#scce7ec9] エージェントがいろいろな方向を見渡すことができるサンプルコードを紹介します。 ***コントローラ作成 [#t10e6f74] $ cd ~/sigverse-<version>/bin/NewWorld $ emacs WatchController.cpp WatchController.cpp #include "Controller.h" #include "Logger.h" #include "ControllerEvent.h" #define PI 3.141592 #define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 ) class WatchController : public Controller { public: void onRecvMessage(RecvMessageEvent &evt); }; void WatchController::onRecvMessage(RecvMessageEvent &evt) { SimObj *my = getObj(myname()); //受け取ったメッセージをint型に変換します。 const char *value(evt.getString(0)); int angle = atoi(value); if (angle <= 180 && angle >=-180){ //体全体をz軸から指定した角度だけ回転します. my->setAxisAndAngle(0, 1.0, 0, angle); } } extern "C" Controller * createController () { return new WatchController; } これは回転する角度をメッセージとして受信して、その角度だけ体を回転させるサンプルです。 z軸方向(ロボットが最初に前を向いている方向)からの角度を指定します。回転する角度は-180°から180°まで指定することができます。 それではコンパイルします。 $ emacs Makefile 変更前 #オブジェクトファイルの指定 OBJS = SendController.so RecvController.so 変更後 #オブジェクトファイルの指定 OBJS = WatchController.so $ make ***リビングルームの世界ファイル作成 [#iea3d264] 新しく世界ファイルを作成します。 //前回の世界ファイルは一応残しておきます。 $ cd ~/sigverse-<version>/bin // $ mv xml/MyWorld.xml xml/MoveWorld.xml $ emacs xml/WatchWorld.xml WatchWorld.xml <?xml version="1.0" encoding="utf8"?> <world name="VisTest2"> <gravity x="0.0" y="-9.8" z="0.0"/> <!--エージェントRobot-niiの設定--> <instanciate class="Robot-nii.xml"> <!--エージェント名--> <set-attr-value name="name" value="robot_000"/> <!--C++言語の指定--> <set-attr-value name="language" value="c++"/> <!--オブジェクトファイルAgentController.soの指定--> <set-attr-value name="implementation" value="./NewWorld/WatchController.so"/> <!--動力学演算をfalseに設定--> <set-attr-value name="dynamics" value="false"/> <!--エージェントの位置(x,y,z)--> <set-attr-value name="x" value="0.0"/> <set-attr-value name="y" value="60.0"/> <set-attr-value name="z" value="-40.0"/> <!--エージェントの視点の位置--> <set-attr-value name="vpx" value="0.0"/> <set-attr-value name="vpy" value="70.0"/> <set-attr-value name="vpz" value="5.0"/> <!--エージェントの視点の向き--> <set-attr-value name="vvx" value="0.0"/> <set-attr-value name="vvy" value="-1.0"/> <set-attr-value name="vvz" value="1.0"/> </instanciate> <!--リビングルーム作成--> <instanciate class="seTV.xml"> <set-attr-value name="name" value="TV_0"/> <set-attr-value name="dynamics" value="false"/> <set-attr-value name="x" value="-20.0"/> <set-attr-value name="y" value="82.0"/> <set-attr-value name="z" value="-250.0"/> <set-attr-value name="visStateAttrName" value="switch"/> <set-attr-value name="switch" value="on"/> </instanciate> <instanciate class="seDoll_Bear.xml"> <set-attr-value name="name" value="kuma_0"/> <set-attr-value name="dynamics" value="false"/> <set-attr-value name="x" value="0.0"/> <set-attr-value name="y" value="5.0"/> <set-attr-value name="z" value="0.0"/> <set-attr-value name="vpx" value="0.0"/> </instanciate> <instanciate class="seToy_D.xml"> <set-attr-value name="name" value="penguin_0"/> <set-attr-value name="dynamics" value="false"/> <set-attr-value name="x" value="50.0"/> <set-attr-value name="y" value="10.0"/> <set-attr-value name="z" value="-40.0"/> <set-attr-value name="vpx" value="0.0"/> <set-attr-value name="vpy" value="10.0"/> <set-attr-value name="vpz" value="0.0"/> <set-attr-value name="vvx" value="0.0"/> <set-attr-value name="vvy" value="0.0"/> <set-attr-value name="vvz" value="1.0"/> </instanciate> <instanciate class="seSofa_2seater.xml"> <set-attr-value name="name" value="sofa_0"/> <set-attr-value name="dynamics" value="false"/> <set-attr-value name="x" value="-200.0"/> <set-attr-value name="y" value="20.0"/> <set-attr-value name="z" value="-100.0"/> <set-attr-value name="qw" value="0.707"/> <set-attr-value name="qx" value="0.0"/> <set-attr-value name="qy" value="0.707"/> <set-attr-value name="qz" value="0.0"/> </instanciate> <instanciate class="seTVbass_B.xml"> <set-attr-value name="name" value="TVdai_0"/> <set-attr-value name="dynamics" value="false"/> <set-attr-value name="x" value="-20.0"/> <set-attr-value name="y" value="13.0"/> <set-attr-value name="z" value="-250.0"/> </instanciate> <instanciate class="sePlant_B.xml"> <set-attr-value name="name" value="ki_0"/> <set-attr-value name="dynamics" value="false"/> <set-attr-value name="x" value="100.0"/> <set-attr-value name="y" value="35.0"/> <set-attr-value name="z" value="-250.0"/> </instanciate> <instanciate class="seSidetable_B.xml"> <set-attr-value name="name" value="sidetable_0"/> <set-attr-value name="dynamics" value="false"/> <set-attr-value name="x" value="-100.0"/> <set-attr-value name="y" value="23.0"/> <set-attr-value name="z" value="-100.0"/> <set-attr-value name="qw" value="0.707"/> <set-attr-value name="qx" value="0.0"/> <set-attr-value name="qy" value="0.707"/> <set-attr-value name="qz" value="0.0"/> </instanciate> <instanciate class="seApple.xml"> <set-attr-value name="name" value="apple_0"/> <set-attr-value name="dynamics" value="false"/> <set-attr-value name="x" value="-50.0"/> <set-attr-value name="y" value="10.0"/> <set-attr-value name="z" value="30.0"/> </instanciate> <instanciate class="seOrange.xml"> <set-attr-value name="name" value="orange_0"/> <set-attr-value name="dynamics" value="false"/> <set-attr-value name="x" value="70.0"/> <set-attr-value name="y" value="10.0"/> <set-attr-value name="z" value="-30.0"/> </instanciate> </world> これはリビングルームにヒューマノイドロボット(Robot-nii.xml)が立っているというxmlファイルです。リビングルームにはテレビやソファなどがおかれています。 このxmlファイルではエージェントの視点の位置や、視点の向きの設定がされています。これらはすべてエージェント座標系で設定されます。エージェント座標系とはエージェントが基準となる座標系で、x軸がエージェントから見て左右(左が正方向)、y軸が上下(上が正方向)、z軸が前後(前が正方向)となります。原点はエージェントの位置です。エージェントのお腹あたりにあるようです。 視点の向きはベクトルで表されます。今回視点の向きを(vvx,vvy,vvz)=(0,-1,1)と設定しました。つまりエージェントはまっすぐ前を向いた方向から、下方向45°に目線があるということになります。 ***起動 [#s12fde3f] それでは起動してみましょう。 $ ./sigserver.sh -w WatchWorld.xml -p 9001 SIGViewerでサーバに接続して、シミュレーションを開始します。リビングルームに立っているヒューマノイドロボット型のエージェントが見えると思います。 #ref(watch_1.jpg) 次に、ヒューマノイドロボットをクリックすると、左上の小さい画面にロボットの目線から見た映像が表示されます。 #ref(Watch_3.jpg) ロボットの目線からはりんごが見えているのがわかります。右のDetected Entitiesを見てみると、ロボットから見て、りんごが検出されているのがわかります。 #ref(watch_2.jpg) 次に右側のコマンドタブをクリックして、ヒューマノイド型ロボットのエージェントに回転する角度を指定して、実行ボタンを押し、メッセージを送信します。例えば180を送信します。 #ref(watch_4.jpg) ロボットが180°回転して今度はテレビや、木、テーブルなどが検出されているのがわかります。 **オレンジを見つけたら手を挙げる [#b15d4040] 次にオレンジを見つけたら手を挙げるサンプルを紹介します。 ※注意)ポートフォワーディングによる接続の場合正常に動作しない場合があります。 ***コントローラ作成[#cef2b65c] コントローラを作成します。 $ cd .. $ emacs WatchOrange.cpp WatchOrange.cpp #include <string> #include <iostream> #include "Controller.h" #include "Logger.h" #include "ControllerEvent.h" #define PI 3.141592 #define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 ) //利用する名前空間の宣言 using namespace std; class WatchController : public Controller { public: double onAction(ActionEvent &evt); void onRecvMessage(RecvMessageEvent &evt); }; //能動的行動を行います。 double WatchController::onAction(ActionEvent &evt) { try { SimObj *my = getObj(myname()); //手をさげます。 my->setJointAngle("LARM_JOINT2", DEG2RAD(0)); //視野内のEntityを得ます。 vector<string> ent; bool b = detectEntities(ent); if(b && ent.size() > 0) { //検出したEntityの名前を取得します。 vector<string>::iterator i; for ( i = ent.begin(); i!= ent.end(); i++) { string name = *i; //検出したEntityを表示します。 LOG_MSG(("detected %s\n", name.c_str())); if (name == "orange_0"){ LOG_MSG(("This is orange")); //オレンジを見つけると手を挙げます。 my->setJointAngle("LARM_JOINT2", DEG2RAD(180)); } } } } catch(SimObj::Exception &) { LOG_ERR(("Exception")); } return 1.0; } //受動的行動を行います。 void WatchController::onRecvMessage(RecvMessageEvent &evt) { SimObj *my = getObj(myname()); const char *value(evt.getString(0)); int angle = atoi(value); if (angle <= 180 && angle >=-180){ //体全体をz軸から指定した角度だけ回転します. my->setAxisAndAngle(0, 1.0, 0, DEG2RAD(angle)); } } extern "C" Controller * createController () { return new WatchController; } これはオレンジを見つけたら手を挙げるサンプルです。detectEntitiesで視野内にあるエンティティを検出します。 それではコンパイルします。 $ emacs Makefile 編集前 #オブジェクトファイルの指定 OBJS = WatchController.so 編集後 #オブジェクトファイルの指定 OBJS = WatchOrange.so $ make ***世界ファイル編集 [#d02191e6] 次に世界ファイルを編集します。 $ cd .. $ emacs xml/WatchWorld.xml 編集前 <!--コントローラの指定--> <set-attr-value name="implementation" value="./NewWorld/WatchController.so"/> 編集後 <!--コントローラの指定--> <set-attr-value name="implementation" value="./NewWorld/WatchOrange.so"/> ***実行 [#i1a28c90] それでは実行してみましょう。 $ ./sigserver.sh -w WatchWorld.xml -p 9001 #ref(watch_5.jpg) オレンジを見つけたら手を挙げます。 [[戻る>間節の操作]]