RobotBrainComponent.C

00001 #ifndef ROBOTBRAINCOMPONENT_C
00002 #define ROBOTBRAINCOMPONENT_C
00003 
00004 #include "Robots/RobotBrain/RobotBrainComponent.H"
00005 #include "Component/ModelParam.H"
00006 #include "Component/ModelOptionDef.H"
00007 
00008 
00009 const ModelOptionCateg MOC_RobotBrainComponent = {
00010     MOC_SORTPRI_3, "RobotBrainComponent Related Options" };
00011 
00012 const ModelOptionDef OPT_IceIdentity =
00013 { MODOPT_ARG(std::string), "IceIdentity", &MOC_RobotBrainComponent, OPTEXP_CORE,
00014     "Unique IceStorm Identity for this RobotBrainComponent",
00015     "ice-identity", '\0', "<string>", "" };
00016 
00017 const ModelOptionDef OPT_IcestormIP =
00018 { MODOPT_ARG(std::string), "IcestormIP", &MOC_RobotBrainComponent, OPTEXP_CORE,
00019     "IP Address to the host running the IceStorm server",
00020     "icestorm-ip", '\0', "<ip address>", "127.0.0.1" };
00021 
00022 const ModelOptionDef OPT_ConnectionTimeout =
00023 { MODOPT_ARG(int), "ConnectionTimeout", &MOC_RobotBrainComponent, OPTEXP_CORE,
00024     "Timeout time when creating a connection to the ice storm server (in ms)",
00025     "timeout", '\0', "<int>", "1000" };
00026 
00027 RobotBrainComponent::RobotBrainComponent(OptionManager& mgr, const std::string& descrName, const std::string& tagName)
00028  : ModelComponent(mgr, descrName, tagName),
00029    itsIceIdentity(&OPT_IceIdentity, this, 0),
00030    itsIcestormIP(&OPT_IcestormIP, this, 0),
00031    itsConnectionTimeout(&OPT_ConnectionTimeout, this, 0),
00032    itsEvolveSleepTime(10000),
00033    itsTagName(tagName)
00034 {}
00035 
00036 
00037 void RobotBrainComponent::init(Ice::CommunicatorPtr ic, Ice::ObjectAdapterPtr adapter)
00038 {
00039   itsIcPtr = ic;
00040   itsAdapterPtr = adapter;
00041 }
00042 
00043 void RobotBrainComponent::start2()
00044 {
00045   Ice::ObjectPtr objPtr = this;
00046 
00047   //Create an ICE proxy using the --ice-identity command line option if specified
00048   //  int suffix = 0;
00049   std::string myIDname;
00050   if(itsIceIdentity.getVal() != "")
00051     myIDname = itsIceIdentity.getVal().c_str();
00052   else
00053     myIDname = itsTagName;
00054 
00055   //////////////////////////////////////////////////////////////////////////////////////////
00056   //This currently does not work - need to find a way to auto-increment the ID if one exists
00057   //already...
00058   /*Ice::ObjectPtr servant = itsAdapterPtr->find(itsIcPtr->stringToIdentity(myIDname.c_str()));
00059   while(servant != NULL)
00060   {
00061     LINFO("Adapter name already taken: %s", myIDname.c_str());
00062     suffix++;
00063     myIDname = itsIceIdentity.getVal() + convertToString(suffix);
00064     servant = itsAdapterPtr->find(itsIcPtr->stringToIdentity(myIDname.c_str()));
00065   }
00066   LINFO("Creating Ice Identity Adapter: %s", myIDname.c_str());
00067   */
00068   itsObjectPrx = itsAdapterPtr->add(objPtr, itsIcPtr->stringToIdentity(myIDname.c_str()));
00069 
00070 
00071   //Create a topic manager to handle messages for us
00072   LDEBUG("Connecting to Ice Storm at %s:11111", itsIcestormIP.getVal().c_str());
00073   char buffer[256];
00074   sprintf(buffer, "SimEvents/TopicManager:tcp -p 11111 -h %s -t %d", itsIcestormIP.getVal().c_str(), itsConnectionTimeout.getVal());
00075   Ice::ObjectPrx TopicMgrObjPrx;
00076   try
00077   {
00078     TopicMgrObjPrx = itsIcPtr->stringToProxy(buffer);
00079     LDEBUG("Got Proxy, Casting...");
00080     itsTopicManagerPrx = IceStorm::TopicManagerPrx::checkedCast(TopicMgrObjPrx);
00081     LDEBUG("Cast Complete!");
00082   }
00083   catch (const Ice::Exception& e) {
00084     std::cerr << "Error Connecting to IceStorm: " << e << std::endl;
00085     exit(1);
00086   }
00087 
00088   LDEBUG("Got Connection To IceStorm Server");
00089   //Now that our topic manager is created, we should call a function to actually register all of our initial
00090   //topics. This function is virtual, and should be overloaded by child classes.
00091   registerTopics();
00092 
00093   itsAlive = true;
00094   IceUtil::ThreadPtr thread = this;
00095 
00096   LDEBUG("Starting Thread");
00097 
00098         start3();
00099 
00100   thread->start();
00101 }
00102 
00103 void RobotBrainComponent::run()
00104 {
00105   while(itsAlive)
00106   {
00107     evolve();
00108     usleep(itsEvolveSleepTime);
00109   }
00110 }
00111 
00112 
00113 void RobotBrainComponent::stop1()
00114 {
00115   itsAlive = false;
00116 
00117   std::map<std::string, IceStorm::TopicPrx>::iterator iter;
00118   for(iter = itsTopicSubscriptions.begin(); iter != itsTopicSubscriptions.end(); ++iter)
00119   {
00120     LINFO("%s Unsubscribing From %s", this->tagName().c_str(), iter->first.c_str());
00121     iter->second->unsubscribe(itsObjectPrx);
00122   }
00123 }
00124 
00125 bool RobotBrainComponent::registerSubscription(const std::string& MessageTopic)
00126 {
00127   LINFO("Subscribing To Ice Topic: %s", MessageTopic.c_str());
00128   IceStorm::TopicPrx topic;
00129 
00130   //Create a dummy "Quality of Service" dictionary - we don't touch it, as the default
00131   //values are acceptable
00132   IceStorm::QoS qos;
00133 
00134   try
00135   {
00136     //Request a handle to the topic from our topic manager
00137     topic = itsTopicManagerPrx->retrieve(MessageTopic.c_str());
00138 
00139     //Actually subscribe to the requested topic
00140     topic->subscribeAndGetPublisher(qos, itsObjectPrx);
00141 
00142     //Store our topic in our internal topic map so that we can unsubscribe from it
00143     //later if we need to clean up
00144     itsTopicSubscriptions.insert( make_pair(MessageTopic, topic));
00145     LINFO("Inserted %s into itsTopicSubscriptions", MessageTopic.c_str());
00146   }
00147   catch(const IceStorm::NoSuchTopic&)
00148   {
00149     LERROR("Message Topic Not Found (%s). Make sure someone has already registered as a publisher.", MessageTopic.c_str() );
00150     return false;
00151   }
00152   catch(const IceStorm::AlreadySubscribed&)
00153   {
00154     LERROR("A RobotBrainComponent with the tagname \"%s\" has already subscribed to \"%s\"", this->tagName().c_str(), MessageTopic.c_str() );
00155     topic->unsubscribe(itsObjectPrx);
00156 
00157     //Request a handle to the topic from our topic manager
00158     topic = itsTopicManagerPrx->retrieve(MessageTopic.c_str());
00159     topic->subscribeAndGetPublisher(qos, itsObjectPrx);
00160     itsTopicSubscriptions.insert( make_pair(MessageTopic, topic));
00161   }
00162   return true;
00163 }
00164 
00165 void RobotBrainComponent::registerPublisher(const std::string& MessageTopic)
00166 {
00167   LINFO("Registering as Publisher Of Ice Topic: %s", MessageTopic.c_str());
00168 
00169   IceStorm::TopicPrx topic;
00170   try
00171   {
00172     //Try to get a handle for our topic if it exists
00173     topic = itsTopicManagerPrx->retrieve(MessageTopic.c_str());
00174   }
00175   catch( const IceStorm::NoSuchTopic& )
00176   {
00177     //If our topic does not exist, then we create it
00178     topic = itsTopicManagerPrx->create(MessageTopic.c_str());
00179   }
00180 
00181   //Request the publisher from the Ice runtime
00182   Ice::ObjectPrx pub = topic->getPublisher()->ice_oneway();
00183 
00184   //Create our actual publisher proxy
00185   RobotSimEvents::EventsPrx publisher = RobotSimEvents::EventsPrx::uncheckedCast(pub);
00186 
00187   //Store our topic publisher so that we can access it later when we actually
00188   //have messages to publish
00189   itsTopicPublishers.insert( make_pair(MessageTopic, publisher) );
00190 }
00191 
00192 bool RobotBrainComponent::publish(const::std::string& MessageTopic, RobotSimEvents::EventMessagePtr msg)
00193 {
00194   LDEBUG("Publishing Ice Topic: %s", MessageTopic.c_str());
00195   //Search for the MessageTopic/Publisher pair from our publisher map
00196   std::map<std::string, RobotSimEvents::EventsPrx>::iterator iter =
00197     itsTopicPublishers.find(MessageTopic);
00198 
00199   //Make sure we are actually registered as a publisher for the requested topic
00200   if(iter == itsTopicPublishers.end())
00201   {
00202     LERROR("Not currently a registered publisher of \"%s\"! Please call registerPublisher to register", MessageTopic.c_str());
00203     return false;
00204   }
00205 
00206   //If we found the publisher in our map, then let's grab it from the iterator
00207   RobotSimEvents::EventsPrx publisher = iter->second;
00208 
00209   //Publish the message
00210   publisher->updateMessage(msg);
00211 
00212   return true;
00213 }
00214 
00215 #endif
00216 
Generated on Sun May 8 08:41:32 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3