Up:Tutorial? Previous:人間型エージェントの操作 Next:音声認識?
前回はクライアント(SIGViewer)からエージェントにメッセージを送信して受信したエージェントはお辞儀をするというサンプルを紹介しました。今回はエージェント間でのやり取りを行うサンプルコードを紹介します。
まずメッセージの送信を行うコントローラを作成します。
$ cd ~/sigverse-<version>/bin/NewWorld $ emacs SendController.cpp
SendController.cpp
これは5秒置きにメッセージ"Hello!"を送信するコントローラのサンプルです。broadcastMessageではエージェント全員にメッセージを送信します。
メッセージを送る相手を指定したいときはbroadcastMessageの代わりにsendMessageを用いて以下のように、メッセージを送る相手を指定します。
↓
メッセージを送信する相手に"robot_000"を指定しました。
次にメッセージの受信を行うエージェントコントローラを作成します。
$ emacs RecvController.cpp
RecvController.cpp
これはメッセージを受信したら手を上げるというサンプルです。また、onActionで1秒ごとに上がった手を下げようとします。
それではコンパイルします。 まず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/sigverse #オブジェクトファイルの指定 OBJS = SendController.so RecvController.so all: $(OBJS) #コンパイルを行います。 ./%.so: ./%.cpp g++ -DCONTROLLER -DNDEBUG -DUSE_ODE -DdDOUBLE -I$(SIG_SRC) -I$(SIG_SRC)/comm/controller -fPIC -shared -o $@ $<
$ make
次に世界ファイルを作成します。
$ cd .. $ emacs xml/MessageWorld.xml
MessageWorld.xml
人型エージェントが、ヒューマノイド型エージェントにメッセージを送信します。
起動して見てみましょう。
$ ./sigserver.sh -w MessageWorld.xml -p 9001
SIGViewerで接続して、シミュレーションを開始するとonInitにより、人型エージェント(メッセージ送信者)が手を下して、後ろを振り返ります。そして5秒に一回ロボット(メッセージ受信者)がメッセージに反応して手を挙げているのがわかります。
SIGViewerの下のほうにあるmessagesタブをクリックします。するとロボットがメッセージに反応して送信者と、文字列数、とその内容を表示します。
文字列の数(# of string)は1と表示されましたが、コントローラでメッセージ作成するときに以下のようにすることで、文字列は同時に複数送ることもできます。
//メッセージを作成します。 char *strs[] = { "Hello!!", "How are you", };
次にエージェント間でのテキスト文字列の送受信について説明します。テキスト文字列は人間が声を出すのと同じように、自分の声が届く範囲を指定することができます。
まずはテキストを送信するコントローラを作成します。
$ cd NewWorld $ emacs SendText.cpp
SendText.cpp
これは3秒に1回テキスト"Hello!"を送信するコントローラです。sendText関数でテキストを送信します。sendTextの2番目の引数がNULL、4番目の引数が300.0となっています。こうすることにより、テキストを送信する相手を指定せず、周囲300(m)にいるすべてのエージェントにテキストを送信します。テキストを送信する相手を指定したい場合は2番目の引数に指定するエージェントの名前を入力し、最後の引数は省略します。
このエージェントはz方向にどんどん移動しながらテキストを送信します。つまりテキストを受信するエージェントからはどんどん遠ざかりながらテキストを送信します。
テキスト受信者のコントローラを作成します。
$ emacs RecvText.cpp
RecvText.cpp
先ほどと同様にテキスト受信時に手を上げます。
コンパイルします。
$ emacs Makefile
変更前
#オブジェクトファイルの指定 OBJS = SendController.so RecvController.so
変更後
#オブジェクトファイルの指定 OBJS = SendText.so RecvText.so
$ make
次に世界ファイルを変更します。
$ cd .. $ emacs xml/MessageWorld.xml
MessageWorld.xml
メッセージ送信者コントローラの修正
↓
メッセージ受信者コントローラの修正
↓
それでは実行してみます。
$ ./sigserver.sh -w MessageWorld.xml -p 9001
SIGVierwerで接続して、シミュレーションを開始してみます。
テキスト送信者が遠ざかりながらテキストを送信しているのがわかります。 エージェントの声がどこまで届くのか確認してみてください。
送信したテキストデータをSIGViewerでテロップ表示させることができます。SendText.cppのsendText関数を以下のように修正します。
$ cd NewWorld $ emacs SendText.cpp
SendText.cpp
↓
sendDisplayTextは送信したテキストデータをテロップで表示させます。4番目の引数にはフォントサイズ、5番目の引数には色を指定することができます。ここではフォントサイズ64、色は赤色を指定しました。
色は"red","green","blue","purple","yellow","brown","gray"が指定できます。
それではコンパイルして実行してみましょう。
$ make $ cd ../ $ ./sigserver.sh -p 9001 -w MessageWorld.xml
テロップが表示されました。このテロップはテキストデータの届く範囲に関係なく表示されます。またテキストデータを受け取るエージェントはsendTextのときと同様にonRecvTextが呼び出されます。
sendDisplayTextと同様にsendMessage, broadcastMessageにもテロップを表示させる関数sendDisplayMessage, broadcastDisplayMessageがあります。これらのフォントサイズや色の指定方法はsendTextと同じです。また複数のメッセージを同時に送信するときには最初のメッセージのみがテロップ表示されるので注意が必要です。
Up:Tutorial? Previous:人間型エージェントの操作 Next:音声認識?
English version?