Body.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, AIST, the University of Tokyo and General Robotix Inc.
00003  * All rights reserved. This program is made available under the terms of the
00004  * Eclipse Public License v1.0 which accompanies this distribution, and is
00005  * available at http://www.eclipse.org/legal/epl-v10.html
00006  * Contributors:
00007  * National Institute of Advanced Industrial Science and Technology (AIST)
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     // delete sensors
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     // copy sensors
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     // do deep copy of extraJoint
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     // buffers for the unit vector method
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     // preserve and clear the joint accelerations
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     // preserve and clear the root link acceleration
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;   // dv = g, dw = 0
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); //  spatial acceleration caused by ang. acc.
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; // motor inertia
00397         ptr->ddq = 0.0;
00398     }
00399 
00400     // subtract the constant term
00401     for(int i = 0; i < out_M.cols(); ++i){
00402         out_M.col(i) -= b1;
00403     }
00404 
00405     // recover state
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  *  see Kajita et al. Humanoid Robot Ohm-sha,  p.210
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;  // Added by Rafa
00454         ptr->w  = parent->w  + sw * ptr->dq;  // Added by Rafa
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;        // Center of mass speed in world frame
00509     Vector3 P;          // Linear momentum of the link
00510     Vector3 L;          // Angular momentum with respect to the world frame origin 
00511     Vector3 Llocal; // Angular momentum with respect to the center of mass of the link
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         //L   = cross(link->wc, P) + link->R * link->I * trans(link->R) * link->w; 
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         // try reversed path
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     // prepare subm, submwc
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         // assuming there is no branch between base and root
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     // compute Jacobian
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     // prepare subm, submwc
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         // assuming there is no branch between base and root
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     // compute Jacobian
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 }


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Thu Apr 11 2019 03:30:15