00001 /*!@file RCBot/landmarkNav.C navigate the robot based on learned landmark 00002 positions */ 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // 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 <lelazary@yahoo.com> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/RCBot/landmarkNav.C $ 00035 // $Id: landmarkNav.C 13993 2010-09-20 04:54:23Z itti $ 00036 // 00037 00038 #include "Image/OpenCVUtil.H" 00039 #include "Image/Image.H" 00040 #include "Image/Pixels.H" 00041 #include "Component/ModelManager.H" 00042 #include "Image/CutPaste.H" // for inplacePaste() 00043 #include "GUI/XWinManaged.H" 00044 #include "Util/Timer.H" 00045 #include "Controllers/PID.H" 00046 #include "Image/PyrBuilder.H" 00047 #include "RCBot/TrackFeature.H" 00048 #include "RCBot/FindLandmark.H" 00049 00050 #include <signal.h> 00051 #include <unistd.h> 00052 #include <netdb.h> 00053 #include <fcntl.h> 00054 #include <arpa/inet.h> 00055 #include <stdlib.h> 00056 00057 #include "Corba/Objects/BotControlServerSK.hh" 00058 #include "Corba/Objects/SceneRecServerSK.hh" 00059 #include "Corba/ImageOrbUtil.H" 00060 #include "Corba/CorbaUtil.H" 00061 00062 #define LAND_WINSIZE 55 00063 00064 char info[255]; 00065 Point2D<int> trackLoc(-1,-1); 00066 Point2D<int> landmarkLoc(-1,-1); 00067 Point2D<int> oldLandmarkLoc(-1,-1); 00068 00069 static bool goforever = true; //!< Will turn false on interrupt signal 00070 00071 //! Signal handler (e.g., for control-C 00072 void terminate(int s) 00073 { LERROR("*** INTERRUPT ***"); goforever = false; exit(1); } 00074 00075 // ###################################################################### 00076 int main(int argc, char **argv) 00077 { 00078 MYLOGVERB = LOG_INFO; 00079 00080 // catch signals and redirect them to terminate for clean exit: 00081 signal(SIGHUP, terminate); signal(SIGINT, terminate); 00082 signal(SIGQUIT, terminate); signal(SIGTERM, terminate); 00083 signal(SIGALRM, terminate); 00084 00085 CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB4"); 00086 00087 // instantiate a model manager (for camera input): 00088 ModelManager manager("SaliencyMT Tester"); 00089 00090 nub::ref<SaliencyMT> smt(new SaliencyMT(manager, orb, 0)); 00091 manager.addSubComponent(smt); 00092 00093 // Bot controller 00094 CORBA::Object_ptr objBotControlRef[10]; int nBotControlObj; 00095 if (!getMultiObjectRef(orb, "saliency.BotControllers", 00096 objBotControlRef, nBotControlObj)){ 00097 LFATAL("Cannot find any object to bind with"); 00098 } 00099 BotControlServer_var robotController = 00100 BotControlServer::_narrow(objBotControlRef[0]); 00101 00102 // SceneRec 00103 CORBA::Object_ptr objSceneRecRef[10]; int nSceneRecObj; 00104 if (!getMultiObjectRef(orb, "saliency.SceneRec", objSceneRecRef, nSceneRecObj)) 00105 { 00106 LFATAL("Cannot find any SceneRec object to bind with"); 00107 } 00108 SceneRecServer_var sceneRec = SceneRecServer::_narrow(objSceneRecRef[0]); 00109 00110 // Parse command-line: 00111 if (manager.parseCommandLine((const int)argc, (const char**)argv, "", 0, 1) == false) 00112 return(1); 00113 00114 manager.start(); 00115 00116 PID<float> steer_pid(0.03, 0, 0, -1, 1); 00117 00118 // initialize the robot controller 00119 robotController->init(); 00120 00121 short w, h; 00122 robotController->getImageSensorDims(w,h,0); 00123 LINFO("Dim %i %i", w, h); 00124 00125 sprintf(info, "Testing..."); 00126 00127 // start the tracking thread 00128 TrackFeature trackFeature(smt); 00129 00130 // start the Landmark finding thread 00131 FindLandmark findLandmark(sceneRec); 00132 Image<PixRGB<byte> > landmarkImg; 00133 bool lookForLandmark = true; 00134 int leg = 0; // our current leg in the path 00135 00136 // start with a stopped car 00137 robotController->setSpeed(0); 00138 robotController->setSteering(0); 00139 00140 // Main loop. Get images and send them to the apropriate places 00141 while(goforever) 00142 { 00143 // get the image from the robot 00144 ImageOrb *imgOrb = robotController->getImageSensor(0); 00145 Image< PixRGB<byte> > ima; 00146 orb2Image(*imgOrb, ima); 00147 00148 LINFO("Send image"); 00149 // send image for tracking 00150 trackFeature.setImg(ima); 00151 00152 LINFO("Send image 2"); 00153 // send image to SceneRec to find the landmark we need to track 00154 findLandmark.setImg(ima); 00155 if (lookForLandmark){ 00156 landmarkImg = ima; 00157 lookForLandmark = false; 00158 } 00159 00160 LINFO("Compute locations"); 00161 int tempLeg = findLandmark.getLandmark(landmarkLoc); 00162 if (tempLeg > leg) leg = tempLeg; 00163 LINFO("Got landmark"); 00164 00165 // if we have a valid landmark location, 00166 // and it is not the same landmark we had before 00167 // then update our template tracking 00168 if ((landmarkLoc.isValid() && oldLandmarkLoc != landmarkLoc) || 00169 !trackLoc.isValid()) 00170 { 00171 LINFO("Setting tracking location"); 00172 trackFeature.setTrackLoc(landmarkLoc, landmarkImg); 00173 oldLandmarkLoc = landmarkLoc; 00174 lookForLandmark = true; 00175 } 00176 00177 LINFO("Getting tracking"); 00178 // Get the location we are tracking 00179 trackLoc = trackFeature.getTrackLoc(); 00180 LINFO("Got tracking"); 00181 00182 // get the user input if we do not know which landmark to track 00183 // and we lost the feature we were tracking 00184 // increment the leg # when the space bar is pressed 00185 LINFO("Landmark (%i,%i) track (%i,%i)", landmarkLoc.i, landmarkLoc.j, 00186 trackLoc.i, trackLoc.j); 00187 Point2DOrb locOrb; 00188 int key = robotController->getUserInput(locOrb); 00189 if (key == 65) // space bar 00190 leg++; 00191 00192 if (locOrb.i > 1 && locOrb.j > 1){ // we got input 00193 landmarkLoc.i = locOrb.i; landmarkLoc.j = locOrb.j; 00194 if (key != -1 || landmarkLoc.isValid()){ 00195 LINFO("Key %i loc (%i,%i)", key, landmarkLoc.i, landmarkLoc.j); 00196 } 00197 00198 // start tracking the given landmark position 00199 trackFeature.setTrackLoc(landmarkLoc, ima); 00200 oldLandmarkLoc = landmarkLoc; 00201 00202 // learn the landmark using SIFT 00203 DimsOrb winOrb = {LAND_WINSIZE, LAND_WINSIZE}; 00204 sceneRec->trainFeature(*image2Orb(ima), toOrb(landmarkLoc), winOrb, leg); 00205 00206 //landmarkLoc.i = -1; landmarkLoc.j = -1; 00207 } 00208 00209 // drive the robot toward the tracking point 00210 if (trackLoc.isValid()){ 00211 00212 double steer_cor = steer_pid.update(w/2, trackLoc.i); 00213 if (steer_cor > 1) steer_cor = 1; 00214 else if (steer_cor < -1) steer_cor = -1; 00215 //LINFO("Steer %i %i %f\n", w/2, fixation.i, steer_cor); 00216 robotController->setSteering(steer_cor); 00217 //robotController->setSpeed(-0.325); 00218 robotController->setSpeed(-0.4); 00219 } else { 00220 robotController->setSpeed(0); 00221 } 00222 00223 sprintf(info, "%.1ffps l=%i", trackFeature.getFps(), leg); 00224 robotController->setInfo(info, toOrb(trackLoc), toOrb(landmarkLoc)); 00225 } 00226 00227 manager.stop(); 00228 return 0; 00229 } 00230 00231 // ###################################################################### 00232 /* So things look consistent in everyone's emacs... */ 00233 /* Local Variables: */ 00234 /* indent-tabs-mode: nil */ 00235 /* End: */