Up:[[Tutorial]]     Previous:[[Humanoid agent operations]]     Next:[[Vision sensor]]

----
#contents

* Exchange of messages between agents. [#ia7882aa]

※This tutorial is valid only for later than v2.1.0.


** Sending and receiving messages [#d353e783]

*** Controller of message sender [#zd064119]

Create a controller for sending messages.

 $ cd ~/MyWorld
 $ emacs SendController.cpp

SendController.cpp
#highlight(cpp){{
#include "Controller.h"
#include "Logger.h"
#include "ControllerEvent.h"
#gist(sigverse-git/4ec290ead83ed03833efd8cd5791531f);

#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:
  // Initialization of the controller
  void onInit(InitEvent &evt);
  double onAction(ActionEvent &evt);
};

void SendController::onInit(InitEvent &evt)
{
  SimObj *my = getObj(myname());

  //Putting the both hands down; rorating the body 180[deg]
  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)
{
  // Message to be sent
  std::string msg = "Hello!!";

  // Sending the message to an agent "robot_000"
  sendMsg("robot_000", msg);

  // onAction will be called again after 1 second
  return 1.0;
}

extern "C"  Controller * createController ()
{
  return new SendController;
}
}}

This controller send a message "Hello!" to the robot agent every second.

If you want to send a message to all of the agents in the world, you should use broadcastMsg instead of sendMsg.

Old
#highlight(cpp:firstline[33]){{
#highlight(cpp:firstline[38]){{
 sendMsg("robot_000",msg);
}}
New
#highlight(cpp:firstline[33]){{
#highlight(cpp:firstline[38]){{
 broadcastMsg(msg);
}}

*** Controller to receive messages [#i2790ab2]

Create a controller to receive messages.

 $ emacs RecvController.cpp

RecvController.cpp

#highlight(cpp){{
#include <string>
#include "Controller.h"
#include "Logger.h"
#include "ControllerEvent.h"
#gist(sigverse-git/dfd3d5c6d9d64180ca9eb8ffba54d544);

#define PI 3.141592
#define DEG2RAD(DEG) ( (PI) * (DEG) / 180.0 )

class RecvController : public Controller
{
public:
  double onAction(ActionEvent &evt);

  // Registrate of a callback function onRecvMsg, which will be called when a message comes
  void onRecvMsg(RecvMsgEvent &evt);

private:
  bool raise_hand;
};

double RecvController::onAction(ActionEvent &evt)
{
  SimObj *my = getObj(myname());

  // Putting a hand down
  if(raise_hand)
    my->setJointAngle("LARM_JOINT2", DEG2RAD(0));

  return 0.5;
}

// Callback function to receive messages
void RecvController::onRecvMsg(RecvMsgEvent &evt)
{
  // Reference of myself
  SimObj *my = getObj(myname());

  // Display of message sender
  std::string sender = evt.getSender();
  LOG_MSG(("sender : %s", sender.c_str()));

  // Receiving text data
  std::string msg = evt.getMsg();
  LOG_MSG(("message : %s", msg.c_str()));

  // Putting a hand up if the received message is "Hello!!"
  if(msg == "Hello!!") {
    my->setJointAngle("LARM_JOINT2", DEG2RAD(180));
    raise_hand = true;
  }
}

extern "C"  Controller * createController ()
{
  return new RecvController;
}
}}
This controller put the agent's hand up if a message "Hello!!" comes.
The agent will put the hand down every 0.5 second.


Compiling the controller.

 $ ./sigmake.sh SendController.cpp RecvController.cpp


