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