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