00001 #include <iomanip>
00002 #include <vector>
00003 #include <pthread.h>
00004 #include <signal.h>
00005 #include <fstream>
00006 #include <boost/lexical_cast.hpp>
00007 #include <boost/algorithm/string.hpp>
00008 #include <list>
00009
00010 #include "Devices/V4L2grabber.H"
00011 #include "Devices/XCgrabber.H"
00012 #include "Util/WorkThreadServer.H"
00013 #include "Raster/Raster.H"
00014 #include "Component/ModelManager.H"
00015 #include "Media/FrameSeries.H"
00016 #include "Raster/GenericFrame.H"
00017 #include "Transport/FrameInfo.H"
00018 #include "Image/Image.H"
00019 #include "Image/DrawOps.H"
00020 #include "GUI/PrefsWindow.H"
00021 #include "Devices/DeviceOpts.H"
00022 #include "Devices/Serial.H"
00023 #include "Image/DrawOps.H"
00024 #include "GUI/XWinManaged.H"
00025 #include "GUI/ImageDisplayStream.H"
00026 #include "GUI/PrefsWindow.H"
00027 #include "GUI/DebugWin.H"
00028 #include "GUI/PrefsWindow.H"
00029 #include "Util/StringUtil.H"
00030 #include "rutz/time.h"
00031 #include "Util/csignals.H"
00032
00033 class ScorbotSimple;
00034
00035 const char* dataDir = "/home2/robotscenes";
00036 std::string sceneDir = "";
00037 int pathID = 0;
00038 int sceneID = 0;
00039
00040 nub::soft_ref<OutputFrameSeries> ofs;
00041 nub::soft_ref<ScorbotSimple> scorbot;
00042 XWinManaged *userInteractiveWindow = NULL;
00043 volatile bool record = false;
00044 volatile bool keepgoing = true;
00045 volatile bool dolivedisplay = false;
00046
00047
00048 volatile int signum = 0;
00049
00050 Image< PixRGB<byte> > inputImage;
00051 volatile unsigned long currentVideoFrameNumber = 0;
00052 pthread_mutex_t imgMutex = PTHREAD_MUTEX_INITIALIZER;
00053
00054 rutz::time epoch = rutz::time::wall_clock_now();
00055
00056 const int focusval[4] = { 10, 6, 7, 8 };
00057
00058
00059 #define NUMCAMS 2
00060
00061
00062
00063 class WriteJob : public JobServer::Job
00064 {
00065 public:
00066 WriteJob(const Image< PixRGB<byte> > img_, const std::string fname_) :
00067 img(img_), fname(fname_) { }
00068
00069 virtual ~WriteJob() { }
00070
00071 virtual void run() { Raster::WriteRGB(img, fname); }
00072
00073 virtual const char* jobType() const { return "WriteJob"; }
00074
00075 private:
00076 const Image< PixRGB<byte> > img;
00077 const std::string fname;
00078 };
00079
00080 WorkThreadServer writer("Write Server", 5, false);
00081
00082 void AsyncWriteImage(const Image< PixRGB<byte> > img, size_t cameraID, unsigned long frameNumber)
00083 {
00084 const std::string fname = sformat("%s/RobotScene-s%04d-p%02d/RobotScene-s%04d-p%02d-c%02zu-f%06lu.ppm",
00085 dataDir, sceneID, pathID, sceneID, pathID, cameraID, frameNumber);
00086 writer.enqueueJob(rutz::make_shared(new WriteJob(img, fname)));
00087 }
00088
00089
00090
00091 std::vector< nub::ref<FrameIstream> > grabbers;
00092
00093
00094 class GrabJob : public JobServer::Job
00095 {
00096 public:
00097 GrabJob(const size_t cameraID_) :
00098 cameraID(cameraID_),
00099 frameNumber(0)
00100 {
00101 ASSERT(cameraID < grabbers.size());
00102 }
00103
00104 virtual ~GrabJob() {}
00105
00106 virtual void run()
00107 {
00108 nub::ref<FrameIstream> grabber = grabbers[cameraID];
00109 bool recording = false;
00110
00111 while(keepgoing) {
00112
00113 GenericFrame frame = grabber->readFrame();
00114 Image< PixRGB<byte> > img;
00115
00116 if (record) {
00117 if (recording == false) { LINFO("Start recording camera %"ZU" at %fms...", cameraID, (rutz::time::wall_clock_now() - epoch).msec()); recording = true; }
00118 img = frame.asRgb();
00119 AsyncWriteImage(img, cameraID, frameNumber);
00120 ++frameNumber;
00121 if ((frameNumber % 10) == 0) LINFO("Camera %"ZU" got frame %"ZU" at %fms", cameraID, frameNumber, (rutz::time::wall_clock_now() - epoch).msec());
00122 } else {
00123 if (recording == true) { LINFO("Stop recording camera %"ZU" frame %"ZU" at %fms...", cameraID, frameNumber, (rutz::time::wall_clock_now() - epoch).msec()); recording = false; }
00124 frameNumber = 0;
00125 }
00126
00127
00128 if (cameraID == 0 && record == false) {
00129 if (img.initialized() == false) img = frame.asRgb();
00130 pthread_mutex_lock(&imgMutex);
00131 inputImage = img;
00132 ++currentVideoFrameNumber;
00133 pthread_mutex_unlock(&imgMutex);
00134 }
00135 }
00136 }
00137
00138 virtual const char* jobType() const { return "GrabJob"; }
00139
00140 private:
00141 const size_t cameraID;
00142 unsigned long frameNumber;
00143 };
00144
00145 WorkThreadServer grabberThreadServer("Grab Server", NUMCAMS, false);
00146
00147 void setupGrabbers(ModelManager& manager)
00148 {
00149 size_t cameraID = 0;
00150 while(true)
00151 {
00152 std::string dev = sformat("/dev/video%"ZU, grabbers.size());
00153 LINFO("Trying to open %s", dev.c_str());
00154 int fd = open(dev.c_str(), O_RDONLY);
00155 if (fd == -1) { LINFO("%s not found -- Skipping.", dev.c_str()); break; } else close(fd);
00156
00157
00158 nub::ref<V4L2grabber> grabber(new V4L2grabber(manager, dev, dev));
00159
00160
00161 grabber->forgetExports();
00162
00163
00164 grabber->setModelParamVal("FrameGrabberDevice", dev);
00165
00166 grabber->setModelParamVal("FrameGrabberNbuf", 2);
00167 grabber->setModelParamVal("FrameGrabberStreaming", true);
00168 grabber->setModelParamVal("FrameGrabberByteSwap", false);
00169 grabber->setModelParamVal("FrameGrabberDims", Dims(1280,720));
00170 grabber->setModelParamVal("FrameGrabberMode", VIDFMT_YUYV);
00171 grabber->setModelParamVal("FrameGrabberChannel", 0);
00172
00173
00174
00175 grabber->setModelParamVal("FrameGrabberWhiteBalTempAuto", true);
00176 grabber->setModelParamVal("FrameGrabberPowerLineFreq", 2);
00177 grabber->setModelParamVal("FrameGrabberBacklightComp", 1);
00178 grabber->setModelParamVal("FrameGrabberFocusAuto", true);
00179
00180
00181 grabber->setModelParamVal("FrameGrabberWhiteBalTempAuto", false);
00182 grabber->setModelParamVal("FrameGrabberPowerLineFreq", 0);
00183 grabber->setModelParamVal("FrameGrabberBacklightComp", 0);
00184 grabber->setModelParamVal("FrameGrabberExposureAuto", 3);
00185 grabber->setModelParamVal("FrameGrabberFocusAuto", false);
00186 grabber->setModelParamVal("FrameGrabberExposureAuto", 1);
00187
00188
00189 grabber->setModelParamVal("FrameGrabberBrightness", 134);
00190 grabber->setModelParamVal("FrameGrabberContrast", 6);
00191 grabber->setModelParamVal("FrameGrabberSaturation", 84);
00192 grabber->setModelParamVal("FrameGrabberWhiteBalTemp", 3101);
00193 grabber->setModelParamVal("FrameGrabberExposureAbs", 39);
00194 grabber->setModelParamVal("FrameGrabberSharpness", 26);
00195 grabber->setModelParamVal("FrameGrabberFocus", focusval[cameraID] + 1);
00196 grabber->setModelParamVal("FrameGrabberZoom", 1);
00197
00198
00199 grabber->setModelParamVal("FrameGrabberPowerLineFreq", 0);
00200 grabber->setModelParamVal("FrameGrabberBacklightComp", 0);
00201 grabber->setModelParamVal("FrameGrabberExposureAuto", 1);
00202 grabber->setModelParamVal("FrameGrabberWhiteBalTempAuto", false);
00203
00204 grabber->setModelParamVal("FrameGrabberBrightness", 133);
00205 grabber->setModelParamVal("FrameGrabberContrast", 5);
00206 grabber->setModelParamVal("FrameGrabberSaturation", 83);
00207 grabber->setModelParamVal("FrameGrabberWhiteBalTemp", 3100);
00208 grabber->setModelParamVal("FrameGrabberSharpness", 25);
00209 grabber->setModelParamVal("FrameGrabberExposureAbs", 156);
00210 grabber->setModelParamVal("FrameGrabberFocusAuto", false);
00211 grabber->setModelParamVal("FrameGrabberFocus", focusval[cameraID]);
00212 grabber->setModelParamVal("FrameGrabberZoom", 0);
00213
00214
00215 manager.addSubComponent(grabber);
00216 grabbers.push_back(grabber);
00217 LINFO("Added V4L2grabber for %s", dev.c_str());
00218
00219 ++cameraID;
00220 }
00221
00222
00223
00224
00225 nub::ref<XCgrabber> grabber(new XCgrabber(manager, "Imagize", "Imagize"));
00226
00227
00228 grabber->forgetExports();
00229
00230
00231 grabber->setModelParamString("XCGrabberFormatFile", "/home/ilab24/xcap/data/imagize-works.xsetup");
00232 grabber->setModelParamVal("FrameGrabberMode", VIDFMT_RGB24);
00233 grabber->setModelParamVal("FrameGrabberNbuf", 2);
00234 grabber->setModelParamVal("FrameGrabberDims", Dims(1280,1024));
00235
00236
00237 manager.addSubComponent(grabber);
00238 grabbers.push_back(grabber);
00239 LINFO("Added XCgrabber for Imagize camera");
00240 }
00241
00242
00243 struct SceneSetup
00244 {
00245 struct Object
00246 {
00247 std::string trayFileName;
00248 std::string trayName;
00249 int trayColumn;
00250 int trayRow;
00251 float trayX;
00252 float trayY;
00253 std::vector< Point2D<int> > outline;
00254 };
00255
00256 std::string setupPath;
00257 int setupNum;
00258 int backgroundIdx;
00259 std::string backgroundFileName;
00260 std::vector<int> pathIndex;
00261
00262 std::vector<SceneSetup::Object> objects;
00263 };
00264
00265
00266
00267 SceneSetup loadSceneSetup(const int id)
00268 {
00269 SceneSetup setup;
00270 setup.setupPath = sceneDir;
00271
00272 std::string setupFileName = setup.setupPath + "/" + sformat("%04d.txt", id);
00273 std::ifstream setupFile(setupFileName.c_str());
00274
00275 if (!setupFile.is_open()) LFATAL("Could not open setup file: %s", setupFileName.c_str());
00276
00277 std::string line;
00278
00279 try
00280 {
00281
00282 getline(setupFile, line);
00283 setup.setupNum = boost::lexical_cast<int>(line.substr(line.find("=")+1));
00284
00285
00286 getline(setupFile, line);
00287 setup.backgroundIdx = boost::lexical_cast<int>(line.substr(line.find("=")+1));
00288
00289
00290 getline(setupFile, line);
00291 setup.backgroundFileName = line.substr(line.find("=")+1);
00292
00293
00294 getline(setupFile, line);
00295 std::vector<std::string> tok;
00296 split(line.substr(line.find("=")+1), ",", std::back_inserter(tok));
00297 for (size_t ii = 0; ii < tok.size(); ++ii)
00298 setup.pathIndex.push_back(boost::lexical_cast<int>(tok[ii]));
00299
00300
00301 getline(setupFile, line);
00302 int numObjects = boost::lexical_cast<int>(line.substr(line.find("=")+1));
00303
00304 for(int i=0; i<numObjects; ++i)
00305 {
00306 SceneSetup::Object obj;
00307
00308
00309 getline(setupFile, line);
00310 obj.trayFileName = line.substr(line.find("=")+1);
00311
00312
00313 size_t s = obj.trayFileName.find_last_of('/');
00314 size_t e = obj.trayFileName.find_last_of('.');
00315 obj.trayName = obj.trayFileName.substr(s+1, e-s-1);
00316
00317
00318 getline(setupFile, line);
00319 obj.trayColumn = boost::lexical_cast<int>(line.substr(line.find("=")+1));
00320
00321
00322 getline(setupFile, line);
00323 obj.trayRow = boost::lexical_cast<int>(line.substr(line.find("=")+1));
00324
00325
00326 getline(setupFile, line);
00327 obj.trayX = boost::lexical_cast<float>(line.substr(line.find("=")+1));
00328
00329
00330 getline(setupFile, line);
00331 obj.trayY = boost::lexical_cast<float>(line.substr(line.find("=")+1));
00332
00333 setup.objects.push_back(obj);
00334 }
00335 }
00336 catch(boost::bad_lexical_cast& e)
00337 {
00338 LFATAL("Error Parsing Setup File (%s) [%s] -- Offending Line: %s", setupFileName.c_str(), e.what(), line.c_str());
00339 }
00340
00341 return setup;
00342 }
00343
00344
00345
00346 void *displayThreadMethod(void*)
00347 {
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 return NULL;
00374 }
00375
00376
00377 class ScorbotSimple: public ModelComponent
00378 {
00379 public:
00380 ScorbotSimple(OptionManager& mgr,
00381 const std::string& descrName = "",
00382 const std::string& tagName = "") :
00383 ModelComponent(mgr, descrName, tagName),
00384 itsSerial(new Serial(mgr))
00385 {
00386 addSubComponent(itsSerial);
00387 itsSerial->configure("/dev/ttyUSB0", 115200, "8N1", false, false, 10000);
00388 }
00389
00390 bool getBusyState()
00391 {
00392 char cmd = 'B';
00393 itsSerial->write(&cmd, 1);
00394 usleep(5000);
00395
00396 char retVal = '?';
00397 itsSerial->read(&retVal, 1);
00398
00399 return (retVal == '1');
00400 }
00401
00402 bool getHomeState()
00403 {
00404 char cmd = 'H';
00405 itsSerial->write(&cmd, 1);
00406 usleep(5000);
00407
00408 char retVal = '?';
00409 itsSerial->read(&retVal, 1);
00410
00411 return (retVal == '1');
00412 }
00413
00414 void emptyBuffer()
00415 {
00416 while(true)
00417 {
00418 usleep(10000);
00419 char retVal = '?';
00420 itsSerial->read(&retVal, 1);
00421 if(retVal == '?') break;
00422 }
00423 }
00424
00425 void setPathNum(int pathnum)
00426 {
00427
00428 char cmd[2] = { 'P', pathnum };
00429 itsSerial->write(&cmd, 2);
00430 }
00431
00432 private:
00433 nub::ref<Serial> itsSerial;
00434 };
00435
00436
00437
00438 void executePath(int pathnum)
00439 {
00440 LINFO("Waiting for Robot HOME ...");
00441 while(!scorbot->getHomeState())
00442 {
00443 if(signum != 0) { record = false; return; }
00444 usleep(10000);
00445 }
00446 LINFO("Going To Path %d", pathnum);
00447 scorbot->setPathNum(pathnum++);
00448 LINFO("Waiting for Robot BUSY ...");
00449 while(!scorbot->getBusyState())
00450 {
00451 if(signum != 0) { record = false; return; }
00452 usleep(10000);
00453 }
00454 epoch = rutz::time::wall_clock_now();
00455 usleep(1000000);
00456 LINFO("Camera recording on.");
00457 record = true;
00458 LINFO("Waiting for Robot ~BUSY ...");
00459 while(scorbot->getBusyState())
00460 {
00461 if(signum != 0) { record = false; return; }
00462 usleep(10000);
00463 }
00464 record = false;
00465 LINFO("Camera recording off.");
00466
00467 scorbot->emptyBuffer();
00468 }
00469
00470
00471
00472
00473 std::vector< Point2D<int> > promptPlaceObjectOnScene(SceneSetup const & setup, int objIdx)
00474 {
00475 LINFO("Place object %d onto table. Follow instructions in User Interactive window...", objIdx);
00476
00477 const SceneSetup::Object &obj = setup.objects[objIdx];
00478
00479 Image< PixRGB<byte> > trayImg = Raster::ReadRGB(setup.setupPath + "/" + obj.trayFileName);
00480 trayImg = rescale(trayImg, trayImg.getDims()/2);
00481
00482 Point2D<int> objPos(obj.trayX*trayImg.getWidth(), obj.trayY*trayImg.getHeight());
00483
00484 drawCircle(trayImg, objPos, trayImg.getWidth()/12, PixRGB<byte>(255, 0, 0), 2);
00485 drawCross(trayImg, objPos, PixRGB<byte>(255, 0, 0), trayImg.getWidth()/8, 2);
00486
00487 std::ostringstream ss;
00488 ss << "Place Tray " << obj.trayName <<
00489 " (row " << obj.trayRow <<
00490 ", col " << obj.trayColumn <<
00491 ") on table and ENTER";
00492 writeText(trayImg, Point2D<int>(0, 0), ss.str().c_str());
00493
00494 userInteractiveWindow->drawImage(trayImg, 0, 0, true);
00495 while(userInteractiveWindow->getLastKeyPress() != 36) usleep(100000);
00496
00497 pthread_mutex_lock(&imgMutex);
00498 Image<PixRGB<byte> > cameraImg = inputImage;
00499 pthread_mutex_unlock(&imgMutex);
00500 userInteractiveWindow->drawImage(cameraImg, 0, 0, true);
00501 std::vector< Point2D<int> > poly;
00502 std::string msg = "Outline new object using 4 points. ESCAPE to undo point. SPACE to refresh image. ENTER when finished.";
00503
00504
00505 while (userInteractiveWindow->getLastMouseClick() != Point2D<int>(-1, -1)) { }
00506 while (userInteractiveWindow->getLastKeyPress() != -1) { }
00507
00508 bool finished = false;
00509 while(!finished) {
00510 Point2D<int> mouseClick = userInteractiveWindow->getLastMouseClick();
00511 if(mouseClick != Point2D<int>(-1, -1) && poly.size() < 4)
00512 poly.push_back(mouseClick);
00513
00514 int lastKeyPress = userInteractiveWindow->getLastKeyPress();
00515 switch(lastKeyPress) {
00516 case -1:
00517 break;
00518 case 9:
00519 if(poly.size()) poly.erase(poly.end()-1);
00520 break;
00521 case 36:
00522 if(poly.size() == 4) finished = true;
00523 break;
00524 case 65:
00525 pthread_mutex_lock(&imgMutex);
00526 cameraImg = inputImage;
00527 pthread_mutex_unlock(&imgMutex);
00528 userInteractiveWindow->drawImage(cameraImg, 0, 0, true);
00529 break;
00530 default:
00531 LINFO("Key Pressed: %d", lastKeyPress);
00532 break;
00533 }
00534
00535 Image< PixRGB<byte> > dispImage = cameraImg;
00536 for(size_t i=0; i<poly.size(); ++i) drawCircle(dispImage, poly[i], 5, PixRGB<byte>(255, 0, 0), 3);
00537 drawOutlinedPolygon(dispImage, poly, PixRGB<byte>(0, 0, 255), Point2D<int>(0,0),0,1,0,0,3);
00538 writeText(dispImage, Point2D<int>(0,0), msg.c_str());
00539 userInteractiveWindow->drawImage(dispImage, 0, 0, true);
00540
00541 usleep(100000);
00542 }
00543
00544 LINFO("Done placing object %d onto table.", objIdx);
00545
00546 return poly;
00547 }
00548
00549
00550
00551 void promptReturnObjectToTray(SceneSetup const & setup, int objIdx)
00552 {
00553 LINFO("Placing back object %d into its tray. Follow instructions in User Interactive window...", objIdx);
00554 const SceneSetup::Object &obj = setup.objects[objIdx];
00555
00556 Image< PixRGB<byte> > trayImg = Raster::ReadRGB(setup.setupPath + "/" + obj.trayFileName);
00557 trayImg = rescale(trayImg, trayImg.getDims()/2);
00558
00559 Point2D<int> objPos(obj.trayX*trayImg.getWidth(), obj.trayY*trayImg.getHeight());
00560
00561 drawCircle(trayImg, objPos, trayImg.getWidth()/12, PixRGB<byte>(255, 0, 0), 2);
00562 drawCross(trayImg, objPos, PixRGB<byte>(255, 0, 0), trayImg.getWidth()/8, 2);
00563
00564 std::ostringstream ss;
00565 ss << "Place back Obj(" <<
00566 "row " << obj.trayRow <<
00567 ", col " << obj.trayColumn <<
00568 ") into tray " << obj.trayName <<
00569 " and ENTER";
00570 writeText(trayImg, Point2D<int>(0, 0), ss.str().c_str());
00571
00572 userInteractiveWindow->drawImage(trayImg, 0, 0, true);
00573
00574
00575 while (userInteractiveWindow->getLastMouseClick() != Point2D<int>(-1, -1)) { }
00576 while (userInteractiveWindow->getLastKeyPress() != -1) { }
00577
00578
00579 while (userInteractiveWindow->getLastKeyPress() != 36) usleep(100000);
00580
00581 LINFO("Done placing back object %d into its tray.", objIdx);
00582 }
00583
00584
00585
00586 void getInt(const char *msg, int& val)
00587 {
00588 printf("%s [%d]: ", msg, val); fflush(stdout);
00589 char input[1000]; while(gets(input) == NULL) LERROR("Invalid input, try again");
00590
00591 if (strlen(input) > 0) val = atoi(input);
00592 };
00593
00594
00595 int submain(const int argc, const char** argv)
00596 {
00597
00598
00599 catchsignals(&signum);
00600
00601 LINFO("#############################################STARTING##############################################");
00602
00603 ModelManager mgr("App Scorbot MultiGrab");
00604
00605 scorbot.reset(new ScorbotSimple(mgr));
00606 mgr.addSubComponent(scorbot);
00607
00608 setupGrabbers(mgr);
00609
00610 ofs.reset(new OutputFrameSeries(mgr));
00611 mgr.addSubComponent(ofs);
00612
00613 if(mgr.parseCommandLine(argc, argv, "FilePrefix SceneID", 2, 2) == false) return -1;
00614 mgr.start();
00615
00616 if (grabbers.size() < NUMCAMS) LFATAL("Only found %"ZU" cameras instead of %d. Reboot your machine and try again.", grabbers.size(), NUMCAMS);
00617
00618
00619 for (size_t cameraID = 0; cameraID < grabbers.size(); ++cameraID)
00620 grabberThreadServer.enqueueJob(rutz::make_shared(new GrabJob(cameraID)));
00621
00622 sceneDir = mgr.getExtraArg(0);
00623 sceneID = boost::lexical_cast<int>(mgr.getExtraArg(1));
00624
00625 pthread_t displayThread;
00626 pthread_create(&displayThread, NULL, &displayThreadMethod, NULL);
00627
00628
00629 userInteractiveWindow = new XWinManaged(Dims(640,480), -1, -1, "User Interactive");
00630 userInteractiveWindow->setVisible(false);
00631 userInteractiveWindow->setPosition(0, 0);
00632
00633
00634 int runnumber = 0;
00635 while(true) {
00636 if(signum != 0) break;
00637
00638
00639 if ((runnumber % 5) == 0) {
00640 int gogo = 0; getInt("Perform robot homing sequence and press ENTER", gogo);
00641 }
00642
00643
00644 getInt("Enter scene ID (-1 to exit):", sceneID);
00645
00646 if (sceneID == -1) break;
00647
00648
00649 SceneSetup setup = loadSceneSetup(sceneID);
00650
00651
00652 userInteractiveWindow->setVisible(true);
00653
00654
00655 Image< PixRGB<byte> > backgroundImage = Raster::ReadRGB(setup.setupPath + "/" + setup.backgroundFileName);
00656 backgroundImage = rescale(backgroundImage, Dims(640, 480));
00657 writeText(backgroundImage, Point2D<int>(0, 0), "Please place this background on the scene and press ENTER.");
00658 userInteractiveWindow->drawImage(backgroundImage, 0, 0, true);
00659 LINFO("Place background map on scene and add houses, trees, and other background objects. See User Interactive window for instructions...");
00660
00661 while (userInteractiveWindow->getLastMouseClick() != Point2D<int>(-1, -1)) { }
00662 while (userInteractiveWindow->getLastKeyPress() != -1) { }
00663
00664 while(userInteractiveWindow->getLastKeyPress() != 36) usleep(100000);
00665 LINFO("Background map done. Make sure you have built a nice scene.");
00666
00667
00668 for (size_t i = 0; i < setup.objects.size(); ++i)
00669 setup.objects[i].outline = promptPlaceObjectOnScene(setup, i);
00670
00671
00672 userInteractiveWindow->setVisible(false);
00673
00674
00675 {
00676 std::string objectFileName = sformat("%s/RobotScene-s%04d-polygons.txt", dataDir, sceneID);
00677 std::ofstream objectFile(objectFileName.c_str());
00678
00679 LINFO("Saving the object bounding boxes into: %s", objectFileName.c_str());
00680
00681 for(size_t i=0; i<setup.objects.size(); ++i)
00682 {
00683 for(size_t j=0; j<setup.objects[i].outline.size(); ++j)
00684 {
00685 Point2D<int> &pnt = setup.objects[i].outline[j];
00686 if(j != 0) objectFile << ',';
00687 objectFile << pnt.i << ',' << pnt.j;
00688 }
00689 objectFile << std::endl;
00690 }
00691 }
00692
00693
00694 for (pathID = 0; pathID < int(setup.pathIndex.size()); ++pathID) {
00695 if(signum != 0) break;
00696
00697 const std::string dir = sformat("%s/RobotScene-s%04d-p%02d", dataDir, sceneID, pathID);
00698 const std::string cmd = sformat("/bin/mkdir -p %s", dir.c_str());
00699 if (system(cmd.c_str()) == -1) PLFATAL("Could not create directory %s", dir.c_str());
00700
00701 int gogo = pathID; getInt("Set light and press ENTER to start video recording", gogo);
00702
00703
00704 while(writer.size() > 1000) {
00705 LINFO("Waiting for image writer thread, queue size = %"ZU"...", writer.size());
00706 usleep(1000000);
00707 }
00708
00709 LINFO("Running Scene %04d Path %02d ...", sceneID, setup.pathIndex[pathID]);
00710
00711 executePath(setup.pathIndex[pathID]);
00712 }
00713 if(signum != 0) break;
00714
00715
00716 userInteractiveWindow->setVisible(true);
00717 userInteractiveWindow->setPosition(0, 0);
00718 for(size_t i=0; i<setup.objects.size(); ++i) promptReturnObjectToTray(setup, i);
00719 userInteractiveWindow->setVisible(false);
00720
00721
00722 ++sceneID;
00723 ++runnumber;
00724 }
00725
00726
00727 keepgoing = false;
00728
00729
00730
00731 while(writer.size()) {
00732 LINFO("Waiting for image writer thread, queue size = %"ZU"...", writer.size());
00733 usleep(500000);
00734 }
00735 writer.flushQueue(250000, true);
00736
00737
00738 LINFO("Cleaning up... Stand by...");
00739 usleep(2000000);
00740
00741
00742 mgr.stop();
00743
00744 LINFO("Finished.");
00745
00746 return 0;
00747 }
00748
00749
00750 int main(int argc, const char** argv)
00751 {
00752 int ret = -1;
00753
00754 try { ret = submain(argc, argv); }
00755 catch(...) { REPORT_CURRENT_EXCEPTION; }
00756
00757 return ret;
00758 }