00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "eigenTorques.h"
00018
00019 #include <iostream>
00020 #include <fstream>
00021 #include <limits>
00022
00023 #include "robot.h"
00024 #include "world.h"
00025 #include "graspitGUI.h"
00026 #include "ivmgr.h"
00027 #include "grasp.h"
00028 #include "mcGrip.h"
00029
00030 #include "DBase/DBPlanner/grasp.h"
00031 #include "DBase/graspit_db_grasp.h"
00032 #include "DBase/graspit_db_model.h"
00033 #include "DBase/DBPlanner/sql_database_manager.h"
00034 #include "searchState.h"
00035 #include "matrix.h"
00036
00037 #include "debug.h"
00038
00041 CGDBGraspProcessor::CGDBGraspProcessor(Hand *h) : mHand(h)
00042 {
00043 mDbMgr = graspItGUI->getIVmgr()->getDBMgr();
00044 mProcessor = new EigenTorqueComputer(mHand);
00045 mProcessor = new McGripOptimizer(mHand);
00046
00047
00048 mProcessedGrasps = 0;
00049 mMaxGrasps = -1;
00050
00051 }
00052
00053 void
00054 CGDBGraspProcessor::processGrasps(std::vector<db_planner::Grasp*> *grasps)
00055 {
00056 std::vector<db_planner::Grasp*>::iterator it;
00057 for (it=grasps->begin(); it!=grasps->end(); it++) {
00058 if (mMaxGrasps >=0 && mProcessedGrasps >= mMaxGrasps) break;
00059
00060 static_cast<GraspitDBGrasp*>(*it)->getFinalGraspPlanningState()->execute();
00061
00062
00063
00064
00065
00066
00067
00068
00069 mHand->getWorld()->findAllContacts();
00070 mHand->getWorld()->updateGrasps();
00071 int numContacts = mHand->getGrasp()->getNumContacts();
00072 DBGA("Processing grasp number " << mProcessedGrasps << "; " << numContacts << " contacts.");
00073 mProcessor->processGrasp();
00074
00075
00076 bool transposeGrasp = true;
00077 if (transposeGrasp) {
00078
00079 double dofs[6];
00080 mHand->getDOFVals(dofs);
00081 for (int j=0; j<3; j++) {
00082 std::swap(dofs[j], dofs[3+j]);
00083 }
00084 mHand->forceDOFVals(dofs);
00085
00086 transf handTran = rotate_transf(M_PI, vec3::Z);
00087 transf newTran = mHand->getApproachTran().inverse() * handTran *
00088 mHand->getApproachTran() * mHand->getTran();
00089 mHand->setTran(newTran);
00090 if (!mHand->getWorld()->noCollision()) {
00091 DBGA("Transposed grasp in COLLISION!!!");
00092 assert(0);
00093 }
00094 mHand->getWorld()->findAllContacts();
00095 mHand->getWorld()->updateGrasps();
00096 if (mHand->getGrasp()->getNumContacts() != numContacts) {
00097 DBGA("Transposed grasp has " << mHand->getGrasp()->getNumContacts() << " contacts.");
00098 continue;
00099 assert(0);
00100 }
00101 DBGA("Processing grasp transpose");
00102 mProcessor->processGrasp();
00103 }
00104
00105 mProcessedGrasps ++;
00106 }
00107 }
00108
00109 void
00110 CGDBGraspProcessor::run()
00111 {
00112 std::vector<db_planner::Model*> models;
00113
00114 mDbMgr->ModelList(&models, db_planner::FilterList::OLD_STYLE_IV);
00115 std::vector<db_planner::Model*>::iterator it;
00116 GraspableBody *currentModel = NULL;
00117
00118 mProcessor->reset();
00119 for (it=models.begin(); it!=models.end(); it++) {
00120 if (mMaxGrasps >=0 && mProcessedGrasps >= mMaxGrasps) break;
00121
00122
00123 if (currentModel) {
00124 mHand->getWorld()->destroyElement(currentModel, false);
00125 currentModel = NULL;
00126 }
00127 GraspitDBModel *gModel = dynamic_cast<GraspitDBModel*>(*it);
00128 if (!gModel) {
00129 assert(0);
00130 continue;
00131 }
00132
00133 if (!gModel->geometryLoaded()) {
00134 gModel->load(mHand->getWorld());
00135 }
00136 gModel->getGraspableBody()->addToIvc();
00137 mHand->getWorld()->addBody(gModel->getGraspableBody());
00138 currentModel = gModel->getGraspableBody();
00139
00140 std::vector<db_planner::Grasp*> grasps;
00141 if(!mDbMgr->GetGrasps(*gModel,GraspitDBGrasp::getHandDBName(mHand).toStdString(), &grasps)){
00142 DBGP("Load grasps failed - no grasps found for model " << gModel->ModelName());
00143 continue;
00144 }
00145
00146 std::vector<db_planner::Grasp*>::iterator it2 = grasps.begin();
00147 while (it2!=grasps.end()) {
00148 if( QString((*it2)->GetSource().c_str()) == "HUMAN_REFINED") {
00149 it2++;
00150 } else {
00151 delete (*it2);
00152 it2 = grasps.erase(it2);
00153 }
00154 }
00155
00156 processGrasps(&grasps);
00157
00158 while (!grasps.empty()) {
00159 delete grasps.back();
00160 grasps.pop_back();
00161 }
00162 }
00163
00164 mProcessor->finalize();
00165
00166 if (currentModel) {
00167 mHand->getWorld()->destroyElement(currentModel, false);
00168 }
00169 while(!models.empty()) {
00170 DBGA("Deleting model");
00171 delete models.back();
00172 DBGA("Model deleted");
00173 models.pop_back();
00174 }
00175 }
00176
00177 void
00178 EigenTorqueComputer::reset()
00179 {
00180 mOptimalTorques.clear();
00181 mNumOptimal = mNumUnfeasible = mNumErrors = 0;
00182 }
00183
00184 void
00185 EigenTorqueComputer::processGrasp()
00186 {
00187 int result;
00188 if (!mHand->isA("McGrip")) {
00189 Matrix tau(Matrix::ZEROES<Matrix>(mHand->getNumJoints(),1));
00190 result = mHand->getGrasp()->computeQuasistaticForcesAndTorques(&tau, Grasp::GRASP_FORCE_EXISTENCE);
00191 if (!result) {
00192 mOptimalTorques.push_back(tau);
00193 }
00194 } else {
00195 Matrix p(8,1);
00196 double objVal;
00197 result = static_cast<McGripGrasp*>(mHand->getGrasp())->tendonAndHandOptimization(&p, objVal);
00198 }
00199 if (!result) {
00200 DBGA("Optimization success");
00201 mNumOptimal++;
00202 } else if (result > 0) {
00203 DBGA("Optimized problem not feasible");
00204 mNumUnfeasible++;
00205 } else {
00206 DBGA("Error in computation!");
00207 mNumErrors++;
00208 }
00209 }
00210
00211 void
00212 EigenTorqueComputer::finalize()
00213 {
00214 DBGA(" Optimal: " << mNumOptimal);
00215 DBGA("Unfeasible: " << mNumUnfeasible);
00216 DBGA(" Errors: " << mNumErrors);
00217
00218 if (!mHand->isA("McGrip")) {
00219 std::fstream outFile;
00220 outFile.open("torques.txt", std::ios::out);
00221 std::vector<Matrix>::iterator it;
00222 for (it=mOptimalTorques.begin(); it!=mOptimalTorques.end(); it++) {
00223 outFile << (*it).transposed() << std::endl;
00224 }
00225 outFile.close();
00226 DBGA("Results output to file torques.txt");
00227 }
00228 }
00229
00230 void
00231 McGripOptimizer::clearList(std::list<Matrix*> &list) {
00232 while (!list.empty()) {
00233 delete list.back();
00234 list.pop_back();
00235 }
00236 }
00237
00238 void
00239 McGripOptimizer::printList(const std::list<Matrix*> &list, FILE *fp)
00240 {
00241 std::list<Matrix*>::const_iterator it;
00242 for(it = list.begin(); it!=list.end(); it++) {
00243 (*it)->print(fp);
00244 fprintf(fp,"\n");
00245 }
00246 }
00247
00248
00249 void
00250 McGripOptimizer::reset()
00251 {
00252 clearList(JTD_negI_list);
00253 clearList(NegB_list);
00254 clearList(GO_list);
00255 clearList(FO_list);
00256 clearList(SO_list);
00257 clearList(Th_list);
00258 clearList(lowerBounds_list);
00259 clearList(upperBounds_list);
00260 }
00261
00262 void
00263 McGripOptimizer::processGrasp()
00264 {
00265
00266 std::list<Contact*> contacts;
00267 for (int i=0; i<mHand->getGrasp()->getNumContacts(); i++) {
00268 contacts.push_back(mHand->getGrasp()->getContact(i));
00269 }
00270
00271 std::list<Joint*> joints;
00272 for (int c=0; c<mHand->getNumChains(); c++) {
00273 std::list<Joint*> chainJoints = mHand->getChain(c)->getJoints();
00274 joints.insert(joints.end(), chainJoints.begin(), chainJoints.end());
00275 }
00276
00277
00278
00279 Matrix J(mHand->getGrasp()->contactJacobian(joints, contacts));
00280 Matrix D(Contact::frictionForceBlockMatrix(contacts));
00281 Matrix F(Contact::frictionConstraintsBlockMatrix(contacts));
00282 Matrix R(Contact::localToWorldWrenchBlockMatrix(contacts));
00283 Matrix G(mHand->getGrasp()->graspMapMatrix(R,D));
00284 Matrix JTran(J.transposed());
00285 Matrix JTD(JTran.rows(), D.cols());
00286 matrixMultiply(JTran, D, JTD);
00287
00288
00289 Matrix *B, *a;
00290 static_cast<McGrip*>(mHand)->getRoutingMatrices(&B, &a);
00291
00292
00293
00294 Matrix *JTD_negI = new Matrix( Matrix::BLOCKROW<Matrix>(JTD, Matrix::NEGEYE(a->rows(), a->rows())) );
00295 JTD_negI_list.push_back(JTD_negI);
00296
00297 Matrix *NegB = new Matrix(*B);
00298 NegB->multiply(-1.0);
00299 NegB_list.push_back(NegB);
00300
00301 Matrix *GO = new Matrix( Matrix::BLOCKROW<Matrix>(G, Matrix::ZEROES<Matrix>(G.rows(), a->rows())) );
00302 GO_list.push_back(GO);
00303
00304 Matrix *FO = new Matrix( Matrix::BLOCKROW<Matrix>(F, Matrix::ZEROES<Matrix>(F.rows(), a->rows())) );
00305 FO_list.push_back(FO);
00306
00307 Matrix S(1, JTD.cols());
00308 S.setAllElements(1.0);
00309 Matrix *SO = new Matrix( Matrix::BLOCKROW<Matrix>(S, Matrix::ZEROES<Matrix>(1, a->rows())) );
00310 SO_list.push_back(SO);
00311
00312 Matrix *lowerBounds = new Matrix( Matrix::BLOCKCOLUMN<Matrix>(Matrix::ZEROES<Matrix>(JTD.cols(),1), *a) );
00313 lowerBounds_list.push_back(lowerBounds);
00314 Matrix *upperBounds = new Matrix( Matrix::BLOCKCOLUMN<Matrix>(Matrix::MAX_VECTOR(JTD.cols()), *a) );
00315 upperBounds_list.push_back(upperBounds);
00316
00317
00318 Matrix *Th;
00319 static_cast<McGrip*>(mHand)->getJointDisplacementMatrix(&Th);
00320 Th_list.push_back(Th);
00321
00322 delete a;
00323 delete B;
00324 }
00325
00360 void
00361 McGripOptimizer::finalize()
00362 {
00363 DBGA("Processing " << JTD_negI_list.size() << " matrices");
00364
00365 int bCols = NegB_list.front()->cols();
00366
00367
00368 SparseMatrix Q( Matrix::BLOCKROW<SparseMatrix>( Matrix::BLOCKDIAG<SparseMatrix>(&JTD_negI_list),
00369 Matrix::BLOCKCOLUMN<SparseMatrix>(&NegB_list) ) );
00370
00371
00372 SparseMatrix GO_block( Matrix::BLOCKDIAG<SparseMatrix>(&GO_list) );
00373 SparseMatrix SO_block( Matrix::BLOCKDIAG<SparseMatrix>(&SO_list) );
00374 assert(GO_block.cols() == SO_block.cols());
00375
00376 bool optimize_r_d;
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 SparseMatrix LeftHandEq( Matrix::ZEROES<SparseMatrix>(GO_block.rows() + SO_block.rows() + 1,
00388 GO_block.cols() + bCols) );
00389 Matrix rightHandEq( Matrix::ZEROES<Matrix>(GO_block.rows() + SO_block.rows() + 1, 1) );
00390 optimize_r_d = true;
00391
00392 LeftHandEq.copySubMatrix(0, 0, GO_block);
00393 LeftHandEq.copySubMatrix(GO_block.rows(), 0, SO_block);
00394
00395 for (int i=0; i<SO_block.rows(); i++) {
00396 rightHandEq.elem( GO_block.rows() + i, 0) = 1.0;
00397 }
00398
00399 if (optimize_r_d) {
00400 Matrix rd(1,2);
00401 rd.setAllElements(1.0);
00402
00403 LeftHandEq.copySubMatrix( LeftHandEq.rows()-1, LeftHandEq.cols()-2, rd);
00404
00405 rightHandEq.elem( rightHandEq.rows()-1, 0) = 25.0;
00406 }
00407
00408
00409 SparseMatrix FO_block( Matrix::BLOCKDIAG<SparseMatrix>(&FO_list) );
00410
00411 SparseMatrix LeftHandInEq( Matrix::ZEROES<SparseMatrix>(FO_block.rows(), FO_block.cols() + bCols) );
00412 LeftHandInEq.copySubMatrix(0, 0, FO_block);
00413
00414 Matrix rightHandInEq( Matrix::ZEROES<Matrix>(FO_block.rows(), 1) );
00415
00416
00417
00418 Matrix lowerParameterBounds(8, 1);
00419 Matrix upperParameterBounds(8, 1);
00420
00421 for (int i=0; i<6; i++) {
00422 lowerParameterBounds.elem(i,0) = -5.0;
00423 upperParameterBounds.elem(i,0) = 5.0;
00424 }
00425 if (!optimize_r_d) {
00426
00427 lowerParameterBounds.elem(6,0) = static_cast<McGrip*>(mHand)->getJointRadius();
00428 upperParameterBounds.elem(6,0) = static_cast<McGrip*>(mHand)->getJointRadius();
00429
00430 lowerParameterBounds.elem(7,0) = static_cast<McGrip*>(mHand)->getLinkLength();
00431 upperParameterBounds.elem(7,0) = static_cast<McGrip*>(mHand)->getLinkLength();
00432 } else {
00433
00434 lowerParameterBounds.elem(6,0) = 3.0;
00435 upperParameterBounds.elem(6,0) = 10.0;
00436
00437 lowerParameterBounds.elem(7,0) = 15.0;
00438 upperParameterBounds.elem(7,0) = 22.0;
00439 }
00440
00441
00442 Matrix lowerBounds( Matrix::BLOCKCOLUMN<Matrix>( Matrix::BLOCKCOLUMN<Matrix>(&lowerBounds_list),
00443 lowerParameterBounds ) );
00444 Matrix upperBounds( Matrix::BLOCKCOLUMN<Matrix>( Matrix::BLOCKCOLUMN<Matrix>(&upperBounds_list),
00445 upperParameterBounds ) );
00446
00447 DBGA("Matrices assembled. Q size: " << Q.rows() << " by " << Q.cols());
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 Matrix solution(Q.cols(), 1);
00480
00481 DBGA("Calling solver");
00482 double objVal;
00483 int result = factorizedQPSolver(Q,
00484 LeftHandEq, rightHandEq,
00485 LeftHandInEq, rightHandInEq,
00486 lowerBounds, upperBounds,
00487 solution, &objVal);
00488 DBGA("Solver complete. Result: " << result << ". Objective: " << objVal);
00489
00490
00491 Matrix parameters(8,1);
00492 parameters.copySubBlock(0, 0, 8, 1, solution, solution.rows()-8, 0);
00493 DBGA("Parameters:\n" << parameters);
00494
00495 DBGA("Building joint stiffness optimization matrices");
00496
00497 SparseMatrix QTh( Matrix::BLOCKROW<SparseMatrix>( Q, Matrix::BLOCKCOLUMN<SparseMatrix>(&Th_list) ) );
00498 SparseMatrix LEqTh( Matrix::BLOCKROW<SparseMatrix>( LeftHandEq,
00499 Matrix::ZEROES<SparseMatrix>(LeftHandEq.rows(), 6) ) );
00500 SparseMatrix LInEqTh( Matrix::BLOCKROW<SparseMatrix>( LeftHandInEq,
00501 Matrix::ZEROES<SparseMatrix>(LeftHandInEq.rows(), 6) ) );
00502
00503 Matrix lowerParameterBoundsTh(14, 1);
00504 Matrix upperParameterBoundsTh(14, 1);
00505
00506
00507
00508
00509 lowerParameterBoundsTh.copySubMatrix(0, 0, lowerParameterBounds);
00510 upperParameterBoundsTh.copySubMatrix(0, 0, upperParameterBounds);
00511
00512
00513
00514
00515
00516 for (int i=0; i<6; i++) {
00517 lowerParameterBoundsTh.elem(8+i, 0) = 1.0;
00518 upperParameterBoundsTh.elem(8+i, 0) = 2.0;
00519 }
00520
00521 Matrix lowerBoundsTh( Matrix::BLOCKCOLUMN<Matrix>( Matrix::BLOCKCOLUMN<Matrix>(&lowerBounds_list),
00522 lowerParameterBoundsTh ) );
00523 Matrix upperBoundsTh( Matrix::BLOCKCOLUMN<Matrix>( Matrix::BLOCKCOLUMN<Matrix>(&upperBounds_list),
00524 upperParameterBoundsTh ) );
00525 Matrix solutionTh(QTh.cols(), 1);
00526
00527 DBGA("Calling solver for joint stiffness");
00528 result = factorizedQPSolver(QTh,
00529 LEqTh, rightHandEq,
00530 LInEqTh, rightHandInEq,
00531 lowerBoundsTh, upperBoundsTh,
00532 solutionTh, &objVal);
00533 DBGA("Solver complete. Result: " << result << ". Objective: " << objVal);
00534
00535
00536 Matrix parametersTh(14,1);
00537 parametersTh.copySubBlock(0, 0, 14, 1, solutionTh, solutionTh.rows()-14, 0);
00538 DBGA("Parameters:\n" << parametersTh);
00539 }
00540
00541 void McGripAnalyzer::processGrasp()
00542 {
00543 Matrix p(8,1);
00544 double objVal;
00545 int result = static_cast<McGripGrasp*>(mHand->getGrasp())->tendonAndHandOptimization(&p, objVal);
00546
00547 if (result < 0) {
00548 fprintf(fp,"-1.0\n");
00549 DBGA("Computation ERROR");
00550 } else {
00551 fprintf(fp,"%f\n",objVal);
00552 DBGA("Unbalanced: " << objVal);
00553 }
00554 }