00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _Joint_H
00019 #define _Joint_H
00020
00021
00022
00023
00024
00025 #include <math.h>
00026 #include <string.h>
00027 #include <iostream>
00028 #include <vector>
00029 #include <stdlib.h>
00030 #include <cstdio>
00031 #include <stdexcept>
00032 #include <limits>
00033
00034
00035
00036
00037
00038
00039 #ifndef JOINT_EPSILON
00040 #define JOINT_EPSILON .01 / 360.0
00041 #endif
00042
00043
00044 #define DEGS_PER_RAD 57.29577951
00045 #define RADS_PER_DEG 0.017453292
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 class Joint_Exception : public std::runtime_error
00058 {
00059 public:
00060 Joint_Exception(const char* _file, int _line, const char* _msg) : std::runtime_error(_msg), file(_file), line(_line)
00061 {
00062 msg = _msg;
00063 }
00064 const char* getFile() const
00065 {
00066 return file;
00067 }
00068 int getLine() const
00069 {
00070 return line;
00071 }
00072 const char* getMsg() const
00073 {
00074 return msg;
00075 }
00076
00077 private:
00078 const char* file;
00079 int line;
00080 const char* msg;
00081 };
00082
00083
00084 inline std::ostream& operator<<(std::ostream& _os, const Joint_Exception& e)
00085 {
00086 _os << "Error in " << e.getFile();
00087 _os << " at line " << e.getLine() << ":" << std::endl;
00088 _os << " " << e.getMsg() << std::endl;
00089 return _os;
00090 }
00091
00092
00093
00094
00095
00096 template <class Real>
00097 class Joint
00098 {
00099 public:
00100
00101
00102
00103 Joint();
00104
00105 Joint(unsigned int NrJoints, bool zero = false);
00106
00107 Joint(const Joint& joints);
00108
00109 Joint(unsigned int NrJoints, const Real d[]);
00110
00111
00112 virtual ~Joint();
00113
00114
00115 void setNrJoints(unsigned int NrJoints);
00116
00117 void zero();
00118
00119
00120
00121
00122 void set(unsigned int i, Real d);
00123 Real& operator[](unsigned int i);
00124
00125 void set(unsigned int NrJoints, Real* d);
00126
00127
00128
00129
00130
00131
00132 Real get(unsigned int i) const;
00133 Real operator[](unsigned int i) const;
00134
00135 void get(unsigned int NrJoints, Real* d) const;
00136
00137 unsigned int size() const;
00138
00139
00140 Real getMax() const;
00141 Real getMin() const;
00142
00143
00144 unsigned int getMaxInd() const;
00145 unsigned int getMinInd() const;
00146
00147
00148 Joint interpolate(const Joint& j2, Real f) const;
00149
00150 static Joint interpolate(const Joint& j1, const Joint& j2, Real f);
00151
00152
00153 void toRad();
00154 void toDeg();
00155
00156
00157
00158
00159 Joint& operator=(const Joint& joint);
00160
00161
00162 bool operator==(const Joint& rhs) const;
00163
00164
00165 Joint operator-(const Joint& rhs) const;
00166 Joint operator+(const Joint& rhs) const;
00167 Joint operator*(Real s) const;
00168 Joint operator/(Real s) const;
00169
00170 void operator+=(const Joint& rhs);
00171 void operator-=(const Joint& rhs);
00172 void operator*=(Real s);
00173 void operator/=(Real s);
00174
00175
00176
00177 Real lengthSqr() const;
00178 Real length() const;
00179
00180
00181
00182 std::string toString(bool convert = false) const;
00183
00184 void fromString(unsigned int nrjoints, const char* str);
00185 void fromString(const char* str);
00186
00187
00188
00189
00190
00191
00192
00193 void print();
00194
00195
00196 unsigned int getNrJoints() const
00197 {
00198 return size();
00199 }
00200
00201 private:
00202 unsigned int m_NrJoints;
00203 Real* m_Joints;
00204 };
00205
00206 typedef Joint<double> Jointd;
00207 typedef Joint<float> Jointf;
00208
00209
00210
00211
00212
00213 template <class Real>
00214 std::ostream& operator<<(std::ostream& _os, const Joint<Real>& joint);
00215
00216 template <class Real>
00217 std::istream& operator>>(std::istream&, Joint<Real>& joint);
00218
00219
00220
00221
00222
00223 template <class Real>
00224 inline double Distance(const Joint<Real>& j1, const Joint<Real>& j2)
00225 {
00226 return (j1 - j2).length();
00227 }
00228
00229
00230
00231
00232
00233
00234 template <class Real>
00235 inline Joint<Real>::Joint()
00236 {
00237 m_NrJoints = 0;
00238 m_Joints = NULL;
00239 }
00240
00241
00242 template <class Real>
00243 inline Joint<Real>::Joint(unsigned int NrJoints, bool _zero)
00244 {
00245 m_NrJoints = NrJoints;
00246 m_Joints = new Real[m_NrJoints];
00247
00248 if (_zero)
00249 zero();
00250 }
00251
00252
00253 template <class Real>
00254 inline Joint<Real>::Joint(const Joint<Real>& rhs)
00255 {
00256 m_NrJoints = rhs.m_NrJoints;
00257 m_Joints = new Real[rhs.m_NrJoints];
00258
00259 for (unsigned int i = 0; i < m_NrJoints; i++)
00260 m_Joints[i] = rhs.m_Joints[i];
00261 }
00262
00263
00264 template <class Real>
00265 inline Joint<Real>::Joint(unsigned int NrJoints, const Real d[])
00266 {
00267 m_NrJoints = NrJoints;
00268 m_Joints = new Real[m_NrJoints];
00269
00270 for (unsigned int i = 0; i < m_NrJoints; i++)
00271 m_Joints[i] = d[i];
00272 }
00273
00274
00275 template <class Real>
00276 inline Joint<Real>::~Joint()
00277 {
00278 if (m_Joints)
00279 delete[] m_Joints;
00280 }
00281
00282
00283 template <class Real>
00284 inline void Joint<Real>::setNrJoints(unsigned int NrJoints)
00285 {
00286
00287
00288 Real* old_m_Joints = m_Joints;
00289 m_Joints = new Real[NrJoints];
00290
00291 for (unsigned int i = 0; i < NrJoints; i++)
00292 {
00293 if (i < m_NrJoints)
00294 m_Joints[i] = old_m_Joints[i];
00295 else
00296 m_Joints[i] = 0.0;
00297 }
00298
00299 if (old_m_Joints)
00300 delete[] old_m_Joints;
00301
00302 m_NrJoints = NrJoints;
00303 }
00304
00305
00306 template <class Real>
00307 inline void Joint<Real>::zero()
00308 {
00309 for (unsigned int i = 0; i < m_NrJoints; i++)
00310 m_Joints[i] = 0.0;
00311 }
00312
00313
00314
00315
00316 template <class Real>
00317 inline void Joint<Real>::set(unsigned int i, Real d)
00318 {
00319 #ifndef JOINT_NO_RANGECHECK
00320 if ((m_Joints == NULL) || (i >= m_NrJoints))
00321 throw Joint_Exception(__FILE__, __LINE__, "tried to acces an element out of Joint range!");
00322 #endif
00323 m_Joints[i] = d;
00324 }
00325
00326 template <class Real>
00327 inline Real& Joint<Real>::operator[](unsigned int i)
00328 {
00329 #ifndef JOINT_NO_RANGECHECK
00330 if ((m_Joints == NULL) || (i >= m_NrJoints))
00331 throw Joint_Exception(__FILE__, __LINE__, "tried to acces an element out of Joint range!");
00332 #endif
00333 return m_Joints[i];
00334 }
00335
00336
00337 template <class Real>
00338 inline void Joint<Real>::set(unsigned int NrJoints, Real* d)
00339 {
00340 #ifndef JOINT_NO_RANGECHECK
00341 if ((!m_Joints) || (NrJoints != m_NrJoints))
00342 setNrJoints(NrJoints);
00343 #endif
00344
00345 for (unsigned int i = 0; i < m_NrJoints; i++)
00346 m_Joints[i] = d[i];
00347 }
00348
00349
00350
00351
00352 template <class Real>
00353 inline Real Joint<Real>::get(unsigned int i) const
00354 {
00355 #ifndef JOINT_NO_RANGECHECK
00356 if ((m_Joints == NULL) || (i >= m_NrJoints))
00357 throw Joint_Exception(__FILE__, __LINE__, "tried to acces an element out of Joint range!");
00358 #endif
00359
00360 return m_Joints[i];
00361 }
00362
00363 template <class Real>
00364 inline Real Joint<Real>::operator[](unsigned int i) const
00365 {
00366 return get(i);
00367 }
00368
00369
00370 template <class Real>
00371 inline void Joint<Real>::get(unsigned int NrJoints, Real* d) const
00372 {
00373 #ifndef JOINT_NO_RANGECHECK
00374 if ((m_Joints == NULL) || (NrJoints > m_NrJoints))
00375 throw Joint_Exception(__FILE__, __LINE__, "tried to acces an element out of Joint range!");
00376 #endif
00377
00378 for (unsigned int i = 0; i < m_NrJoints; i++)
00379 d[i] = m_Joints[i];
00380 }
00381
00382
00383 template <class Real>
00384 inline unsigned int Joint<Real>::size() const
00385 {
00386 return m_NrJoints;
00387 }
00388
00389
00390 template <class Real>
00391 inline Real Joint<Real>::getMax() const
00392 {
00393 #ifndef JOINT_NO_RANGECHECK
00394 if (m_NrJoints == 0)
00395 throw Joint_Exception(__FILE__, __LINE__, "tried to call getMax on empty Joint!");
00396 #endif
00397
00398 Real max = m_Joints[0];
00399 for (unsigned int i = 1; i < m_NrJoints; i++)
00400 max = (m_Joints[i] > max) ? m_Joints[i] : max;
00401 return max;
00402 }
00403
00404 template <class Real>
00405 inline Real Joint<Real>::getMin() const
00406 {
00407 #ifndef JOINT_NO_RANGECHECK
00408 if (m_NrJoints == 0)
00409 throw Joint_Exception(__FILE__, __LINE__, "tried to call getMin on empty Joint!");
00410 #endif
00411
00412 Real min = m_Joints[0];
00413 for (unsigned int i = 1; i < m_NrJoints; i++)
00414 min = (m_Joints[i] < min) ? m_Joints[i] : min;
00415 return min;
00416 }
00417
00418
00419 template <class Real>
00420 inline unsigned int Joint<Real>::getMaxInd() const
00421 {
00422 #ifndef JOINT_NO_RANGECHECK
00423 if (m_NrJoints == 0)
00424 throw Joint_Exception(__FILE__, __LINE__, "tried to call getMaxInd on empty Joint!");
00425 #endif
00426
00427 Real max = m_Joints[0];
00428 unsigned int maxI = 0;
00429
00430 for (unsigned int i = 1; i < m_NrJoints; i++)
00431 {
00432 if (m_Joints[i] > max)
00433 {
00434 max = m_Joints[i];
00435 maxI = i;
00436 }
00437 }
00438 return maxI;
00439 }
00440
00441 template <class Real>
00442 inline unsigned int Joint<Real>::getMinInd() const
00443 {
00444 #ifndef JOINT_NO_RANGECHECK
00445 if (m_NrJoints == 0)
00446 throw Joint_Exception(__FILE__, __LINE__, "tried to call getMinInd on empty Joint!");
00447 #endif
00448
00449 Real min = m_Joints[0];
00450 unsigned int minI = 0;
00451
00452 for (unsigned int i = 1; i < m_NrJoints; i++)
00453 {
00454 if (m_Joints[i] < min)
00455 {
00456 min = m_Joints[i];
00457 minI = i;
00458 }
00459 }
00460 return minI;
00461 }
00462
00463
00464 template <class Real>
00465 inline Joint<Real> Joint<Real>::interpolate(const Joint& j2, Real f) const
00466 {
00467 #ifndef JOINT_NO_RANGECHECK
00468 if ((m_Joints == NULL) || (j2.size() != m_NrJoints))
00469 throw Joint_Exception(__FILE__, __LINE__, "Joint dimensions mismatch in interpolate!");
00470 #endif
00471
00472 Joint<Real> result(m_NrJoints);
00473
00474 for (unsigned int i = 0; i < m_NrJoints; i++)
00475 result[i] = m_Joints[i] + (j2[i] - m_Joints[i]) * f;
00476
00477 return result;
00478 }
00479
00480
00481 template <class Real>
00482 inline Joint<Real> Joint<Real>::interpolate(const Joint& j1, const Joint& j2, Real f)
00483 {
00484 #ifndef JOINT_NO_RANGECHECK
00485 if (j1.size() != j2.size())
00486 throw Joint_Exception(__FILE__, __LINE__, "Joint dimensions mismatch in interpolate!");
00487 #endif
00488
00489 Joint<Real> result(j1.size());
00490
00491 for (unsigned int i = 0; i < j1.size(); i++)
00492 result[i] = j1[i] + f * (j2[i] - j1[i]);
00493
00494 return result;
00495 }
00496
00497
00498 template <class Real>
00499 inline void Joint<Real>::toRad()
00500 {
00501 for (unsigned int i = 0; i < m_NrJoints; i++)
00502 m_Joints[i] *= RADS_PER_DEG;
00503 }
00504
00505 template <class Real>
00506 inline void Joint<Real>::toDeg()
00507 {
00508 for (unsigned int i = 0; i < m_NrJoints; i++)
00509 m_Joints[i] *= DEGS_PER_RAD;
00510
00511 }
00512
00513
00514
00515
00516 template <class Real>
00517 inline Joint<Real>& Joint<Real>::operator=(const Joint<Real>& joint)
00518 {
00519 if (joint.size() != m_NrJoints)
00520 setNrJoints(joint.size());
00521
00522 for (unsigned int i = 0; i < m_NrJoints; i++)
00523 m_Joints[i] = joint[i];
00524
00525 return *this;
00526 }
00527
00528
00529 template <class Real>
00530 inline bool Joint<Real>::operator==(const Joint& joint2) const
00531 {
00532 #ifndef JOINT_NO_RANGECHECK
00533 if (m_NrJoints != joint2.size())
00534 return false;
00535 else
00536 {
00537 #endif
00538
00539
00540 Joint<Real> diff = *this - joint2;
00541 if (diff.lengthSqr() < JOINT_EPSILON)
00542 return true;
00543 else
00544 return false;
00545
00546 #ifndef JOINT_NO_RANGECHECK
00547 }
00548 #endif
00549 }
00550
00551
00552 template <class Real>
00553 inline Joint<Real> Joint<Real>::operator+(const Joint<Real>& rhs) const
00554 {
00555 #ifndef JOINT_NO_RANGECHECK
00556 if (m_NrJoints != rhs.size())
00557 throw Joint_Exception(__FILE__, __LINE__, "Joint dimensions mismatch in operator+ !");
00558 #endif
00559
00560 Joint<Real> result(*this);
00561 for (unsigned int i = 0; i < m_NrJoints; i++)
00562 {
00563 result.m_Joints[i] += rhs[i];
00564 }
00565 return result;
00566 }
00567
00568 template <class Real>
00569 inline Joint<Real> Joint<Real>::operator-(const Joint<Real>& rhs) const
00570 {
00571 #ifndef JOINT_NO_RANGECHECK
00572 if (m_NrJoints != rhs.size())
00573 throw Joint_Exception(__FILE__, __LINE__, "Joint dimensions mismatch in operator- !");
00574 #endif
00575
00576 Joint<Real> result(*this);
00577 for (unsigned int i = 0; i < m_NrJoints; i++)
00578 {
00579 result.m_Joints[i] -= rhs[i];
00580 }
00581 return result;
00582 }
00583
00584 template <class Real>
00585 inline Joint<Real> Joint<Real>::operator*(Real s) const
00586 {
00587 Joint<Real> result(*this);
00588 for (unsigned int i = 0; i < m_NrJoints; i++)
00589 result.m_Joints[i] *= s;
00590 return result;
00591 }
00592
00593 template <class Real>
00594 inline Joint<Real> Joint<Real>::operator/(Real s) const
00595 {
00596 Joint<Real> result(*this);
00597 if (fabs(s) > std::numeric_limits<Real>::epsilon())
00598 for (unsigned int i = 0; i < m_NrJoints; i++)
00599 result.m_Joints[i] /= s;
00600 else
00601 throw Joint_Exception(__FILE__, __LINE__, "Attempt to divide by zero in operator/ !");
00602
00603 return result;
00604 }
00605
00606
00607 template <class Real>
00608 inline void Joint<Real>::operator+=(const Joint<Real>& rhs)
00609 {
00610 #ifndef JOINT_NO_RANGECHECK
00611 if (m_NrJoints != rhs.size())
00612 throw Joint_Exception(__FILE__, __LINE__, "Joint dimensions mismatch in operator+= !");
00613 #endif
00614
00615 for (unsigned int i = 0; i < m_NrJoints; i++)
00616 {
00617 m_Joints[i] += rhs[i];
00618 }
00619 }
00620
00621 template <class Real>
00622 inline void Joint<Real>::operator-=(const Joint<Real>& rhs)
00623 {
00624 #ifndef JOINT_NO_RANGECHECK
00625 if (m_NrJoints != rhs.size())
00626 throw Joint_Exception(__FILE__, __LINE__, "Joint dimensions mismatch in operator-= !");
00627 #endif
00628
00629 for (unsigned int i = 0; i < m_NrJoints; i++)
00630 {
00631 m_Joints[i] -= rhs[i];
00632 }
00633 }
00634
00635 template <class Real>
00636 inline void Joint<Real>::operator*=(Real s)
00637 {
00638 for (unsigned int i = 0; i < m_NrJoints; i++)
00639 m_Joints[i] *= s;
00640 }
00641
00642 template <class Real>
00643 inline void Joint<Real>::operator/=(Real s)
00644 {
00645 if (fabs(s) > std::numeric_limits<Real>::epsilon())
00646 for (unsigned int i = 0; i < m_NrJoints; i++)
00647 m_Joints[i] /= s;
00648 else
00649 throw Joint_Exception(__FILE__, __LINE__, "Attempt to divide by zero in operator/= !");
00650 }
00651
00652
00653
00654 template <class Real>
00655 inline Real Joint<Real>::lengthSqr() const
00656 {
00657 Real l = 0;
00658 for (unsigned int i = 0; i < getNrJoints(); i++)
00659 {
00660 l += m_Joints[i] * m_Joints[i];
00661 }
00662 return l;
00663 }
00664
00665 template <class Real>
00666 inline Real Joint<Real>::length() const
00667 {
00668 return sqrt(lengthSqr());
00669 }
00670
00671
00672
00673 template <class Real>
00674 inline std::string Joint<Real>::toString(bool convert) const
00675 {
00676 char out[10];
00677 std::string str("(");
00678 for (unsigned int i = 0; i < m_NrJoints; i++)
00679 {
00680 if (i != 0)
00681 str += ",";
00682 if (convert)
00683 sprintf(out, "%3.3lf", m_Joints[i] * DEGS_PER_RAD);
00684 else
00685 sprintf(out, "%3.6lf", m_Joints[i]);
00686 str += std::string(out);
00687 }
00688 str += ")";
00689 return str;
00690 }
00691
00692
00693 template <class Real>
00694 inline void Joint<Real>::fromString(unsigned int nrjoints, const char* str)
00695 {
00696
00697 if (nrjoints != m_NrJoints)
00698 setNrJoints(nrjoints);
00699
00700 const char* start = strrchr(str, '(');
00701 const char* end = strrchr(str, ')');
00702 if (end > start)
00703 {
00704 int n = end - start;
00705 char* numbers = new char[n];
00706 strncpy(numbers, start + 1, n - 1);
00707 char* pch = strtok(numbers, ",");
00708 unsigned int i = 0;
00709 while (pch != NULL && i < nrjoints)
00710 {
00711
00712 set(i, atof(pch));
00713 i++;
00714 pch = strtok(NULL, ",");
00715 }
00716 delete numbers;
00717 }
00718 }
00719
00720
00721 template <class Real>
00722 inline void Joint<Real>::fromString(const char* str)
00723 {
00724 std::vector<Real> vec;
00725
00726 const char* start = strrchr(str, '(');
00727 const char* end = strrchr(str, ')');
00728 if (end > start)
00729 {
00730 int n = end - start;
00731 char* numbers = new char[n];
00732 strncpy(numbers, start + 1, n - 1);
00733 char* pch = strtok(numbers, ",");
00734
00735 while (pch != NULL)
00736 {
00737
00738 vec.push_back(atof(pch));
00739 pch = strtok(NULL, ",");
00740 }
00741 }
00742
00743 setNrJoints(vec.size());
00744 for (unsigned int i = 0; i < m_NrJoints; i++)
00745 m_Joints[i] = vec[i];
00746 }
00747
00748
00749 template <class Real>
00750 inline void Joint<Real>::print()
00751 {
00752 for (unsigned int i = 0; i < m_NrJoints; i++)
00753 printf("%f ", get(i));
00754 printf("\n");
00755 }
00756
00757 template <class Real>
00758 inline std::ostream& operator<<(std::ostream& _os, const Joint<Real>& joint)
00759
00760 {
00761 std::string str = joint.toString();
00762 _os << str;
00763 return _os;
00764 }
00765
00766 template <class Real>
00767 inline std::istream& operator>>(std::istream& _is, Joint<Real>& joint)
00768 {
00769 char c_str[255];
00770 _is.get(c_str, 255);
00771 joint.fromString(c_str);
00772 return _is;
00773 }
00774
00775 #endif
00776
00777 #ifdef SWIG
00778 %module Util
00779 %include Source/Manipulation/ManipUtil/datastructsManipulator.h
00780 %include Source/Manipulation/ManipUtil/Trajectory.h
00781 %{
00782 #include "Joint.h"
00783 %}
00784 %include "std_vector.i"
00785 %template(Jointd) Joint<double>;
00786 #endif