Up:[[Tutorial]] Previous:[[テスト実行]] Next:[[人間型エージェントの操作]] ---- #contents *物体が落下する仮想空間の作成 [#c6d40ee5] ここでは物体を落下させる動力学シミュレーションを行う新しい仮想空間を作成します。 **ディレクトリ構造 [#fea2aba6] インストールしたパッケージのディレクトリ構造は以下のようになります。 sigverse-<version> | |---bin |---include | +----sigverse +---shared +----sigverse +----data | |----xml | +----shape |----etc |----jar +----samples まず自分の好きな場所(たとえばホームディレクトリ)にディレクトリを作りそこを作業場所とします。 ※このチュートリアルではsigverse-<version>/binに新しくディレクトリを作りそこを作業場所とします。 **エージェントコントローラの作成 [#b9411488] 簡単なエージェントコントローラを作成します。 エージェントとは仮想世界で自律動作を行う物体のことを言います。 まずSIGVerseの sigverse-<version>/binに移動します。 $ cd ~/sigverse-<version>/bin ここに新しいディレクトリを作成します。 $ mkdir NewWorld $ cd NewWorld emacsまたはviなどのエディタを使ってMoveController.cppファイルを作成します。 $ emacs MoveController.cpp MoveController.cpp #highlight(cpp){{ #include "Controller.h" #include "Logger.h" //ControllerのサブクラスMoveControllerの宣言します。 class MoveController : public Controller { public: //定期的な処理を行うonActionの利用を宣言します。 double onAction(ActionEvent&); }; double MoveController::onAction(ActionEvent &evt) { return 5.0; //次にonActionが呼ばれるまでの時間を返します。 } //自身のインスタンスをSIGVerseに返します。 extern "C" Controller * createController() { return new MoveController; } }} ※ファイル保存時にコードシステムを聞かれたら今後すべてutf-8を指定してください。 これは何もしないコントローラです。5秒ごとに何もしない関数onActionが呼び出されます。 **コンパイル [#hf0f4b09] 次に作成したコードのコンパイルを行うためのmakefileを作成します。 // emacs make.sh //make.sh // #!/bin/sh // #SIGVerseソースの場所を指定します。 // export SIG_SRC="/home/<username>/sigverse-201003/include/sigverse" // #コンパイルを行います。 // make clean // make $ emacs Makefile Makefile #SIGVerseソースの場所指定 SIG_SRC = /home/<username>/sigverse-<version>/include/sigverse #オブジェクトファイルの指定 OBJS = MoveController.so all: $(OBJS) #コンパイルを行います。 ./%.so: ./%.cpp g++ -DCONTROLLER -DNDEBUG -DUSE_ODE -DdDOUBLE -I$(SIG_SRC) -I$(SIG_SRC)/comm/controller -fPIC -shared -o $@ $< ※<username>はユーザー名、<version>はバージョン番号に置き換えます。 コマンド行のg++の前のスペースはTabですので注意してください。 makeを実行します。 $ make MoveController.soが作成されていればコンパイル成功です。 $ ls Makefile MoveController.cpp MoveController.so **世界ファイルの作成 [#j3bf1bf8] 次に仮想世界の設定を記述した世界ファイルを作成します。世界ファイルでは仮想世界に登場するエージェントの設定を行います。 世界ファイルをsigverse-<version>/share/sigverse/data/xmlに作成します。 $ cd ~/sigverse-<version>/share/sigverse/data/xml $ emacs NewWorld.xml NewWorld.xml #highlight(xml){{ <?xml version="1.0" encoding="utf8"?> <world name="myworld1"> <!--重力の設定--> <gravity x="0.0" y="-9.8" z="0.0"/> <!--エージェントToy_Dのインスタンス作成--> <instanciate class="seToy_D.xml"> <!--エージェント名--> <set-attr-value name="name" value="Toy_D"/> <!--C++言語の指定--> <set-attr-value name="language" value="c++"/> <!--作成したコントローラの指定--> <set-attr-value name="implementation" value="./NewWorld/MoveController.so"/> <!--動力学演算フラグ--> <set-attr-value name="dynamics" value="true"/> <!--エージェントの最初の位置(x,y,z)--> <set-attr-value name="x" value="0.0"/> <set-attr-value name="y" value="18.0"/> <set-attr-value name="z" value="5.0"/> <!--エージェントの質量設定--> <set-attr-value name="mass" value="1.0"/> </instanciate> </world> }} ここでは動力学シミュレーションを行うため"dynamics"を"true"に設定しました。また、エージェントとしてseToy_D.xmlというファイルを読み込むように設定しています。さまざまなエージェントやエンティティの形状ファイル(x3d,wrlファイル)やそれに付随したxmlファイルがあらかじめ用意されているので、それを用います。 作成したコントローラの指定は以下のように設定しました。 #highlight(xml:firstline[18]){{ <set-attr-value name="implementation" value="./NewWorld/MoveController.so"/> }} 作成したコントローラのパスを指定するときはシグバースを実行する場所(sigserver.shがある場所)からの相対パス、または絶対パスを指定します。 これで準備は完了です。 **シミュレーション開始[#i190b28d] それではSIGVerseを起動してみます。 sigverseを起動するにはシグバースインストール先の~/sigverse-<version>/binにある シェルスクリプトsigserver.shを使って実行します。 わざわざディレクトリを移動するのが面倒な場合は $ export PATH=$PATH:/home/<username>/sigverse-<version>/bin でシェルスクリプトがあるディレクトリのパスを通しておきます。 また、作業場所にこのファイルをコピーして使用することもできます。 $ cd ~/sigverse-<version>/bin $ ./sigserver.sh -w NewWorld.xml -p 9001 : : [SYS] waiting for connection... [SYS] Controller attached to "Toy_D" [SYS] 127.0.0.1 connected [SYS] Toy_D : dataport [SYS] 127.0.0.1 connected この時-wオプションで作成した世界ファイルを指定します。(何も指定しないときはMyWorld.xmlが読み込まれます。) xmlファイルの中で今回作成したコントローラを指定したので、SIGVerseの起動と同時に自動的にエージェント"Toy_D"にアタッチされました。 次にSIGViewerを起動して接続するホスト名とポート番号を入力し、Connect to SimServerボタンをクリックしてサーバに接続します。 #ref(toy_1.jpg) エージェントToy_Dが世界ファイルで記述した位置(0.0, 18.0, 5.0)でスタンバイしている様子が確認できます。SIGVerseではy方向が高さになります。 次にSIM_CTRL_CMDの枠の中がSTARTとなっている状態でSendボタンを押してシミュレーションを開始します。 #ref(toy_2.jpg) シミュレーションが開始し、エージェント(toy_D)が地面に落下して弾んでいるのが確認できます。 *エージェントの移動 [#z54adf9a] 次にエージェントに力を与えて移動させます。MoveController.cppを修正します。 $ cd NewWorld $ emacs MoveController.cpp onActionの中に以下のコードを追加します。 MoveController.cpp #highlight(cpp:firstline[13]){{ double MoveController::onAction(ActionEvent &evt) { return 5.0; //次にonActionが呼ばれるまでの時間を返します。 } }} ↓ #highlight(cpp:firstline[13]){{ double MoveController::onAction(ActionEvent &evt) { SimObj *obj = getObj(myname()); //自分自身の取得 obj->setForce(0,0,300); //z軸方向に300[N]の力を加える return 5.0; //次にonActionが呼ばれるまでの時間を返します。 } }} コンパイルして実行します。 $ make $ cd .. $ ./sigserver.sh -w NewWorld.xml -p 9001 SIGViewerで確認すると、5秒に一回エージェントがz方向に力が加えられて、移動しているのがわかります。 #ref(toy_3.jpg) 力を与える関数setForce以外にも加速度を設定するsetAccelやトルクを設定するsetTorqueなどもあるのでいろいろ試してみると面白いと思います。 *物理演算用の形状、大きさ、位置の設定 [#n6779cdb] 物理演算で用いるオブジェクトの形状は見た目の形状と異なり、sphere,cube, cylinderで近似されています。デフォルトでは見た目と大体同じ形状、大きさに設定されていますが、これらを設定ファイルで修正することができます。 **設定ファイル修正 [#ofb6b204] まず、オブジェクトの設定ファイルを編集します。 $ cd ~/sigverse-<version>/share/sigverse/data/xml $ emacs seToy_D.xml seToy_D.xmlの中の <body filename="dummy-body.xml"/> の下に以下のいずれかを追加します。 ***box [#b90fa015] #highlight(xml:nogutter){{ <!--形状をboxに設定します。--> <simpleShape type="box"> <!--物理演算形状の位置(見た目の形状からのずれ)を設定します。--> <position x="0" y="0" z="0"/> <!--物理演算用の形状のサイズを設定します。--> <size sx="10" sy="10" sz="10"/> </simpleShape> }} 一辺が10の立方体に設定しました。 ***sphere [#f0404294] sphereに設定する場合は以下のように設定します。 #highlight(xml:nogutter){{ <simpleShape type="sphere"> <position x="0" y="0" z="0"/> <size r="10"/> </simpleShape> }} 半径10の球に設定しました。 ***cylinder [#z94a7687] #highlight(xml:nogutter){{ <simpleShape type="cylinder"> <position x="0" y="0" z="0"/> <size r="3" h="10"/> </simpleShape> }} ※2011/10時点ではシリンダ形状の代わりにカプセル型形状を作ります。 底面の円の半径3、円筒の高さ10のシリンダーに設定しました。 **実行 [#r537a2f8] 再度シグバースを実行してエージェントが落下した時や、力を加えた時の動きの違いを確認してみてください。 Up:[[Tutorial]] Previous:[[テスト実行]] Next:[[人間型エージェントの操作]] [[English version>Samples/Control of humanoid agent]] #highlight(end)