00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <Inventor/sensors/SoIdleSensor.h>
00027
00028 #include "egPlanner.h"
00029 #include "searchState.h"
00030 #include "searchEnergy.h"
00031 #include "robot.h"
00032 #include "barrett.h"
00033 #include "pr2Gripper.h"
00034 #include "body.h"
00035 #include "simAnn.h"
00036 #include "world.h"
00037 #include "gloveInterface.h"
00038 #include "eigenGrasp.h"
00039 #include "collisionInterface.h"
00040
00041
00042 #include "debug.h"
00043
00044
00045 #include "profiling.h"
00046
00047 PROF_DECLARE(EG_PLANNER);
00048
00049 #define BEST_LIST_SIZE 20
00050
00051 EGPlanner::EGPlanner(Hand *h)
00052 {
00053 mHand = h;
00054 init();
00055 mEnergyCalculator = new SearchEnergy();
00056 }
00057
00061 void
00062 EGPlanner::init()
00063 {
00064 mProfileInstance = new Profiling::ProfileInstance();
00065
00066 mIdleSensor = NULL;
00067 mCurrentState = NULL;
00068 mTargetState = NULL;
00069 mInputType = INPUT_NONE;
00070 mRenderType = RENDER_LEGAL;
00071 mRepeat = false;
00072 mCurrentStep = 0;
00073 mRenderCount = 0;
00074 mLastRenderState = NULL;
00075 mMaxSteps = 100000;
00076 mMaxTime = -1;
00077 mMultiThread = false;
00078 mState = INIT;
00079 mUsesClone = false;
00080 mOut = NULL;
00081 }
00082
00083 EGPlanner::~EGPlanner()
00084 {
00085 delete mProfileInstance;
00086 clearSolutions();
00087 if (mEnergyCalculator) delete mEnergyCalculator;
00088 if (mUsesClone) {
00089 mHand->getWorld()->destroyElement(mHand);
00090 }
00091 if (mCurrentState) delete mCurrentState;
00092 if (mTargetState) delete mTargetState;
00093 if (mIdleSensor) delete mIdleSensor;
00094 }
00095
00102 void
00103 EGPlanner::setState(PlannerState s)
00104 {
00105 if (mMultiThread) mControlMutex.lock();
00106 if (mState == DONE && s != DONE && s != EXITED) {
00107 DBGA("Planner is DONE; change state no longer possible");
00108 } else if (mState == EXITED && s != EXITED) {
00109 DBGA("Planner is EXITED; change state no longer possible");
00110 } else {
00111 mState = s;
00112 }
00113 if (mMultiThread) mControlMutex.unlock();
00114 }
00115
00116 PlannerState
00117 EGPlanner::getState()
00118 {
00119 if (mMultiThread) mControlMutex.lock();
00120 PlannerState s = mState;
00121 if (mMultiThread) mControlMutex.unlock();
00122 return s;
00123 }
00124
00129 void
00130 EGPlanner::resetParameters()
00131 {
00132 mCurrentStep = 0;
00133 mRenderCount = 0;
00134 }
00135
00146 bool
00147 EGPlanner::resetPlanner()
00148 {
00149 if ( getState() == RUNNING || getState() == DONE) {
00150 DBGA("Planner is either running or dead; cannot reset");
00151 return false;
00152 }
00153 if (!initialized()) {
00154 DBGA("Planner is not ready; not all necessary information has been set");
00155 return false;
00156 }
00157 clearSolutions();
00158 resetParameters();
00159
00160 mProfileInstance->reset();
00161
00162 setState(READY);
00163 if (!mMultiThread) emit update();
00164 return true;
00165 }
00166
00167 bool
00168 EGPlanner::checkTerminationConditions()
00169 {
00170 if (!isActive()) return true;
00171 bool termination = false;
00172
00173 if (mMaxSteps != -1 && mCurrentStep >= mMaxSteps){
00174 if (!mRepeat) {
00175 pausePlanner();
00176 termination = true;
00177 } else {
00178 resetParameters();
00179 }
00180 if (!mMultiThread) {
00181 emit update();
00182 }
00183 } else if (mMaxTime != -1 ) {
00184
00185
00186 if (getRunningTime() > mMaxTime) {
00187 termination = true;
00188 stopPlanner();
00189 }
00190 }
00191 if (termination) {
00192 emit complete();
00193 }
00194 return termination;
00195 }
00196
00197 void
00198 EGPlanner::createAndUseClone()
00199 {
00200 if (isActive()) {
00201 DBGA("Can not change hands while planner is running");
00202 return;
00203 }
00204 if (mMultiThread) {
00205
00206 mHand->getWorld()->getCollisionInterface()->newThread();
00207 }
00208 Hand *clone;
00209 if (mHand->isA("Barrett")) {
00210 clone = new Barrett( mHand->getWorld(), "Barrett clone");
00211 } else if (mHand->isA("Pr2Gripper")) {
00212 clone = new Pr2Gripper( mHand->getWorld(), "PR2 Gripper clone");
00213 } else {
00214 clone = new Hand(mHand->getWorld(), "Hand clone");
00215 }
00216 clone->cloneFrom(mHand);
00217 clone->setRenderGeometry(false);
00218 clone->showVirtualContacts(false);
00219 if (mMultiThread) {
00220
00221
00222 mHand->getWorld()->addRobot(clone,false);
00223 } else {
00224 mHand->getWorld()->addRobot(clone,true);
00225 }
00226 mHand->getWorld()->toggleCollisions(false, mHand, clone);
00227 clone->setTran( mHand->getTran() );
00228 mHand = clone;
00229 mUsesClone = true;
00230 if (mCurrentState) mCurrentState->changeHand(mHand);
00231 }
00232
00239 void
00240 EGPlanner::showClone(bool s)
00241 {
00242 if (!mUsesClone) {
00243 DBGA("Planner is not using a clone");
00244 return;
00245 }
00246 if (!s) {
00247 mHand->getWorld()->removeElementFromSceneGraph(mHand);
00248 } else {
00249 mHand->getWorld()->addElementToSceneGraph(mHand);
00250 }
00251 }
00252
00253 void
00254 EGPlanner::setEnergyType(SearchEnergyType s)
00255 {
00256 assert (mEnergyCalculator);
00257 mEnergyCalculator->setType(s);
00258 }
00259
00260 void
00261 EGPlanner::setContactType(SearchContactType c)
00262 {
00263 assert (mEnergyCalculator);
00264 mEnergyCalculator->setContactType(c);
00265 }
00266
00267 void
00268 EGPlanner::sensorCB(void *data, SoSensor *)
00269 {
00270 EGPlanner *planner = (EGPlanner*)data;
00271 if (planner->checkTerminationConditions()) {
00272
00273 return;
00274 }
00275 planner->mainLoop();
00276 planner->mIdleSensor->schedule();
00277 }
00278
00279 void EGPlanner::threadLoop()
00280 {
00281 bool done = false;
00282 while (!done) {
00283 PlannerState s = getState();
00284 switch(s) {
00285 case INIT:
00286 sleep(0.1);
00287 break;
00288 case READY:
00289 sleep(0.1);
00290 break;
00291 case RUNNING:
00292 mainLoop();
00293 break;
00294 case DONE:
00295 done = true;
00296 break;
00297 }
00298 if (!done) checkTerminationConditions();
00299 }
00300 setState(EXITED);
00301 DBGP("Thread is done!");
00302 }
00303
00304
00305 double
00306 EGPlanner::getRunningTime()
00307 {
00308 return 1.0e-6 * mProfileInstance->getTotalTimeMicroseconds();
00309 }
00310
00311 void
00312 EGPlanner::run()
00313 {
00314 mMultiThread = true;
00315 mRenderType = RENDER_NEVER;
00316
00317 createAndUseClone();
00318
00319 setState(INIT);
00320 threadLoop();
00321 }
00322
00328 void
00329 EGPlanner::startThread()
00330 {
00331 if (mMultiThread) {
00332 DBGA("Can not start thread; already multi-threaded");
00333 }
00334 if (getState()!=INIT) {
00335 DBGA("Can not start thread; state is not INIT");
00336 }
00337 setState(STARTING_THREAD);
00338 start();
00339 mMultiThread = true;
00340
00341 while (getState() == STARTING_THREAD);
00342
00343
00344
00345 mHand->getWorld()->addElementToSceneGraph(mHand);
00346 }
00347
00348 void
00349 EGPlanner::startPlanner()
00350 {
00351 if ( getState() != READY ) {
00352 DBGA("Planner not ready to start!");
00353 return;
00354 }
00355 if (!mMultiThread) {
00356 mHand->showVirtualContacts(false);
00357 mIdleSensor = new SoIdleSensor(sensorCB, this);
00358 mIdleSensor->schedule();
00359 }
00360 PROF_RESET_ALL;
00361 PROF_START_TIMER(EG_PLANNER);
00362
00363 mProfileInstance->startTimer();
00364
00365 setState( RUNNING );
00366 }
00367
00372 void
00373 EGPlanner::stopPlanner()
00374 {
00375 if (getState()==DONE || getState()==EXITED) return;
00376
00377 pausePlanner();
00378
00379 setState(DONE);
00380 if (mMultiThread) {
00381 DBGP("Waiting for exit");
00382
00383 while (getState()!=EXITED);
00384 DBGP("Exited");
00385 }
00386 }
00387
00388 void
00389 EGPlanner::pausePlanner()
00390 {
00391 if (getState() != RUNNING) return;
00392 mProfileInstance->stopTimer();
00393 if (!mMultiThread) {
00394 if (mIdleSensor) delete mIdleSensor;
00395 mIdleSensor = NULL;
00396 mHand->showVirtualContacts(true);
00397 }
00398 setState(READY);
00399 PROF_STOP_TIMER(EG_PLANNER);
00400 PROF_PRINT_ALL;
00401 if (!mMultiThread) emit complete();
00402 }
00403
00404 void
00405 EGPlanner::render()
00406 {
00407 if (mMultiThread) {
00408
00409
00410 return;
00411 }
00412 if (mRenderType == RENDER_BEST) {
00413 if ( mBestList.empty() ) return;
00414 if ( mLastRenderState == mBestList.front() ) return;
00415 mLastRenderState = mBestList.front();
00416 mBestList.front()->execute();
00417 } else if (mRenderType == RENDER_LEGAL) {
00418 if (mRenderCount >= 20) {
00419 DBGP("Render: geom is " << mHand->getRenderGeometry() );
00420 mRenderCount = 0;
00421 if ( mCurrentState && mCurrentState->isLegal() ) mCurrentState->execute();
00422 } else mRenderCount++;
00423 } else if (mRenderType==RENDER_ALWAYS) {
00424 mCurrentState->execute();
00425 } else if ( mRenderType == RENDER_NEVER ) {
00426 return;
00427 }
00428 }
00429
00430 const GraspPlanningState*
00431 EGPlanner::getGrasp(int i)
00432 {
00433 assert (i>=0 && i<(int)mBestList.size());
00434 std::list<GraspPlanningState*>::iterator it = mBestList.begin();
00435 for (int k=0; k<i; k++) {
00436 it++;
00437 }
00438 return (*it);
00439 }
00440
00441 void
00442 EGPlanner::showGrasp(int i)
00443 {
00444 assert (i>=0 && i<getListSize());
00445 const GraspPlanningState *s = getGrasp(i);
00446 s->execute();
00447 bool l; double e;
00448 mEnergyCalculator->analyzeCurrentPosture(s->getHand(), s->getObject(), l, e, false);
00449 DBGA("Re-computed energy: " << e);
00450 }
00451
00452 void
00453 EGPlanner::clearSolutions()
00454 {
00455 while ( !mBestList.empty() ) {
00456 delete(mBestList.back());
00457 mBestList.pop_back();
00458 }
00459 }
00460 bool
00461 EGPlanner::setInput(unsigned char input, bool on)
00462 {
00463 if (input == INPUT_NONE) {
00464 mInputType = INPUT_NONE;
00465 } else if (on) {
00466 mInputType = mInputType | input;
00467 } else {
00468 mInputType = mInputType & (~input);
00469 }
00470 return true;
00471 }
00472
00473 bool
00474 EGPlanner::processInput()
00475 {
00476 assert(mTargetState);
00477 if (mInputType & INPUT_GLOVE) {
00478
00479
00480
00481 assert(mHand->getGloveInterface());
00482 double *gloveDOF = new double [mHand->getNumDOF()];
00483 for (int d=0; d<mHand->getNumDOF(); d++) {
00484 if (mHand->getGloveInterface()->isDOFControlled(d)) {
00485 gloveDOF[d] = mHand->getGloveInterface()->getDOFValue(d);
00486 } else {
00487 gloveDOF[d] = mHand->getDOF(d)->getVal();
00488 }
00489 }
00490 mTargetState->getPosture()->storeHandDOF(gloveDOF);
00491 delete [] gloveDOF;
00492 }
00493
00494
00495
00496
00497 return true;
00498 }
00499
00500 double
00501 EGPlanner::stateDistance(const GraspPlanningState *s1, const GraspPlanningState *s2) {
00502 return s1->distance(s2);
00503 }
00504
00513 bool
00514 EGPlanner::addToListOfUniqueSolutions(GraspPlanningState *s, std::list<GraspPlanningState*> *list, double distance)
00515 {
00516 std::list<GraspPlanningState*>::iterator it;
00517 it = list->begin();
00518 bool add = true;
00519 while (it!=list->end()) {
00520 double d = stateDistance(s,*it);
00521 if ( fabs(d) < distance ) {
00522 DBGP("Distance: " << fabs(d) );
00523
00524 if ( s->getEnergy() < (*it)->getEnergy() ) {
00525
00526 delete (*it);
00527 it = list->erase(it);
00528 DBGP("Old state removed");
00529 } else {
00530
00531 add = false;
00532 break;
00533 }
00534 } else {
00535
00536 it++;
00537 }
00538 }
00539 if (add) {
00540 list->push_back(s);
00541 }
00542 return add;
00543 }
00544
00545 void
00546 EGPlanner::setStatStream(std::ostream *out) const
00547 {
00548 mOut = out;
00549 assert(mEnergyCalculator);
00550 mEnergyCalculator->setStatStream(out);
00551 }