*** Creating a worldfile [#w395fedb]

 $ emacs MessageWorld.xml

MessageWorld.xml
#highlight(xml){{
<?xml version="1.0" encoding="utf8"?>
 <world name="myworld3">
 
   <gravity x="0.0" y="-980.7" z="0.0"/>
 
 <!--Setting of an avatar agent Man-nii who sends messages-->
   <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++"/>
 
 <!--setting of a controller for the avatar agent-->
         <set-attr-value name="implementation" value="./SendController.so"/>
 
 <!--setting the initial position of the avatar agent (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>
 
 
 <!--setting of a humanoid agent Robot-nii who receives messages-->
   <instanciate class="Robot-nii.xml">
 
         <set-attr-value name="name" value="robot_000"/>
         <set-attr-value name="language" value="c++"/>
 
 <!--setting of a controller for the humanoid (receiver) agent-->
         <set-attr-value name="implementation" value="./RecvController.so"/>
 
 <!--put the flag of dynamics to false-->
         <set-attr-value name="dynamics" value="false"/>
 
 <!--setting the initial position of the humanoid agent (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>
}}
#gist(sigverse-git/008dee0218d42c41388f7e02a2fe09c5);

In this controller, a human avator will send a message to a humanoid agent.


*** Execution [#tb38ac14]

 $ sigserver.sh -w ./MessageWorld.xml 

First, the avatar agent put a hand down and turn back by onInit function.
Then, you can see that the agent put it's hand up every second with receiving a message.

#ref(./message_1.PNG,40%)


** Specification of message reachable area [#a22b41bf]

This part explains how to specify the maximum length of the reachable area of the message sending function.

*** Controller of text message sender [#we283cc2]

Create another controller to send messages.

 $ emacs SendController2.cpp 

SendController2.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])) )
#gist(sigverse-git/8a057f168978dd46bb2c48ae5c912a11);

class SendController : public Controller
{
public:
  void onInit(InitEvent &evt);
  double onAction(ActionEvent &evt);
};

void SendController::onInit(InitEvent &evt)
{
  SimObj *my = getObj(myname());

  // Putting the both hands and rotate the body 180[deg]
  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)
{
  SimObj *my = getObj(myname());

  Vector3d vec;
  my->getPosition(vec);

  // Moving 20 to z-axis
  my->setPosition( vec.x(), vec.y(), vec.z() + 20 );

  // Creating a message
  std::string msg = "Hello!!";

  // Broadcasting the message to all of the agents within 3-meter radius from the agent
  broadcastMsg(msg, 300.0);

  //
  return 1.0;
}

extern "C"  Controller * createController ()
{
  return new SendController;
}
}}

The second argument of the broadcastMsg, 300, means that the maximum distance of the message reachable area is 3 meters.
If you omit the secnod argument, the message will be reached to all of the agents irrespective of the distance.

This agent keeps on sending a message and moving to z-axis.



*** Compiling [#k7a9b5fc]

 $ ./sigmake.sh SendController2.cpp

*** Modification of the world file [#s62dc619]

 $ emacs MessageWorld.xml

Modify the MessageWorld.xml to change the controller for sending agent

Old
#highlight(xml:firstline[13]){{
       <set-attr-value name="implementation" value="./SendController.so"/>
}}

New
#highlight(xml:firstline[13]){{        
       <set-attr-value name="implementation" value="./SendController2.so"/>
}}
 
*** Execution [#m24d78ab]

 $ sigserver.sh -w ./MessageWorld.xml

#ref(./message_3.PNG,40%)

You can see the agent sending messages with backing away from the receiver.
Please check how far the message reaches to the receiver.


** Sending message to the SIGViewer [#sa02f588]
If the broadcastMsg is used, the message will be reached to all of the agents, SIGViewer and SIGVerse services.
The SIGViewer will show the received message as log message.

You can send messages to the SIGViewer using sendMsg.
In this case, you should specify a service name which is determined when the SIGViewer connected to the SIGverse server.
If the service name is "SIGViewer", the following modification will change the sending target from the agent to the SIGViewer.

SendController.so

Old
#highlight(cpp:firstline[33]){{
 sendMsg("robot_000",msg);
}}
New
#highlight(cpp:firstline[33]){{
 sendMsg("SIGViewer",msg);
}}


#highlight(end)


--------
Up:[[Tutorial]]     Previous:[[Humanoid agent operations]]     Next:[[Vision sensor]]

#counter


Front page   New List of pages Search Recent changes   Help   RSS of recent changes