**新規仮想空間の作成 [#c6d40ee5]
ここでは新しい仮想空間を作成します。
前回インストールしたSIGVerseの sigverse-<version>/binに移動します。
[[Tutorial]]

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または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) {
   SimObj *obj = getObj(myname());
   obj->fz(1000);
   return 5.0;
   return 5.0;      //次にonActionが呼ばれるまでの時間を返します。
 }
 
 //自身のインスタンスをSIGVerseに返します。
 extern "C" Controller * createController() {
   return new MoveController;
      return new MoveController;
 }
}}
※ファイル保存時にコードシステムを聞かれたら今後すべてutf-8を指定してください。

基本的にコントローラはContorollerクラスを継承して作成します。
これは何もしないコントローラです。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  = ../../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 $@   $<

※コマンド行の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="20.0"/>
    <set-attr-value name="z" value="0.0"/>

    <!--エージェントの質量設定-->
    <set-attr-value name="mass" value="1.0"/>

  </instanciate>
</world>
}}


ここでは動力学シミュレーションを行うため"dynamics"を"true"に設定しました。また、地面との衝突判定を行うため"collision"を"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ボタンを押してシミュレーションを開始します。

シミュレーションが開始し、エージェント(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以外にも速度を設定するsetVelocityやトルクを設定する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のシリンダーに設定しました。
※オブジェクトの大きさを0に設定し、物理演算用の形状を作らないことも可能です。

**実行 [#r537a2f8]
再度シグバースを実行してエージェントが落下した時や、力を加えた時の動きの違いを確認してみてください。

*単位系 [#c72a1e70]
SIGVerseでは単位系は角度(ラジアン)以外は特に決まっていませんが、このチュートリアルでは世界標準の国際(SI)単位系を用います。

|量|名称|記号|
|長さ|メートル|m|
|質量|キログラム|kg|
|時間|秒|s|
|角度|ラジアン|rad|
|速度|メートル毎秒|m/s|
|加速度|メートル毎秒毎秒|m/s^2|
|力|ニュートン|N|
|トルク|ニュートン・メートル|Nm|

Up:[[Tutorial]]     Previous:[[テスト実行]]     Next:[[人間型エージェントの操作]]

[[English version>Samples/Control of humanoid agent]]

#highlight(end)


Front page   New List of pages Search Recent changes   Help   RSS of recent changes