00001 00022 #include <grasp_planning_graspit/GraspItSceneManagerHeadless.h> 00023 #include <grasp_planning_graspit/LogBinding.h> 00024 #include <grasp_planning_graspit/PrintHelpers.h> 00025 00026 #include <string> 00027 #include <exception> 00028 00029 #include <graspit/graspitCore.h> 00030 00031 #include <Inventor/sensors/SoIdleSensor.h> 00032 00033 using GraspIt::GraspItSceneManagerHeadless; 00034 00035 GraspItSceneManagerHeadless::GraspItSceneManagerHeadless(): 00036 ivThread(NULL), 00037 ivReady(false), 00038 mIdleSensor(NULL) 00039 { 00040 initialize(); 00041 } 00042 00043 GraspItSceneManagerHeadless::~GraspItSceneManagerHeadless() 00044 { 00045 shutdown(); 00046 } 00047 00048 void GraspItSceneManagerHeadless::initializeCore() 00049 { 00050 // start the thread loop which will kick off a new thread to run the QT Application 00051 ivThread = new THREAD_CONSTR(ivThreadLoop, this); 00052 00053 // wait until Qt is initialized before doing anything else 00054 waitForInventorState(true); 00055 } 00056 00057 00058 void GraspItSceneManagerHeadless::destroyCore() 00059 { 00060 PRINTMSG("GraspItSceneManagerHeadless::destroyCore()"); 00061 // have to quit core main loop first so that the thread 00062 // exits its loop 00063 /*if (core) 00064 { 00065 GraspitCore * _core = dynamic_cast<GraspitCore*>(core); 00066 if (!_core) 00067 { 00068 throw std::string("Inconsistency:: core should be of class GraspitCore!"); 00069 } 00070 _core->exitMainLoop(); 00071 waitForInventorState(false); 00072 }*/ 00073 core->exitMainLoop(); 00074 // PRINTMSG("Done in destroyCore()"); 00075 if (ivThread) 00076 { 00077 PRINTMSG("Now exit Inventor thread."); 00078 ivThread->join(); 00079 delete ivThread; 00080 ivThread = NULL; 00081 } 00082 if (core) 00083 { 00084 delete core; 00085 core = NULL; 00086 } 00087 } 00088 00089 00090 00091 00092 World * GraspItSceneManagerHeadless::createNewGraspitWorld() 00093 { 00094 if (!core) 00095 { 00096 throw std::string("Cannot initialize world without core begin intialized"); 00097 } 00098 00099 PRINTMSG("Creating new graspit world"); 00100 core->emptyWorld("GraspItWorld"); 00101 return core->getWorld(); 00102 } 00103 00104 00105 00106 void GraspItSceneManagerHeadless::ivThreadLoop(GraspItSceneManagerHeadless * _this) 00107 { 00108 PRINTMSG("Enter INVENTOR thread loop"); 00109 std::string name("GraspIt"); 00110 std::string hArg("--headless"); 00111 char * args[2]; 00112 args[0]=const_cast<char*>(name.c_str()); 00113 args[1]=const_cast<char*>(hArg.c_str()); 00114 PRINTMSG("Starting with args "<<args[0]<<", "<<args[1]); 00115 GraspitCore * coreHeadless = new GraspitCore(2,args); 00116 PRINTMSG("Created."); 00117 _this->core = coreHeadless; 00118 00119 _this->createIdleSensor(); 00120 00121 // we will schedule the idle sensor once, so that 00122 // it can call _this->setInventorReady(true) 00123 _this->mIdleSensor->schedule(); 00124 00125 // begin the main loop of inventor 00126 coreHeadless->startMainLoop(); 00127 00128 _this->deleteIdleSensor(); 00129 00130 _this->setInventorReady(false); 00131 00132 PRINTMSG("Exit INVENTOR thread loop"); 00133 } 00134 00135 00136 bool GraspItSceneManagerHeadless::isReady() const 00137 { 00138 return isInventorReady(); 00139 } 00140 00141 void GraspItSceneManagerHeadless::waitUntilReady() const 00142 { 00143 return waitForInventorState(true); 00144 } 00145 00146 void GraspItSceneManagerHeadless::waitForInventorState(const bool value) const 00147 { 00148 while (isInventorReady() != value) SLEEP(0.1); 00149 } 00150 00151 bool GraspItSceneManagerHeadless::isInventorReady() const 00152 { 00153 UNIQUE_LOCK lck(ivReadyMtx); 00154 return ivReady; 00155 } 00156 00157 void GraspItSceneManagerHeadless::setInventorReady(const bool flag) 00158 { 00159 UNIQUE_LOCK lck(ivReadyMtx); 00160 ivReady = flag; 00161 } 00162 00163 00164 void GraspItSceneManagerHeadless::deleteIdleSensor() 00165 { 00166 if (mIdleSensor) 00167 { 00168 if (mIdleSensor->isScheduled()) mIdleSensor->unschedule(); 00169 delete mIdleSensor; 00170 mIdleSensor = NULL; 00171 } 00172 } 00173 00174 void GraspItSceneManagerHeadless::createIdleSensor() 00175 { 00176 if (mIdleSensor) 00177 { 00178 if (mIdleSensor->isScheduled()) mIdleSensor->unschedule(); 00179 delete mIdleSensor; 00180 } 00181 00182 // start the idle sensor which is triggered regularly from within the inventor thread 00183 mIdleSensor = new SoIdleSensor(sensorCB, this); 00184 } 00185 00186 00187 void GraspItSceneManagerHeadless::sensorCB(void *data, SoSensor *) 00188 { 00189 // PRINTMSG(" ### sensorCB ###"); 00190 GraspItSceneManagerHeadless* _this = dynamic_cast<GraspItSceneManagerHeadless*>(static_cast<GraspItSceneManagerHeadless*>(data)); 00191 if (!_this) 00192 { 00193 PRINTERROR("Could not cast GraspItSceneManagerHeadless"); 00194 return; 00195 } 00196 00197 // Inventor obviously is ready, because otherwise this callback would not have been called. 00198 // use this here to trigger first initialization of the ivReady variable. 00199 if (!_this->isInventorReady()) 00200 { 00201 _this->setInventorReady(true); 00202 } 00203 00204 _this->processIdleEvent(); 00205 } 00206 00207 00208 bool GraspItSceneManagerHeadless::scheduleIdleEvent() 00209 { 00210 // PRINTMSG("Registering"); 00211 if (!isInventorReady()) 00212 { 00213 PRINTERROR("Cannot schedule update because Inventor is not initialized yet"); 00214 return false; 00215 } 00216 00217 assert(mIdleSensor); 00218 00219 // trigger another call of this method in the next event loop iteration 00220 if (!mIdleSensor->isScheduled()) 00221 { 00222 mIdleSensor->schedule(); 00223 } 00224 return true; 00225 }