00001 /*!@file Robots2/Beobot2/LaneFollowing/RG_Lane/RG_Lane.C */ 00002 // //////////////////////////////////////////////////////////////////// // 00003 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00004 // University of Southern California (USC) and the iLab at USC. // 00005 // See http://iLab.usc.edu for information about this project. // 00006 // //////////////////////////////////////////////////////////////////// // 00007 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00008 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00009 // in Visual Environments, and Applications'' by Christof Koch and // 00010 // Laurent Itti, California Institute of Technology, 2001 (patent // 00011 // pending; application number 09/912,225 filed July 23, 2001; see // 00012 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00013 // //////////////////////////////////////////////////////////////////// // 00014 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00015 // // 00016 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00017 // redistribute it and/or modify it under the terms of the GNU General // 00018 // Public License as published by the Free Software Foundation; either // 00019 // version 2 of the License, or (at your option) any later version. // 00020 // // 00021 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00022 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00023 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00024 // PURPOSE. See the GNU General Public License for more details. // 00025 // // 00026 // You should have received a copy of the GNU General Public License // 00027 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00028 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00029 // Boston, MA 02111-1307 USA. // 00030 // //////////////////////////////////////////////////////////////////// // 00031 // 00032 // Primary maintainer for this file: Chin-Kai Chang <chinkaic@usc.edu> 00033 // $HeadURL: svn://ilab.usc.edu/trunk/saliency/src/Robots/Beobot2/RG_Lane.C 00034 // $ $Id: RG_Lane.C 13084 2010-03-30 02:42:00Z kai $ 00035 // 00036 ////////////////////////////////////////////////////////////////////////// 00037 //#include "Image/OpenCVUtil.H" 00038 #include "Robots/Beobot2/LaneFollowing/RG_Lane/RG_Lane.H" 00039 00040 #include "Raster/Raster.H" 00041 #include "Util/sformat.H" 00042 #include "Image/Image.H" 00043 #include "Image/DrawOps.H" // for 00044 #include "Image/ColorOps.H" // for luminance(),colorize() 00045 #include "Image/ShapeOps.H" // for rescale() 00046 #include "Image/MathOps.H" // for stdev() 00047 #include "Image/MatrixOps.H" // for matrixMult() 00048 #include "Image/CutPaste.H" // for inplacePaste() 00049 #include "Image/Transforms.H" // for segmentObject() 00050 #include "Image/Normalize.H" // for normalizeFloat() 00051 #include "Util/Timer.H" 00052 #include "Ice/BeobotEvents.ice.H" 00053 00054 00055 #include "SIFT/Keypoint.H" 00056 #include "SIFT/VisualObject.H" 00057 #include "SIFT/VisualObjectMatch.H" 00058 #include "Transport/FrameInfo.H" 00059 00060 #include "Ice/IceImageUtils.H" 00061 00062 #include "Component/ModelParam.H" 00063 #include "Component/ModelOptionDef.H" 00064 00065 #include "GUI/DebugWin.H" // for SHOWIMG() 00066 00067 #include <map> 00068 #define FOLDER "../data/logs" 00069 //#define DBNAME "Lane" 00070 //#define DBNAME "outdoor" 00071 //#define DBNAME "indoor" 00072 #define DBNAME "Equad" 00073 #define IMAGE_PREFIX "image_0000000000" 00074 00075 00076 //float window does not doing better 00077 #define USE_FLOAT_WINDOW 0 00078 // ###################################################################### 00079 RG_Lane::RG_Lane(OptionManager& mgr, 00080 const std::string& descrName, const std::string& tagName) : 00081 RobotBrainComponent(mgr, descrName, tagName), 00082 itsSmt(new SaliencyMT(mgr,descrName,tagName)), 00083 itsOfs(new OutputFrameSeries(mgr)), 00084 itsKf(80.0,30.0), 00085 itsKfx(0), 00086 itsTimer(1000000) 00087 { 00088 setModelParamVal("InputFameDims",Dims(320,240),MC_RECURSE|MC_IGNORE_MISSING); 00089 addSubComponent(itsSmt); 00090 itsRoadColor = PixRGB<byte>(0,0,0); 00091 itsMiddlePoint[0] = 0; 00092 itsMiddlePoint[1] = 0; 00093 itsMiddlePoint[2] = 0; 00094 itsMiddlePoint[3] = 0; 00095 itsMiddlePoint[4] = 0; 00096 itsRoadColorDiff = 0.0; 00097 itsEstMiddlePoint = Point2D<int>(0,0); 00098 itsRoadColorDiffSub = PixRGB<byte>(0,0,0); 00099 itsOfs->addFrameDest("display");//Add default --out=display 00100 addSubComponent(itsOfs); 00101 itsWaitScreen = false; 00102 itsGroundTruthMode = false; 00103 itsUseFloatWindow = false; 00104 00105 // load image db 00106 LINFO("load db"); 00107 itsConfFilename = std::string(sformat("%s/%s/%s.conf",FOLDER,DBNAME,DBNAME)); 00108 openDB(itsConfFilename.c_str()); 00109 } 00110 00111 // ###################################################################### 00112 void RG_Lane::openDB(const std::string& path) 00113 { 00114 FILE *dbconf = fopen(path.c_str(),"r"); 00115 if(dbconf == NULL){ 00116 LFATAL("Can not open file: %s",path.c_str()); 00117 }else{ 00118 char line[512]; 00119 while(fgets(line,sizeof line,dbconf)!= NULL) 00120 { 00121 LINFO("Got line[%s]",line); 00122 //Skip the line start at# 00123 if(line[0] != '#') 00124 { 00125 char subdb[256]; 00126 int start,end; 00127 int ret = sscanf(line,"%s %d %d",subdb,&start,&end); 00128 if(ret == 3){ 00129 LINFO("Got [%s],start[%d],end[%d]",subdb,start,end); 00130 std::string path = sformat("%s/%s/%s/%s",FOLDER,DBNAME,subdb,IMAGE_PREFIX); 00131 imageDB tmpDB(path,start,end); 00132 itsImageDB = tmpDB; 00133 } 00134 } 00135 } 00136 } 00137 } 00138 00139 // ###################################################################### 00140 RG_Lane::~RG_Lane() 00141 { } 00142 00143 // ###################################################################### 00144 void RG_Lane::start1() 00145 { } 00146 00147 // ###################################################################### 00148 void RG_Lane::registerTopics() 00149 { 00150 // subscribe to all sensor data 00151 this->registerSubscription("CameraMessageTopic"); 00152 this->registerSubscription("MotorMessageTopic"); 00153 this->registerPublisher("MotorRequestTopic"); 00154 } 00155 00156 // ###################################################################### 00157 void RG_Lane::evolve() 00158 { 00159 // if simulation 00160 00161 00162 if(!itsWaitScreen){ 00163 loadFrame();//Load fram from file instead of camera 00164 drawState(); 00165 itsOfs->writeRGB(itsDispImg, "display", FrameInfo("RG_nav",SRC_POS)); 00166 } 00167 //handle clicks 00168 const nub::soft_ref<ImageDisplayStream> ids = 00169 itsOfs->findFrameDestType<ImageDisplayStream>(); 00170 00171 const rutz::shared_ptr<XWinManaged> uiwin = 00172 ids.is_valid() 00173 ? ids->getWindow("display") 00174 : rutz::shared_ptr<XWinManaged>(); 00175 00176 00177 if (uiwin.is_valid()) 00178 { 00179 00180 int key = uiwin->getLastKeyPress(); 00181 00182 switch(key) 00183 { 00184 case -1: 00185 break; 00186 case 42: //g label ground 00187 itsWaitScreen = true; 00188 itsGroundTruthMode = true; 00189 groundTruthMode(uiwin); 00190 break; 00191 case 41: //f forward faster 00192 itsImageDB.forwardFaster(); 00193 break; 00194 case 40: //d forward slower 00195 itsImageDB.forwardSlower(); 00196 break; 00197 case 39: //s flip play direction 00198 itsImageDB.flipDirection(); 00199 break; 00200 case 38: //a forward normal 00201 itsImageDB.forwardNormal(); 00202 break; 00203 default: 00204 LINFO("key %i", key); 00205 itsWaitScreen =! itsWaitScreen; 00206 break; 00207 00208 } 00209 00210 Point2D<int> pos = uiwin->getLastMouseClick(); 00211 if (pos.isValid()) 00212 { 00213 PixRGB<byte> pixColor = itsDispImg.getVal(pos); 00214 LINFO("Mouse Click (%d %d) Color (%d,%d,%d)", pos.i,pos.j,pixColor.red(),pixColor.green(),pixColor.blue()); 00215 } 00216 00217 00218 00219 00220 } 00221 00222 00223 00224 00225 //itsOfs->writeRGB(itsDispImg, "RG_nav", FrameInfo("RG_nav",SRC_POS)); 00226 } 00227 00228 // ###################################################################### 00229 void RG_Lane::loadFrame() 00230 { 00231 // load teach image data 00232 itsTimer.reset(); 00233 itsCurrImg = itsImageDB.nextImg(); 00234 if(itsCurrImg.getDims() != Dims(320,240)){ 00235 itsCurrImg = rescale(itsCurrImg,Dims(320,240)) ; 00236 } 00237 00238 00239 LDEBUG("Time for Load %f", itsTimer.get()/1000.0); 00240 } 00241 00242 void RG_Lane::groundTruthMode(const rutz::shared_ptr<XWinManaged> uiwin){ 00243 00244 int clickCount = 0; 00245 int w = itsCurrImg.getWidth(); 00246 int h = itsCurrImg.getHeight(); 00247 Point2D<int> l1,l2,r1,r2,r3,vp,mp,bp,lbp,rbp; 00248 00249 00250 00251 Point2D<int> bl1 = Point2D<int>(0,2*h);//Image bottom line left 00252 Point2D<int> bl2 = Point2D<int>(w,2*h);//Image bottom line right 00253 Point2D<int> offset_2x = Point2D<int>(w,0); 00254 Image<PixRGB<byte> > tempImage; 00255 00256 tempImage.resize(itsDispImg.getDims(), ZEROS); 00257 tempImage = itsDispImg; 00258 char buffer[200]; 00259 bool save = false; 00260 sprintf(buffer,"Ground Truth Mode"); 00261 writeText(tempImage,Point2D<int>(0,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(20)); 00262 inplacePaste(tempImage, rescale(itsCurrImg,itsCurrImg.getDims()*2), offset_2x); 00263 00264 00265 sprintf(buffer,"Please Click Left Top Edge"); 00266 writeText(tempImage,Point2D<int>(w,10),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,255),SimpleFont::FIXED(20)); 00267 itsOfs->writeRGB(tempImage, "display", FrameInfo("RG_nav",SRC_POS)); 00268 00269 00270 while(clickCount < 5){ 00271 if (uiwin.is_valid()) 00272 { 00273 00274 Point2D<int> pos = uiwin->getLastMouseClick(); 00275 if (pos.isValid()) 00276 { 00277 PixRGB<byte> pixColor = itsDispImg.getVal(pos); 00278 LINFO("Mouse Click (%d %d) Color (%d,%d,%d) Click %d", pos.i,pos.j,pixColor.red(),pixColor.green(),pixColor.blue(),clickCount); 00279 switch(clickCount){ 00280 case 0: 00281 l1 = pos; 00282 sprintf(buffer,"Please Click Left Bottom Edge"); 00283 writeText(tempImage,Point2D<int>(w*1,10),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,255),SimpleFont::FIXED(20)); 00284 break; 00285 case 1: 00286 l2 = pos; 00287 drawLine(tempImage,l1,l2,PixRGB<byte>(0,255,0),2);//screen center -Green line 00288 sprintf(buffer,"Please Click Right Top Edge"); 00289 writeText(tempImage,Point2D<int>(w*1,10),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,255),SimpleFont::FIXED(20)); 00290 break; 00291 case 2: 00292 sprintf(buffer,"Please Click Right Bottom Edge"); 00293 writeText(tempImage,Point2D<int>(w*1,10),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,255),SimpleFont::FIXED(20)); 00294 r1 = pos; 00295 break; 00296 case 3: 00297 r2 = pos; 00298 drawLine(tempImage,r1,r2,PixRGB<byte>(0,255,0),2);//screen center -Green line 00299 vp = vanishPoint(l1,l2,r1,r2); 00300 drawCircle(tempImage,vp,5,PixRGB<byte>(20,50,255),10); 00301 00302 r3 = vanishPoint(l2,Point2D<int>(l2.i+1,l2.j),r1,r2);//Find r3 point with same y of left line 00303 mp = (l2+r3)/2;//bottom of middle point 00304 //drawCircle(tempImage,mp,10,PixRGB<byte>(20,50,255)); 00305 00306 //middle point of image bottom edge 00307 bp = vanishPoint(bl1,bl2,vp,mp); 00308 //drawCircle(tempImage,bp,10,PixRGB<byte>(20,50,255)); 00309 00310 lbp = vanishPoint(l1,l2,bl1,bl2); 00311 rbp = vanishPoint(r1,r2,bl1,bl2); 00312 00313 00314 drawLine(tempImage,vp,bp,PixRGB<byte>(255,255,0),2);//groudtruth middle line 00315 drawLine(tempImage,vp,lbp,PixRGB<byte>(0,255,0),2);//screen center -Green line 00316 drawLine(tempImage,vp,rbp,PixRGB<byte>(0,255,0),2);//screen center -Green line 00317 00318 00319 //Draw Buttons 00320 sprintf(buffer," "); 00321 writeText(tempImage,Point2D<int>(w*1,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(20)); 00322 writeText(tempImage,Point2D<int>(w*1,10),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(20)); 00323 sprintf(buffer,"Save"); 00324 writeText(tempImage,Point2D<int>(w*1.7,10),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,255,0),SimpleFont::FIXED(20)); 00325 sprintf(buffer,"Redo"); 00326 writeText(tempImage,Point2D<int>(w*2.0,10),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,255,0),SimpleFont::FIXED(20)); 00327 sprintf(buffer,"Cancel"); 00328 writeText(tempImage,Point2D<int>(w*2.3,10),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,255,0),SimpleFont::FIXED(20)); 00329 00330 break; 00331 case 4: 00332 00333 //redo 00334 if(pos.j < 55){ 00335 00336 //handle button click 00337 if(pos.i >= (w*1.7-10) && pos.i < (w*2-10)){ 00338 LINFO("Save"); 00339 clickCount = 6; 00340 save = true; 00341 }else if(pos.i >= (w*2-10) && pos.i < (w*2.3-10)){ 00342 LINFO("Redo"); 00343 00344 clickCount = -1; 00345 tempImage = itsDispImg; 00346 inplacePaste(tempImage, rescale(itsCurrImg,itsCurrImg.getDims()*2), offset_2x); 00347 sprintf(buffer,"Ground Truth Mode"); 00348 writeText(tempImage,Point2D<int>(0,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(20)); 00349 sprintf(buffer,"Please Click Left Top Edge"); 00350 writeText(tempImage,Point2D<int>(w,10),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,255),SimpleFont::FIXED(20)); 00351 }else if(pos.i >= (w*2.3-10) && pos.i < (w*2.6-10)){ 00352 clickCount = 6;//exit click 00353 tempImage = itsDispImg; 00354 LINFO("Cancel"); 00355 }else{ 00356 00357 clickCount = 3;//do notthing 00358 } 00359 00360 }else{ 00361 clickCount = 3;//do notthing 00362 } 00363 00364 00365 00366 00367 break; 00368 default: 00369 break; 00370 } 00371 clickCount++; 00372 00373 } 00374 } 00375 itsOfs->writeRGB(tempImage, "display", FrameInfo("RG_nav",SRC_POS)); 00376 } 00377 00378 00379 if(save){ 00380 //Convert coords to 1x size 00381 Point2D<int> nvp,nbp,nlbp,nrbp,offset_1x,np; 00382 nvp = (vp - offset_2x)/2; 00383 nbp = (bp - offset_2x)/2; 00384 nlbp = (lbp - offset_2x)/2; 00385 nrbp = (rbp - offset_2x)/2; 00386 00387 //Conpute navigation point, 8 pixel above bottom 00388 np = vanishPoint(Point2D<int>(0,h-8),Point2D<int>(w,h-8),nvp,nbp); 00389 00390 std::string trainGT = std::string(sformat("GT:ID %d,VP %d,%d,BP %d,%d,LBP %d,%d,RBP %d,%d,npx %d\n",itsImageDB.getCurrentImageID(),nvp.i,nvp.j,nbp.i,nbp.j,nlbp.i,nlbp.j,nrbp.i,nrbp.j,np.i)); 00391 LINFO(trainGT.c_str()); 00392 writeToConfFile(trainGT); 00393 LINFO("GT - EST %d",np.i - itsEstMiddlePoint.i); 00394 00395 tempImage = itsDispImg; 00396 offset_1x = Point2D<int>(2*w,h); 00397 //Draw line on orginal image 00398 00399 drawCircle(itsGroundTruthImg,nvp ,5,PixRGB<byte>(20,50,255),10); 00400 drawLine(itsGroundTruthImg,nvp ,nbp ,PixRGB<byte>(255,255,0),2);//groudtruth middle line 00401 drawLine(itsGroundTruthImg,nvp ,nlbp ,PixRGB<byte>(0,255,0),2);//screen center -Green line 00402 drawLine(itsGroundTruthImg,nvp ,nrbp ,PixRGB<byte>(0,255,0),2);//screen center -Green line 00403 00404 inplacePaste(tempImage, itsGroundTruthImg, Point2D<int>(2*w, h)); 00405 } 00406 00407 //Return back to normal mode with labeled data 00408 itsOfs->writeRGB(tempImage, "display", FrameInfo("RG_nav",SRC_POS)); 00409 00410 } 00411 // ###################################################################### 00412 Image<PixRGB<byte> > RG_Lane::getSuperPixel(Image<PixRGB<byte> > img) 00413 { 00414 if(!img.initialized()) 00415 return Image<PixRGB<byte> >(320,240,ZEROS); 00416 // default parameters for the Superpixel segmentation 00417 float sigma = .5; uint k = 500; uint minSize = 20; 00418 int num_ccs; 00419 std::vector<std::vector<Point2D<int> > > groups; 00420 Image<int> groupImage = SuperPixelSegment(img,sigma, k, minSize, num_ccs, &groups); 00421 Image<PixRGB<byte> > sp_img = SuperPixelDebugImage(groups,img); 00422 Image<int> sp_size_img = SuperPixelRegionSizeImage(groups,groupImage); 00423 00424 int w = sp_img.getWidth(); 00425 int h = sp_img.getHeight(); 00426 00427 //Look for road color, let's assume it always show up in the middle bottom 00428 //(h-5,w/2 +- 10) 00429 00430 std::vector<PixRGB<byte> > color_map; 00431 std::vector<int> color_size_map; 00432 std::vector<int> color_map_count; 00433 00434 //Pick all road pixel candidates 00435 for(int i = -10; i<= 10;i++) 00436 { 00437 //We are search bottom area as most likely road pixel candidates 00438 for(int k = 1; k <=5;k++){ 00439 00440 //set our grow window float to the middle of road 00441 int middlePoint; 00442 if(itsMiddlePoint[k-1]!=0 && itsUseFloatWindow){ 00443 middlePoint = itsMiddlePoint[k-1]/4;//1/4 size image 00444 LINFO("=========Float Window %d midpoint %d",middlePoint,k-1); 00445 }else{ 00446 00447 middlePoint = w/2; 00448 LINFO("=========Fixed Window %d midpoint",middlePoint); 00449 } 00450 if(sp_img.coordsOk(middlePoint+i,h-k)){ 00451 PixRGB<byte> tmp_color = sp_img.getVal(middlePoint + i,h-k); 00452 int regionSize = sp_size_img.getVal(middlePoint+i,h-k); 00453 00454 bool notfound = true; 00455 00456 // Search color 00457 for(int j = 0; j < (int)color_map.size() && notfound ; j++) 00458 { 00459 if(color_map[j] == tmp_color) 00460 { 00461 notfound = false; 00462 color_map_count[j]++; 00463 } 00464 } 00465 if(notfound) 00466 { 00467 //This color is not in the map 00468 color_map.push_back(tmp_color); 00469 color_map_count.push_back(0); 00470 color_size_map.push_back(regionSize); 00471 } 00472 } 00473 } 00474 } 00475 00476 if(color_map.size() != 1) 00477 {//if we found more than one color 00478 //Some Option Here: 00479 //1.Choose max count color 00480 //2.Pick min color difference from previous avg road color pixel 00481 00482 //if road color is not available, we pick max pixel color 00483 if(itsRoadColor == PixRGB<byte>(0,0,0)){ 00484 int max = color_map_count[0]; 00485 int max_index = 0; 00486 for(int i = 1; i < (int)color_map_count.size() ; i++) 00487 { 00488 if(max < color_map_count[i]) 00489 { 00490 max = color_map_count[i]; 00491 max_index = i; 00492 } 00493 } 00494 itsRoadColor = color_map[max_index]; 00495 LINFO("Max count color have count %d",max); 00496 }else{ 00497 //Pick min color difference color 00498 int min_index = 0; 00499 float min = colorDiff(itsRoadColor,color_map[0]); 00500 for(int i = 1; i < (int)color_map_count.size() ; i++) 00501 { 00502 float cd = colorDiff(itsRoadColor,color_map[i]); 00503 int rs = color_size_map[i];//region size 00504 LINFO("======Road Region Size %d",rs); 00505 if(cd < min && rs > 100) 00506 { 00507 min = cd; 00508 min_index = i; 00509 } 00510 } 00511 itsRoadColorDiff = colorDiff(itsRoadColor,color_map[min_index]); 00512 00513 //to prevent jump too much 00514 if(itsRoadColorDiff < 50.0){ 00515 itsRoadColor = color_map[min_index]; 00516 }else{ 00517 //keep avg color so it will help to solve kid-napping problem 00518 PixRGB<byte> avgColor = colorAvg(itsRoadColor,color_map[0]); 00519 itsRoadColor = avgColor; 00520 LINFO("COLOR DIFF1 %f",itsRoadColorDiff); 00521 } 00522 } 00523 } 00524 else 00525 { 00526 //if only one region 00527 itsRoadColorDiff = colorDiff(itsRoadColor,color_map[0]); 00528 itsRoadColorDiffSub = colorDiffSub(itsRoadColor,color_map[0]); 00529 00530 if(itsRoadColorDiff < 50.0 && color_map[0].green() > 150){ 00531 itsRoadColor = color_map[0]; 00532 itsUseFloatWindow = false; 00533 }else{ 00534 PixRGB<byte> avgColor = colorAvg(itsRoadColor,color_map[0]); 00535 itsRoadColor = avgColor; 00536 itsUseFloatWindow = true; 00537 LINFO("COLOR DIFF2 %f,USE float window",itsRoadColorDiff); 00538 } 00539 LINFO("Only one color (%d,%d,%d)",itsRoadColor.red(),itsRoadColor.green(),itsRoadColor.blue()); 00540 } 00541 00542 // use iterator!!!!!! 00543 Image<PixRGB<byte> > output(w,h,ZEROS); 00544 Image<PixRGB<byte> > hybrid(w,h,ZEROS); 00545 // inplacePaste(output, sp_img, Point2D<int>(w, 0)); 00546 for(int y = 0 ; y < h ; y ++) 00547 { 00548 int dot = 0; 00549 for(int x = 0 ; x < w ; x ++) 00550 { 00551 PixRGB<byte> c = sp_img.getVal(x,y); 00552 //LINFO("Pixel color(%d,%d,%d)road color(%d,%d,%d)",c.red(),c.green(),c.blue(), 00553 // itsRoadColor.red(),itsRoadColor.green(),itsRoadColor.blue()); 00554 if(c == itsRoadColor) { 00555 //Set road color to red 00556 output.setVal(x,y,PixRGB<byte>(255,0,0)); 00557 //LINFO("Found road pixel============"); 00558 if(dot % 3 == 0){ 00559 hybrid.setVal(x,y,PixRGB<byte>(255,0,0)); 00560 }else{ 00561 hybrid.setVal(x,y,c); 00562 } 00563 dot ++; 00564 } 00565 else{ 00566 //set to it's color 00567 output.setVal(x,y,c); 00568 hybrid.setVal(x,y,c); 00569 // output.setVal(x,y,c); 00570 } 00571 } 00572 } 00573 if(!output.initialized()) 00574 return img; 00575 00576 LINFO("Finish Road Finding"); 00577 itsRawSuperPixelImg = hybrid; 00578 return output; 00579 } 00580 00581 // ###################################################################### 00582 //Image<PixRGB<byte> > RG_Lane::getCannyEdgeDraw(Image<PixRGB<byte> > img){} 00583 // ###################################################################### 00584 00585 //Doing Canny Edge 00586 Image<PixRGB<byte> > RG_Lane::getCannyEdge(Image<PixRGB<byte> > img,Image<PixRGB<byte> > &rawCannyImg){ 00587 00588 if(!itsCurrImg.initialized()) 00589 return img; 00590 //Doing Canny Edge 00591 IplImage *cvImg = cvCreateImage(cvGetSize(img2ipl(itsCurrImg)),8,1); 00592 CvMemStorage *s = cvCreateMemStorage(0); 00593 CvSeq *lines = 0; 00594 00595 cvCanny(img2ipl(luminance(itsCurrImg)),cvImg,100,150,3); 00596 Image<PixRGB<byte> > edgeImg = toRGB(ipl2gray(cvImg)); 00597 rawCannyImg = edgeImg; 00598 00599 lines = cvHoughLines2(cvImg,s,CV_HOUGH_PROBABILISTIC,1,CV_PI/180,80,30,10); 00600 00601 int lx1 = 0,lx2 = 0,ly1 = 0,ly2 = 0,rx1 = 0,rx2 =0 ,ry1 = 0,ry2 = 0; 00602 for(int i = 0;i<MIN(lines->total,100);i++) 00603 { 00604 CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i); 00605 Point2D<int> pt1 = Point2D<int>(line[0].x,line[0].y); 00606 Point2D<int> pt2 = Point2D<int>(line[1].x,line[1].y); 00607 int dx = pt2.i - pt1.i; 00608 int dy = pt2.j - pt1.j; 00609 int midx = (pt1.i+pt2.i)/2; 00610 int midy = (pt1.j+pt2.j)/2; 00611 float slope = 0; 00612 if(dx*dy != 0) 00613 slope = dy/dx; 00614 PixRGB<byte > line_color; 00615 if(slope == 0.0) 00616 line_color = PixRGB<byte>(200,0,0);//Dark Red 00617 else if(slope < 0.0 && slope > -10.0) 00618 { 00619 line_color = PixRGB<byte>(128,128,200);//Light blue 00620 LDEBUG("Left edge Road!!!! %f",slope); 00621 lx1 = pt2.i - (pt2.j*slope); 00622 ly1 = 0; 00623 lx2 = pt2.i -(pt2.j-240)*slope; 00624 ly2 = 240; 00625 } 00626 else if(slope <= -10.0 ) 00627 line_color = PixRGB<byte>(0,128,0);//Green 00628 else if(slope > 0.0 && slope < 10.0) 00629 { 00630 line_color = PixRGB<byte>(0,255,0);//light green 00631 rx1 = pt2.i - pt2.j*slope; 00632 ry1 = 0; 00633 rx2 = pt2.i -(pt2.j-240)*slope; 00634 ry2 = 240; 00635 } 00636 else { 00637 line_color = PixRGB<byte>(0,0,128);//blue 00638 } 00639 if(slope != 0.0) 00640 { 00641 drawLine(edgeImg,pt1,pt2,line_color,2); 00642 char buffer[128]; 00643 sprintf(buffer,"%1.2f",slope); 00644 writeText(edgeImg,Point2D<int>(midx,midy),buffer,line_color,PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00645 }//end slope != 0.0 00646 00647 //find center line, using Kalman filter 00648 //int midx1 = (lx1+rx1)/2; 00649 //int midx2 = (lx2+rx2)/2; 00650 //int mid_dx = midx1 -midx2; 00651 /* 00652 if(midx1 != 0){ 00653 float fkfx = itsKf.update(midx1*1.0); 00654 //LINFO("update kalman filter old_kfx[%d],measure[%d],new_kfx[%f]",itsKfx,midx1,fkfx); 00655 00656 itsKfx = (int)fkfx; 00657 } 00658 //LINFO("Slope %f",slope); 00659 drawLine(edgeImg,Point2D<int>(itsKfx,0),Point2D<int>(itsKfx,240),PixRGB<byte>(255,255,0),2);//Yellow line 00660 */ 00661 }//end for loop 00662 return edgeImg; 00663 } 00664 // ###################################################################### 00665 Image<PixRGB<byte> > RG_Lane::getSaliency(Image<PixRGB<byte> > img) 00666 { 00667 //uint w = 320, h = 240; 00668 uint w = img.getWidth(), h = img.getHeight(); 00669 Image<PixRGB<byte> > saliencyImage; 00670 saliencyImage.resize(w, h, ZEROS); 00671 //Do Saliency 00672 //descard the currently processed saliency map 00673 //build a new unbised saliency map, and find the highest local value within it 00674 while(!itsSmt->outputReady()){ //wait for any processing to finish 00675 usleep(100); 00676 } 00677 //itsSmt->setBiasSM(false);//let the system know we dont want a biased smap 00678 //itsSmt->setSaliencyMapLevel(0); //set the saliency map level to 0 00679 itsSmt->newInput(itsCurrImg,true);//set the image 00680 while(!itsSmt->outputReady()){ //wait for any processing to finish 00681 usleep(100); 00682 } 00683 Image<float> salMap = itsSmt->getOutput(); 00684 Image<PixRGB<byte> > smap = normalizeFloat(salMap,FLOAT_NORM_0_255); 00685 Image<float> rgMap = itsSmt->getRGOutput(); 00686 Image<PixRGB<byte> > rg_map = normalizeFloat(rgMap,FLOAT_NORM_0_255); 00687 Image<float> byMap = itsSmt->getBYOutput(); 00688 Image<PixRGB<byte> > by_map = normalizeFloat(byMap,FLOAT_NORM_0_255); 00689 Image<float> colorMap = rgMap+byMap; 00690 Image<PixRGB<byte> > color_map = normalizeFloat(colorMap,FLOAT_NORM_0_255); 00691 Image<float> intensityMap = itsSmt->getIntensityOutput(); 00692 Image<PixRGB<byte> > intensity_map = normalizeFloat(intensityMap,FLOAT_NORM_0_255); 00693 00694 //save channels for superpixel 00695 itsMapChannels.push_back(salMap); 00696 itsMapChannels.push_back(rgMap); 00697 itsMapChannels.push_back(byMap); 00698 itsMapChannels.push_back(intensityMap); 00699 itsSalMap = salMap; 00700 itsRgMap = rgMap; 00701 itsByMap = byMap; 00702 itsIntMap = intensityMap; 00703 00704 00705 //draw circle on saliency poin 00706 float minval; 00707 Point2D<int> minPoint; 00708 findMax(salMap,minPoint,minval); 00709 drawCircle(smap,minPoint,10,PixRGB<byte>(20,50,255)); 00710 findMax(rgMap,minPoint,minval); 00711 drawCircle(rg_map,minPoint,10,PixRGB<byte>(20,50,255)); 00712 findMax(byMap,minPoint,minval); 00713 drawCircle(by_map,minPoint,10,PixRGB<byte>(20,50,255)); 00714 findMax(colorMap,minPoint,minval); 00715 //drawCircle(color_map,minPoint,10,PixRGB<byte>(20,50,255)); 00716 findMax(intensityMap,minPoint,minval); 00717 drawCircle(intensity_map,minPoint,10,PixRGB<byte>(20,50,255)); 00718 00719 00720 //write text on each channel 00721 char buffer[200]; 00722 00723 /* 00724 sprintf(buffer,"RG + BY"); 00725 writeText(color_map,Point2D<int>(0,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00726 inplacePaste(saliencyImage, rescale(color_map,itsCurrImg.getDims()), Point2D<int>(w, 0)); 00727 */ 00728 00729 //sprintf(buffer,"Color"); 00730 //writeText(saliencyImage,Point2D<int>(w,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00731 00732 /* 00733 inplacePaste(saliencyImage, rescale(rg_map,itsCurrImg.getDims()/2), Point2D<int>(w*1.5, 0)); 00734 sprintf(buffer,"Red-Green"); 00735 writeText(saliencyImage,Point2D<int>(w*1.5,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00736 00737 inplacePaste(saliencyImage, rescale(by_map,itsCurrImg.getDims()/2), Point2D<int>(w*1.5, h*0.5)); 00738 sprintf(buffer,"Blue-Yellow"); 00739 writeText(saliencyImage,Point2D<int>(w*1.5,h*0.5),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00740 00741 inplacePaste(saliencyImage, rescale(intensity_map,itsCurrImg.getDims()/2), Point2D<int>(w, h*0.5)); 00742 sprintf(buffer,"Intensity"); 00743 writeText(saliencyImage,Point2D<int>(w,h*0.5),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00744 LINFO("hi"); 00745 */ 00746 //inplacePaste(saliencyImage, rescale(smap,itsCurrImg.getDims()), Point2D<int>(0, 0)); 00747 saliencyImage = rescale(smap,itsCurrImg.getDims()); 00748 sprintf(buffer,"Saliency"); 00749 writeText(saliencyImage,Point2D<int>(0,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00750 return saliencyImage; 00751 } 00752 00753 // ###################################################################### 00754 void RG_Lane::drawState() 00755 { 00756 int w = 320, h = 240; 00757 if(itsCurrImg.initialized()) 00758 { 00759 w = itsCurrImg.getWidth(); 00760 h = itsCurrImg.getHeight(); 00761 itsDispImg.resize(w*5, 2*h, ZEROS); 00762 00763 char buffer[256]; 00764 00765 00766 // Do canny edge 00767 Image<PixRGB<byte> > rawCannyImg; 00768 Image<PixRGB<byte> > cannyEdgeMap = getCannyEdge(itsCurrImg,rawCannyImg); 00769 00770 sprintf(buffer,"Canny Edge"); 00771 writeText(cannyEdgeMap,Point2D<int>(0,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00772 inplacePaste(itsDispImg,cannyEdgeMap, Point2D<int>(2*w, 0)); 00773 00774 // Segment the regions in the image 00775 // using Superpixel algorithm (Felzenszwalb & Huttenlocher 2003) 00776 LINFO("current image size w %d h %d", 00777 itsCurrImg.getWidth(),itsCurrImg.getHeight()); 00778 00779 //get Saliency map, it will also compute each cmap which required by superpixel 00780 inplacePaste(itsDispImg,getSaliency(itsCurrImg), Point2D<int>(w, 0)); 00781 00782 00783 00784 /* 00785 //RGB superpixel 00786 float sigma = .5; uint k = 500; uint minSize = 20; 00787 int num_ccs; 00788 std::vector<std::vector<Point2D<int> > > groups; 00789 SuperPixelSegment(rescale(itsCurrImg,itsCurrImg.getDims()),sigma, k, minSize, num_ccs, &groups); 00790 Image<PixRGB<byte> > superPixelMap= rescale(SuperPixelDebugImage(groups,itsCurrImg),itsCurrImg.getDims()); 00791 sprintf(buffer,"RGB"); 00792 writeText(superPixelMap,Point2D<int>(0,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00793 inplacePaste(itsDispImg,superPixelMap, Point2D<int>(3*w, 0)); 00794 */ 00795 //Saliency map for superPixel 00796 /* 00797 std::vector<Image<float> > salchannels; 00798 LINFO("itsSalMap size1 w %d h %d",itsSalMap.getWidth(),itsSalMap.getHeight()); 00799 00800 salchannels.push_back(rescale(itsSalMap,itsCurrImg.getDims()));//saliency map is only 1/4 of image! 00801 std::vector<std::vector<Point2D<int> > > salgroups; 00802 int num_ccs2; 00803 SuperPixelSegment(itsCurrImg,sigma, k, minSize, num_ccs2, &salgroups,salchannels); 00804 Image<PixRGB<byte> > salsp_img = SuperPixelDebugImage(salgroups,itsCurrImg); 00805 LINFO("sal superpixel size1 w %d h %d",salsp_img.getWidth(),salsp_img.getHeight()); 00806 sprintf(buffer,"Saliency"); 00807 writeText(salsp_img,Point2D<int>(0,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00808 inplacePaste(itsDispImg,salsp_img, Point2D<int>(w, 0)); 00809 00810 00811 std::vector<Image<float> > intchannels; 00812 intchannels.push_back(rescale(itsIntMap,itsCurrImg.getDims()));//saliency map is only 1/4 of image! 00813 std::vector<std::vector<Point2D<int> > > intgroups; 00814 int num_ccs3; 00815 SuperPixelSegment(itsCurrImg,sigma, k, minSize, num_ccs3, &intgroups,intchannels); 00816 Image<PixRGB<byte> > intsp_img = SuperPixelDebugImage(salgroups,itsCurrImg); 00817 LINFO("int superpixel size1 w %d h %d",intsp_img.getWidth(),intsp_img.getHeight()); 00818 sprintf(buffer,"Intensity"); 00819 writeText(intsp_img,Point2D<int>(0,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00820 inplacePaste(itsDispImg,intsp_img, Point2D<int>(w*4, 0)); 00821 */ 00822 00823 00824 //Compute Superpixel and find road region. Resize to original for display only 00825 Image<PixRGB<byte> > superPixelMap = rescale(getSuperPixel(rescale(itsCurrImg,itsCurrImg.getDims()/4)),itsCurrImg.getWidth(),itsCurrImg.getHeight()); 00826 00827 LINFO("superpixel size1 w %d h %d",superPixelMap.getWidth(),superPixelMap.getHeight()); 00828 00829 00830 //Estimate Middle of Road 00831 if(superPixelMap.initialized()) 00832 { 00833 itsRawSuperPixelImg = rescale(itsRawSuperPixelImg,itsCurrImg.getDims()); 00834 sprintf(buffer,"Raw SuperPixel"); 00835 writeText(itsRawSuperPixelImg,Point2D<int>(0,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00836 inplacePaste(itsDispImg, itsRawSuperPixelImg , Point2D<int>(w, h)); 00837 00838 //Combine Superpixel & Canny edge 00839 Image<PixRGB<byte> > superCannyMap; 00840 std::vector<Point2D<int> > points; 00841 superCannyMap.resize(w, h, ZEROS); 00842 00843 LINFO("current image size2 w %d h %d",itsCurrImg.getWidth(),itsCurrImg.getHeight()); 00844 LINFO("superpixel size w %d h %d",superPixelMap.getWidth(),superPixelMap.getHeight()); 00845 00846 sprintf(buffer,"Ground truth"); 00847 itsGroundTruthImg = superPixelMap; 00848 writeText(itsGroundTruthImg,Point2D<int>(0,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00849 00850 inplacePaste(itsDispImg, itsGroundTruthImg, Point2D<int>(2*w, h)); 00851 00852 00853 for(int y = 0 ; y < superPixelMap.getHeight() ; y ++) 00854 { 00855 int middle = 0, pixCount = 0; 00856 for(int x = 0 ; x < superPixelMap.getWidth() ; x ++) 00857 { 00858 //PixRGB<byte> c = rawCannyImg.getVal(x,y); 00859 //LINFO("get val"); 00860 PixRGB<byte> s = superPixelMap.getVal(x,y); 00861 //LINFO("got val"); 00862 //if(c.red()==0 && c.green()==0 && c.blue()==0){ 00863 //Find ave of middle pixel 00864 if(s.red()==255 && s.green()==0 && s.blue()==0) 00865 { 00866 middle+=x; 00867 pixCount++; 00868 } 00869 superCannyMap.setVal(x,y,s);//copy pixel from superPixelMap 00870 } 00871 if(pixCount!=0) 00872 { 00873 int midx = (int)middle/pixCount; 00874 superCannyMap.setVal(midx,y,PixRGB<byte>(255,255,0));//draw yellow point in the middle line 00875 //Only use bottom 20 pixel for middle line,which is just right front the robot 00876 00877 if(y > h-21 && y < h-5) 00878 points.push_back(Point2D<int>(midx,y)); 00879 00880 if(y > h-5){ 00881 itsMiddlePoint[h-y] = midx; 00882 } 00883 } 00884 } 00885 00886 LINFO("Do Middle Line finder"); 00887 if(points.size() > 1) 00888 { 00889 Point2D<int> p1,p2; 00890 fitLine(points,p1,p2); 00891 drawLine(superCannyMap,Point2D<int>(w/2,0),Point2D<int>(w/2,h),PixRGB<byte>(0,255,0),1);//Green line 00892 drawLine(superCannyMap,p1,p2,PixRGB<byte>(255,255,0),3);//Yellow line 00893 00894 itsEstMiddlePoint = Point2D<int>((p1.i+p2.i)/2,h-8); 00895 double error = (w - (p1.i+p2.i))/2; 00896 drawLine(superCannyMap,Point2D<int>(w/2,h/2),Point2D<int>(w/2+error,h/2),PixRGB<byte>(0,255,0),2);//screen center -Green line 00897 char buffer[20]; 00898 sprintf(buffer,"%1.2f",error); 00899 writeText(superCannyMap,Point2D<int>(w/2,h/2),buffer,PixRGB<byte>(0,255,0),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00900 00901 sprintf(buffer,"DF %1.2f (%d,%d,%d)",itsRoadColorDiff,itsRoadColorDiffSub.red(),itsRoadColorDiffSub.green(),itsRoadColorDiffSub.blue()); 00902 writeText(superCannyMap,Point2D<int>(0,h-15),buffer,PixRGB<byte>(255,255,0),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00903 00904 sprintf(buffer,"Road Map"); 00905 writeText(superCannyMap,Point2D<int>(0,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00906 00907 inplacePaste(itsDispImg,superCannyMap, Point2D<int>(0, h)); 00908 00909 00910 //error < 0 turn right 00911 //error > 0 turn left 00912 updateMotor(0.5,1*(error/100)); 00913 }else 00914 { 00915 updateMotor(0.0,0.0); 00916 } 00917 }//do supercanny 00918 00919 //draw a play bar 00920 Image<PixRGB<byte> > meterImg; 00921 meterImg.resize(w, 23, ZEROS); 00922 drawFilledRect(meterImg, Rectangle(Point2D<int>(0,0), Dims(w, 23)), PixRGB<byte>(128,128,128)); 00923 drawFilledRect(meterImg, Rectangle(Point2D<int>(0,0), Dims(w*itsImageDB.getPercentage(), 23)), PixRGB<byte>(0,255,128)); 00924 inplacePaste(itsCurrImg, meterImg, Point2D<int>(0, 0)); 00925 00926 int ptg = itsImageDB.getPercentage()*100; 00927 sprintf(buffer,"ID:%6d Fps:%3d Time:%3.2fs %d%%",itsImageDB.getCurrentImageID(),itsImageDB.getFps(),itsImageDB.getCurrentTime(),ptg); 00928 writeText(itsCurrImg,Point2D<int>(0,0),buffer,PixRGB<byte>(255,255,255),PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00929 // 00930 inplacePaste(itsDispImg, itsCurrImg, Point2D<int>(0, 0)); 00931 }//initialized image 00932 } 00933 00934 void RG_Lane:: fitLine(std::vector<Point2D<int> > points, Point2D<int>&p1,Point2D<int>&p2){ 00935 float *line = new float[4]; 00936 float linearity = 0.0f; 00937 CvMemStorage* storage = cvCreateMemStorage(0); 00938 // CvSeq* point_seq = cvCreateSeq( CV_32FC2, sizeof(CvSeq), sizeof(CvPoint2D32f), storage ); 00939 CvPoint* cvPoints = (CvPoint*)malloc(points.size()*sizeof(Point2D<int>)); 00940 for(uint i = 0; i < points.size(); i++){ 00941 int x = points.at(i).i; 00942 int y = points.at(i).j; 00943 //cvSeqPush(point_seq,cvPoint2D32f(x,y)); 00944 cvPoints[i].x = x; 00945 cvPoints[i].y = y; 00946 } 00947 // linearity = myLinearity(point_seq); 00948 CvMat point_mat = cvMat(1,points.size(), CV_32SC2, cvPoints); 00949 cvFitLine(&point_mat, CV_DIST_L2,0, 0.01,0.01,line); 00950 LINFO("v=(%f,%f),vy/vx=%f,(x,y)=(%f,%f), Linearity=%f\n",line[0],line[1],line[1]/line[0],line[2],line[3],linearity); 00951 cvReleaseMemStorage(&storage); 00952 00953 double a, b, c, d, e, f,x0,y0,x1,y1; // y = a + b*x, b is slop 00954 b = line[1]/ line[0]; // y = c + d*x 00955 a = line[3]- b*line[2]; // y = e + f*x 00956 d = -1/b; 00957 c = points[0].j - d*points[0].i; 00958 f = d; 00959 e = points[points.size()-1].j - f*points[points.size()-1].i; 00960 00961 x0 = (a-c)/(d-b); // x = (a-c)/(d-b) 00962 y0 = c+d*x0; // y = a + b*x 00963 x1 = (a-e)/(f-b); 00964 y1 = e+f*x1; 00965 00966 p1.i = (int)x0; 00967 p1.j = (int)y0; 00968 p2.i = (int)x1; 00969 p2.j = (int)y1; 00970 00971 } 00972 00973 // ###################################################################### 00974 void RG_Lane:: updateMessage 00975 (const RobotSimEvents::EventMessagePtr& eMsg, const Ice::Current&) 00976 { 00977 // camera message 00978 if(eMsg->ice_isA("::BeobotEvents::CameraMessage")) 00979 { 00980 // store the image 00981 BeobotEvents::CameraMessagePtr cameraMsg = 00982 BeobotEvents::CameraMessagePtr::dynamicCast(eMsg); 00983 00984 int currRequestID = cameraMsg->RequestID; 00985 Image<PixRGB<byte> > img = Ice2Image<PixRGB<byte> >(cameraMsg->image); 00986 00987 LDEBUG("Got a CameraMessage with Request ID = %d", currRequestID); 00988 00989 its_Curr_Img_mutex.lock(); 00990 itsCurrImg = img; 00991 itsCurrImgID = cameraMsg->RequestID; 00992 its_Curr_Img_mutex.unlock(); 00993 } 00994 00995 // motor message 00996 else if(eMsg->ice_isA("::BeobotEvents::MotorMessage")) 00997 { 00998 BeobotEvents::MotorMessagePtr mtrMsg = 00999 BeobotEvents::MotorMessagePtr::dynamicCast(eMsg); 01000 LDEBUG("Got a MotorMessage with Request ID = %d: RC Trans %f, Rot %f", 01001 mtrMsg->RequestID, itsRcTransSpeed, itsRcRotSpeed); 01002 its_Curr_Mtr_mutex.lock(); 01003 itsRemoteMode = mtrMsg->rcMode; 01004 itsRcTransSpeed = mtrMsg->rcTransVel; 01005 itsRcRotSpeed = mtrMsg->rcRotVel; 01006 its_Curr_Mtr_mutex.unlock(); 01007 } 01008 // LINFO("updateMessage"); 01009 01010 01011 } 01012 // ###################################################################### 01013 void RG_Lane::updateMotor(double tran, double rot) 01014 { 01015 BeobotEvents::MotorRequestPtr msg = new BeobotEvents::MotorRequest; 01016 msg->transVel = tran; 01017 msg->rotVel = rot; 01018 this->publish("MotorRequestTopic", msg); 01019 LINFO("[%d] Publish motor request Trans %f Rotation %f", 01020 itsPrevProcImgID,tran,rot); 01021 } 01022 01023 01024 // ###################################################################### 01025 /* So things look consistent in everyone's emacs... */ 01026 /* Local Variables: */ 01027 /* indent-tabs-mode: nil */ 01028 /* End: */