00001
00019
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
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
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
00209 frame->setFrameType(CFrame::FRAME_POSITION);
00210 sprintf(buffer, "%s", CConfiguration::getAttributeString(frameNode, "type", ""));
00211 if (strcasecmp(buffer, "velocity") == 0)
00212 {
00213
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
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
00330 frame->setFrameType(CFrame::FRAME_POSITION);
00331 sprintf(buffer, "%s", CConfiguration::getAttributeString(frameNode, "type", ""));
00332 if (strcasecmp(buffer, "velocity") == 0)
00333 {
00334
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
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
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
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
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
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
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
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
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
00801
00802
00803
00804
00805
00806
00807
00808
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
00821
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
00834
00835
00836
00837
00838
00839
00840
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
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
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
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
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
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
01164 double CDh::getAngle()
01165 {
01166 return sgn * this->angle;
01167 }
01168
01169
01170 void CDh::setAngle(double angle)
01171 {
01172 this->angle = sgn * angle;
01173 }
01174
01175
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
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
01295 _isValid = false;
01296
01297
01298
01299
01300
01301
01302
01303
01304 for (unsigned int i=0; i<parents.size(); i++)
01305 parents[i]->invalidate();
01306 }
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401 }