00001 /*!@file NeovisionII/HippocampusService.C */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Lior Elazary 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/NeovisionII/HippocampusService.C $ 00035 // $Id: HippocampusService.C 13901 2010-09-09 15:12:26Z lior $ 00036 // 00037 00038 #include "NeovisionII/HippocampusService.H" 00039 #include "Util/sformat.H" 00040 #include "Image/DrawOps.H" 00041 00042 using namespace std; 00043 using namespace ImageIceMod; 00044 00045 HippocampusI::HippocampusI(OptionManager& mgr, 00046 nub::ref<OutputFrameSeries> ofs, 00047 const std::string& descrName, 00048 const std::string& tagName) : 00049 ModelComponent(mgr, descrName, tagName), 00050 itsOfs(ofs), 00051 itsCameraDistance(880.954432), 00052 itsCameraAngle(2.321289), 00053 itsRadPerTilt(0.001298016), 00054 itsRadPerPan(0.001824947) 00055 { 00056 //Subscribe to the various topics 00057 IceStorm::TopicPrx topicPrx; 00058 itsTopicsSubscriptions.push_back(TopicInfo("PrefrontalCortexTopic", topicPrx)); 00059 00060 resetCurrentObject(); 00061 } 00062 00063 00064 00065 HippocampusI::~HippocampusI() 00066 { 00067 unsubscribeSimEvents(); 00068 } 00069 00070 void HippocampusI::start2() 00071 { 00072 } 00073 00074 void HippocampusI::resetCurrentObject() 00075 { 00076 itsCurrentObject.objName = "noname"; 00077 itsCurrentObject.loc = Point2D<int>(-1, -1); 00078 itsCurrentObject.size = 0; 00079 } 00080 00081 void HippocampusI::initSimEvents(Ice::CommunicatorPtr icPtr, Ice::ObjectPrx objectPrx) 00082 { 00083 //Get the IceStorm object 00084 Ice::ObjectPrx obj = icPtr->stringToProxy("SimEvents/TopicManager:tcp -p 11111"); 00085 IceStorm::TopicManagerPrx topicManager = 00086 IceStorm::TopicManagerPrx::checkedCast(obj); 00087 00088 //Create a Segmenter Topic 00089 IceStorm::TopicPrx topic; 00090 try { 00091 topic = topicManager->retrieve("HippocampusTopic"); //check if the Retina topic exists 00092 } catch (const IceStorm::NoSuchTopic&) { 00093 topic = topicManager->create("HippocampusTopic"); //The retina topic does not exists, create 00094 } 00095 //Make a one way visualCortex message publisher for efficency 00096 Ice::ObjectPrx pub = topic->getPublisher()->ice_oneway(); 00097 itsEventsPub = SimEvents::EventsPrx::uncheckedCast(pub); 00098 00099 00100 //Subscribe the SimulationViewer to theTopics 00101 itsObjectPrx = objectPrx; 00102 //subscribe to the topics 00103 for(uint i=0; i<itsTopicsSubscriptions.size(); i++) 00104 { 00105 try { 00106 IceStorm::QoS qos; 00107 itsTopicsSubscriptions[i].topicPrx = 00108 topicManager->retrieve(itsTopicsSubscriptions[i].name.c_str()); //Get the 00109 itsTopicsSubscriptions[i].topicPrx->subscribeAndGetPublisher(qos, itsObjectPrx); //Subscribe to the retina topic 00110 } catch (const IceStorm::NoSuchTopic&) { 00111 LFATAL("Error! No %s topic found!", itsTopicsSubscriptions[i].name.c_str()); 00112 } catch (const char* msg) { 00113 LINFO("Error %s", msg); 00114 } catch (const Ice::Exception& e) { 00115 cerr << e << endl; 00116 } 00117 } 00118 } 00119 00120 void HippocampusI::unsubscribeSimEvents() 00121 { 00122 //Unsubscribe from all the topics we are registerd to 00123 for(uint i=0; i<itsTopicsSubscriptions.size(); i++) 00124 { 00125 itsTopicsSubscriptions[i].topicPrx->unsubscribe(itsObjectPrx); 00126 } 00127 } 00128 00129 00130 void HippocampusI::evolve(const SimEvents::EventMessagePtr& eMsg, 00131 const Ice::Current&) 00132 { 00133 00134 if (eMsg->ice_isA("::SimEvents::HippocampusBiasMessage")){ 00135 SimEvents::HippocampusBiasMessagePtr msg = SimEvents::HippocampusBiasMessagePtr::dynamicCast(eMsg); 00136 00137 LINFO("Got bias message objName:%s loc:%ix%i rotation=%0.2f", 00138 msg->objectName.c_str(), msg->loc.i, msg->loc.j, msg->rotation*M_PI); 00139 00140 //Get the image 00141 Image<PixRGB<byte> > retinaImg(320,240,ZEROS); 00142 00143 if (msg->img.width > 0 && msg->img.height > 0) 00144 retinaImg = Ice2Image<PixRGB<byte> >(msg->img); 00145 00146 if (msg->objectName == "MODE:rec") 00147 { 00148 itsCurrentObject.loc = Point2D<int>(msg->loc.i, msg->loc.j); 00149 itsCurrentObject.size = 20; 00150 itsCurrentObject.objName = "MODE:rec"; 00151 } 00152 00153 if (itsCurrentObject.loc.isValid() && msg->objectName != "nomatch" && msg->loc.i == -2 && msg->loc.j == -2) 00154 { 00155 itsCurrentObject.objName = msg->objectName; 00156 itsCurrentObject.pos = get3Dpos(msg->pan, msg->tilt); 00157 itsCurrentObject.rotation = msg->rotation; 00158 //Update the state 00159 itsObjectsState[itsCurrentObject.objName] = itsCurrentObject; 00160 } 00161 00162 //Show the current objects; 00163 00164 Image<PixRGB<byte> > stateMap = retinaImg; 00165 00166 if (itsCurrentObject.objName != "nomatch") 00167 { 00168 if (itsCurrentObject.objName == "MODE:rec") 00169 drawCircle(stateMap, itsCurrentObject.loc, (int)itsCurrentObject.size, PixRGB<byte>(255,0,0),2); 00170 else 00171 { 00172 drawCircle(stateMap, itsCurrentObject.loc, (int)itsCurrentObject.size, PixRGB<byte>(0,255,0),2); 00173 writeText(stateMap, itsCurrentObject.loc, itsCurrentObject.objName.c_str(), 00174 PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0)); 00175 } 00176 } 00177 00178 Image<byte> trmMap(stateMap.getDims(), ZEROS); 00179 trmMap.clear(0); 00180 00181 Image<PixRGB<byte> > STMMap(512, 512, ZEROS); 00182 00183 //Default IOR 00184 drawFilledRect(trmMap, Rectangle(Point2D<int>(280,0), Dims(40, 230)), (byte)0); 00185 drawFilledRect(trmMap, Rectangle(Point2D<int>(0,0), Dims(40, 230)), (byte)0); 00186 00187 if (itsObjectsState.size() > 0) 00188 { 00189 SimEvents::HippocampusMessagePtr hMsg = new SimEvents::HippocampusMessage; 00190 SimEvents::ObjectsStateSeq objectsStateSeq; 00191 00192 //Show the current objects 00193 for( std::map<std::string, ObjectState>::iterator itr = itsObjectsState.begin(); itr != itsObjectsState.end(); itr++) 00194 { 00195 LINFO("Object %s", itr->second.objName.c_str()); 00196 drawCircle(stateMap, itr->second.loc, (int)itr->second.size, PixRGB<byte>(0,255,0),2); 00197 writeText(stateMap, itr->second.loc, itr->second.objName.c_str(), 00198 PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0)); 00199 00200 //Build the task relevent map 00201 //drawDisk(trmMap, itr->second.loc, (int)itr->second.size+10, (byte)0); 00202 Point2D<int> loc = itr->second.loc; 00203 int length = trmMap.getWidth()-(loc.i+30); 00204 drawFilledRect(trmMap, Rectangle(Point2D<int>(loc.i+30,loc.j-20), Dims(length, 40)), (byte)1); 00205 00206 //Add the object the seq 00207 00208 drawObject(STMMap, itr->second); 00209 00210 //Check if object is in danger 00211 00212 std::string msg; 00213 bool inDanger = false; 00214 for( std::map<std::string, ObjectState>::iterator itr2 = itsObjectsState.begin(); itr2 != itsObjectsState.end(); itr2++) 00215 { 00216 if (itr->second.pos.x > itr2->second.pos.x && itr->second.pos.x < itr2->second.pos.x+1000 && 00217 itr->second.pos.y > itr2->second.pos.y-30 && itr->second.pos.y < itr2->second.pos.y+30) 00218 { 00219 msg = itr->second.objName + " is threatened by " + itr2->second.objName; 00220 inDanger = true; 00221 LINFO("%s", msg.c_str()); 00222 writeText(STMMap, Point2D<int>(100,100), msg.c_str(), 00223 PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0)); 00224 } 00225 } 00226 00227 SimEvents::ObjectState objectState; 00228 objectState.objectName = itr->second.objName; 00229 objectState.objectMsg = msg; 00230 objectState.loc.i = itr->second.loc.i; 00231 objectState.loc.j = itr->second.loc.j; 00232 objectState.pos.x = itr->second.pos.x; 00233 objectState.pos.y = itr->second.pos.y; 00234 objectState.pos.z = itr->second.pos.z; 00235 objectState.inDanger = inDanger; 00236 objectState.rotation = itr->second.rotation; 00237 objectState.size = itr->second.size; 00238 objectsStateSeq.push_back(objectState); 00239 00240 } 00241 hMsg->objectsState = objectsStateSeq; 00242 itsEventsPub->evolve(hMsg); 00243 } 00244 00245 //send the trm map 00246 SimEvents::SaliencyMapBiasMessagePtr sMapBiasMsg = new SimEvents::SaliencyMapBiasMessage; 00247 sMapBiasMsg->biasImg = Image2Ice(trmMap); 00248 itsEventsPub->evolve(sMapBiasMsg); 00249 00250 00251 itsOfs->writeRGB(stateMap, "Hippocampus", FrameInfo("Hippocampus", SRC_POS)); 00252 //itsOfs->writeRGB(STMMap, "STMMap", FrameInfo("STMMap", SRC_POS)); 00253 itsOfs->updateNext(); 00254 00255 00256 } 00257 00258 } 00259 00260 void HippocampusI::drawObject(Image<PixRGB<byte> > & img, ObjectState &objState) 00261 { 00262 Point2D<int> loc( (img.getWidth()/2) + objState.pos.x, img.getHeight() - objState.pos.y); 00263 drawCircle(img, loc, 00264 (int)objState.size, PixRGB<byte>(0,255,0),2); 00265 writeText(img, loc, objState.objName.c_str(), 00266 PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0)); 00267 drawLine(img, loc, 00268 objState.rotation, objState.size*3, PixRGB<byte>(255,0,0)); 00269 00270 if (objState.objName == "soldier") 00271 { 00272 int length = img.getWidth()-loc.i; 00273 drawRect(img, Rectangle(Point2D<int>(loc.i,loc.j-30), Dims(length, 60)), PixRGB<byte>(0,255,0)); 00274 } 00275 } 00276 00277 Point3D<float> HippocampusI::get3Dpos(int pan, int tilt) 00278 { 00279 Point3D<float> pos; 00280 00281 float cameraHeight = cos(M_PI-itsCameraAngle)*itsCameraDistance; 00282 float tiltAng = (M_PI-itsCameraAngle)+tilt*itsRadPerTilt; 00283 float panAng = pan*itsRadPerPan; 00284 00285 pos.y = tan(tiltAng)*cameraHeight; 00286 pos.x = tan(panAng)*sqrt( (cameraHeight*cameraHeight) + (pos.y*pos.y)); 00287 pos.z = 35; 00288 LINFO("Converting pan=%i tilt=%i to x=%f y=%f", pan, tilt, pos.x, pos.y); 00289 00290 return pos; 00291 } 00292 00293 00294 /////////////////////////// The VC Service to init the retina and start as a deamon /////////////// 00295 class HippocampusService : public Ice::Service { 00296 protected: 00297 virtual bool start(int, char* argv[]); 00298 virtual bool stop() { 00299 if (itsMgr) 00300 delete itsMgr; 00301 return true; 00302 } 00303 00304 private: 00305 Ice::ObjectAdapterPtr itsAdapter; 00306 ModelManager *itsMgr; 00307 }; 00308 00309 bool HippocampusService::start(int argc, char* argv[]) 00310 { 00311 00312 itsMgr = new ModelManager("HippocampusService"); 00313 00314 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(*itsMgr)); 00315 itsMgr->addSubComponent(ofs); 00316 00317 nub::ref<HippocampusI> hipp(new HippocampusI(*itsMgr, ofs)); 00318 itsMgr->addSubComponent(hipp); 00319 00320 itsMgr->parseCommandLine((const int)argc, (const char**)argv, "", 0, 0); 00321 00322 char adapterStr[255]; 00323 sprintf(adapterStr, "default -p %i", BrainObjects::HippocampusPort); 00324 itsAdapter = communicator()->createObjectAdapterWithEndpoints("HippocampusAdapter", 00325 adapterStr); 00326 00327 Ice::ObjectPtr object = hipp.get(); 00328 Ice::ObjectPrx objectPrx = itsAdapter->add(object, communicator()->stringToIdentity("Hippocampus")); 00329 hipp->initSimEvents(communicator(), objectPrx); 00330 itsAdapter->activate(); 00331 00332 itsMgr->start(); 00333 00334 return true; 00335 } 00336 00337 // ###################################################################### 00338 int main(int argc, char** argv) { 00339 00340 HippocampusService svc; 00341 return svc.main(argc, argv); 00342 }