frame.cpp
Go to the documentation of this file.
00001 
00019 // TODO: split into several files
00020 
00021 #include <math.h>
00022 #include <iostream>
00023 #include <cstdlib>
00024 #include <cstring> 
00025 
00026 #include "frame.h"
00027 #include "log.h"
00028 
00029 using namespace std;
00030 
00031 #undef DEBUG_MESSAGES_FRAME_CPP
00032 
00033 namespace robotLibPbD {
00034 
00035 bool CFrameContainer::xmlToFrame(CFrame *frame, TiXmlElement* frameNode, bool create)
00036 {
00037   DataPairs dataPairs;
00038   return xmlToFrame(frame, frameNode, dataPairs, create);
00039 }
00040 
00041 
00042 int CFrameContainer::compareBase(CFrame* first, CFrame* second)
00043 {
00044   std::vector<CFrame*> firstFrames, secondFrames;
00045   
00046   while (first != NULL)
00047     {    
00048       firstFrames.push_back(first);
00049       first = first->getBase();
00050     }
00051 
00052   while (second != NULL)
00053     {    
00054       secondFrames.push_back(second);
00055       second = second->getBase();
00056     }
00057 
00058   for (unsigned int i=0; i<firstFrames.size(); i++)
00059     for (unsigned int j=0; j<secondFrames.size(); j++)
00060       {
00061         if (firstFrames[i] == secondFrames[j])
00062           {
00063             
00064             return firstFrames.size()-1 - i;
00065           }
00066       }
00067 
00068   return -1;
00069 }
00070 
00071 
00072 void CFrameContainer::resolve(std::vector<std::string> &in, std::vector<CFrame*> &out)
00073 {
00074   out.clear();
00075   for (unsigned int i=0; i<in.size(); i++)
00076     {
00077       int id = getFrameByName(in[i].c_str(), false);
00078       if (id >= 0)
00079         out.push_back(getFrame(id));
00080     }
00081 }
00082 
00083 
00084   void CFrame::setDofs(const std::vector<double> &dofs_min, const std::vector<double> &dofs_max)
00085   {
00086     this->dofs_min.clear();
00087     this->dofs_min = dofs_min;
00088     this->dofs_max.clear();
00089     this->dofs_max = dofs_max;
00090   }
00091 
00092 bool CFrameContainer::xmlToFrame(CFrame *frame, TiXmlElement* frameNode, DataPairs &additionalData, bool create)
00093 {
00094     // get min max
00095     std::vector<double> dofs_min(6), dofs_max(6);
00096     const char* dofs[6] = { "x", "y", "z", "rx", "ry", "rz" };
00097     for (unsigned int i=0; i<6 && i<dofs_min.size() && i<dofs_max.size(); i++)
00098     {
00099         dofs_min[i] = CConfiguration::getAttributeDouble(frameNode, printToString("min_%s", dofs[i]).c_str(), 0.0);
00100         dofs_max[i] = CConfiguration::getAttributeDouble(frameNode, printToString("max_%s", dofs[i]).c_str(), 0.0);
00101         //LOG_VERBOSE("min: %g max: %g\n", dofs_min[i], dofs_max[i]);
00102     }
00103     frame->setDofs(dofs_min, dofs_max);
00104 
00105 
00106     frame->setData(CConfiguration::getAttributeBoolean(frameNode, "data", false));
00107 
00108     double a,b,g,x,y,z, qx,qy,qz,qw;
00109     a = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "a", "0.0")).c_str());
00110     b = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "b", "0.0")).c_str());
00111     g = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "g", "0.0")).c_str());
00112     x = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "x", "0.0")).c_str());
00113     y = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "y", "0.0")).c_str());
00114     z = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "z", "0.0")).c_str());
00115 
00116 
00117     qx = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "qx", "0.0")).c_str());
00118     qy = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "qy", "0.0")).c_str());
00119     qz = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "qz", "0.0")).c_str());
00120     qw = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "qw", "0.0")).c_str());
00121 
00122     if (qx != 0.0 || qw != 0.0 || qw != 0.0 || qw != 0.0)
00123     {
00124         CVec quater;
00125         CMatrix pose;
00126 
00127         quater.x = qx;
00128         quater.y = qy;
00129         quater.z = qz;
00130         quater.w = qw;
00131         CMathLib::matrixFromQuaternion(quater, pose);
00132 
00133         CVec tmp;
00134         CMathLib::getOrientation(pose, tmp, tmp);
00135         a = tmp.x;
00136         b = tmp.y;
00137         g = tmp.z;
00138 
00139         a *= 180.0/M_PI;
00140         b *= 180.0/M_PI;
00141         g *= 180.0/M_PI;
00142     }
00143     else if (a == 0 && b == 0 && g == 0)
00144     {
00145         CMatrix mat, test;
00146         CVec tmp;
00147         double angle;
00148         tmp.x = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "rx", "0.0")).c_str());
00149         tmp.y = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "ry", "0.0")).c_str());
00150         tmp.z = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "rz", "0.0")).c_str());
00151         angle = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "ra", "0.0")).c_str());
00152 
00153         CMathLib::getMatrixFromRotation(mat, tmp, angle);
00154         CMathLib::getOrientation(mat, tmp, tmp);
00155         a = tmp.x;
00156         b = tmp.y;
00157         g = tmp.z;
00158 
00159         CMathLib::getRotation(test, tmp);
00160         test.invert();
00161         test.mul(test, mat);
00162 
00163         double dist = test.length();
00164         if (dist > 0.01)
00165         {
00166             LOG_VERBOSE("Error: xmlToFrame, matrix conversion failed, distance is %g\n", dist);
00167             a = 0.0;
00168             b = 0.0;
00169             g = 0.0;
00170         }
00171 
00172         a *= 180.0/M_PI;
00173         b *= 180.0/M_PI;
00174         g *= 180.0/M_PI;
00175     }
00176 
00177     CMatrix pose;
00178     pose.set(1.0, 0.0, 0.0, 0.0,
00179     0.0, 1.0, 0.0, 0.0,
00180     0.0, 0.0, 1.0, 0.0,
00181     0.0, 0.0, 0.0, 1.0);
00182     CMathLib::getRotation(pose, a*M_PI/180.0, b*M_PI/180.0, g*M_PI/180.0);
00183 
00184     if (a == 0 && b == 0 && g == 0)
00185     {
00186         pose.a[0] = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "a0", "1.0")).c_str());
00187         pose.a[1] = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "a1", "0.0")).c_str());
00188         pose.a[2] = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "a2", "0.0")).c_str());
00189 
00190         pose.a[4] = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "a4", "0.0")).c_str());
00191         pose.a[5] = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "a5", "1.0")).c_str());
00192         pose.a[6] = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "a6", "0.0")).c_str());
00193 
00194         pose.a[8] = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "a8", "0.0")).c_str());
00195         pose.a[9] = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "a9", "0.0")).c_str());
00196         pose.a[10] = atof(additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "a10", "1.0")).c_str());
00197     }
00198 
00199     pose.a[12] = x;
00200     pose.a[13] = y;
00201     pose.a[14] = z;
00202     frame->setPose(pose);
00203 
00204     char buffer[255];
00205     sprintf(buffer, "%s", additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "name", "")).c_str());
00206     frame->setName(buffer);
00207 
00208     // frame type
00209     frame->setFrameType(CFrame::FRAME_POSITION);
00210     sprintf(buffer, "%s", CConfiguration::getAttributeString(frameNode, "type", ""));
00211     if (strcasecmp(buffer, "velocity") == 0)
00212     {
00213         //LOG_VERBOSE("Frame: Type = VELOCITY\n");
00214         frame->setFrameType(CFrame::FRAME_VELOCITY);
00215     }
00216     sprintf(buffer, "%s", additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "base", "")).c_str());
00217 
00218     std::string tmp = buffer;
00219     std::vector<std::string> tokens;
00220     tokenize(tmp, tokens, " ");
00221     if (tokens.size() > 0)
00222     tmp = tokens.back();
00223     tokens.clear();
00224 
00225     sprintf(buffer, "%s", tmp.c_str());
00226 
00227     tokenize(tmp, tokens, ":");
00228     if (tokens.size() > 1)
00229     {
00230         if (strcasecmp(tokens[0].c_str(), "geometry") == 0)
00231         {
00232             frame->setBaseType(CFrame::BASE_GEOMETRY);
00233             frame->setBaseName(tokens[1].c_str());
00234         } else frame->setBaseName(buffer);
00235     } else frame->setBaseName(buffer);
00236 
00237 
00238     frame->setBase(NULL);
00239 
00240     switch (frame->getBaseType())
00241     {
00242         case CFrame::BASE_NORMAL:
00243         default:
00244         {
00245             if (strcasecmp(buffer, "") == 0)
00246             create = false;
00247 
00248             // create referenced base frame if it doesnt exist yet
00249             int i = getFrameByName(buffer, create);
00250             if (i >= 0)
00251             frame->setBase(frames[i]);
00252         }
00253     }
00254     return true;
00255 }
00256 
00257 
00258 void CFrameContainer::clear()
00259 {
00260   for (unsigned int i=0; i<frames.size(); i++)
00261     {
00262       frames[i]->setBase(NULL);
00263     }
00264 
00265   for (unsigned int i=0; i<frames.size(); i++)
00266     {
00267       delete frames[i];
00268     }
00269 
00270   frames.clear();
00271 }
00272 
00273 bool CFrameContainer::xmlToFrameCombination(CFrameCombination *frame, TiXmlElement* frameNode, DataPairs &additionalData, bool create)
00274 {
00275     double a,b,g,x,y,z;
00276     a = CConfiguration::getAttributeDouble(frameNode, "a", 0.0);
00277     b = CConfiguration::getAttributeDouble(frameNode, "b", 0.0);
00278     g = CConfiguration::getAttributeDouble(frameNode, "g", 0.0);
00279     x = CConfiguration::getAttributeDouble(frameNode, "x", 0.0);
00280     y = CConfiguration::getAttributeDouble(frameNode, "y", 0.0);
00281     z = CConfiguration::getAttributeDouble(frameNode, "z", 0.0);
00282 
00283     if (a == 0 && b == 0 && g == 0)
00284     {
00285         CMatrix mat, test;
00286         CVec tmp;
00287         double angle;
00288         tmp.x = CConfiguration::getAttributeDouble(frameNode, "rx", 0.0);
00289         tmp.y = CConfiguration::getAttributeDouble(frameNode, "ry", 0.0);
00290         tmp.z = CConfiguration::getAttributeDouble(frameNode, "rz", 0.0);
00291         angle = CConfiguration::getAttributeDouble(frameNode, "ra", 0.0);
00292         CMathLib::getMatrixFromRotation(mat, tmp, angle);
00293         CMathLib::getOrientation(mat, tmp, tmp);
00294         a = tmp.x;
00295         b = tmp.y;
00296         g = tmp.z;
00297 
00298         CMathLib::getRotation(test, tmp);
00299         test.invert();
00300         test.mul(test, mat);
00301 
00302         double dist = test.length();
00303         if (dist > 0.01)
00304         {
00305             LOG_VERBOSE("Error: xmlToFrame, matrix conversion failed, distance is %g\n", dist);
00306             a = 0.0;
00307             b = 0.0;
00308             g = 0.0;
00309         }
00310     }
00311 
00312 
00313     CMatrix pose;
00314     pose.set(1.0, 0.0, 0.0, 0.0,
00315       0.0, 1.0, 0.0, 0.0,
00316       0.0, 0.0, 1.0, 0.0,
00317       0.0, 0.0, 0.0, 1.0);
00318     CMathLib::getRotation(pose, a*M_PI/180.0, b*M_PI/180.0, g*M_PI/180.0);
00319 
00320     pose.a[12] = x;
00321     pose.a[13] = y;
00322     pose.a[14] = z;
00323     frame->setPose(pose);
00324 
00325     char buffer[255];
00326     sprintf(buffer, "%s", additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "name", "")).c_str());
00327     frame->setName(buffer);
00328 
00329     // frame type
00330     frame->setFrameType(CFrame::FRAME_POSITION);
00331     sprintf(buffer, "%s", CConfiguration::getAttributeString(frameNode, "type", ""));
00332     if (strcasecmp(buffer, "velocity") == 0)
00333     {
00334         //printf("Frame: Type = VELOCITY\n");
00335         frame->setFrameType(CFrame::FRAME_VELOCITY);
00336     }
00337     sprintf(buffer, "%s", additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "base", "")).c_str());
00338 
00339     std::string tmp = buffer;
00340     std::vector<std::string> tokens;
00341     tokenize(tmp, tokens, " ");
00342     if (tokens.size() > 0)
00343     tmp = tokens.back();
00344     tokens.clear();
00345 
00346     sprintf(buffer, "%s", tmp.c_str());
00347 
00348     tokenize(tmp, tokens, ":");
00349     if (tokens.size() > 1)
00350     {
00351         if (strcasecmp(tokens[0].c_str(), "geometry") == 0)
00352         {
00353             frame->setBaseType(CFrame::BASE_GEOMETRY);
00354             frame->setBaseName(tokens[1].c_str());
00355         } else frame->setBaseName(buffer);
00356     } else frame->setBaseName(buffer);
00357 
00358 
00359     frame->setBase(NULL);
00360 
00361     switch (frame->getBaseType())
00362     {
00363         case CFrame::BASE_NORMAL:
00364         default:
00365         {
00366             if (strcasecmp(buffer, "") == 0)
00367             create = false;
00368 
00369             // create referenced base frame if it doesnt exist yet
00370             int i = getFrameByName(buffer, create);
00371             if (i >= 0)
00372             frame->setBase(frames[i]);
00373         }
00374     }
00375 
00376     sprintf(buffer, "%s", additionalData.resolveString(CConfiguration::getAttributeString(frameNode, "baseOrientation", "")).c_str());
00377     frame->setBaseOrientation(NULL);
00378 
00379     if (strcasecmp(buffer, "") == 0)
00380     create = false;
00381 
00382     // create referenced base frame if it doesnt exist yet
00383     int i = getFrameByName(buffer, create);
00384     if (i >= 0)
00385     {
00386         frame->setBaseOrientationName(buffer);
00387         frame->setBaseOrientation(frames[i]);
00388     }
00389     return true;
00390 }
00391 
00392 
00393 CFrame* CFrame::getByName(char* str)
00394 {
00395     if (hasName(str))
00396        return this;
00397     else
00398        return NULL;
00399 }
00400 
00401 
00402 void CFrame::removeParent(CFrame *parent)
00403 { 
00404 #ifdef DEBUG_MESSAGES_FRAME_CPP
00405   LOG_VERBOSE("Frame: removing frame %s of %s: ", parent->getName(), getName());
00406 #endif
00407 
00408   std::vector<CFrame*> tmp = parents;
00409   parents.clear();
00410   for (unsigned int i=0; i<tmp.size(); i++)
00411     if (tmp[i] != parent)
00412       parents.push_back(tmp[i]); 
00413 #ifdef DEBUG_MESSAGES_FRAME_CPP
00414     else
00415       {
00416         LOG_VERBOSE("found frame to remove: ");
00417       } 
00418   
00419   LOG_VERBOSE("(");
00420   for (unsigned int i=0; i<parents.size(); i++)
00421     LOG_VERBOSE("%s ", parents[i]->getName());
00422   LOG_VERBOSE(")\n");
00423 #endif
00424 }
00425 
00426 void CFrame::addParent(CFrame *parent)
00427 {
00428 #ifdef DEBUG_MESSAGES_FRAME_CPP
00429   LOG_VERBOSE("Frame: adding parent %s of %s ", parent->getName(), getName());
00430 #endif
00431 
00432   if (parent != NULL && getParentId(parent) < 0)
00433     {
00434 #ifdef DEBUG_MESSAGES_FRAME_CPP
00435       LOG_VERBOSE("added %s: ", parent->getName());
00436 #endif
00437       parents.push_back(parent);
00438     }
00439 #ifdef DEBUG_MESSAGES_FRAME_CPP
00440  else
00441     {
00442       LOG_VERBOSE("%s already included: ", parent->getName());
00443     } 
00444   LOG_VERBOSE("(");
00445   for (unsigned int i=0; i<parents.size(); i++)
00446     LOG_VERBOSE("%s ", parents[i]->getName());
00447   LOG_VERBOSE(")\n");
00448 #endif
00449 }
00450 
00451 void* CFrame::getCopy()
00452 {
00453   CFrame* ptr = new CFrame();
00454   ptr->setName(getName());
00455   ptr->setBase(getBase());
00456   ptr->setBaseName(getBaseName());
00457   ptr->setBaseType(getBaseType());
00458   ptr->setPose(getPose());
00459   ptr->setFrameType(getFrameType());
00460   ptr->setTime(getTime());
00461   if (_isLocked)
00462     ptr->lock();
00463   else
00464     ptr->unlock();
00465 
00466   return (void*) ptr;
00467 }
00468 
00469 void* CFrameCombination::getCopy()
00470 {
00471   CFrameCombination* ptr = new CFrameCombination();
00472   ptr->setName(getName());
00473   ptr->setBase(getBase());
00474   ptr->setBaseName(getBaseName());
00475   ptr->setBaseType(getBaseType());
00476 
00477   ptr->setBaseOrientationName(getBaseOrientationName());
00478   ptr->setBaseOrientation(getBaseOrientation());
00479   
00480 
00481   ptr->setPose(getPose());
00482   ptr->setFrameType(getFrameType());
00483   ptr->setTime(getTime());
00484   if (_isLocked)
00485     ptr->lock();
00486   else
00487     ptr->unlock(); 
00488   
00489   return (void*) ptr;
00490 }
00491 
00492 
00493   void CFrame::getDofs(std::vector<double> &dofs_min, std::vector<double> &dofs_max)
00494   {
00495     dofs_max.clear();
00496     dofs_max = this->dofs_max;
00497     dofs_min.clear();
00498     dofs_min = this->dofs_min;
00499   }
00500 
00501   void CFrame::getDofs(std::vector<unsigned int> &dofs)
00502   {
00503     dofs.clear();
00504     for (unsigned int i=0; i<dofs_min.size() && i<dofs_max.size(); i++)
00505       if (fabsf(dofs_max[i] - dofs_min[i]) > 1.0e-8)
00506         dofs.push_back(i);
00507   }
00508 
00509 CFrame::CFrame()
00510 {
00511   childs.reserve(20);
00512   frameType = FRAME_POSITION;
00513   base = NULL;
00514   name = "";
00515   _isValid = false;
00516   baseName = "";
00517   time = -1;
00518   baseType = BASE_NORMAL;
00519   _isData = false;
00520   _isLocked = false;
00521   counter = baseCounter = 0;
00522 
00523   dofs_min.resize(6, 0.0);
00524   dofs_max.resize(6, 0.0);
00525 }
00526 
00527 
00528 void CFrame::invalidateAll()
00529 {
00530   invalidate();
00531 
00532   if (base != NULL)
00533     base->invalidateAll();
00534 }
00535 
00536 CFrame::CFrame(char* str)
00537 { 
00538   _isData = false;
00539   childs.reserve(20);
00540   frameType = FRAME_POSITION;
00541   base = NULL;
00542   name = str;
00543   _isValid = false;
00544   baseName = "";
00545   time = -1;
00546   baseType = BASE_NORMAL;
00547   _isLocked = false;
00548   counter = baseCounter = 0;
00549 }
00550 
00551 CFrame::~CFrame()
00552 {
00553 #ifdef DEBUG_MESSAGES_FRAME_CPP
00554   LOG_VERBOSE("Frame: freeing %s\n", getName());
00555 #endif
00556   setBase(NULL);
00557 }
00558 
00559 /*
00560 CMatrix CFrame::getRelativeToBase()
00561 {
00562     CFrame *frame = this;
00563     relativePose = pose;
00564     while (frame->base != NULL)
00565     {
00566         frame = frame->base;
00567         relativePose.mul( frame->pose, relativePose);
00568     }
00569 
00570     isValid = true;
00571 
00572     return relativePose;
00573 }*/
00574 
00575 
00576 void CFrame::setRelativePose(const CMatrix &value) 
00577 { 
00578   if (_isLocked)
00579     return;
00580 
00581   relativePose = value; 
00582   _isValid = true; 
00583   _isUpdated = true; 
00584 }
00585 
00586 
00587 void CFrame::setBase(CFrame* base) 
00588 {
00589   if (this->base != base)
00590     {
00591       if (this->base != NULL)
00592         this->base->removeParent(this);
00593 
00594       this->base = base; 
00595 
00596       if (this->base != NULL)
00597         this->base->addParent(this);
00598 
00599         if (_isValid)
00600           invalidate();
00601     }
00602 }
00603 
00604 
00605 bool CFrame::hasName(char* str)
00606 {
00607   return (strcasecmp(str, name.c_str()) == 0);
00608 }
00609 
00610 void CFrame::setName(const char* str)
00611 {
00612   name = str;
00613 }
00614 
00615 void CFrame::update()
00616 {
00617 
00618 }
00619 
00620 
00621 CFrame* CKinematicChain::getLastFrame()
00622 {
00623   int id = getLength();
00624   if (id > 0)
00625     return frames[id-1];
00626   return NULL;
00627 }
00628 
00629 CFrame* CKinematicChain::getFrame(unsigned int id)
00630 {
00631   if (id < getLength())
00632     return frames[id];
00633 
00634   return NULL;
00635 }
00636 
00637 CDh& CKinematicChain::getDhParameters(unsigned int id)
00638 {
00639   if (id >= getLength())
00640     LOG_VERBOSE("Error: this needs fixing (CKinematicChain::getDhParameters)\n");
00641 
00642   return dhParameters[id];
00643 }
00644 
00645 CFrame* CKinematicChain::getByName(char* str)
00646 {
00647         char buffer[255];
00648         strcpy(buffer, str);
00649         char* delimiter = strchr(buffer, '_');
00650 
00651         if (delimiter == NULL)
00652         {
00653           return NULL;
00654         } else
00655         {
00656            *delimiter = 0;
00657            delimiter++;
00658 
00659            int number = atoi(delimiter);
00660            std::cout << "chain: " << str << " number: " << number << "\n";
00661 
00662            //return this;
00663            if ((number >= 0) && (number < length))
00664            {
00665               return frames[number];
00666            }
00667         }
00668 
00669         return NULL;
00670 }
00671 
00672 
00673 void CKinematicChain::loadFromXml(CConfiguration &config, TiXmlElement* kinChainsNode, CFrameContainer &container)
00674 {
00675     if (kinChainsNode == NULL)
00676        return;
00677 
00678     char text[1024];
00679     int len = CConfiguration::getAttributeInteger(kinChainsNode, "len", 0);
00680 
00681     std::vector<TiXmlElement*> result;
00682     result.clear();
00683     config.findNodes("dh", result, kinChainsNode);
00684 
00685     if ((int)result.size() != len)
00686       {
00687         len = result.size();
00688         LOG_VERBOSE("Error: different size of dh entries, using %d\n", len);
00689       }
00690 
00691     if (len <= 0)
00692       {
00693         LOG_ERROR("Error: kinematic chain has length 0\n");
00694         exit(0);
00695       }
00696 
00697     sprintf(text, "%s", CConfiguration::getAttributeString(kinChainsNode, "name", ""));
00698     name = text;
00699     
00700 
00701     char buffer[1024], baseName[1024];
00702     sprintf(buffer, "%s", CConfiguration::getAttributeString(kinChainsNode, "base", ""));
00703     sprintf(baseName, "%s", buffer);
00704     CFrame* base = NULL;
00705     // create referenced base frame if it doesnt exist yet
00706     int id = container.getFrameByName(buffer);
00707  
00708     if (id >= 0)
00709        base = container.frames[id];
00710 
00711     setLength(len);
00712 
00713     totalArmLength = 0.0;
00714 
00715     for (unsigned int i=0; i<result.size(); i++)
00716     {
00717       sprintf(text, "%s_%d", name.c_str(), i);
00718         id = container.getFrameByName(text, true);
00719         if (id >= 0)
00720             frames[i] = container.frames[id];
00721         else
00722         {
00723             LOG_VERBOSE("CKinematicChain::loadFromXml() failed.\n");
00724             return;
00725         }
00726 
00727         dhParameters[i].speedFactor = CConfiguration::getAttributeDouble(result[i], "speed", 0.01);
00728         dhParameters[i].ivModel = CConfiguration::getAttributeString(result[i], "ivmodel", "");
00729         dhParameters[i].angle = 0.0;
00730         bool trans = CConfiguration::getAttributeBoolean(result[i], "translational", false) || CConfiguration::getAttributeBoolean(result[i], "trans", false);
00731         //printf("Frame: %s\n", trans ? "translation":"rotation");
00732         dhParameters[i].rotationalDof = !trans;
00733         dhParameters[i].rot_z = M_PI / 180.0 * CConfiguration::getAttributeDouble(result[i], "rotz", 0.0);
00734         dhParameters[i].rot_x = M_PI / 180.0 * CConfiguration::getAttributeDouble(result[i], "rotx", 0.0);
00735         dhParameters[i].trans_z = CConfiguration::getAttributeDouble(result[i], "transz", 0.0);
00736         dhParameters[i].trans_x = CConfiguration::getAttributeDouble(result[i], "transx", 0.0);
00737         dhParameters[i].id = CConfiguration::getAttributeInteger(result[i], "id", -1);
00738         dhParameters[i].sgn = CConfiguration::getAttributeDouble(result[i], "sgn", 1.0);
00739         dhParameters[i].min = M_PI / 180.0 * CConfiguration::getAttributeDouble(result[i], "min", -180.0);
00740         dhParameters[i].max = M_PI / 180.0 * CConfiguration::getAttributeDouble(result[i], "max", 180.0);
00741         dhParameters[i].axis.x = CConfiguration::getAttributeDouble(result[i], "x", 0.0);
00742         dhParameters[i].axis.y = CConfiguration::getAttributeDouble(result[i], "y", 0.0);
00743         dhParameters[i].axis.z = CConfiguration::getAttributeDouble(result[i], "z", 0.0);
00744         dhParameters[i].useAxis = CConfiguration::getAttributeBoolean(result[i], "axis", false);
00745         dhParameters[i].rot_z += CConfiguration::getAttributeDouble(result[i], "value", 0.0);
00746 
00747         if (dhParameters[i].useAxis && dhParameters[i].rotationalDof && dhParameters[i].axis.length() < 0.001)
00748           {
00749             CMatrix pose;
00750             pose.a[0] = CConfiguration::getAttributeDouble(result[i], "a0", 1.0);
00751             pose.a[1] = CConfiguration::getAttributeDouble(result[i], "a1", 0.0);
00752             pose.a[2] = CConfiguration::getAttributeDouble(result[i], "a2", 0.0);
00753             
00754             pose.a[4] = CConfiguration::getAttributeDouble(result[i], "a4", 0.0);
00755             pose.a[5] = CConfiguration::getAttributeDouble(result[i], "a5", 1.0);
00756             pose.a[6] = CConfiguration::getAttributeDouble(result[i], "a6", 0.0);
00757             
00758             pose.a[8] = CConfiguration::getAttributeDouble(result[i], "a8", 0.0);
00759             pose.a[9] = CConfiguration::getAttributeDouble(result[i], "a9", 0.0);
00760             pose.a[10] = CConfiguration::getAttributeDouble(result[i], "a10", 1.0);
00761             
00762             double angle;
00763             CMathLib::getRotationFromMatrix(pose, dhParameters[i].axis, angle);
00764 
00765             dhParameters[i].rot_z += angle;
00766           }
00767 
00768         if (dhParameters[i].useAxis && dhParameters[i].rotationalDof)
00769           dhParameters[i].axis.normalize();
00770 
00771         
00772         totalArmLength += fabsf(dhParameters[i].trans_z);
00773 
00774         CMatrix pose;
00775         pose.setDh(dhParameters[i]);
00776         frames[i]->setPose(pose);
00777         frames[i]->setName(text);
00778 
00779         if (i==0)
00780           {
00781             frames[i]->setBase(base);
00782             frames[i]->setBaseName(baseName);
00783           } else
00784           {
00785             frames[i]->setBase(frames[i-1]);
00786             frames[i]->setBaseName(frames[i-1]->getName());
00787           }
00788     }
00789 
00790     // add tcp frame for kinematic chain
00791     std::string tcpFrame = name + "_tcp";
00792     int tcpFrameId = container.getFrameByName(tcpFrame.c_str(), true);
00793     container.getFrame(tcpFrameId)->setBaseName(frames[getLength()-1]->getName());
00794     container.getFrame(tcpFrameId)->setBase(frames[getLength()-1]);
00795     LOG_VERBOSE("Frame: added frame %s for kinematic chain\n", tcpFrame.c_str());
00796 
00797 
00798     std::string lastPoseBufferName = name + "_tcp_buffer";
00799     /*
00800     int lastPoseBufferId = container.getFrameByName(lastPoseBufferName.c_str(), false);
00801       if (lastPoseBufferId >= 0)
00802       {
00803       printf("Error: buffer frame %s already exists. You have to remove it\n", lastPoseBufferName.c_str());
00804       exit(0);
00805       }
00806       CFrameReference *newFrame = new CFrameReference(frames[getLength()-1]);
00807       lastPoseBuffer = (CFrame*) newFrame;
00808       container.add(lastPoseBuffer);
00809     */
00810     int lastPoseBufferId = container.getFrameByName(lastPoseBufferName.c_str(), true);
00811     if (lastPoseBufferId < 0)
00812       {
00813         printf("Error: buffer frame %s couldnt be generated\n", lastPoseBufferName.c_str());
00814         exit(0);
00815       }
00816     lastPoseBuffer = container.getFrame(lastPoseBufferId);
00817 }
00818 
00819 
00820 // Kinematic Chain Class
00821 // - chain of homogenous transformation matrices based
00822 CKinematicChain::CKinematicChain()
00823 {
00824     dhParameters = 0;
00825     frames = 0;
00826     length = 0;
00827     totalArmLength = 0.0;
00828     lastPoseBuffer = NULL;
00829 }
00830 
00831 
00832 
00833 /*void CKinematicChain::getPose(CMatrix &result)
00834 {
00835     CMatrix b;
00836 
00837     if (base != NULL)
00838        b = base->getRelativeToBase();
00839 
00840     result.mul(b, pose);
00841     }*/
00842 
00843 CKinematicChain::~CKinematicChain()
00844 {
00845   setLength(0);
00846 }
00847 
00848 
00849 void CKinematicChain::setLength(int len)
00850 {
00851     if (length > 0)
00852     {
00853             if (dhParameters != NULL)
00854                delete [] dhParameters;
00855 
00856             if (frames != NULL)
00857                delete [] frames;
00858 
00859             frames = NULL;
00860             dhParameters = NULL;
00861             length = 0;
00862     }
00863 
00864     if (len > 0)
00865     {
00866        dhParameters = new CDh[len];
00867        if (dhParameters == NULL)
00868            {
00869                 LOG_VERBOSE("setLength: malloc failed().\n");
00870                 return;
00871        }
00872 
00873        frames     = new CFrame*[len];
00874        if (frames == NULL)
00875            {
00876                 LOG_VERBOSE("setLength: malloc failed().\n");
00877                 return;
00878        }
00879 
00880        length       = len;
00881     }
00882 }
00883 
00884 
00885 CKinematicChainContainer::CKinematicChainContainer()
00886 {
00887   chain = NULL;
00888   length = 0;
00889 }
00890 
00891 CKinematicChainContainer::~CKinematicChainContainer()
00892 {
00893     if (chain != NULL)
00894     {
00895         delete [] chain;
00896         chain = NULL;
00897     }
00898     length = 0;
00899 }
00900 
00901 
00902 void CKinematicChainContainer::loadFromXml(CConfiguration &config, TiXmlElement* kinChainsNode,  CFrameContainer &container)
00903 {
00904     //char text[255];
00905     int len = CConfiguration::getAttributeInteger(kinChainsNode, "len", 0);
00906     std::vector<TiXmlElement*> result;
00907     result.clear();
00908     config.findNodes("chain", result, kinChainsNode);
00909 
00910     if ((int)result.size() != len)
00911       {
00912         len = result.size();
00913         LOG_VERBOSE("Error: different size of chain entries, using %d\n", len);
00914       }
00915     length = len;
00916     if (chain != NULL)
00917     {
00918         delete [] chain;
00919         chain = NULL;
00920     }
00921     chain = new CKinematicChain[len];
00922 
00923     
00924     for (unsigned int i=0; i<result.size(); i++)
00925       {
00926         chain[i].loadFromXml(config, result[i], container);
00927       }
00928 }
00929 
00930 
00931 
00932 bool CFrameContainer::isRelativeTo(CFrame* first, CFrame* relative)
00933 {
00934   while (first != NULL)
00935     {
00936       if (first == relative)
00937         return true;
00938 
00939       first = first->getBase();
00940     }
00941 
00942   return false;
00943 }
00944 
00945 bool CFrameContainer::getFrameByName(const char* name, CFrame* &frame)
00946 {
00947   char buffer[1024];
00948   //int id;
00949   std::string object;
00950 
00951 
00952   object = name;
00953 
00954   std::vector<std::string> tokens;
00955   tokenize(object, tokens, " ");
00956 
00957   if (tokens.size() == 0)
00958     sprintf(buffer, " ");
00959   else
00960     sprintf(buffer, "%s", tokens.back().c_str());
00961 
00962   frame = NULL;
00963   for (unsigned int i=0; i<frames.size(); i++)
00964     if (strcasecmp(frames[i]->getName(), buffer) == 0)
00965       {
00966         frame = frames[i];
00967         return true;
00968       }
00969   
00970  return false;
00971 }
00972 
00973 int CFrameContainer::getFrameByName(const char* name, bool create)
00974 {
00975   const char* empty ="";
00976   if (strcasecmp(name, empty) == 0)
00977     return -1;
00978   
00979   char buffer[1024];
00980   std::string object = name;
00981   std::vector<std::string> tokens;
00982   tokenize(object, tokens, " ");
00983   
00984   if (tokens.size() == 0)
00985     sprintf(buffer, "%s", "");
00986   else
00987     sprintf(buffer, "%s", tokens.back().c_str());
00988 
00989   for (unsigned int i=0; i<frames.size(); i++)
00990     if (strcasecmp(frames[i]->getName(), buffer) == 0)
00991       {
00992         return (int)i;
00993       }
00994   
00995   if (create && (strlen(buffer) > 0))
00996     {
00997       frames.push_back(new CFrame(buffer));
00998       
00999       return ((int)frames.size()) - 1;
01000     }
01001   return -1;
01002 }
01003 
01004 
01005 int CFrameContainer::add(CFrame* newFrame)
01006 {
01007   frames.push_back(newFrame);
01008   return frames.size()-1;
01009 }
01010 
01011 
01012 bool CFrameContainer::setBase(char* fr, char* b)
01013 {
01014   int frame = getFrameByName(fr, false);
01015   int base = getFrameByName(b, false);
01016 
01017   if (frame < 0)
01018     return false;
01019 
01020   if (base < 0)
01021     frames[frame]->setBase(NULL);
01022   else frames[frame]->setBase(frames[base]);
01023   return true;
01024 }
01025 
01026 
01027 void CFrameContainer::checkBaseFrames()
01028 {
01029   for (unsigned int i=0; i<frames.size(); i++)
01030     {
01031       if (frames[i]->getBase() != NULL)
01032         {
01033           int id = -1;
01034           for (unsigned int j=0; j<frames.size(); j++)
01035             {
01036               if (frames[j] == frames[i]->getBase())
01037                 {
01038                   id = j;
01039                   break;
01040                 }
01041             }
01042           if (id < 0)
01043             {
01044               LOG_VERBOSE("Removing base of frame %s\n", frames[i]->getName());
01045               frames[i]->setBase(NULL);
01046               frames[i]->setBaseName("");
01047             }
01048         }
01049     }
01050 }
01051 
01052 void CFrameContainer::updateBaseLinks()
01053 {
01054   updateBaseLinks(frames);
01055 }
01056 
01057 void CFrameContainer::updateBaseLinks(CFrame* frame)
01058 {
01059   if (frame == NULL)
01060     return;
01061 
01062   std::vector<CFrame*> frames;
01063   frames.push_back(frame);
01064   updateBaseLinks(frames);
01065 }
01066 
01067 void CFrameContainer::updateBaseLinks(std::vector<CFrame*> &frames)
01068 {
01069   for (unsigned int i=0; i<frames.size(); i++)
01070     {
01071       frames[i]->setBase(NULL);
01072       if (frames[i]->getBaseType() == CFrame::BASE_COMBINED)
01073         ((CFrameCombination*)frames[i])->setBaseOrientation(NULL);
01074         
01075       frames[i]->getParents().clear();
01076     }
01077 
01078   for (unsigned int i=0; i<frames.size(); i++)
01079     {
01080       //LOG_VERBOSE("Info: Frame is %s with base %s\n", frames[i]->getName(), frames[i]->getBaseName());
01081 
01082       if (strcasecmp(frames[i]->getBaseName(), "") != 0)
01083         {
01084           int id = getFrameByName(frames[i]->getBaseName(), false);
01085           if (id >= 0)
01086             {
01087               frames[i]->setBase(this->frames[id]);
01088               LOG_VERBOSE("Info: setting base of %s to %s\n", frames[i]->getName(), this->frames[id]->getName());
01089             }
01090           else 
01091             {
01092               LOG_VERBOSE("Error: Couldnt find base named %s of frame %s\n", frames[i]->getBaseName(), frames[i]->getName());
01093             }
01094         }
01095 
01096       
01097       if (frames[i]->getBaseType() == CFrame::BASE_COMBINED)
01098         if (strcasecmp(((CFrameCombination*)frames[i])->getBaseOrientationName(), "") != 0)
01099           {
01100             int id = getFrameByName(((CFrameCombination*)frames[i])->getBaseOrientationName(), false);
01101             if (id >= 0)
01102               {
01103                 ((CFrameCombination*)frames[i])->setBaseOrientation(this->frames[id]);
01104                 LOG_VERBOSE("Info: setting base orientiation of %s to %s\n", frames[i]->getName(), this->frames[id]->getName());
01105               }
01106                 else LOG_VERBOSE("Error: Couldnt find base named %s of frame %s\n", ((CFrameCombination*)frames[i])->getBaseOrientationName(), frames[i]->getName());
01107         }
01108     }
01109 }
01110 
01111 
01112 void CFrameContainer::loadFromFile(const char* filename)
01113 {
01114   CConfiguration config("Data");
01115   //bool okay = config.load(filename);
01116   config.load(filename);
01117 
01118   DataPairs additionalData;
01119   loadFromFile(filename, additionalData, config, true);
01120 }
01121 
01122 void CFrameContainer::loadFromFile(const char* filename, DataPairs &additionalData, CConfiguration &config, bool loadAll)
01123 {
01124   std::vector<TiXmlElement*> result;
01125   config.findNodes("Frames.Frame", result);
01126   for (unsigned int i=0; i<result.size(); i++)
01127     {
01128       if (!loadAll)
01129         if (!CConfiguration::getAttributeBoolean(result[i], "data", false))
01130           continue;
01131 
01132       int frame = getFrameByName(CConfiguration::getAttributeString(result[i], "name", ""), false);
01133 
01134       CFrame* tmp;
01135 
01136       if (frame < 0)
01137         {
01138           tmp = new CFrame();
01139           add(tmp);
01140         } else tmp = frames[frame];
01141 
01142       xmlToFrame(tmp, result[i], additionalData, false);
01143     }
01144 
01145   invalidate();
01146 }
01147 
01148 
01149 // Denavit Hartenberg Storage Class
01150 CDh::CDh()
01151 {
01152   speedFactor = 0.01;
01153   rotationalDof = true;
01154   rot_z = trans_z = rot_x = trans_x = angle = 0.0;
01155   sgn = 1.0;
01156   min = -180.0;
01157   max = 180.0;
01158   useAxis = false;
01159   axis.set(0.0, 0.0, 0.0);
01160   id = -1;
01161 }
01162 
01163 // get variable rotation angle (variable portion of theta)
01164 double CDh::getAngle()
01165 {
01166         return sgn * this->angle;
01167 }
01168 
01169 // set variable rotation angle (variable portion of theta)
01170 void CDh::setAngle(double angle)
01171 {
01172         this->angle = sgn * angle;
01173 }
01174 
01175 // set fixed dh parameters
01176 void CDh::set(double rot_z, double trans_z, double rot_x, double trans_x)
01177 {
01178     this->rot_z = rot_z;
01179     this->trans_z = trans_z;
01180     this->rot_x = rot_x;
01181     this->trans_x = trans_x;
01182 }
01183 
01184 
01185 
01186 std::string CFrameInterface::getFrameAsXml()
01187 {
01188   if (frame == NULL)
01189     return "";
01190 
01191   CVec t1, t2;
01192   CMatrix m;
01193   m = frame->getPose();
01194   CMathLib::getOrientation(m, t1, t2);
01195 
01196   char buffer[1024];
01197 
01198   if (frame->getBaseType() == CFrame::BASE_COMBINED)
01199     {
01200       sprintf(buffer, "<Frame name=\"%s\" base=\"%s\" baseOrientation=\"%s\"  a=\"%g\" b=\"%g\" g=\"%g\" x=\"%g\" y=\"%g\" z=\"%g\" />\n",
01201               frame->getName(), frame->getBaseName(), ((CFrameCombination*)frame)->getBaseOrientationName(),
01202               180.0/M_PI * t1.x, 180.0/M_PI * t1.y, 180.0/M_PI * t1.z, m.a[12], m.a[13],  m.a[14]); 
01203     } else
01204     {
01205       sprintf(buffer, "<Frame name=\"%s\" base=\"%s\" a=\"%g\" b=\"%g\" g=\"%g\" x=\"%g\" y=\"%g\" z=\"%g\" />\n",
01206               frame->getName(), frame->getBaseName(),
01207               180.0/M_PI * t1.x, 180.0/M_PI * t1.y, 180.0/M_PI * t1.z, m.a[12], m.a[13],  m.a[14]); 
01208     }
01209   return buffer;
01210 };
01211 
01212 
01213 CFrameCombination::CFrameCombination()
01214 {
01215   frameType = FRAME_POSITION;
01216   base = NULL;
01217   baseOrientation = NULL;
01218   name = "";
01219   _isValid = false;
01220   baseName = "";
01221   baseOrientationName = "";
01222   time = -1;
01223   baseType = BASE_NORMAL;
01224   _isLocked = false;
01225   counter = baseCounter = 0;
01226 
01227   //LOG_VERBOSE("Created combined frame.\n");
01228 
01229   baseType = CFrame::BASE_COMBINED;
01230 }
01231 
01232 CFrameCombination::~CFrameCombination()
01233 {
01234 #ifdef DEBUG_MESSAGES_FRAME_CPP
01235   LOG_VERBOSE("FrameCombination: freeing %s\n", getName());
01236 #endif
01237   setBaseOrientation(NULL);
01238   setBase(NULL);
01239 }
01240 
01241 
01242 
01243 CFrame* CFrameCombination::getBaseOrientation()
01244 {
01245   return baseOrientation;
01246 }
01247 
01248 void CFrameCombination::setBaseOrientation(CFrame* baseOrientation)
01249 {
01250   if (this->baseOrientation != baseOrientation)
01251     {
01252       if (this->baseOrientation != NULL && this->baseOrientation != this->base)
01253         this->baseOrientation->removeParent(this);
01254  
01255       this->baseOrientation = baseOrientation; 
01256 
01257       if (baseOrientation != NULL)
01258         baseOrientation->addParent(this);
01259 
01260         if (_isValid)
01261           invalidate();
01262     } 
01263 }
01264 
01265 
01266 void CFrameCombination::invalidateAll()
01267 {
01268   invalidate();
01269 
01270   if (base != NULL)
01271     base->invalidateAll();
01272 
01273   if (baseOrientation != NULL)
01274     baseOrientation->invalidateAll();
01275 }
01276 
01277 
01278  
01279 
01280 CFrameReference::CFrameReference(CFrame *reference)
01281 {
01282   this->reference = reference;
01283 }
01284 
01285 CFrameReference::CFrameReference()
01286 {
01287   reference = NULL;
01288 }
01289 
01290 
01291 
01292 void CFrame::invalidate()
01293 {
01294   // _isUpdated = false;
01295     _isValid = false;
01296 
01297     //printf("Frame: Invalidating %s\n", name.c_str());
01298     /*
01299   if (_isLocked)// || time >= 0)
01300     return;
01301 
01302     _isValid = false;  */  
01303 
01304     for (unsigned int i=0; i<parents.size(); i++)
01305       parents[i]->invalidate();
01306 }
01307 
01308 
01309 
01310 // test
01311 
01312 
01313  /*
01314 void CFrame::getRelativeToBase(CMatrix &mat)
01315 {
01316   if (_isValid || _isLocked) 
01317       {
01318         mat = relativePose;
01319         return;
01320       } 
01321 
01322   if (getBase() == NULL)
01323     {
01324       mat = relativePose = pose;
01325       return;
01326     }
01327 
01328   childs.clear();
01329   CFrame *frame = getBase();
01330   while (frame != NULL)
01331     {
01332       childs.push_back(frame);
01333       if (frame->_isValid || frame->_isLocked)
01334         { 
01335           break;
01336         }
01337       frame = frame->getBase();
01338     }
01339 
01340   childs.back()->getRelativeToBase(tmpMatrix);
01341   for (int i=(int)childs.size()-2; i>= 0; i--)
01342     {
01343       childs[i]->relativePose.mulNoAlloc(childs[i+1]->relativePose, childs[i]->pose);
01344       childs[i]->_isValid = true;
01345     }
01346   
01347   relativePose.mulNoAlloc(childs[0]->relativePose, pose);
01348     
01349   _isValid = true;
01350 
01351   mat = relativePose;
01352 }
01353 
01354 CMatrix CFrame::getRelativeToBase()
01355   {
01356     CMatrix tmpMatrix;
01357     getRelativeToBase(tmpMatrix);
01358     return tmpMatrix;
01359   }
01360  */
01361 /*
01362 void CFrame::getRelativeToBase(CMatrix &mat)
01363 {
01364   if (_isValid || _isLocked) 
01365       {
01366         mat = relativePose;
01367         return;
01368       } 
01369 
01370   if (getBase() != NULL)
01371     {
01372       getBase()->getRelativeToBase(tmpMatrix);
01373       relativePose.mulNoAlloc(tmpMatrix, pose);
01374     } else relativePose = pose;
01375   
01376   _isValid = true;
01377 
01378   mat = relativePose;
01379 }
01380 
01381 CMatrix CFrame::getRelativeToBase()
01382   {
01383     
01384   if (_isValid || _isLocked) 
01385       {
01386         return relativePose; 
01387       } 
01388 
01389   if (getBase() != NULL)
01390     {
01391       getBase()->getRelativeToBase(tmpMatrix);
01392       relativePose.mulNoAlloc(tmpMatrix, pose);
01393     } else relativePose = pose;
01394   
01395   _isValid = true;
01396 
01397   return relativePose;
01398   }
01399 */      
01400 
01401 }


asr_kinematic_chain_optimizer
Author(s): Aumann Florian, Heller Florian, Jäkel Rainer, Wittenbeck Valerij
autogenerated on Sat Jun 8 2019 19:42:49