00001
00002
00003
00004
00005
00006
00007
00008
00009
00015 #include "Body.h"
00016 #include "Link.h"
00017 #include "JointPath.h"
00018 #include "Sensor.h"
00019 #include "Light.h"
00020 #include "BodyCustomizerInterface.h"
00021 #include <hrpCollision/ColdetModel.h>
00022 #include <map>
00023 #include <cstdlib>
00024
00025 using namespace hrp;
00026 using namespace std;
00027
00028 static const bool PUT_DEBUG_MESSAGE = true;
00029
00030 static bool pluginsInDefaultDirectoriesLoaded = false;
00031
00032 #ifndef uint
00033 typedef unsigned int uint;
00034 #endif
00035
00036 namespace hrp {
00037
00038 class CustomizedJointPath : public JointPath
00039 {
00040 Body* body;
00041 int ikTypeId;
00042 bool isCustomizedIkPathReversed;
00043 virtual void onJointPathUpdated();
00044 public:
00045 CustomizedJointPath(Body* body, Link* baseLink, Link* targetLink);
00046 virtual ~CustomizedJointPath();
00047 virtual bool calcInverseKinematics(const Vector3& end_p, const Matrix33& end_R);
00048 virtual bool hasAnalyticalIK();
00049 };
00050 }
00051
00052
00053 Body::~Body()
00054 {
00055 if(customizerHandle){
00056 customizerInterface->destroy(customizerHandle);
00057 }
00058
00059 delete rootLink_;
00060
00061
00062 for(unsigned int sensorType =0; sensorType < numSensorTypes(); ++sensorType){
00063 int n = numSensors(sensorType);
00064 for(int i=0; i < n; ++i){
00065 Sensor* s = sensor(sensorType, i);
00066 if(s){
00067 Sensor::destroy(s);
00068 }
00069 }
00070 }
00071 }
00072
00073
00074 void Body::initialize()
00075 {
00076 rootLink_ = 0;
00077
00078 customizerHandle = 0;
00079 customizerInterface = 0;
00080 bodyHandleEntity.body = this;
00081 bodyHandle = &bodyHandleEntity;
00082 }
00083
00084
00085 Body::Body()
00086 : allSensors(Sensor::NUM_SENSOR_TYPES)
00087 {
00088 initialize();
00089
00090 rootLink_ = new Link;
00091 rootLink_->body = this;
00092
00093 defaultRootPosition.setZero();
00094 defaultRootAttitude.setIdentity();
00095 }
00096
00097
00098 Body::Body(const Body& org)
00099 : name_(org.name_),
00100 modelName_(org.modelName_),
00101 allSensors(Sensor::NUM_SENSOR_TYPES)
00102 {
00103 initialize();
00104
00105 setRootLink(new Link(*org.rootLink()));
00106
00107 defaultRootPosition = org.defaultRootPosition;
00108 defaultRootAttitude = org.defaultRootAttitude;
00109
00110
00111 std::map<Link*, int> linkToIndexMap;
00112
00113 for(unsigned int i=0; i < org.linkTraverse_.numLinks(); ++i){
00114 Link* lnk = org.linkTraverse_[i];
00115 linkToIndexMap[lnk] = i;
00116 }
00117
00118 int n = org.numSensorTypes();
00119 for(int sensorType = 0; sensorType < n; ++sensorType){
00120 for(unsigned int i=0; i < org.numSensors(sensorType); ++i){
00121 Sensor* orgSensor = org.sensor(sensorType, i);
00122 if (orgSensor){
00123 int linkIndex = linkToIndexMap[orgSensor->link];
00124 Link* newLink = linkTraverse_[linkIndex];
00125 Sensor* cloneSensor = createSensor(newLink, sensorType, orgSensor->id, orgSensor->name);
00126 *cloneSensor = *orgSensor;
00127 }
00128 }
00129 }
00130
00131
00132 for(size_t i=0; i < org.extraJoints.size(); ++i){
00133 const ExtraJoint& orgExtraJoint = org.extraJoints[i];
00134 ExtraJoint extraJoint(orgExtraJoint);
00135 for(int j=0; j < 2; ++j){
00136 extraJoint.link[j] = link(orgExtraJoint.link[j]->index);
00137 }
00138 }
00139
00140 if(org.customizerInterface){
00141 installCustomizer(org.customizerInterface);
00142 }
00143 }
00144
00145
00146 void Body::setRootLink(Link* link)
00147 {
00148 if(rootLink_){
00149 delete rootLink_;
00150 }
00151 rootLink_ = link;
00152
00153 updateLinkTree();
00154 }
00155
00156
00157 void Body::setDefaultRootPosition(const Vector3& p, const Matrix33& R)
00158 {
00159 defaultRootPosition = p;
00160 defaultRootAttitude = R;
00161 }
00162
00163
00164 void Body::getDefaultRootPosition(Vector3& out_p, Matrix33& out_R)
00165 {
00166 out_p = defaultRootPosition;
00167 out_R = defaultRootAttitude;
00168 }
00169
00170
00171 Link* Body::createEmptyJoint(int jointId)
00172 {
00173 Link* empty = new Link;
00174 empty->body = this;
00175 empty->jointId = jointId;
00176 empty->p.setZero();
00177 empty->R.setIdentity();
00178 empty->v.setZero();
00179 empty->w.setZero();
00180 empty->dv.setZero();
00181 empty->dw.setZero();
00182 empty->q = 0.0;
00183 empty->dq = 0.0;
00184 empty->ddq = 0.0;
00185 empty->u = 0.0;
00186 empty->a.setZero();
00187 empty->d.setZero();
00188 empty->b.setZero();
00189 empty->Rs.setIdentity();
00190 empty->m = 0.0;
00191 empty->I.setZero();
00192 empty->c.setZero();
00193 empty->wc.setZero();
00194 empty->vo.setZero();
00195 empty->dvo.setZero();
00196 empty->fext.setZero();
00197 empty->tauext.setZero();
00198 empty->Jm2 = 0.0;
00199 empty->ulimit = 0.0;
00200 empty->llimit = 0.0;
00201 empty->uvlimit = 0.0;
00202 empty->lvlimit = 0.0;
00203 empty->defaultJointValue = 0.0;
00204 empty->Ir = 0.0;
00205 empty->gearRatio = 1.0;
00206
00207 return empty;
00208 }
00209
00210
00211 void Body::updateLinkTree()
00212 {
00213 nameToLinkMap.clear();
00214 linkTraverse_.find(rootLink());
00215
00216 int n = linkTraverse_.numLinks();
00217 jointIdToLinkArray.clear();
00218 jointIdToLinkArray.resize(n, 0);
00219 int maxJointID = -1;
00220
00221 for(int i=0; i < n; ++i){
00222 Link* link = linkTraverse_[i];
00223 link->body = this;
00224 link->index = i;
00225 nameToLinkMap[link->name] = link;
00226
00227 int id = link->jointId;
00228 if(id >= 0){
00229 int size = jointIdToLinkArray.size();
00230 if(id >= size){
00231 jointIdToLinkArray.resize(id + 1, 0);
00232 }
00233 jointIdToLinkArray[id] = link;
00234 if(id > maxJointID){
00235 maxJointID = id;
00236 }
00237 }
00238 }
00239
00240 jointIdToLinkArray.resize(maxJointID + 1);
00241
00242 for(size_t i=0; i < jointIdToLinkArray.size(); ++i){
00243 if(!jointIdToLinkArray[i]){
00244 jointIdToLinkArray[i] = createEmptyJoint(i);
00245 std::cerr << "Warning: Model " << modelName_ <<
00246 " has empty joint ID in the valid IDs." << std::endl;
00247 }
00248 }
00249
00250 calcTotalMass();
00251
00252 isStaticModel_ = (rootLink_->jointType == Link::FIXED_JOINT && numJoints() == 0);
00253 }
00254
00255
00260 Link* Body::link(const std::string& name) const
00261 {
00262 NameToLinkMap::const_iterator p = nameToLinkMap.find(name);
00263 return (p != nameToLinkMap.end()) ? p->second : 0;
00264 }
00265
00266
00267 void Body::initializeConfiguration()
00268 {
00269 rootLink_->p = defaultRootPosition;
00270 rootLink_->setAttitude(defaultRootAttitude);
00271
00272 rootLink_->v.setZero();
00273 rootLink_->dv.setZero();
00274 rootLink_->w.setZero();
00275 rootLink_->dw.setZero();
00276 rootLink_->vo.setZero();
00277 rootLink_->dvo.setZero();
00278 rootLink_->constraintForces.clear();
00279
00280 int n = linkTraverse_.numLinks();
00281 for(int i=0; i < n; ++i){
00282 Link* link = linkTraverse_[i];
00283 link->u = 0.0;
00284 link->q = 0.0;
00285 link->dq = 0.0;
00286 link->ddq = 0.0;
00287 link->constraintForces.clear();
00288 }
00289
00290 calcForwardKinematics(true, true);
00291
00292 clearExternalForces();
00293 }
00294
00295
00296
00297 double Body::calcTotalMass()
00298 {
00299 totalMass_ = 0.0;
00300
00301 int n = linkTraverse_.numLinks();
00302 for(int i=0; i < n; ++i){
00303 totalMass_ += linkTraverse_[i]->m;
00304 }
00305
00306 return totalMass_;
00307 }
00308
00309
00310 Vector3 Body::calcCM()
00311 {
00312 totalMass_ = 0.0;
00313
00314 Vector3 mc(Vector3::Zero());
00315
00316 int n = linkTraverse_.numLinks();
00317 for(int i=0; i < n; i++){
00318 Link* link = linkTraverse_[i];
00319 link->wc = link->p + link->R * link->c;
00320 mc += link->m * link->wc;
00321 totalMass_ += link->m;
00322 }
00323
00324 return mc / totalMass_;
00325 }
00326
00327
00338 void Body::calcMassMatrix(dmatrix& out_M)
00339 {
00340
00341 dmatrix b1;
00342 dvector ddqorg;
00343 dvector uorg;
00344 Vector3 dvoorg;
00345 Vector3 dworg;
00346 Vector3 root_w_x_v;
00347 Vector3 g(0, 0, 9.8);
00348
00349 uint nJ = numJoints();
00350 int totaldof = nJ;
00351 if( !isStaticModel_ ) totaldof += 6;
00352
00353 out_M.resize(totaldof,totaldof);
00354 b1.resize(totaldof, 1);
00355
00356
00357 ddqorg.resize(nJ);
00358 uorg.resize(nJ);
00359 for(uint i = 0; i < nJ; ++i){
00360 Link* ptr = joint(i);
00361 ddqorg[i] = ptr->ddq;
00362 uorg [i] = ptr->u;
00363 ptr->ddq = 0.0;
00364 }
00365
00366
00367 dvoorg = rootLink_->dvo;
00368 dworg = rootLink_->dw;
00369 root_w_x_v = rootLink_->w.cross(rootLink_->vo + rootLink_->w.cross(rootLink_->p));
00370 rootLink_->dvo = g - root_w_x_v;
00371 rootLink_->dw.setZero();
00372
00373 setColumnOfMassMatrix(b1, 0);
00374
00375 if( !isStaticModel_ ){
00376 for(int i=0; i < 3; ++i){
00377 rootLink_->dvo[i] += 1.0;
00378 setColumnOfMassMatrix(out_M, i);
00379 rootLink_->dvo[i] -= 1.0;
00380 }
00381 for(int i=0; i < 3; ++i){
00382 rootLink_->dw[i] = 1.0;
00383 Vector3 dw_x_p = rootLink_->dw.cross(rootLink_->p);
00384 rootLink_->dvo -= dw_x_p;
00385 setColumnOfMassMatrix(out_M, i + 3);
00386 rootLink_->dvo += dw_x_p;
00387 rootLink_->dw[i] = 0.0;
00388 }
00389 }
00390
00391 for(uint i = 0; i < nJ; ++i){
00392 Link* ptr = joint(i);
00393 ptr->ddq = 1.0;
00394 int j = i + 6;
00395 setColumnOfMassMatrix(out_M, j);
00396 out_M(j, j) += ptr->Jm2;
00397 ptr->ddq = 0.0;
00398 }
00399
00400
00401 for(int i = 0; i < out_M.cols(); ++i){
00402 out_M.col(i) -= b1;
00403 }
00404
00405
00406 for(uint i = 0; i < nJ; ++i){
00407 Link* ptr = joint(i);
00408 ptr->ddq = ddqorg[i];
00409 ptr->u = uorg [i];
00410 }
00411 rootLink_->dvo = dvoorg;
00412 rootLink_->dw = dworg;
00413 }
00414
00415
00416 void Body::setColumnOfMassMatrix(dmatrix& out_M, int column)
00417 {
00418 Vector3 f;
00419 Vector3 tau;
00420
00421 calcInverseDynamics(rootLink_, f, tau);
00422
00423 if( !isStaticModel_ ){
00424 tau -= rootLink_->p.cross(f);
00425 out_M.block<6,1>(0, column) << f, tau;
00426 }
00427
00428 int n = numJoints();
00429 for(int i = 0; i < n; ++i){
00430 Link* ptr = joint(i);
00431 out_M(i + 6, column) = ptr->u;
00432 }
00433 }
00434
00435
00436
00437
00438
00439 void Body::calcInverseDynamics(Link* ptr, Vector3& out_f, Vector3& out_tau)
00440 {
00441 Link* parent = ptr->parent;
00442 if(parent){
00443 Vector3 dsv,dsw,sv,sw;
00444
00445 if(ptr->jointType != Link::FIXED_JOINT){
00446 sw.noalias() = parent->R * ptr->a;
00447 sv = ptr->p.cross(sw);
00448 }else{
00449 sw.setZero();
00450 sv.setZero();
00451 }
00452
00453 ptr->vo = parent->vo + sv * ptr->dq;
00454 ptr->w = parent->w + sw * ptr->dq;
00455
00456 dsv = parent->w.cross(sv) + parent->vo.cross(sw);
00457 dsw = parent->w.cross(sw);
00458
00459 ptr->dw = parent->dw + dsw * ptr->dq + sw * ptr->ddq;
00460 ptr->dvo = parent->dvo + dsv * ptr->dq + sv * ptr->ddq;
00461
00462 ptr->sw = sw;
00463 ptr->sv = sv;
00464 }
00465
00466 Vector3 c, P, L;
00467 Matrix33 I, c_hat;
00468
00469 c = ptr->R * ptr->c + ptr->p;
00470 I.noalias() = ptr->R * ptr->I * ptr->R.transpose();
00471 c_hat = hat(c);
00472 I.noalias() += ptr->m * c_hat * c_hat.transpose();
00473 P.noalias() = ptr->m * (ptr->vo + ptr->w.cross(c));
00474 L = ptr->m * c.cross(ptr->vo) + I * ptr->w;
00475
00476 out_f = ptr->m * (ptr->dvo + ptr->dw.cross(c)) + ptr->w.cross(P);
00477 out_tau = ptr->m * c.cross(ptr->dvo) + I * ptr->dw + ptr->vo.cross(P) + ptr->w.cross(L);
00478
00479 if(ptr->child){
00480 Vector3 f_c;
00481 Vector3 tau_c;
00482 calcInverseDynamics(ptr->child, f_c, tau_c);
00483 out_f += f_c;
00484 out_tau += tau_c;
00485 }
00486
00487 ptr->u = ptr->sv.dot(out_f) + ptr->sw.dot(out_tau);
00488
00489 if(ptr->sibling){
00490 Vector3 f_s;
00491 Vector3 tau_s;
00492 calcInverseDynamics(ptr->sibling, f_s, tau_s);
00493 out_f += f_s;
00494 out_tau += tau_s;
00495 }
00496 }
00497
00498
00503 void Body::calcTotalMomentum(Vector3& out_P, Vector3& out_L)
00504 {
00505 out_P.setZero();
00506 out_L.setZero();
00507
00508 Vector3 dwc;
00509 Vector3 P;
00510 Vector3 L;
00511 Vector3 Llocal;
00512
00513 int n = linkTraverse_.numLinks();
00514 for(int i=0; i < n; i++){
00515 Link* link = linkTraverse_[i];
00516
00517 dwc = link->v + link->w.cross(link->R * link->c);
00518
00519 P = link->m * dwc;
00520
00521
00522 Llocal.noalias() = link->I * link->R.transpose()*link->w;
00523 L = link->wc.cross(P) + link->R * Llocal;
00524
00525 out_P += P;
00526 out_L += L;
00527 }
00528 }
00529
00530 void Body::calcTotalMomentumFromJacobian(Vector3& out_P, Vector3& out_L)
00531 {
00532 out_P.setZero();
00533 out_L.setZero();
00534
00535 dmatrix J,H;
00536 calcCMJacobian(NULL,J);
00537 calcAngularMomentumJacobian(NULL,H);
00538
00539 dvector dq;
00540 int n = numJoints();
00541 dq.resize(n);
00542 for(int i=0; i < n; i++){
00543 Link* link = joint(i);
00544 dq[i] = link->dq;
00545 }
00546 dvector v;
00547 v.resize(n+3+3);
00548 v << dq, rootLink_->v, rootLink_->w;
00549
00550 out_P = totalMass_ * J * v;
00551 out_L = H * v;
00552 }
00553
00554 void Body::calcForwardKinematics(bool calcVelocity, bool calcAcceleration)
00555 {
00556 linkTraverse_.calcForwardKinematics(calcVelocity, calcAcceleration);
00557 }
00558
00559
00560 Light* Body::createLight(Link* link, int lightType, const std::string& name)
00561 {
00562 Light *light = new Light(link, lightType, name);
00563 nameToLightMap[name] = light;
00564 return light;
00565 }
00566
00567 Sensor* Body::createSensor(Link* link, int sensorType, int id, const std::string& name)
00568 {
00569 Sensor* sensor = 0;
00570
00571 if(sensorType < Sensor::NUM_SENSOR_TYPES && id >= 0){
00572
00573 SensorArray& sensors = allSensors[sensorType];
00574 int n = sensors.size();
00575 if(id >= n){
00576 sensors.resize(id + 1, 0);
00577 }
00578 sensor = sensors[id];
00579 if(sensor){
00580 std::cerr << "duplicated sensor Id is specified(id = "
00581 << id << ", name = " << name << ")" << std::endl;
00582
00583 nameToSensorMap.erase(sensor->name);
00584 } else {
00585 sensor = Sensor::create(sensorType);
00586 }
00587 if(sensor){
00588 sensor->id = id;
00589 sensors[id] = sensor;
00590 sensor->link = link;
00591 sensor->name = name;
00592 nameToSensorMap[name] = sensor;
00593 link->sensors.push_back(sensor);
00594 }
00595 }
00596
00597 return sensor;
00598 }
00599
00600 void Body::addSensor(Sensor* sensor, int sensorType, int id ){
00601 if(sensorType < Sensor::NUM_SENSOR_TYPES && id >= 0){
00602 SensorArray& sensors = allSensors[sensorType];
00603 int n = sensors.size();
00604 if(id >= n){
00605 sensors.resize(id + 1, 0);
00606 }
00607 Sensor* sameId = sensors[id];
00608 if(sameId){
00609 std::cerr << "duplicated sensor Id is specified(id = "
00610 << id << ", name = " << sensor->name << ")" << std::endl;
00611
00612 nameToSensorMap.erase(sameId->name);
00613 }
00614 sensors[id] = sensor;
00615 nameToSensorMap[sensor->name] = sensor;
00616 }
00617 }
00618
00619
00620 void Body::clearSensorValues()
00621 {
00622 for(unsigned int i=0; i < numSensorTypes(); ++i){
00623 for(unsigned int j=0; j < numSensors(i); ++j){
00624 if(sensor(i,j))
00625 sensor(i, j)->clear();
00626 }
00627 }
00628 }
00629
00630
00631 JointPathPtr Body::getJointPath(Link* baseLink, Link* targetLink)
00632 {
00633 if(customizerInterface && customizerInterface->initializeAnalyticIk){
00634 return JointPathPtr(new CustomizedJointPath(this, baseLink, targetLink));
00635 } else {
00636 return JointPathPtr(new JointPath(baseLink, targetLink));
00637 }
00638 }
00639
00640
00641 void Body::setVirtualJointForcesSub()
00642 {
00643 if(customizerInterface->setVirtualJointForces){
00644 customizerInterface->setVirtualJointForces(customizerHandle);
00645 }
00646 }
00647
00648
00649 void Body::clearExternalForces()
00650 {
00651 int n = linkTraverse_.numLinks();
00652 for(int i=0; i < n; ++i){
00653 Link* link = linkTraverse_[i];
00654 link->fext.setZero();
00655 link->tauext.setZero();
00656 }
00657 }
00658
00659
00660 void Body::updateLinkColdetModelPositions()
00661 {
00662 const int n = linkTraverse_.numLinks();
00663 for(int i=0; i < n; ++i){
00664 Link* link = linkTraverse_[i];
00665 if(link->coldetModel){
00666 link->coldetModel->setPosition(link->segmentAttitude(), link->p);
00667 }
00668 }
00669 }
00670
00671
00672 void Body::putInformation(std::ostream &out)
00673 {
00674 out << "Body: model name = " << modelName_ << " name = " << name_ << "\n\n";
00675
00676 int n = numLinks();
00677 for(int i=0; i < n; ++i){
00678 out << *link(i);
00679 }
00680 out << std::endl;
00681 }
00682
00683
00687 bool Body::installCustomizer()
00688 {
00689 if(!pluginsInDefaultDirectoriesLoaded){
00690 loadBodyCustomizers(bodyInterface());
00691 pluginsInDefaultDirectoriesLoaded = true;
00692 }
00693
00694 BodyCustomizerInterface* interface = findBodyCustomizer(modelName_);
00695
00696 return interface ? installCustomizer(interface) : false;
00697 }
00698
00699
00700 bool Body::installCustomizer(BodyCustomizerInterface * customizerInterface)
00701 {
00702 if(this->customizerInterface){
00703 if(customizerHandle){
00704 this->customizerInterface->destroy(customizerHandle);
00705 customizerHandle = 0;
00706 }
00707 this->customizerInterface = 0;
00708 }
00709
00710 if(customizerInterface){
00711 customizerHandle = customizerInterface->create(bodyHandle, modelName_.c_str());
00712 if(customizerHandle){
00713 this->customizerInterface = customizerInterface;
00714 }
00715 }
00716
00717 return (customizerHandle != 0);
00718 }
00719
00720
00721 std::ostream& operator<< (std::ostream& out, Body& body)
00722 {
00723 body.putInformation(out);
00724 return out;
00725 }
00726
00727
00728 static inline Link* extractLink(BodyHandle bodyHandle, int linkIndex)
00729 {
00730 return static_cast<BodyHandleEntity*>(bodyHandle)->body->link(linkIndex);
00731 }
00732
00733
00734 static int getLinkIndexFromName(BodyHandle bodyHandle, const char* linkName)
00735 {
00736 Body* body = static_cast<BodyHandleEntity*>(bodyHandle)->body;
00737 Link* link = body->link(linkName);
00738 return (link ? link->index : -1);
00739 }
00740
00741
00742 static const char* getLinkName(BodyHandle bodyHandle, int linkIndex)
00743 {
00744 return extractLink(bodyHandle, linkIndex)->name.c_str();
00745 }
00746
00747
00748 static double* getJointValuePtr(BodyHandle bodyHandle, int linkIndex)
00749 {
00750 return &(extractLink(bodyHandle,linkIndex)->q);
00751 }
00752
00753
00754 static double* getJointVelocityPtr(BodyHandle bodyHandle, int linkIndex)
00755 {
00756 return &(extractLink(bodyHandle, linkIndex)->dq);
00757 }
00758
00759
00760 static double* getJointTorqueForcePtr(BodyHandle bodyHandle, int linkIndex)
00761 {
00762 return &(extractLink(bodyHandle, linkIndex)->u);
00763 }
00764
00765
00766 BodyInterface* Body::bodyInterface()
00767 {
00768 static BodyInterface interface = {
00769 hrp::BODY_INTERFACE_VERSION,
00770 getLinkIndexFromName,
00771 getLinkName,
00772 getJointValuePtr,
00773 getJointVelocityPtr,
00774 getJointTorqueForcePtr,
00775 };
00776
00777 return &interface;
00778 }
00779
00780
00781 CustomizedJointPath::CustomizedJointPath(Body* body, Link* baseLink, Link* targetLink) :
00782 JointPath(baseLink, targetLink),
00783 body(body)
00784 {
00785 onJointPathUpdated();
00786 }
00787
00788
00789 CustomizedJointPath::~CustomizedJointPath()
00790 {
00791
00792 }
00793
00794
00795 void CustomizedJointPath::onJointPathUpdated()
00796 {
00797 ikTypeId = body->customizerInterface->initializeAnalyticIk(
00798 body->customizerHandle, baseLink()->index, endLink()->index);
00799 if(ikTypeId){
00800 isCustomizedIkPathReversed = false;
00801 } else {
00802
00803 ikTypeId = body->customizerInterface->initializeAnalyticIk(
00804 body->customizerHandle, endLink()->index, baseLink()->index);
00805 if(ikTypeId){
00806 isCustomizedIkPathReversed = true;
00807 }
00808 }
00809 }
00810
00811
00812 bool CustomizedJointPath::calcInverseKinematics(const Vector3& end_p, const Matrix33& end_R)
00813 {
00814 bool solved;
00815
00816 if(ikTypeId == 0 || isBestEffortIKMode){
00817
00818 solved = JointPath::calcInverseKinematics(end_p, end_R);
00819
00820 } else {
00821
00822 std::vector<double> qorg(numJoints());
00823
00824 for(unsigned int i=0; i < numJoints(); ++i){
00825 qorg[i] = joint(i)->q;
00826 }
00827
00828 const Link* targetLink = endLink();
00829 const Link* baseLink_ = baseLink();
00830
00831 Vector3 p_relative;
00832 Matrix33 R_relative;
00833 if(!isCustomizedIkPathReversed){
00834 p_relative.noalias() = baseLink_->R.transpose() * (end_p - baseLink_->p);
00835 R_relative.noalias() = baseLink_->R.transpose() * end_R;
00836 } else {
00837 p_relative.noalias() = end_R.transpose() * (baseLink_->p - end_p);
00838 R_relative.noalias() = end_R.transpose() * baseLink_->R;
00839 }
00840 solved = body->customizerInterface->
00841 calcAnalyticIk(body->customizerHandle, ikTypeId, p_relative, R_relative);
00842
00843 if(solved){
00844
00845 calcForwardKinematics();
00846
00847 Vector3 dp(end_p - targetLink->p);
00848 Vector3 omega(omegaFromRot((targetLink->R*targetLink->Rs).transpose() * end_R));
00849
00850 double errsqr = dp.dot(dp) + omega.dot(omega);
00851
00852 if(errsqr < maxIKErrorSqr){
00853 solved = true;
00854 } else {
00855 solved = false;
00856 for(unsigned int i=0; i < numJoints(); ++i){
00857 joint(i)->q = qorg[i];
00858 }
00859 calcForwardKinematics();
00860 }
00861 }
00862 }
00863
00864 return solved;
00865 }
00866
00867
00868 bool CustomizedJointPath::hasAnalyticalIK()
00869 {
00870 return (ikTypeId != 0);
00871 }
00872
00873 void Body::calcCMJacobian(Link *base, dmatrix &J)
00874 {
00875
00876 JointPathPtr jp;
00877 if (base){
00878 jp = getJointPath(rootLink(), base);
00879 Link *skip = jp->joint(0);
00880 skip->subm = rootLink()->m;
00881 skip->submwc = rootLink()->m*rootLink()->wc;
00882 Link *l = rootLink()->child;
00883 if (l){
00884 if (l != skip) {
00885 l->calcSubMassCM();
00886 skip->subm += l->subm;
00887 skip->submwc += l->submwc;
00888 }
00889 l = l->sibling;
00890 while(l){
00891 if (l != skip){
00892 l->calcSubMassCM();
00893 skip->subm += l->subm;
00894 skip->submwc += l->submwc;
00895 }
00896 l = l->sibling;
00897 }
00898 }
00899
00900
00901 for (unsigned int i=1; i<jp->numJoints(); i++){
00902 l = jp->joint(i);
00903 l->subm = l->parent->m + l->parent->subm;
00904 l->submwc = l->parent->m*l->parent->wc + l->parent->submwc;
00905 }
00906
00907 J.resize(3, numJoints());
00908 }else{
00909 rootLink()->calcSubMassCM();
00910 J.resize(3, numJoints()+6);
00911 }
00912
00913
00914 std::vector<int> sgn(numJoints(), 1);
00915 if (jp) {
00916 for (unsigned int i=0; i<jp->numJoints(); i++) sgn[jp->joint(i)->jointId] = -1;
00917 }
00918
00919 for (unsigned int i=0; i<numJoints(); i++){
00920 Link *j = joint(i);
00921 switch(j->jointType){
00922 case Link::ROTATIONAL_JOINT:
00923 {
00924 Vector3 omega(sgn[j->jointId]*j->R*j->a);
00925 Vector3 arm((j->submwc-j->subm*j->p)/totalMass_);
00926 Vector3 dp(omega.cross(arm));
00927 J.col(j->jointId) = dp;
00928 break;
00929 }
00930 case Link::SLIDE_JOINT:
00931 {
00932 Vector3 dp((j->subm/totalMass_)*sgn[j->jointId]*j->R*j->d);
00933 J.col(j->jointId) = dp;
00934 break;
00935 }
00936 default:
00937 std::cerr << "calcCMJacobian() : unsupported jointType("
00938 << j->jointType << ")" << std::endl;
00939 }
00940 }
00941 if (!base){
00942 int c = numJoints();
00943 J(0, c ) = 1.0; J(0, c+1) = 0.0; J(0, c+2) = 0.0;
00944 J(1, c ) = 0.0; J(1, c+1) = 1.0; J(1, c+2) = 0.0;
00945 J(2, c ) = 0.0; J(2, c+1) = 0.0; J(2, c+2) = 1.0;
00946
00947 Vector3 dp(rootLink()->submwc/totalMass_ - rootLink()->p);
00948 J(0, c+3) = 0.0; J(0, c+4) = dp(2); J(0, c+5) = -dp(1);
00949 J(1, c+3) = -dp(2); J(1, c+4) = 0.0; J(1, c+5) = dp(0);
00950 J(2, c+3) = dp(1); J(2, c+4) = -dp(0); J(2, c+5) = 0.0;
00951 }
00952 }
00953
00954 void Body::calcAngularMomentumJacobian(Link *base, dmatrix &H)
00955 {
00956
00957 JointPathPtr jp;
00958
00959 dmatrix M;
00960 calcCMJacobian(base, M);
00961 M.conservativeResize(3, numJoints());
00962 M *= totalMass();
00963
00964 if (base){
00965 jp = getJointPath(rootLink(), base);
00966 Link *skip = jp->joint(0);
00967 skip->subm = rootLink()->m;
00968 skip->submwc = rootLink()->m*rootLink()->wc;
00969 Link *l = rootLink()->child;
00970 if (l){
00971 if (l != skip) {
00972 l->calcSubMassCM();
00973 skip->subm += l->subm;
00974 skip->submwc += l->submwc;
00975 }
00976 l = l->sibling;
00977 while(l){
00978 if (l != skip){
00979 l->calcSubMassCM();
00980 skip->subm += l->subm;
00981 skip->submwc += l->submwc;
00982 }
00983 l = l->sibling;
00984 }
00985 }
00986
00987
00988 for (unsigned int i=1; i<jp->numJoints(); i++){
00989 l = jp->joint(i);
00990 l->subm = l->parent->m + l->parent->subm;
00991 l->submwc = l->parent->m*l->parent->wc + l->parent->submwc;
00992 }
00993
00994 H.resize(3, numJoints());
00995 }else{
00996 rootLink()->calcSubMassCM();
00997 H.resize(3, numJoints()+6);
00998 }
00999
01000
01001 std::vector<int> sgn(numJoints(), 1);
01002 if (jp) {
01003 for (unsigned int i=0; i<jp->numJoints(); i++) sgn[jp->joint(i)->jointId] = -1;
01004 }
01005
01006 for (unsigned int i=0; i<numJoints(); i++){
01007 Link *j = joint(i);
01008 switch(j->jointType){
01009 case Link::ROTATIONAL_JOINT:
01010 {
01011 Vector3 omega(sgn[j->jointId]*j->R*j->a);
01012 Vector3 Mcol = M.col(j->jointId);
01013 Matrix33 jsubIw;
01014 j->calcSubMassInertia(jsubIw);
01015 Vector3 dp = jsubIw*omega;
01016 if (j->subm!=0) dp += (j->submwc/j->subm).cross(Mcol);
01017 H.col(j->jointId) = dp;
01018 break;
01019 }
01020 case Link::SLIDE_JOINT:
01021 {
01022 if(j->subm!=0){
01023 Vector3 Mcol =M.col(j->jointId);
01024 Vector3 dp = (j->submwc/j->subm).cross(Mcol);
01025 H.col(j->jointId) = dp;
01026 }
01027 break;
01028 }
01029 default:
01030 std::cerr << "calcCMJacobian() : unsupported jointType("
01031 << j->jointType << ")" << std::endl;
01032 }
01033 }
01034 if (!base){
01035 int c = numJoints();
01036 H.block(0, c, 3, 3).setZero();
01037 Matrix33 Iw;
01038 rootLink_->calcSubMassInertia(Iw);
01039 H.block(0, c+3, 3, 3) = Iw;
01040 Vector3 cm = calcCM();
01041 Matrix33 cm_cross;
01042 cm_cross <<
01043 0.0, -cm(2), cm(1),
01044 cm(2), 0.0, -cm(0),
01045 -cm(1), cm(0), 0.0;
01046 H.block(0,0,3,c) -= cm_cross * M;
01047 }
01048 }