00001 #include <Ice/Ice.h> 00002 #include "Raster/Raster.H" 00003 #include "Component/ModelManager.H" 00004 #include "Media/FrameSeries.H" 00005 #include "Raster/GenericFrame.H" 00006 #include "Transport/FrameInfo.H" 00007 #include "Image/Image.H" 00008 #include "Image/DrawOps.H" 00009 #include "GUI/PrefsWindow.H" 00010 #include "Devices/DeviceOpts.H" 00011 #include "Devices/Serial.H" 00012 #include "Image/DrawOps.H" 00013 #include <vector> 00014 #include "GUI/XWinManaged.H" 00015 #include "GUI/ImageDisplayStream.H" 00016 #include "GUI/PrefsWindow.H" 00017 #include "GUI/DebugWin.H" 00018 #include <pthread.h> 00019 #include <iomanip> 00020 00021 int numPossibleObjects = 30; 00022 int numSlots = 25; 00023 std::vector<std::set<int> > slotObjs; 00024 00025 nub::soft_ref<OutputFrameSeries> ofs; 00026 nub::soft_ref<InputFrameSeries> ifs; 00027 00028 class ScorbotReallySimple: public ModelComponent 00029 { 00030 public: 00031 ScorbotReallySimple(OptionManager& mgr, 00032 const std::string& descrName = "", 00033 const std::string& tagName = "") : 00034 ModelComponent(mgr, descrName, tagName), 00035 itsSerial(new Serial(mgr)) 00036 { 00037 addSubComponent(itsSerial); 00038 itsSerial->configure("/dev/ttyUSB0", 115200, "8N1", false, false, 10000); 00039 //itsSerial->setBlocking(true); 00040 } 00041 00042 bool getState() 00043 { 00044 00045 int ret; 00046 //char tmpbuf[1024]; 00047 //int ret = itsSerial->read(tmpbuf, 1024); 00048 //LINFO("Got %i", ret); 00049 00050 char retVal = '?'; 00051 for(int i=0; i<10; i++) 00052 { 00053 char cmd = 'S'; 00054 itsSerial->write(&cmd, 1); 00055 usleep(10000); 00056 00057 ret = itsSerial->read(&retVal, 1); 00058 LINFO("%i: RetVal %c", ret, retVal); 00059 if (ret > 0) break; 00060 00061 itsSerial->enablePort("/dev/ttyUSB0"); 00062 00063 } 00064 00065 return (retVal == '1'); 00066 00067 } 00068 00069 void setPos(int pos) 00070 { 00071 LINFO("Moving to %i", pos); 00072 char cmd[2]; 00073 cmd[0] = 'M'; 00074 cmd[1] = pos; 00075 itsSerial->write(&cmd, 2); 00076 00077 sleep(5); 00078 00079 //LINFO("Wait for 0"); 00080 //while(getState()) usleep(100000); 00081 LINFO("Wait for 1"); 00082 while(!getState()) usleep(10000); 00083 LINFO("Move Done"); 00084 } 00085 00086 private: 00087 nub::ref<Serial> itsSerial; 00088 }; 00089 00090 // ###################################################################### 00091 int getKey() 00092 { 00093 const nub::soft_ref<ImageDisplayStream> ids = 00094 ofs->findFrameDestType<ImageDisplayStream>(); 00095 00096 const rutz::shared_ptr<XWinManaged> uiwin = 00097 ids.is_valid() 00098 ? ids->getWindow("Output") 00099 : rutz::shared_ptr<XWinManaged>(); 00100 return uiwin->getLastKeyPress(); 00101 } 00102 00103 // ###################################################################### 00104 std::map<int, Image<PixRGB<byte> > > loadObjectImgs() 00105 { 00106 std::map<int, Image<PixRGB<byte> > > imgs; 00107 for(int i=1; i<=numPossibleObjects; i++) 00108 { 00109 char filename[256]; 00110 sprintf(filename, "/home/igpu/Desktop/MicroMachines/cropped/%d.png", i); 00111 imgs[i] = Raster::ReadRGB(filename); 00112 } 00113 return imgs; 00114 } 00115 00116 // ###################################################################### 00117 void initPossibleObjs() 00118 { 00119 slotObjs.clear(); 00120 00121 for(int slotIdx=0; slotIdx<numSlots; slotIdx++) 00122 { 00123 slotObjs.push_back(std::set<int>()); 00124 for(int objIdx=1; objIdx<=numPossibleObjects; objIdx++) 00125 { 00126 slotObjs[slotIdx].insert(objIdx); 00127 } 00128 } 00129 } 00130 00131 // ###################################################################### 00132 std::vector<int> randomizeSlots(int slotOffset, int slotsInc) 00133 { 00134 std::vector<int> slotAssignments(numSlots, -1); 00135 00136 //Make a copy of slotObjs 00137 std::vector<std::set<int> > tmpSlotObjs = slotObjs; 00138 00139 //For each slot, pick a random index from it's list of available objects 00140 for(int slotIdx = slotOffset; slotIdx<numSlots; slotIdx+=slotsInc) 00141 { 00142 //Make sure there are objects left to go in this slot 00143 if(tmpSlotObjs[slotIdx].size() == 0) 00144 { 00145 std::cout << "NO MORE OBJECTS AVAILABLE FOR SLOT " << slotIdx << " -- EXITING" << std::endl; 00146 exit(0); 00147 } 00148 00149 //Randomly pick an object from those available for the slot 00150 int objIdx = rand() % (int)tmpSlotObjs[slotIdx].size(); 00151 00152 //Linearly roll through the avaible objects to get to the id at our random index 00153 std::set<int>::iterator objIdIt = tmpSlotObjs[slotIdx].begin(); 00154 for(int objItIdx=0; objItIdx!=objIdx; objItIdx++) objIdIt++; 00155 00156 //Assign the object to the slot 00157 int objId = *objIdIt; 00158 slotAssignments[slotIdx] = objId; 00159 00160 //Never let this object be assigned to this slot again 00161 slotObjs[slotIdx].erase(slotObjs[slotIdx].find(objId)); 00162 00163 //Make this object unavailable for other slots in this run 00164 for(int i=0; i<numSlots; i++) 00165 { 00166 std::set<int>::iterator objIt = tmpSlotObjs[i].find(objId); 00167 if(objIt != tmpSlotObjs[i].end()) tmpSlotObjs[i].erase(objId); 00168 } 00169 } 00170 00171 return slotAssignments; 00172 } 00173 00174 00175 // ###################################################################### 00176 int main(int argc, char* argv[]) 00177 { 00178 LINFO("#############################################STARTING##############################################"); 00179 //srand(unsigned(time(NULL))); 00180 00181 std::vector<Point2D<int> > slotCoords(numSlots); 00182 slotCoords[0] = Point2D<int>(782,634); 00183 slotCoords[1] = Point2D<int>(812,538); 00184 slotCoords[2] = Point2D<int>(844,433); 00185 slotCoords[3] = Point2D<int>(866,344); 00186 slotCoords[4] = Point2D<int>(890,244); 00187 slotCoords[5] = Point2D<int>(915,164); 00188 slotCoords[6] = Point2D<int>(945,80); 00189 slotCoords[7] = Point2D<int>(540,614); 00190 slotCoords[8] = Point2D<int>(530,503); 00191 slotCoords[9] = Point2D<int>(515,366); 00192 slotCoords[10] = Point2D<int>(538,258); 00193 slotCoords[11] = Point2D<int>(593,162); 00194 slotCoords[12] = Point2D<int>(643,90); 00195 slotCoords[13] = Point2D<int>(93,451); 00196 slotCoords[14] = Point2D<int>(185,411); 00197 slotCoords[15] = Point2D<int>(273,366); 00198 slotCoords[16] = Point2D<int>(387,301); 00199 slotCoords[17] = Point2D<int>(472,209); 00200 slotCoords[18] = Point2D<int>(492,128); 00201 slotCoords[19] = Point2D<int>(202,144); 00202 slotCoords[20] = Point2D<int>(736,210); 00203 slotCoords[21] = Point2D<int>(1161,466); 00204 slotCoords[22] = Point2D<int>(1028,429); 00205 slotCoords[23] = Point2D<int>(1187,297); 00206 slotCoords[24] = Point2D<int>(347,47); 00207 00208 ModelManager mgr("Test Scorbot Interface"); 00209 00210 nub::ref<ScorbotReallySimple> scorbot(new ScorbotReallySimple(mgr)); 00211 mgr.addSubComponent(scorbot); 00212 00213 ifs.reset(new InputFrameSeries(mgr)); 00214 mgr.addSubComponent(ifs); 00215 00216 ofs.reset(new OutputFrameSeries(mgr)); 00217 mgr.addSubComponent(ofs); 00218 00219 if(mgr.parseCommandLine(argc, argv, "filename", 1, 1) == false) return -1; 00220 mgr.start(); 00221 00222 std::string fileName = mgr.getExtraArg(0); 00223 00224 00225 //while(true) 00226 //{ 00227 // for(int pos=1; pos<25; pos++) 00228 // scorbot->setPos(pos); 00229 //} 00230 00231 // while(true) 00232 // scorbot->getState(); 00233 00234 PrefsWindow pWin("Camera Control", SimpleFont::FIXED(8)); 00235 pWin.setValueNumChars(16); 00236 pWin.addPrefsForComponent(ifs.get(), true); 00237 00238 //Load in the object images 00239 std::map<int, Image<PixRGB<byte> > > objectImgs = loadObjectImgs(); 00240 00241 //Initialize the data structure for our randomization algorithm 00242 initPossibleObjs(); 00243 00244 ifs->startStream(); 00245 00246 // ###################################################################### 00247 // LOOP 00248 // ###################################################################### 00249 int sceneId = 0; 00250 00251 int slotIncrement = 3; // How many slots to skip when placing toys 00252 int slotOffset = 0; // On which slot should we start 00253 00254 while(1) 00255 { 00256 00257 //Set the first focus 00258 char focusString[128]; 00259 sprintf(focusString, "%d", 7); 00260 mgr.setOptionValString(&OPT_FrameGrabberFocus, focusString); 00261 00262 //Randomize which toy goes into which slot 00263 std::vector<int> objAssignments(numSlots, -1); 00264 if (sceneId > 0) 00265 objAssignments = randomizeSlots(slotOffset, slotIncrement); 00266 00267 slotOffset = (slotOffset+1)%slotIncrement; 00268 00269 for(int ori=0; ori<2; ori++) 00270 { 00271 //Go to position the top position 00272 scorbot->setPos(63); 00273 00274 int key = -1; 00275 do 00276 { 00277 pWin.update(); 00278 00279 if(ifs->updateNext() == FRAME_COMPLETE) break; 00280 GenericFrame input = ifs->readFrame(); 00281 00282 //Display the new frame 00283 Image<PixRGB<byte> > img = input.asRgb(); 00284 00285 for(size_t slotIdx=0; slotIdx<slotCoords.size(); slotIdx++) 00286 { 00287 if(objAssignments[slotIdx] != -1) 00288 { 00289 Point2D<int> center = slotCoords[slotIdx] + Point2D<int>(0, -15); 00290 drawRect(img, Rectangle::centerDims(center, Dims(40,40)), PixRGB<byte>(255, 0, 0)); 00291 drawCircle(img, center, 3, PixRGB<byte>(255, 0, 0), 3); 00292 00293 int objId = objAssignments[slotIdx]; 00294 00295 Rectangle objImgRect = img.getBounds().getOverlap(objectImgs[objId].getBounds()/2 + center + Point2D<int>(-20, objectImgs[objId].getHeight()/4)); 00296 00297 inplaceEmbed(img, objectImgs[objId], objImgRect, PixRGB<byte>(0,0,0)); 00298 00299 char buffer[128]; 00300 sprintf(buffer, "%d", (int)objId); 00301 00302 writeText(img, center+Point2D<int>(0, 20), buffer, PixRGB<byte>(0, 0, 0)); 00303 } 00304 } 00305 00306 char msg[255]; 00307 sprintf(msg, "Please place items in ori %i the slots indicated above and then press ENTER", ori); 00308 00309 writeText(img, Point2D<int>(0, img.getHeight() - 20), msg , PixRGB<byte>(255,0,0)); 00310 00311 ofs->writeRGB(img, "Output", FrameInfo("output", SRC_POS)); 00312 ofs->updateNext(); 00313 00314 key = getKey(); 00315 if(key != -1) LINFO("Pressed: %d", key); 00316 00317 }while(key != 36 && key != 44); 00318 00319 00320 // Enumerate the focus values for each position 00321 std::vector<int> focusVals(numSlots); 00322 focusVals[0] = 9; 00323 focusVals[1] = 9; 00324 focusVals[2] = 9; 00325 focusVals[3] = 10; 00326 focusVals[4] = 10; 00327 focusVals[5] = 10; 00328 focusVals[6] = 9; 00329 focusVals[7] = 9; 00330 focusVals[8] = 9; 00331 focusVals[9] = 9; 00332 focusVals[10] = 9; 00333 focusVals[11] = 9; 00334 focusVals[12] = 9; 00335 focusVals[13] = 9; 00336 focusVals[14] = 9; 00337 focusVals[15] = 10; 00338 focusVals[16] = 12; 00339 focusVals[17] = 10; 00340 focusVals[18] = 10; 00341 focusVals[19] = 9; 00342 focusVals[20] = 11; 00343 focusVals[21] = 10; 00344 focusVals[22] = 10; 00345 focusVals[23] = 11; 00346 focusVals[24] = 11; 00347 00348 // Enumerate the target type in each slot as a string 00349 std::vector<std::string> targetType(numSlots,"none"); 00350 for(int slotIdx=0; slotIdx<numSlots; slotIdx++) 00351 { 00352 std::string objType; 00353 00354 int objId = objAssignments[slotIdx]; 00355 if(objId == -1) 00356 objType = "none"; 00357 else if(objId > 0 && objId <= 10) 00358 objType = "boat"; 00359 else if(objId > 10 && objId <= 20) 00360 objType = "car"; 00361 else if(objId > 20 && objId <= 30) 00362 objType = "tank"; 00363 00364 targetType[slotIdx] = objType; 00365 } 00366 00367 std::cout << "----------------------------------------" << std::endl; 00368 std::cout << "----------------------------------------" << std::endl; 00369 00370 for(size_t i=0; i<objAssignments.size(); i++) 00371 std::cout << std::setw(5) << objAssignments[i] << " "; 00372 std::cout << std::endl; 00373 00374 for(size_t i=0; i<targetType.size(); i++) 00375 std::cout << std::setw(5) << targetType[i] << " "; 00376 std::cout << std::endl; 00377 00378 00379 for(int positionIndex=0; positionIndex<numSlots; positionIndex++) 00380 { 00381 if(sceneId > 0 && objAssignments[positionIndex] == -1) continue; 00382 00383 LINFO("Moving To %d", positionIndex); 00384 00385 //Tell the box to go to the next position 00386 scorbot->setPos(positionIndex+1); 00387 00388 //We've reached the endpoint 00389 LINFO("Grabbing Images..."); 00390 00391 for(int focus=focusVals[positionIndex]-4; focus < focusVals[positionIndex]+4; focus+=4) 00392 { 00393 int foc = focus%40; 00394 if(foc <0) foc = 40+foc; 00395 //Set the focus 00396 char focusString[128]; 00397 sprintf(focusString, "%d", foc); 00398 mgr.setOptionValString(&OPT_FrameGrabberFocus, focusString); 00399 00400 GenericFrame input; 00401 for(int i=0; i<30; i++) 00402 { 00403 if(ifs->updateNext() == FRAME_COMPLETE) break; 00404 input = ifs->readFrame(); 00405 } 00406 00407 //Display the new frame 00408 Image<PixRGB<byte> > img = input.asRgb(); 00409 ofs->writeRGB(img, "Output", FrameInfo("output", SRC_POS)); 00410 ofs->updateNext(); 00411 00412 LINFO("Final State: %d", scorbot->getState()); 00413 00414 bool inFocus = (foc == focusVals[positionIndex]); 00415 //Write the frame 00416 char fileNameBuffer[256]; 00417 sprintf(fileNameBuffer, "%s/%d_%d_%d_%d_%s_%d_%d_%lu.pnm", fileName.c_str(), 00418 sceneId, 00419 positionIndex, // Position Index 00420 ori, 00421 objAssignments[positionIndex], 00422 targetType[positionIndex].c_str(), // Target type 00423 foc, // Actual focus value 00424 inFocus, // Whether this value is in focus 00425 time(NULL)); 00426 00427 Raster::WriteRGB(img, fileNameBuffer); 00428 00429 } // for(focus) 00430 00431 } // for(positionIndex) 00432 00433 if (sceneId == 0) ori = 2; //No orientation for sceneId 0 00434 } 00435 00436 LINFO("Done!"); 00437 sceneId++; 00438 } // while(1) 00439 00440 } // main 00441