エージェント間のメッセージのやりとり(v120330, v1.4.8)
[
Front page
] [
New
|
List of pages
|
Search
|
Recent changes
|
Help
]
Start:
Up:[[Tutorial]] Previous:[[人間型エージェントの...
#contents
*エージェント間でのメッセージのやり取り [#he80bd53]
前回はクライアント(SIGViewer)からエージェントにメッセー...
**メッセージの送受信 [#v4c148e5]
***メッセージ送信者のコントローラ作成 [#pd6017d2]
まずメッセージの送信を行うコントローラを作成します。
$ cd ~/sigverse-<version>/bin/NewWorld
$ emacs SendController.cpp
SendController.cpp
#highlight(cpp){{
#include "Controller.h"
#include "Logger.h"
#include "ControllerEvent.h"
#define PI 3.141592
#define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 )
#define ARY_SIZE(ARY) ( (int)(sizeof(ARY)/sizeof(ARY[0])...
class SendController : public Controller
{
public:
//シミュレーション開始時に一度だけ呼出される関数onInit...
void onInit(InitEvent &evt);
double onAction(ActionEvent &evt);
};
void SendController::onInit(InitEvent &evt)
{
SimObj *my = getObj(myname());
if (!my->dynamics()) {
//右手、左手を下げ、体全体を180°後ろに回転させます。
my->setJointAngle("LARM_JOINT2", DEG2RAD(-90));
my->setJointAngle("RARM_JOINT2", DEG2RAD(90));
my->setAxisAndAngle(0, 1.0, 0, DEG2RAD(180));
}
}
double SendController::onAction(ActionEvent &evt)
{
//メッセージを作成します。
char *strs[] = {
"Hello!!",
};
//エージェント全員にメッセージを送信します。
broadcastMessage(ARY_SIZE(strs),strs);
//5秒置きにメッセージを送信します。
return 5.0;
}
extern "C" Controller * createController ()
{
return new SendController;
}
}}
これは5秒置きにメッセージ"Hello!"を送信するコントローラの...
メッセージを送る相手を指定したいときはbroadcastMessageの...
#highlight(cpp:firstline[40]){{
broadcastMessage(ARY_SIZE(strs),strs);
}}
↓
#highlight(cpp:firstline[40]){{
sendMessaage("robot_000",ARY_SIZE(strs), strs);
}}
メッセージを送信する相手に"robot_000"を指定しました。
***メッセージ受信者のコントローラ作成 [#sb6efc03]
次にメッセージの受信を行うエージェントコントローラを作成...
$ emacs RecvController.cpp
RecvController.cpp
#highlight(cpp){{
#include "Controller.h"
#include "Logger.h"
#include "ControllerEvent.h"
#define PI 3.141592
#define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 )
class RecvController : public Controller
{
public:
double onAction(ActionEvent &evt);
//メッセージ受信時に呼び出される関数onRecvMessageの利...
void onRecvMessage(RecvMessageEvent &evt);
};
double RecvController::onAction(ActionEvent &evt)
{
SimObj *my = getObj(myname());
if (!my->dynamics()) {
//上がった手を下げます。
my->setJointAngle("LARM_JOINT2", DEG2RAD(0));
}
return 1.0;
}
//メッセージ受信時
void RecvController::onRecvMessage(RecvMessageEvent &evt)
{
//自分自身の取得
SimObj *my = getObj(myname());
// メッセージの送り主表示
LOG_MSG(("sender : %s", evt.getSender()));
// getSize で送られてきた文字列数を取得する
int n = evt.getSize();
LOG_MSG(("# of string : %d", n));
for (int i=0; i<n; i++) {
// 文字列を順に取得する
LOG_MSG(("string[%d] : %s", i, evt.getString(i)));
//手を上げます。
if (!my->dynamics() ) {
my->setJointAngle("LARM_JOINT2", DEG2RAD(180));
}
}
}
extern "C" Controller * createController ()
{
return new RecvController;
}
}}
これはメッセージを受信したら手を上げるというサンプルです...
それではコンパイルします。
まずMakefileを修正します。
$ emacs Makefile
変更前
#オブジェクトファイルの指定
OBJS = AgentController.so
変更後
#オブジェクトファイルの指定
OBJS = SendController.so RecvController.so
共有オブジェクトにSendController.so, RecvController.soの2...
Makefile
#SIGVerseソースの場所指定
SIG_SRC = /home/<username>/sigverse-<version>/include/s...
#オブジェクトファイルの指定
OBJS = SendController.so RecvController.so
all: $(OBJS)
#コンパイルを行います。
./%.so: ./%.cpp
g++ -DCONTROLLER -DNDEBUG -DUSE_ODE -DdDOUBLE -I...
$ make
***世界ファイルの作成 [#me49924f]
次に世界ファイルを作成します。
$ cd ..
$ emacs xml/MessageWorld.xml
MessageWorld.xml
#highlight(xml){{
<?xml version="1.0" encoding="utf8"?>
<world name="myworld3">
<gravity x="0.0" y="-9.8" z="0.0"/>
<!--メッセージ送信エージェント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="language" value="c++"/>
<!--メッセージ送信者のコントローラ指定-->
<set-attr-value name="implementation"
value="./NewWorld/SendController.so"/>
<!--エージェントの位置(x,y,z)-->
<set-attr-value name="x" value="0.0"/>
<set-attr-value name="y" value="60.0"/>
<set-attr-value name="z" value="60.0"/>
</instanciate>
<!--メッセージ受信エージェントRobot-niiの設定-->
<instanciate class="Robot-nii.xml">
<set-attr-value name="name" value="robot_000"/>
<set-attr-value name="language" value="c++"/>
<!--メッセージ受信者のコントローラ指定-->
<set-attr-value name="implementation"
value="./NewWorld/RecvController.so"/>
<!--動力学演算をfalseに設定-->
<set-attr-value name="dynamics" value="false"/>
<!--エージェントの位置(x,y,z)-->
<set-attr-value name="x" value="0.0"/>
<set-attr-value name="y" value="60.0"/>
<set-attr-value name="z" value="-60.0"/>
</instanciate>
</world>
}}
人型エージェントが、ヒューマノイド型エージェントにメッセ...
***起動 [#k2bccc17]
起動して見てみましょう。
$ ./sigserver.sh -w MessageWorld.xml -p 9001
SIGViewerで接続して、シミュレーションを開始するとonInitに...
#ref(mess_1.jpg)
SIGViewerの下のほうにあるmessagesタブをクリックします。す...
#ref(mess_2.jpg)
文字列の数(# of string)は1と表示されましたが、コントロ...
//メッセージを作成します。
char *strs[] = {
"Hello!!",
"How are you",
};
**テキスト文字列の送受信 [#a561e72f]
次にエージェント間でのテキスト文字列の送受信について説明...
***テキスト送信者のコントローラ作成 [#wb648f75]
まずはテキストを送信するコントローラを作成します。
$ cd NewWorld
$ emacs SendText.cpp
SendText.cpp
#highlight(cpp){{
#include "Controller.h"
#include "Logger.h"
#include "ControllerEvent.h"
#define PI 3.141592
#define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 )
class SendController : public Controller
{
public:
void onInit(InitEvent &evt);
double onAction(ActionEvent &evt);
};
void SendController::onInit(InitEvent &evt)
{
SimObj *my = getObj(myname());
if (!my->dynamics()) {
my->setJointAngle("LARM_JOINT2", DEG2RAD(-90));
my->setJointAngle("RARM_JOINT2", DEG2RAD(90));
my->setAxisAndAngle(0, 1.0, 0, DEG2RAD(180));
}
}
double SendController::onAction(ActionEvent &evt)
{
try
{
SimObj *my = getObj(myname());
//自分の位置を得ます。
double x = my->x();
double y = my->y();
double z = my->z();
//z方向に20移動します。
my->setPosition( x, y, z + 20 );
//半径300.0以内のすべてのエージェントに対してテキス...
sendText(evt.time(), NULL, "Hello!", 300.0);
}catch(SimObj::Exception &) {
;
}
//3秒後にonActionが呼び出されます。
return 3.0;
}
extern "C" Controller * createController ()
{
return new SendController;
}
}}
これは3秒に1回テキスト"Hello!"を送信するコントローラです...
このエージェントはz方向にどんどん移動しながらテキストを送...
***テキスト受信者のコントローラ作成 [#jfd5b8e7]
テキスト受信者のコントローラを作成します。
$ emacs RecvText.cpp
RecvText.cpp
#highlight(cpp){{
#include <string>
#include "Controller.h"
#include "Logger.h"
#include "ControllerEvent.h"
#define PI 3.141592
#define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 )
class RecvController : public Controller
{
public:
double onAction(ActionEvent &evt);
//テキスト受信時に呼出される関数onRecvTextの利用を宣言...
void onRecvText(RecvTextEvent &evt);
};
double RecvController::onAction(ActionEvent &evt)
{
SimObj *my = getObj(myname());
if (!my->dynamics()) {
my->setJointAngle("LARM_JOINT2", DEG2RAD(0));
}
return 1.0;
}
//テキスト受信時
void RecvController::onRecvText(RecvTextEvent &evt)
{
//自分自身を取得します。
SimObj *my = getObj(myname());
// テキストの送り主を取得します。
const char *caller = evt.getCaller();
//テキストの内容を取得します。
const char *text = evt.getText();
//送り主と内容を表示します。
LOG_MSG(("receive from %s : \"%s\"", caller, text));
//手を挙げます。
if (!my->dynamics()) {
my->setJointAngle("LARM_JOINT2", DEG2RAD(180));
}
}
extern "C" Controller * createController ()
{
return new RecvController;
}
}}
先ほどと同様にテキスト受信時に手を上げます。
***コンパイル [#bbf536df]
コンパイルします。
$ emacs Makefile
変更前
#オブジェクトファイルの指定
OBJS = SendController.so RecvController.so
変更後
#オブジェクトファイルの指定
OBJS = SendText.so RecvText.so
$ make
***世界ファイルの編集 [#m7f88908]
次に世界ファイルを変更します。
$ cd ..
$ emacs xml/MessageWorld.xml
MessageWorld.xml
メッセージ送信者コントローラの修正
#highlight(xml:firstline[13]){{
<!--メッセージ送信者コントローラ指定-->
<set-attr-value name="implementation"
value="./NewWorld/SendController.so"/>
}}
↓
#highlight(xml:firstline[13]){{
<!--メッセージ送信者コントローラ指定-->
<set-attr-value name="implementation"
value="./NewWorld/SendText.so"/>
}}
メッセージ受信者コントローラの修正
#highlight(xml:firstline[31]){{
<!--メッセージ受信者コントローラ指定-->
<set-attr-value name="implementation"
value="./NewWorld/RecvController.so"/>
}}
↓
#highlight(xml:firstline[31]){{
<!--メッセージ受信者コントローラ指定-->
<set-attr-value name="implementation"
value="./NewWorld/RecvText.so"/>
}}
***起動 [#o073f136]
それでは実行してみます。
$ ./sigserver.sh -w MessageWorld.xml -p 9001
SIGVierwerで接続して、シミュレーションを開始してみます。
#ref(mess_3.jpg)
テキスト送信者が遠ざかりながらテキストを送信しているのが...
エージェントの声がどこまで届くのか確認してみてください。
**テロップ表示 [#bb25270a]
***コントローラ修正 [#o04e7c0c]
送信したテキストデータをSIGViewerでテロップ表示させること...
$ cd NewWorld
$ emacs SendText.cpp
SendText.cpp
#highlight(cpp:firstline[42]){{
sendText(evt.time(), NULL, "Hello!", 300.0);
}}
↓
#highlight(cpp:firstline[42]){{
sendDisplayText(evt.time(), NULL, "Hello!", 64, "red...
}}
sendDisplayTextは送信したテキストデータをテロップで表示さ...
色は"red","green","blue","purple","yellow","brown","gray"...
**実行 [#s6f3180e]
それではコンパイルして実行してみましょう。
$ make
$ cd ../
$ ./sigserver.sh -p 9001 -w MessageWorld.xml
#ref(telop.jpg)
テロップが表示されました。このテロップはテキストデータの...
sendDisplayTextと同様にsendMessage, broadcastMessageにも...
#highlight(end)
Up:[[Tutorial]] Previous:[[人間型エージェントの...
[[English version>Samples/Communication between agents]]
End:
Up:[[Tutorial]] Previous:[[人間型エージェントの...
#contents
*エージェント間でのメッセージのやり取り [#he80bd53]
前回はクライアント(SIGViewer)からエージェントにメッセー...
**メッセージの送受信 [#v4c148e5]
***メッセージ送信者のコントローラ作成 [#pd6017d2]
まずメッセージの送信を行うコントローラを作成します。
$ cd ~/sigverse-<version>/bin/NewWorld
$ emacs SendController.cpp
SendController.cpp
#highlight(cpp){{
#include "Controller.h"
#include "Logger.h"
#include "ControllerEvent.h"
#define PI 3.141592
#define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 )
#define ARY_SIZE(ARY) ( (int)(sizeof(ARY)/sizeof(ARY[0])...
class SendController : public Controller
{
public:
//シミュレーション開始時に一度だけ呼出される関数onInit...
void onInit(InitEvent &evt);
double onAction(ActionEvent &evt);
};
void SendController::onInit(InitEvent &evt)
{
SimObj *my = getObj(myname());
if (!my->dynamics()) {
//右手、左手を下げ、体全体を180°後ろに回転させます。
my->setJointAngle("LARM_JOINT2", DEG2RAD(-90));
my->setJointAngle("RARM_JOINT2", DEG2RAD(90));
my->setAxisAndAngle(0, 1.0, 0, DEG2RAD(180));
}
}
double SendController::onAction(ActionEvent &evt)
{
//メッセージを作成します。
char *strs[] = {
"Hello!!",
};
//エージェント全員にメッセージを送信します。
broadcastMessage(ARY_SIZE(strs),strs);
//5秒置きにメッセージを送信します。
return 5.0;
}
extern "C" Controller * createController ()
{
return new SendController;
}
}}
これは5秒置きにメッセージ"Hello!"を送信するコントローラの...
メッセージを送る相手を指定したいときはbroadcastMessageの...
#highlight(cpp:firstline[40]){{
broadcastMessage(ARY_SIZE(strs),strs);
}}
↓
#highlight(cpp:firstline[40]){{
sendMessaage("robot_000",ARY_SIZE(strs), strs);
}}
メッセージを送信する相手に"robot_000"を指定しました。
***メッセージ受信者のコントローラ作成 [#sb6efc03]
次にメッセージの受信を行うエージェントコントローラを作成...
$ emacs RecvController.cpp
RecvController.cpp
#highlight(cpp){{
#include "Controller.h"
#include "Logger.h"
#include "ControllerEvent.h"
#define PI 3.141592
#define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 )
class RecvController : public Controller
{
public:
double onAction(ActionEvent &evt);
//メッセージ受信時に呼び出される関数onRecvMessageの利...
void onRecvMessage(RecvMessageEvent &evt);
};
double RecvController::onAction(ActionEvent &evt)
{
SimObj *my = getObj(myname());
if (!my->dynamics()) {
//上がった手を下げます。
my->setJointAngle("LARM_JOINT2", DEG2RAD(0));
}
return 1.0;
}
//メッセージ受信時
void RecvController::onRecvMessage(RecvMessageEvent &evt)
{
//自分自身の取得
SimObj *my = getObj(myname());
// メッセージの送り主表示
LOG_MSG(("sender : %s", evt.getSender()));
// getSize で送られてきた文字列数を取得する
int n = evt.getSize();
LOG_MSG(("# of string : %d", n));
for (int i=0; i<n; i++) {
// 文字列を順に取得する
LOG_MSG(("string[%d] : %s", i, evt.getString(i)));
//手を上げます。
if (!my->dynamics() ) {
my->setJointAngle("LARM_JOINT2", DEG2RAD(180));
}
}
}
extern "C" Controller * createController ()
{
return new RecvController;
}
}}
これはメッセージを受信したら手を上げるというサンプルです...
それではコンパイルします。
まずMakefileを修正します。
$ emacs Makefile
変更前
#オブジェクトファイルの指定
OBJS = AgentController.so
変更後
#オブジェクトファイルの指定
OBJS = SendController.so RecvController.so
共有オブジェクトにSendController.so, RecvController.soの2...
Makefile
#SIGVerseソースの場所指定
SIG_SRC = /home/<username>/sigverse-<version>/include/s...
#オブジェクトファイルの指定
OBJS = SendController.so RecvController.so
all: $(OBJS)
#コンパイルを行います。
./%.so: ./%.cpp
g++ -DCONTROLLER -DNDEBUG -DUSE_ODE -DdDOUBLE -I...
$ make
***世界ファイルの作成 [#me49924f]
次に世界ファイルを作成します。
$ cd ..
$ emacs xml/MessageWorld.xml
MessageWorld.xml
#highlight(xml){{
<?xml version="1.0" encoding="utf8"?>
<world name="myworld3">
<gravity x="0.0" y="-9.8" z="0.0"/>
<!--メッセージ送信エージェント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="language" value="c++"/>
<!--メッセージ送信者のコントローラ指定-->
<set-attr-value name="implementation"
value="./NewWorld/SendController.so"/>
<!--エージェントの位置(x,y,z)-->
<set-attr-value name="x" value="0.0"/>
<set-attr-value name="y" value="60.0"/>
<set-attr-value name="z" value="60.0"/>
</instanciate>
<!--メッセージ受信エージェントRobot-niiの設定-->
<instanciate class="Robot-nii.xml">
<set-attr-value name="name" value="robot_000"/>
<set-attr-value name="language" value="c++"/>
<!--メッセージ受信者のコントローラ指定-->
<set-attr-value name="implementation"
value="./NewWorld/RecvController.so"/>
<!--動力学演算をfalseに設定-->
<set-attr-value name="dynamics" value="false"/>
<!--エージェントの位置(x,y,z)-->
<set-attr-value name="x" value="0.0"/>
<set-attr-value name="y" value="60.0"/>
<set-attr-value name="z" value="-60.0"/>
</instanciate>
</world>
}}
人型エージェントが、ヒューマノイド型エージェントにメッセ...
***起動 [#k2bccc17]
起動して見てみましょう。
$ ./sigserver.sh -w MessageWorld.xml -p 9001
SIGViewerで接続して、シミュレーションを開始するとonInitに...
#ref(mess_1.jpg)
SIGViewerの下のほうにあるmessagesタブをクリックします。す...
#ref(mess_2.jpg)
文字列の数(# of string)は1と表示されましたが、コントロ...
//メッセージを作成します。
char *strs[] = {
"Hello!!",
"How are you",
};
**テキスト文字列の送受信 [#a561e72f]
次にエージェント間でのテキスト文字列の送受信について説明...
***テキスト送信者のコントローラ作成 [#wb648f75]
まずはテキストを送信するコントローラを作成します。
$ cd NewWorld
$ emacs SendText.cpp
SendText.cpp
#highlight(cpp){{
#include "Controller.h"
#include "Logger.h"
#include "ControllerEvent.h"
#define PI 3.141592
#define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 )
class SendController : public Controller
{
public:
void onInit(InitEvent &evt);
double onAction(ActionEvent &evt);
};
void SendController::onInit(InitEvent &evt)
{
SimObj *my = getObj(myname());
if (!my->dynamics()) {
my->setJointAngle("LARM_JOINT2", DEG2RAD(-90));
my->setJointAngle("RARM_JOINT2", DEG2RAD(90));
my->setAxisAndAngle(0, 1.0, 0, DEG2RAD(180));
}
}
double SendController::onAction(ActionEvent &evt)
{
try
{
SimObj *my = getObj(myname());
//自分の位置を得ます。
double x = my->x();
double y = my->y();
double z = my->z();
//z方向に20移動します。
my->setPosition( x, y, z + 20 );
//半径300.0以内のすべてのエージェントに対してテキス...
sendText(evt.time(), NULL, "Hello!", 300.0);
}catch(SimObj::Exception &) {
;
}
//3秒後にonActionが呼び出されます。
return 3.0;
}
extern "C" Controller * createController ()
{
return new SendController;
}
}}
これは3秒に1回テキスト"Hello!"を送信するコントローラです...
このエージェントはz方向にどんどん移動しながらテキストを送...
***テキスト受信者のコントローラ作成 [#jfd5b8e7]
テキスト受信者のコントローラを作成します。
$ emacs RecvText.cpp
RecvText.cpp
#highlight(cpp){{
#include <string>
#include "Controller.h"
#include "Logger.h"
#include "ControllerEvent.h"
#define PI 3.141592
#define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 )
class RecvController : public Controller
{
public:
double onAction(ActionEvent &evt);
//テキスト受信時に呼出される関数onRecvTextの利用を宣言...
void onRecvText(RecvTextEvent &evt);
};
double RecvController::onAction(ActionEvent &evt)
{
SimObj *my = getObj(myname());
if (!my->dynamics()) {
my->setJointAngle("LARM_JOINT2", DEG2RAD(0));
}
return 1.0;
}
//テキスト受信時
void RecvController::onRecvText(RecvTextEvent &evt)
{
//自分自身を取得します。
SimObj *my = getObj(myname());
// テキストの送り主を取得します。
const char *caller = evt.getCaller();
//テキストの内容を取得します。
const char *text = evt.getText();
//送り主と内容を表示します。
LOG_MSG(("receive from %s : \"%s\"", caller, text));
//手を挙げます。
if (!my->dynamics()) {
my->setJointAngle("LARM_JOINT2", DEG2RAD(180));
}
}
extern "C" Controller * createController ()
{
return new RecvController;
}
}}
先ほどと同様にテキスト受信時に手を上げます。
***コンパイル [#bbf536df]
コンパイルします。
$ emacs Makefile
変更前
#オブジェクトファイルの指定
OBJS = SendController.so RecvController.so
変更後
#オブジェクトファイルの指定
OBJS = SendText.so RecvText.so
$ make
***世界ファイルの編集 [#m7f88908]
次に世界ファイルを変更します。
$ cd ..
$ emacs xml/MessageWorld.xml
MessageWorld.xml
メッセージ送信者コントローラの修正
#highlight(xml:firstline[13]){{
<!--メッセージ送信者コントローラ指定-->
<set-attr-value name="implementation"
value="./NewWorld/SendController.so"/>
}}
↓
#highlight(xml:firstline[13]){{
<!--メッセージ送信者コントローラ指定-->
<set-attr-value name="implementation"
value="./NewWorld/SendText.so"/>
}}
メッセージ受信者コントローラの修正
#highlight(xml:firstline[31]){{
<!--メッセージ受信者コントローラ指定-->
<set-attr-value name="implementation"
value="./NewWorld/RecvController.so"/>
}}
↓
#highlight(xml:firstline[31]){{
<!--メッセージ受信者コントローラ指定-->
<set-attr-value name="implementation"
value="./NewWorld/RecvText.so"/>
}}
***起動 [#o073f136]
それでは実行してみます。
$ ./sigserver.sh -w MessageWorld.xml -p 9001
SIGVierwerで接続して、シミュレーションを開始してみます。
#ref(mess_3.jpg)
テキスト送信者が遠ざかりながらテキストを送信しているのが...
エージェントの声がどこまで届くのか確認してみてください。
**テロップ表示 [#bb25270a]
***コントローラ修正 [#o04e7c0c]
送信したテキストデータをSIGViewerでテロップ表示させること...
$ cd NewWorld
$ emacs SendText.cpp
SendText.cpp
#highlight(cpp:firstline[42]){{
sendText(evt.time(), NULL, "Hello!", 300.0);
}}
↓
#highlight(cpp:firstline[42]){{
sendDisplayText(evt.time(), NULL, "Hello!", 64, "red...
}}
sendDisplayTextは送信したテキストデータをテロップで表示さ...
色は"red","green","blue","purple","yellow","brown","gray"...
**実行 [#s6f3180e]
それではコンパイルして実行してみましょう。
$ make
$ cd ../
$ ./sigserver.sh -p 9001 -w MessageWorld.xml
#ref(telop.jpg)
テロップが表示されました。このテロップはテキストデータの...
sendDisplayTextと同様にsendMessage, broadcastMessageにも...
#highlight(end)
Up:[[Tutorial]] Previous:[[人間型エージェントの...
[[English version>Samples/Communication between agents]]
Page: