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 "gloveInterface.h"
00027
00028 #include "robot.h"
00029
00030 #ifdef HARDWARE_LIB
00031 #include "CyberGlove.h"
00032 #else
00033 #define N_SENSOR_VALUES 24
00034 #endif
00035
00036 #include "world.h"
00037 #include "matvec3D.h"
00038 #include "jacobian.h"
00039
00040 #ifdef MKL
00041 #include "mkl_wrappers.h"
00042 #else
00043 #include "lapack_wrappers.h"
00044 #endif
00045
00046 #include "debug.h"
00047
00048
00049 void CalibrationPose::init(int size)
00050 {
00051 if (size < 0) {
00052 fprintf(stderr,"Wrong size of calibration pose\n");
00053 mSize = 0;
00054 } else {
00055 mSize = size;
00056 }
00057 if (mSize>0) {
00058 jointValues = new double[size];
00059 sensorValues = new int[size];
00060 sensorMap = new int[size];
00061 }
00062 recordedDistance = 0;
00063 mSize = size;
00064 jointsSet = false;
00065 sensorsSet = false;
00066 mapSet = false;
00067 poseSet = false;
00068 mTransf = transf::IDENTITY;
00069 }
00070
00071 CalibrationPose::CalibrationPose(int size)
00072 {
00073 init(size);
00074 }
00075
00076 CalibrationPose::CalibrationPose(int size, double *joints, int *map)
00077 {
00078 init(size);
00079 setAllJointValues(joints);
00080 for (int i=0; i<size; i++) {
00081 jointValues[i] = jointValues[i] * 3.14159 / 180.0;
00082 }
00083 setAllMaps(map);
00084 }
00085
00086 CalibrationPose::~CalibrationPose()
00087 {
00088 delete [] jointValues;
00089 delete [] sensorValues;
00090 delete [] sensorMap;
00091 }
00092
00093 void CalibrationPose::readFromFile(FILE *fp)
00094 {
00095 int val;
00096 float floatVal;
00097 int j;
00098
00099 fscanf(fp,"%d",&mSize);
00100 init(mSize);
00101
00102 fscanf(fp,"%f",&floatVal);
00103 recordedDistance = floatVal;
00104
00105 fscanf(fp,"%d",&val);
00106 if (val) {
00107 for (j=0; j<mSize; j++) {
00108 fscanf(fp,"%d",&val);
00109 setSensorValue(j,val);
00110 }
00111 sensorsSet = true;
00112 } else sensorsSet = false;
00113
00114 fscanf(fp,"%d",&val);
00115 if (val) {
00116 for (j=0; j<mSize; j++) {
00117 fscanf(fp,"%d",&val);
00118 setMap(j,val);
00119 }
00120 mapSet = true;
00121 } else mapSet = false;
00122
00123 fscanf(fp,"%d",&val);
00124 if (val) {
00125 for (j=0; j<mSize; j++) {
00126 fscanf(fp,"%f",&floatVal);
00127 setJointValue(j,floatVal);
00128 }
00129 jointsSet = true;
00130 } else jointsSet = false;
00131
00132
00133 float x,y,z,w;
00134 fscanf(fp,"%f %f %f %f",&x, &y, &z, &w);
00135 Quaternion q(w,x,y,z);
00136 fscanf(fp,"%f %f %f",&x,&y,&z);
00137 vec3 t(x,y,z);
00138 mTransf.set(q,t);
00139 }
00140
00141 void CalibrationPose::writeToFile(FILE *fp)
00142 {
00143 fprintf(fp,"%d\n",getSize());
00144 fprintf(fp,"%f\n",recordedDistance);
00145
00146 if ( sensorsSet ) {
00147 fprintf(fp,"1\n");
00148 for (int i=0; i<getSize(); i++)
00149 fprintf(fp,"%d ",getSensorValue(i));
00150 fprintf(fp,"\n");
00151 } else fprintf(fp,"0\n");
00152 if (mapSet) {
00153 fprintf(fp,"1\n");
00154 for (int i=0; i<getSize(); i++)
00155 fprintf(fp,"%d ",getMap(i) );
00156 fprintf(fp,"\n");
00157 } else fprintf(fp,"0\n");
00158 if (jointsSet) {
00159 fprintf(fp,"1\n");
00160 for (int i=0; i<getSize(); i++)
00161 fprintf(fp,"%f ",getJointValue(i) );
00162 fprintf(fp,"\n");
00163 } else fprintf(fp,"0\n");
00164
00165 fprintf(fp,"%f %f %f %f\n",mTransf.rotation().x, mTransf.rotation().y,
00166 mTransf.rotation().z, mTransf.rotation().w);
00167
00168 fprintf(fp,"%f %f %f\n",mTransf.translation().x(), mTransf.translation().y(),
00169 mTransf.translation().z());
00170 }
00171
00173
00177 void loadPoseListFromFile(std::list<CalibrationPose*> *list, const char *filename)
00178 {
00179 FILE *fp = fopen(filename,"r");
00180 if (!fp) {
00181 fprintf(stderr,"Unable to open calibration file!\n");
00182 return;
00183 }
00184
00185 int nPoses;
00186 CalibrationPose *pose;
00187 fscanf(fp,"%d",&nPoses);
00188 fprintf(stderr,"Total of %d poses\n",nPoses);
00189 for (int i=0; i<nPoses; i++) {
00190 pose = new CalibrationPose(0);
00191 pose->readFromFile(fp);
00192 list->push_back(pose);
00193 }
00194 fclose(fp);
00195 }
00196
00198
00199 void writePoseListToFile(std::list<CalibrationPose*> *list, const char *filename)
00200 {
00201 FILE *fp = fopen(filename,"w");
00202 if (!fp) {
00203 fprintf(stderr,"Unable to open calibration file!\n");
00204 return;
00205 }
00206 fprintf(fp,"%d\n",list->size());
00207 std::list<CalibrationPose*>::iterator it;
00208 for (it = list->begin(); it!=list->end(); it++) {
00209 (*it)->writeToFile(fp);
00210 }
00211 fprintf(stderr,"Calibration poses saved\n");
00212 fclose(fp);
00213 }
00214
00215 bool CalibrationPose::isSet()
00216 {
00217 return poseSet;
00218 }
00219
00220 void CalibrationPose::setAllJointValues(double *jv)
00221 {
00222 for (int i=0; i<mSize; i++) {
00223 jointValues[i] = jv[i];
00224 }
00225 jointsSet = true;
00226 if (sensorsSet && mapSet) poseSet = true;
00227 }
00228
00229 void CalibrationPose::setJointValue(int j, double jv)
00230 {
00231 jointValues[j] = jv;
00232 jointsSet = true;
00233 }
00234
00235 void CalibrationPose::setAllSensorValues(int *sv)
00236 {
00237 for (int i=0; i<mSize; i++) {
00238 sensorValues[i] = sv[i];
00239 }
00240 sensorsSet = true;
00241 if (jointsSet && mapSet) poseSet = true;
00242 }
00243
00244 void CalibrationPose::setSensorValue(int i, int sv)
00245 {
00246 if (i>=mSize) {
00247 fprintf(stderr,"Error attempting to set calibration pose sensor value\n");
00248 return;
00249 }
00250 sensorValues[i] = sv;
00251 sensorsSet = true;
00252 }
00253
00254 void CalibrationPose::setAllMaps(int *m)
00255 {
00256 for (int i=0; i<mSize; i++) {
00257 sensorMap[i] = m[i];
00258 }
00259 mapSet = true;
00260 if (jointsSet && sensorsSet) poseSet = true;
00261 }
00262
00263 void CalibrationPose::setMap(int i, int mv)
00264 {
00265 if (i>=mSize) {
00266 fprintf(stderr,"Error attempting to set calibration pose map value\n");
00267 return;
00268 }
00269 sensorMap[i] = mv;
00270 mapSet = true;
00271 }
00272
00273
00274
00275 CData::CData(int nd, int ns)
00276 {
00277 nDOF = nd;
00278 nSensors = ns;
00279 slopes = new double[nDOF*nSensors];
00280 intercepts = new double[nDOF];
00281 reset();
00282 }
00283
00284 CData::~CData()
00285 {
00286 delete [] slopes;
00287 delete [] intercepts;
00288 }
00289
00290 void CData::reset()
00291 {
00292 int i;
00293 for (i=0; i<nDOF*nSensors; i++)
00294 slopes[i] = 0;
00295 for (i=0; i<nDOF; i++)
00296 intercepts[i] = 0;
00297 }
00298
00299 void CData::setSlope(int d, int s, double val)
00300 {
00301 if ( d>= nDOF || s >= nSensors) {
00302 fprintf(stderr,"Wrong addressing in Conversion Data\n");
00303 return;
00304 }
00305 slopes[d+s*nDOF] = val;
00306 }
00307
00308 void CData::setIntercept(int d, double val)
00309 {
00310 if ( d >= nDOF ) {
00311 fprintf(stderr,"Wrong addressing in Conversion Data\n");
00312 return;
00313 }
00314 intercepts[d] = val;
00315 }
00316
00317 void CData::addToSlope(int d, int s, double val)
00318 {
00319 if ( d>= nDOF || s >= nSensors) {
00320 fprintf(stderr,"Wrong addressing in Conversion Data\n");
00321 return;
00322 }
00323 slopes[d+s*nDOF] += val;
00324 }
00325
00326 void CData::addToIntercept(int d, double val)
00327 {
00328 if ( d >= nDOF ) {
00329 fprintf(stderr,"Wrong addressing in Conversion Data\n");
00330 return;
00331 }
00332 intercepts[d] += val;
00333 }
00334 double CData::getSlope(int d, int s)
00335 {
00336 if ( d>= nDOF || s >= nSensors) {
00337 fprintf(stderr,"Wrong addressing in Conversion Data\n");
00338 return 0;
00339 }
00340 return slopes[d+s*nDOF];
00341 }
00342
00343 double CData::getIntercept(int d)
00344 {
00345 if ( d >= nDOF ) {
00346 fprintf(stderr,"Wrong addressing in Conversion Data\n");
00347 return 0;
00348 }
00349 return intercepts[d];
00350 }
00351
00352
00353
00354 GloveInterface::GloveInterface(Robot *robot)
00355 {
00356 mRobot = robot;
00357 rawGlove = NULL;
00358
00359 savedDOFVals = new double[mRobot->getNumDOF()];
00360 mRobot->getDOFVals(savedDOFVals);
00361
00362 mData = new CData( mRobot->getNumDOF(), N_SENSOR_VALUES);
00363 currentPose = cPoses.begin();
00364 }
00365
00366 GloveInterface::~GloveInterface()
00367 {
00368 delete mData;
00369 delete [] savedDOFVals;
00370 }
00371
00372 void GloveInterface::setGlove(CyberGlove *glove)
00373 {
00374 rawGlove = glove;
00375 }
00376
00377 void GloveInterface::saveRobotPose()
00378 {
00379 mRobot->getDOFVals(savedDOFVals);
00380 }
00381
00382 void GloveInterface::revertRobotPose()
00383 {
00384 mRobot->forceDOFVals(savedDOFVals);
00385 }
00386
00387 int GloveInterface::instantRead()
00388 {
00389 #ifdef HARDWARE_LIB
00390 if (!rawGlove)
00391 return 0;
00392 if (!rawGlove->instantRead() )
00393 return 0;
00394 return 1;
00395 #else
00396 return 0;
00397 #endif
00398 }
00399
00403 void GloveInterface::setParameters(int s, int d, float sMin, float sMax, float dMin, float dMax)
00404 {
00405 fprintf(stderr,"sensor %d to DOF %d -- sMin %f sMax %f dMin %f dMax %f\n",s,d,sMin,sMax,dMin,dMax);
00406
00407 double slope = ( dMax - dMin ) / ( sMax - sMin );
00408 double intercept = dMin - sMin * slope;
00409 fprintf(stderr," Slope %f and intercept %f \n",slope,intercept);
00410 mData->setSlope(d, s, slope);
00411 mData->setIntercept(d, intercept);
00412 }
00413
00414
00415 void GloveInterface::setParameters(int s, int d, float slope, float intercept)
00416 {
00417 fprintf(stderr,"sensor %d to DOF %d -- slope %f and intercept %f \n", s, d, slope, intercept);
00418 mData->setSlope(d, s, slope);
00419 mData->setIntercept(d, intercept);
00420 }
00421
00422 int GloveInterface::getNumSensors()
00423 {
00424 return N_SENSOR_VALUES;
00425 }
00426
00427 bool GloveInterface::isDOFControlled(int d)
00428 {
00429 for (int s=0; s<N_SENSOR_VALUES; s++)
00430 if ( mData->getSlope(d,s) != 0 )
00431 return true;
00432 return false;
00433 }
00434
00439 float GloveInterface::getDOFValue(int d)
00440 {
00441 #ifdef HARDWARE_LIB
00442 float dofVal = 0;
00443 for ( int s=0; s<N_SENSOR_VALUES; s++) {
00444 int rawValue = rawGlove->getSensorValue ( s );
00445 dofVal += rawValue * mData->getSlope(d,s);
00446 }
00447 dofVal += mData->getIntercept(d);
00448 return dofVal;
00449 #else
00450 assert(0);
00451 (void*)&d;
00452 return 0;
00453 #endif
00454 }
00455
00460 float GloveInterface::getDOFValue(int d, int *rawValues)
00461 {
00462 float dofVal = 0;
00463 for ( int s=0; s<N_SENSOR_VALUES; s++) {
00464 int rawValue = rawValues[s];
00465 dofVal += rawValue * mData->getSlope(d,s);
00466 }
00467 dofVal += mData->getIntercept(d);
00468 return dofVal;
00469 }
00470
00471
00472
00473 void GloveInterface::initCalibration(int type)
00474 {
00475 if ( type == FIST || type == SIMPLE_THUMB || type == ABD_ADD) {
00476
00477 cPoses.clear();
00478 if (type == FIST ) {
00479
00480
00481
00482
00483
00484
00485 int map[] = {-1,-1,-1,-1, 1, 2, 3, 5, 6, 7,-1, 9, 10, 11,-1, 13, 14, 15,-1,-1,-1,-1,-1,-1};
00486 double cp1[] = {0, 0, 0, 0, 0, -6, -4.5, -5.4, 0, 0, 0, -5.6, -3.7, 2, 0, -9.2, -2.0, -4.5, 0, 0, 0, 0, 0, 0};
00487 double cp2[] = {0, 0, 0, 0, 90, 90, 90, 90, 90, 90, 0, 90, 90, 90, 0, 90, 90, 90, 0, 0, 0, 0, 0, 0};
00488 cType = FIST;
00489 cPoses.push_back( new CalibrationPose(N_SENSOR_VALUES, cp1, map));
00490 cPoses.push_back( new CalibrationPose(N_SENSOR_VALUES, cp2, map));
00491 } else if (type == SIMPLE_THUMB) {
00492
00493
00494 int map[] = {16, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
00495 double cp1[] = { 70, 0, 0,-50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
00496 double cp2[] = {-10, 0, 0,-50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
00497 cType = SIMPLE_THUMB;
00498 cPoses.push_back( new CalibrationPose(N_SENSOR_VALUES, cp1, map));
00499 cPoses.push_back( new CalibrationPose(N_SENSOR_VALUES, cp2, map));
00500 } else if (type == ABD_ADD) {
00501
00502
00503
00504
00505 int map[] = {-1,-1,-1,-1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 8, -1, -1, -1, 12, -1, -1, -1, -1, -1};
00506 double cp1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
00507 double cp2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0,-20, 0, 0, 0,-30, 0, 0, 0, 0, 0};
00508 cType = ABD_ADD;
00509 cPoses.push_back( new CalibrationPose(N_SENSOR_VALUES, cp1, map));
00510 cPoses.push_back( new CalibrationPose(N_SENSOR_VALUES, cp2, map));
00511 }
00512 } else if (type == COMPLEX_THUMB) {
00513 cType = COMPLEX_THUMB;
00514 } else if (type == MEAN_POSE) {
00515
00516
00517 cType = MEAN_POSE;
00518 cPoses.clear();
00519 }
00520 mCalibrated = false;
00521 currentPose = cPoses.begin();
00522 }
00523
00524 void GloveInterface::nextPose(int direction)
00525 {
00526
00527 if ( cPoses.empty() ) {
00528 fprintf(stderr,"No calibration poses recorded!\n");
00529 return;
00530 }
00531
00532 if (direction > 0) {
00533 currentPose++;
00534 if ( currentPose == cPoses.end() ) currentPose = cPoses.begin();
00535 } else {
00536 if ( currentPose == cPoses.begin() ) currentPose = cPoses.end();
00537 currentPose--;
00538 }
00539 getPoseError();
00540 }
00541
00542
00543 void GloveInterface::showCurrentPose()
00544 {
00545 if ( cPoses.empty() ) {
00546 fprintf(stderr,"No poses recorded!\n");
00547 return;
00548 }
00549
00550 double *desiredVals = new double[mRobot->getNumDOF()];
00551 int *map = (*currentPose)->getAllMaps();
00552 double *jointVals = (*currentPose)->getAllJointValues();
00553 int *sensorVals = (*currentPose)->getAllSensorValues();
00554
00555 int s,d;
00556
00557
00558 for (d=0; d<mRobot->getNumDOF(); d++) {
00559 desiredVals[d] = mRobot->getDOF(d)->getVal();
00560 }
00561
00562
00563 for (s=0; s<(*currentPose)->getSize(); s++) {
00564 d = map[s];
00565 if ( d >= 0) {
00566 if ( (*currentPose)->jointsSet )
00567 desiredVals[d] = jointVals[s];
00568 else if ( (*currentPose)->sensorsSet)
00569 desiredVals[d] = getDOFValue(d, sensorVals) ;
00570 else fprintf(stderr,"Can not show pose - neither joints nor sensors are set!\n");
00571
00572 }
00573 }
00574 mRobot->forceDOFVals(desiredVals);
00575 transf t = mRobot->getFlockTran()->getAbsolute( (*currentPose)->getTransf() );
00576
00577 mRobot->setTran( t );
00578 }
00579
00580 void GloveInterface::recordPoseFromGlove(int d)
00581 {
00582 #ifdef HARDWARE_LIB
00583 if (!instantRead()) {
00584 fprintf(stderr,"Can not read glove for calibration\n");
00585 return;
00586 }
00587
00588 int sv[N_SENSOR_VALUES];
00589 double* jv = new double[mRobot->getNumDOF()];
00590
00591 for (int i=0; i<N_SENSOR_VALUES; i++) {
00592 sv[i] = rawGlove->getSensorValue(i);
00593 }
00594
00595 if (cType==FIST || cType==SIMPLE_THUMB || cType == ABD_ADD) {
00596 if ( cPoses.empty() ) {
00597 fprintf(stderr,"No poses recorded!\n");
00598 return;
00599 }
00600 (*currentPose)->setAllSensorValues(sv);
00601 } else if (cType == COMPLEX_THUMB) {
00602 cPoses.push_back( new CalibrationPose(N_SENSOR_VALUES) );
00603 currentPose = cPoses.end();
00604 currentPose--;
00605
00606 (*currentPose)->setAllSensorValues(sv);
00607
00608 int map[] = {16, 18, 19, 17, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
00609 (*currentPose)->setAllMaps(map);
00610 (*currentPose)->recordedDistance = d;
00611 fprintf(stderr,"Distance: %d\n",d);
00612 } else if (cType == MEAN_POSE) {
00613 cPoses.push_back( new CalibrationPose(N_SENSOR_VALUES) );
00614 currentPose = cPoses.end();
00615 currentPose--;
00616 (*currentPose)->setAllSensorValues(sv);
00617 for (int d=0; d<mRobot->getNumDOF(); d++) {
00618 jv[d] = getDOFValue(d,sv);
00619 mRobot->checkSetDOFVals(jv);
00620 }
00621 (*currentPose)->setAllJointValues(jv);
00622 int map[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,-1,-1,-1,-1};
00623 (*currentPose)->setAllMaps(map);
00624
00625
00626 transf t = mRobot->getFlockTran()->getMount() * mRobot->getTran();
00627
00628 (*currentPose)->setTransf(t);
00629
00630 fprintf(stderr,"Pose for mean recorded!\n");
00631 } else {
00632 fprintf(stderr,"No calibration type initialized!\n");
00633 }
00634 delete [] jv;
00635 #else
00636 (void*)&d;
00637 assert(0);
00638 #endif
00639 }
00640
00641 bool GloveInterface::poseSet()
00642 {
00643 if ( cPoses.empty() )
00644 return false;
00645
00646 return (*currentPose)->isSet();
00647 }
00648
00649
00650 bool GloveInterface::readyToCalibrate()
00651 {
00652 if (cType == FIST || cType == SIMPLE_THUMB || cType == ABD_ADD) {
00653 int numSet = 0;
00654 std::list<CalibrationPose*>::iterator it;
00655 for (it=cPoses.begin(); it!=cPoses.end(); it++) {
00656 if ( (*it)->isSet() ) numSet++;
00657 }
00658 if (numSet>=2) return true;
00659 } else if (cType == COMPLEX_THUMB) {
00660 if ( (int)cPoses.size() > 5 )return true;
00661 } else if (cType == MEAN_POSE) {
00662 if (!cPoses.empty()) return true;
00663 }
00664 return false;
00665 }
00666
00667 bool GloveInterface::performCalibration()
00668 {
00669 switch (cType) {
00670 case FIST:
00671 return performSimpleCalibration();
00672 break;
00673 case ABD_ADD:
00674 return performSimpleCalibration();
00675 break;
00676 case SIMPLE_THUMB:
00677 return performThumbCalibration();
00678 break;
00679 case COMPLEX_THUMB:
00680 performComplexCalibration();
00681 mCalibrated = true;
00682
00683 return true;
00684 break;
00685 case MEAN_POSE:
00686 computeMeanPose();
00687 break;
00688 default:
00689 fprintf(stderr,"Unknown calibration type requested\n");
00690 break;
00691 }
00692 return false;
00693 }
00694
00695
00696
00697 bool GloveInterface::performSimpleCalibration()
00698 {
00699 if (!readyToCalibrate() ){
00700 return false;
00701 }
00702
00703 CalibrationPose *cp1, *cp2;
00704 std::list<CalibrationPose*>::iterator it;
00705 it = cPoses.begin();
00706 cp1 = (*it);
00707 it++;
00708 cp2 = (*it);
00709
00710 float sMin, sMax, dMin, dMax;
00711 for (int i=0; i<N_SENSOR_VALUES;i++){
00712
00713 if ( cp1->getMap(i) < 0 || cp2->getMap(i) < 0 ){
00714 fprintf(stderr,"Sensor %d masked\n",i);
00715 continue;
00716 }
00717 int d = cp1->getMap(i);
00718 if ( d != cp2->getMap(i) ) {
00719 fprintf(stderr,"Error! Sensor %d has different maps in poses!\n",i);
00720 continue;
00721 }
00722 sMin = cp1->getSensorValue(i); sMax = cp2->getSensorValue(i);
00723 dMin = cp1->getJointValue(i); dMax = cp2->getJointValue(i);
00724 setParameters(i, d, sMin, sMax, dMin, dMax);
00725 }
00726
00727 mCalibrated = true;
00728 return true;
00729 }
00730
00731 bool GloveInterface::performThumbCalibration()
00732 {
00733 if (!readyToCalibrate() ){
00734 return false;
00735 }
00736
00737 CalibrationPose *cp1, *cp2;
00738 std::list<CalibrationPose*>::iterator it;
00739 it = cPoses.begin();
00740 cp1 = (*it);
00741 it++;
00742 cp2 = (*it);
00743
00744 int R11 = cp1->getSensorValue(3);
00745 int R12 = cp2->getSensorValue(3);
00746
00747 double S1 = mData->getSlope(17, 3);
00748 double alpha = S1 * ( R11 - R12 );
00749
00750 int R21 = cp1->getSensorValue(0);
00751 int R22 = cp2->getSensorValue(0);
00752
00753 double S2 = alpha / ( R22 - R21 );
00754 double I2 = - S2 * R21;
00755
00756 mData->setSlope(17, 0, S2);
00757 mData->setIntercept(17, mData->getIntercept(17)+I2);
00758 fprintf(stderr,"Result: slope %f and intercept %f \n",S2,I2);
00759
00760 mCalibrated = true;
00761 return true;
00762 }
00763
00764 bool GloveInterface::performComplexCalibration()
00765 {
00766 for (int i=0; i<100; i++) {
00767 complexCalibrationStep();
00768 }
00769 return true;
00770 }
00771
00772 bool GloveInterface::complexCalibrationStep()
00773 {
00774
00775 int i;
00776
00777 int nPoses = 0;
00778 for (currentPose = cPoses.begin(); currentPose!=cPoses.end(); currentPose++) {
00779 showCurrentPose();
00780
00781
00782 if ( getPoseError() > -7.8)
00783 nPoses ++;
00784 }
00785 double *JD = new double[nPoses * 30];
00786 int ldd = nPoses * 3;
00787
00788 double *P = new double[nPoses * 3];
00789 double *fg = new double[10];
00790
00791 i=0;
00792 for (currentPose = cPoses.begin(); currentPose!=cPoses.end(); currentPose++) {
00793 showCurrentPose();
00794 if (getPoseError() <= -7.8)
00795 continue;
00796 assembleJMatrix( JD + i*3, ldd);
00797 assemblePMatrix( P + i*3 );
00798 i++;
00799 }
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820 int info,rank;
00821 int lwork = 100 * 3 * nPoses;
00822 double *work = new double[lwork];
00823 double *SVDs = new double[MIN(3*nPoses,10)];
00824
00825 dgelss(3*nPoses, 10, 1,
00826 JD, 3*nPoses, P, 3*nPoses, SVDs, 1.0e-5, &rank, work, lwork, &info);
00827
00828
00829
00830
00831
00832
00833
00834
00835 mData->addToIntercept(16,P[0]);
00836 mData->addToIntercept(17,P[1]);
00837 mData->addToIntercept(18,P[2]);
00838 mData->addToIntercept(19,P[3]);
00839
00840 mData->addToSlope(16,0,P[4]);
00841 mData->addToSlope(16,3,P[5]);
00842 mData->addToSlope(17,0,P[6]);
00843 mData->addToSlope(17,3,P[7]);
00844 mData->addToSlope(18,1,P[8]);
00845 mData->addToSlope(19,2,P[9]);
00846
00847 fprintf(stderr,"Total error AFTER step: %f\n",getTotalError());
00848 currentPose = cPoses.begin();
00849
00850 delete [] SVDs;
00851 delete [] work;
00852 delete [] JD;
00853 delete [] P;
00854 delete [] fg;
00855
00856 return true;
00857 }
00858
00859 bool
00860 GloveInterface::computeMeanPose()
00861 {
00862
00863 double *jv = new double[mRobot->getNumDOF()];
00864
00865 for (int d=0; d<mRobot->getNumDOF(); d++) {
00866 jv[d]=0;
00867 }
00868
00869 for (currentPose = cPoses.begin(); currentPose != cPoses.end(); currentPose++) {
00870 for (int d=0; d<mRobot->getNumDOF(); d++) {
00871 jv[d] += (*currentPose)->getJointValue(d);
00872 }
00873 }
00874
00875 for (int d=0; d<mRobot->getNumDOF(); d++) {
00876 jv[d] = jv[d] / cPoses.size();
00877 }
00878
00879 cPoses.push_back( new CalibrationPose(N_SENSOR_VALUES) );
00880 currentPose = cPoses.end();
00881 currentPose--;
00882 (*currentPose)->setAllJointValues(jv);
00883 int map[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,-1,-1,-1,-1};
00884 (*currentPose)->setAllMaps(map);
00885 showCurrentPose();
00886
00887 FILE *fp = fopen("mean_pose.txt","w");
00888 fprintf(stderr,"Mean pose written to mean_pose.txt \n");
00889 (*currentPose)->writeToFile(fp);
00890 fclose(fp);
00891
00892 delete [] jv;
00893 return true;
00894 }
00895
00896 void GloveInterface::saveCalibration(const char* filename)
00897 {
00898 FILE *fp = fopen(filename,"w");
00899 if (!fp) {
00900 fprintf(stderr,"Unable to open calibration file!\n");
00901 return;
00902 }
00903
00904 int d,s;
00905 fprintf(fp,"%d %d\n",mRobot->getNumDOF(), N_SENSOR_VALUES);
00906 for (d=0; d<mRobot->getNumDOF(); d++) {
00907 for (s=0; s<N_SENSOR_VALUES; s++)
00908 fprintf(fp, "%f ",mData->getSlope(d,s));
00909 fprintf(fp,"\n");
00910 }
00911 for (d=0; d<mRobot->getNumDOF(); d++)
00912 fprintf(fp,"%f ",mData->getIntercept(d));
00913 fprintf(fp,"\n");
00914 fclose(fp);
00915 fprintf(stderr,"Calibration saved\n");
00916 }
00917
00918 bool GloveInterface::loadCalibration(const char* filename)
00919 {
00920 FILE *fp = fopen(filename,"r");
00921 if (!fp) {
00922 fprintf(stderr,"Unable to open calibration file!\n");
00923 return false;
00924 }
00925
00926 int d,s;
00927 int numDOF, numSens;
00928 float val;
00929
00930 fscanf(fp,"%d %d ",&numDOF,&numSens);
00931 if ( numDOF != mRobot->getNumDOF() || numSens != N_SENSOR_VALUES ) {
00932 fprintf(stderr,"WARNING: calibration file contains wrong number of DOFs/sensors\n");
00933 return false;
00934 }
00935
00936 mData->reset();
00937 for (d=0; d<numDOF; d++) {
00938 for (s=0; s<numSens; s++) {
00939 fscanf(fp,"%f",&val);
00940 mData->setSlope(d,s,val);
00941 }
00942 }
00943 for (d=0; d<mRobot->getNumDOF(); d++) {
00944 fscanf(fp,"%f",&val);
00945 mData->setIntercept(d,val);
00946 }
00947
00948 fclose(fp);
00949 fprintf(stderr,"Calibration loaded from file\n");
00950 return true;
00951 }
00952
00953
00954 void GloveInterface::saveCalibrationPoses(const char *filename)
00955 {
00956 writePoseListToFile(&cPoses, filename);
00957 currentPose = cPoses.begin();
00958 }
00959
00960 void GloveInterface::loadCalibrationPoses(const char *filename)
00961 {
00962 loadPoseListFromFile(&cPoses, filename);
00963 currentPose = cPoses.begin();
00964 }
00965
00966 double GloveInterface::getPoseError(vec3* error, position* thumbLocation)
00967 {
00968 double shellDistance = 8;
00969 double cFactor = (*currentPose)->recordedDistance;
00970
00971 vec3 expectedVector, measuredVector, e;
00972
00973 showCurrentPose();
00974 Body *thumbTip = mRobot->getChain(4)->getLink(2);
00975 Body *indexTip = mRobot->getChain(0)->getLink(2);
00976 position p1, p2;
00977 double rawDistance;
00978 rawDistance = mRobot->getWorld()->getDist(thumbTip, indexTip, p1, p2);
00979
00980 if (thumbLocation != NULL) {
00981 *thumbLocation = p1;
00982 }
00983
00984 p1 = p1 * thumbTip->getTran() * mRobot->getChain(4)->getTran().inverse();
00985 p2 = p2 * indexTip->getTran() * mRobot->getChain(4)->getTran().inverse();
00986 measuredVector = p2 - p1;
00987
00988 expectedVector = normalise(measuredVector);
00989 expectedVector = ( cFactor + shellDistance) * expectedVector;
00990
00991
00992
00993 e = measuredVector - expectedVector;
00994
00995 if (error != NULL) {
00996 *error = e;
00997 }
00998
00999
01000
01001
01002
01003 return e.len();
01004 }
01005
01006 double GloveInterface::getTotalError()
01007 {
01008 double totalError = 0;
01009 for ( currentPose=cPoses.begin(); currentPose!=cPoses.end(); currentPose++) {
01010 totalError += getPoseError();
01011 }
01012 totalError /= cPoses.size();
01013 return totalError;
01014 }
01015
01016 void GloveInterface::getPoseJacobian(double *J)
01017 {
01018 double t1 = mRobot->getDOF(16)->getVal();
01019 double t2 = mRobot->getDOF(17)->getVal() + 0.8639;
01020 double t3 = mRobot->getDOF(18)->getVal() + 0.0873;
01021 double t4 = mRobot->getDOF(19)->getVal() + 1.4835;
01022
01023 jacobian(t1, t2, t3, t4, 0, 0, 1000, J);
01024 }
01025
01026 void GloveInterface::assembleJMatrix(double *D, int ldd)
01027 {
01028 double t1 = mRobot->getDOF(16)->getVal();
01029 double t2 = mRobot->getDOF(17)->getVal() + 0.8639;
01030 double t3 = mRobot->getDOF(18)->getVal() + 0.0873;
01031 double t4 = mRobot->getDOF(19)->getVal() + 1.4835;
01032
01033 position errorPos;
01034 getPoseError(NULL,&errorPos);
01035
01036 double J[12];
01037
01038 jacobian(t1, t2, t3, t4, errorPos.x(), errorPos.y(), errorPos.z(), J);
01039
01040 double s0 = (*currentPose)->getSensorValue(0);
01041 double s1 = (*currentPose)->getSensorValue(3);
01042 double s2 = (*currentPose)->getSensorValue(1);
01043 double s3 = (*currentPose)->getSensorValue(2);
01044
01045 double dTdG[4*6];
01046 compute_dTdG(s0, s1, s2, s3, dTdG);
01047
01048 double JD[3*6];
01049 dgemm("N", "N", 3, 6, 4,
01050 1, J, 3,
01051 dTdG, 4,
01052 0, JD, 3);
01053
01054 int i,j;
01055 for (i=0; i<3; i++) {
01056 for (j=0; j<4; j++) {
01057 D[ i + j*ldd] = J[ i + 3*j];
01058 }
01059 }
01060 for (i=0; i<3; i++) {
01061 for (j=0; j<6; j++) {
01062 D[ i + (4+j)*ldd ] = JD[ i + 3*j ];
01063 }
01064 }
01065 }
01066
01067 void GloveInterface::assemblePMatrix( double *P )
01068 {
01069 vec3 error;
01070 getPoseError(&error);
01071
01072 P[0] = error.x();
01073 P[1] = error.y();
01074 P[2] = error.z();
01075 }
01076
01077 void GloveInterface::clearPoses()
01078 {
01079 cPoses.clear();
01080 currentPose = cPoses.begin();
01081 }
01082
01083 void GloveInterface::startGlove()
01084 {
01085 DBGA("Disabled... Init glove from World menu");
01086 }