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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "ArmControl/ArmPlanner.H"
00039
00040
00041 ArmPlanner::ArmPlanner( OptionManager& mgr,
00042 const std::string& descrName,
00043 const std::string& tagName,
00044 nub::soft_ref<ArmController> realController,
00045 nub::soft_ref<ArmController> controller,
00046 nub::soft_ref<ArmSim> armSim):
00047 ModelComponent(mgr, descrName, tagName),
00048 numWarnings(0),
00049 itsRealArmController(realController),
00050 itsArmController(controller),
00051 itsArmSim(armSim),
00052 itsImage(512,256, ZEROS)
00053 {
00054 addSubComponent(itsArmController);
00055 addSubComponent(itsArmSim);
00056
00057 #ifdef USE_LWPR
00058 lwpr_read_xml(&ik_model, "ik_model.xml", &numWarnings);
00059 #endif
00060 }
00061
00062
00063 #ifdef USE_LWPR
00064 ArmController::JointPos ArmPlanner::getIK(LWPR_Model& ik_model, const double* desiredPos)
00065 {
00066 double joints[5];
00067 lwpr_predict(&ik_model, desiredPos, 0.001, joints, NULL, NULL);
00068
00069 ArmController::JointPos jointPos;
00070
00071 jointPos.base = (int)joints[0];
00072 jointPos.sholder = (int)joints[1];
00073 jointPos.elbow = (int)joints[2];
00074 jointPos.wrist1 = (int)joints[3];
00075 jointPos.wrist2 = (int)joints[4];
00076
00077
00078 LDEBUG("Mapping %0.2f %0.2f %0.2f => %i %i %i %i %i",
00079 desiredPos[0], desiredPos[1], desiredPos[2],
00080 jointPos.base, jointPos.sholder, jointPos.elbow,
00081 jointPos.wrist1, jointPos.wrist2);
00082 return jointPos;
00083 }
00084 #endif
00085 void ArmPlanner::getFK(double *endPos)
00086 {
00087 double jointsAng[5],armLoc[3];
00088 itsArmSim->getArmLoc(armLoc);
00089 ArmController::JointPos jointPos = itsArmController->getJointPos();
00090 jointsAng[0] = itsArmSim->encoder2ang(jointPos.base,RobotArm::BASE);
00091 jointsAng[1] = itsArmSim->encoder2ang(jointPos.sholder,RobotArm::SHOLDER);
00092 jointsAng[2] = itsArmSim->encoder2ang(jointPos.elbow,RobotArm::ELBOW);
00093 jointsAng[3] = itsArmSim->encoder2ang(jointPos.wrist1,RobotArm::WRIST1);
00094 jointsAng[4] = itsArmSim->encoder2ang(jointPos.wrist2,RobotArm::WRIST2);
00095
00096 }
00097 ArmController::JointPos ArmPlanner::getIK2(const double* desiredPos)
00098 {
00099 double joints[5],armLoc[3];
00100 itsArmSim->getArmLoc(armLoc);
00101 ArmController::JointPos jointPos = itsArmController->getJointPos();
00102
00103 joints[0] = atan2(desiredPos[1]-armLoc[1],desiredPos[0]-armLoc[0]);
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 double r = getDistance2D(armLoc,desiredPos);
00130 double x = r - 0.03;
00131 double y = -1*(0.210+0.174) + desiredPos[2];
00132 double l1 = 0.220 ;
00133 double l2 = 0.220 + 0.145;
00134
00135 double c2 = (sq(x)+sq(y)-sq(l1)-sq(l2)) / (2*l1*l2);
00136 if(c2 < 1 && c2 > -1){
00137 jointPos.base = itsArmSim->ang2encoder(joints[0],RobotArm::BASE);
00138 double s2 = -1* sqrt(1-sq(c2));
00139
00140 double th2 = atan2(-1*s2,c2);
00141 jointPos.elbow = itsArmSim->ang2encoder(th2-M_PI/2,RobotArm::ELBOW);
00142
00143 double k1 = l1+l2*c2;
00144 double k2 = l2*s2;
00145 double th1 = atan2(y,x) - atan2(k2,k1);
00146
00147 jointPos.sholder = itsArmSim->ang2encoder(-1*th1+M_PI/2,RobotArm::SHOLDER);
00148 double th3 = M_PI/2 - th1 - th2;
00149 jointPos.wrist2 = itsArmSim->ang2encoder(th3,RobotArm::WRIST2);
00150 jointPos.wrist2 = 0;
00151 jointPos.wrist1 = 0;
00152
00153 LINFO("th1 %f,th2 %f , th3 %f, r %f ,x %f,y %f, c2 %f ,s2 %f",th1,th2,th3, r,x,y,c2,s2);
00154
00155 jointPos.reachable = true;
00156 }else{
00157
00158 LINFO("Unreachable point x %f y %f z %f",desiredPos[0],desiredPos[1],desiredPos[2]);
00159 jointPos.reachable = false;
00160 }
00161 LDEBUG("Mapping %0.2f %0.2f %0.2f => %i %i %i %i %i",
00162 desiredPos[0], desiredPos[1], desiredPos[2],
00163 jointPos.base, jointPos.sholder, jointPos.elbow,
00164 jointPos.wrist1, jointPos.wrist2);
00165 return jointPos;
00166 }
00167
00168 #ifdef USE_LWPR
00169 void ArmPlanner::trainArm(LWPR_Model& ik_model, const double* armPos, const ArmController::JointPos& jointPos)
00170 {
00171
00172 double joints[5];
00173 double pJoints[5];
00174 LDEBUG("Training => %0.2f,%0.2f,%0.2f => %i %i %i %i %i",
00175 armPos[0], armPos[1], armPos[2],
00176 jointPos.base, jointPos.sholder, jointPos.elbow,
00177 jointPos.wrist1, jointPos.wrist2);
00178
00179 joints[0] = jointPos.base;
00180 joints[1] = jointPos.sholder;
00181 joints[2] = jointPos.elbow;
00182 joints[3] = jointPos.wrist1;
00183 joints[4] = jointPos.wrist2;
00184
00185 lwpr_update(&ik_model, armPos, joints, pJoints, NULL);
00186
00187 }
00188 #endif
00189 ArmController::JointPos ArmPlanner::calcGradient(const double* desiredPos)
00190 {
00191
00192 ArmController::JointPos jointPos = itsArmController->getJointPos();
00193 ArmController::JointPos tmpJointPos = jointPos;
00194
00195 double dist1, dist2;
00196 double baseGrad, sholderGrad, elbowGrad;
00197 double err = getDistance(itsArmSim->getEndPos(), desiredPos);
00198
00199
00200 tmpJointPos.base = jointPos.base + 100;
00201 itsArmController->setJointPos(tmpJointPos);
00202 dist1 = getDistance(itsArmSim->getEndPos(), desiredPos);
00203
00204 tmpJointPos.base = jointPos.base - 100;
00205 itsArmController->setJointPos(tmpJointPos);
00206 dist2 = getDistance(itsArmSim->getEndPos(), desiredPos);
00207 baseGrad = dist1 - dist2;
00208 tmpJointPos.base = jointPos.base;
00209
00210
00211 tmpJointPos.sholder = jointPos.sholder + 100;
00212 itsArmController->setJointPos(tmpJointPos);
00213 dist1 = getDistance(itsArmSim->getEndPos(), desiredPos);
00214 tmpJointPos.sholder = jointPos.sholder - 100;
00215 itsArmController->setJointPos(tmpJointPos);
00216 dist2 = getDistance(itsArmSim->getEndPos(), desiredPos);
00217 sholderGrad = dist1 - dist2;
00218 tmpJointPos.sholder = jointPos.sholder;
00219
00220
00221 tmpJointPos.elbow = jointPos.elbow + 100;
00222 itsArmController->setJointPos(tmpJointPos);
00223 dist1 = getDistance(itsArmSim->getEndPos(), desiredPos);
00224 tmpJointPos.elbow = jointPos.elbow - 100;
00225 itsArmController->setJointPos(tmpJointPos);
00226 dist2 = getDistance(itsArmSim->getEndPos(), desiredPos);
00227 elbowGrad = dist1 - dist2;
00228 tmpJointPos.elbow = jointPos.elbow;
00229
00230 int moveThresh = (int)(err*100000);
00231 jointPos.base -= (int)(randomUpToIncluding(moveThresh)*baseGrad);
00232 jointPos.sholder -= (int)(randomUpToIncluding(moveThresh)*sholderGrad);
00233 jointPos.elbow -= (int)(randomUpToIncluding(moveThresh)*elbowGrad);
00234
00235 return jointPos;
00236 }
00237
00238
00239 bool ArmPlanner::gibbsSampling(double *desire,double errThres)
00240 {
00241 double current_distance = getDistance(itsArmSim->getEndPos(),desire);
00242 double prev_distance = current_distance;
00243 errThres = errThres * errThres;
00244 int moveThres = 200;
00245 if(current_distance < 0.02)
00246 moveThres /= 2;
00247 if(current_distance < 0.01)
00248 moveThres /= 2;
00249 if(current_distance < errThres){
00250 return true;
00251 }
00252 do{
00253 int motor = randomUpToIncluding(2);
00254 int move = randomUpToIncluding(moveThres*2)-moveThres;
00255
00256 LINFO("Move motor %d with %d dist %f",motor,move,current_distance);
00257 prev_distance = current_distance;
00258 moveMotor(motor,move);
00259 current_distance = getDistance(itsArmSim->getEndPos(),desire);
00260 LINFO("Motor moved %d with %d dist %f",motor,move,current_distance);
00261
00262
00263 if(current_distance > prev_distance)
00264 {
00265
00266 moveMotor(motor,-move);
00267 }
00268 }while(current_distance > prev_distance);
00269
00270
00271 ArmController::JointPos jointPos = itsArmController->getJointPos();
00272 itsRealArmController->setJointPos(sim2real(jointPos),false);
00273 return false;
00274 }
00275
00276 void ArmPlanner::moveMotor(int motor,int move)
00277 {
00278 switch(motor)
00279 {
00280 case 0:
00281 itsArmController->setBasePos(move, true);
00282 break;
00283 case 1:
00284 itsArmController->setSholderPos(move, true);
00285 break;
00286 case 2:
00287 itsArmController->setElbowPos(move, true);
00288 break;
00289 default:
00290 break;
00291 }
00292 while(!itsArmController->isFinishMove())
00293 {
00294 itsArmSim->simLoop();
00295 usleep(1000);
00296 }
00297 }
00298 bool ArmPlanner::gibbsControl(double *desire,double d)
00299 {
00300 double *current = itsArmSim->getEndPos();
00301 double distance = getDistance(itsArmSim->getEndPos(),desire);
00302
00303 double errThresForSampling = d;
00304 double v[3],nextPoint[3];
00305 if(getDistance(itsArmSim->getEndPos(),desire) < 0.01){
00306 LINFO("Move by gibbs only");
00307 errThresForSampling = d;
00308 return gradient(desire,errThresForSampling);
00309 }else{
00310 for(int i=0;i<3;i++)
00311 {
00312 v[i] = desire[i] - current[i];
00313 v[i] = v[i]/distance;
00314 nextPoint[i] = current[i]+(distance/2)*v[i];
00315 }
00316 while(!gradient(nextPoint,errThresForSampling));
00317 LINFO("Move to next point %f %f %f %f",nextPoint[0],nextPoint[1],nextPoint[2],getDistance(itsArmSim->getEndPos(),nextPoint));
00318
00319 }
00320
00321 return false;
00322
00323 }
00324
00325 bool ArmPlanner::gradient(double *desire,double errThres)
00326 {
00327 int gradient_base = itsArmSim->getGradientEncoder(RobotArm::BASE,desire);
00328 int gradient_sholder= itsArmSim->getGradientEncoder(RobotArm::SHOLDER,desire);
00329 int gradient_elbow = itsArmSim->getGradientEncoder(RobotArm::ELBOW,desire);
00330 gradient_base =(int)((double)gradient_base*(-483/63));
00331 gradient_sholder=(int)((double)gradient_sholder*(-2606/354));
00332 gradient_elbow =(int)((double)gradient_elbow*(-46/399));
00333 errThres = errThres * errThres;
00334 LINFO("Gradient: %d %d %d dist %f",gradient_base,gradient_sholder,gradient_elbow,
00335 getDistance(itsArmSim->getEndPos(),desire));
00336 if(getDistance(itsArmSim->getEndPos(),desire) > errThres){
00337
00338
00339
00340
00341 }else{
00342 return true;
00343 }
00344 return false;
00345 }
00346
00347 bool ArmPlanner::moveRel(double x,double y,double z,double errThres)
00348 {
00349
00350 double err;
00351 double* current = itsArmSim->getEndPos();
00352 double desire[3];
00353 int numTries = 0;
00354
00355 desire[0] = current[0] + x;
00356 desire[1] = current[1] + y;
00357 desire[2] = current[2] + z;
00358 LINFO("Current %f,%f,%f De: %f,%f,%f",
00359 current[0], current[1], current[2],
00360 desire[0], desire[1], desire[2]);
00361 getchar();
00362
00363
00364 ArmController::JointPos jointPos = getIK2(desire);
00365 LINFO("Got Joint POs");
00366 if(!jointPos.reachable){
00367 LINFO("Can't reach point");
00368 return false;
00369 }
00370
00371 CtrlPolicy xCP;
00372 CtrlPolicy yCP;
00373 CtrlPolicy zCP;
00374 xCP.setGoalPos(desire[0]);
00375 yCP.setGoalPos(desire[1]);
00376 zCP.setGoalPos(desire[2]);
00377
00378
00379 xCP.setCurrentPos(current[0]);
00380 yCP.setCurrentPos(current[1]);
00381 zCP.setCurrentPos(current[2]);
00382 LINFO("Moving");
00383 err = getDistance(itsArmSim->getEndPos(), desire);
00384 int numTriesThres = 10000;
00385 while(err > errThres && numTries < numTriesThres)
00386 {
00387
00388 numTries++;
00389 double cp[3];
00390 current = itsArmSim->getEndPos();
00391 cp[0] = xCP.getPos(current[0]);
00392 cp[1] = yCP.getPos(current[1]);
00393 cp[2] = zCP.getPos(current[2]);
00394
00395
00396
00397 jointPos = getIK2(cp);
00398 updateDataImg();
00399 if(jointPos.reachable){
00400 itsArmController->setJointPos(jointPos,true);
00401
00402 } else {
00403 LINFO("Can't reach point");
00404 }
00405
00406 err = getDistance(itsArmSim->getEndPos(), desire);
00407 }
00408 if(numTries <= numTriesThres)
00409 {
00410 jointPos = getIK2(desire);
00411 itsArmController->setJointPos(jointPos);
00412
00413
00414 }
00415 else{
00416 LINFO("Can't reach point");
00417
00418 }
00419
00420
00421 err = getDistance(itsArmSim->getEndPos(), desire);
00422
00423 LINFO("Moving Done,err %f errThres %f",err,errThres);
00424 return (err < errThres);
00425
00426 }
00427 bool ArmPlanner::move(double *desire,double errThres)
00428 {
00429 double err;
00430 int numTries = 0;
00431
00432 ArmController::JointPos jointPos = getIK2(desire);
00433 LINFO("Got Joint POs");
00434 if(!jointPos.reachable){
00435 LINFO("Can't reach point");
00436 return false;
00437 }
00438
00439 CtrlPolicy xCP;
00440 CtrlPolicy yCP;
00441 CtrlPolicy zCP;
00442 xCP.setGoalPos(desire[0]);
00443 yCP.setGoalPos(desire[1]);
00444 zCP.setGoalPos(desire[2]);
00445
00446
00447 double* current = itsArmSim->getEndPos();
00448 xCP.setCurrentPos(current[0]);
00449 yCP.setCurrentPos(current[1]);
00450 zCP.setCurrentPos(current[2]);
00451 LINFO("Moving");
00452 err = getDistance(itsArmSim->getEndPos(), desire);
00453 int numTriesThres = 10000;
00454 while(err > errThres && numTries < numTriesThres)
00455 {
00456
00457 numTries++;
00458 double cp[3];
00459 current = itsArmSim->getEndPos();
00460 cp[0] = xCP.getPos(current[0]);
00461 cp[1] = yCP.getPos(current[1]);
00462 cp[2] = zCP.getPos(current[2]);
00463
00464
00465
00466 jointPos = getIK2(cp);
00467 updateDataImg();
00468 if(jointPos.reachable){
00469 itsArmController->setJointPos(jointPos,true);
00470 itsRealArmController->setJointPos(sim2real(jointPos),false);
00471 } else {
00472 LINFO("Can't reach point");
00473 }
00474
00475 err = getDistance(itsArmSim->getEndPos(), desire);
00476 }
00477 if(numTries <= numTriesThres)
00478 {
00479 jointPos = getIK2(desire);
00480 itsArmController->setJointPos(jointPos);
00481
00482 itsRealArmController->setJointPos(sim2real(jointPos),false);
00483 }
00484 else{
00485 LINFO("Can't reach point");
00486
00487 }
00488
00489
00490 err = getDistance(itsArmSim->getEndPos(), desire);
00491
00492 LINFO("Moving Done,err %f errThres %f",err,errThres);
00493 return (err < errThres);
00494 }
00495 void ArmPlanner::minJerk(double *desire,double *nextPoint,double time)
00496 {
00497 double *currentPos = itsArmSim->getEndPos();
00498 double distance = getDistance(currentPos,desire);
00499 double d = distance * 100;
00500
00501 for(int i = 0 ; i < 3 ; i++)
00502 {
00503 double td = time/d;
00504 nextPoint[i] = currentPos[i]+(desire[i] - currentPos[i])
00505 *(10*pow(td,3) - 15*pow(td,4) + 6*pow(td,5));
00506
00507 }
00508
00509 }
00510
00511 void ArmPlanner::updateDataImg()
00512 {
00513 static int x = 0;
00514
00515 if (x < itsImage.getWidth())
00516 {
00517 if (!x)
00518 itsImage.clear();
00519
00520
00521
00522
00523 itsImage.setVal(x,0, PixRGB<byte>(255,0,0));
00524
00525
00526 x++;
00527 }
00528
00529 }
00530
00531 ArmController::JointPos ArmPlanner::sim2real(ArmController::JointPos armSimJointPos )
00532 {
00533
00534 ArmController::JointPos scorbotJointPos;
00535
00536 scorbotJointPos.base = armSimJointPos.base ;
00537 scorbotJointPos.sholder = armSimJointPos.sholder;
00538 scorbotJointPos.elbow = armSimJointPos.elbow ;
00539 scorbotJointPos.wrist1 = armSimJointPos.wrist1 ;
00540 scorbotJointPos.wrist2 = armSimJointPos.wrist2 ;
00541 scorbotJointPos.reachable= armSimJointPos.reachable ;
00542
00543
00544 scorbotJointPos.elbow += scorbotJointPos.sholder;
00545
00546 scorbotJointPos.wrist1 += (int)((0.2496*(float)scorbotJointPos.elbow )-39.746) ;
00547 scorbotJointPos.wrist2 -= (int)((0.2496*(float)scorbotJointPos.elbow )-39.746) ;
00548 scorbotJointPos.elbow *=-1;
00549
00550 return scorbotJointPos;
00551 }