00001
00029 #ifndef __VECMATH
00030
00031 #define __VECMATH
00032
00033 #include <boost/random/mersenne_twister.hpp>
00034 #include <boost/random/uniform_01.hpp>
00035 #include <boost/random/variate_generator.hpp>
00036
00037 #include <math.h>
00038 #include <vector>
00039 #include <string>
00040 #include <string.h>
00041 #include "config.h"
00042
00043
00044 #define PRECISION double // todo: use template instead
00045 #define PI360 6.283185307179586
00046 #define PI90 1.570796326794897
00047 #define RAD2ANGLE(X) ((X)*57.295779513082322)
00048 #define ANGLE2RAD(X) ((X)*1.745329251994e-02)
00049 #define RAD2ANGLEMAP(X) (X > M_PI ? RAD2ANGLE(PI360 - X) : RAD2ANGLE(X))
00050
00051 namespace robotLibPbD {
00052
00053 class CDh;
00054
00057 class CVec
00058 {
00059 public:
00060 PRECISION x, y, z, w;
00061
00062 CVec() { x = y = z = 0.0; w = 1.0;}
00063 CVec(PRECISION x, PRECISION y, PRECISION z)
00064 {
00065 set(x, y, z);
00066 };
00067
00068 void set(PRECISION x, PRECISION y, PRECISION z);
00069
00070 std::string toString();
00073 void print() const;
00076 CVec operator * ( PRECISION s) const
00077 {
00078 return CVec( x*s, y*s, z*s );
00079 };
00080 CVec operator / ( PRECISION s) const
00081 {
00082 return CVec( x/s, y/s, z/s );
00083 };
00086 CVec& operator = ( const CVec& v)
00087 {
00088 x = v.x; y = v.y; z = v.z; w = 1.0f;
00089 return *this;
00090 };
00093 PRECISION operator [] (unsigned int i) const
00094 {
00095 return (&x)[i];
00096 };
00099 PRECISION& operator [] (unsigned int i)
00100 {
00101 return (&x)[i];
00102 };
00105 CVec operator + ( const CVec& v) const
00106 {
00107 return CVec( x + v.x, y + v.y, z + v.z );
00108 };
00109
00110 CVec& operator += ( const CVec& v)
00111 {
00112 x += v.x;
00113 y += v.y;
00114 z += v.z;
00115
00116 return *this;
00117 };
00118 CVec& operator -= ( const CVec& v)
00119 {
00120 x -= v.x;
00121 y -= v.y;
00122 z -= v.z;
00123
00124 return *this;
00125 };
00126 CVec& operator *= ( PRECISION s)
00127 {
00128 x *= s;
00129 y *= s;
00130 z *= s;
00131
00132 return *this;
00133 };
00134 CVec& operator /= ( PRECISION s)
00135 {
00136 x /= s;
00137 y /= s;
00138 z /= s;
00139
00140 return *this;
00141 };
00144 CVec operator - ( const CVec& v) const
00145 {
00146 return CVec( x - v.x, y - v.y, z - v.z );
00147 };
00148
00151 CVec operator - () const
00152 {
00153 return CVec( -x, -y, -z );
00154 };
00157 PRECISION operator | (const CVec& v) const
00158 {
00159 return x*v.x + y*v.y + z*v.z;
00160 };
00163 CVec operator ^ (const CVec& v) const
00164 {
00165 return CVec( y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x );
00166 };
00167
00168 PRECISION length() const
00169 {
00170 return sqrt(x*x+y*y+z*z);
00171 };
00172 void normalize()
00173 {
00174 PRECISION len = sqrt(x*x+y*y+z*z);
00175
00176 if (len > 0.001)
00177 {
00178 x /= len;
00179 y /= len;
00180 z /= len;
00181 }
00182 };
00183 };
00184
00187 class CMatrix
00188 {
00189 public:
00190 PRECISION a[16];
00191 CMatrix();
00192 CMatrix(
00193 PRECISION a0, PRECISION a4, PRECISION a8, PRECISION a12,
00194 PRECISION a1, PRECISION a5, PRECISION a9, PRECISION a13,
00195 PRECISION a2, PRECISION a6, PRECISION a10, PRECISION a14,
00196 PRECISION a3 = 0.0f, PRECISION a7 = 0.0f, PRECISION a11 = 0.0f, PRECISION a15 = 1.0f);
00197 void set(
00198 PRECISION a0, PRECISION a4, PRECISION a8, PRECISION a12,
00199 PRECISION a1, PRECISION a5, PRECISION a9, PRECISION a13,
00200 PRECISION a2, PRECISION a6, PRECISION a10, PRECISION a14,
00201 PRECISION a3 = 0.0f, PRECISION a7 = 0.0f, PRECISION a11 = 0.0f, PRECISION a15 = 1.0f);
00204 PRECISION trace();
00205
00208 void transpose();
00209
00210 void printText();
00211
00214 void invert();
00215
00218 void mul(const CMatrix &first, const CMatrix &second);
00219
00220 void mulNoAlloc(const CMatrix &first, const CMatrix &second);
00221
00222 std::string toString(bool round = false);
00223
00226 void print(bool round = false) const;
00227
00230 void setDh(const robotLibPbD::CDh &dh);
00231 void arrayToMatrix(std::vector<double> &values);
00232 void matrixToArray(std::vector<double> &values);
00233
00234 void randomOrientation(double max = 2.0 * M_PI);
00237 CMatrix operator * ( PRECISION f) const ;
00240 CMatrix operator + ( const CMatrix &b) const ;
00241
00244 CMatrix operator - ( const CMatrix &b) const ;
00247 CMatrix operator * ( const CMatrix &m) const ;
00250 CMatrix& operator += ( const CVec &v);
00253 CVec operator * ( const CVec &v) const ;
00254
00257 const CVec& operator [] ( int i ) const;
00258
00261 CVec& operator [] ( int i );
00262
00265 CMatrix& operator = ( const CMatrix& v);
00266
00267 PRECISION length() const;
00268
00269 void unity();
00270 };
00271
00272
00275 class CMathLib
00276 {
00277 public:
00280 static double calcDotProduct(double firstVector[], double secondVector[], int size);
00285 static void calcMatrixResult(double matrix[], double vector[], int rows, int columns, double resultVector[]);
00288 static void getRotationFromMatrix(const CMatrix &mat, CVec &axis, double &angle);
00289 static void getQuaternionFromRotation(CVec &quater, CVec &axis, double angle);
00296 static void transposeMatrix(double *matrix, double *resultMatrix, int size);
00301 static void multiplyMatrices(double *firstMatrix, double *secondMatrix, int firstRows, int firstColumns, int secondColumns, double *resultMatrix);
00306 static void quaternionFromMatrix(const CMatrix &mat, CVec &quaternion);
00309 static void matrixFromQuaternion(CVec &quaternion, CMatrix &matrix);
00312 static void getMatrixFromRotation(CMatrix &mat, const CVec &axis, double angle);
00315 static void getEulerZXZ(CMatrix &mat, CVec &first);
00318 static void getOrientation(CMatrix &mat, CVec &first, CVec &second, bool old = false);
00323 static void getRotation(CMatrix &mat, CVec &vec, bool old = false);
00326 static void getRotation(CMatrix &mat, double x, double y, double z, bool old = false);
00336 static void calcAngles(double leg1, double leg2, double x, double y, double &first, double &second);
00337 };
00338
00339
00340 double sign(double value);
00341
00342 double vectorlength(std::vector<double> &v);
00343 unsigned long fac(unsigned int value);
00344 int roundToInt(double value);
00345
00346 void getMeanFromVectors(std::vector<std::vector<double> > &values, std::vector<double> &mean);
00347
00348 double getSigmoid(double value, double offset, double factor);
00349 double getGaussian(double value, double mean, double std);
00350 double getGaussianWithoutNormalization(double value, double mean, double std);
00351 double getUniform();
00352 int getUniform(int min, int max);
00353 void setUniformSeed(unsigned int seed);
00354 double getGaussianProb(double mean, double std);
00355 double getLogisticProb(double alpha, double beta);
00356 void calculateTransformationFromPlane(CVec &plane, CMatrix &transformation);
00357 void convertMatrix(CMatrix &from, double (*R)[3], double *T);
00358 void convertMatrix(double (*R)[3], double *T, CMatrix &to);
00359
00360 void orientation2scaledAxis(CMatrix &matrix, CVec &axis);
00361 void orientation2scaledAxis(CMatrix &matrix, std::vector<double> &axis);
00362 void scaledAxis2Orientation(CVec &axis, CMatrix &matrix);
00363 void scaledAxis2Orientation(std::vector<double> &axis, CMatrix &matrix);
00364
00365 void rosenbrock(int n, double *x, double *bl, double *bu,
00366 double bigbnd, int maxiter, double eps, int verbose,
00367 void obj(int,double *,double *,void *), void *extraparams);
00368 void simulatedannealing(int n, double *x, double *bl, double *bu,
00369 double bigbnd, int maxiter, double eps, int verbose,
00370 void obj(int,double *,double *,void *), void *extraparams);
00371
00374 int rnd(PRECISION value);
00375
00376
00377
00378
00379
00380 inline void CMatrix::mul(const CMatrix &first, const CMatrix &second)
00381 {
00382
00383 PRECISION tmpCMatrixMul[16];
00384 tmpCMatrixMul[0] = first.a[0] * second.a[0] + first.a[4] * second.a[1] + first.a[8] * second.a[2];
00385 tmpCMatrixMul[1] = first.a[1] * second.a[0] + first.a[5] * second.a[1] + first.a[9] * second.a[2];
00386 tmpCMatrixMul[2] = first.a[2] * second.a[0] + first.a[6] * second.a[1] + first.a[10] * second.a[2];
00387 tmpCMatrixMul[3] = 0.0;
00388 tmpCMatrixMul[4] = first.a[0] * second.a[4] + first.a[4] * second.a[5] + first.a[8] * second.a[6];
00389 tmpCMatrixMul[5] = first.a[1] * second.a[4] + first.a[5] * second.a[5] + first.a[9] * second.a[6];
00390 tmpCMatrixMul[6] = first.a[2] * second.a[4] + first.a[6] * second.a[5] + first.a[10] * second.a[6];
00391 tmpCMatrixMul[7] = 0.0;
00392 tmpCMatrixMul[8] = first.a[0] * second.a[8] + first.a[4] * second.a[9] + first.a[8] * second.a[10];
00393 tmpCMatrixMul[9] = first.a[1] * second.a[8] + first.a[5] * second.a[9] + first.a[9] * second.a[10];
00394 tmpCMatrixMul[10] = first.a[2] * second.a[8] + first.a[6] * second.a[9] + first.a[10] * second.a[10];
00395 tmpCMatrixMul[11] = 0.0;
00396 tmpCMatrixMul[12] = first.a[0] * second.a[12] + first.a[4] * second.a[13] + first.a[8] * second.a[14] + first.a[12] * second.a[15];
00397 tmpCMatrixMul[13] = first.a[1] * second.a[12] + first.a[5] * second.a[13] + first.a[9] * second.a[14] + first.a[13] * second.a[15];
00398 tmpCMatrixMul[14] = first.a[2] * second.a[12] + first.a[6] * second.a[13] + first.a[10] * second.a[14] + first.a[14] * second.a[15];
00399 tmpCMatrixMul[15] = first.a[15] * second.a[15];
00400 memcpy(a, tmpCMatrixMul, 16*sizeof(PRECISION));
00401 };
00402
00403
00404
00405 inline void CMatrix::mulNoAlloc(const CMatrix &first, const CMatrix &second)
00406 {
00407 a[0] = first.a[0] * second.a[0] + first.a[4] * second.a[1] + first.a[8] * second.a[2];
00408 a[1] = first.a[1] * second.a[0] + first.a[5] * second.a[1] + first.a[9] * second.a[2];
00409 a[2] = first.a[2] * second.a[0] + first.a[6] * second.a[1] + first.a[10] * second.a[2];
00410 a[3] = 0.0;
00411 a[4] = first.a[0] * second.a[4] + first.a[4] * second.a[5] + first.a[8] * second.a[6];
00412 a[5] = first.a[1] * second.a[4] + first.a[5] * second.a[5] + first.a[9] * second.a[6];
00413 a[6] = first.a[2] * second.a[4] + first.a[6] * second.a[5] + first.a[10] * second.a[6];
00414 a[7] = 0.0;
00415 a[8] = first.a[0] * second.a[8] + first.a[4] * second.a[9] + first.a[8] * second.a[10];
00416 a[9] = first.a[1] * second.a[8] + first.a[5] * second.a[9] + first.a[9] * second.a[10];
00417 a[10] = first.a[2] * second.a[8] + first.a[6] * second.a[9] + first.a[10] * second.a[10];
00418 a[11] = 0.0;
00419 a[12] = first.a[0] * second.a[12] + first.a[4] * second.a[13] + first.a[8] * second.a[14] + first.a[12] * second.a[15];
00420 a[13] = first.a[1] * second.a[12] + first.a[5] * second.a[13] + first.a[9] * second.a[14] + first.a[13] * second.a[15];
00421 a[14] = first.a[2] * second.a[12] + first.a[6] * second.a[13] + first.a[10] * second.a[14] + first.a[14] * second.a[15];
00422 a[15] = first.a[15] * second.a[15];
00423 };
00424
00425 extern boost::mt19937 pRngMt19937;
00426 extern boost::uniform_01<double> pRngDist;
00427 extern boost::variate_generator<boost::mt19937&, boost::uniform_01<double> > pRngUniform01;
00428
00429 inline double getUniform()
00430 {
00431 return pRngUniform01();
00432
00433 }
00434
00435 inline int getUniform(int min, int max)
00436 {
00437 return min + (int) (((double)(max - min)) * pRngUniform01() + 0.5);
00438 }
00439
00440 inline double getGaussianProb(double mean, double std)
00441 {
00442 double u1, u2, v, x;
00443
00444 do
00445 {
00446 u1 = pRngUniform01();
00447 u2 = pRngUniform01();
00448
00449 v = (2.0*u1 - 1.0)*(2.0*u1 - 1.0) + (2.0*u2 - 1.0)*(2.0*u2 - 1.0);
00450 } while (v >= 1.0);
00451
00452 x = (2.0*u1 -1.0)*sqrt(-2.0*log(v) / v);
00453
00454 return std*x + mean;
00455 }
00456
00457
00458 #define SWAPELEMENTS(x,y) tmp = a[x];a[x]=a[y];a[y] = tmp;
00459
00460
00461 inline void CMatrix::invert()
00462 {
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 PRECISION tmp;
00476 PRECISION x = -a[12];
00477 PRECISION y = -a[13];
00478 PRECISION z = -a[14];
00479
00480 SWAPELEMENTS(1,4);
00481 SWAPELEMENTS(2,8);
00482 SWAPELEMENTS(6,9);
00483 a[12] = a[0] * x + a[4] * y + a[8] * z;
00484 a[13] = a[1] * x + a[5] * y + a[9] * z;
00485 a[14] = a[2] * x + a[6] * y + a[10] * z;
00486 }
00487 };
00488
00489 #endif
00490