00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00029 #include "dbase_grasp.h"
00030 #include "ivmgr.h"
00031 #include "graspitGUI.h"
00032 #include "world.h"
00033 #include "searchState.h"
00034 #include "egPlanner.h"
00035 #include "guidedPlanner.h"
00036 #include "body.h"
00037 #include "robot.h"
00038 #include "searchEnergy.h"
00039 #include "loopPlanner.h"
00040
00041 #include "scanSimulator.h"
00042
00043 #include "debug.h"
00044 #include <Inventor/sensors/SoTimerSensor.h>
00045
00046 DBaseBatchPlanner::DBaseBatchPlanner(IVmgr *mgr, GraspItGUI *gui)
00047 {
00048 ivmgr = mgr;
00049 mGui = gui;
00050 mObject = NULL;
00051 mHand = NULL;
00052 mPlanner = NULL;
00053 mTimerSensor = NULL;
00054 numOfGrasps = 0;
00055 energyConstraint = -3.0;
00056
00057 }
00058
00059 DBaseBatchPlanner::~DBaseBatchPlanner()
00060 {
00061 if (mPlanner) delete mPlanner;
00062 if (mTimerSensor) delete mTimerSensor;
00063 DBGAF(mLogStream,"Planner successfully deleted");
00064 mLogStream.close();
00065 }
00066
00067 bool DBaseBatchPlanner::processArguments(int argc, char **argv)
00068 {
00069 if (argc < 8) {
00070 DBGA("Not enough arguments to DBasePlanner");
00071 usage();
00072 return false;
00073 }
00074
00075 if ( !strcmp(argv[1],"dbase") ) {
00076 mType = DEXTEROUS;
00077 } else if ( !strcmp(argv[1],"dbase_gripper") ) {
00078 mType = GRIPPER;
00079 if (argc < 9) {
00080 DBGA("Not enough arguments to DBasePlanner GRIPPER");
00081 usage();
00082 return false;
00083 }
00084 } else {
00085 DBGA("dbase specifier missing??");
00086 usage();
00087 return false;
00088 }
00089
00090
00091 mLogStream.open(argv[6],std::fstream::out | std::fstream::app);
00092 if (mLogStream.fail()) {
00093 DBGA("Failed to open log file " << argv[6]);
00094 return false;
00095 }
00096
00097 QString filename;
00098 QString graspitRoot = QString(getenv("GRASPIT"));
00099 if (graspitRoot.isNull()) {
00100 DBGAF(mLogStream,"GRASPIT environment variable not set");
00101 return false;
00102 }
00103
00104 filename = graspitRoot + QString("/models/robots/") + QString(argv[2]) + QString("/")
00105 + QString(argv[2]) + QString(".xml");
00106 mHand = (Hand*)ivmgr->getWorld()->importRobot(filename);
00107 if ( !mHand ) {
00108 DBGAF(mLogStream,"DBase planner: failed to load robot name " << argv[2] << ", or it is not a Hand");
00109 return false;
00110 }
00111 if (mHand->getNumVirtualContacts()==0) {
00112 DBGAF(mLogStream,"Specified hand does not have virtual contacts defined");
00113 DBGAF(mLogStream,"Hint: make sure capitalization in robot name is correct");
00114 DBGAF(mLogStream,"(i.e. HumanHand20DOF, Barrett)");
00115 getchar();
00116 return false;
00117 }
00118 filename = QString(argv[3]);
00119 mObject = static_cast<GraspableBody*>(ivmgr->getWorld()->importBody("GraspableBody",filename));
00120 ((GraspableBody*)mObject)->showAxes(false);
00121
00122 if (!mObject) {
00123 DBGAF(mLogStream,"Failed to load graspable body from file " << argv[3]);
00124 return false;
00125 }
00126 mMaxTime = atof(argv[4]);
00127 if (mMaxTime <=0) {
00128 DBGAF(mLogStream,"Wrong time budget specification: " << mMaxTime );
00129 return false;
00130 }
00131 DBGAF(mLogStream,"Time: " << mMaxTime << " sec");
00132
00133
00134 numOfGraspsGoal = atoi(argv[7]);
00135 if (numOfGraspsGoal <=0) {
00136 DBGAF(mLogStream,"Wrong number of grasps specification: " << numOfGraspsGoal );
00137 return false;
00138 }
00139 DBGAF(mLogStream,"numOfGraspsGoal: " << numOfGraspsGoal << " grasps");
00140
00141 energyConstraint = atof(argv[8]);
00142 DBGAF(mLogStream,"energyConstraint: " << energyConstraint);
00143
00144 if (mType == GRIPPER) {
00145 mScanDirectory = new char[1000];
00146 strcpy(mScanDirectory, argv[9]);
00147 QString testfile = QString(mScanDirectory) + QString("scan_log.txt");
00148 FILE *tf = fopen(testfile.latin1(),"a");
00149 if (!tf) {
00150 DBGAF(mLogStream,"Failed scan directory test: " << testfile.latin1());
00151 return false;
00152 }
00153 fprintf(tf,"Starting object: %s\n",mObject->getName().latin1());
00154 fclose(tf);
00155 }
00156
00157 if ( !strcmp(argv[5],"stderr") ) mResultFile = stderr;
00158 else if (!strcmp(argv[5],"stdout")) mResultFile = stdout;
00159 else mResultFile = fopen(argv[5],"w");
00160 if (!mResultFile) {
00161 DBGAF(mLogStream,"Failed to open result file " << argv[5]);
00162 return false;
00163 }
00164 DBGAF(mLogStream,"DBasePlanner init successfull. Robot " << argv[2] << " and object " << argv[3]);
00165 ivmgr->getViewer()->viewAll();
00166 return true;
00167 }
00168
00169 void DBaseBatchPlanner::usage()
00170 {
00171 DBGA("DataBaseBatch planner usage:");
00172 DBGA(" graspit dbase robot_name body_file time_budget_in_seconds result_file log_file max_num_grasps min_grasp_energy [scan_sim_dir]");
00173 }
00174
00175 bool DBaseBatchPlanner::startPlanner()
00176 {
00177 if (!mHand || !mObject || mMaxTime <= 0) {
00178 DBGA("Can not start batch planner; Hand or Object or Time not set");
00179 return false;
00180 }
00181
00182 GraspPlanningState seed(mHand);
00183 seed.setObject(mObject);
00184 seed.setPositionType(SPACE_AXIS_ANGLE);
00185 seed.setPostureType(POSE_EIGEN);
00186 seed.setRefTran(mObject->getTran());
00187 seed.reset();
00188
00189
00190
00191
00192 if (mType == DEXTEROUS) {
00193
00194 mPlanner = new GuidedPlanner(mHand);
00195
00196 int numChildren;
00197
00198 #ifdef WIN32
00199 QString numCPU = QString(getenv("NUMBER_OF_PROCESSORS"));
00200 if (numCPU.isNull()) {
00201 DBGAF(mLogStream,"NUMBER_OF_PROCESSORS env var. not specified; using 1 child thread");
00202 numChildren = 1;
00203 } else {
00204 numChildren = numCPU.toInt();
00205 }
00206 if (numChildren <= 0) {
00207 DBGAF(mLogStream,"Can not understand NUMBER_OF_PROCESSORS: " << numCPU.latin1());
00208 }
00209 #else
00210
00211 numChildren = 2;
00212 #endif
00213
00214 if (numChildren <= 0) {
00215 numChildren = 1;
00216 } else {
00217 numChildren --;
00218 if (!numChildren) numChildren = 1;
00219 }
00220
00221
00222 DBGAF(mLogStream,"Using up to " << numChildren << " child threads");
00223 ((GuidedPlanner*)mPlanner)->setMaxChildren(numChildren);
00224 } else if (mType == GRIPPER) {
00225
00226 mPlanner = new LoopPlanner(mHand);
00227 mPlanner->setEnergyType(ENERGY_CONTACT);
00228 }
00229
00230 mPlanner->setContactType(CONTACT_PRESET);
00231 mPlanner->setMaxSteps(65000);
00232 mPlanner->setRepeat(true);
00233 mPlanner->setMaxTime(mMaxTime);
00234
00235 static_cast<SimAnnPlanner*>(mPlanner)->setModelState(&seed);
00236 if (!mPlanner->resetPlanner()) {
00237 DBGA("Failed to reset planner");
00238 return false;
00239 }
00240
00241 QObject::connect(mPlanner, SIGNAL(update()), this, SLOT(plannerUpdate()));
00242 QObject::connect(mPlanner, SIGNAL(complete()), this, SLOT(plannerComplete()));
00243 mPlanner->startPlanner();
00244 return true;
00245 }
00246
00247 void DBaseBatchPlanner::plannerUpdate()
00248 {
00249 static int lastSolution = 0;
00250 bool newSol = false;
00251
00252
00253 for (int i=lastSolution; i<mPlanner->getListSize();i++){
00254 processSolution(mPlanner->getGrasp(i));
00255 newSol = true;
00256 }
00257
00258 if (newSol) {
00259
00260 fflush(mResultFile);
00261 if (mType == DEXTEROUS) {
00262
00263 mPlanner->clearSolutions();
00264 lastSolution = 0;
00265 } else if (mType == GRIPPER) {
00266
00267 lastSolution = mPlanner->getListSize();
00268 }
00269 }
00270 }
00271
00272 void DBaseBatchPlanner::plannerComplete()
00273 {
00274 if (mPlanner->isActive()) {
00275 DBGAF(mLogStream,"Planner is not finished!");
00276 return;
00277 }
00278
00279 plannerUpdate();
00280
00281 DBGAF(mLogStream,"Planner completed; starting shutdown");
00282
00283 if (mType == GRIPPER) {
00284 ivmgr->getWorld()->destroyElement(mHand,false);
00285 fprintf(stderr,"Taking scans...\n");
00286 takeScans();
00287 }
00288
00289 if (mResultFile!=stderr && mResultFile!=stdout) fclose(mResultFile);
00290
00291
00292
00293 mTimerSensor = new SoTimerSensor(sensorCB, this);
00294 mTimerSensor->setInterval( SbTime( 3.0 ));
00295 mTimerSensor->schedule();
00296 }
00297
00298 void DBaseBatchPlanner::sensorCB(void *data, SoSensor*)
00299 {
00300 DBaseBatchPlanner *planner = (DBaseBatchPlanner*)data;
00301 GraspItGUI *gui = planner->mGui;
00302 DBGAF(planner->mLogStream,"Shutdown signal received");
00303 delete planner;
00304 gui->exitMainLoop();
00305 }
00306
00307 void DBaseBatchPlanner::processSolution(const GraspPlanningState *s)
00308 {
00309
00310
00311
00312 if (s->getEnergy() > energyConstraint){
00313 DBGAF(mLogStream,"Solution with energy to be thrown: " << s->getEnergy());
00314 return;
00315 }
00316
00317 static SearchEnergy *se = NULL;
00318 if (!se) {
00319 se = new SearchEnergy();
00320
00321 switch(mType) {
00322 case DEXTEROUS:
00323 se->setType(ENERGY_STRICT_AUTOGRASP);
00324 break;
00325 case GRIPPER:
00326 se->setType(ENERGY_CONTACT);
00327 se->setContactType(CONTACT_PRESET);
00328 break;
00329 }
00330 }
00331 DBGAF(mLogStream,"Solution with energy: " << s->getEnergy());
00332
00333 GraspPlanningState *sol = new GraspPlanningState(s);
00334
00335
00336
00337 sol->setPositionType(SPACE_COMPLETE,true);
00338
00339
00340 sol->setPostureType(POSE_DOF,true);
00341
00342
00343 fprintf(mResultFile,"pre-grasp\n");
00344 sol->writeToFile(mResultFile);
00345
00346
00347 if (mType == DEXTEROUS) {
00348
00349
00350 bool legal; double energy;
00351
00352
00353 se->analyzeState(legal,energy,sol,false);
00354 if (!legal) {
00355 DBGAF(mLogStream,"buru Illegal solution! This should not be!");
00356 }
00357
00358
00359 sol->saveCurrentHandState();
00360
00361
00362 fprintf(mResultFile,"grasp\n");
00363 sol->writeToFile(mResultFile);
00364
00365
00366
00367 fprintf(mResultFile,"contacts\n");
00368 writeContactsToFile(sol->getHand(), sol->getObject());
00369 }
00370
00371 numOfGrasps++;
00372 printf("\nup to now, %d out of %d grasps have been found\n",numOfGrasps, numOfGraspsGoal);
00373
00374
00375 if(numOfGrasps == numOfGraspsGoal)
00376 {
00377 mMaxTime = 10;
00378 printf("begin to leave...");
00379 DBGAF(mLogStream, numOfGraspsGoal);
00380 mPlanner->setMaxTime(mMaxTime);
00381 }
00382
00383
00384 delete sol;
00385 }
00386
00387 void DBaseBatchPlanner::writeContactsToFile(Hand *hand, Body *object)
00388 {
00389 int f,l;
00390 std::list<Contact *>::iterator cp;
00391 std::list<Contact *> contactList;
00392
00393 contactList = hand->getPalm()->getContacts();
00394 for (cp=contactList.begin();cp!=contactList.end();cp++){
00395 if ((*cp)->getBody2()==object) {
00396
00397 position pos = (*cp)->getMate()->getPosition();
00398 fprintf(mResultFile,"%f %f %f\n",pos.x(), pos.y(), pos.z());
00399 }
00400 }
00401
00402 for(f=0;f<hand->getNumFingers();f++) {
00403 for (l=0;l<hand->getFinger(f)->getNumLinks();l++) {
00404 contactList = hand->getFinger(f)->getLink(l)->getContacts();
00405 for (cp=contactList.begin();cp!=contactList.end();cp++){
00406 if ((*cp)->getBody2()==object) {
00407 position pos = (*cp)->getMate()->getPosition();
00408 fprintf(mResultFile,"%f %f %f\n",pos.x(), pos.y(), pos.z());
00409 }
00410 }
00411 }
00412 }
00413
00414 }
00415
00416
00417
00418
00419 void DBaseBatchPlanner::takeScans()
00420 {
00421 ScanSimulator sim;
00422
00423 sim.setOptics(-45.0 , 45.0 , 400 ,
00424 -45.0 , 45.0 , 400 );
00425 sim.setType(ScanSimulator::WORLD_COORDINATES);
00426
00427 int numAltitudes = 3;
00428 float altitudes[3] = {(float)M_PI/6.0f, (float)M_PI/3.0f, (float)M_PI/2.0f };
00429 int numSamples[3] = {8, 4, 1};
00430
00431 float distance = 1000;
00432
00433 std::vector<position> cloud;
00434 std::vector<RawScanPoint> rawData;
00435
00436 for (int i=0; i<numAltitudes; i++) {
00437 float theta = altitudes[i];
00438 float phi_step = M_PI / numSamples[i];
00439
00440 for (int j=0; j<numSamples[i]; j++) {
00441 float phi = phi_step * j;
00442
00443 vec3 loc( distance * cos(theta) * cos(phi),
00444 distance * cos(theta) * sin(phi),
00445 distance * sin(theta) );
00446
00447 vec3 dir = -1 * normalise(loc);
00448 vec3 up(0,0,1);
00449 sim.setPosition(loc, dir, up, ScanSimulator::STEREO_CAMERA);
00450
00451 cloud.clear();
00452 rawData.clear();
00453
00454 sim.scan(&cloud, &rawData);
00455
00456 writeCloudToFile(i, j, cloud);
00457 vec3 foo, trueUp;
00458 position foop;
00459 sim.getPosition(foop,foo,trueUp);
00460 writeRawToFile(i, j, rawData, loc, dir, trueUp);
00461 }
00462 }
00463 }
00464
00465 void DBaseBatchPlanner::writeCloudToFile( int i, int j, const std::vector<position> &cloud)
00466 {
00467 QString filename = QString(mScanDirectory) + mObject->getName() + QString("_cloud");
00468 QString n;
00469 n.setNum(i);
00470 filename = filename + n;
00471 n.setNum(j);
00472 filename = filename + QString("_") + n + QString(".txt");
00473
00474 FILE *f = fopen(filename.latin1(),"w");
00475 if (!f) {
00476 DBGAF(mLogStream,"Failed to open file " << filename.latin1());
00477 fprintf(stderr,"Failed to open scan file\n");
00478 return;
00479 }
00480
00481 fprintf(f,"%d\n",(int)cloud.size());
00482 for (int k=0; k<(int)cloud.size(); k++) {
00483 fprintf(f,"%f %f %f -1\n",cloud[k].x(), cloud[k].y(), cloud[k].z());
00484 }
00485
00486 writeSolutionsToFile(f);
00487 fclose(f);
00488 }
00489
00490 void DBaseBatchPlanner::writeRawToFile( int i, int j, const std::vector<RawScanPoint> &rawData,
00491 vec3 loc, vec3 dir, vec3 up)
00492 {
00493 QString filename = QString(mScanDirectory) + mObject->getName() + QString("_raw");
00494 QString n;
00495 n.setNum(i);
00496 filename = filename + n;
00497 n.setNum(j);
00498 filename = filename + QString("_") + n + QString(".txt");
00499
00500 FILE *f = fopen(filename.latin1(),"w");
00501 if (!f) {
00502 DBGAF(mLogStream,"Failed to open file " << filename.latin1());
00503 fprintf(stderr,"Failed to open scan file\n");
00504 return;
00505 }
00506
00507 fprintf(f,"%f %f %f\n",loc.x(), loc.y(), loc.z());
00508 fprintf(f,"%f %f %f\n",dir.x(), dir.y(), dir.z());
00509 fprintf(f,"%f %f %f\n",up.x(), up.y(), up.z());
00510 fprintf(f,"%d\n",(int)rawData.size());
00511
00512 for (int k=0; k<(int)rawData.size(); k++) {
00513 fprintf(f,"%f %f ",rawData[k].hAngle, rawData[k].vAngle);
00514 fprintf(f,"%f %f %f ",rawData[k].dx, rawData[k].dy, rawData[k].dz);
00515 fprintf(f,"%f\n",rawData[k].distance);
00516 }
00517
00518 writeSolutionsToFile(f);
00519 fclose(f);
00520 }
00521
00522 void DBaseBatchPlanner::writeSolutionsToFile(FILE *f)
00523 {
00524
00525 numOfGrasps = 0;
00526 FILE *temp = mResultFile;
00527 mResultFile = f;
00528 for (int i=0; i<mPlanner->getListSize();i++){
00529 processSolution(mPlanner->getGrasp(i));
00530 }
00531 mResultFile = temp;
00532
00533 }