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 "onLinePlanner.h"
00027
00028 #include <Inventor/nodes/SoSeparator.h>
00029
00030 #include "world.h"
00031 #include "robot.h"
00032 #include "simAnn.h"
00033 #include "searchState.h"
00034 #include "searchEnergy.h"
00035 #include "graspTesterThread.h"
00036 #include "onLineGraspInterface.h"
00037 #include "grasp.h"
00038 #include "eigenGrasp.h"
00039 #include "matvec3D.h"
00040
00041
00042 #include "debug.h"
00043
00044 #define SHOW_RECENT_SOLUTION 1
00045 #define CANDIDATE_BUFFER_SIZE 20
00046 #define SOLUTION_BUFFER_SIZE 10
00047
00048 OnLinePlanner::OnLinePlanner(Hand *h) : SimAnnPlanner(h)
00049 {
00050 mSolutionClone = NULL;
00051 mMarkSolutions = true;
00052 mCurrentBest = NULL;
00053 mSimAnn->setParameters(ANNEAL_ONLINE);
00054 setRenderType(RENDER_LEGAL);
00055 mRepeat = true;
00056
00057 mGraspTester = new GraspTester(h);
00058 mGraspTester->startThread();
00059 mGraspTester->showClone(false);
00060
00061
00062 mRefHand = h;
00063 createAndUseClone();
00064
00065 mHand->setRenderGeometry(true);
00066
00067 showClone(false);
00068
00069
00070
00071
00072 mHand->getWorld()->toggleCollisions(false, mGraspTester->getHand(), mHand);
00073
00074 mGraspTester->getHand()->setName( mGraspTester->getHand()->getName() + QString(" th") );
00075 mHand->setName( mHand->getName() + QString(" pl") );
00076
00077
00078 mInterface = new OnLineGraspInterface(mRefHand);
00079 }
00080
00081 OnLinePlanner::~OnLinePlanner()
00082 {
00083 mGraspTester->stopPlanner();
00084 mGraspTester->wait();
00085 delete mGraspTester;
00086 DBGA("Grasp tester deleted");
00087 if (mSolutionClone) {
00088 mHand->getWorld()->destroyElement(mSolutionClone);
00089 }
00090 delete mInterface;
00091 }
00092
00093 void
00094 OnLinePlanner::resetParameters()
00095 {
00096 SimAnnPlanner::resetParameters();
00097 if (mCurrentBest) mCurrentBest->setEnergy(1.0e8);
00098 }
00099
00100 void
00101 OnLinePlanner::createSolutionClone()
00102 {
00103 if(mSolutionClone) {
00104 DBGA("Solution clone exists already!");
00105 return;
00106 }
00107
00108 mSolutionClone = new Hand(mHand->getWorld(), "Solution clone");
00109 mSolutionClone->cloneFrom(mHand);
00110 mSolutionClone->setTransparency(0.5);
00111 mSolutionClone->showVirtualContacts(false);
00112
00113 mHand->getWorld()->addRobot(mSolutionClone, true);
00114 mHand->getWorld()->toggleCollisions(false, mSolutionClone);
00115 mSolutionClone->setTran( mHand->getTran() );
00116 }
00117
00118 void
00119 OnLinePlanner::action(ActionType a)
00120 {
00121 mInterface->action(a);
00122 }
00123
00124 void
00125 OnLinePlanner::useRealBarrettHand(bool s)
00126 {
00127 mInterface->useRealBarrettHand(s);
00128 }
00129
00130 ActionType
00131 OnLinePlanner::getAction()
00132 {
00133 return mInterface->getAction();
00134 }
00135
00136 void
00137 OnLinePlanner::showSolutionClone(bool s)
00138 {
00139 if (s) {
00140 if (!mSolutionClone) createSolutionClone();
00141 else mHand->getWorld()->addElementToSceneGraph(mSolutionClone);
00142 } else {
00143 if (mSolutionClone) mHand->getWorld()->removeElementFromSceneGraph(mSolutionClone);
00144 }
00145 }
00146
00147 void
00148 OnLinePlanner::showClone(bool s)
00149 {
00150 SimAnnPlanner::showClone(s);
00151 }
00152
00153 bool
00154 OnLinePlanner::resetPlanner()
00155 {
00156 DBGA("Online planner reset");
00157 if (!mGraspTester->resetPlanner()) {
00158 DBGA("Failed to reset parallel tester!");
00159 return false;
00160 }
00161 while (!mCandidateList.empty()) {
00162 delete mCandidateList.front(); mCandidateList.pop_front();
00163 }
00164 if (!SimAnnPlanner::resetPlanner()) return false;
00165 if (mCurrentBest) delete mCurrentBest;
00166 mCurrentBest = new GraspPlanningState(mCurrentState);
00167 return true;
00168 }
00169
00170 void
00171 OnLinePlanner::startPlanner()
00172 {
00173 DBGP("Starting on-line planner");
00174 SimAnnPlanner::startPlanner();
00175 mGraspTester->startPlanner();
00176 }
00177
00178 void
00179 OnLinePlanner::pausePlanner()
00180 {
00181 mGraspTester->pausePlanner();
00182 msleep(1000);
00183
00184 SimAnnPlanner::pausePlanner();
00185 }
00186
00187 double
00188 OnLinePlanner::stateDistance(const GraspPlanningState *s1, const GraspPlanningState *s2)
00189 {
00190 return distanceOutsideApproach(s1->getTotalTran(), s2->getTotalTran());
00191 }
00192
00197 double
00198 OnLinePlanner::distanceOutsideApproach(const transf &solTran, const transf &handTran)
00199 {
00200 double max_angle = M_PI / 4.0;
00201 double max_dist = 50.0;
00202 double f;
00203
00204 transf changeTran = solTran * handTran.inverse();
00205
00206
00207
00208
00209
00210
00211 changeTran = mHand->getApproachTran() * changeTran * mHand->getApproachTran().inverse();
00212
00213
00214 double angle; vec3 axis;
00215 changeTran.rotation().ToAngleAxis(angle, axis);
00216
00217
00218 vec3 approach = changeTran.translation();
00219
00220
00221 if (approach.z() < 0) {
00222 f = -1.0;
00223 } else {
00224 f = 1.0;
00225 }
00226 approach.z() = 0;
00227 double dist = approach.len();
00228
00229
00230 if (angle > M_PI) angle -= 2*M_PI;
00231 if (angle < -M_PI) angle += 2*M_PI;
00232 angle = fabs(angle) / max_angle ;
00233 dist = dist / max_dist;
00234
00235 return f * std::max(angle, dist);
00236 }
00237
00239 void
00240 OnLinePlanner::updateSolutionList()
00241 {
00242 transf stateTran, currentHandTran = mRefHand->getTran();
00243
00244 std::list<GraspPlanningState*>::iterator it;
00245
00246 for ( it = mBestList.begin(); it != mBestList.end(); it++ ) {
00247 stateTran = (*it)->getTotalTran();
00248
00249 double dist = distanceOutsideApproach(stateTran, currentHandTran);
00250 if (dist < 0) dist = -dist;
00251 (*it)->setDistance(dist);
00252 if (mMarkSolutions) {
00253 if (dist<1) (*it)->setIVMarkerColor(1-dist, dist, 0);
00254 else (*it)->setIVMarkerColor(0 , 1, 1);
00255 }
00256 }
00257
00258
00259 mBestList.sort(GraspPlanningState::compareStatesDistances);
00260
00261 while (mBestList.size() > SOLUTION_BUFFER_SIZE) {
00262 delete mBestList.back();
00263 mBestList.pop_back();
00264 }
00265 }
00266
00267 void
00268 OnLinePlanner::mainLoop()
00269 {
00270 static clock_t lastCheck = clock();
00271 clock_t time = clock();
00272 double secs = (float)(time - lastCheck) / CLOCKS_PER_SEC;
00273
00274 if (secs < 0.2) {
00275
00276 graspLoop();
00277 return;
00278 }
00279 lastCheck = time;
00280
00281
00282
00283
00284
00285 mCurrentState->setRefTran( mRefHand->getTran(), false );
00286
00287 mCurrentState->setLegal(false);
00288
00289 if ( mCurrentState->getVariable("dist")) {
00290 Body *obj = mCurrentState->getObject();
00291 double maxDist = 200;
00292 mObjectDistance = mRefHand->getApproachDistance(obj,maxDist);
00293 if (mObjectDistance > maxDist) mObjectDistance = maxDist;
00294 mCurrentState->getPosition()->getVariable("dist")->setRange(-30,mObjectDistance);
00295
00296 mCurrentState->getPosition()->getVariable("dist")->setValue(mObjectDistance/2);
00297 mCurrentState->getPosition()->getVariable("dist")->setJump(0.33);
00298 }
00299
00300
00301 std::list<GraspPlanningState*>::iterator it = mCandidateList.begin();
00302 while (it!=mCandidateList.end()) {
00303
00304 if ( mGraspTester->postCandidate(*it) ) {
00305 DBGP("Candidate posted");
00306 it = mCandidateList.erase(it);
00307 } else {
00308 DBGP("Tester thread buffer is full");
00309 break;
00310 }
00311 }
00312
00313
00314 GraspPlanningState *s;
00315 while ( (s = mGraspTester->popSolution()) != NULL ) {
00316
00317
00318 s->changeHand( mRefHand, true );
00319 mBestList.push_back(s);
00320 if (mMarkSolutions) {
00321 mHand->getWorld()->getIVRoot()->addChild( s->getIVRoot() );
00322 }
00323 }
00324 updateSolutionList();
00325
00326
00327 s = mInterface->updateHand(&mBestList);
00328 if (s) {
00329 if (mSolutionClone) s->execute(mSolutionClone);
00330 if (mMarkSolutions) s->setIVMarkerColor(1,1,0);
00331 }
00332
00333 DBGP("On-line main loop done");
00334 }
00335
00336 void
00337 OnLinePlanner::graspLoop()
00338 {
00339
00340
00341 GraspPlanningState *input = NULL;
00342 if ( processInput() ) {
00343 input = mTargetState;
00344 }
00345
00346
00347 SimAnn::Result r = mSimAnn->iterate(mCurrentState,mEnergyCalculator,input);
00348 mCurrentStep = mSimAnn->getCurrentStep();
00349
00350 if ( r == SimAnn::JUMP ) {
00351 assert(mCurrentState->isLegal());
00352
00353 if (mCurrentState->getEnergy() < 0 || mCurrentState->getEnergy() < mCurrentBest->getEnergy()) {
00354 DBGP("New candidate");
00355 GraspPlanningState *insertState = new GraspPlanningState(mCurrentState);
00356
00357 insertState->setPositionType(SPACE_COMPLETE,true);
00358 insertState->setRefTran( mCurrentState->getObject()->getTran(), true);
00359 insertState->setItNumber( mCurrentStep );
00360 if (insertState->getEnergy() < mCurrentBest->getEnergy()) {
00361 mCurrentBest->copyFrom( insertState );
00362 }
00363 if (!addToListOfUniqueSolutions(insertState, &mCandidateList,0.4)) {
00364 DBGP("Similar to old candidate");
00365 delete insertState;
00366 } else {
00367 mCandidateList.sort(GraspPlanningState::compareStates);
00368 while (mCandidateList.size() > CANDIDATE_BUFFER_SIZE) {
00369 delete mCandidateList.back();
00370 mCandidateList.pop_back();
00371 }
00372 }
00373 DBGP("Added candidate");
00374 }
00375 }
00376
00377 if (mCurrentStep % 100 == 0) emit update();
00378 render();
00379
00380 }
00381
00382 int
00383 OnLinePlanner::getFCBufferSize() const
00384 {
00385 return mGraspTester->getNumCandidates();
00386 }