00001
00002 #include "robodyn_controllers/KdlTreeTr.h"
00003
00004 using namespace Eigen;
00005 using namespace KDL;
00006 using namespace std;
00007
00008 KdlTreeTr::KdlTreeTr()
00009 : KdlTreeIk()
00010 {
00011 setMBar();
00012 setKr();
00013 setMaxTwist();
00014 setMaxJointDecel();
00015
00016
00017
00018
00019
00020
00021
00022 }
00023
00024 KdlTreeTr::~KdlTreeTr()
00025 {
00026
00027 }
00028
00029 void KdlTreeTr::initialize()
00030 {
00031 KdlTreeIk::initialize();
00032 nodeNames.clear();
00033 currentFrameMap.clear();
00034 twistMap.clear();
00035 desiredFrameMap.clear();
00036 taskList.clear();
00037 }
00038
00039 void KdlTreeTr::setJointInertias(const std::map<std::string, double>& inertia_in)
00040 {
00041 KdlTreeIk::setJointInertias(inertia_in);
00042
00043
00044
00045
00046
00047 jacJntWeights = inertias.data.asDiagonal();
00048
00049
00050
00051
00052 }
00053
00056 void KdlTreeTr::createFrameTwistMaps(const vector<Frame>& nodeFrames, const vector<NodePriority>& nodePriorities)
00057 {
00058 desiredFrameMap.clear();
00059 currentFrameMap.clear();
00060 twistMap.clear();
00061 taskList.clear();
00062 priorityTaskAxisMap.clear();
00063
00064 unsigned int i;
00065
00066 for (i = 0; i < nodeNames.size(); ++i)
00067 {
00068 if (tree.getSegment(nodeNames[i]) == tree.getSegments().end())
00069 {
00070 std::stringstream err;
00071 err << "KdlTreeIk node name (" << nodeNames[i] << ") not found in tree" << std::endl;
00072 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr", log4cpp::Priority::ERROR, err.str());
00073 throw std::runtime_error(err.str());
00074 return;
00075 }
00076
00077 desiredFrameMap.insert(std::make_pair(nodeNames[i], nodeFrames[i]));
00078 currentFrameMap.insert(std::make_pair(nodeNames[i], KDL::Frame()));
00079 twistMap.insert(std::make_pair(nodeNames[i], std::make_pair(KDL::Twist(), nodePriorities[i])));
00080 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.createFrameTwistMaps") << log4cpp::Priority::INFO << "node " << nodeNames[i] << " added to maps";
00081
00082 for (int p = 0; p < 6; ++p)
00083 {
00084 priorityTaskAxisMap.insert(std::make_pair(nodePriorities[i][p], std::make_pair(nodeNames[i], p) ) );
00085 }
00086 }
00087
00088 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.createFrameTwistMaps") << log4cpp::Priority::INFO << "maps resized to " << nodeNames.size();
00089 }
00090
00093 void KdlTreeTr::updateNodeFrameMap(const vector<Frame>& nodeFrames)
00094 {
00095 for (unsigned int i = 0; i < nodeNames.size(); ++i)
00096 {
00097 if (tree.getSegment(nodeNames[i]) == tree.getSegments().end())
00098 {
00099 std::stringstream err;
00100 err << "in updateFrameMaps() node name (" << nodeNames[i] << ") not found in tree" << std::endl;
00101 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr", log4cpp::Priority::ERROR, err.str());
00102 throw std::runtime_error(err.str());
00103 }
00104
00105 desiredFrameMap[nodeNames[i]] = nodeFrames[i];
00106 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.updateNodeFrameMap") << log4cpp::Priority::DEBUG << "updated " << nodeNames[i] << " to : "
00107 << "(" << desiredFrameMap[nodeNames[i]].p.x()
00108 << "," << desiredFrameMap[nodeNames[i]].p.y()
00109 << "," << desiredFrameMap[nodeNames[i]].p.z()
00110 << "," << desiredFrameMap[nodeNames[i]].M.GetRot().x()
00111 << "," << desiredFrameMap[nodeNames[i]].M.GetRot().y()
00112 << "," << desiredFrameMap[nodeNames[i]].M.GetRot().z() << ")";
00113 }
00114 }
00115
00121 bool KdlTreeTr::findFrameTwist(const JntArray& jointIn)
00122 {
00123
00124 fkPosSolverPtr->getPoses(jointIn, currentFrameMap);
00125
00126 bool converged = true;
00127
00128
00129 for (FrameMapItr nodeFrameItr = desiredFrameMap.begin(); nodeFrameItr != desiredFrameMap.end(); ++nodeFrameItr)
00130 {
00132 FrameMapItr frameItr = currentFrameMap.find(nodeFrameItr->first);
00133
00134 if (frameItr == currentFrameMap.end())
00135 {
00136 std::stringstream err;
00137 err << "node name (" << frameItr->first << ") not found in frame map" << std::endl;
00138 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr.findFrameTwist", log4cpp::Priority::ERROR, err.str());
00139 throw std::runtime_error(err.str());
00140 }
00141
00143 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.findFrameTwist") << log4cpp::Priority::DEBUG << "Current pose:"
00144 << frameItr->second.p.x() << ", " << frameItr->second.p.y() << ", " << frameItr->second.p.z() << ", "
00145 << frameItr->second.M.GetRot().x() << ", " << frameItr->second.M.GetRot().y() << ", " << frameItr->second.M.GetRot().z();
00146
00147 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.findFrameTwist") << log4cpp::Priority::DEBUG << "Desired pose:"
00148 << nodeFrameItr->second.p.x() << ", " << nodeFrameItr->second.p.y() << ", " << nodeFrameItr->second.p.z() << ", "
00149 << nodeFrameItr->second.M.GetRot().x() << ", " << nodeFrameItr->second.M.GetRot().y() << ", " << nodeFrameItr->second.M.GetRot().z();
00150
00151 Twist twist = diff(frameItr->second, nodeFrameItr->second);
00152 limitTaskTwist(twist);
00153
00155 TwistMapItr twistItr = twistMap.find(nodeFrameItr->first);
00156
00157 if (twistItr == twistMap.end())
00158 {
00159 std::stringstream err;
00160 err << "node name (" << nodeFrameItr->first << ") not found in twist map" << std::endl;
00161 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr.findFrameTwist", log4cpp::Priority::ERROR, err.str());
00162 throw std::runtime_error(err.str());
00163 }
00164
00165 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.findFrameTwist") << log4cpp::Priority::DEBUG << "Twist for " << nodeFrameItr->first << ":";
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 for (int i = 0; i < 6; ++i)
00210 {
00211 if (isnan(twist[i]))
00212 {
00213 throw std::runtime_error("nan in twist found");
00214 }
00215
00216
00217
00218
00219 if (twistItr->second.second[i] <= LOW && !(std::abs(twist[i]) < eps || std::abs(twistItr->second.first[i] - twist[i]) < eps ))
00220 {
00221 converged = false;
00222 }
00223
00224
00225
00226
00227
00228
00229 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.findFrameTwist") << log4cpp::Priority::DEBUG << twist[i] << ", " << std::abs(twistItr->second.first[i] - twist[i]);
00230 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.findFrameTwist") << log4cpp::Priority::DEBUG << twist[i] << ", " << twistItr->second.second[i];
00231 }
00232
00233 twistItr->second.first = twist;
00234 }
00235
00236
00237 return converged;
00238
00239 }
00240
00241
00242 bool KdlTreeTr::limitTaskTwist(KDL::Twist& twist)
00243 {
00244 bool changed = false;
00245
00246 for (int i = 0; i < 6; ++i)
00247 {
00248 if (twist[i] > maxTwist)
00249 {
00250 twist[i] = maxTwist;
00251 changed = true;
00252 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.limitTaskTwist") << log4cpp::Priority::DEBUG << i << ", " << twist[i] << ", limited to " << maxTwist;
00253 }
00254
00255 if (twist[i] < -maxTwist)
00256 {
00257 twist[i] = -maxTwist;
00258 changed = true;
00259 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.limitTaskTwist") << log4cpp::Priority::DEBUG << i << ", " << twist[i] << ", limited to " << -maxTwist;
00260 }
00261 }
00262
00263 return changed;
00264 }
00265
00266 bool KdlTreeTr::limitTaskTwist(VectorXd& twist)
00267 {
00268 bool changed = false;
00269
00270 for (int i = 0; i < 6; ++i)
00271 {
00272 if (twist[i] > maxTwist)
00273 {
00274 twist[i] = maxTwist;
00275 changed = true;
00276 }
00277
00278 if (twist[i] < -maxTwist)
00279 {
00280 twist[i] = -maxTwist;
00281 changed = true;
00282 }
00283 }
00284
00285 return changed;
00286 }
00287
00296 void KdlTreeTr::getJointPositions(const JntArray& jointIn, const vector<string>& nodeNames,
00297 const vector<Frame>& nodeFrames, JntArray& jointsOut,
00298 const vector<NodePriority>& nodePriorities)
00299 {
00300 if (this->nodeNames != nodeNames || this->nodePriorities != nodePriorities)
00301 {
00302 this->nodeNames = nodeNames;
00303 this->nodePriorities = nodePriorities;
00304 createFrameTwistMaps(nodeFrames, nodePriorities);
00305 }
00306
00307 updateNodeFrameMap(nodeFrames);
00308
00309 numJoints = jointIn.rows();
00310
00311 KDL::JntArray deltaJoints(numJoints);
00312 jointsOut = jointIn;
00313 unsigned int i;
00314
00315 for (i = 0; i < critMaxIter; ++i)
00316 {
00317 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.getJointPositions") << log4cpp::Priority::INFO << "entering loop " << i;
00318
00319 if (findFrameTwist(jointsOut))
00320 {
00321 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.getJointPositions") << log4cpp::Priority::INFO << "converged " << i;
00322 break;
00323 }
00324
00326 getTaskReconstruction(jointsOut, deltaJoints);
00327
00328 for (unsigned int jointIndex = 0; jointIndex < jointsOut.rows(); ++jointIndex)
00329 {
00330 jointsOut(jointIndex) += deltaJoints(jointIndex);
00331 }
00332 }
00333
00336 limitJoints(jointIn, jointsOut, deltaJoints);
00337
00340 std::stringstream err;
00341 err << "Unable to find a good TR solution.. " << std::endl;
00342
00343 if (!isTaskAchieved(jointsOut, err))
00344 {
00345 if (momLim)
00346 {
00347 err << "mom below limit" << std::endl;
00348
00350 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr.getJointPositions", log4cpp::Priority::ERROR, err.str());
00351 throw std::runtime_error(err.str());
00352 }
00353
00354 }
00355 }
00356
00357 bool KdlTreeTr::isTaskAchieved(const KDL::JntArray& jointIn, stringstream& errMsg)
00358 {
00359 fkPosSolverPtr->getPoses(jointIn, currentFrameMap);
00360
00361 bool achieved = true;
00362
00363 for (FrameMapItr nodeFrameItr = desiredFrameMap.begin(); nodeFrameItr != desiredFrameMap.end(); ++nodeFrameItr)
00364 {
00366 FrameMapItr frameItr = currentFrameMap.find(nodeFrameItr->first);
00367
00368 if (frameItr == currentFrameMap.end())
00369 {
00370 std::stringstream err;
00371 err << "node name (" << frameItr->first << ") not found in frame map" << std::endl;
00372 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr.isTaskAchieved", log4cpp::Priority::ERROR, err.str());
00373 throw std::runtime_error(err.str());
00374 }
00375
00377 Twist twist = diff(frameItr->second, nodeFrameItr->second);
00378 limitTaskTwist(twist);
00379
00381 TwistMapItr twistItr = twistMap.find(nodeFrameItr->first);
00382
00383 if (twistItr == twistMap.end())
00384 {
00385 std::stringstream err;
00386 err << "node name (" << nodeFrameItr->first << ") not found in twist map" << std::endl;
00387 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr.isTaskAchieved", log4cpp::Priority::ERROR, err.str());
00388 throw std::runtime_error(err.str());
00389 }
00390
00391 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.isTaskAchieved") << log4cpp::Priority::DEBUG << "Twist for " << nodeFrameItr->first << ":";
00392
00393 for (int i = 0; i < 3; ++i)
00394 {
00395 if (isnan(twist.vel[i]))
00396 {
00397 throw std::runtime_error("nan in twist vel found");
00398 }
00399
00400 if (priorityTolMap.find((unsigned int)twistItr->second.second.vel[i]) != priorityTolMap.end())
00401 {
00402 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.isTaskAchieved") << log4cpp::Priority::DEBUG << "tolerence: " << priorityTolMap.at(twistItr->second.second.vel[i]).first;
00403
00404 if (fabs(twist.vel[i]) > priorityTolMap.at(twistItr->second.second.vel[i]).first)
00405 {
00406 errMsg << nodeFrameItr->first << " exceeds tolerence on axis " << i << ". Value: " << abs(twist.vel[i]) << ", Tol: " << priorityTolMap.at(twistItr->second.second.vel[i]).second << std::endl;
00407 achieved = false;
00408 }
00409 }
00410
00411 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.isTaskAchieved") << log4cpp::Priority::DEBUG << "new twist: " << twist.vel[i] << ", " << fabs(twistItr->second.first.vel[i] - twist.vel[i]);
00412 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.isTaskAchieved") << log4cpp::Priority::DEBUG << "priority: " << twist.vel[i] << ", " << twistItr->second.second.vel[i];
00413 }
00414
00415 for (int i = 0; i < 3; ++i)
00416 {
00417 if (isnan(twist.rot[i]))
00418 {
00419 throw std::runtime_error("nan in twist ang found");
00420 }
00421
00422 if (priorityTolMap.find((unsigned int)twistItr->second.second.rot[i]) != priorityTolMap.end())
00423 {
00424 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.isTaskAchieved") << log4cpp::Priority::DEBUG << "tolerence: " << priorityTolMap.at(twistItr->second.second.rot[i]).second;
00425
00426 if (fabs(twist.rot[i]) > priorityTolMap.at(twistItr->second.second.rot[i]).second)
00427 {
00428 errMsg << nodeFrameItr->first << " exceeds tolerence on axis " << i << ". Value: " << abs(twist.rot[i]) << ", Tol: " << priorityTolMap.at(twistItr->second.second.rot[i]).second << std::endl;
00429 achieved = false;
00430 }
00431 }
00432
00433 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.isTaskAchieved") << log4cpp::Priority::DEBUG << "new twist: " << twist.rot[i] << ", " << fabs(twistItr->second.first.rot[i] - twist.rot[i]);
00434 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.isTaskAchieved") << log4cpp::Priority::DEBUG << "priority: " << twist.rot[i] << ", " << twistItr->second.second.rot[i];
00435 }
00436
00437 twistItr->second.first = twist;
00438 }
00439
00440 return achieved;
00441 }
00442
00451 void KdlTreeTr::getTaskReconstruction(const KDL::JntArray& jointIn, KDL::JntArray& joint_deltas)
00452 {
00453 MatrixXd J;
00454 MatrixXd Jh;
00455 MatrixXd Jhi;
00456 VectorXd dr;
00457 VectorXd drh;
00458 VectorXd drhp;
00459 MatrixXd N = MatrixXd::Identity(numJoints, numJoints);
00460 VectorXd dq = VectorXd::Zero(numJoints);
00461
00462
00463 MatrixXd L;
00464 MatrixXd Li;
00465 double mom;
00466
00467
00468
00469 getOrderedTasksByPriority(jointIn);
00470
00472
00473
00474 for (unsigned int i = 0; i < taskList.size(); ++i)
00475 {
00476 mom = 0;
00477 J = taskList[i].first;
00478 dr = taskList[i].second;
00479 numConstraints = dr.rows();
00480
00481
00482 pInv(jacJntWeights, ijacJntWeights, mom);
00483 Jh = J * N;
00484 L = Jh * ijacJntWeights * Jh.transpose();
00485 pInv(L, Li, mom);
00486 Jhi = ijacJntWeights * Jh.transpose() * Li;
00487 N = N - Jhi * Jh;
00488 drh = dr - J * dq;
00489
00490
00491
00492
00493
00494
00495
00496 if (mom != 0)
00497 {
00498 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.getTaskReconstruction") << log4cpp::Priority::DEBUG << "mom:" << mom;
00499 modifyToAvoidSingularities(getBiasVector(jointIn.data, dq, Jhi), mom, drh, drhp);
00500 dq = dq + Jhi * drhp;
00501 }
00502 else
00503 {
00504 std::stringstream err;
00505 err << "Unable to find a good TR solution -- MOM is zero." << std::endl;
00506 err << "This only happens if:" << std::endl;
00507 err << "\ta) You are attempting to control the same axis twice in the same trajectory" << std::endl;
00508 err << "\tb) You are attempting to control an axis which can not move" << std::endl;
00509 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr.getTaskReconstruction", log4cpp::Priority::ERROR, err.str());
00510 throw std::runtime_error(err.str());
00511 }
00512 }
00513
00514 joint_deltas.data = dq;
00515 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.getTaskReconstruction") << log4cpp::Priority::DEBUG << "dq:" << joint_deltas.data;
00516
00517
00518
00519
00520
00521
00522 }
00523
00534 void KdlTreeTr::getOrderedTasksByPriority(const JntArray& jointIn)
00535 {
00536
00537 std::map<std::string, KDL::Jacobian> nameJacobianMap;
00538 Jacobian jac(numJoints);
00539
00540 for (TwistMapItr twistIt = twistMap.begin(); twistIt != twistMap.end(); ++twistIt)
00541 {
00542 int ret = jacSolverPtr->JntToJac(jointIn, jac, twistIt->first);
00543
00544 if (ret < 0)
00545 {
00546 std::stringstream err;
00547 err << "unable to find Jacobian for Twist: " << twistIt->first << ", probably due to incorrectly initialized jacobian size" << std::endl;
00548 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr.getOrderedTasksByPriority", log4cpp::Priority::ERROR, err.str());
00549 throw std::runtime_error(err.str());
00550 }
00551
00552 nameJacobianMap[twistIt->first] = jac;
00553 }
00554
00555 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.getOrderedTasksByPriority") << log4cpp::Priority::DEBUG << "solved for jacobians";
00556
00557 taskList.clear();
00558
00559 for (PriorityTaskAxisItr ptaItr = priorityTaskAxisMap.begin(); ptaItr != priorityTaskAxisMap.end(); ++ptaItr)
00560 {
00561 int priorityNum = ptaItr->first;
00562 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.getOrderedTasksByPriority") << log4cpp::Priority::DEBUG << "Finding task for priority #" << priorityNum;
00563
00564 if (priorityNum == IGNORE)
00565 {
00566 continue;
00567 }
00568
00569 Task mTask;
00570 int priorityCount = priorityTaskAxisMap.count(priorityNum);
00571 mTask.first.resize(priorityCount, numJoints);
00572 mTask.second.resize(priorityCount);
00573
00574 for (int i = 0; i < priorityCount; ++i)
00575 {
00576 string nodeName = ptaItr->second.first;
00577 int axis = ptaItr->second.second;
00578 mTask.first.block(i, 0, 1, numJoints) = nameJacobianMap[nodeName].data.block(axis, 0, 1, numJoints);
00579 mTask.second[i] = twistMap[nodeName].first[axis];
00580 ++ptaItr;
00581 }
00582
00583 taskList.push_back(mTask);
00584 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.getOrderedTasksByPriority") << log4cpp::Priority::DEBUG << "task #" << priorityNum << ":\n\r" << mTask.second;
00585
00586 if (priorityCount > 0)
00587 {
00588 --ptaItr;
00589 }
00590
00591
00592 }
00593
00594
00595
00596 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.getOrderedTasksByPriority") << log4cpp::Priority::DEBUG << "Found " << taskList.size() << " tasks";
00597 }
00598
00605 void KdlTreeTr::getOrderedTasksByFrame(const JntArray& jointIn)
00606 {
00607 TwistMapItr twistMapItr;
00608 KDL::RotationalInertia ri;
00609 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr.getOrderedTasksByFrame", log4cpp::Priority::DEBUG, "Ordered task list by frame:");
00610
00611 if (taskList.size() != nodeNames.size())
00612 {
00613 taskList.resize(nodeNames.size());
00614 }
00615
00616 for (unsigned int i = 0; i < nodeNames.size(); ++i)
00617 {
00618 if ((twistMapItr = twistMap.find(nodeNames[i])) == twistMap.end())
00619 {
00620 std::stringstream err;
00621 err << "could not find twist for frame: " << nodeNames[i] << std::endl;
00622 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr.getOrderedTasksByFrame", log4cpp::Priority::ERROR, err.str());
00623 throw std::runtime_error(err.str());
00624 }
00625
00626 TwistPriority twistPriority = twistMapItr->second;
00627
00628 numConstraints = 0;
00629
00630 for (int j = 0; j < 6; ++j)
00631 {
00632 if (twistPriority.second[j] != IGNORE)
00633 {
00634 ++numConstraints;
00635 }
00636 }
00637
00638 if (numConstraints != 0)
00639 {
00640 MatrixXd J = MatrixXd::Zero(numConstraints, numJoints);
00641 VectorXd dr(numConstraints);
00642 Jacobian jac(numJoints);
00643
00644
00645 int ret = jacSolverPtr->JntToJac(jointIn, jac, twistMapItr->first);
00646
00647 if (ret < 0)
00648 {
00649 std::stringstream err;
00650 err << "unable to find a Jacobian for Twist: " << twistMapItr->first << std::endl;
00651 err << "jointIn : " << jointIn.data;
00652 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr.getOrderedTasksByFrame", log4cpp::Priority::ERROR, err.str());
00653 throw std::runtime_error(err.str());
00654 }
00655
00656
00657
00658 int jacIndex = 0;
00659
00660 for (int j = 0; j < 6; ++j)
00661 {
00662 if (twistPriority.second[j] != IGNORE)
00663 {
00664 J.block(jacIndex, 0, 1, numJoints) = jac.data.block(j, 0, 1, numJoints);
00665 dr[jacIndex] = twistPriority.first[j];
00666 ++jacIndex;
00667 }
00668 }
00669
00670 taskList[i] = std::make_pair(J, dr);
00671 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.getOrderedTasksByFrame") << log4cpp::Priority::DEBUG << "task " << nodeNames[i] << ":\n\r" << dr;
00672 }
00673
00674 }
00675
00676 return;
00677 }
00678
00679 KdlTreeTr::Task KdlTreeTr::getCenterJointsTask(const JntArray& jointIn)
00680 {
00681
00682 std::map<std::string, double>::const_iterator minIt;
00683 std::map<std::string, double>::const_iterator maxIt;
00684 JntArray q(numJoints);
00686 std::pair<double, double> limits;
00687
00688 for (int jointIndex = 0; jointIndex < numJoints; ++jointIndex)
00689 {
00690 if (positionLimiter->getLimits(jointNames.at(jointIndex), limits))
00691 {
00692 q(jointIndex) = (limits.first + limits.second) / 2.;
00693 }
00694 else
00695 {
00696 std::stringstream err;
00697 err << "in getCenterJointsTask() unable to find the min/max for joint: " << jointNames.at(jointIndex);
00698 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr", log4cpp::Priority::ERROR, err.str());
00699 throw std::runtime_error(err.str());
00700 }
00701 }
00702
00703 std::map<std::string, KDL::Frame> centerFrameMap;
00704 fkPosSolverPtr->getPoses(q, centerFrameMap);
00705 std::map<std::string, KDL::Frame> currentFrameMap;
00706 fkPosSolverPtr->getPoses(jointIn, currentFrameMap);
00707
00708 MatrixXd bigJac(6 * centerFrameMap.size(), numJoints);
00709 VectorXd bigTwist(6 * centerFrameMap.size());
00710 int jacIndex = 0;
00711
00712 for (FrameMapItr frameItr = currentFrameMap.begin(); frameItr != currentFrameMap.end(); ++frameItr)
00713 {
00714 FrameMapItr nodeFrameItr;
00715
00716 if ((nodeFrameItr = centerFrameMap.find(frameItr->first)) != centerFrameMap.end())
00717 {
00719 Twist twist = diff(frameItr->second, nodeFrameItr->second);
00720
00721 for (int twistIdx = 0; twistIdx < 6; ++twistIdx)
00722 {
00724 if (isnan(twist[twistIdx]))
00725 {
00726 twist[twistIdx] = 0;
00727 }
00728 }
00729
00731 Jacobian jac;
00732 int ret = jacSolverPtr->JntToJac(jointIn, jac, frameItr->first);
00733
00734 if (ret < 0)
00735 {
00736 std::stringstream err;
00737 err << "in getCenterJointsTask() unable to find a Jacobian for Twist: " << frameItr->first << std::endl;
00738 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr", log4cpp::Priority::ERROR, err.str());
00739 throw std::runtime_error(err.str());
00740 }
00741
00743 for (unsigned int i = 0; i < 6; ++i)
00744 {
00745 bigJac.block(jacIndex, 0, 1, numJoints) = jac.data.block(i, 0, 1, numJoints);
00746 bigTwist[jacIndex] = twist[i];
00747 ++jacIndex;
00748 }
00749
00750 }
00751 else
00752 {
00753 std::stringstream err;
00754 err << "in CenterJointsTask() unable to find the center frame for joint: " << frameItr->first;
00755 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr", log4cpp::Priority::ERROR, err.str());
00756 throw std::runtime_error(err.str());
00757 }
00758
00759 }
00760
00761 return Task(bigJac, bigTwist);
00762 }
00763
00764
00771 void KdlTreeTr::modifyToAvoidSingularities(const VectorXd& nm, const double mom, const VectorXd& dr, VectorXd& drp)
00772 {
00773 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.modifyToAvoidSingularities") << log4cpp::Priority::DEBUG << "entered modifyToAvoidSingularities(const VectorXd& nm, const double mom, const VectorXd& dr, VectorXd& drp)";
00774 MatrixXd Im(numConstraints, numConstraints);
00775 MatrixXd Mtemp;
00776 double k1;
00777 double k2;
00778 VectorXd drp_temp;
00779 momLim = false;
00780
00781
00782 k1 = 0.5 * (1 - sign(dr.dot(nm))) * boundedCubic(mom, 1, 0, mbar, 2 * mbar);
00783
00784 k2 = Kr * boundedCubic(mom, 1, 0, 0.5 * mbar, mbar);
00785
00786 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.modifyToAvoidSingularities") << log4cpp::Priority::DEBUG << "k1: " << k1;
00787 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.modifyToAvoidSingularities") << log4cpp::Priority::DEBUG << "k2: " << k2;
00788 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.modifyToAvoidSingularities") << log4cpp::Priority::DEBUG << "mbar: " << mbar;
00789 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.modifyToAvoidSingularities") << log4cpp::Priority::DEBUG << "boundedCubic k1: " << boundedCubic(mom, 1, 0, mbar, 2 * mbar);
00790 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.modifyToAvoidSingularities") << log4cpp::Priority::DEBUG << "boundedCubic k2: " << boundedCubic(mom, 1, 0, eps, mbar);
00791 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.modifyToAvoidSingularities") << log4cpp::Priority::DEBUG << "task size: " << taskList.size();
00792 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.modifyToAvoidSingularities") << log4cpp::Priority::INFO << "mom: " << mom;
00793
00794 if (k1 > 0 || k2 > 0)
00795 {
00796 momLim = true;
00797 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.modifyToAvoidSingularities") << log4cpp::Priority::INFO << "k1: " << k1;
00798 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.modifyToAvoidSingularities") << log4cpp::Priority::INFO << "k2: " << k2;
00799 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.modifyToAvoidSingularities") << log4cpp::Priority::INFO << "nm\n" << nm;
00800 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.modifyToAvoidSingularities") << log4cpp::Priority::INFO << "mom: " << mom;
00801 }
00802
00803 Im.setIdentity(numConstraints, numConstraints);
00804
00805 Mtemp = Im - k1 * (nm * nm.transpose());
00806
00807 drp_temp = Mtemp * dr;
00808
00809 drp = drp_temp + k2 * nm;
00810
00811
00812
00813
00814
00815
00816 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.modifyToAvoidSingularities") << log4cpp::Priority::DEBUG << "drp: " << drp;
00817
00818
00819
00820
00821 }
00822
00829 bool KdlTreeTr::limitJoints(const JntArray& jointIn, JntArray& jointsOut, JntArray& deltaJoints)
00830 {
00832 velocityLim = false;
00833 jointLim = false;
00834 double velocityLimitFactor = 1.0;
00835 double jointLimBuffer, jointMaxVel;
00836 std::string whichJoint;
00837
00838
00839
00840 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.limitJoints") << log4cpp::Priority::INFO << "Time step: " << timeStep << " Max Decel: " << jointMaxDecel;
00841
00842 for (unsigned int jointIndex = 0; jointIndex < jointsOut.rows(); ++jointIndex)
00843 {
00844 double newJointPos = jointsOut(jointIndex);
00845 deltaJoints(jointIndex) = newJointPos - jointIn(jointIndex);
00846
00847 if (positionLimiter->getMaxVelocity(jointNames.at(jointIndex), jointMaxVel))
00848 {
00849 jointLimBuffer = 0.5;
00850 jointMaxVel *= timeStep;
00851 }
00852 else
00853 {
00854 jointMaxVel = 100000.0;
00855 jointLimBuffer = 0.1 ;
00856 }
00857
00858 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.limitJoints") << log4cpp::Priority::INFO << jointNames.at(jointIndex) << " max vel: " << jointMaxVel << " and jointLimBuf: " << jointLimBuffer;
00859 double absPosDiff = std::abs(deltaJoints(jointIndex));
00860 std::pair<double, double> limits;
00861
00862 if (positionLimiter->getLimits(jointNames.at(jointIndex), limits))
00863 {
00864 if (newJointPos <= (limits.first + jointLimBuffer) && sign(deltaJoints(jointIndex)) < 0 && deltaJoints(jointIndex) != 0)
00865 {
00866
00867 double distToLimit = newJointPos - limits.first;
00868
00869 if (distToLimit > 0)
00870 {
00871 jointMaxVel = jointMaxVel * distToLimit / jointLimBuffer ;
00872 }
00873 else
00874 {
00875 jointMaxVel = 0;
00876 jointLim = true;
00877 whichJoint = jointNames.at(jointIndex);
00878 }
00879 }
00880
00881 if (newJointPos >= (limits.second - jointLimBuffer) && sign(deltaJoints(jointIndex)) > 0 && deltaJoints(jointIndex) != 0)
00882 {
00883 double distToLimit = limits.second - newJointPos;
00884
00885 if (distToLimit > 0)
00886 {
00887 jointMaxVel = jointMaxVel * distToLimit / jointLimBuffer ;
00888 }
00889 else
00890 {
00891 jointMaxVel = 0;
00892 jointLim = true;
00893 whichJoint = jointNames.at(jointIndex);
00894 }
00895 }
00896 }
00897
00898 if (absPosDiff > jointMaxVel)
00899 {
00900 velocityLim = true;
00901 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.limitJoints") << log4cpp::Priority::INFO << jointNames.at(jointIndex) << ": " << absPosDiff << " near max vel " << jointMaxVel;
00902 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.limitJoints") << log4cpp::Priority::DEBUG << "current delta: " << deltaJoints(jointIndex);
00903
00904 if ( velocityLimitFactor > (jointMaxVel / absPosDiff) )
00905 {
00906 velocityLimitFactor = jointMaxVel / absPosDiff ;
00907 }
00908 }
00909 }
00910
00911 if (velocityLim)
00912 {
00913 for (unsigned int jointIndex = 0; jointIndex < jointsOut.rows(); ++jointIndex)
00914 {
00915 deltaJoints(jointIndex) = velocityLimitFactor * deltaJoints(jointIndex);
00916 jointsOut(jointIndex) = deltaJoints(jointIndex) + jointIn(jointIndex);
00917 }
00918 }
00919
00920 if (jointLim)
00921 {
00922 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.limitJoints") << log4cpp::Priority::WARN << "Joint Limit Reached on " << whichJoint;
00923 }
00924
00925 if (!jointLim && velocityLimitFactor < 0.1)
00926 {
00927 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.limitJoints") << log4cpp::Priority::NOTICE << "Approaching joint limit- velocityLimitFactor: " << velocityLimitFactor;
00928 }
00929
00930 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.limitJoints") << log4cpp::Priority::DEBUG << "jointsOut\n" << jointsOut.data;
00931 return velocityLim;
00932 }
00933
00934 VectorXd KdlTreeTr::getBiasVector(const VectorXd& jointIn, const VectorXd& joint_deltas, const MatrixXd& ijac)
00935 {
00936 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.getBiasVector") << log4cpp::Priority::DEBUG << "entered getBiasVector(const VectorXd& jointIn, const VectorXd& joint_deltas, const MatrixXd& ijac)";
00937 VectorXd bias = VectorXd::Zero(numJoints);
00938 VectorXd output = VectorXd::Zero(numConstraints);
00939
00940
00941 std::map<std::string, double>::const_iterator it;
00942 std::pair<double, double> limits;
00943
00944 for (int jointIndex = 0; jointIndex < numJoints; ++jointIndex)
00945 {
00946 limits.first = 0;
00947 limits.second = 0;
00948 positionLimiter->getLimits(jointNames.at(jointIndex), limits);
00949
00950
00951
00952 bias(jointIndex) = (limits.first + limits.second) * 0.5 - (jointIn(jointIndex) + joint_deltas(jointIndex));
00953 }
00954
00955 output = bias.transpose() * ijac;
00956
00957 if (output.norm() != 0)
00958 {
00959 output.normalize();
00960 }
00961
00963
00964 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.getBiasVector") << log4cpp::Priority::DEBUG << "output bias vector: \n\r" << output;
00966 return output;
00967 }
00968
00979 double KdlTreeTr::cubic(const double& q, const double& pLeft, const double& pRight, const double& ct1, const double& ct2)
00980 {
00981 double t1;
00982 double t12;
00983 double t17;
00984 double t2;
00985 double t24;
00986 double t25;
00987 double t30;
00988 double t31;
00989 double t36;
00990 double t7;
00991
00992 t1 = q * q;
00993 t2 = t1 * q;
00994 t7 = t1 * pRight;
00995 t12 = t1 * pLeft;
00996 t17 = ct1 * ct2;
00997 t24 = ct1 * ct1;
00998 t25 = t24 * ct1;
00999 t30 = ct2 * ct2;
01000 t31 = t30 * ct2;
01001 t36 = 2.0 * t2 * pRight - 2.0 * t2 * pLeft - 3.0 * t7 * ct1 - 3.0 * t7 * ct2 + 3.0 * t12 * ct1 + 3.0 * t12 *
01002 ct2 + 6.0 * t17 * q * pRight - 6.0 * t17 * q * pLeft + t25 * pRight - 3.0 * t24 * pRight * ct2 - pLeft * t31 +
01003 3.0 * pLeft * ct1 * t30;
01004 return (t36 / (-t31 - 3.0 * ct2 * t24 + t25 + 3.0 * ct1 * t30));
01005 }
01006
01019 double KdlTreeTr::boundedCubic(const double& q, const double& pLeft, const double& pRight, const double& ct1, const double& ct2)
01020 {
01021 if (q <= ct1)
01022 {
01023 return pLeft;
01024 }
01025 else if (ct2 <= q)
01026 {
01027 return pRight;
01028 }
01029 else
01030 {
01031 return cubic(q, pLeft, pRight, ct1, ct2);
01032 }
01033 }
01034
01035
01042 int KdlTreeTr::pInv(const MatrixXd& jacIn, MatrixXd& ijacOut, double& mom)
01043 {
01044 int numConstraints = jacIn.rows();
01045 int numJoints = jacIn.cols();
01046 double momcheck;
01047
01048 ijacOut.resize(numJoints, numConstraints);
01049
01050 VectorXd tmp(numJoints);
01051 VectorXd S(VectorXd::Zero(numJoints));
01052 MatrixXd U(MatrixXd::Identity(numConstraints, numJoints));
01053 MatrixXd V(MatrixXd::Identity(numJoints, numJoints));
01054
01055 if (KDL::svd_eigen_HH(jacIn, U, S, V, tmp, critMaxIter) < 0)
01056 {
01057 std::stringstream err;
01058 err << "in pInv() SVD calculation failed" << std::endl;
01059 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlTreeTr", log4cpp::Priority::ERROR, err.str());
01060 return -1;
01061 }
01062
01063 tmp = VectorXd::Zero(numJoints);
01064 mom = 1;
01065 momcheck = 1;
01066
01067
01068 for (int i = 0; i < min(numJoints, numConstraints); ++i)
01069 {
01070 if (S(i) != 0)
01071 {
01072 double is = 1 / S(i);
01073 tmp(i) = is;
01074 }
01075
01076
01077 mom *= S(i);
01078 }
01079
01080
01081 ijacOut = V * tmp.asDiagonal() * U.adjoint();
01082 mom = pow(mom, (double)1 / numConstraints);
01083
01084 momcheck = S.minCoeff() * S.maxCoeff();
01086
01087
01088 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.pInv") << log4cpp::Priority::DEBUG << "mom: " << mom;
01089 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.KdlTreeTr.pInv") << log4cpp::Priority::DEBUG << "momcehck: " << momcheck;
01091 mom = momcheck;
01092 return 0;
01093 }
01094