Up:Tutorial? Previous:エージェント視点の画像取得? Next:物体を持つ動作?
ここではエージェントが衝突したときに衝突したエンティティを検出してUターンするサンプルを紹介します。
$ cd ~/sigverse-<version>/bin/NewWorld $ emacs Colli.cpp
Colli.cpp
このサンプルコードは衝突を検出したら衝突した相手のエンティティ名を表示して、Uターンするというものです。衝突時に関数onCollisionが呼び出され、体を180°後ろに体を回転させます。onActionでは常に自分の向いている方向に進みます。また、このサンプルコードは2体のロボットが登場することを想定して、2体のロボットにそれぞれ違った速度を設定しています。
それではコンパイルします。
$ emacs Makefile
オブジェクトファイルの指定を変更します。
#オブジェクトファイルの指定 OBJS = Colli.so
$ make
世界ファイルを作成します。
$ cd .. $ emacs xml/ColliWorld.xml
ColliWorld.xml
ここではロボットが2体登場します。それぞれ同じコントローラを割り当てます。
それでは実行してみましょう。
$ ./sigserver.sh -w ColliWorld.xml -p 9001
#ref(): File not found: "Colli_3.jpg" at page "Collision detection by agents"
サーバに接続するとロボットが2体いて、人間が通せんぼしているのがわかります。 それではシミュレーションを開始してみましょう。
#ref(): File not found: "Colli_4.jpg" at page "Collision detection by agents"
まず前にいるロボットが人間と衝突して前にいるロボットだけがUターンします。
#ref(): File not found: "Colli_5.jpg" at page "Collision detection by agents"
次にロボット同士が衝突してそれぞれUターンします。
#ref(): File not found: "Colli_6.jpg" at page "Collision detection by agents"
この後、先ほどと同様に前にいるロボットがまた人間と衝突してUターンして、後ろにいるロボットを追いかけますが、前にいるロボットのほうが速度を早く設定しているため、いずれ後ろのロボットに追い付きます。
#ref(): File not found: "Colli_7.jpg" at page "Collision detection by agents"
追い付いたロボット2体は再びUターンをして人間の方向に進みます。
延々とこの動作を繰り返します。
SIGViewerの下のMessagesタブを見てみると衝突時に検出したエージェントの名前と衝突相手の名前が表示されています。
#ref(): File not found: "Colli_8.jpg" at page "Collision detection by agents"
上のサンプルコントローラではロボットのエージェントごとに速度が設定されています。パラメータの値を変えるたびにコンパイルするのは面倒なので、ここではエージェントに属性として速度を追加して、世界ファイルでパラメータの値を設定する方法を紹介します。
世界ファイルが読み込むロボットの設定ファイルを編集します。
$ emacs -nw xml/Robot-nii.xml
以下の行の追加により速度パラメータ"vel"を追加します。
<attr name="vel" type="double" group="velocity" value="0.0"/>
Robot-nii.xml
次に世界ファイルでエージェントごとに速度を設定します。
$ emacs xml/ColliWorld.xml
"robot_000"の属性の値を設定しているところ
の下に以下の一行を加えます。
<set-attr-value name="vel" value="5.0"/>
同様に"robot_001"の属性値を設定している箇所に以下を追加します。
<set-attr-value name="vel" value="7.0"/>
次にコントローラの編集を行います。
速度パラメータvelは世界ファイルで設定を行ったので、onInit関数の中のvelの設定箇所を以下のように変更します。
$ cd NewWorld $ emacs Colli.cpp
Colli.cpp
↓
これでコンパイルするとエージェントの速度は世界ファイルで設定可能となります。
$ make
正常に動作することを確認してみてください。
衝突判定を行うかどうかのフラグを設定することができます。 世界ファイルの衝突判定を行わないエージェントの箇所に以下の行を一行追加します。
<set-attr-value name="collision" value="false"/>
属性"collision"をfalseに設定した場合そのエンティティは衝突判定を行わなくなります。
このサンプルは奈良先端技術大学院大学の柴田智広先生にアドバイスをいただきました。ありがとうございました。