00001 /*!@file NeovisionII/PTZService.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/PTZService.C $ 00035 // $Id: PTZService.C 12962 2010-03-06 02:13:53Z irock $ 00036 // 00037 00038 #include "NeovisionII/PTZService.H" 00039 #include "Util/sformat.H" 00040 #include "Image/DrawOps.H" 00041 00042 using namespace std; 00043 using namespace ImageIceMod; 00044 00045 PTZI::PTZI(OptionManager& mgr, 00046 const std::string& descrName, 00047 const std::string& tagName) : 00048 ModelComponent(mgr, descrName, tagName), 00049 itsZoomIn(false), 00050 itsZoomOut(false), 00051 itsInitPtz(false) 00052 { 00053 //Subscribe to the various topics 00054 IceStorm::TopicPrx topicPrx; 00055 itsTopicsSubscriptions.push_back(TopicInfo("VisualTrackerTopic", topicPrx)); 00056 itsTopicsSubscriptions.push_back(TopicInfo("PrefrontalCortexTopic", topicPrx)); 00057 00058 itsCameraCtrl = nub::soft_ref<Visca>(new Visca(mgr)); 00059 addSubComponent(itsCameraCtrl); 00060 00061 } 00062 00063 00064 00065 PTZI::~PTZI() 00066 { 00067 unsubscribeSimEvents(); 00068 } 00069 00070 void PTZI::start2() 00071 { 00072 } 00073 00074 00075 void PTZI::initSimEvents(Ice::CommunicatorPtr icPtr, Ice::ObjectPrx objectPrx) 00076 { 00077 //Get the IceStorm object 00078 Ice::ObjectPrx obj = icPtr->stringToProxy("SimEvents/TopicManager:tcp -p 11111"); 00079 IceStorm::TopicManagerPrx topicManager = 00080 IceStorm::TopicManagerPrx::checkedCast(obj); 00081 00082 //Create a Segmenter Topic 00083 IceStorm::TopicPrx topic; 00084 try { 00085 topic = topicManager->retrieve("CameraCtrlTopic"); //check if the Retina topic exists 00086 } catch (const IceStorm::NoSuchTopic&) { 00087 topic = topicManager->create("CameraCtrlTopic"); //The retina topic does not exists, create 00088 } 00089 //Make a one way visualCortex message publisher for efficency 00090 Ice::ObjectPrx pub = topic->getPublisher()->ice_oneway(); 00091 itsEventsPub = SimEvents::EventsPrx::uncheckedCast(pub); 00092 00093 //Subscribe the SimulationViewer to theTopics 00094 itsObjectPrx = objectPrx; 00095 //subscribe to the topics 00096 for(uint i=0; i<itsTopicsSubscriptions.size(); i++) 00097 { 00098 try { 00099 IceStorm::QoS qos; 00100 itsTopicsSubscriptions[i].topicPrx = 00101 topicManager->retrieve(itsTopicsSubscriptions[i].name.c_str()); //Get the 00102 itsTopicsSubscriptions[i].topicPrx->subscribeAndGetPublisher(qos, itsObjectPrx); //Subscribe to the retina topic 00103 } catch (const IceStorm::NoSuchTopic&) { 00104 LFATAL("Error! No %s topic found!", itsTopicsSubscriptions[i].name.c_str()); 00105 } catch (const char* msg) { 00106 LINFO("Error %s", msg); 00107 } catch (const Ice::Exception& e) { 00108 cerr << e << endl; 00109 } 00110 00111 } 00112 } 00113 00114 void PTZI::unsubscribeSimEvents() 00115 { 00116 //Unsubscribe from all the topics we are registerd to 00117 for(uint i=0; i<itsTopicsSubscriptions.size(); i++) 00118 { 00119 itsTopicsSubscriptions[i].topicPrx->unsubscribe(itsObjectPrx); 00120 } 00121 } 00122 00123 00124 void PTZI::evolve(const SimEvents::EventMessagePtr& eMsg, 00125 const Ice::Current&) 00126 { 00127 if (eMsg->ice_isA("::SimEvents::VisualTrackerMessage")){ 00128 SimEvents::VisualTrackerMessagePtr msg = SimEvents::VisualTrackerMessagePtr::dynamicCast(eMsg); 00129 00130 if (msg->trackLocs.size() > 0) 00131 if (itsZoomIn) 00132 moveCameraToTarget(Point2D<int>(msg->trackLocs[0].pos.i, msg->trackLocs[0].pos.j)); 00133 00134 } else if (eMsg->ice_isA("::SimEvents::CameraCtrlBiasMessage")){ 00135 SimEvents::CameraCtrlBiasMessagePtr msg = SimEvents::CameraCtrlBiasMessagePtr::dynamicCast(eMsg); 00136 00137 itsZoomIn = msg->zoomIn; 00138 itsZoomOut = msg->zoomOut; 00139 itsInitPtz = msg->initPtz; 00140 } 00141 00142 if (itsInitPtz) 00143 { 00144 sleep(2); 00145 LINFO("INit pan tilt"); 00146 itsCameraCtrl->zoom(0); //Zoom out 00147 sleep(3); 00148 itsCameraCtrl->movePanTilt(0,0); 00149 itsInitPtz = false; 00150 sleep(3); //TODO replace with a blocking call 00151 00152 SimEvents::CameraCtrlMessagePtr ptzMsg = new SimEvents::CameraCtrlMessage; 00153 ptzMsg->initPtzDone = true; 00154 ptzMsg->zoomDone = false; 00155 ptzMsg->pan = 0; 00156 ptzMsg->tilt = 0; 00157 itsEventsPub->evolve(ptzMsg); 00158 } 00159 00160 } 00161 00162 00163 void PTZI::moveCameraToTarget(Point2D<int> targetLoc) 00164 { 00165 00166 //move camera to target loc 00167 Point2D<int> locErr = targetLoc - Point2D<int>(320/2, 240/2); 00168 00169 int currentZoom = itsCameraCtrl->getCurrentZoom(); 00170 00171 Point2D<float> pGain(0.30, 0.30); 00172 00173 if (currentZoom > 800) 00174 { 00175 pGain.i = 0.01; pGain.j = 0.01; 00176 } else if (currentZoom > 1000) 00177 { 00178 pGain.i = 0.05; pGain.j = 0.05; 00179 } 00180 00181 00182 //P controller for now 00183 Point2D<float> u = pGain*locErr; 00184 00185 00186 LINFO("Target is at: %ix%i zoom=%i (err %ix%i) move=%ix%i", 00187 targetLoc.i, targetLoc.j, currentZoom, 00188 locErr.i, locErr.j, 00189 (int)u.i, (int)u.j); 00190 00191 if (fabs(locErr.distance(Point2D<int>(0,0))) > 16) 00192 itsCameraCtrl->movePanTilt((int)u.i, -1*(int)u.j, true); //move relative 00193 else 00194 { 00195 if (currentZoom < 750) 00196 itsCameraCtrl->zoom(10, true); //move relative 00197 else 00198 { 00199 LINFO("Done zooming"); 00200 sleep(1); 00201 itsZoomOut = false; 00202 itsZoomIn = false; 00203 SimEvents::CameraCtrlMessagePtr ptzMsg = new SimEvents::CameraCtrlMessage; 00204 ptzMsg->initPtzDone = false; 00205 ptzMsg->zoomDone = true; 00206 short int pan=0, tilt = 0; 00207 bool gotPanTilt = false; 00208 for(int i=0; i<5 && !gotPanTilt; i++) 00209 if (itsCameraCtrl->getPanTilt(pan,tilt)) 00210 gotPanTilt = true; 00211 00212 if (!gotPanTilt) 00213 { 00214 LINFO("Error getting pan tilt"); 00215 sleep(10); 00216 } 00217 00218 ptzMsg->pan = pan; 00219 ptzMsg->tilt = tilt; 00220 itsEventsPub->evolve(ptzMsg); 00221 } 00222 } 00223 00224 } 00225 00226 /////////////////////////// The VC Service to init the retina and start as a deamon /////////////// 00227 class PTZService : public Ice::Service { 00228 protected: 00229 virtual bool start(int, char* argv[]); 00230 virtual bool stop() { 00231 if (itsMgr) 00232 delete itsMgr; 00233 return true; 00234 } 00235 00236 private: 00237 Ice::ObjectAdapterPtr itsAdapter; 00238 ModelManager *itsMgr; 00239 }; 00240 00241 bool PTZService::start(int argc, char* argv[]) 00242 { 00243 00244 itsMgr = new ModelManager("PTZService"); 00245 00246 nub::ref<PTZI> ptz(new PTZI(*itsMgr)); 00247 itsMgr->addSubComponent(ptz); 00248 00249 itsMgr->parseCommandLine((const int)argc, (const char**)argv, "", 0, 0); 00250 00251 char adapterStr[255]; 00252 sprintf(adapterStr, "default -p %i", BrainObjects::PTZPort); 00253 itsAdapter = communicator()->createObjectAdapterWithEndpoints("PTZAdapter", 00254 adapterStr); 00255 00256 Ice::ObjectPtr object = ptz.get(); 00257 Ice::ObjectPrx objectPrx = itsAdapter->add(object, communicator()->stringToIdentity("PTZ")); 00258 ptz->initSimEvents(communicator(), objectPrx); 00259 itsAdapter->activate(); 00260 00261 itsMgr->start(); 00262 00263 return true; 00264 } 00265 00266 // ###################################################################### 00267 int main(int argc, char** argv) { 00268 00269 PTZService svc; 00270 return svc.main(argc, argv); 00271 }