31 #undef DEBUG_MESSAGES_FRAME_CPP 35 bool CFrameContainer::xmlToFrame(
CFrame *frame, TiXmlElement* frameNode,
bool create)
38 return xmlToFrame(frame, frameNode, dataPairs, create);
44 std::vector<CFrame*> firstFrames, secondFrames;
48 firstFrames.push_back(first);
52 while (second != NULL)
54 secondFrames.push_back(second);
58 for (
unsigned int i=0; i<firstFrames.size(); i++)
59 for (
unsigned int j=0; j<secondFrames.size(); j++)
61 if (firstFrames[i] == secondFrames[j])
64 return firstFrames.size()-1 - i;
72 void CFrameContainer::resolve(std::vector<std::string> &in, std::vector<CFrame*> &out)
75 for (
unsigned int i=0; i<in.size(); i++)
77 int id = getFrameByName(in[i].c_str(),
false);
79 out.push_back(getFrame(
id));
84 void CFrame::setDofs(
const std::vector<double> &dofs_min,
const std::vector<double> &dofs_max)
86 this->dofs_min.clear();
87 this->dofs_min = dofs_min;
88 this->dofs_max.clear();
89 this->dofs_max = dofs_max;
92 bool CFrameContainer::xmlToFrame(
CFrame *frame, TiXmlElement* frameNode,
DataPairs &additionalData,
bool create)
95 std::vector<double> dofs_min(6), dofs_max(6);
96 const char* dofs[6] = {
"x",
"y",
"z",
"rx",
"ry",
"rz" };
97 for (
unsigned int i=0; i<6 && i<dofs_min.size() && i<dofs_max.size(); i++)
103 frame->
setDofs(dofs_min, dofs_max);
108 double a,b,g,x,y,z, qx,qy,qz,qw;
122 if (qx != 0.0 || qw != 0.0 || qw != 0.0 || qw != 0.0)
131 CMathLib::matrixFromQuaternion(quater, pose);
134 CMathLib::getOrientation(pose, tmp, tmp);
143 else if (a == 0 && b == 0 && g == 0)
153 CMathLib::getMatrixFromRotation(mat, tmp, angle);
154 CMathLib::getOrientation(mat, tmp, tmp);
159 CMathLib::getRotation(test, tmp);
163 double dist = test.
length();
166 LOG_VERBOSE(
"Error: xmlToFrame, matrix conversion failed, distance is %g\n", dist);
178 pose.
set(1.0, 0.0, 0.0, 0.0,
182 CMathLib::getRotation(pose, a*M_PI/180.0, b*M_PI/180.0, g*M_PI/180.0);
184 if (a == 0 && b == 0 && g == 0)
211 if (strcasecmp(buffer,
"velocity") == 0)
218 std::string tmp = buffer;
219 std::vector<std::string> tokens;
221 if (tokens.size() > 0)
225 sprintf(buffer,
"%s", tmp.c_str());
228 if (tokens.size() > 1)
230 if (strcasecmp(tokens[0].c_str(),
"geometry") == 0)
242 case CFrame::BASE_NORMAL:
245 if (strcasecmp(buffer,
"") == 0)
249 int i = getFrameByName(buffer, create);
258 void CFrameContainer::clear()
260 for (
unsigned int i=0; i<frames.size(); i++)
262 frames[i]->setBase(NULL);
265 for (
unsigned int i=0; i<frames.size(); i++)
283 if (a == 0 && b == 0 && g == 0)
292 CMathLib::getMatrixFromRotation(mat, tmp, angle);
293 CMathLib::getOrientation(mat, tmp, tmp);
298 CMathLib::getRotation(test, tmp);
302 double dist = test.
length();
305 LOG_VERBOSE(
"Error: xmlToFrame, matrix conversion failed, distance is %g\n", dist);
314 pose.
set(1.0, 0.0, 0.0, 0.0,
318 CMathLib::getRotation(pose, a*M_PI/180.0, b*M_PI/180.0, g*M_PI/180.0);
332 if (strcasecmp(buffer,
"velocity") == 0)
339 std::string tmp = buffer;
340 std::vector<std::string> tokens;
342 if (tokens.size() > 0)
346 sprintf(buffer,
"%s", tmp.c_str());
349 if (tokens.size() > 1)
351 if (strcasecmp(tokens[0].c_str(),
"geometry") == 0)
363 case CFrame::BASE_NORMAL:
366 if (strcasecmp(buffer,
"") == 0)
370 int i = getFrameByName(buffer, create);
379 if (strcasecmp(buffer,
"") == 0)
383 int i = getFrameByName(buffer, create);
402 void CFrame::removeParent(
CFrame *parent)
404 #ifdef DEBUG_MESSAGES_FRAME_CPP 408 std::vector<CFrame*> tmp = parents;
410 for (
unsigned int i=0; i<tmp.size(); i++)
411 if (tmp[i] != parent)
412 parents.push_back(tmp[i]);
413 #ifdef DEBUG_MESSAGES_FRAME_CPP 420 for (
unsigned int i=0; i<parents.size(); i++)
428 #ifdef DEBUG_MESSAGES_FRAME_CPP 432 if (parent != NULL && getParentId(parent) < 0)
434 #ifdef DEBUG_MESSAGES_FRAME_CPP 437 parents.push_back(parent);
439 #ifdef DEBUG_MESSAGES_FRAME_CPP 445 for (
unsigned int i=0; i<parents.size(); i++)
451 void* CFrame::getCopy()
469 void* CFrameCombination::getCopy()
493 void CFrame::getDofs(std::vector<double> &dofs_min, std::vector<double> &dofs_max)
496 dofs_max = this->dofs_max;
498 dofs_min = this->dofs_min;
501 void CFrame::getDofs(std::vector<unsigned int> &dofs)
504 for (
unsigned int i=0; i<dofs_min.size() && i<dofs_max.size(); i++)
505 if (fabsf(dofs_max[i] - dofs_min[i]) > 1.0e-8)
512 frameType = FRAME_POSITION;
518 baseType = BASE_NORMAL;
521 counter = baseCounter = 0;
523 dofs_min.resize(6, 0.0);
524 dofs_max.resize(6, 0.0);
528 void CFrame::invalidateAll()
533 base->invalidateAll();
536 CFrame::CFrame(
char* str)
540 frameType = FRAME_POSITION;
546 baseType = BASE_NORMAL;
548 counter = baseCounter = 0;
553 #ifdef DEBUG_MESSAGES_FRAME_CPP 576 void CFrame::setRelativePose(
const CMatrix &value)
581 relativePose = value;
589 if (this->base != base)
591 if (this->base != NULL)
596 if (this->base != NULL)
605 bool CFrame::hasName(
char* str)
607 return (strcasecmp(str, name.c_str()) == 0);
610 void CFrame::setName(
const char* str)
615 void CFrame::update()
623 int id = getLength();
629 CFrame* CKinematicChain::getFrame(
unsigned int id)
631 if (
id < getLength())
637 CDh& CKinematicChain::getDhParameters(
unsigned int id)
639 if (
id >= getLength())
640 LOG_VERBOSE(
"Error: this needs fixing (CKinematicChain::getDhParameters)\n");
642 return dhParameters[id];
645 CFrame* CKinematicChain::getByName(
char* str)
649 char* delimiter = strchr(buffer,
'_');
651 if (delimiter == NULL)
659 int number = atoi(delimiter);
660 std::cout <<
"chain: " << str <<
" number: " << number <<
"\n";
663 if ((number >= 0) && (number < length))
665 return frames[number];
675 if (kinChainsNode == NULL)
681 std::vector<TiXmlElement*> result;
683 config.
findNodes(
"dh", result, kinChainsNode);
685 if ((
int)result.size() != len)
688 LOG_VERBOSE(
"Error: different size of dh entries, using %d\n", len);
693 LOG_ERROR(
"Error: kinematic chain has length 0\n");
701 char buffer[1024], baseName[1024];
703 sprintf(baseName,
"%s", buffer);
709 base = container.
frames[id];
713 totalArmLength = 0.0;
715 for (
unsigned int i=0; i<result.size(); i++)
717 sprintf(text,
"%s_%d", name.c_str(), i);
720 frames[i] = container.
frames[id];
723 LOG_VERBOSE(
"CKinematicChain::loadFromXml() failed.\n");
729 dhParameters[i].angle = 0.0;
732 dhParameters[i].rotationalDof = !trans;
747 if (dhParameters[i].useAxis && dhParameters[i].rotationalDof && dhParameters[i].axis.length() < 0.001)
763 CMathLib::getRotationFromMatrix(pose, dhParameters[i].axis, angle);
765 dhParameters[i].rot_z += angle;
768 if (dhParameters[i].useAxis && dhParameters[i].rotationalDof)
769 dhParameters[i].axis.normalize();
772 totalArmLength += fabsf(dhParameters[i].trans_z);
775 pose.
setDh(dhParameters[i]);
776 frames[i]->setPose(pose);
777 frames[i]->setName(text);
781 frames[i]->setBase(base);
782 frames[i]->setBaseName(baseName);
785 frames[i]->setBase(frames[i-1]);
786 frames[i]->setBaseName(frames[i-1]->getName());
791 std::string tcpFrame = name +
"_tcp";
792 int tcpFrameId = container.
getFrameByName(tcpFrame.c_str(),
true);
795 LOG_VERBOSE(
"Frame: added frame %s for kinematic chain\n", tcpFrame.c_str());
798 std::string lastPoseBufferName = name +
"_tcp_buffer";
810 int lastPoseBufferId = container.
getFrameByName(lastPoseBufferName.c_str(),
true);
811 if (lastPoseBufferId < 0)
813 printf(
"Error: buffer frame %s couldnt be generated\n", lastPoseBufferName.c_str());
816 lastPoseBuffer = container.
getFrame(lastPoseBufferId);
822 CKinematicChain::CKinematicChain()
827 totalArmLength = 0.0;
828 lastPoseBuffer = NULL;
843 CKinematicChain::~CKinematicChain()
849 void CKinematicChain::setLength(
int len)
853 if (dhParameters != NULL)
854 delete [] dhParameters;
866 dhParameters =
new CDh[len];
867 if (dhParameters == NULL)
873 frames =
new CFrame*[len];
885 CKinematicChainContainer::CKinematicChainContainer()
891 CKinematicChainContainer::~CKinematicChainContainer()
906 std::vector<TiXmlElement*> result;
908 config.
findNodes(
"chain", result, kinChainsNode);
910 if ((
int)result.size() != len)
913 LOG_VERBOSE(
"Error: different size of chain entries, using %d\n", len);
924 for (
unsigned int i=0; i<result.size(); i++)
926 chain[i].
loadFromXml(config, result[i], container);
934 while (first != NULL)
936 if (first == relative)
945 bool CFrameContainer::getFrameByName(
const char* name,
CFrame* &frame)
954 std::vector<std::string> tokens;
957 if (tokens.size() == 0)
958 sprintf(buffer,
" ");
960 sprintf(buffer,
"%s", tokens.back().c_str());
963 for (
unsigned int i=0; i<frames.size(); i++)
964 if (strcasecmp(frames[i]->getName(), buffer) == 0)
973 int CFrameContainer::getFrameByName(
const char* name,
bool create)
975 const char* empty =
"";
976 if (strcasecmp(name, empty) == 0)
980 std::string
object = name;
981 std::vector<std::string> tokens;
984 if (tokens.size() == 0)
985 sprintf(buffer,
"%s",
"");
987 sprintf(buffer,
"%s", tokens.back().c_str());
989 for (
unsigned int i=0; i<frames.size(); i++)
990 if (strcasecmp(frames[i]->getName(), buffer) == 0)
995 if (create && (strlen(buffer) > 0))
997 frames.push_back(
new CFrame(buffer));
999 return ((
int)frames.size()) - 1;
1007 frames.push_back(newFrame);
1008 return frames.size()-1;
1012 bool CFrameContainer::setBase(
char* fr,
char* b)
1014 int frame = getFrameByName(fr,
false);
1015 int base = getFrameByName(b,
false);
1021 frames[frame]->setBase(NULL);
1022 else frames[frame]->setBase(frames[base]);
1027 void CFrameContainer::checkBaseFrames()
1029 for (
unsigned int i=0; i<frames.size(); i++)
1031 if (frames[i]->getBase() != NULL)
1034 for (
unsigned int j=0; j<frames.size(); j++)
1036 if (frames[j] == frames[i]->getBase())
1044 LOG_VERBOSE(
"Removing base of frame %s\n", frames[i]->getName());
1045 frames[i]->setBase(NULL);
1046 frames[i]->setBaseName(
"");
1052 void CFrameContainer::updateBaseLinks()
1054 updateBaseLinks(frames);
1057 void CFrameContainer::updateBaseLinks(
CFrame* frame)
1062 std::vector<CFrame*> frames;
1063 frames.push_back(frame);
1064 updateBaseLinks(frames);
1067 void CFrameContainer::updateBaseLinks(std::vector<CFrame*> &frames)
1069 for (
unsigned int i=0; i<frames.size(); i++)
1071 frames[i]->setBase(NULL);
1072 if (frames[i]->getBaseType() == CFrame::BASE_COMBINED)
1075 frames[i]->getParents().clear();
1078 for (
unsigned int i=0; i<frames.size(); i++)
1082 if (strcasecmp(frames[i]->getBaseName(),
"") != 0)
1084 int id = getFrameByName(frames[i]->getBaseName(),
false);
1087 frames[i]->setBase(this->frames[
id]);
1088 LOG_VERBOSE(
"Info: setting base of %s to %s\n", frames[i]->getName(), this->frames[
id]->getName());
1092 LOG_VERBOSE(
"Error: Couldnt find base named %s of frame %s\n", frames[i]->getBaseName(), frames[i]->getName());
1097 if (frames[i]->getBaseType() == CFrame::BASE_COMBINED)
1098 if (strcasecmp(((
CFrameCombination*)frames[i])->getBaseOrientationName(),
"") != 0)
1100 int id = getFrameByName(((
CFrameCombination*)frames[i])->getBaseOrientationName(),
false);
1104 LOG_VERBOSE(
"Info: setting base orientiation of %s to %s\n", frames[i]->getName(), this->frames[
id]->getName());
1106 else LOG_VERBOSE(
"Error: Couldnt find base named %s of frame %s\n", ((
CFrameCombination*)frames[i])->getBaseOrientationName(), frames[i]->getName());
1112 void CFrameContainer::loadFromFile(
const char* filename)
1116 config.
load(filename);
1119 loadFromFile(filename, additionalData, config,
true);
1124 std::vector<TiXmlElement*> result;
1125 config.
findNodes(
"Frames.Frame", result);
1126 for (
unsigned int i=0; i<result.size(); i++)
1140 }
else tmp = frames[frame];
1142 xmlToFrame(tmp, result[i], additionalData,
false);
1153 rotationalDof =
true;
1154 rot_z = trans_z = rot_x = trans_x = angle = 0.0;
1159 axis.set(0.0, 0.0, 0.0);
1164 double CDh::getAngle()
1166 return sgn * this->angle;
1170 void CDh::setAngle(
double angle)
1172 this->angle = sgn * angle;
1176 void CDh::set(
double rot_z,
double trans_z,
double rot_x,
double trans_x)
1178 this->rot_z = rot_z;
1179 this->trans_z = trans_z;
1180 this->rot_x = rot_x;
1181 this->trans_x = trans_x;
1186 std::string CFrameInterface::getFrameAsXml()
1193 m = frame->getPose();
1194 CMathLib::getOrientation(m, t1, t2);
1198 if (frame->getBaseType() == CFrame::BASE_COMBINED)
1200 sprintf(buffer,
"<Frame name=\"%s\" base=\"%s\" baseOrientation=\"%s\" a=\"%g\" b=\"%g\" g=\"%g\" x=\"%g\" y=\"%g\" z=\"%g\" />\n",
1201 frame->getName(), frame->getBaseName(), ((
CFrameCombination*)frame)->getBaseOrientationName(),
1202 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]);
1205 sprintf(buffer,
"<Frame name=\"%s\" base=\"%s\" a=\"%g\" b=\"%g\" g=\"%g\" x=\"%g\" y=\"%g\" z=\"%g\" />\n",
1206 frame->getName(), frame->getBaseName(),
1207 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]);
1213 CFrameCombination::CFrameCombination()
1215 frameType = FRAME_POSITION;
1217 baseOrientation = NULL;
1221 baseOrientationName =
"";
1223 baseType = BASE_NORMAL;
1225 counter = baseCounter = 0;
1229 baseType = CFrame::BASE_COMBINED;
1232 CFrameCombination::~CFrameCombination()
1234 #ifdef DEBUG_MESSAGES_FRAME_CPP 1235 LOG_VERBOSE(
"FrameCombination: freeing %s\n", getName());
1237 setBaseOrientation(NULL);
1243 CFrame* CFrameCombination::getBaseOrientation()
1245 return baseOrientation;
1248 void CFrameCombination::setBaseOrientation(
CFrame* baseOrientation)
1250 if (this->baseOrientation != baseOrientation)
1252 if (this->baseOrientation != NULL && this->baseOrientation != this->base)
1255 this->baseOrientation = baseOrientation;
1257 if (baseOrientation != NULL)
1266 void CFrameCombination::invalidateAll()
1271 base->invalidateAll();
1273 if (baseOrientation != NULL)
1274 baseOrientation->invalidateAll();
1280 CFrameReference::CFrameReference(
CFrame *reference)
1282 this->reference = reference;
1285 CFrameReference::CFrameReference()
1292 void CFrame::invalidate()
1304 for (
unsigned int i=0; i<parents.size(); i++)
1305 parents[i]->invalidate();
Denavit Hartenberg Link information.
std::string printToString(const char *format,...)
virtual void setBase(CFrame *base)
bool getFrameByName(const char *name, CFrame *&frame)
void setDh(const robotLibPbD::CDh &dh)
Creates Denavit Hartenberg matrix.
void mul(const CMatrix &first, const CMatrix &second)
Assigns product of two matrices to matrix.
Frame in cartesian space.
static const char * getAttributeString(TiXmlElement *node, const char *str, const char *def="")
void tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters)
virtual void setBaseOrientationName(const char *str)
virtual void setBaseOrientation(CFrame *base)
void resolveString(std::string input, std::string &output)
Data Storage Class (Attribute-Value Pairs)
void loadFromXml(CConfiguration &config, TiXmlElement *kinChainsNode, CFrameContainer &container)
Transforms <CHAIN> (xml object) into kinematic chain object.
virtual void setBaseName(const char *str)
std::vector< CFrame * > frames
virtual void setTime(double time)
bool load(const char *cfgFile)
virtual void setBaseType(unsigned int type)
void set(PRECISION a0, PRECISION a4, PRECISION a8, PRECISION a12, PRECISION a1, PRECISION a5, PRECISION a9, PRECISION a13, PRECISION a2, PRECISION a6, PRECISION a10, PRECISION a14, PRECISION a3=0.0f, PRECISION a7=0.0f, PRECISION a11=0.0f, PRECISION a15=1.0f)
virtual void setPose(const CMatrix &pose)
#define LOG_VERBOSE(format,...)
Robot types with implemented inverse kinematics.
virtual CFrame * getBase()
void addParent(CFrame *parent)
CFrame * getFrame(unsigned int id)
void findNodes(const char *name, std::vector< TiXmlElement * > &result, TiXmlElement *start, unsigned int level)
virtual void setName(const char *str)
static bool getAttributeBoolean(TiXmlElement *node, const char *str, bool def=false)
static int getAttributeInteger(TiXmlElement *node, const char *str, int def=0)
virtual void setFrameType(unsigned int type)
void setDofs(const std::vector< double > &dofs_min, const std::vector< double > &dofs_max)
Configuration file wrapper.
#define LOG_ERROR(format,...)
void invert()
Inverts the matrix (only for homogenous matrices)
static double getAttributeDouble(TiXmlElement *node, const char *str, double def=0.0)
virtual unsigned int getBaseType()
void removeParent(CFrame *parent)