エージェントの衝突
[
Front page
] [
New
|
List of pages
|
Search
|
Recent changes
|
Help
]
Start:
Up:[[Tutorial]] Previous:[[エージェント視点の画...
-----
#contents
*エージェントの衝突 [#faf7135a]
※このチュートリアルはv2.1.0以降対応しています。
ここではエージェントが衝突したときに衝突したエンティティ...
**コントローラ作成 [#b16b5ba2]
$ cd ~/MyWorld
$ emacs Colli.cpp
Colli.cpp
#highlight(cpp){{
#include "Controller.h"
#include "ControllerEvent.h"
#include "Logger.h"
#include "math.h"
#define PI 3.141592
#define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 )
using namespace std;
class AgentController: public Controller {
public:
double onAction(ActionEvent &evt);
void onInit(InitEvent &evt);
//衝突時に呼出される関数onCollisionの利用を宣言します。
void onCollision(CollisionEvent &evt);
private:
//衝突フラグ
bool Colli;
int Colli_cnt;
double vel;
};
void AgentController::onInit(InitEvent &evt)
{
Colli = false;
Colli_cnt = 0;
//"robot_000"の速度設定
if(strstr(myname() , "000")!= NULL)
{
vel = 1;
}
//"robot_001"の速度設定
else if(strstr(myname() , "001")!= NULL)
{
vel = 2.0;
}
else
vel = 0;
}
//衝突時に呼び出されます。
void AgentController::onCollision(CollisionEvent &evt) {
if (Colli == false && Colli_cnt == 0){
const vector<string> & wname= evt.getWith(); /...
const vector<string> & wparts = evt.getWithParts(); ...
const vector<string> & mparts = evt.getMyParts(); ...
for(int i = 0; i < wname.size(); i++)
{
//衝突相手の名前表示します。
LOG_MSG(("\"%s\"", wname[i].c_str()));
LOG_MSG(("\"%s\"", wparts[i].c_str()));
LOG_MSG(("\"%s\"", mparts[i].c_str()));
//LOG_MSG(("\"%s\"", myParts));
SimObj *my = getObj(myname());
// 自分の回転を得ます(クオータニオン)
Rotation rot;
my->getRotation(rot);
//クオータニオンから回転角を導出します
double theta = 2*asin(rot.qy());
double dy = theta + DEG2RAD(-180);
if (dy <= -PI) {
dy = -1*dy - PI;
}
my->setAxisAndAngle(0, 1.0, 0, dy);
Colli = true;
Colli_cnt = 3;
}
}
}
double AgentController::onAction(ActionEvent &evt) {
try {
Controller * con;
SimObj *my = getObj(myname());
//自分の位置を得ます。
Vector3d pos;
my->getPosition(pos);
//y軸周りの自分の回転を得ます。(クオータニオン)
Rotation rot;
my->getRotation(rot);
//クオータニオンから回転角を導出します。
double theta = 2*asin(rot.qy());
double dx = 0;
double dz = 0;
//移動する方向を決定します。
dx = sin(theta) * vel;
dz = cos(theta) * vel;
//移動します。
my->setPosition( pos.x() + dx, pos.y() , pos.z() + dz...
if (Colli_cnt > 0)
{
if (--Colli_cnt <=0)
Colli = false;
}
} catch (SimObj::Exception &) {
}
return 0.1;
}
extern "C" Controller * createController() {
return new AgentController;
}
}}
このサンプルコードは衝突を検出したら衝突した相手のエンテ...
コンパイルします。
$ ./sigmake.sh Colli.cpp
**世界ファイルの作成 [#v96d9bc1]
世界ファイルを作成します。
$ emacs ColliWorld.xml
ColliWorld.xml
#highlight(xml){{
<?xml version="1.0" encoding="utf8"?>
<world name="myworld8">
<gravity x="0.0" y="-980.7" z="0.0"/>
<instanciate class="Robot-nii.xml">
<!--エージェント名-->
<set-attr-value name="name" value="robot_000"/>
<set-attr-value name="language" value="c++"/>
<!--オブジェクトファイルColli.soの指定-->
<set-attr-value name="implementation"
value="./Colli.so"/>
<set-attr-value name="dynamics" value="false"/>
<!--エージェントの位置-->
<set-attr-value name="x" value="90.0"/>
<set-attr-value name="y" value="58.0"/>
<set-attr-value name="z" value="-90.0"/>
<!--エージェントの向き(x,y,z) -->
<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"/>
<!--衝突判定を行うためcollisionフラグをtrueにします ...
<set-attr-value name="collision" value="true"/>
</instanciate>
<instanciate class="Robot-nii.xml">
<!--エージェント名-->
<set-attr-value name="name" value="robot_001"/>
<set-attr-value name="language" value="c++"/>
<!--オブジェクトファイルColli.soの指定-->
<set-attr-value name="implementation"
value="./Colli.so"/>
<set-attr-value name="dynamics" value="false"/>
<!--エージェントの位置-->
<set-attr-value name="x" value="30.0"/>
<set-attr-value name="y" value="58.0"/>
<set-attr-value name="z" value="-90.0"/>
<!--エージェントの向き(x,y,z) -->
<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"/>
<!--衝突判定を行うためcollisionフラグをtrueにします-->
<set-attr-value name="collision" value="true"/>
</instanciate>
<!--エージェントMan-niiの設定-->
<instanciate class="Man-nii.xml">
<!--エージェント名-->
<set-attr-value name="name" value="man_000"/>
<set-attr-value name="dynamics" value="false"/>
<set-attr-value name="x" value="-60.0"/>
<set-attr-value name="y" value="60.0"/>
<set-attr-value name="z" value="-100.0"/>
<!--エージェントの向き(x,y,z) -->
<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"/>
<!--衝突判定を行うためcollisionフラグをtrueにします-->
<set-attr-value name="collision" value="true"/>
</instanciate>
</world>
}}
ここではロボットが2体登場します。それぞれ同じコントローラ...
衝突判定を行うエンティティは以下のように属性"collision"を...
#highlight(xml:firstline[27]){{
<set-attr-value name="collision" value="true"/>
}}
**実行 [#ge5926ae]
それでは実行してみましょう。
$ sigserver.sh -w ./ColliWorld.xml
#ref(エージェントの衝突(v2.0系)/Colli_1.PNG,40%)
サーバに接続するとロボットが2体いて、人間が通せんぼしてい...
それではシミュレーションを開始してみましょう。
#ref(エージェントの衝突(v2.0系)/Colli_2.PNG,40%)
まず前にいるロボットが人間と衝突して前にいるロボットだけ...
#ref(エージェントの衝突(v2.0系)/Colli_3.PNG,40%)
次にロボット同士が衝突してそれぞれUターンします。
この後、先ほどと同様に前にいるロボットがまた人間と衝突し...
追い付いたロボット2体は再びUターンをして人間の方向に進み...
延々とこの動作を繰り返します。
*属性の追加 [#i5f76bfa]
上のサンプルコントローラではロボットのエージェントごとに...
**エンティティファイルの編集 [#xcda9213]
世界ファイルが読み込むロボットの設定ファイルを編集します。
まずロボットの設定ファイルをカレントディレクトリにコピー...
$ cp ~/sigverse-<version>/share/sigverse/data/xml/Robot-...
以下の行を追加します。
<attr name="vel" type="double" group="velocity" value="0...
Robot-nii.xml
#highlight(xml){{
<?xml version="1.0" encoding="utf8"?>
<define-class name="Robot" inherit="Agent.xml">
<set-attr-value name="scalex" value="0.7"/>
<set-attr-value name="scaley" value="0.7"/>
<set-attr-value name="scalez" value="0.7"/>
<!-- 属性"vel"を追加 -->
<attr name="vel" type="double" group="velocity" value=...
<x3d>
<filename>nii_robot.x3d</filename>
</x3d>
</define-class>
}}
**世界ファイルの編集 [#l72a2513]
次に世界ファイルでエージェントごとに速度を設定します。
$ emacs ColliWorld.xml
"robot_000"の属性の値を設定しているところ
#highlight(xml:firstline[26]){{
<!--衝突判定を行うためcollisionフラグをtrueにします --...
<set-attr-value name="collision" value="true"/>
}}
の下に以下の一行を加えます。
<set-attr-value name="vel" value="1.0"/>
同様に"robot_001"の属性値を設定している箇所に以下を追加し...
<set-attr-value name="vel" value="2.0"/>
**コントローラの編集 [#v237b73a]
次にコントローラの編集を行います。
速度パラメータvelは世界ファイルで設定を行ったので、onInit...
$ emacs Colli.cpp
Colli.cpp
#highlight(cpp:firstline[28]){{
void AgentController::onInit(InitEvent &evt)
{
Colli = false;
Colli_cnt = 0;
//"robot_000"の速度設定
if(strstr(myname() , "000")!= NULL)
{
vel = 1;
}
//"robot_001"の速度設定
else if(strstr(myname() , "001")!= NULL)
{
vel = 2;
}
else
vel = 0;
}
}}
↓
#highlight(cpp:firstline[27]){{
void AgentController::onInit(InitEvent &evt)
{
Colli = false;
Colli_cnt = 0;
//自分の速度を得ます。
SimObj *my = getObj(myname());
vel = my->getAttr("vel").value().getDouble();
}
}}
これでコンパイルするとエージェントの速度は世界ファイルで...
$ ./sigmake.sh Colli.cpp
正常に動作することを確認してみてください。
*謝辞 [#ad94a306]
このサンプルは奈良先端技術大学院大学の柴田智広先生にアド...
#highlight(end)
*Old Version [#cf12fda7]
-[[エージェントの衝突(v2.0系)]]
-[[エージェントの衝突(v120330, v1.4.8)]]
----
Up:[[Tutorial]] Previous:[[エージェント視点の画...
#counter
End:
Up:[[Tutorial]] Previous:[[エージェント視点の画...
-----
#contents
*エージェントの衝突 [#faf7135a]
※このチュートリアルはv2.1.0以降対応しています。
ここではエージェントが衝突したときに衝突したエンティティ...
**コントローラ作成 [#b16b5ba2]
$ cd ~/MyWorld
$ emacs Colli.cpp
Colli.cpp
#highlight(cpp){{
#include "Controller.h"
#include "ControllerEvent.h"
#include "Logger.h"
#include "math.h"
#define PI 3.141592
#define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 )
using namespace std;
class AgentController: public Controller {
public:
double onAction(ActionEvent &evt);
void onInit(InitEvent &evt);
//衝突時に呼出される関数onCollisionの利用を宣言します。
void onCollision(CollisionEvent &evt);
private:
//衝突フラグ
bool Colli;
int Colli_cnt;
double vel;
};
void AgentController::onInit(InitEvent &evt)
{
Colli = false;
Colli_cnt = 0;
//"robot_000"の速度設定
if(strstr(myname() , "000")!= NULL)
{
vel = 1;
}
//"robot_001"の速度設定
else if(strstr(myname() , "001")!= NULL)
{
vel = 2.0;
}
else
vel = 0;
}
//衝突時に呼び出されます。
void AgentController::onCollision(CollisionEvent &evt) {
if (Colli == false && Colli_cnt == 0){
const vector<string> & wname= evt.getWith(); /...
const vector<string> & wparts = evt.getWithParts(); ...
const vector<string> & mparts = evt.getMyParts(); ...
for(int i = 0; i < wname.size(); i++)
{
//衝突相手の名前表示します。
LOG_MSG(("\"%s\"", wname[i].c_str()));
LOG_MSG(("\"%s\"", wparts[i].c_str()));
LOG_MSG(("\"%s\"", mparts[i].c_str()));
//LOG_MSG(("\"%s\"", myParts));
SimObj *my = getObj(myname());
// 自分の回転を得ます(クオータニオン)
Rotation rot;
my->getRotation(rot);
//クオータニオンから回転角を導出します
double theta = 2*asin(rot.qy());
double dy = theta + DEG2RAD(-180);
if (dy <= -PI) {
dy = -1*dy - PI;
}
my->setAxisAndAngle(0, 1.0, 0, dy);
Colli = true;
Colli_cnt = 3;
}
}
}
double AgentController::onAction(ActionEvent &evt) {
try {
Controller * con;
SimObj *my = getObj(myname());
//自分の位置を得ます。
Vector3d pos;
my->getPosition(pos);
//y軸周りの自分の回転を得ます。(クオータニオン)
Rotation rot;
my->getRotation(rot);
//クオータニオンから回転角を導出します。
double theta = 2*asin(rot.qy());
double dx = 0;
double dz = 0;
//移動する方向を決定します。
dx = sin(theta) * vel;
dz = cos(theta) * vel;
//移動します。
my->setPosition( pos.x() + dx, pos.y() , pos.z() + dz...
if (Colli_cnt > 0)
{
if (--Colli_cnt <=0)
Colli = false;
}
} catch (SimObj::Exception &) {
}
return 0.1;
}
extern "C" Controller * createController() {
return new AgentController;
}
}}
このサンプルコードは衝突を検出したら衝突した相手のエンテ...
コンパイルします。
$ ./sigmake.sh Colli.cpp
**世界ファイルの作成 [#v96d9bc1]
世界ファイルを作成します。
$ emacs ColliWorld.xml
ColliWorld.xml
#highlight(xml){{
<?xml version="1.0" encoding="utf8"?>
<world name="myworld8">
<gravity x="0.0" y="-980.7" z="0.0"/>
<instanciate class="Robot-nii.xml">
<!--エージェント名-->
<set-attr-value name="name" value="robot_000"/>
<set-attr-value name="language" value="c++"/>
<!--オブジェクトファイルColli.soの指定-->
<set-attr-value name="implementation"
value="./Colli.so"/>
<set-attr-value name="dynamics" value="false"/>
<!--エージェントの位置-->
<set-attr-value name="x" value="90.0"/>
<set-attr-value name="y" value="58.0"/>
<set-attr-value name="z" value="-90.0"/>
<!--エージェントの向き(x,y,z) -->
<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"/>
<!--衝突判定を行うためcollisionフラグをtrueにします ...
<set-attr-value name="collision" value="true"/>
</instanciate>
<instanciate class="Robot-nii.xml">
<!--エージェント名-->
<set-attr-value name="name" value="robot_001"/>
<set-attr-value name="language" value="c++"/>
<!--オブジェクトファイルColli.soの指定-->
<set-attr-value name="implementation"
value="./Colli.so"/>
<set-attr-value name="dynamics" value="false"/>
<!--エージェントの位置-->
<set-attr-value name="x" value="30.0"/>
<set-attr-value name="y" value="58.0"/>
<set-attr-value name="z" value="-90.0"/>
<!--エージェントの向き(x,y,z) -->
<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"/>
<!--衝突判定を行うためcollisionフラグをtrueにします-->
<set-attr-value name="collision" value="true"/>
</instanciate>
<!--エージェントMan-niiの設定-->
<instanciate class="Man-nii.xml">
<!--エージェント名-->
<set-attr-value name="name" value="man_000"/>
<set-attr-value name="dynamics" value="false"/>
<set-attr-value name="x" value="-60.0"/>
<set-attr-value name="y" value="60.0"/>
<set-attr-value name="z" value="-100.0"/>
<!--エージェントの向き(x,y,z) -->
<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"/>
<!--衝突判定を行うためcollisionフラグをtrueにします-->
<set-attr-value name="collision" value="true"/>
</instanciate>
</world>
}}
ここではロボットが2体登場します。それぞれ同じコントローラ...
衝突判定を行うエンティティは以下のように属性"collision"を...
#highlight(xml:firstline[27]){{
<set-attr-value name="collision" value="true"/>
}}
**実行 [#ge5926ae]
それでは実行してみましょう。
$ sigserver.sh -w ./ColliWorld.xml
#ref(エージェントの衝突(v2.0系)/Colli_1.PNG,40%)
サーバに接続するとロボットが2体いて、人間が通せんぼしてい...
それではシミュレーションを開始してみましょう。
#ref(エージェントの衝突(v2.0系)/Colli_2.PNG,40%)
まず前にいるロボットが人間と衝突して前にいるロボットだけ...
#ref(エージェントの衝突(v2.0系)/Colli_3.PNG,40%)
次にロボット同士が衝突してそれぞれUターンします。
この後、先ほどと同様に前にいるロボットがまた人間と衝突し...
追い付いたロボット2体は再びUターンをして人間の方向に進み...
延々とこの動作を繰り返します。
*属性の追加 [#i5f76bfa]
上のサンプルコントローラではロボットのエージェントごとに...
**エンティティファイルの編集 [#xcda9213]
世界ファイルが読み込むロボットの設定ファイルを編集します。
まずロボットの設定ファイルをカレントディレクトリにコピー...
$ cp ~/sigverse-<version>/share/sigverse/data/xml/Robot-...
以下の行を追加します。
<attr name="vel" type="double" group="velocity" value="0...
Robot-nii.xml
#highlight(xml){{
<?xml version="1.0" encoding="utf8"?>
<define-class name="Robot" inherit="Agent.xml">
<set-attr-value name="scalex" value="0.7"/>
<set-attr-value name="scaley" value="0.7"/>
<set-attr-value name="scalez" value="0.7"/>
<!-- 属性"vel"を追加 -->
<attr name="vel" type="double" group="velocity" value=...
<x3d>
<filename>nii_robot.x3d</filename>
</x3d>
</define-class>
}}
**世界ファイルの編集 [#l72a2513]
次に世界ファイルでエージェントごとに速度を設定します。
$ emacs ColliWorld.xml
"robot_000"の属性の値を設定しているところ
#highlight(xml:firstline[26]){{
<!--衝突判定を行うためcollisionフラグをtrueにします --...
<set-attr-value name="collision" value="true"/>
}}
の下に以下の一行を加えます。
<set-attr-value name="vel" value="1.0"/>
同様に"robot_001"の属性値を設定している箇所に以下を追加し...
<set-attr-value name="vel" value="2.0"/>
**コントローラの編集 [#v237b73a]
次にコントローラの編集を行います。
速度パラメータvelは世界ファイルで設定を行ったので、onInit...
$ emacs Colli.cpp
Colli.cpp
#highlight(cpp:firstline[28]){{
void AgentController::onInit(InitEvent &evt)
{
Colli = false;
Colli_cnt = 0;
//"robot_000"の速度設定
if(strstr(myname() , "000")!= NULL)
{
vel = 1;
}
//"robot_001"の速度設定
else if(strstr(myname() , "001")!= NULL)
{
vel = 2;
}
else
vel = 0;
}
}}
↓
#highlight(cpp:firstline[27]){{
void AgentController::onInit(InitEvent &evt)
{
Colli = false;
Colli_cnt = 0;
//自分の速度を得ます。
SimObj *my = getObj(myname());
vel = my->getAttr("vel").value().getDouble();
}
}}
これでコンパイルするとエージェントの速度は世界ファイルで...
$ ./sigmake.sh Colli.cpp
正常に動作することを確認してみてください。
*謝辞 [#ad94a306]
このサンプルは奈良先端技術大学院大学の柴田智広先生にアド...
#highlight(end)
*Old Version [#cf12fda7]
-[[エージェントの衝突(v2.0系)]]
-[[エージェントの衝突(v120330, v1.4.8)]]
----
Up:[[Tutorial]] Previous:[[エージェント視点の画...
#counter
Page: