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

*物体が落下する仮想空間の作成 [#c6d40ee5]
このチュートリアルはv2.1.0以降に対応しています。v2.0.3以前は[[こちら>#s7e27ae3]]。

ここでは物体を落下させる動力学シミュレーションを行う新しい仮想空間を作成します。


**ディレクトリ構造 [#fea2aba6]
インストール先のディレクトリ構造は以下のようになります。

 sigverse-<version>
       |
       |---bin
       |---include
       |     +----sigverse       
       +---shared 
             +----sigverse
                     +----data
                     |     |----xml
                     |     +----shape
                     |----etc
                     |----jar
                     +----samples  
***設定ファイル [#w984ca88]
sigverse-<version>/shared/sigverse/data/xml の中にSIGVerseに登場可能なロボットやオブジェクトの設定ファイルや世界ファイルのサンプルが置かれています。

***形状ファイル [#a6c41c09]
sigverse-<version>/shared/sigverse/data/shape の中にX3D,VRMLで書かれた3次元形状モデルのサンプルが置かれています。

**作業ディレクトリ作成 [#jb22f95f]
まず作業ディレクトリを作成します。
どこでも構いませんがこのチュートリアルではhomeディレクトリの下にMyWorldというディレクトリを作成します。

SIGVerse作業ディレクトリを作成するにはsigcreate.shを使います

 $ cd ~/
 $ sigcreate.sh MyWorld
 
MyWorldディレクトリが作られます。

 $ cd MyWorld

この中には世界ファイルやコントローラ、Makefileなどのサンプルが用意されています。

***世界ファイルとは [#if9e5580]
世界ファイルとはSIGVerseに登場するキャラクターやSIGVerse世界の環境を設定することができるファイルです。世界ファイルを作成することにより自分独自の仮想世界を作成することができます。

***コントローラとは [#c3a3fbd9]

SIGVerseではC++で書かれたコントローラをSIGVerseエンティティにアタッチすることでエンティティは自律的に行動することができます。ここでは簡単なコントローラの作成方法について説明します。

**コントローラコンパイル [#b9411488]
サンプルとして用意されているコントローラをコンパイルします。
コントローラのコンパイルにはsigmake.shを使います。

 $ ./sigmake.sh ControllerSample.cpp

ControllerSample.soが作成されたら成功です。
これは何もしないコントローラです。

コントローラを見てみましょう
 $ emacs ControllerSample.cpp
#highlight(cpp){{
#include "ControllerEvent.h"
#include "Controller.h"
#include "Logger.h"

//ControllerのサブクラスMyController作成
class MyController : public Controller {
public:

  // シミュレーション開始時に一度だけ呼出される関数onInit
  void onInit(InitEvent &evt);

  // 定期的な処理を行うonAction
  double onAction(ActionEvent&);

  // メッセージ受信時に呼び出されます
  void onRecvMsg(RecvMsgEvent &evt);

  // 衝突時に呼び出されます
  void onCollision(CollisionEvent &evt);
};

void MyController::onInit(InitEvent &evt) {
}

double MyController::onAction(ActionEvent &evt) {
  return 1.0;     //次にonActionが呼ばれるまでの時間を返します
}

void MyController::onRecvMsg(RecvMsgEvent &evt) {
}

void MyController::onCollision(CollisionEvent &evt) {
}

//自身のインスタンスをSIGVerseに返します
extern "C" Controller * createController() {
  return new MyController;
}
}}
※コメントはチュートリアル用に付け加えています。

基本的にコントローラはContorollerクラスを継承して作成します。
これは何もしないコントローラです。1秒ごとに何もしない関数onActionが呼び出されます。
**世界ファイル [#y8597f04]
次に世界ファイルを見てみましょう

 $ emacs WorldSample.xml 

#highlight(xml){{
<?xml version="1.0" encoding="utf8"?>
<world name="myworld1">
  <!-- 重力設定 -->
  <gravity x="0.0" y="-980.7" z="0.0"/>

  <!-- 登場キャラクターの設定 -->
  <instanciate class="seToy_D.xml">

    <!-- キャラクターの名前 -->
    <set-attr-value name="name" value="toy_D"/>

    <!-- コントローラ指定 -->
    <set-attr-value name="language" value="c++"/>
    <set-attr-value name="implementation"
                    value="./ControllerSample.so"/>

    <!-- dynamicsモードon -->
    <set-attr-value name="dynamics" value="true"/>

    <!-- 初期位置 -->
    <set-attr-value name="x" value="0.0"/>
    <set-attr-value name="y" value="60.0"/>
    <set-attr-value name="z" value="0.0"/>

    <!-- 質量 -->
    <set-attr-value name="mass" value="1.0"/>

    <!-- 衝突判定on -->
    <set-attr-value name="collision" value="true"/>
  </instanciate>
</world>

}}

登場キャラクターとしてseToy_D.xmlが読み込まれます。

seToy_D.xmlは
sigverse-<version>/shared/sigverse/data/xmlの中に用意される、エンティティの設定ファイルです。

作成したコントローラの指定は以下のように設定しました。
 <set-attr-value name="implementation"
                    value="./ControllerSample.so"/>

それ以外にも仮想世界における重力や、エンティティの名前、位置、質量、dynamics、collisionなどの設定ができます。

**シミュレーション開始[#i190b28d]
それではSIGVerseを起動してみます。

 $ sigserver.sh -w ./WorldSample.xml 
       :
       :
 [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が読み込まれます。)


次にSIGViewerを起動して接続するホスト名とポート番号を入力し、"Connect"ボタンをクリックしてサーバに接続します。


#ref(動力学シミュレーションのサンプル(v2.0系)/toy_1.PNG,40%)

エージェントToy_Dが位置(0.0, 60.0, 0.0)でスタンバイしている様子が確認できます。SIGViewerでは目印として原点から三軸方向に短い線が伸びており、赤がx軸、黄色がy軸、緑がz軸であることが確認できます。

次に"START"ボタンを押してシミュレーションを開始します。

シミュレーションが開始し、エージェント(toy_D)が地面に落下して弾んでいるのが確認できます。

*エージェントの移動 [#z54adf9a]
次にエージェントに力を与えて移動させます。ControllerSample.cppを修正します。

 $ emacs ControllerSample.cpp

onActionの中に以下のコードを追加します。

ControllerSample.cpp

#highlight(cpp:firstline[16]){{
 double MyController::onAction(ActionEvent &evt) {
   return 1.0;      //次にonActionが呼ばれるまでの時間を返します。
 }
}}

     ↓
#highlight(cpp:firstline[16]){{
 double MyController::onAction(ActionEvent &evt) {
   SimObj *obj = getObj(myname());  //自分自身の取得
   obj->addForce(0,0,500);         //z軸方向に5000[kg・cm/s^2]の力を加える
   return 1.0;      //次にonActionが呼ばれるまでの時間を返します。
 }
}}

定期的に呼び出される関数onActionでエンティティに力を加えます。

コンパイルして実行します。
 $ ./sigmake.sh ControllerSample.cpp
 $ sigserver.sh -w ./NewWorld.xml 
 $ sigserver.sh -w ./WorldSample.xml 

SIGViewerで確認すると、1秒に一回エージェントがz方向に力が加えられて、移動しているのがわかります。

//SIGVerseシミュレーションにおける時間ステップ幅はデフォルトで0.01秒に設定されているため、力が加わるのは0.01秒間ということになります。

//#ref(動力学シミュレーションのサンプル(v120330, v1.4.8)/toy_3.jpg)

力を与える関数setForce以外にも速度を設定するsetVelocityやトルクを設定するsetTorqueなどもあるのでいろいろ試してみると面白いと思います。

*衝突判定用の形状、大きさ、位置の設定 [#n6779cdb]
衝突判定で用いるオブジェクトの形状は見た目の形状と異なり、球,Box,円柱で近似されています。衝突判定形状は見た目の形状から自動的に推定されます。

**衝突判定形状の確認 [#k4f9e6c5]

この衝突判定用の形状をビューワーで見ることができます。
ビューワーでオブジェクトを表示している状態でメニューバーのOptionをクリックし、Dynamics viewをクリックします。

#ref(dynamicsView1.PNG)

転がっているオブジェクトの衝突判定用形状を見ることができます。

#ref(./dynamicsView2.PNG,60%)

ペンギンキャラクターは球とみなされ物理シミュレーションが行われます。

**形状の設定 [#ofb6b204]

物理シミュレーションに使われる形状を少し変えてみます。
まずエンティティの設定ファイルを作業ディレクトリにコピーします。
 $ cp ~/sigverse-<version>/share/sigverse/data/xml/seToy_D.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>
}}

底面の円の半径3、円筒の高さ10のシリンダーに設定しました。

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

*単位系 [#c72a1e70]
SIGVerseでは単位系は以下を用います

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


*Old version [#s7e27ae3]
-[[動力学シミュレーションのサンプル(v2.0系)]]
-[[動力学シミュレーションのサンプル(v120330, v1.4.8)]]

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

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

#highlight(end)

Front page   Edit Diff Backup Upload Copy Rename Reload   New List of pages Search Recent changes   Help   RSS of recent changes